130 const Address oop_addr (rcx, JvmtiThreadState::earlyret_oop_offset()); |
130 const Address oop_addr (rcx, JvmtiThreadState::earlyret_oop_offset()); |
131 const Address val_addr (rcx, JvmtiThreadState::earlyret_value_offset()); |
131 const Address val_addr (rcx, JvmtiThreadState::earlyret_value_offset()); |
132 const Address val_addr1(rcx, JvmtiThreadState::earlyret_value_offset() |
132 const Address val_addr1(rcx, JvmtiThreadState::earlyret_value_offset() |
133 + in_ByteSize(wordSize)); |
133 + in_ByteSize(wordSize)); |
134 switch (state) { |
134 switch (state) { |
135 case atos: movl(rax, oop_addr); |
135 case atos: movptr(rax, oop_addr); |
136 movl(oop_addr, NULL_WORD); |
136 movptr(oop_addr, (int32_t)NULL_WORD); |
137 verify_oop(rax, state); break; |
137 verify_oop(rax, state); break; |
138 case ltos: movl(rdx, val_addr1); // fall through |
138 case ltos: |
|
139 movl(rdx, val_addr1); // fall through |
139 case btos: // fall through |
140 case btos: // fall through |
140 case ctos: // fall through |
141 case ctos: // fall through |
141 case stos: // fall through |
142 case stos: // fall through |
142 case itos: movl(rax, val_addr); break; |
143 case itos: movl(rax, val_addr); break; |
143 case ftos: fld_s(val_addr); break; |
144 case ftos: fld_s(val_addr); break; |
144 case dtos: fld_d(val_addr); break; |
145 case dtos: fld_d(val_addr); break; |
145 case vtos: /* nothing to do */ break; |
146 case vtos: /* nothing to do */ break; |
146 default : ShouldNotReachHere(); |
147 default : ShouldNotReachHere(); |
147 } |
148 } |
148 // Clean up tos value in the thread object |
149 // Clean up tos value in the thread object |
149 movl(tos_addr, (int) ilgl); |
150 movl(tos_addr, (int32_t) ilgl); |
150 movl(val_addr, NULL_WORD); |
151 movptr(val_addr, (int32_t)NULL_WORD); |
151 movl(val_addr1, NULL_WORD); |
152 NOT_LP64(movl(val_addr1, (int32_t)NULL_WORD)); |
152 } |
153 } |
153 |
154 |
154 |
155 |
155 void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) { |
156 void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) { |
156 if (JvmtiExport::can_force_early_return()) { |
157 if (JvmtiExport::can_force_early_return()) { |
157 Label L; |
158 Label L; |
158 Register tmp = java_thread; |
159 Register tmp = java_thread; |
159 movl(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset())); |
160 movptr(tmp, Address(tmp, JavaThread::jvmti_thread_state_offset())); |
160 testl(tmp, tmp); |
161 testptr(tmp, tmp); |
161 jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; |
162 jcc(Assembler::zero, L); // if (thread->jvmti_thread_state() == NULL) exit; |
162 |
163 |
163 // Initiate earlyret handling only if it is not already being processed. |
164 // Initiate earlyret handling only if it is not already being processed. |
164 // If the flag has the earlyret_processing bit set, it means that this code |
165 // If the flag has the earlyret_processing bit set, it means that this code |
165 // is called *during* earlyret handling - we don't want to reenter. |
166 // is called *during* earlyret handling - we don't want to reenter. |
181 |
182 |
182 |
183 |
183 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) { |
184 void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) { |
184 assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode"); |
185 assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode"); |
185 movl(reg, Address(rsi, bcp_offset)); |
186 movl(reg, Address(rsi, bcp_offset)); |
186 bswap(reg); |
187 bswapl(reg); |
187 shrl(reg, 16); |
188 shrl(reg, 16); |
188 } |
189 } |
189 |
190 |
190 |
191 |
191 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset) { |
192 void InterpreterMacroAssembler::get_cache_and_index_at_bcp(Register cache, Register index, int bcp_offset) { |
192 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
193 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
193 assert(cache != index, "must use different registers"); |
194 assert(cache != index, "must use different registers"); |
194 load_unsigned_word(index, Address(rsi, bcp_offset)); |
195 load_unsigned_word(index, Address(rsi, bcp_offset)); |
195 movl(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
196 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
196 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
197 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
197 shll(index, 2); // convert from field index to ConstantPoolCacheEntry index |
198 shlptr(index, 2); // convert from field index to ConstantPoolCacheEntry index |
198 } |
199 } |
199 |
200 |
200 |
201 |
201 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset) { |
202 void InterpreterMacroAssembler::get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset) { |
202 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
203 assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); |
204 load_unsigned_word(tmp, Address(rsi, bcp_offset)); |
205 load_unsigned_word(tmp, Address(rsi, bcp_offset)); |
205 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
206 assert(sizeof(ConstantPoolCacheEntry) == 4*wordSize, "adjust code below"); |
206 // convert from field index to ConstantPoolCacheEntry index |
207 // convert from field index to ConstantPoolCacheEntry index |
207 // and from word offset to byte offset |
208 // and from word offset to byte offset |
208 shll(tmp, 2 + LogBytesPerWord); |
209 shll(tmp, 2 + LogBytesPerWord); |
209 movl(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
210 movptr(cache, Address(rbp, frame::interpreter_frame_cache_offset * wordSize)); |
210 // skip past the header |
211 // skip past the header |
211 addl(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); |
212 addptr(cache, in_bytes(constantPoolCacheOopDesc::base_offset())); |
212 addl(cache, tmp); // construct pointer to cache entry |
213 addptr(cache, tmp); // construct pointer to cache entry |
213 } |
214 } |
214 |
215 |
215 |
216 |
216 // Generate a subtype check: branch to ok_is_subtype if sub_klass is |
217 // Generate a subtype check: branch to ok_is_subtype if sub_klass is |
217 // a subtype of super_klass. EAX holds the super_klass. Blows ECX. |
218 // a subtype of super_klass. EAX holds the super_klass. Blows ECX. |
230 // Load from the sub-klass's super-class display list, or a 1-word cache of |
231 // Load from the sub-klass's super-class display list, or a 1-word cache of |
231 // the secondary superclass list, or a failing value with a sentinel offset |
232 // the secondary superclass list, or a failing value with a sentinel offset |
232 // if the super-klass is an interface or exceptionally deep in the Java |
233 // if the super-klass is an interface or exceptionally deep in the Java |
233 // hierarchy and we have to scan the secondary superclass list the hard way. |
234 // hierarchy and we have to scan the secondary superclass list the hard way. |
234 // See if we get an immediate positive hit |
235 // See if we get an immediate positive hit |
235 cmpl( rax, Address(Rsub_klass,rcx,Address::times_1) ); |
236 cmpptr( rax, Address(Rsub_klass,rcx,Address::times_1) ); |
236 jcc( Assembler::equal,ok_is_subtype ); |
237 jcc( Assembler::equal,ok_is_subtype ); |
237 |
238 |
238 // Check for immediate negative hit |
239 // Check for immediate negative hit |
239 cmpl( rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); |
240 cmpl( rcx, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() ); |
240 jcc( Assembler::notEqual, not_subtype ); |
241 jcc( Assembler::notEqual, not_subtype ); |
241 // Check for self |
242 // Check for self |
242 cmpl( Rsub_klass, rax ); |
243 cmpptr( Rsub_klass, rax ); |
243 jcc( Assembler::equal, ok_is_subtype ); |
244 jcc( Assembler::equal, ok_is_subtype ); |
244 |
245 |
245 // Now do a linear scan of the secondary super-klass chain. |
246 // Now do a linear scan of the secondary super-klass chain. |
246 movl( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); |
247 movptr( rdi, Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes()) ); |
247 // EDI holds the objArrayOop of secondary supers. |
248 // EDI holds the objArrayOop of secondary supers. |
248 movl( rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));// Load the array length |
249 movl( rcx, Address(rdi, arrayOopDesc::length_offset_in_bytes()));// Load the array length |
249 // Skip to start of data; also clear Z flag incase ECX is zero |
250 // Skip to start of data; also clear Z flag incase ECX is zero |
250 addl( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); |
251 addptr( rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT) ); |
251 // Scan ECX words at [EDI] for occurance of EAX |
252 // Scan ECX words at [EDI] for occurance of EAX |
252 // Set NZ/Z based on last compare |
253 // Set NZ/Z based on last compare |
253 repne_scan(); |
254 repne_scan(); |
254 restore_locals(); // Restore EDI; Must not blow flags |
255 restore_locals(); // Restore EDI; Must not blow flags |
255 // Not equal? |
256 // Not equal? |
256 jcc( Assembler::notEqual, not_subtype ); |
257 jcc( Assembler::notEqual, not_subtype ); |
257 // Must be equal but missed in cache. Update cache. |
258 // Must be equal but missed in cache. Update cache. |
258 movl( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); |
259 movptr( Address(Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes()), rax ); |
259 jmp( ok_is_subtype ); |
260 jmp( ok_is_subtype ); |
260 |
261 |
261 bind(not_subtype); |
262 bind(not_subtype); |
262 profile_typecheck_failed(rcx); // blows rcx |
263 profile_typecheck_failed(rcx); // blows rcx |
263 } |
264 } |
274 if (IEEEPrecision) { |
275 if (IEEEPrecision) { |
275 fstp_d(Address(rsp, 0)); |
276 fstp_d(Address(rsp, 0)); |
276 fld_d(Address(rsp, 0)); |
277 fld_d(Address(rsp, 0)); |
277 } |
278 } |
278 } |
279 } |
279 #endif // CC_INTERP |
|
280 |
280 |
281 // Java Expression Stack |
281 // Java Expression Stack |
282 |
282 |
283 #ifdef ASSERT |
283 #ifdef ASSERT |
284 void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { |
284 void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { |
285 if (TaggedStackInterpreter) { |
285 if (TaggedStackInterpreter) { |
286 Label okay; |
286 Label okay; |
287 cmpl(Address(rsp, wordSize), (int)t); |
287 cmpptr(Address(rsp, wordSize), (int32_t)t); |
288 jcc(Assembler::equal, okay); |
288 jcc(Assembler::equal, okay); |
289 // Also compare if the stack value is zero, then the tag might |
289 // Also compare if the stack value is zero, then the tag might |
290 // not have been set coming from deopt. |
290 // not have been set coming from deopt. |
291 cmpl(Address(rsp, 0), 0); |
291 cmpptr(Address(rsp, 0), 0); |
292 jcc(Assembler::equal, okay); |
292 jcc(Assembler::equal, okay); |
293 stop("Java Expression stack tag value is bad"); |
293 stop("Java Expression stack tag value is bad"); |
294 bind(okay); |
294 bind(okay); |
295 } |
295 } |
296 } |
296 } |
297 #endif // ASSERT |
297 #endif // ASSERT |
298 |
298 |
299 void InterpreterMacroAssembler::pop_ptr(Register r) { |
299 void InterpreterMacroAssembler::pop_ptr(Register r) { |
300 debug_only(verify_stack_tag(frame::TagReference)); |
300 debug_only(verify_stack_tag(frame::TagReference)); |
301 popl(r); |
301 pop(r); |
302 if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); |
302 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
303 } |
303 } |
304 |
304 |
305 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { |
305 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { |
306 popl(r); |
306 pop(r); |
307 // Tag may not be reference for jsr, can be returnAddress |
307 // Tag may not be reference for jsr, can be returnAddress |
308 if (TaggedStackInterpreter) popl(tag); |
308 if (TaggedStackInterpreter) pop(tag); |
309 } |
309 } |
310 |
310 |
311 void InterpreterMacroAssembler::pop_i(Register r) { |
311 void InterpreterMacroAssembler::pop_i(Register r) { |
312 debug_only(verify_stack_tag(frame::TagValue)); |
312 debug_only(verify_stack_tag(frame::TagValue)); |
313 popl(r); |
313 pop(r); |
314 if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); |
314 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
315 } |
315 } |
316 |
316 |
317 void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { |
317 void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { |
318 debug_only(verify_stack_tag(frame::TagValue)); |
318 debug_only(verify_stack_tag(frame::TagValue)); |
319 popl(lo); |
319 pop(lo); |
320 if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); |
320 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
321 debug_only(verify_stack_tag(frame::TagValue)); |
321 debug_only(verify_stack_tag(frame::TagValue)); |
322 popl(hi); |
322 pop(hi); |
323 if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); |
323 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
324 } |
324 } |
325 |
325 |
326 void InterpreterMacroAssembler::pop_f() { |
326 void InterpreterMacroAssembler::pop_f() { |
327 debug_only(verify_stack_tag(frame::TagValue)); |
327 debug_only(verify_stack_tag(frame::TagValue)); |
328 fld_s(Address(rsp, 0)); |
328 fld_s(Address(rsp, 0)); |
329 addl(rsp, 1 * wordSize); |
329 addptr(rsp, 1 * wordSize); |
330 if (TaggedStackInterpreter) addl(rsp, 1 * wordSize); |
330 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
331 } |
331 } |
332 |
332 |
333 void InterpreterMacroAssembler::pop_d() { |
333 void InterpreterMacroAssembler::pop_d() { |
334 // Write double to stack contiguously and load into ST0 |
334 // Write double to stack contiguously and load into ST0 |
335 pop_dtos_to_rsp(); |
335 pop_dtos_to_rsp(); |
336 fld_d(Address(rsp, 0)); |
336 fld_d(Address(rsp, 0)); |
337 addl(rsp, 2 * wordSize); |
337 addptr(rsp, 2 * wordSize); |
338 } |
338 } |
339 |
339 |
340 |
340 |
341 // Pop the top of the java expression stack to execution stack (which |
341 // Pop the top of the java expression stack to execution stack (which |
342 // happens to be the same place). |
342 // happens to be the same place). |
343 void InterpreterMacroAssembler::pop_dtos_to_rsp() { |
343 void InterpreterMacroAssembler::pop_dtos_to_rsp() { |
344 if (TaggedStackInterpreter) { |
344 if (TaggedStackInterpreter) { |
345 // Pop double value into scratch registers |
345 // Pop double value into scratch registers |
346 debug_only(verify_stack_tag(frame::TagValue)); |
346 debug_only(verify_stack_tag(frame::TagValue)); |
347 popl(rax); |
347 pop(rax); |
348 addl(rsp, 1* wordSize); |
348 addptr(rsp, 1* wordSize); |
349 debug_only(verify_stack_tag(frame::TagValue)); |
349 debug_only(verify_stack_tag(frame::TagValue)); |
350 popl(rdx); |
350 pop(rdx); |
351 addl(rsp, 1* wordSize); |
351 addptr(rsp, 1* wordSize); |
352 pushl(rdx); |
352 push(rdx); |
353 pushl(rax); |
353 push(rax); |
354 } |
354 } |
355 } |
355 } |
356 |
356 |
357 void InterpreterMacroAssembler::pop_ftos_to_rsp() { |
357 void InterpreterMacroAssembler::pop_ftos_to_rsp() { |
358 if (TaggedStackInterpreter) { |
358 if (TaggedStackInterpreter) { |
359 debug_only(verify_stack_tag(frame::TagValue)); |
359 debug_only(verify_stack_tag(frame::TagValue)); |
360 popl(rax); |
360 pop(rax); |
361 addl(rsp, 1 * wordSize); |
361 addptr(rsp, 1 * wordSize); |
362 pushl(rax); // ftos is at rsp |
362 push(rax); // ftos is at rsp |
363 } |
363 } |
364 } |
364 } |
365 |
365 |
366 void InterpreterMacroAssembler::pop(TosState state) { |
366 void InterpreterMacroAssembler::pop(TosState state) { |
367 switch (state) { |
367 switch (state) { |
378 } |
378 } |
379 verify_oop(rax, state); |
379 verify_oop(rax, state); |
380 } |
380 } |
381 |
381 |
382 void InterpreterMacroAssembler::push_ptr(Register r) { |
382 void InterpreterMacroAssembler::push_ptr(Register r) { |
383 if (TaggedStackInterpreter) pushl(frame::TagReference); |
383 if (TaggedStackInterpreter) push(frame::TagReference); |
384 pushl(r); |
384 push(r); |
385 } |
385 } |
386 |
386 |
387 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { |
387 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { |
388 if (TaggedStackInterpreter) pushl(tag); // tag first |
388 if (TaggedStackInterpreter) push(tag); // tag first |
389 pushl(r); |
389 push(r); |
390 } |
390 } |
391 |
391 |
392 void InterpreterMacroAssembler::push_i(Register r) { |
392 void InterpreterMacroAssembler::push_i(Register r) { |
393 if (TaggedStackInterpreter) pushl(frame::TagValue); |
393 if (TaggedStackInterpreter) push(frame::TagValue); |
394 pushl(r); |
394 push(r); |
395 } |
395 } |
396 |
396 |
397 void InterpreterMacroAssembler::push_l(Register lo, Register hi) { |
397 void InterpreterMacroAssembler::push_l(Register lo, Register hi) { |
398 if (TaggedStackInterpreter) pushl(frame::TagValue); |
398 if (TaggedStackInterpreter) push(frame::TagValue); |
399 pushl(hi); |
399 push(hi); |
400 if (TaggedStackInterpreter) pushl(frame::TagValue); |
400 if (TaggedStackInterpreter) push(frame::TagValue); |
401 pushl(lo); |
401 push(lo); |
402 } |
402 } |
403 |
403 |
404 void InterpreterMacroAssembler::push_f() { |
404 void InterpreterMacroAssembler::push_f() { |
405 if (TaggedStackInterpreter) pushl(frame::TagValue); |
405 if (TaggedStackInterpreter) push(frame::TagValue); |
406 // Do not schedule for no AGI! Never write beyond rsp! |
406 // Do not schedule for no AGI! Never write beyond rsp! |
407 subl(rsp, 1 * wordSize); |
407 subptr(rsp, 1 * wordSize); |
408 fstp_s(Address(rsp, 0)); |
408 fstp_s(Address(rsp, 0)); |
409 } |
409 } |
410 |
410 |
411 void InterpreterMacroAssembler::push_d(Register r) { |
411 void InterpreterMacroAssembler::push_d(Register r) { |
412 if (TaggedStackInterpreter) { |
412 if (TaggedStackInterpreter) { |
413 // Double values are stored as: |
413 // Double values are stored as: |
414 // tag |
414 // tag |
415 // high |
415 // high |
416 // tag |
416 // tag |
417 // low |
417 // low |
418 pushl(frame::TagValue); |
418 push(frame::TagValue); |
419 subl(rsp, 3 * wordSize); |
419 subptr(rsp, 3 * wordSize); |
420 fstp_d(Address(rsp, 0)); |
420 fstp_d(Address(rsp, 0)); |
421 // move high word up to slot n-1 |
421 // move high word up to slot n-1 |
422 movl(r, Address(rsp, 1*wordSize)); |
422 movl(r, Address(rsp, 1*wordSize)); |
423 movl(Address(rsp, 2*wordSize), r); |
423 movl(Address(rsp, 2*wordSize), r); |
424 // move tag |
424 // move tag |
425 movl(Address(rsp, 1*wordSize), frame::TagValue); |
425 movl(Address(rsp, 1*wordSize), frame::TagValue); |
426 } else { |
426 } else { |
427 // Do not schedule for no AGI! Never write beyond rsp! |
427 // Do not schedule for no AGI! Never write beyond rsp! |
428 subl(rsp, 2 * wordSize); |
428 subptr(rsp, 2 * wordSize); |
429 fstp_d(Address(rsp, 0)); |
429 fstp_d(Address(rsp, 0)); |
430 } |
430 } |
431 } |
431 } |
432 |
432 |
433 |
433 |
445 case vtos: /* nothing to do */ break; |
445 case vtos: /* nothing to do */ break; |
446 default : ShouldNotReachHere(); |
446 default : ShouldNotReachHere(); |
447 } |
447 } |
448 } |
448 } |
449 |
449 |
450 #ifndef CC_INTERP |
|
451 |
450 |
452 // Tagged stack helpers for swap and dup |
451 // Tagged stack helpers for swap and dup |
453 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, |
452 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, |
454 Register tag) { |
453 Register tag) { |
455 movl(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); |
454 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); |
456 if (TaggedStackInterpreter) { |
455 if (TaggedStackInterpreter) { |
457 movl(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); |
456 movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); |
458 } |
457 } |
459 } |
458 } |
460 |
459 |
461 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, |
460 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, |
462 Register tag) { |
461 Register tag) { |
463 movl(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); |
462 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); |
464 if (TaggedStackInterpreter) { |
463 if (TaggedStackInterpreter) { |
465 movl(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); |
464 movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); |
466 } |
465 } |
467 } |
466 } |
468 |
467 |
469 |
468 |
470 // Tagged local support |
469 // Tagged local support |
471 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { |
470 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { |
472 if (TaggedStackInterpreter) { |
471 if (TaggedStackInterpreter) { |
473 if (tag == frame::TagCategory2) { |
472 if (tag == frame::TagCategory2) { |
474 movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int)frame::TagValue); |
473 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)frame::TagValue); |
475 movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)frame::TagValue); |
474 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)frame::TagValue); |
476 } else { |
475 } else { |
477 movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)tag); |
476 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); |
478 } |
477 } |
479 } |
478 } |
480 } |
479 } |
481 |
480 |
482 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { |
481 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { |
483 if (TaggedStackInterpreter) { |
482 if (TaggedStackInterpreter) { |
484 if (tag == frame::TagCategory2) { |
483 if (tag == frame::TagCategory2) { |
485 movl(Address(rdi, idx, Interpreter::stackElementScale(), |
484 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
486 Interpreter::local_tag_offset_in_bytes(1)), (int)frame::TagValue); |
485 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); |
487 movl(Address(rdi, idx, Interpreter::stackElementScale(), |
486 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
488 Interpreter::local_tag_offset_in_bytes(0)), (int)frame::TagValue); |
487 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); |
489 } else { |
488 } else { |
490 movl(Address(rdi, idx, Interpreter::stackElementScale(), |
489 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
491 Interpreter::local_tag_offset_in_bytes(0)), (int)tag); |
490 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)tag); |
492 } |
491 } |
493 } |
492 } |
494 } |
493 } |
495 |
494 |
496 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { |
495 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { |
497 if (TaggedStackInterpreter) { |
496 if (TaggedStackInterpreter) { |
498 // can only be TagValue or TagReference |
497 // can only be TagValue or TagReference |
499 movl(Address(rdi, idx, Interpreter::stackElementScale(), |
498 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
500 Interpreter::local_tag_offset_in_bytes(0)), tag); |
499 Interpreter::local_tag_offset_in_bytes(0)), tag); |
501 } |
500 } |
502 } |
501 } |
503 |
502 |
504 |
503 |
505 void InterpreterMacroAssembler::tag_local(Register tag, int n) { |
504 void InterpreterMacroAssembler::tag_local(Register tag, int n) { |
506 if (TaggedStackInterpreter) { |
505 if (TaggedStackInterpreter) { |
507 // can only be TagValue or TagReference |
506 // can only be TagValue or TagReference |
508 movl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); |
507 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); |
509 } |
508 } |
510 } |
509 } |
511 |
510 |
512 #ifdef ASSERT |
511 #ifdef ASSERT |
513 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { |
512 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { |
514 if (TaggedStackInterpreter) { |
513 if (TaggedStackInterpreter) { |
515 frame::Tag t = tag; |
514 frame::Tag t = tag; |
516 if (tag == frame::TagCategory2) { |
515 if (tag == frame::TagCategory2) { |
517 Label nbl; |
516 Label nbl; |
518 t = frame::TagValue; // change to what is stored in locals |
517 t = frame::TagValue; // change to what is stored in locals |
519 cmpl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int)t); |
518 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); |
520 jcc(Assembler::equal, nbl); |
519 jcc(Assembler::equal, nbl); |
521 stop("Local tag is bad for long/double"); |
520 stop("Local tag is bad for long/double"); |
522 bind(nbl); |
521 bind(nbl); |
523 } |
522 } |
524 Label notBad; |
523 Label notBad; |
525 cmpl(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int)t); |
524 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); |
526 jcc(Assembler::equal, notBad); |
525 jcc(Assembler::equal, notBad); |
527 // Also compare if the local value is zero, then the tag might |
526 // Also compare if the local value is zero, then the tag might |
528 // not have been set coming from deopt. |
527 // not have been set coming from deopt. |
529 cmpl(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); |
528 cmpptr(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); |
530 jcc(Assembler::equal, notBad); |
529 jcc(Assembler::equal, notBad); |
531 stop("Local tag is bad"); |
530 stop("Local tag is bad"); |
532 bind(notBad); |
531 bind(notBad); |
533 } |
532 } |
534 } |
533 } |
537 if (TaggedStackInterpreter) { |
536 if (TaggedStackInterpreter) { |
538 frame::Tag t = tag; |
537 frame::Tag t = tag; |
539 if (tag == frame::TagCategory2) { |
538 if (tag == frame::TagCategory2) { |
540 Label nbl; |
539 Label nbl; |
541 t = frame::TagValue; // change to what is stored in locals |
540 t = frame::TagValue; // change to what is stored in locals |
542 cmpl(Address(rdi, idx, Interpreter::stackElementScale(), |
541 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), |
543 Interpreter::local_tag_offset_in_bytes(1)), (int)t); |
542 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); |
544 jcc(Assembler::equal, nbl); |
543 jcc(Assembler::equal, nbl); |
545 stop("Local tag is bad for long/double"); |
544 stop("Local tag is bad for long/double"); |
546 bind(nbl); |
545 bind(nbl); |
547 } |
546 } |
548 Label notBad; |
547 Label notBad; |
549 cmpl(Address(rdi, idx, Interpreter::stackElementScale(), |
548 cmpl(Address(rdi, idx, Interpreter::stackElementScale(), |
550 Interpreter::local_tag_offset_in_bytes(0)), (int)t); |
549 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); |
551 jcc(Assembler::equal, notBad); |
550 jcc(Assembler::equal, notBad); |
552 // Also compare if the local value is zero, then the tag might |
551 // Also compare if the local value is zero, then the tag might |
553 // not have been set coming from deopt. |
552 // not have been set coming from deopt. |
554 cmpl(Address(rdi, idx, Interpreter::stackElementScale(), |
553 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), |
555 Interpreter::local_offset_in_bytes(0)), 0); |
554 Interpreter::local_offset_in_bytes(0)), 0); |
556 jcc(Assembler::equal, notBad); |
555 jcc(Assembler::equal, notBad); |
557 stop("Local tag is bad"); |
556 stop("Local tag is bad"); |
558 bind(notBad); |
557 bind(notBad); |
559 |
558 |
565 MacroAssembler::call_VM_leaf_base(entry_point, 0); |
564 MacroAssembler::call_VM_leaf_base(entry_point, 0); |
566 } |
565 } |
567 |
566 |
568 |
567 |
569 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1) { |
568 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1) { |
570 pushl(arg_1); |
569 push(arg_1); |
571 MacroAssembler::call_VM_leaf_base(entry_point, 1); |
570 MacroAssembler::call_VM_leaf_base(entry_point, 1); |
572 } |
571 } |
573 |
572 |
574 |
573 |
575 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2) { |
574 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2) { |
576 pushl(arg_2); |
575 push(arg_2); |
577 pushl(arg_1); |
576 push(arg_1); |
578 MacroAssembler::call_VM_leaf_base(entry_point, 2); |
577 MacroAssembler::call_VM_leaf_base(entry_point, 2); |
579 } |
578 } |
580 |
579 |
581 |
580 |
582 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3) { |
581 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2, Register arg_3) { |
583 pushl(arg_3); |
582 push(arg_3); |
584 pushl(arg_2); |
583 push(arg_2); |
585 pushl(arg_1); |
584 push(arg_1); |
586 MacroAssembler::call_VM_leaf_base(entry_point, 3); |
585 MacroAssembler::call_VM_leaf_base(entry_point, 3); |
587 } |
586 } |
588 |
587 |
589 |
588 |
590 // Jump to from_interpreted entry of a call unless single stepping is possible |
589 // Jump to from_interpreted entry of a call unless single stepping is possible |
591 // in this thread in which case we must call the i2i entry |
590 // in this thread in which case we must call the i2i entry |
592 void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { |
591 void InterpreterMacroAssembler::jump_from_interpreted(Register method, Register temp) { |
593 // set sender sp |
592 // set sender sp |
594 leal(rsi, Address(rsp, wordSize)); |
593 lea(rsi, Address(rsp, wordSize)); |
595 // record last_sp |
594 // record last_sp |
596 movl(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi); |
595 movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), rsi); |
597 |
596 |
598 if (JvmtiExport::can_post_interpreter_events()) { |
597 if (JvmtiExport::can_post_interpreter_events()) { |
599 Label run_compiled_code; |
598 Label run_compiled_code; |
600 // JVMTI events, such as single-stepping, are implemented partly by avoiding running |
599 // JVMTI events, such as single-stepping, are implemented partly by avoiding running |
601 // compiled code in threads for which the event is enabled. Check here for |
600 // compiled code in threads for which the event is enabled. Check here for |
627 void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, |
626 void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, |
628 bool verifyoop) { |
627 bool verifyoop) { |
629 verify_FPU(1, state); |
628 verify_FPU(1, state); |
630 if (VerifyActivationFrameSize) { |
629 if (VerifyActivationFrameSize) { |
631 Label L; |
630 Label L; |
632 movl(rcx, rbp); |
631 mov(rcx, rbp); |
633 subl(rcx, rsp); |
632 subptr(rcx, rsp); |
634 int min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; |
633 int min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; |
635 cmpl(rcx, min_frame_size); |
634 cmpptr(rcx, min_frame_size); |
636 jcc(Assembler::greaterEqual, L); |
635 jcc(Assembler::greaterEqual, L); |
637 stop("broken stack frame"); |
636 stop("broken stack frame"); |
638 bind(L); |
637 bind(L); |
639 } |
638 } |
640 if (verifyoop) verify_oop(rax, state); |
639 if (verifyoop) verify_oop(rax, state); |
641 Address index(noreg, rbx, Address::times_4); |
640 Address index(noreg, rbx, Address::times_ptr); |
642 ExternalAddress tbl((address)table); |
641 ExternalAddress tbl((address)table); |
643 ArrayAddress dispatch(tbl, index); |
642 ArrayAddress dispatch(tbl, index); |
644 jump(dispatch); |
643 jump(dispatch); |
645 } |
644 } |
646 |
645 |
698 get_thread(rcx); |
697 get_thread(rcx); |
699 const Address do_not_unlock_if_synchronized(rcx, |
698 const Address do_not_unlock_if_synchronized(rcx, |
700 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); |
699 in_bytes(JavaThread::do_not_unlock_if_synchronized_offset())); |
701 |
700 |
702 movbool(rbx, do_not_unlock_if_synchronized); |
701 movbool(rbx, do_not_unlock_if_synchronized); |
703 movl(rdi,rbx); |
702 mov(rdi,rbx); |
704 movbool(do_not_unlock_if_synchronized, false); // reset the flag |
703 movbool(do_not_unlock_if_synchronized, false); // reset the flag |
705 |
704 |
706 movl(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags |
705 movptr(rbx, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); // get method access flags |
707 movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); |
706 movl(rcx, Address(rbx, methodOopDesc::access_flags_offset())); |
708 |
707 |
709 testl(rcx, JVM_ACC_SYNCHRONIZED); |
708 testl(rcx, JVM_ACC_SYNCHRONIZED); |
710 jcc(Assembler::zero, unlocked); |
709 jcc(Assembler::zero, unlocked); |
711 |
710 |
712 // Don't unlock anything if the _do_not_unlock_if_synchronized flag |
711 // Don't unlock anything if the _do_not_unlock_if_synchronized flag |
713 // is set. |
712 // is set. |
714 movl(rcx,rdi); |
713 mov(rcx,rdi); |
715 testbool(rcx); |
714 testbool(rcx); |
716 jcc(Assembler::notZero, no_unlock); |
715 jcc(Assembler::notZero, no_unlock); |
717 |
716 |
718 // unlock monitor |
717 // unlock monitor |
719 push(state); // save result |
718 push(state); // save result |
720 |
719 |
721 // BasicObjectLock will be first in list, since this is a synchronized method. However, need |
720 // BasicObjectLock will be first in list, since this is a synchronized method. However, need |
722 // to check that the object has not been unlocked by an explicit monitorexit bytecode. |
721 // to check that the object has not been unlocked by an explicit monitorexit bytecode. |
723 const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); |
722 const Address monitor(rbp, frame::interpreter_frame_initial_sp_offset * wordSize - (int)sizeof(BasicObjectLock)); |
724 leal (rdx, monitor); // address of first monitor |
723 lea (rdx, monitor); // address of first monitor |
725 |
724 |
726 movl (rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); |
725 movptr (rax, Address(rdx, BasicObjectLock::obj_offset_in_bytes())); |
727 testl (rax, rax); |
726 testptr(rax, rax); |
728 jcc (Assembler::notZero, unlock); |
727 jcc (Assembler::notZero, unlock); |
729 |
728 |
730 pop(state); |
729 pop(state); |
731 if (throw_monitor_exception) { |
730 if (throw_monitor_exception) { |
732 empty_FPU_stack(); // remove possible return value from FPU-stack, otherwise stack could overflow |
731 empty_FPU_stack(); // remove possible return value from FPU-stack, otherwise stack could overflow |
733 |
732 |
810 } else { |
809 } else { |
811 notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA |
810 notify_method_exit(state, SkipNotifyJVMTI); // preserve TOSCA |
812 } |
811 } |
813 |
812 |
814 // remove activation |
813 // remove activation |
815 movl(rbx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp |
814 movptr(rbx, Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize)); // get sender sp |
816 leave(); // remove frame anchor |
815 leave(); // remove frame anchor |
817 popl(ret_addr); // get return address |
816 pop(ret_addr); // get return address |
818 movl(rsp, rbx); // set sp to sender sp |
817 mov(rsp, rbx); // set sp to sender sp |
819 if (UseSSE) { |
818 if (UseSSE) { |
820 // float and double are returned in xmm register in SSE-mode |
819 // float and double are returned in xmm register in SSE-mode |
821 if (state == ftos && UseSSE >= 1) { |
820 if (state == ftos && UseSSE >= 1) { |
822 subl(rsp, wordSize); |
821 subptr(rsp, wordSize); |
823 fstp_s(Address(rsp, 0)); |
822 fstp_s(Address(rsp, 0)); |
824 movflt(xmm0, Address(rsp, 0)); |
823 movflt(xmm0, Address(rsp, 0)); |
825 addl(rsp, wordSize); |
824 addptr(rsp, wordSize); |
826 } else if (state == dtos && UseSSE >= 2) { |
825 } else if (state == dtos && UseSSE >= 2) { |
827 subl(rsp, 2*wordSize); |
826 subptr(rsp, 2*wordSize); |
828 fstp_d(Address(rsp, 0)); |
827 fstp_d(Address(rsp, 0)); |
829 movdbl(xmm0, Address(rsp, 0)); |
828 movdbl(xmm0, Address(rsp, 0)); |
830 addl(rsp, 2*wordSize); |
829 addptr(rsp, 2*wordSize); |
831 } |
830 } |
832 } |
831 } |
833 } |
832 } |
834 |
833 |
835 #endif /* !CC_INTERP */ |
834 #endif /* !CC_INTERP */ |
856 const int mark_offset = lock_offset + BasicLock::displaced_header_offset_in_bytes(); |
855 const int mark_offset = lock_offset + BasicLock::displaced_header_offset_in_bytes(); |
857 |
856 |
858 Label slow_case; |
857 Label slow_case; |
859 |
858 |
860 // Load object pointer into obj_reg %rcx |
859 // Load object pointer into obj_reg %rcx |
861 movl(obj_reg, Address(lock_reg, obj_offset)); |
860 movptr(obj_reg, Address(lock_reg, obj_offset)); |
862 |
861 |
863 if (UseBiasedLocking) { |
862 if (UseBiasedLocking) { |
864 // Note: we use noreg for the temporary register since it's hard |
863 // Note: we use noreg for the temporary register since it's hard |
865 // to come up with a free register on all incoming code paths |
864 // to come up with a free register on all incoming code paths |
866 biased_locking_enter(lock_reg, obj_reg, swap_reg, noreg, false, done, &slow_case); |
865 biased_locking_enter(lock_reg, obj_reg, swap_reg, noreg, false, done, &slow_case); |
867 } |
866 } |
868 |
867 |
869 // Load immediate 1 into swap_reg %rax, |
868 // Load immediate 1 into swap_reg %rax, |
870 movl(swap_reg, 1); |
869 movptr(swap_reg, (int32_t)1); |
871 |
870 |
872 // Load (object->mark() | 1) into swap_reg %rax, |
871 // Load (object->mark() | 1) into swap_reg %rax, |
873 orl(swap_reg, Address(obj_reg, 0)); |
872 orptr(swap_reg, Address(obj_reg, 0)); |
874 |
873 |
875 // Save (object->mark() | 1) into BasicLock's displaced header |
874 // Save (object->mark() | 1) into BasicLock's displaced header |
876 movl(Address(lock_reg, mark_offset), swap_reg); |
875 movptr(Address(lock_reg, mark_offset), swap_reg); |
877 |
876 |
878 assert(lock_offset == 0, "displached header must be first word in BasicObjectLock"); |
877 assert(lock_offset == 0, "displached header must be first word in BasicObjectLock"); |
879 if (os::is_MP()) { |
878 if (os::is_MP()) { |
880 lock(); |
879 lock(); |
881 } |
880 } |
882 cmpxchg(lock_reg, Address(obj_reg, 0)); |
881 cmpxchgptr(lock_reg, Address(obj_reg, 0)); |
883 if (PrintBiasedLockingStatistics) { |
882 if (PrintBiasedLockingStatistics) { |
884 cond_inc32(Assembler::zero, |
883 cond_inc32(Assembler::zero, |
885 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); |
884 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); |
886 } |
885 } |
887 jcc(Assembler::zero, done); |
886 jcc(Assembler::zero, done); |
893 // These 3 tests can be done by evaluating the following |
892 // These 3 tests can be done by evaluating the following |
894 // expression: ((mark - rsp) & (3 - os::vm_page_size())), |
893 // expression: ((mark - rsp) & (3 - os::vm_page_size())), |
895 // assuming both stack pointer and pagesize have their |
894 // assuming both stack pointer and pagesize have their |
896 // least significant 2 bits clear. |
895 // least significant 2 bits clear. |
897 // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg |
896 // NOTE: the oopMark is in swap_reg %rax, as the result of cmpxchg |
898 subl(swap_reg, rsp); |
897 subptr(swap_reg, rsp); |
899 andl(swap_reg, 3 - os::vm_page_size()); |
898 andptr(swap_reg, 3 - os::vm_page_size()); |
900 |
899 |
901 // Save the test result, for recursive case, the result is zero |
900 // Save the test result, for recursive case, the result is zero |
902 movl(Address(lock_reg, mark_offset), swap_reg); |
901 movptr(Address(lock_reg, mark_offset), swap_reg); |
903 |
902 |
904 if (PrintBiasedLockingStatistics) { |
903 if (PrintBiasedLockingStatistics) { |
905 cond_inc32(Assembler::zero, |
904 cond_inc32(Assembler::zero, |
906 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); |
905 ExternalAddress((address) BiasedLocking::fast_path_entry_count_addr())); |
907 } |
906 } |
937 |
936 |
938 save_bcp(); // Save in case of exception |
937 save_bcp(); // Save in case of exception |
939 |
938 |
940 // Convert from BasicObjectLock structure to object and BasicLock structure |
939 // Convert from BasicObjectLock structure to object and BasicLock structure |
941 // Store the BasicLock address into %rax, |
940 // Store the BasicLock address into %rax, |
942 leal(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); |
941 lea(swap_reg, Address(lock_reg, BasicObjectLock::lock_offset_in_bytes())); |
943 |
942 |
944 // Load oop into obj_reg(%rcx) |
943 // Load oop into obj_reg(%rcx) |
945 movl(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ())); |
944 movptr(obj_reg, Address(lock_reg, BasicObjectLock::obj_offset_in_bytes ())); |
946 |
945 |
947 // Free entry |
946 // Free entry |
948 movl(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), NULL_WORD); |
947 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), (int32_t)NULL_WORD); |
949 |
948 |
950 if (UseBiasedLocking) { |
949 if (UseBiasedLocking) { |
951 biased_locking_exit(obj_reg, header_reg, done); |
950 biased_locking_exit(obj_reg, header_reg, done); |
952 } |
951 } |
953 |
952 |
954 // Load the old header from BasicLock structure |
953 // Load the old header from BasicLock structure |
955 movl(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes())); |
954 movptr(header_reg, Address(swap_reg, BasicLock::displaced_header_offset_in_bytes())); |
956 |
955 |
957 // Test for recursion |
956 // Test for recursion |
958 testl(header_reg, header_reg); |
957 testptr(header_reg, header_reg); |
959 |
958 |
960 // zero for recursive case |
959 // zero for recursive case |
961 jcc(Assembler::zero, done); |
960 jcc(Assembler::zero, done); |
962 |
961 |
963 // Atomic swap back the old header |
962 // Atomic swap back the old header |
964 if (os::is_MP()) lock(); |
963 if (os::is_MP()) lock(); |
965 cmpxchg(header_reg, Address(obj_reg, 0)); |
964 cmpxchgptr(header_reg, Address(obj_reg, 0)); |
966 |
965 |
967 // zero for recursive case |
966 // zero for recursive case |
968 jcc(Assembler::zero, done); |
967 jcc(Assembler::zero, done); |
969 |
968 |
970 // Call the runtime routine for slow case. |
969 // Call the runtime routine for slow case. |
971 movl(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj |
970 movptr(Address(lock_reg, BasicObjectLock::obj_offset_in_bytes()), obj_reg); // restore obj |
972 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); |
971 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::monitorexit), lock_reg); |
973 |
972 |
974 bind(done); |
973 bind(done); |
975 |
974 |
976 restore_bcp(); |
975 restore_bcp(); |
981 #ifndef CC_INTERP |
980 #ifndef CC_INTERP |
982 |
981 |
983 // Test ImethodDataPtr. If it is null, continue at the specified label |
982 // Test ImethodDataPtr. If it is null, continue at the specified label |
984 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& zero_continue) { |
983 void InterpreterMacroAssembler::test_method_data_pointer(Register mdp, Label& zero_continue) { |
985 assert(ProfileInterpreter, "must be profiling interpreter"); |
984 assert(ProfileInterpreter, "must be profiling interpreter"); |
986 movl(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); |
985 movptr(mdp, Address(rbp, frame::interpreter_frame_mdx_offset * wordSize)); |
987 testl(mdp, mdp); |
986 testptr(mdp, mdp); |
988 jcc(Assembler::zero, zero_continue); |
987 jcc(Assembler::zero, zero_continue); |
989 } |
988 } |
990 |
989 |
991 |
990 |
992 // Set the method data pointer for the current bcp. |
991 // Set the method data pointer for the current bcp. |
993 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { |
992 void InterpreterMacroAssembler::set_method_data_pointer_for_bcp() { |
994 assert(ProfileInterpreter, "must be profiling interpreter"); |
993 assert(ProfileInterpreter, "must be profiling interpreter"); |
995 Label zero_continue; |
994 Label zero_continue; |
996 pushl(rax); |
995 push(rax); |
997 pushl(rbx); |
996 push(rbx); |
998 |
997 |
999 get_method(rbx); |
998 get_method(rbx); |
1000 // Test MDO to avoid the call if it is NULL. |
999 // Test MDO to avoid the call if it is NULL. |
1001 movl(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
1000 movptr(rax, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
1002 testl(rax, rax); |
1001 testptr(rax, rax); |
1003 jcc(Assembler::zero, zero_continue); |
1002 jcc(Assembler::zero, zero_continue); |
1004 |
1003 |
1005 // rbx,: method |
1004 // rbx,: method |
1006 // rsi: bcp |
1005 // rsi: bcp |
1007 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, rsi); |
1006 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::bcp_to_di), rbx, rsi); |
1008 // rax,: mdi |
1007 // rax,: mdi |
1009 |
1008 |
1010 movl(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
1009 movptr(rbx, Address(rbx, in_bytes(methodOopDesc::method_data_offset()))); |
1011 testl(rbx, rbx); |
1010 testptr(rbx, rbx); |
1012 jcc(Assembler::zero, zero_continue); |
1011 jcc(Assembler::zero, zero_continue); |
1013 addl(rbx, in_bytes(methodDataOopDesc::data_offset())); |
1012 addptr(rbx, in_bytes(methodDataOopDesc::data_offset())); |
1014 addl(rbx, rax); |
1013 addptr(rbx, rax); |
1015 movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); |
1014 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), rbx); |
1016 |
1015 |
1017 bind(zero_continue); |
1016 bind(zero_continue); |
1018 popl(rbx); |
1017 pop(rbx); |
1019 popl(rax); |
1018 pop(rax); |
1020 } |
1019 } |
1021 |
1020 |
1022 void InterpreterMacroAssembler::verify_method_data_pointer() { |
1021 void InterpreterMacroAssembler::verify_method_data_pointer() { |
1023 assert(ProfileInterpreter, "must be profiling interpreter"); |
1022 assert(ProfileInterpreter, "must be profiling interpreter"); |
1024 #ifdef ASSERT |
1023 #ifdef ASSERT |
1025 Label verify_continue; |
1024 Label verify_continue; |
1026 pushl(rax); |
1025 push(rax); |
1027 pushl(rbx); |
1026 push(rbx); |
1028 pushl(rcx); |
1027 push(rcx); |
1029 pushl(rdx); |
1028 push(rdx); |
1030 test_method_data_pointer(rcx, verify_continue); // If mdp is zero, continue |
1029 test_method_data_pointer(rcx, verify_continue); // If mdp is zero, continue |
1031 get_method(rbx); |
1030 get_method(rbx); |
1032 |
1031 |
1033 // If the mdp is valid, it will point to a DataLayout header which is |
1032 // If the mdp is valid, it will point to a DataLayout header which is |
1034 // consistent with the bcp. The converse is highly probable also. |
1033 // consistent with the bcp. The converse is highly probable also. |
1035 load_unsigned_word(rdx, Address(rcx, in_bytes(DataLayout::bci_offset()))); |
1034 load_unsigned_word(rdx, Address(rcx, in_bytes(DataLayout::bci_offset()))); |
1036 addl(rdx, Address(rbx, methodOopDesc::const_offset())); |
1035 addptr(rdx, Address(rbx, methodOopDesc::const_offset())); |
1037 leal(rdx, Address(rdx, constMethodOopDesc::codes_offset())); |
1036 lea(rdx, Address(rdx, constMethodOopDesc::codes_offset())); |
1038 cmpl(rdx, rsi); |
1037 cmpptr(rdx, rsi); |
1039 jcc(Assembler::equal, verify_continue); |
1038 jcc(Assembler::equal, verify_continue); |
1040 // rbx,: method |
1039 // rbx,: method |
1041 // rsi: bcp |
1040 // rsi: bcp |
1042 // rcx: mdp |
1041 // rcx: mdp |
1043 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), rbx, rsi, rcx); |
1042 call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::verify_mdp), rbx, rsi, rcx); |
1044 bind(verify_continue); |
1043 bind(verify_continue); |
1045 popl(rdx); |
1044 pop(rdx); |
1046 popl(rcx); |
1045 pop(rcx); |
1047 popl(rbx); |
1046 pop(rbx); |
1048 popl(rax); |
1047 pop(rax); |
1049 #endif // ASSERT |
1048 #endif // ASSERT |
1050 } |
1049 } |
1051 |
1050 |
1052 |
1051 |
1053 void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, int constant, Register value) { |
1052 void InterpreterMacroAssembler::set_mdp_data_at(Register mdp_in, int constant, Register value) { |
|
1053 // %%% this seems to be used to store counter data which is surely 32bits |
|
1054 // however 64bit side stores 64 bits which seems wrong |
1054 assert(ProfileInterpreter, "must be profiling interpreter"); |
1055 assert(ProfileInterpreter, "must be profiling interpreter"); |
1055 Address data(mdp_in, constant); |
1056 Address data(mdp_in, constant); |
1056 movl(data, value); |
1057 movptr(data, value); |
1057 } |
1058 } |
1058 |
1059 |
1059 |
1060 |
1060 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, |
1061 void InterpreterMacroAssembler::increment_mdp_data_at(Register mdp_in, |
1061 int constant, |
1062 int constant, |
1117 Register value, |
1119 Register value, |
1118 Register test_value_out, |
1120 Register test_value_out, |
1119 Label& not_equal_continue) { |
1121 Label& not_equal_continue) { |
1120 assert(ProfileInterpreter, "must be profiling interpreter"); |
1122 assert(ProfileInterpreter, "must be profiling interpreter"); |
1121 if (test_value_out == noreg) { |
1123 if (test_value_out == noreg) { |
1122 cmpl(value, Address(mdp_in, offset)); |
1124 cmpptr(value, Address(mdp_in, offset)); |
1123 } else { |
1125 } else { |
1124 // Put the test value into a register, so caller can use it: |
1126 // Put the test value into a register, so caller can use it: |
1125 movl(test_value_out, Address(mdp_in, offset)); |
1127 movptr(test_value_out, Address(mdp_in, offset)); |
1126 cmpl(test_value_out, value); |
1128 cmpptr(test_value_out, value); |
1127 } |
1129 } |
1128 jcc(Assembler::notEqual, not_equal_continue); |
1130 jcc(Assembler::notEqual, not_equal_continue); |
1129 } |
1131 } |
1130 |
1132 |
1131 |
1133 |
1132 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { |
1134 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, int offset_of_disp) { |
1133 assert(ProfileInterpreter, "must be profiling interpreter"); |
1135 assert(ProfileInterpreter, "must be profiling interpreter"); |
1134 Address disp_address(mdp_in, offset_of_disp); |
1136 Address disp_address(mdp_in, offset_of_disp); |
1135 addl(mdp_in,disp_address); |
1137 addptr(mdp_in,disp_address); |
1136 movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1138 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1137 } |
1139 } |
1138 |
1140 |
1139 |
1141 |
1140 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp) { |
1142 void InterpreterMacroAssembler::update_mdp_by_offset(Register mdp_in, Register reg, int offset_of_disp) { |
1141 assert(ProfileInterpreter, "must be profiling interpreter"); |
1143 assert(ProfileInterpreter, "must be profiling interpreter"); |
1142 Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); |
1144 Address disp_address(mdp_in, reg, Address::times_1, offset_of_disp); |
1143 addl(mdp_in, disp_address); |
1145 addptr(mdp_in, disp_address); |
1144 movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1146 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1145 } |
1147 } |
1146 |
1148 |
1147 |
1149 |
1148 void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { |
1150 void InterpreterMacroAssembler::update_mdp_by_constant(Register mdp_in, int constant) { |
1149 assert(ProfileInterpreter, "must be profiling interpreter"); |
1151 assert(ProfileInterpreter, "must be profiling interpreter"); |
1150 addl(mdp_in, constant); |
1152 addptr(mdp_in, constant); |
1151 movl(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1153 movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp_in); |
1152 } |
1154 } |
1153 |
1155 |
1154 |
1156 |
1155 void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { |
1157 void InterpreterMacroAssembler::update_mdp_for_ret(Register return_bci) { |
1156 assert(ProfileInterpreter, "must be profiling interpreter"); |
1158 assert(ProfileInterpreter, "must be profiling interpreter"); |
1157 pushl(return_bci); // save/restore across call_VM |
1159 push(return_bci); // save/restore across call_VM |
1158 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci); |
1160 call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::update_mdp_for_ret), return_bci); |
1159 popl(return_bci); |
1161 pop(return_bci); |
1160 } |
1162 } |
1161 |
1163 |
1162 |
1164 |
1163 void InterpreterMacroAssembler::profile_taken_branch(Register mdp, Register bumped_count) { |
1165 void InterpreterMacroAssembler::profile_taken_branch(Register mdp, Register bumped_count) { |
1164 if (ProfileInterpreter) { |
1166 if (ProfileInterpreter) { |