src/cpu/x86/vm/vtableStubs_x86_32.cpp

Tue, 31 Mar 2009 14:07:08 -0700

author
cfang
date
Tue, 31 Mar 2009 14:07:08 -0700
changeset 1116
fbde8ec322d0
parent 1058
9adddb8c0fc8
child 1144
1d037ecd7960
permissions
-rw-r--r--

6761600: Use sse 4.2 in intrinsics
Summary: Use SSE 4.2 in intrinsics for String.{compareTo/equals/indexOf} and Arrays.equals.
Reviewed-by: kvn, never, jrose

     1 /*
     2  * Copyright 1997-2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 #include "incls/_precompiled.incl"
    26 #include "incls/_vtableStubs_x86_32.cpp.incl"
    28 // machine-dependent part of VtableStubs: create VtableStub of correct size and
    29 // initialize its code
    31 #define __ masm->
    33 #ifndef PRODUCT
    34 extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int index);
    35 #endif
    37 // These stubs are used by the compiler only.
    38 // Argument registers, which must be preserved:
    39 //   rcx - receiver (always first argument)
    40 //   rdx - second argument (if any)
    41 // Other registers that might be usable:
    42 //   rax - inline cache register (is interface for itable stub)
    43 //   rbx - method (used when calling out to interpreter)
    44 // Available now, but may become callee-save at some point:
    45 //   rsi, rdi
    46 // Note that rax and rdx are also used for return values.
    47 //
    48 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
    49   const int i486_code_length = VtableStub::pd_code_size_limit(true);
    50   VtableStub* s = new(i486_code_length) VtableStub(true, vtable_index);
    51   ResourceMark rm;
    52   CodeBuffer cb(s->entry_point(), i486_code_length);
    53   MacroAssembler* masm = new MacroAssembler(&cb);
    55 #ifndef PRODUCT
    57   if (CountCompiledCalls) {
    58     __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
    59   }
    60 #endif /* PRODUCT */
    62   // get receiver (need to skip return address on top of stack)
    63   assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
    65   // get receiver klass
    66   address npe_addr = __ pc();
    67   __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));
    68   // compute entry offset (in words)
    69   int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
    70 #ifndef PRODUCT
    71   if (DebugVtables) {
    72     Label L;
    73     // check offset vs vtable length
    74     __ cmpl(Address(rax, instanceKlass::vtable_length_offset()*wordSize), vtable_index*vtableEntry::size());
    75     __ jcc(Assembler::greater, L);
    76     __ movl(rbx, vtable_index);
    77     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), rcx, rbx);
    78     __ bind(L);
    79   }
    80 #endif // PRODUCT
    82   const Register method = rbx;
    84   // load methodOop and target address
    85   __ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes()));
    86   if (DebugVtables) {
    87     Label L;
    88     __ cmpptr(method, (int32_t)NULL_WORD);
    89     __ jcc(Assembler::equal, L);
    90     __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD);
    91     __ jcc(Assembler::notZero, L);
    92     __ stop("Vtable entry is NULL");
    93     __ bind(L);
    94   }
    96   // rax,: receiver klass
    97   // method (rbx): methodOop
    98   // rcx: receiver
    99   address ame_addr = __ pc();
   100   __ jmp( Address(method, methodOopDesc::from_compiled_offset()));
   102   masm->flush();
   104   if (PrintMiscellaneous && (WizardMode || Verbose)) {
   105     tty->print_cr("vtable #%d at "PTR_FORMAT"[%d] left over: %d",
   106                   vtable_index, s->entry_point(),
   107                   (int)(s->code_end() - s->entry_point()),
   108                   (int)(s->code_end() - __ pc()));
   109   }
   110   guarantee(__ pc() <= s->code_end(), "overflowed buffer");
   112   s->set_exception_points(npe_addr, ame_addr);
   113   return s;
   114 }
   117 VtableStub* VtableStubs::create_itable_stub(int itable_index) {
   118   // Note well: pd_code_size_limit is the absolute minimum we can get away with.  If you
   119   //            add code here, bump the code stub size returned by pd_code_size_limit!
   120   const int i486_code_length = VtableStub::pd_code_size_limit(false);
   121   VtableStub* s = new(i486_code_length) VtableStub(false, itable_index);
   122   ResourceMark rm;
   123   CodeBuffer cb(s->entry_point(), i486_code_length);
   124   MacroAssembler* masm = new MacroAssembler(&cb);
   126   // Entry arguments:
   127   //  rax,: Interface
   128   //  rcx: Receiver
   130 #ifndef PRODUCT
   131   if (CountCompiledCalls) {
   132     __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
   133   }
   134 #endif /* PRODUCT */
   135   // get receiver (need to skip return address on top of stack)
   137   assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
   139   // get receiver klass (also an implicit null-check)
   140   address npe_addr = __ pc();
   141   __ movptr(rsi, Address(rcx, oopDesc::klass_offset_in_bytes()));
   143   // Most registers are in use; we'll use rax, rbx, rsi, rdi
   144   // (If we need to make rsi, rdi callee-save, do a push/pop here.)
   145   const Register method = rbx;
   146   Label throw_icce;
   148   // Get methodOop and entrypoint for compiler
   149   __ lookup_interface_method(// inputs: rec. class, interface, itable index
   150                              rsi, rax, itable_index,
   151                              // outputs: method, scan temp. reg
   152                              method, rdi,
   153                              throw_icce);
   155   // method (rbx): methodOop
   156   // rcx: receiver
   158 #ifdef ASSERT
   159   if (DebugVtables) {
   160       Label L1;
   161       __ cmpptr(method, (int32_t)NULL_WORD);
   162       __ jcc(Assembler::equal, L1);
   163       __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD);
   164       __ jcc(Assembler::notZero, L1);
   165       __ stop("methodOop is null");
   166       __ bind(L1);
   167     }
   168 #endif // ASSERT
   170   address ame_addr = __ pc();
   171   __ jmp(Address(method, methodOopDesc::from_compiled_offset()));
   173   __ bind(throw_icce);
   174   __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
   175   masm->flush();
   177   if (PrintMiscellaneous && (WizardMode || Verbose)) {
   178     tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
   179                   itable_index, s->entry_point(),
   180                   (int)(s->code_end() - s->entry_point()),
   181                   (int)(s->code_end() - __ pc()));
   182   }
   183   guarantee(__ pc() <= s->code_end(), "overflowed buffer");
   185   s->set_exception_points(npe_addr, ame_addr);
   186   return s;
   187 }
   191 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
   192   if (is_vtable_stub) {
   193     // Vtable stub size
   194     return (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0);
   195   } else {
   196     // Itable stub size
   197     return (DebugVtables ? 256 : 66) + (CountCompiledCalls ? 6 : 0);
   198   }
   199 }
   201 int VtableStub::pd_code_alignment() {
   202   return wordSize;
   203 }

mercurial