27 #include "asm/macroAssembler.inline.hpp"
28 #include "assembler_aarch64.inline.hpp"
29 #include "code/vtableStubs.hpp"
30 #include "interp_masm_aarch64.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "oops/compiledICHolder.hpp"
33 #include "oops/instanceKlass.hpp"
34 #include "oops/klassVtable.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "vmreg_aarch64.inline.hpp"
37 #ifdef COMPILER2
38 #include "opto/runtime.hpp"
39 #endif
40
41 // machine-dependent part of VtableStubs: create VtableStub of correct size and
42 // initialize its code
43
44 #define __ masm->
45
46 #ifndef PRODUCT
47 extern "C" void bad_compiled_vtable_index(JavaThread* thread,
48 oop receiver,
49 int index);
50 #endif
51
52 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
53 const int aarch64_code_length = VtableStub::pd_code_size_limit(true);
54 VtableStub* s = new(aarch64_code_length) VtableStub(true, vtable_index);
55 // Can be NULL if there is no free space in the code cache.
56 if (s == NULL) {
57 return NULL;
58 }
59
60 ResourceMark rm;
61 CodeBuffer cb(s->entry_point(), aarch64_code_length);
62 MacroAssembler* masm = new MacroAssembler(&cb);
63
64 #ifndef PRODUCT
65 if (CountCompiledCalls) {
66 __ lea(r16, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
67 __ incrementw(Address(r16));
68 }
69 #endif
70
71 // get receiver (need to skip return address on top of stack)
72 assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
73
74 // get receiver klass
75 address npe_addr = __ pc();
76 __ load_klass(r16, j_rarg0);
77
78 #ifndef PRODUCT
79 if (DebugVtables) {
80 Label L;
81 // check offset vs vtable length
82 __ ldrw(rscratch1, Address(r16, Klass::vtable_length_offset()));
83 __ cmpw(rscratch1, vtable_index * vtableEntry::size());
84 __ br(Assembler::GT, L);
85 __ enter();
86 __ mov(r2, vtable_index);
87 __ call_VM(noreg,
88 CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), j_rarg0, r2);
89 __ leave();
90 __ bind(L);
91 }
92 #endif // PRODUCT
93
94 __ lookup_virtual_method(r16, vtable_index, rmethod);
95
96 if (DebugVtables) {
97 Label L;
98 __ cbz(rmethod, L);
99 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
100 __ cbnz(rscratch1, L);
101 __ stop("Vtable entry is NULL");
102 __ bind(L);
103 }
104 // r0: receiver klass
105 // rmethod: Method*
106 // r2: receiver
107 address ame_addr = __ pc();
108 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
109 __ br(rscratch1);
110
111 __ flush();
112
113 if (PrintMiscellaneous && (WizardMode || Verbose)) {
114 tty->print_cr("vtable #%d at " PTR_FORMAT "[%d] left over: %d",
115 vtable_index, p2i(s->entry_point()),
116 (int)(s->code_end() - s->entry_point()),
117 (int)(s->code_end() - __ pc()));
118 }
119 guarantee(__ pc() <= s->code_end(), "overflowed buffer");
120
121 s->set_exception_points(npe_addr, ame_addr);
122 return s;
123 }
124
125
126 VtableStub* VtableStubs::create_itable_stub(int itable_index) {
127 // Note well: pd_code_size_limit is the absolute minimum we can get
128 // away with. If you add code here, bump the code stub size
129 // returned by pd_code_size_limit!
130 const int code_length = VtableStub::pd_code_size_limit(false);
131 VtableStub* s = new(code_length) VtableStub(false, itable_index);
132 ResourceMark rm;
133 CodeBuffer cb(s->entry_point(), code_length);
134 MacroAssembler* masm = new MacroAssembler(&cb);
135
136 #ifndef PRODUCT
137 if (CountCompiledCalls) {
138 __ lea(r10, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
139 __ incrementw(Address(r10));
140 }
141 #endif
142
143 // Entry arguments:
144 // rscratch2: CompiledICHolder
145 // j_rarg0: Receiver
146
147
148 // Most registers are in use; we'll use r16, rmethod, r10, r11
149 const Register recv_klass_reg = r10;
150 const Register holder_klass_reg = r16; // declaring interface klass (DECC)
151 const Register resolved_klass_reg = rmethod; // resolved interface klass (REFC)
152 const Register temp_reg = r11;
153 const Register icholder_reg = rscratch2;
154
155 Label L_no_such_interface;
156
157 __ ldr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
158 __ ldr(holder_klass_reg, Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
159
160 // get receiver (need to skip return address on top of stack)
161 assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
162 // get receiver klass (also an implicit null-check)
163 address npe_addr = __ pc();
164 __ load_klass(recv_klass_reg, j_rarg0);
165
166 // Receiver subtype check against REFC.
167 // Destroys recv_klass_reg value.
168 __ lookup_interface_method(// inputs: rec. class, interface
169 recv_klass_reg, resolved_klass_reg, noreg,
170 // outputs: scan temp. reg1, scan temp. reg2
171 recv_klass_reg, temp_reg,
172 L_no_such_interface,
173 /*return_method=*/false);
174
175 // Get selected method from declaring class and itable index
176 __ load_klass(recv_klass_reg, j_rarg0); // restore recv_klass_reg
177 __ lookup_interface_method(// inputs: rec. class, interface, itable index
178 recv_klass_reg, holder_klass_reg, itable_index,
179 // outputs: method, scan temp. reg
180 rmethod, temp_reg,
181 L_no_such_interface);
182
183 // method (rmethod): Method*
184 // j_rarg0: receiver
185
186 #ifdef ASSERT
187 if (DebugVtables) {
188 Label L2;
189 __ cbz(rmethod, L2);
190 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
191 __ cbnz(rscratch1, L2);
192 __ stop("compiler entrypoint is null");
193 __ bind(L2);
194 }
195 #endif // ASSERT
196
197 // rmethod: Method*
198 // j_rarg0: receiver
199 address ame_addr = __ pc();
200 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
201 __ br(rscratch1);
202
203 __ bind(L_no_such_interface);
204 // Handle IncompatibleClassChangeError in itable stubs.
205 // More detailed error message.
206 // We force resolving of the call site by jumping to the "handle
207 // wrong method" stub, and so let the interpreter runtime do all the
208 // dirty work.
209 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
210
211 __ flush();
212
213 if (PrintMiscellaneous && (WizardMode || Verbose)) {
214 tty->print_cr("itable #%d at " PTR_FORMAT "[%d] left over: %d",
215 itable_index, p2i(s->entry_point()),
216 (int)(s->code_end() - s->entry_point()),
217 (int)(s->code_end() - __ pc()));
218 }
219 guarantee(__ pc() <= s->code_end(), "overflowed buffer");
220
221 s->set_exception_points(npe_addr, ame_addr);
222 return s;
223 }
224
225
226 int VtableStub::pd_code_size_limit(bool is_vtable_stub) {
227 int size = DebugVtables ? 216 : 0;
228 if (CountCompiledCalls)
229 size += 6 * 4;
230 // FIXME: vtable stubs only need 36 bytes
231 if (is_vtable_stub)
232 size += 52;
233 else
234 size += 176;
235 return size;
236
237 // In order to tune these parameters, run the JVM with VM options
238 // +PrintMiscellaneous and +WizardMode to see information about
239 // actual itable stubs. Run it with -Xmx31G -XX:+UseCompressedOops.
240 //
241 // If Universe::narrow_klass_base is nonzero, decoding a compressed
242 // class can take zeveral instructions.
243 //
244 // The JVM98 app. _202_jess has a megamorphic interface call.
245 // The itable code looks like this:
246
247 // ldr xmethod, [xscratch2,#CompiledICHolder::holder_klass_offset]
248 // ldr x0, [xscratch2]
249 // ldr w10, [x1,#oopDesc::klass_offset_in_bytes]
250 // mov xheapbase, #0x3c000000 // #narrow_klass_base
251 // movk xheapbase, #0x3f7, lsl #32
252 // add x10, xheapbase, x10
253 // mov xheapbase, #0xe7ff0000 // #heapbase
254 // movk xheapbase, #0x3f7, lsl #32
255 // ldr w11, [x10,#vtable_length_offset]
256 // add x11, x10, x11, uxtx #3
257 // add x11, x11, #itableMethodEntry::method_offset_in_bytes
258 // ldr x10, [x11]
259 // cmp xmethod, x10
260 // b.eq found_method
261 // search:
262 // cbz x10, no_such_interface
263 // add x11, x11, #0x10
264 // ldr x10, [x11]
265 // cmp xmethod, x10
266 // b.ne search
267 // found_method:
268 // ldr w10, [x1,#oopDesc::klass_offset_in_bytes]
269 // mov xheapbase, #0x3c000000 // #narrow_klass_base
270 // movk xheapbase, #0x3f7, lsl #32
271 // add x10, xheapbase, x10
272 // mov xheapbase, #0xe7ff0000 // #heapbase
273 // movk xheapbase, #0x3f7, lsl #32
274 // ldr w11, [x10,#vtable_length_offset]
275 // add x11, x10, x11, uxtx #3
276 // add x11, x11, #itableMethodEntry::method_offset_in_bytes
277 // add x10, x10, #itentry_off
278 // ldr xmethod, [x11]
279 // cmp x0, xmethod
280 // b.eq found_method2
281 // search2:
282 // cbz xmethod, 0x000003ffa872e6cc
283 // add x11, x11, #0x10
284 // ldr xmethod, [x11]
285 // cmp x0, xmethod
286 // b.ne search2
287 // found_method2:
288 // ldr w11, [x11,#itableOffsetEntry::offset_offset_in_bytes]
289 // ldr xmethod, [x10,w11,uxtw]
290 // ldr xscratch1, [xmethod,#Method::from_compiled_offset]
291 // br xscratch1
292 // no_such_interface:
293 // b throw_ICCE_entry
294
295 }
296
297 int VtableStub::pd_code_alignment() { return 4; }
|
27 #include "asm/macroAssembler.inline.hpp"
28 #include "assembler_aarch64.inline.hpp"
29 #include "code/vtableStubs.hpp"
30 #include "interp_masm_aarch64.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "oops/compiledICHolder.hpp"
33 #include "oops/instanceKlass.hpp"
34 #include "oops/klassVtable.hpp"
35 #include "runtime/sharedRuntime.hpp"
36 #include "vmreg_aarch64.inline.hpp"
37 #ifdef COMPILER2
38 #include "opto/runtime.hpp"
39 #endif
40
41 // machine-dependent part of VtableStubs: create VtableStub of correct size and
42 // initialize its code
43
44 #define __ masm->
45
46 #ifndef PRODUCT
47 extern "C" void bad_compiled_vtable_index(JavaThread* thread, oop receiver, int index);
48 #endif
49
50 VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
51 // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing.
52 const int stub_code_length = VtableStub::code_size_limit(true);
53 VtableStub* s = new(stub_code_length) VtableStub(true, vtable_index);
54 // Can be NULL if there is no free space in the code cache.
55 if (s == NULL) {
56 return NULL;
57 }
58
59 // Count unused bytes in instruction sequences of variable size.
60 // We add them to the computed buffer size in order to avoid
61 // overflow in subsequently generated stubs.
62 address start_pc;
63 int slop_bytes = 0;
64 int slop_delta = 0;
65
66 ResourceMark rm;
67 CodeBuffer cb(s->entry_point(), stub_code_length);
68 MacroAssembler* masm = new MacroAssembler(&cb);
69
70 #if (!defined(PRODUCT) && defined(COMPILER2))
71 if (CountCompiledCalls) {
72 __ lea(r16, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
73 __ incrementw(Address(r16));
74 }
75 #endif
76
77 // get receiver (need to skip return address on top of stack)
78 assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
79
80 // get receiver klass
81 address npe_addr = __ pc();
82 __ load_klass(r16, j_rarg0);
83
84 #ifndef PRODUCT
85 if (DebugVtables) {
86 Label L;
87 // check offset vs vtable length
88 __ ldrw(rscratch1, Address(r16, Klass::vtable_length_offset()));
89 __ cmpw(rscratch1, vtable_index * vtableEntry::size());
90 __ br(Assembler::GT, L);
91 __ enter();
92 __ mov(r2, vtable_index);
93
94 // TODO: find upper bound for call_VM length.
95 start_pc = __ pc();
96 __ call_VM(noreg, CAST_FROM_FN_PTR(address, bad_compiled_vtable_index), j_rarg0, r2);
97 slop_delta = 470 - (__ pc() - start_pc); // call_VM varies in length, depending on data
98 slop_bytes += slop_delta;
99 assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta);
100
101 __ leave();
102 __ bind(L);
103 }
104 #endif // PRODUCT
105
106 start_pc = __ pc();
107 __ lookup_virtual_method(r16, vtable_index, rmethod);
108 slop_delta = 8 - (int)(__ pc() - start_pc);
109 slop_bytes += slop_delta;
110 assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta);
111
112 #ifndef PRODUCT
113 if (DebugVtables) {
114 Label L;
115 __ cbz(rmethod, L);
116 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
117 __ cbnz(rscratch1, L);
118 __ stop("Vtable entry is NULL");
119 __ bind(L);
120 }
121 #endif // PRODUCT
122
123 // r0: receiver klass
124 // rmethod: Method*
125 // r2: receiver
126 address ame_addr = __ pc();
127 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
128 __ br(rscratch1);
129
130 masm->flush();
131 bookkeeping(masm, tty, s, npe_addr, ame_addr, true, vtable_index, slop_bytes, 0);
132
133 return s;
134 }
135
136
137 VtableStub* VtableStubs::create_itable_stub(int itable_index) {
138 // Read "A word on VtableStub sizing" in share/code/vtableStubs.hpp for details on stub sizing.
139 const int stub_code_length = VtableStub::code_size_limit(false);
140 VtableStub* s = new(stub_code_length) VtableStub(false, itable_index);
141 // Can be NULL if there is no free space in the code cache.
142 if (s == NULL) {
143 return NULL;
144 }
145 // Count unused bytes in instruction sequences of variable size.
146 // We add them to the computed buffer size in order to avoid
147 // overflow in subsequently generated stubs.
148 address start_pc;
149 int slop_bytes = 0;
150 int slop_delta = 0;
151
152 ResourceMark rm;
153 CodeBuffer cb(s->entry_point(), stub_code_length);
154 MacroAssembler* masm = new MacroAssembler(&cb);
155
156 #if (!defined(PRODUCT) && defined(COMPILER2))
157 if (CountCompiledCalls) {
158 __ lea(r10, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
159 __ incrementw(Address(r10));
160 }
161 #endif
162
163 // get receiver (need to skip return address on top of stack)
164 assert(VtableStub::receiver_location() == j_rarg0->as_VMReg(), "receiver expected in j_rarg0");
165
166 // Entry arguments:
167 // rscratch2: CompiledICHolder
168 // j_rarg0: Receiver
169
170 // Most registers are in use; we'll use r16, rmethod, r10, r11
171 const Register recv_klass_reg = r10;
172 const Register holder_klass_reg = r16; // declaring interface klass (DECC)
173 const Register resolved_klass_reg = rmethod; // resolved interface klass (REFC)
174 const Register temp_reg = r11;
175 const Register icholder_reg = rscratch2;
176
177 Label L_no_such_interface;
178
179 __ ldr(resolved_klass_reg, Address(icholder_reg, CompiledICHolder::holder_klass_offset()));
180 __ ldr(holder_klass_reg, Address(icholder_reg, CompiledICHolder::holder_metadata_offset()));
181
182 start_pc = __ pc();
183
184 // get receiver klass (also an implicit null-check)
185 address npe_addr = __ pc();
186 __ load_klass(recv_klass_reg, j_rarg0);
187
188 // Receiver subtype check against REFC.
189 // Destroys recv_klass_reg value.
190 __ lookup_interface_method(// inputs: rec. class, interface
191 recv_klass_reg, resolved_klass_reg, noreg,
192 // outputs: scan temp. reg1, scan temp. reg2
193 recv_klass_reg, temp_reg,
194 L_no_such_interface,
195 /*return_method=*/false);
196
197 const ptrdiff_t typecheckSize = __ pc() - start_pc;
198 start_pc = __ pc();
199
200 // Get selected method from declaring class and itable index
201 __ load_klass(recv_klass_reg, j_rarg0); // restore recv_klass_reg
202 __ lookup_interface_method(// inputs: rec. class, interface, itable index
203 recv_klass_reg, holder_klass_reg, itable_index,
204 // outputs: method, scan temp. reg
205 rmethod, temp_reg,
206 L_no_such_interface);
207
208 const ptrdiff_t lookupSize = __ pc() - start_pc;
209
210 // Reduce "estimate" such that "padding" does not drop below 8.
211 const ptrdiff_t estimate = 152;
212 const ptrdiff_t codesize = typecheckSize + lookupSize;
213 slop_delta = (int)(estimate - codesize);
214 slop_bytes += slop_delta;
215 assert(slop_delta >= 0, "itable #%d: Code size estimate (%d) for lookup_interface_method too small, required: %d", itable_index, (int)estimate, (int)codesize);
216
217 #ifdef ASSERT
218 if (DebugVtables) {
219 Label L2;
220 __ cbz(rmethod, L2);
221 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
222 __ cbnz(rscratch1, L2);
223 __ stop("compiler entrypoint is null");
224 __ bind(L2);
225 }
226 #endif // ASSERT
227
228 // rmethod: Method*
229 // j_rarg0: receiver
230 address ame_addr = __ pc();
231 __ ldr(rscratch1, Address(rmethod, Method::from_compiled_offset()));
232 __ br(rscratch1);
233
234 __ bind(L_no_such_interface);
235 // Handle IncompatibleClassChangeError in itable stubs.
236 // More detailed error message.
237 // We force resolving of the call site by jumping to the "handle
238 // wrong method" stub, and so let the interpreter runtime do all the
239 // dirty work.
240 assert(SharedRuntime::get_handle_wrong_method_stub() != NULL, "check initialization order");
241 __ far_jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
242
243 masm->flush();
244 bookkeeping(masm, tty, s, npe_addr, ame_addr, false, itable_index, slop_bytes, 0);
245
246 return s;
247 }
248
249 int VtableStub::pd_code_alignment() {
250 // aarch64 cache line size is not an architected constant. We just align on 4 bytes (instruction size).
251 const unsigned int icache_line_size = 4;
252 return icache_line_size;
253 }
|