hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp

Print this page
rev 611 : Merge
   1 #ifdef USE_PRAGMA_IDENT_SRC
   2 #pragma ident "@(#)vtableStubs_sparc.cpp        1.58 07/07/19 12:19:09 JVM"
   3 #endif
   4 /*
   5  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *


  46   const int sparc_code_length = VtableStub::pd_code_size_limit(true);
  47   VtableStub* s = new(sparc_code_length) VtableStub(true, vtable_index);
  48   ResourceMark rm;
  49   CodeBuffer cb(s->entry_point(), sparc_code_length);
  50   MacroAssembler* masm = new MacroAssembler(&cb);
  51 
  52 #ifndef PRODUCT
  53   if (CountCompiledCalls) {
  54     Address ctr(G5, SharedRuntime::nof_megamorphic_calls_addr());
  55     __ sethi(ctr);
  56     __ ld(ctr, G3_scratch);
  57     __ inc(G3_scratch);
  58     __ st(G3_scratch, ctr);
  59   }
  60 #endif /* PRODUCT */
  61 
  62   assert(VtableStub::receiver_location() == O0->as_VMReg(), "receiver expected in O0");
  63 
  64   // get receiver klass
  65   address npe_addr = __ pc();
  66   __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
  67 
  68   // set methodOop (in case of interpreted method), and destination address
  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     __ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5);
  75     __ cmp(G5, vtable_index*vtableEntry::size());
  76     __ br(Assembler::greaterUnsigned, false, Assembler::pt, L);
  77     __ delayed()->nop();
  78     __ set(vtable_index, O2);
  79     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
  80     __ bind(L);
  81   }
  82 #endif
  83   int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
  84   if( __ is_simm13(v_off) ) {
  85     __ ld_ptr(G3, v_off, G5_method);
  86   } else {


 117 // NOTE:  %%%% if any change is made to this stub make sure that the function
 118 //             pd_code_size_limit is changed to ensure the correct size for VtableStub
 119 VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
 120   const int sparc_code_length = VtableStub::pd_code_size_limit(false);
 121   VtableStub* s = new(sparc_code_length) VtableStub(false, vtable_index);
 122   ResourceMark rm;
 123   CodeBuffer cb(s->entry_point(), sparc_code_length);
 124   MacroAssembler* masm = new MacroAssembler(&cb);
 125 
 126   Register G3_klassOop = G3_scratch;
 127   Register G5_interface = G5;  // Passed in as an argument
 128   Label search;
 129 
 130   // Entry arguments:
 131   //  G5_interface: Interface
 132   //  O0:           Receiver
 133   assert(VtableStub::receiver_location() == O0->as_VMReg(), "receiver expected in O0");
 134 
 135   // get receiver klass (also an implicit null-check)
 136   address npe_addr = __ pc();
 137   __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_klassOop);
 138   __ verify_oop(G3_klassOop);
 139 
 140   // Push a new window to get some temp registers.  This chops the head of all
 141   // my 64-bit %o registers in the LION build, but this is OK because no longs
 142   // are passed in the %o registers.  Instead, longs are passed in G1 and G4
 143   // and so those registers are not available here.
 144   __ save(SP,-frame::register_save_words*wordSize,SP);
 145   Register I0_receiver = I0;    // Location of receiver after save
 146 
 147 #ifndef PRODUCT
 148   if (CountCompiledCalls) {
 149     Address ctr(L0, SharedRuntime::nof_megamorphic_calls_addr());
 150     __ sethi(ctr);
 151     __ ld(ctr, L1);
 152     __ inc(L1);
 153     __ st(L1, ctr);
 154   }
 155 #endif /* PRODUCT */
 156 
 157   // load start of itable entries into L0 register


 227 
 228   __ bind(throw_icce);
 229   Address icce(G3_scratch, StubRoutines::throw_IncompatibleClassChangeError_entry());
 230   __ jump_to(icce, 0);
 231   __ delayed()->restore();
 232 
 233   masm->flush();
 234 
 235   guarantee(__ pc() <= s->code_end(), "overflowed buffer");
 236 
 237   s->set_exception_points(npe_addr, ame_addr);
 238   return s;
 239 }
 240 
 241 
 242 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
 243   if (TraceJumps || DebugVtables || CountCompiledCalls || VerifyOops) return 1000;
 244   else {
 245     const int slop = 2*BytesPerInstWord; // sethi;add  (needed for long offsets)
 246     if (is_vtable_stub) {
 247       const int basic = 5*BytesPerInstWord; // ld;ld;ld,jmp,nop



 248       return basic + slop;
 249     } else {
 250       // save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, sethi, add, ld, ld, jmp, restore, sethi, jmpl, restore
 251       const int basic = (22 LP64_ONLY(+ 12)) * BytesPerInstWord; // worst case extra 6 bytes for each sethi in 64-bit mode


 252       return (basic + slop);
 253     }
 254   }
 255 }
 256 
 257 
 258 int VtableStub::pd_code_alignment() {
 259   // UltraSPARC cache line size is 8 instructions:
 260   const unsigned int icache_line_size = 32;
 261   return icache_line_size;
 262 }



   1 /*
   2  * Copyright 1997-2009 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  *


  43   const int sparc_code_length = VtableStub::pd_code_size_limit(true);
  44   VtableStub* s = new(sparc_code_length) VtableStub(true, vtable_index);
  45   ResourceMark rm;
  46   CodeBuffer cb(s->entry_point(), sparc_code_length);
  47   MacroAssembler* masm = new MacroAssembler(&cb);
  48 
  49 #ifndef PRODUCT
  50   if (CountCompiledCalls) {
  51     Address ctr(G5, SharedRuntime::nof_megamorphic_calls_addr());
  52     __ sethi(ctr);
  53     __ ld(ctr, G3_scratch);
  54     __ inc(G3_scratch);
  55     __ st(G3_scratch, ctr);
  56   }
  57 #endif /* PRODUCT */
  58 
  59   assert(VtableStub::receiver_location() == O0->as_VMReg(), "receiver expected in O0");
  60 
  61   // get receiver klass
  62   address npe_addr = __ pc();
  63   __ load_klass(O0, G3_scratch);
  64 
  65   // set methodOop (in case of interpreted method), and destination address
  66   int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
  67 #ifndef PRODUCT
  68   if (DebugVtables) {
  69     Label L;
  70     // check offset vs vtable length
  71     __ ld(G3_scratch, instanceKlass::vtable_length_offset()*wordSize, G5);
  72     __ cmp(G5, vtable_index*vtableEntry::size());
  73     __ br(Assembler::greaterUnsigned, false, Assembler::pt, L);
  74     __ delayed()->nop();
  75     __ set(vtable_index, O2);
  76     __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), O0, O2);
  77     __ bind(L);
  78   }
  79 #endif
  80   int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
  81   if( __ is_simm13(v_off) ) {
  82     __ ld_ptr(G3, v_off, G5_method);
  83   } else {


 114 // NOTE:  %%%% if any change is made to this stub make sure that the function
 115 //             pd_code_size_limit is changed to ensure the correct size for VtableStub
 116 VtableStub* VtableStubs::create_itable_stub(int vtable_index) {
 117   const int sparc_code_length = VtableStub::pd_code_size_limit(false);
 118   VtableStub* s = new(sparc_code_length) VtableStub(false, vtable_index);
 119   ResourceMark rm;
 120   CodeBuffer cb(s->entry_point(), sparc_code_length);
 121   MacroAssembler* masm = new MacroAssembler(&cb);
 122 
 123   Register G3_klassOop = G3_scratch;
 124   Register G5_interface = G5;  // Passed in as an argument
 125   Label search;
 126 
 127   // Entry arguments:
 128   //  G5_interface: Interface
 129   //  O0:           Receiver
 130   assert(VtableStub::receiver_location() == O0->as_VMReg(), "receiver expected in O0");
 131 
 132   // get receiver klass (also an implicit null-check)
 133   address npe_addr = __ pc();
 134   __ load_klass(O0, G3_klassOop);
 135   __ verify_oop(G3_klassOop);
 136 
 137   // Push a new window to get some temp registers.  This chops the head of all
 138   // my 64-bit %o registers in the LION build, but this is OK because no longs
 139   // are passed in the %o registers.  Instead, longs are passed in G1 and G4
 140   // and so those registers are not available here.
 141   __ save(SP,-frame::register_save_words*wordSize,SP);
 142   Register I0_receiver = I0;    // Location of receiver after save
 143 
 144 #ifndef PRODUCT
 145   if (CountCompiledCalls) {
 146     Address ctr(L0, SharedRuntime::nof_megamorphic_calls_addr());
 147     __ sethi(ctr);
 148     __ ld(ctr, L1);
 149     __ inc(L1);
 150     __ st(L1, ctr);
 151   }
 152 #endif /* PRODUCT */
 153 
 154   // load start of itable entries into L0 register


 224 
 225   __ bind(throw_icce);
 226   Address icce(G3_scratch, StubRoutines::throw_IncompatibleClassChangeError_entry());
 227   __ jump_to(icce, 0);
 228   __ delayed()->restore();
 229 
 230   masm->flush();
 231 
 232   guarantee(__ pc() <= s->code_end(), "overflowed buffer");
 233 
 234   s->set_exception_points(npe_addr, ame_addr);
 235   return s;
 236 }
 237 
 238 
 239 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
 240   if (TraceJumps || DebugVtables || CountCompiledCalls || VerifyOops) return 1000;
 241   else {
 242     const int slop = 2*BytesPerInstWord; // sethi;add  (needed for long offsets)
 243     if (is_vtable_stub) {
 244       // ld;ld;ld,jmp,nop
 245       const int basic = 5*BytesPerInstWord +
 246                         // shift;add for load_klass
 247                         (UseCompressedOops ? 2*BytesPerInstWord : 0);
 248       return basic + slop;
 249     } else {
 250       // save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, ld, ld, jmp, restore, sethi, jmpl, restore
 251       const int basic = (22 LP64_ONLY(+ 12)) * BytesPerInstWord +
 252                         // shift;add for load_klass
 253                         (UseCompressedOops ? 2*BytesPerInstWord : 0);
 254       return (basic + slop);
 255     }
 256   }
 257 }
 258 
 259 
 260 int VtableStub::pd_code_alignment() {
 261   // UltraSPARC cache line size is 8 instructions:
 262   const unsigned int icache_line_size = 32;
 263   return icache_line_size;
 264 }