Mercurial > hg > truffle
comparison src/cpu/x86/vm/interp_masm_x86_64.cpp @ 304:dc7f315e41f7
5108146: Merge i486 and amd64 cpu directories
6459804: Want client (c1) compiler for x86_64 (amd64) for faster start-up
Reviewed-by: kvn
author | never |
---|---|
date | Wed, 27 Aug 2008 00:21:55 -0700 |
parents | d1605aabd0a1 |
children | f8199438385b |
comparison
equal
deleted
inserted
replaced
303:fa4d1d240383 | 304:dc7f315e41f7 |
---|---|
26 #include "incls/_interp_masm_x86_64.cpp.incl" | 26 #include "incls/_interp_masm_x86_64.cpp.incl" |
27 | 27 |
28 | 28 |
29 // Implementation of InterpreterMacroAssembler | 29 // Implementation of InterpreterMacroAssembler |
30 | 30 |
31 #ifdef CC_INTERP | |
32 void InterpreterMacroAssembler::get_method(Register reg) { | |
33 movptr(reg, Address(rbp, -(sizeof(BytecodeInterpreter) + 2 * wordSize))); | |
34 movptr(reg, Address(reg, byte_offset_of(BytecodeInterpreter, _method))); | |
35 } | |
36 #endif // CC_INTERP | |
37 | |
38 #ifndef CC_INTERP | |
39 | |
31 void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, | 40 void InterpreterMacroAssembler::call_VM_leaf_base(address entry_point, |
32 int number_of_arguments) { | 41 int number_of_arguments) { |
33 // interpreter specific | 42 // interpreter specific |
34 // | 43 // |
35 // Note: No need to save/restore bcp & locals (r13 & r14) pointer | 44 // Note: No need to save/restore bcp & locals (r13 & r14) pointer |
37 // GC can happen in leaf calls. | 46 // GC can happen in leaf calls. |
38 #ifdef ASSERT | 47 #ifdef ASSERT |
39 save_bcp(); | 48 save_bcp(); |
40 { | 49 { |
41 Label L; | 50 Label L; |
42 cmpq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD); | 51 cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
43 jcc(Assembler::equal, L); | 52 jcc(Assembler::equal, L); |
44 stop("InterpreterMacroAssembler::call_VM_leaf_base:" | 53 stop("InterpreterMacroAssembler::call_VM_leaf_base:" |
45 " last_sp != NULL"); | 54 " last_sp != NULL"); |
46 bind(L); | 55 bind(L); |
47 } | 56 } |
50 MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments); | 59 MacroAssembler::call_VM_leaf_base(entry_point, number_of_arguments); |
51 // interpreter specific | 60 // interpreter specific |
52 #ifdef ASSERT | 61 #ifdef ASSERT |
53 { | 62 { |
54 Label L; | 63 Label L; |
55 cmpq(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); | 64 cmpptr(r13, Address(rbp, frame::interpreter_frame_bcx_offset * wordSize)); |
56 jcc(Assembler::equal, L); | 65 jcc(Assembler::equal, L); |
57 stop("InterpreterMacroAssembler::call_VM_leaf_base:" | 66 stop("InterpreterMacroAssembler::call_VM_leaf_base:" |
58 " r13 not callee saved?"); | 67 " r13 not callee saved?"); |
59 bind(L); | 68 bind(L); |
60 } | 69 } |
61 { | 70 { |
62 Label L; | 71 Label L; |
63 cmpq(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); | 72 cmpptr(r14, Address(rbp, frame::interpreter_frame_locals_offset * wordSize)); |
64 jcc(Assembler::equal, L); | 73 jcc(Assembler::equal, L); |
65 stop("InterpreterMacroAssembler::call_VM_leaf_base:" | 74 stop("InterpreterMacroAssembler::call_VM_leaf_base:" |
66 " r14 not callee saved?"); | 75 " r14 not callee saved?"); |
67 bind(L); | 76 bind(L); |
68 } | 77 } |
84 // assert(java_thread == noreg , "not expecting a precomputed java thread"); | 93 // assert(java_thread == noreg , "not expecting a precomputed java thread"); |
85 save_bcp(); | 94 save_bcp(); |
86 #ifdef ASSERT | 95 #ifdef ASSERT |
87 { | 96 { |
88 Label L; | 97 Label L; |
89 cmpq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int)NULL_WORD); | 98 cmpptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); |
90 jcc(Assembler::equal, L); | 99 jcc(Assembler::equal, L); |
91 stop("InterpreterMacroAssembler::call_VM_leaf_base:" | 100 stop("InterpreterMacroAssembler::call_VM_leaf_base:" |
92 " last_sp != NULL"); | 101 " last_sp != NULL"); |
93 bind(L); | 102 bind(L); |
94 } | 103 } |
125 } | 134 } |
126 } | 135 } |
127 | 136 |
128 | 137 |
129 void InterpreterMacroAssembler::load_earlyret_value(TosState state) { | 138 void InterpreterMacroAssembler::load_earlyret_value(TosState state) { |
130 movq(rcx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); | 139 movptr(rcx, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); |
131 const Address tos_addr(rcx, JvmtiThreadState::earlyret_tos_offset()); | 140 const Address tos_addr(rcx, JvmtiThreadState::earlyret_tos_offset()); |
132 const Address oop_addr(rcx, JvmtiThreadState::earlyret_oop_offset()); | 141 const Address oop_addr(rcx, JvmtiThreadState::earlyret_oop_offset()); |
133 const Address val_addr(rcx, JvmtiThreadState::earlyret_value_offset()); | 142 const Address val_addr(rcx, JvmtiThreadState::earlyret_value_offset()); |
134 switch (state) { | 143 switch (state) { |
135 case atos: movq(rax, oop_addr); | 144 case atos: movptr(rax, oop_addr); |
136 movptr(oop_addr, NULL_WORD); | 145 movptr(oop_addr, (int32_t)NULL_WORD); |
137 verify_oop(rax, state); break; | 146 verify_oop(rax, state); break; |
138 case ltos: movq(rax, val_addr); break; | 147 case ltos: movptr(rax, val_addr); break; |
139 case btos: // fall through | 148 case btos: // fall through |
140 case ctos: // fall through | 149 case ctos: // fall through |
141 case stos: // fall through | 150 case stos: // fall through |
142 case itos: movl(rax, val_addr); break; | 151 case itos: movl(rax, val_addr); break; |
143 case ftos: movflt(xmm0, val_addr); break; | 152 case ftos: movflt(xmm0, val_addr); break; |
145 case vtos: /* nothing to do */ break; | 154 case vtos: /* nothing to do */ break; |
146 default : ShouldNotReachHere(); | 155 default : ShouldNotReachHere(); |
147 } | 156 } |
148 // Clean up tos value in the thread object | 157 // Clean up tos value in the thread object |
149 movl(tos_addr, (int) ilgl); | 158 movl(tos_addr, (int) ilgl); |
150 movl(val_addr, (int) NULL_WORD); | 159 movl(val_addr, (int32_t) NULL_WORD); |
151 } | 160 } |
152 | 161 |
153 | 162 |
154 void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) { | 163 void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) { |
155 if (JvmtiExport::can_force_early_return()) { | 164 if (JvmtiExport::can_force_early_return()) { |
156 Label L; | 165 Label L; |
157 movq(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); | 166 movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); |
158 testq(c_rarg0, c_rarg0); | 167 testptr(c_rarg0, c_rarg0); |
159 jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; | 168 jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; |
160 | 169 |
161 // Initiate earlyret handling only if it is not already being processed. | 170 // Initiate earlyret handling only if it is not already being processed. |
162 // If the flag has the earlyret_processing bit set, it means that this code | 171 // If the flag has the earlyret_processing bit set, it means that this code |
163 // is called *during* earlyret handling - we don't want to reenter. | 172 // is called *during* earlyret handling - we don't want to reenter. |
165 cmpl(c_rarg0, JvmtiThreadState::earlyret_pending); | 174 cmpl(c_rarg0, JvmtiThreadState::earlyret_pending); |
166 jcc(Assembler::notEqual, L); | 175 jcc(Assembler::notEqual, L); |
167 | 176 |
168 // Call Interpreter::remove_activation_early_entry() to get the address of the | 177 // Call Interpreter::remove_activation_early_entry() to get the address of the |
169 // same-named entrypoint in the generated interpreter code. | 178 // same-named entrypoint in the generated interpreter code. |
170 movq(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); | 179 movptr(c_rarg0, Address(r15_thread, JavaThread::jvmti_thread_state_offset())); |
171 movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset())); | 180 movl(c_rarg0, Address(c_rarg0, JvmtiThreadState::earlyret_tos_offset())); |
172 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0); | 181 call_VM_leaf(CAST_FROM_FN_PTR(address, Interpreter::remove_activation_early_entry), c_rarg0); |
173 jmp(rax); | 182 jmp(rax); |
174 bind(L); | 183 bind(L); |
175 } | 184 } |
190 Register index, | 199 Register index, |
191 int bcp_offset) { | 200 int bcp_offset) { |
192 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); | 201 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
193 assert(cache != index, "must use different registers"); | 202 assert(cache != index, "must use different registers"); |
194 load_unsigned_word(index, Address(r13, bcp_offset)); | 203 load_unsigned_word(index, Address(r13, bcp_offset)); |
195 movq(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); | 204 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
196 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); | 205 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); |
197 // convert from field index to ConstantPoolCacheEntry index | 206 // convert from field index to ConstantPoolCacheEntry index |
198 shll(index, 2); | 207 shll(index, 2); |
199 } | 208 } |
200 | 209 |
207 load_unsigned_word(tmp, Address(r13, bcp_offset)); | 216 load_unsigned_word(tmp, Address(r13, bcp_offset)); |
208 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); | 217 assert(sizeof(ConstantPoolCacheEntry) == 4 * wordSize, "adjust code below"); |
209 // convert from field index to ConstantPoolCacheEntry index | 218 // convert from field index to ConstantPoolCacheEntry index |
210 // and from word offset to byte offset | 219 // and from word offset to byte offset |
211 shll(tmp, 2 + LogBytesPerWord); | 220 shll(tmp, 2 + LogBytesPerWord); |
212 movq(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); | 221 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
213 // skip past the header | 222 // skip past the header |
214 addq(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); | 223 addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); |
215 addq(cache, tmp); // construct pointer to cache entry | 224 addptr(cache, tmp); // construct pointer to cache entry |
216 } | 225 } |
217 | 226 |
218 | 227 |
219 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a | 228 // Generate a subtype check: branch to ok_is_subtype if sub_klass is a |
220 // subtype of super_klass. | 229 // subtype of super_klass. |
245 // cache of the secondary superclass list, or a failing value with a | 254 // cache of the secondary superclass list, or a failing value with a |
246 // sentinel offset if the super-klass is an interface or | 255 // sentinel offset if the super-klass is an interface or |
247 // exceptionally deep in the Java hierarchy and we have to scan the | 256 // exceptionally deep in the Java hierarchy and we have to scan the |
248 // secondary superclass list the hard way. See if we get an | 257 // secondary superclass list the hard way. See if we get an |
249 // immediate positive hit | 258 // immediate positive hit |
250 cmpq(rax, Address(Rsub_klass, rcx, Address::times_1)); | 259 cmpptr(rax, Address(Rsub_klass, rcx, Address::times_1)); |
251 jcc(Assembler::equal,ok_is_subtype); | 260 jcc(Assembler::equal,ok_is_subtype); |
252 | 261 |
253 // Check for immediate negative hit | 262 // Check for immediate negative hit |
254 cmpl(rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); | 263 cmpl(rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()); |
255 jcc( Assembler::notEqual, not_subtype ); | 264 jcc( Assembler::notEqual, not_subtype ); |
256 // Check for self | 265 // Check for self |
257 cmpq(Rsub_klass, rax); | 266 cmpptr(Rsub_klass, rax); |
258 jcc(Assembler::equal, ok_is_subtype); | 267 jcc(Assembler::equal, ok_is_subtype); |
259 | 268 |
260 // Now do a linear scan of the secondary super-klass chain. | 269 // Now do a linear scan of the secondary super-klass chain. |
261 movq(rdi, Address(Rsub_klass, sizeof(oopDesc) + | 270 movptr(rdi, Address(Rsub_klass, sizeof(oopDesc) + |
262 Klass::secondary_supers_offset_in_bytes())); | 271 Klass::secondary_supers_offset_in_bytes())); |
263 // rdi holds the objArrayOop of secondary supers. | 272 // rdi holds the objArrayOop of secondary supers. |
264 // Load the array length | 273 // Load the array length |
265 movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); | 274 movl(rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes())); |
266 // Skip to start of data; also clear Z flag incase rcx is zero | 275 // Skip to start of data; also clear Z flag incase rcx is zero |
267 addq(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); | 276 addptr(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); |
268 // Scan rcx words at [rdi] for occurance of rax | 277 // Scan rcx words at [rdi] for occurance of rax |
269 // Set NZ/Z based on last compare | 278 // Set NZ/Z based on last compare |
270 | 279 |
271 // this part is kind tricky, as values in supers array could be 32 or 64 bit wide | 280 // this part is kind tricky, as values in supers array could be 32 or 64 bit wide |
272 // and we store values in objArrays always encoded, thus we need to encode value | 281 // and we store values in objArrays always encoded, thus we need to encode value |
273 // before repne | 282 // before repne |
274 if (UseCompressedOops) { | 283 if (UseCompressedOops) { |
275 pushq(rax); | 284 push(rax); |
276 encode_heap_oop(rax); | 285 encode_heap_oop(rax); |
277 repne_scanl(); | 286 repne_scanl(); |
278 // Not equal? | 287 // Not equal? |
279 jcc(Assembler::notEqual, not_subtype_pop); | 288 jcc(Assembler::notEqual, not_subtype_pop); |
280 // restore heap oop here for movq | 289 // restore heap oop here for movq |
281 popq(rax); | 290 pop(rax); |
282 } else { | 291 } else { |
283 repne_scanq(); | 292 repne_scan(); |
284 jcc(Assembler::notEqual, not_subtype); | 293 jcc(Assembler::notEqual, not_subtype); |
285 } | 294 } |
286 // Must be equal but missed in cache. Update cache. | 295 // Must be equal but missed in cache. Update cache. |
287 movq(Address(Rsub_klass, sizeof(oopDesc) + | 296 movptr(Address(Rsub_klass, sizeof(oopDesc) + |
288 Klass::secondary_super_cache_offset_in_bytes()), rax); | 297 Klass::secondary_super_cache_offset_in_bytes()), rax); |
289 jmp(ok_is_subtype); | 298 jmp(ok_is_subtype); |
290 | 299 |
291 bind(not_subtype_pop); | 300 bind(not_subtype_pop); |
292 // restore heap oop here for miss | 301 // restore heap oop here for miss |
293 if (UseCompressedOops) popq(rax); | 302 if (UseCompressedOops) pop(rax); |
294 bind(not_subtype); | 303 bind(not_subtype); |
295 profile_typecheck_failed(rcx); // blows rcx | 304 profile_typecheck_failed(rcx); // blows rcx |
296 } | 305 } |
306 | |
297 | 307 |
298 | 308 |
299 // Java Expression Stack | 309 // Java Expression Stack |
300 | 310 |
301 #ifdef ASSERT | 311 #ifdef ASSERT |
305 if (TaggedStackInterpreter) { | 315 if (TaggedStackInterpreter) { |
306 frame::Tag tag = t; | 316 frame::Tag tag = t; |
307 if (t == frame::TagCategory2) { | 317 if (t == frame::TagCategory2) { |
308 tag = frame::TagValue; | 318 tag = frame::TagValue; |
309 Label hokay; | 319 Label hokay; |
310 cmpq(Address(rsp, 3*wordSize), (int)tag); | 320 cmpptr(Address(rsp, 3*wordSize), (int32_t)tag); |
311 jcc(Assembler::equal, hokay); | 321 jcc(Assembler::equal, hokay); |
312 stop("Java Expression stack tag high value is bad"); | 322 stop("Java Expression stack tag high value is bad"); |
313 bind(hokay); | 323 bind(hokay); |
314 } | 324 } |
315 Label okay; | 325 Label okay; |
316 cmpq(Address(rsp, wordSize), (int)tag); | 326 cmpptr(Address(rsp, wordSize), (int32_t)tag); |
317 jcc(Assembler::equal, okay); | 327 jcc(Assembler::equal, okay); |
318 // Also compare if the stack value is zero, then the tag might | 328 // Also compare if the stack value is zero, then the tag might |
319 // not have been set coming from deopt. | 329 // not have been set coming from deopt. |
320 cmpq(Address(rsp, 0), 0); | 330 cmpptr(Address(rsp, 0), 0); |
321 jcc(Assembler::equal, okay); | 331 jcc(Assembler::equal, okay); |
322 stop("Java Expression stack tag value is bad"); | 332 stop("Java Expression stack tag value is bad"); |
323 bind(okay); | 333 bind(okay); |
324 } | 334 } |
325 } | 335 } |
326 #endif // ASSERT | 336 #endif // ASSERT |
327 | 337 |
328 void InterpreterMacroAssembler::pop_ptr(Register r) { | 338 void InterpreterMacroAssembler::pop_ptr(Register r) { |
329 debug_only(verify_stack_tag(frame::TagReference)); | 339 debug_only(verify_stack_tag(frame::TagReference)); |
330 popq(r); | 340 pop(r); |
331 if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); | 341 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
332 } | 342 } |
333 | 343 |
334 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { | 344 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { |
335 popq(r); | 345 pop(r); |
336 if (TaggedStackInterpreter) popq(tag); | 346 if (TaggedStackInterpreter) pop(tag); |
337 } | 347 } |
338 | 348 |
339 void InterpreterMacroAssembler::pop_i(Register r) { | 349 void InterpreterMacroAssembler::pop_i(Register r) { |
340 // XXX can't use popq currently, upper half non clean | 350 // XXX can't use pop currently, upper half non clean |
341 debug_only(verify_stack_tag(frame::TagValue)); | 351 debug_only(verify_stack_tag(frame::TagValue)); |
342 movl(r, Address(rsp, 0)); | 352 movl(r, Address(rsp, 0)); |
343 addq(rsp, wordSize); | 353 addptr(rsp, wordSize); |
344 if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); | 354 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
345 } | 355 } |
346 | 356 |
347 void InterpreterMacroAssembler::pop_l(Register r) { | 357 void InterpreterMacroAssembler::pop_l(Register r) { |
348 debug_only(verify_stack_tag(frame::TagCategory2)); | 358 debug_only(verify_stack_tag(frame::TagCategory2)); |
349 movq(r, Address(rsp, 0)); | 359 movq(r, Address(rsp, 0)); |
350 addq(rsp, 2 * Interpreter::stackElementSize()); | 360 addptr(rsp, 2 * Interpreter::stackElementSize()); |
351 } | 361 } |
352 | 362 |
353 void InterpreterMacroAssembler::pop_f(XMMRegister r) { | 363 void InterpreterMacroAssembler::pop_f(XMMRegister r) { |
354 debug_only(verify_stack_tag(frame::TagValue)); | 364 debug_only(verify_stack_tag(frame::TagValue)); |
355 movflt(r, Address(rsp, 0)); | 365 movflt(r, Address(rsp, 0)); |
356 addq(rsp, wordSize); | 366 addptr(rsp, wordSize); |
357 if (TaggedStackInterpreter) addq(rsp, 1 * wordSize); | 367 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
358 } | 368 } |
359 | 369 |
360 void InterpreterMacroAssembler::pop_d(XMMRegister r) { | 370 void InterpreterMacroAssembler::pop_d(XMMRegister r) { |
361 debug_only(verify_stack_tag(frame::TagCategory2)); | 371 debug_only(verify_stack_tag(frame::TagCategory2)); |
362 movdbl(r, Address(rsp, 0)); | 372 movdbl(r, Address(rsp, 0)); |
363 addq(rsp, 2 * Interpreter::stackElementSize()); | 373 addptr(rsp, 2 * Interpreter::stackElementSize()); |
364 } | 374 } |
365 | 375 |
366 void InterpreterMacroAssembler::push_ptr(Register r) { | 376 void InterpreterMacroAssembler::push_ptr(Register r) { |
367 if (TaggedStackInterpreter) pushq(frame::TagReference); | 377 if (TaggedStackInterpreter) push(frame::TagReference); |
368 pushq(r); | 378 push(r); |
369 } | 379 } |
370 | 380 |
371 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { | 381 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { |
372 if (TaggedStackInterpreter) pushq(tag); | 382 if (TaggedStackInterpreter) push(tag); |
373 pushq(r); | 383 push(r); |
374 } | 384 } |
375 | 385 |
376 void InterpreterMacroAssembler::push_i(Register r) { | 386 void InterpreterMacroAssembler::push_i(Register r) { |
377 if (TaggedStackInterpreter) pushq(frame::TagValue); | 387 if (TaggedStackInterpreter) push(frame::TagValue); |
378 pushq(r); | 388 push(r); |
379 } | 389 } |
380 | 390 |
381 void InterpreterMacroAssembler::push_l(Register r) { | 391 void InterpreterMacroAssembler::push_l(Register r) { |
382 if (TaggedStackInterpreter) { | 392 if (TaggedStackInterpreter) { |
383 pushq(frame::TagValue); | 393 push(frame::TagValue); |
384 subq(rsp, 1 * wordSize); | 394 subptr(rsp, 1 * wordSize); |
385 pushq(frame::TagValue); | 395 push(frame::TagValue); |
386 subq(rsp, 1 * wordSize); | 396 subptr(rsp, 1 * wordSize); |
387 } else { | 397 } else { |
388 subq(rsp, 2 * wordSize); | 398 subptr(rsp, 2 * wordSize); |
389 } | 399 } |
390 movq(Address(rsp, 0), r); | 400 movq(Address(rsp, 0), r); |
391 } | 401 } |
392 | 402 |
393 void InterpreterMacroAssembler::push_f(XMMRegister r) { | 403 void InterpreterMacroAssembler::push_f(XMMRegister r) { |
394 if (TaggedStackInterpreter) pushq(frame::TagValue); | 404 if (TaggedStackInterpreter) push(frame::TagValue); |
395 subq(rsp, wordSize); | 405 subptr(rsp, wordSize); |
396 movflt(Address(rsp, 0), r); | 406 movflt(Address(rsp, 0), r); |
397 } | 407 } |
398 | 408 |
399 void InterpreterMacroAssembler::push_d(XMMRegister r) { | 409 void InterpreterMacroAssembler::push_d(XMMRegister r) { |
400 if (TaggedStackInterpreter) { | 410 if (TaggedStackInterpreter) { |
401 pushq(frame::TagValue); | 411 push(frame::TagValue); |
402 subq(rsp, 1 * wordSize); | 412 subptr(rsp, 1 * wordSize); |
403 pushq(frame::TagValue); | 413 push(frame::TagValue); |
404 subq(rsp, 1 * wordSize); | 414 subptr(rsp, 1 * wordSize); |
405 } else { | 415 } else { |
406 subq(rsp, 2 * wordSize); | 416 subptr(rsp, 2 * wordSize); |
407 } | 417 } |
408 movdbl(Address(rsp, 0), r); | 418 movdbl(Address(rsp, 0), r); |
409 } | 419 } |
410 | 420 |
411 void InterpreterMacroAssembler::pop(TosState state) { | 421 void InterpreterMacroAssembler::pop(TosState state) { |
439 default : ShouldNotReachHere(); | 449 default : ShouldNotReachHere(); |
440 } | 450 } |
441 } | 451 } |
442 | 452 |
443 | 453 |
454 | |
455 | |
444 // Tagged stack helpers for swap and dup | 456 // Tagged stack helpers for swap and dup |
445 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, | 457 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, |
446 Register tag) { | 458 Register tag) { |
447 movq(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); | 459 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); |
448 if (TaggedStackInterpreter) { | 460 if (TaggedStackInterpreter) { |
449 movq(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); | 461 movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); |
450 } | 462 } |
451 } | 463 } |
452 | 464 |
453 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, | 465 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, |
454 Register tag) { | 466 Register tag) { |
455 movq(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); | 467 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); |
456 if (TaggedStackInterpreter) { | 468 if (TaggedStackInterpreter) { |
457 movq(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); | 469 movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); |
458 } | 470 } |
459 } | 471 } |
460 | 472 |
461 | 473 |
462 // Tagged local support | 474 // Tagged local support |
463 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { | 475 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { |
464 if (TaggedStackInterpreter) { | 476 if (TaggedStackInterpreter) { |
465 if (tag == frame::TagCategory2) { | 477 if (tag == frame::TagCategory2) { |
466 mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), | 478 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), |
467 (intptr_t)frame::TagValue); | 479 (int32_t)frame::TagValue); |
468 mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), | 480 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), |
469 (intptr_t)frame::TagValue); | 481 (int32_t)frame::TagValue); |
470 } else { | 482 } else { |
471 mov64(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (intptr_t)tag); | 483 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); |
472 } | 484 } |
473 } | 485 } |
474 } | 486 } |
475 | 487 |
476 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { | 488 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { |
477 if (TaggedStackInterpreter) { | 489 if (TaggedStackInterpreter) { |
478 if (tag == frame::TagCategory2) { | 490 if (tag == frame::TagCategory2) { |
479 mov64(Address(r14, idx, Address::times_8, | 491 movptr(Address(r14, idx, Address::times_8, |
480 Interpreter::local_tag_offset_in_bytes(1)), (intptr_t)frame::TagValue); | 492 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); |
481 mov64(Address(r14, idx, Address::times_8, | 493 movptr(Address(r14, idx, Address::times_8, |
482 Interpreter::local_tag_offset_in_bytes(0)), (intptr_t)frame::TagValue); | 494 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); |
483 } else { | 495 } else { |
484 mov64(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), | 496 movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), |
485 (intptr_t)tag); | 497 (int32_t)tag); |
486 } | 498 } |
487 } | 499 } |
488 } | 500 } |
489 | 501 |
490 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { | 502 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { |
491 if (TaggedStackInterpreter) { | 503 if (TaggedStackInterpreter) { |
492 // can only be TagValue or TagReference | 504 // can only be TagValue or TagReference |
493 movq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), tag); | 505 movptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), tag); |
494 } | 506 } |
495 } | 507 } |
496 | 508 |
497 | 509 |
498 void InterpreterMacroAssembler::tag_local(Register tag, int n) { | 510 void InterpreterMacroAssembler::tag_local(Register tag, int n) { |
499 if (TaggedStackInterpreter) { | 511 if (TaggedStackInterpreter) { |
500 // can only be TagValue or TagReference | 512 // can only be TagValue or TagReference |
501 movq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), tag); | 513 movptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), tag); |
502 } | 514 } |
503 } | 515 } |
504 | 516 |
505 #ifdef ASSERT | 517 #ifdef ASSERT |
506 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { | 518 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { |
507 if (TaggedStackInterpreter) { | 519 if (TaggedStackInterpreter) { |
508 frame::Tag t = tag; | 520 frame::Tag t = tag; |
509 if (tag == frame::TagCategory2) { | 521 if (tag == frame::TagCategory2) { |
510 Label nbl; | 522 Label nbl; |
511 t = frame::TagValue; // change to what is stored in locals | 523 t = frame::TagValue; // change to what is stored in locals |
512 cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), (int)t); | 524 cmpptr(Address(r14, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); |
513 jcc(Assembler::equal, nbl); | 525 jcc(Assembler::equal, nbl); |
514 stop("Local tag is bad for long/double"); | 526 stop("Local tag is bad for long/double"); |
515 bind(nbl); | 527 bind(nbl); |
516 } | 528 } |
517 Label notBad; | 529 Label notBad; |
518 cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int)t); | 530 cmpq(Address(r14, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); |
519 jcc(Assembler::equal, notBad); | 531 jcc(Assembler::equal, notBad); |
520 // Also compare if the local value is zero, then the tag might | 532 // Also compare if the local value is zero, then the tag might |
521 // not have been set coming from deopt. | 533 // not have been set coming from deopt. |
522 cmpq(Address(r14, Interpreter::local_offset_in_bytes(n)), 0); | 534 cmpptr(Address(r14, Interpreter::local_offset_in_bytes(n)), 0); |
523 jcc(Assembler::equal, notBad); | 535 jcc(Assembler::equal, notBad); |
524 stop("Local tag is bad"); | 536 stop("Local tag is bad"); |
525 bind(notBad); | 537 bind(notBad); |
526 } | 538 } |
527 } | 539 } |
530 if (TaggedStackInterpreter) { | 542 if (TaggedStackInterpreter) { |
531 frame::Tag t = tag; | 543 frame::Tag t = tag; |
532 if (tag == frame::TagCategory2) { | 544 if (tag == frame::TagCategory2) { |
533 Label nbl; | 545 Label nbl; |
534 t = frame::TagValue; // change to what is stored in locals | 546 t = frame::TagValue; // change to what is stored in locals |
535 cmpq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(1)), (int)t); | 547 cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); |
536 jcc(Assembler::equal, nbl); | 548 jcc(Assembler::equal, nbl); |
537 stop("Local tag is bad for long/double"); | 549 stop("Local tag is bad for long/double"); |
538 bind(nbl); | 550 bind(nbl); |
539 } | 551 } |
540 Label notBad; | 552 Label notBad; |
541 cmpq(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), (int)t); | 553 cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); |
542 jcc(Assembler::equal, notBad); | 554 jcc(Assembler::equal, notBad); |
543 // Also compare if the local value is zero, then the tag might | 555 // Also compare if the local value is zero, then the tag might |
544 // not have been set coming from deopt. | 556 // not have been set coming from deopt. |
545 cmpq(Address(r14, idx, Address::times_8, Interpreter::local_offset_in_bytes(0)), 0); | 557 cmpptr(Address(r14, idx, Address::times_8, Interpreter::local_offset_in_bytes(0)), 0); |
546 jcc(Assembler::equal, notBad); | 558 jcc(Assembler::equal, notBad); |
547 stop("Local tag is bad"); | 559 stop("Local tag is bad"); |
548 bind(notBad); | 560 bind(notBad); |
549 } | 561 } |
550 } | 562 } |
557 | 569 |
558 | 570 |
559 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, | 571 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, |
560 Register arg_1) { | 572 Register arg_1) { |
561 if (c_rarg0 != arg_1) { | 573 if (c_rarg0 != arg_1) { |
562 movq(c_rarg0, arg_1); | 574 mov(c_rarg0, arg_1); |
563 } | 575 } |
564 MacroAssembler::call_VM_leaf_base(entry_point, 1); | 576 MacroAssembler::call_VM_leaf_base(entry_point, 1); |
565 } | 577 } |
566 | 578 |
567 | 579 |
569 Register arg_1, | 581 Register arg_1, |
570 Register arg_2) { | 582 Register arg_2) { |
571 assert(c_rarg0 != arg_2, "smashed argument"); | 583 assert(c_rarg0 != arg_2, "smashed argument"); |
572 assert(c_rarg1 != arg_1, "smashed argument"); | 584 assert(c_rarg1 != arg_1, "smashed argument"); |
573 if (c_rarg0 != arg_1) { | 585 if (c_rarg0 != arg_1) { |
574 movq(c_rarg0, arg_1); | 586 mov(c_rarg0, arg_1); |
575 } | 587 } |
576 if (c_rarg1 != arg_2) { | 588 if (c_rarg1 != arg_2) { |
577 movq(c_rarg1, arg_2); | 589 mov(c_rarg1, arg_2); |
578 } | 590 } |
579 MacroAssembler::call_VM_leaf_base(entry_point, 2); | 591 MacroAssembler::call_VM_leaf_base(entry_point, 2); |
580 } | 592 } |
581 | 593 |
582 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, | 594 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, |
588 assert(c_rarg1 != arg_1, "smashed argument"); | 600 assert(c_rarg1 != arg_1, "smashed argument"); |
589 assert(c_rarg1 != arg_3, "smashed argument"); | 601 assert(c_rarg1 != arg_3, "smashed argument"); |
590 assert(c_rarg2 != arg_1, "smashed argument"); | 602 assert(c_rarg2 != arg_1, "smashed argument"); |
591 assert(c_rarg2 != arg_2, "smashed argument"); | 603 assert(c_rarg2 != arg_2, "smashed argument"); |
592 if (c_rarg0 != arg_1) { | 604 if (c_rarg0 != arg_1) { |
593 movq(c_rarg0, arg_1); | 605 mov(c_rarg0, arg_1); |
594 } | 606 } |
595 if (c_rarg1 != arg_2) { | 607 if (c_rarg1 != arg_2) { |
596 movq(c_rarg1, arg_2); | 608 mov(c_rarg1, arg_2); |
597 } | 609 } |
598 if (c_rarg2 != arg_3) { | 610 if (c_rarg2 != arg_3) { |
599 movq(c_rarg2, arg_3); | 611 mov(c_rarg2, arg_3); |
600 } | 612 } |
601 MacroAssembler::call_VM_leaf_base(entry_point, 3); | 613 MacroAssembler::call_VM_leaf_base(entry_point, 3); |
602 } | 614 } |
603 | 615 |
604 // Jump to from_interpreted entry of a call unless single stepping is possible | 616 // Jump to from_interpreted entry of a call unless single stepping is possible |
605 // in this thread in which case we must call the i2i entry | 617 // in this thread in which case we must call the i2i entry |
606 void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { | 618 void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { |
607 // set sender sp | 619 // set sender sp |
608 leaq(r13, Address(rsp, wordSize)); | 620 lea(r13, Address(rsp, wordSize)); |
609 // record last_sp | 621 // record last_sp |
610 movq(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), r13); | 622 movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), r13); |
611 | 623 |
612 if (JvmtiExport::can_post_interpreter_events()) { | 624 if (JvmtiExport::can_post_interpreter_events()) { |
613 Label run_compiled_code; | 625 Label run_compiled_code; |
614 // JVMTI events, such as single-stepping, are implemented partly by avoiding running | 626 // JVMTI events, such as single-stepping, are implemented partly by avoiding running |
615 // compiled code in threads for which the event is enabled. Check here for | 627 // compiled code in threads for which the event is enabled. Check here for |
642 address* table, | 654 address* table, |
643 bool verifyoop) { | 655 bool verifyoop) { |
644 verify_FPU(1, state); | 656 verify_FPU(1, state); |
645 if (VerifyActivationFrameSize) { | 657 if (VerifyActivationFrameSize) { |
646 Label L; | 658 Label L; |
647 movq(rcx, rbp); | 659 mov(rcx, rbp); |
648 subq(rcx, rsp); | 660 subptr(rcx, rsp); |
649 int min_frame_size = | 661 int32_t min_frame_size = |
650 (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * | 662 (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * |
651 wordSize; | 663 wordSize; |
652 cmpq(rcx, min_frame_size); | 664 cmpptr(rcx, (int32_t)min_frame_size); |
653 jcc(Assembler::greaterEqual, L); | 665 jcc(Assembler::greaterEqual, L); |
654 stop("broken stack frame"); | 666 stop("broken stack frame"); |
655 bind(L); | 667 bind(L); |
656 } | 668 } |
657 if (verifyoop) { | 669 if (verifyoop) { |
676 | 688 |
677 void InterpreterMacroAssembler::dispatch_next(TosState state, int step) { | 689 void InterpreterMacroAssembler::dispatch_next(TosState state, int step) { |
678 // load next bytecode (load before advancing r13 to prevent AGI) | 690 // load next bytecode (load before advancing r13 to prevent AGI) |
679 load_unsigned_byte(rbx, Address(r13, step)); | 691 load_unsigned_byte(rbx, Address(r13, step)); |
680 // advance r13 | 692 // advance r13 |
681 incrementq(r13, step); | 693 increment(r13, step); |
682 dispatch_base(state, Interpreter::dispatch_table(state)); | 694 dispatch_base(state, Interpreter::dispatch_table(state)); |
683 } | 695 } |
684 | 696 |
685 void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) { | 697 void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) { |
686 // load current bytecode | 698 // load current bytecode |
716 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); | 728 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); |
717 movbool(rdx, do_not_unlock_if_synchronized); | 729 movbool(rdx, do_not_unlock_if_synchronized); |
718 movbool(do_not_unlock_if_synchronized, false); // reset the flag | 730 movbool(do_not_unlock_if_synchronized, false); // reset the flag |
719 | 731 |
720 // get method access flags | 732 // get method access flags |
721 movq(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); | 733 movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); |
722 movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); | 734 movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); |
723 testl(rcx, JVM_ACC_SYNCHRONIZED); | 735 testl(rcx, JVM_ACC_SYNCHRONIZED); |
724 jcc(Assembler::zero, unlocked); | 736 jcc(Assembler::zero, unlocked); |
725 | 737 |
726 // Don't unlock anything if the _do_not_unlock_if_synchronized flag | 738 // Don't unlock anything if the _do_not_unlock_if_synchronized flag |
736 // not been unlocked by an explicit monitorexit bytecode. | 748 // not been unlocked by an explicit monitorexit bytecode. |
737 const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * | 749 const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * |
738 wordSize - (int) sizeof(BasicObjectLock)); | 750 wordSize - (int) sizeof(BasicObjectLock)); |
739 // We use c_rarg1 so that if we go slow path it will be the correct | 751 // We use c_rarg1 so that if we go slow path it will be the correct |
740 // register for unlock_object to pass to VM directly | 752 // register for unlock_object to pass to VM directly |
741 leaq(c_rarg1, monitor); // address of first monitor | 753 lea(c_rarg1, monitor); // address of first monitor |
742 | 754 |
743 movq(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); | 755 movptr(rax, Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes())); |
744 testq(rax, rax); | 756 testptr(rax, rax); |
745 jcc(Assembler::notZero, unlock); | 757 jcc(Assembler::notZero, unlock); |
746 | 758 |
747 pop(state); | 759 pop(state); |
748 if (throw_monitor_exception) { | 760 if (throw_monitor_exception) { |
749 // Entry already unlocked, need to throw exception | 761 // Entry already unlocked, need to throw exception |
781 rbp, frame::interpreter_frame_initial_sp_offset * wordSize); | 793 rbp, frame::interpreter_frame_initial_sp_offset * wordSize); |
782 | 794 |
783 bind(restart); | 795 bind(restart); |
784 // We use c_rarg1 so that if we go slow path it will be the correct | 796 // We use c_rarg1 so that if we go slow path it will be the correct |
785 // register for unlock_object to pass to VM directly | 797 // register for unlock_object to pass to VM directly |
786 movq(c_rarg1, monitor_block_top); // points to current entry, starting | 798 movptr(c_rarg1, monitor_block_top); // points to current entry, starting |
787 // with top-most entry | 799 // with top-most entry |
788 leaq(rbx, monitor_block_bot); // points to word before bottom of | 800 lea(rbx, monitor_block_bot); // points to word before bottom of |
789 // monitor block | 801 // monitor block |
790 jmp(entry); | 802 jmp(entry); |
791 | 803 |
792 // Entry already locked, need to throw exception | 804 // Entry already locked, need to throw exception |
793 bind(exception); | 805 bind(exception); |
816 jmp(restart); | 828 jmp(restart); |
817 } | 829 } |
818 | 830 |
819 bind(loop); | 831 bind(loop); |
820 // check if current entry is used | 832 // check if current entry is used |
821 cmpq(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), (int) NULL); | 833 cmpptr(Address(c_rarg1, BasicObjectLock::obj_offset_in_bytes()), (int32_t) NULL); |
822 jcc(Assembler::notEqual, exception); | 834 jcc(Assembler::notEqual, exception); |
823 | 835 |
824 addq(c_rarg1, entry_size); // otherwise advance to next entry | 836 addptr(c_rarg1, entry_size); // otherwise advance to next entry |
825 bind(entry); | 837 bind(entry); |
826 cmpq(c_rarg1, rbx); // check if bottom reached | 838 cmpptr(c_rarg1, rbx); // check if bottom reached |
827 jcc(Assembler::notEqual, loop); // if not at bottom then check this entry | 839 jcc(Assembler::notEqual, loop); // if not at bottom then check this entry |
828 } | 840 } |
829 | 841 |
830 bind(no_unlock); | 842 bind(no_unlock); |
831 | 843 |
836 notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA | 848 notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA |
837 } | 849 } |
838 | 850 |
839 // remove activation | 851 // remove activation |
840 // get sender sp | 852 // get sender sp |
841 movq(rbx, | 853 movptr(rbx, |
842 Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); | 854 Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); |
843 leave(); // remove frame anchor | 855 leave(); // remove frame anchor |
844 popq(ret_addr); // get return address | 856 pop(ret_addr); // get return address |
845 movq(rsp, rbx); // set sp to sender sp | 857 mov(rsp, rbx); // set sp to sender sp |
846 } | 858 } |
859 | |
860 #endif // C_INTERP | |
847 | 861 |
848 // Lock object | 862 // Lock object |
849 // | 863 // |
850 // Args: | 864 // Args: |
851 // c_rarg1: BasicObjectLock to be used for locking | 865 // c_rarg1: BasicObjectLock to be used for locking |
873 BasicLock::displaced_header_offset_in_bytes(); | 887 BasicLock::displaced_header_offset_in_bytes(); |
874 | 888 |
875 Label slow_case; | 889 Label slow_case; |
876 | 890 |
877 // Load object pointer into obj_reg %c_rarg3 | 891 // Load object pointer into obj_reg %c_rarg3 |
878 movq(obj_reg, Address(lock_reg, obj_offset)); | 892 movptr(obj_reg, Address(lock_reg, obj_offset)); |
879 | 893 |
880 if (UseBiasedLocking) { | 894 if (UseBiasedLocking) { |
881 biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, done, &slow_case); | 895 biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, done, &slow_case); |
882 } | 896 } |
883 | 897 |
884 // Load immediate 1 into swap_reg %rax | 898 // Load immediate 1 into swap_reg %rax |
885 movl(swap_reg, 1); | 899 movl(swap_reg, 1); |
886 | 900 |
887 // Load (object->mark() | 1) into swap_reg %rax | 901 // Load (object->mark() | 1) into swap_reg %rax |
888 orq(swap_reg, Address(obj_reg, 0)); | 902 orptr(swap_reg, Address(obj_reg, 0)); |
889 | 903 |
890 // Save (object->mark() | 1) into BasicLock's displaced header | 904 // Save (object->mark() | 1) into BasicLock's displaced header |
891 movq(Address(lock_reg, mark_offset), swap_reg); | 905 movptr(Address(lock_reg, mark_offset), swap_reg); |
892 | 906 |
893 assert(lock_offset == 0, | 907 assert(lock_offset == 0, |
894 "displached header must be first word in BasicObjectLock"); | 908 "displached header must be first word in BasicObjectLock"); |
895 | 909 |
896 if (os::is_MP()) lock(); | 910 if (os::is_MP()) lock(); |
897 cmpxchgq(lock_reg, Address(obj_reg, 0)); | 911 cmpxchgptr(lock_reg, Address(obj_reg, 0)); |
898 if (PrintBiasedLockingStatistics) { | 912 if (PrintBiasedLockingStatistics) { |
899 cond_inc32(Assembler::zero, | 913 cond_inc32(Assembler::zero, |
900 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); | 914 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); |
901 } | 915 } |
902 jcc(Assembler::zero, done); | 916 jcc(Assembler::zero, done); |
908 // These 3 tests can be done by evaluating the following | 922 // These 3 tests can be done by evaluating the following |
909 // expression: ((mark - rsp) & (7 - os::vm_page_size())), | 923 // expression: ((mark - rsp) & (7 - os::vm_page_size())), |
910 // assuming both stack pointer and pagesize have their | 924 // assuming both stack pointer and pagesize have their |
911 // least significant 3 bits clear. | 925 // least significant 3 bits clear. |
912 // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg | 926 // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg |
913 subq(swap_reg, rsp); | 927 subptr(swap_reg, rsp); |
914 andq(swap_reg, 7 - os::vm_page_size()); | 928 andptr(swap_reg, 7 - os::vm_page_size()); |
915 | 929 |
916 // Save the test result, for recursive case, the result is zero | 930 // Save the test result, for recursive case, the result is zero |
917 movq(Address(lock_reg, mark_offset), swap_reg); | 931 movptr(Address(lock_reg, mark_offset), swap_reg); |
918 | 932 |
919 if (PrintBiasedLockingStatistics) { | 933 if (PrintBiasedLockingStatistics) { |
920 cond_inc32(Assembler::zero, | 934 cond_inc32(Assembler::zero, |
921 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); | 935 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); |
922 } | 936 } |
961 | 975 |
962 save_bcp(); // Save in case of exception | 976 save_bcp(); // Save in case of exception |
963 | 977 |
964 // Convert from BasicObjectLock structure to object and BasicLock | 978 // Convert from BasicObjectLock structure to object and BasicLock |
965 // structure Store the BasicLock address into %rax | 979 // structure Store the BasicLock address into %rax |
966 leaq(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); | 980 lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); |
967 | 981 |
968 // Load oop into obj_reg(%c_rarg3) | 982 // Load oop into obj_reg(%c_rarg3) |
969 movq(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); | 983 movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes())); |
970 | 984 |
971 // Free entry | 985 // Free entry |
972 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); | 986 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); |
973 | 987 |
974 if (UseBiasedLocking) { | 988 if (UseBiasedLocking) { |
975 biased_locking_exit(obj_reg, header_reg, done); | 989 biased_locking_exit(obj_reg, header_reg, done); |
976 } | 990 } |
977 | 991 |
978 // Load the old header from BasicLock structure | 992 // Load the old header from BasicLock structure |
979 movq(header_reg, Address(swap_reg, | 993 movptr(header_reg, Address(swap_reg, |
980 BasicLock::displaced_header_offset_in_bytes())); | 994 BasicLock::displaced_header_offset_in_bytes())); |
981 | 995 |
982 // Test for recursion | 996 // Test for recursion |
983 testq(header_reg, header_reg); | 997 testptr(header_reg, header_reg); |
984 | 998 |
985 // zero for recursive case | 999 // zero for recursive case |
986 jcc(Assembler::zero, done); | 1000 jcc(Assembler::zero, done); |
987 | 1001 |
988 // Atomic swap back the old header | 1002 // Atomic swap back the old header |
989 if (os::is_MP()) lock(); | 1003 if (os::is_MP()) lock(); |
990 cmpxchgq(header_reg, Address(obj_reg, 0)); | 1004 cmpxchgptr(header_reg, Address(obj_reg, 0)); |
991 | 1005 |
992 // zero for recursive case | 1006 // zero for recursive case |
993 jcc(Assembler::zero, done); | 1007 jcc(Assembler::zero, done); |
994 | 1008 |
995 // Call the runtime routine for slow case. | 1009 // Call the runtime routine for slow case. |
996 movq(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), | 1010 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), |
997 obj_reg); // restore obj | 1011 obj_reg); // restore obj |
998 call_VM(noreg, | 1012 call_VM(noreg, |
999 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), | 1013 CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), |
1000 lock_reg); | 1014 lock_reg); |
1001 | 1015 |
1003 | 1017 |
1004 restore_bcp(); | 1018 restore_bcp(); |
1005 } | 1019 } |
1006 } | 1020 } |
1007 | 1021 |
1022 #ifndef CC_INTERP | |
1008 | 1023 |
1009 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, | 1024 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, |
1010 Label& zero_continue) { | 1025 Label& zero_continue) { |
1011 assert(ProfileInterpreter, "must be profiling interpreter"); | 1026 assert(ProfileInterpreter, "must be profiling interpreter"); |
1012 movq(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); | 1027 movptr(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); |
1013 testq(mdp, mdp); | 1028 testptr(mdp, mdp); |
1014 jcc(Assembler::zero, zero_continue); | 1029 jcc(Assembler::zero, zero_continue); |
1015 } | 1030 } |
1016 | 1031 |
1017 | 1032 |
1018 // Set the method data pointer for the current bcp. | 1033 // Set the method data pointer for the current bcp. |
1019 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { | 1034 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { |
1020 assert(ProfileInterpreter, "must be profiling interpreter"); | 1035 assert(ProfileInterpreter, "must be profiling interpreter"); |
1021 Label zero_continue; | 1036 Label zero_continue; |
1022 pushq(rax); | 1037 push(rax); |
1023 pushq(rbx); | 1038 push(rbx); |
1024 | 1039 |
1025 get_method(rbx); | 1040 get_method(rbx); |
1026 // Test MDO to avoid the call if it is NULL. | 1041 // Test MDO to avoid the call if it is NULL. |
1027 movq(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); | 1042 movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
1028 testq(rax, rax); | 1043 testptr(rax, rax); |
1029 jcc(Assembler::zero, zero_continue); | 1044 jcc(Assembler::zero, zero_continue); |
1030 | 1045 |
1031 // rbx: method | 1046 // rbx: method |
1032 // r13: bcp | 1047 // r13: bcp |
1033 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13); | 1048 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, r13); |
1034 // rax: mdi | 1049 // rax: mdi |
1035 | 1050 |
1036 movq(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); | 1051 movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
1037 testq(rbx, rbx); | 1052 testptr(rbx, rbx); |
1038 jcc(Assembler::zero, zero_continue); | 1053 jcc(Assembler::zero, zero_continue); |
1039 addq(rbx, in_bytes(methodDataOopDesc::data_offset())); | 1054 addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); |
1040 addq(rbx, rax); | 1055 addptr(rbx, rax); |
1041 movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); | 1056 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); |
1042 | 1057 |
1043 bind(zero_continue); | 1058 bind(zero_continue); |
1044 popq(rbx); | 1059 pop(rbx); |
1045 popq(rax); | 1060 pop(rax); |
1046 } | 1061 } |
1047 | 1062 |
1048 void InterpreterMacroAssembler::verify_method_data_pointer() { | 1063 void InterpreterMacroAssembler::verify_method_data_pointer() { |
1049 assert(ProfileInterpreter, "must be profiling interpreter"); | 1064 assert(ProfileInterpreter, "must be profiling interpreter"); |
1050 #ifdef ASSERT | 1065 #ifdef ASSERT |
1051 Label verify_continue; | 1066 Label verify_continue; |
1052 pushq(rax); | 1067 push(rax); |
1053 pushq(rbx); | 1068 push(rbx); |
1054 pushq(c_rarg3); | 1069 push(c_rarg3); |
1055 pushq(c_rarg2); | 1070 push(c_rarg2); |
1056 test_method_data_pointer(c_rarg3, verify_continue); // If mdp is zero, continue | 1071 test_method_data_pointer(c_rarg3, verify_continue); // If mdp is zero, continue |
1057 get_method(rbx); | 1072 get_method(rbx); |
1058 | 1073 |
1059 // If the mdp is valid, it will point to a DataLayout header which is | 1074 // If the mdp is valid, it will point to a DataLayout header which is |
1060 // consistent with the bcp. The converse is highly probable also. | 1075 // consistent with the bcp. The converse is highly probable also. |
1061 load_unsigned_word(c_rarg2, | 1076 load_unsigned_word(c_rarg2, |
1062 Address(c_rarg3, in_bytes(DataLayout::bci_offset()))); | 1077 Address(c_rarg3, in_bytes(DataLayout::bci_offset()))); |
1063 addq(c_rarg2, Address(rbx, methodOopDesc::const_offset())); | 1078 addptr(c_rarg2, Address(rbx, methodOopDesc::const_offset())); |
1064 leaq(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset())); | 1079 lea(c_rarg2, Address(c_rarg2, constMethodOopDesc::codes_offset())); |
1065 cmpq(c_rarg2, r13); | 1080 cmpptr(c_rarg2, r13); |
1066 jcc(Assembler::equal, verify_continue); | 1081 jcc(Assembler::equal, verify_continue); |
1067 // rbx: method | 1082 // rbx: method |
1068 // r13: bcp | 1083 // r13: bcp |
1069 // c_rarg3: mdp | 1084 // c_rarg3: mdp |
1070 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), | 1085 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), |
1071 rbx, r13, c_rarg3); | 1086 rbx, r13, c_rarg3); |
1072 bind(verify_continue); | 1087 bind(verify_continue); |
1073 popq(c_rarg2); | 1088 pop(c_rarg2); |
1074 popq(c_rarg3); | 1089 pop(c_rarg3); |
1075 popq(rbx); | 1090 pop(rbx); |
1076 popq(rax); | 1091 pop(rax); |
1077 #endif // ASSERT | 1092 #endif // ASSERT |
1078 } | 1093 } |
1079 | 1094 |
1080 | 1095 |
1081 void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, | 1096 void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, |
1082 int constant, | 1097 int constant, |
1083 Register value) { | 1098 Register value) { |
1084 assert(ProfileInterpreter, "must be profiling interpreter"); | 1099 assert(ProfileInterpreter, "must be profiling interpreter"); |
1085 Address data(mdp_in, constant); | 1100 Address data(mdp_in, constant); |
1086 movq(data, value); | 1101 movptr(data, value); |
1087 } | 1102 } |
1088 | 1103 |
1089 | 1104 |
1090 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, | 1105 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, |
1091 int constant, | 1106 int constant, |
1097 } | 1112 } |
1098 | 1113 |
1099 void InterpreterMacroAssembler::increment_mdp_data_at(Address data, | 1114 void InterpreterMacroAssembler::increment_mdp_data_at(Address data, |
1100 bool decrement) { | 1115 bool decrement) { |
1101 assert(ProfileInterpreter, "must be profiling interpreter"); | 1116 assert(ProfileInterpreter, "must be profiling interpreter"); |
1117 // %%% this does 64bit counters at best it is wasting space | |
1118 // at worst it is a rare bug when counters overflow | |
1102 | 1119 |
1103 if (decrement) { | 1120 if (decrement) { |
1104 // Decrement the register. Set condition codes. | 1121 // Decrement the register. Set condition codes. |
1105 addq(data, -DataLayout::counter_increment); | 1122 addptr(data, (int32_t) -DataLayout::counter_increment); |
1106 // If the decrement causes the counter to overflow, stay negative | 1123 // If the decrement causes the counter to overflow, stay negative |
1107 Label L; | 1124 Label L; |
1108 jcc(Assembler::negative, L); | 1125 jcc(Assembler::negative, L); |
1109 addq(data, DataLayout::counter_increment); | 1126 addptr(data, (int32_t) DataLayout::counter_increment); |
1110 bind(L); | 1127 bind(L); |
1111 } else { | 1128 } else { |
1112 assert(DataLayout::counter_increment == 1, | 1129 assert(DataLayout::counter_increment == 1, |
1113 "flow-free idiom only works with 1"); | 1130 "flow-free idiom only works with 1"); |
1114 // Increment the register. Set carry flag. | 1131 // Increment the register. Set carry flag. |
1115 addq(data, DataLayout::counter_increment); | 1132 addptr(data, DataLayout::counter_increment); |
1116 // If the increment causes the counter to overflow, pull back by 1. | 1133 // If the increment causes the counter to overflow, pull back by 1. |
1117 sbbq(data, 0); | 1134 sbbptr(data, (int32_t)0); |
1118 } | 1135 } |
1119 } | 1136 } |
1120 | 1137 |
1121 | 1138 |
1122 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, | 1139 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, |
1144 Register value, | 1161 Register value, |
1145 Register test_value_out, | 1162 Register test_value_out, |
1146 Label& not_equal_continue) { | 1163 Label& not_equal_continue) { |
1147 assert(ProfileInterpreter, "must be profiling interpreter"); | 1164 assert(ProfileInterpreter, "must be profiling interpreter"); |
1148 if (test_value_out == noreg) { | 1165 if (test_value_out == noreg) { |
1149 cmpq(value, Address(mdp_in, offset)); | 1166 cmpptr(value, Address(mdp_in, offset)); |
1150 } else { | 1167 } else { |
1151 // Put the test value into a register, so caller can use it: | 1168 // Put the test value into a register, so caller can use it: |
1152 movq(test_value_out, Address(mdp_in, offset)); | 1169 movptr(test_value_out, Address(mdp_in, offset)); |
1153 cmpq(test_value_out, value); | 1170 cmpptr(test_value_out, value); |
1154 } | 1171 } |
1155 jcc(Assembler::notEqual, not_equal_continue); | 1172 jcc(Assembler::notEqual, not_equal_continue); |
1156 } | 1173 } |
1157 | 1174 |
1158 | 1175 |
1159 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, | 1176 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, |
1160 int offset_of_disp) { | 1177 int offset_of_disp) { |
1161 assert(ProfileInterpreter, "must be profiling interpreter"); | 1178 assert(ProfileInterpreter, "must be profiling interpreter"); |
1162 Address disp_address(mdp_in, offset_of_disp); | 1179 Address disp_address(mdp_in, offset_of_disp); |
1163 addq(mdp_in, disp_address); | 1180 addptr(mdp_in, disp_address); |
1164 movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); | 1181 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1165 } | 1182 } |
1166 | 1183 |
1167 | 1184 |
1168 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, | 1185 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, |
1169 Register reg, | 1186 Register reg, |
1170 int offset_of_disp) { | 1187 int offset_of_disp) { |
1171 assert(ProfileInterpreter, "must be profiling interpreter"); | 1188 assert(ProfileInterpreter, "must be profiling interpreter"); |
1172 Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); | 1189 Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); |
1173 addq(mdp_in, disp_address); | 1190 addptr(mdp_in, disp_address); |
1174 movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); | 1191 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1175 } | 1192 } |
1176 | 1193 |
1177 | 1194 |
1178 void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, | 1195 void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, |
1179 int constant) { | 1196 int constant) { |
1180 assert(ProfileInterpreter, "must be profiling interpreter"); | 1197 assert(ProfileInterpreter, "must be profiling interpreter"); |
1181 addq(mdp_in, constant); | 1198 addptr(mdp_in, constant); |
1182 movq(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); | 1199 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1183 } | 1200 } |
1184 | 1201 |
1185 | 1202 |
1186 void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { | 1203 void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { |
1187 assert(ProfileInterpreter, "must be profiling interpreter"); | 1204 assert(ProfileInterpreter, "must be profiling interpreter"); |
1188 pushq(return_bci); // save/restore across call_VM | 1205 push(return_bci); // save/restore across call_VM |
1189 call_VM(noreg, | 1206 call_VM(noreg, |
1190 CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), | 1207 CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), |
1191 return_bci); | 1208 return_bci); |
1192 popq(return_bci); | 1209 pop(return_bci); |
1193 } | 1210 } |
1194 | 1211 |
1195 | 1212 |
1196 void InterpreterMacroAssembler::profile_taken_branch(Register mdp, | 1213 void InterpreterMacroAssembler::profile_taken_branch(Register mdp, |
1197 Register bumped_count) { | 1214 Register bumped_count) { |
1204 | 1221 |
1205 // We are taking a branch. Increment the taken count. | 1222 // We are taking a branch. Increment the taken count. |
1206 // We inline increment_mdp_data_at to return bumped_count in a register | 1223 // We inline increment_mdp_data_at to return bumped_count in a register |
1207 //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); | 1224 //increment_mdp_data_at(mdp, in_bytes(JumpData::taken_offset())); |
1208 Address data(mdp, in_bytes(JumpData::taken_offset())); | 1225 Address data(mdp, in_bytes(JumpData::taken_offset())); |
1209 movq(bumped_count, data); | 1226 movptr(bumped_count, data); |
1210 assert(DataLayout::counter_increment == 1, | 1227 assert(DataLayout::counter_increment == 1, |
1211 "flow-free idiom only works with 1"); | 1228 "flow-free idiom only works with 1"); |
1212 addq(bumped_count, DataLayout::counter_increment); | 1229 addptr(bumped_count, DataLayout::counter_increment); |
1213 sbbq(bumped_count, 0); | 1230 sbbptr(bumped_count, 0); |
1214 movq(data, bumped_count); // Store back out | 1231 movptr(data, bumped_count); // Store back out |
1215 | 1232 |
1216 // The method data pointer needs to be updated to reflect the new target. | 1233 // The method data pointer needs to be updated to reflect the new target. |
1217 update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset())); | 1234 update_mdp_by_offset(mdp, in_bytes(JumpData::displacement_offset())); |
1218 bind(profile_continue); | 1235 bind(profile_continue); |
1219 } | 1236 } |
1337 jmp(done); | 1354 jmp(done); |
1338 bind(next_test); | 1355 bind(next_test); |
1339 | 1356 |
1340 if (test_for_null_also) { | 1357 if (test_for_null_also) { |
1341 // Failed the equality check on receiver[n]... Test for null. | 1358 // Failed the equality check on receiver[n]... Test for null. |
1342 testq(reg2, reg2); | 1359 testptr(reg2, reg2); |
1343 if (start_row == last_row) { | 1360 if (start_row == last_row) { |
1344 // The only thing left to do is handle the null case. | 1361 // The only thing left to do is handle the null case. |
1345 jcc(Assembler::notZero, done); | 1362 jcc(Assembler::notZero, done); |
1346 break; | 1363 break; |
1347 } | 1364 } |
1533 test_method_data_pointer(mdp, profile_continue); | 1550 test_method_data_pointer(mdp, profile_continue); |
1534 | 1551 |
1535 // Build the base (index * per_case_size_in_bytes()) + | 1552 // Build the base (index * per_case_size_in_bytes()) + |
1536 // case_array_offset_in_bytes() | 1553 // case_array_offset_in_bytes() |
1537 movl(reg2, in_bytes(MultiBranchData::per_case_size())); | 1554 movl(reg2, in_bytes(MultiBranchData::per_case_size())); |
1538 imulq(index, reg2); // XXX l ? | 1555 imulptr(index, reg2); // XXX l ? |
1539 addq(index, in_bytes(MultiBranchData::case_array_offset())); // XXX l ? | 1556 addptr(index, in_bytes(MultiBranchData::case_array_offset())); // XXX l ? |
1540 | 1557 |
1541 // Update the case count | 1558 // Update the case count |
1542 increment_mdp_data_at(mdp, | 1559 increment_mdp_data_at(mdp, |
1543 index, | 1560 index, |
1544 in_bytes(MultiBranchData::relative_count_offset())); | 1561 in_bytes(MultiBranchData::relative_count_offset())); |
1552 bind(profile_continue); | 1569 bind(profile_continue); |
1553 } | 1570 } |
1554 } | 1571 } |
1555 | 1572 |
1556 | 1573 |
1574 | |
1557 void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { | 1575 void InterpreterMacroAssembler::verify_oop(Register reg, TosState state) { |
1558 if (state == atos) { | 1576 if (state == atos) { |
1559 MacroAssembler::verify_oop(reg); | 1577 MacroAssembler::verify_oop(reg); |
1560 } | 1578 } |
1561 } | 1579 } |
1562 | 1580 |
1563 void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { | 1581 void InterpreterMacroAssembler::verify_FPU(int stack_depth, TosState state) { |
1564 } | 1582 } |
1583 #endif // !CC_INTERP | |
1565 | 1584 |
1566 | 1585 |
1567 void InterpreterMacroAssembler::notify_method_entry() { | 1586 void InterpreterMacroAssembler::notify_method_entry() { |
1568 // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to | 1587 // Whenever JVMTI is interp_only_mode, method entry/exit events are sent to |
1569 // track stack depth. If it is possible to enter interp_only_mode we add | 1588 // track stack depth. If it is possible to enter interp_only_mode we add |
1596 Label L; | 1615 Label L; |
1597 // Note: frame::interpreter_frame_result has a dependency on how the | 1616 // Note: frame::interpreter_frame_result has a dependency on how the |
1598 // method result is saved across the call to post_method_exit. If this | 1617 // method result is saved across the call to post_method_exit. If this |
1599 // is changed then the interpreter_frame_result implementation will | 1618 // is changed then the interpreter_frame_result implementation will |
1600 // need to be updated too. | 1619 // need to be updated too. |
1601 push(state); | 1620 |
1621 // For c++ interpreter the result is always stored at a known location in the frame | |
1622 // template interpreter will leave it on the top of the stack. | |
1623 NOT_CC_INTERP(push(state);) | |
1602 movl(rdx, Address(r15_thread, JavaThread::interp_only_mode_offset())); | 1624 movl(rdx, Address(r15_thread, JavaThread::interp_only_mode_offset())); |
1603 testl(rdx, rdx); | 1625 testl(rdx, rdx); |
1604 jcc(Assembler::zero, L); | 1626 jcc(Assembler::zero, L); |
1605 call_VM(noreg, | 1627 call_VM(noreg, |
1606 CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit)); | 1628 CAST_FROM_FN_PTR(address, InterpreterRuntime::post_method_exit)); |
1607 bind(L); | 1629 bind(L); |
1608 pop(state); | 1630 NOT_CC_INTERP(pop(state)); |
1609 } | 1631 } |
1610 | 1632 |
1611 { | 1633 { |
1612 SkipIfEqual skip(this, &DTraceMethodProbes, false); | 1634 SkipIfEqual skip(this, &DTraceMethodProbes, false); |
1613 push(state); | 1635 NOT_CC_INTERP(push(state)); |
1614 get_method(c_rarg1); | 1636 get_method(c_rarg1); |
1615 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), | 1637 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), |
1616 r15_thread, c_rarg1); | 1638 r15_thread, c_rarg1); |
1617 pop(state); | 1639 NOT_CC_INTERP(pop(state)); |
1618 } | 1640 } |
1619 } | 1641 } |