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 }
|