src/cpu/x86/vm/interp_masm_x86.cpp

Wed, 17 Jun 2015 17:48:25 -0700

author
ascarpino
date
Wed, 17 Jun 2015 17:48:25 -0700
changeset 9788
44ef77ad417c
parent 8368
32b682649973
child 8604
04d83ba48607
permissions
-rw-r--r--

8073108: Use x86 and SPARC CPU instructions for GHASH acceleration
Reviewed-by: kvn, jrose, phh

     1 /*
     2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "interp_masm_x86.hpp"
    27 #include "interpreter/interpreter.hpp"
    28 #include "oops/methodData.hpp"
    31 // 8u does not have InterpreterMacroAssembler::load_earlyret_value here
    33 void InterpreterMacroAssembler::narrow(Register result) {
    35   // Get method->_constMethod->_result_type
    36   movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
    37   movptr(rcx, Address(rcx, Method::const_offset()));
    38   load_unsigned_byte(rcx, Address(rcx, ConstMethod::result_type_offset()));
    40   Label done, notBool, notByte, notChar;
    42   // common case first
    43   cmpl(rcx, T_INT);
    44   jcc(Assembler::equal, done);
    46   // mask integer result to narrower return type.
    47   cmpl(rcx, T_BOOLEAN);
    48   jcc(Assembler::notEqual, notBool);
    49   andl(result, 0x1);
    50   jmp(done);
    52   bind(notBool);
    53   cmpl(rcx, T_BYTE);
    54   jcc(Assembler::notEqual, notByte);
    55   LP64_ONLY(movsbl(result, result);)
    56   NOT_LP64(shll(result, 24);)      // truncate upper 24 bits
    57   NOT_LP64(sarl(result, 24);)      // and sign-extend byte
    58   jmp(done);
    60   bind(notByte);
    61   cmpl(rcx, T_CHAR);
    62   jcc(Assembler::notEqual, notChar);
    63   LP64_ONLY(movzwl(result, result);)
    64   NOT_LP64(andl(result, 0xFFFF);)  // truncate upper 16 bits
    65   jmp(done);
    67   bind(notChar);
    68   // cmpl(rcx, T_SHORT);  // all that's left
    69   // jcc(Assembler::notEqual, done);
    70   LP64_ONLY(movswl(result, result);)
    71   NOT_LP64(shll(result, 16);)      // truncate upper 16 bits
    72   NOT_LP64(sarl(result, 16);)      // and sign-extend short
    74   // Nothing to do for T_INT
    75   bind(done);
    76 }
    78 #ifndef CC_INTERP
    79 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
    80   Label update, next, none;
    82   verify_oop(obj);
    84   testptr(obj, obj);
    85   jccb(Assembler::notZero, update);
    86   orptr(mdo_addr, TypeEntries::null_seen);
    87   jmpb(next);
    89   bind(update);
    90   load_klass(obj, obj);
    92   xorptr(obj, mdo_addr);
    93   testptr(obj, TypeEntries::type_klass_mask);
    94   jccb(Assembler::zero, next); // klass seen before, nothing to
    95                                // do. The unknown bit may have been
    96                                // set already but no need to check.
    98   testptr(obj, TypeEntries::type_unknown);
    99   jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
   101   cmpptr(mdo_addr, 0);
   102   jccb(Assembler::equal, none);
   103   cmpptr(mdo_addr, TypeEntries::null_seen);
   104   jccb(Assembler::equal, none);
   105   // There is a chance that the checks above (re-reading profiling
   106   // data from memory) fail if another thread has just set the
   107   // profiling to this obj's klass
   108   xorptr(obj, mdo_addr);
   109   testptr(obj, TypeEntries::type_klass_mask);
   110   jccb(Assembler::zero, next);
   112   // different than before. Cannot keep accurate profile.
   113   orptr(mdo_addr, TypeEntries::type_unknown);
   114   jmpb(next);
   116   bind(none);
   117   // first time here. Set profile type.
   118   movptr(mdo_addr, obj);
   120   bind(next);
   121 }
   123 void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
   124   if (!ProfileInterpreter) {
   125     return;
   126   }
   128   if (MethodData::profile_arguments() || MethodData::profile_return()) {
   129     Label profile_continue;
   131     test_method_data_pointer(mdp, profile_continue);
   133     int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
   135     cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
   136     jcc(Assembler::notEqual, profile_continue);
   138     if (MethodData::profile_arguments()) {
   139       Label done;
   140       int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
   141       addptr(mdp, off_to_args);
   143       for (int i = 0; i < TypeProfileArgsLimit; i++) {
   144         if (i > 0 || MethodData::profile_return()) {
   145           // If return value type is profiled we may have no argument to profile
   146           movptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
   147           subl(tmp, i*TypeStackSlotEntries::per_arg_count());
   148           cmpl(tmp, TypeStackSlotEntries::per_arg_count());
   149           jcc(Assembler::less, done);
   150         }
   151         movptr(tmp, Address(callee, Method::const_offset()));
   152         load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
   153         // stack offset o (zero based) from the start of the argument
   154         // list, for n arguments translates into offset n - o - 1 from
   155         // the end of the argument list
   156         subptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
   157         subl(tmp, 1);
   158         Address arg_addr = argument_address(tmp);
   159         movptr(tmp, arg_addr);
   161         Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
   162         profile_obj_type(tmp, mdo_arg_addr);
   164         int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
   165         addptr(mdp, to_add);
   166         off_to_args += to_add;
   167       }
   169       if (MethodData::profile_return()) {
   170         movptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
   171         subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
   172       }
   174       bind(done);
   176       if (MethodData::profile_return()) {
   177         // We're right after the type profile for the last
   178         // argument. tmp is the number of cells left in the
   179         // CallTypeData/VirtualCallTypeData to reach its end. Non null
   180         // if there's a return to profile.
   181         assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
   182         shll(tmp, exact_log2(DataLayout::cell_size));
   183         addptr(mdp, tmp);
   184       }
   185       movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
   186     } else {
   187       assert(MethodData::profile_return(), "either profile call args or call ret");
   188       update_mdp_by_constant(mdp, in_bytes(TypeEntriesAtCall::return_only_size()));
   189     }
   191     // mdp points right after the end of the
   192     // CallTypeData/VirtualCallTypeData, right after the cells for the
   193     // return value type if there's one
   195     bind(profile_continue);
   196   }
   197 }
   199 void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
   200   assert_different_registers(mdp, ret, tmp, _bcp_register);
   201   if (ProfileInterpreter && MethodData::profile_return()) {
   202     Label profile_continue, done;
   204     test_method_data_pointer(mdp, profile_continue);
   206     if (MethodData::profile_return_jsr292_only()) {
   207       // If we don't profile all invoke bytecodes we must make sure
   208       // it's a bytecode we indeed profile. We can't go back to the
   209       // begining of the ProfileData we intend to update to check its
   210       // type because we're right after it and we don't known its
   211       // length
   212       Label do_profile;
   213       cmpb(Address(_bcp_register, 0), Bytecodes::_invokedynamic);
   214       jcc(Assembler::equal, do_profile);
   215       cmpb(Address(_bcp_register, 0), Bytecodes::_invokehandle);
   216       jcc(Assembler::equal, do_profile);
   217       get_method(tmp);
   218       cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm);
   219       jcc(Assembler::notEqual, profile_continue);
   221       bind(do_profile);
   222     }
   224     Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
   225     mov(tmp, ret);
   226     profile_obj_type(tmp, mdo_ret_addr);
   228     bind(profile_continue);
   229   }
   230 }
   232 void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2) {
   233   if (ProfileInterpreter && MethodData::profile_parameters()) {
   234     Label profile_continue, done;
   236     test_method_data_pointer(mdp, profile_continue);
   238     // Load the offset of the area within the MDO used for
   239     // parameters. If it's negative we're not profiling any parameters
   240     movl(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
   241     testl(tmp1, tmp1);
   242     jcc(Assembler::negative, profile_continue);
   244     // Compute a pointer to the area for parameters from the offset
   245     // and move the pointer to the slot for the last
   246     // parameters. Collect profiling from last parameter down.
   247     // mdo start + parameters offset + array length - 1
   248     addptr(mdp, tmp1);
   249     movptr(tmp1, Address(mdp, ArrayData::array_len_offset()));
   250     decrement(tmp1, TypeStackSlotEntries::per_arg_count());
   252     Label loop;
   253     bind(loop);
   255     int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0));
   256     int type_base = in_bytes(ParametersTypeData::type_offset(0));
   257     Address::ScaleFactor per_arg_scale = Address::times(DataLayout::cell_size);
   258     Address arg_off(mdp, tmp1, per_arg_scale, off_base);
   259     Address arg_type(mdp, tmp1, per_arg_scale, type_base);
   261     // load offset on the stack from the slot for this parameter
   262     movptr(tmp2, arg_off);
   263     negptr(tmp2);
   264     // read the parameter from the local area
   265     movptr(tmp2, Address(_locals_register, tmp2, Interpreter::stackElementScale()));
   267     // profile the parameter
   268     profile_obj_type(tmp2, arg_type);
   270     // go to next parameter
   271     decrement(tmp1, TypeStackSlotEntries::per_arg_count());
   272     jcc(Assembler::positive, loop);
   274     bind(profile_continue);
   275   }
   276 }
   277 #endif

mercurial