src/cpu/x86/vm/vtableStubs_x86_32.cpp

Fri, 26 Jun 2009 07:26:10 -0700

author
twisti
date
Fri, 26 Jun 2009 07:26:10 -0700
changeset 1259
18a08a7e16b5
parent 1144
1d037ecd7960
child 1279
bd02caa94611
permissions
-rw-r--r--

5057225: Remove useless I2L conversions
Summary: The optimizer should be told to normalize (AndL (ConvI2L x) 0xFF) to (ConvI2L (AndI x 0xFF)), and then the existing matcher rule will work for free.
Reviewed-by: kvn

     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");
   111   // shut the door on sizing bugs
   112   int slop = 3;  // 32-bit offset is this much larger than an 8-bit one
   113   assert(vtable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
   115   s->set_exception_points(npe_addr, ame_addr);
   116   return s;
   117 }
   120 VtableStub* VtableStubs::create_itable_stub(int itable_index) {
   121   // Note well: pd_code_size_limit is the absolute minimum we can get away with.  If you
   122   //            add code here, bump the code stub size returned by pd_code_size_limit!
   123   const int i486_code_length = VtableStub::pd_code_size_limit(false);
   124   VtableStub* s = new(i486_code_length) VtableStub(false, itable_index);
   125   ResourceMark rm;
   126   CodeBuffer cb(s->entry_point(), i486_code_length);
   127   MacroAssembler* masm = new MacroAssembler(&cb);
   129   // Entry arguments:
   130   //  rax,: Interface
   131   //  rcx: Receiver
   133 #ifndef PRODUCT
   134   if (CountCompiledCalls) {
   135     __ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
   136   }
   137 #endif /* PRODUCT */
   138   // get receiver (need to skip return address on top of stack)
   140   assert(VtableStub::receiver_location() == rcx->as_VMReg(), "receiver expected in rcx");
   142   // get receiver klass (also an implicit null-check)
   143   address npe_addr = __ pc();
   144   __ movptr(rsi, Address(rcx, oopDesc::klass_offset_in_bytes()));
   146   // Most registers are in use; we'll use rax, rbx, rsi, rdi
   147   // (If we need to make rsi, rdi callee-save, do a push/pop here.)
   148   const Register method = rbx;
   149   Label throw_icce;
   151   // Get methodOop and entrypoint for compiler
   152   __ lookup_interface_method(// inputs: rec. class, interface, itable index
   153                              rsi, rax, itable_index,
   154                              // outputs: method, scan temp. reg
   155                              method, rdi,
   156                              throw_icce);
   158   // method (rbx): methodOop
   159   // rcx: receiver
   161 #ifdef ASSERT
   162   if (DebugVtables) {
   163       Label L1;
   164       __ cmpptr(method, (int32_t)NULL_WORD);
   165       __ jcc(Assembler::equal, L1);
   166       __ cmpptr(Address(method, methodOopDesc::from_compiled_offset()), (int32_t)NULL_WORD);
   167       __ jcc(Assembler::notZero, L1);
   168       __ stop("methodOop is null");
   169       __ bind(L1);
   170     }
   171 #endif // ASSERT
   173   address ame_addr = __ pc();
   174   __ jmp(Address(method, methodOopDesc::from_compiled_offset()));
   176   __ bind(throw_icce);
   177   __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
   178   masm->flush();
   180   if (PrintMiscellaneous && (WizardMode || Verbose)) {
   181     tty->print_cr("itable #%d at "PTR_FORMAT"[%d] left over: %d",
   182                   itable_index, s->entry_point(),
   183                   (int)(s->code_end() - s->entry_point()),
   184                   (int)(s->code_end() - __ pc()));
   185   }
   186   guarantee(__ pc() <= s->code_end(), "overflowed buffer");
   187   // shut the door on sizing bugs
   188   int slop = 3;  // 32-bit offset is this much larger than an 8-bit one
   189   assert(itable_index > 10 || __ pc() + slop <= s->code_end(), "room for 32-bit offset");
   191   s->set_exception_points(npe_addr, ame_addr);
   192   return s;
   193 }
   197 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
   198   if (is_vtable_stub) {
   199     // Vtable stub size
   200     return (DebugVtables ? 210 : 16) + (CountCompiledCalls ? 6 : 0);
   201   } else {
   202     // Itable stub size
   203     return (DebugVtables ? 256 : 66) + (CountCompiledCalls ? 6 : 0);
   204   }
   205   // In order to tune these parameters, run the JVM with VM options
   206   // +PrintMiscellaneous and +WizardMode to see information about
   207   // actual itable stubs.  Look for lines like this:
   208   //   itable #1 at 0x5551212[65] left over: 3
   209   // Reduce the constants so that the "left over" number is >=3
   210   // for the common cases.
   211   // Do not aim at a left-over number of zero, because a
   212   // large vtable or itable index (> 16) will require a 32-bit
   213   // immediate displacement instead of an 8-bit one.
   214   //
   215   // The JVM98 app. _202_jess has a megamorphic interface call.
   216   // The itable code looks like this:
   217   // Decoding VtableStub itbl[1]@1
   218   //   mov    0x4(%ecx),%esi
   219   //   mov    0xe8(%esi),%edi
   220   //   lea    0x130(%esi,%edi,4),%edi
   221   //   add    $0x7,%edi
   222   //   and    $0xfffffff8,%edi
   223   //   lea    0x4(%esi),%esi
   224   //   mov    (%edi),%ebx
   225   //   cmp    %ebx,%eax
   226   //   je     success
   227   // loop:
   228   //   test   %ebx,%ebx
   229   //   je     throw_icce
   230   //   add    $0x8,%edi
   231   //   mov    (%edi),%ebx
   232   //   cmp    %ebx,%eax
   233   //   jne    loop
   234   // success:
   235   //   mov    0x4(%edi),%edi
   236   //   mov    (%esi,%edi,1),%ebx
   237   //   jmp    *0x44(%ebx)
   238   // throw_icce:
   239   //   jmp    throw_ICCE_entry
   240 }
   242 int VtableStub::pd_code_alignment() {
   243   return wordSize;
   244 }

mercurial