263 } |
263 } |
264 } |
264 } |
265 |
265 |
266 // Java Expression Stack |
266 // Java Expression Stack |
267 |
267 |
268 #ifdef ASSERT |
|
269 void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t) { |
|
270 if (TaggedStackInterpreter) { |
|
271 Label okay; |
|
272 cmpptr(Address(rsp, wordSize), (int32_t)t); |
|
273 jcc(Assembler::equal, okay); |
|
274 // Also compare if the stack value is zero, then the tag might |
|
275 // not have been set coming from deopt. |
|
276 cmpptr(Address(rsp, 0), 0); |
|
277 jcc(Assembler::equal, okay); |
|
278 stop("Java Expression stack tag value is bad"); |
|
279 bind(okay); |
|
280 } |
|
281 } |
|
282 #endif // ASSERT |
|
283 |
|
284 void InterpreterMacroAssembler::pop_ptr(Register r) { |
268 void InterpreterMacroAssembler::pop_ptr(Register r) { |
285 debug_only(verify_stack_tag(frame::TagReference)); |
|
286 pop(r); |
269 pop(r); |
287 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
270 } |
288 } |
271 |
289 |
272 void InterpreterMacroAssembler::pop_i(Register r) { |
290 void InterpreterMacroAssembler::pop_ptr(Register r, Register tag) { |
|
291 pop(r); |
273 pop(r); |
292 // Tag may not be reference for jsr, can be returnAddress |
|
293 if (TaggedStackInterpreter) pop(tag); |
|
294 } |
|
295 |
|
296 void InterpreterMacroAssembler::pop_i(Register r) { |
|
297 debug_only(verify_stack_tag(frame::TagValue)); |
|
298 pop(r); |
|
299 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
|
300 } |
274 } |
301 |
275 |
302 void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { |
276 void InterpreterMacroAssembler::pop_l(Register lo, Register hi) { |
303 debug_only(verify_stack_tag(frame::TagValue)); |
|
304 pop(lo); |
277 pop(lo); |
305 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
|
306 debug_only(verify_stack_tag(frame::TagValue)); |
|
307 pop(hi); |
278 pop(hi); |
308 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
|
309 } |
279 } |
310 |
280 |
311 void InterpreterMacroAssembler::pop_f() { |
281 void InterpreterMacroAssembler::pop_f() { |
312 debug_only(verify_stack_tag(frame::TagValue)); |
|
313 fld_s(Address(rsp, 0)); |
282 fld_s(Address(rsp, 0)); |
314 addptr(rsp, 1 * wordSize); |
283 addptr(rsp, 1 * wordSize); |
315 if (TaggedStackInterpreter) addptr(rsp, 1 * wordSize); |
|
316 } |
284 } |
317 |
285 |
318 void InterpreterMacroAssembler::pop_d() { |
286 void InterpreterMacroAssembler::pop_d() { |
319 // Write double to stack contiguously and load into ST0 |
|
320 pop_dtos_to_rsp(); |
|
321 fld_d(Address(rsp, 0)); |
287 fld_d(Address(rsp, 0)); |
322 addptr(rsp, 2 * wordSize); |
288 addptr(rsp, 2 * wordSize); |
323 } |
289 } |
324 |
290 |
325 |
|
326 // Pop the top of the java expression stack to execution stack (which |
|
327 // happens to be the same place). |
|
328 void InterpreterMacroAssembler::pop_dtos_to_rsp() { |
|
329 if (TaggedStackInterpreter) { |
|
330 // Pop double value into scratch registers |
|
331 debug_only(verify_stack_tag(frame::TagValue)); |
|
332 pop(rax); |
|
333 addptr(rsp, 1* wordSize); |
|
334 debug_only(verify_stack_tag(frame::TagValue)); |
|
335 pop(rdx); |
|
336 addptr(rsp, 1* wordSize); |
|
337 push(rdx); |
|
338 push(rax); |
|
339 } |
|
340 } |
|
341 |
|
342 void InterpreterMacroAssembler::pop_ftos_to_rsp() { |
|
343 if (TaggedStackInterpreter) { |
|
344 debug_only(verify_stack_tag(frame::TagValue)); |
|
345 pop(rax); |
|
346 addptr(rsp, 1 * wordSize); |
|
347 push(rax); // ftos is at rsp |
|
348 } |
|
349 } |
|
350 |
291 |
351 void InterpreterMacroAssembler::pop(TosState state) { |
292 void InterpreterMacroAssembler::pop(TosState state) { |
352 switch (state) { |
293 switch (state) { |
353 case atos: pop_ptr(rax); break; |
294 case atos: pop_ptr(rax); break; |
354 case btos: // fall through |
295 case btos: // fall through |
363 } |
304 } |
364 verify_oop(rax, state); |
305 verify_oop(rax, state); |
365 } |
306 } |
366 |
307 |
367 void InterpreterMacroAssembler::push_ptr(Register r) { |
308 void InterpreterMacroAssembler::push_ptr(Register r) { |
368 if (TaggedStackInterpreter) push(frame::TagReference); |
|
369 push(r); |
309 push(r); |
370 } |
310 } |
371 |
311 |
372 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { |
312 void InterpreterMacroAssembler::push_i(Register r) { |
373 if (TaggedStackInterpreter) push(tag); // tag first |
|
374 push(r); |
313 push(r); |
375 } |
314 } |
376 |
315 |
377 void InterpreterMacroAssembler::push_i(Register r) { |
|
378 if (TaggedStackInterpreter) push(frame::TagValue); |
|
379 push(r); |
|
380 } |
|
381 |
|
382 void InterpreterMacroAssembler::push_l(Register lo, Register hi) { |
316 void InterpreterMacroAssembler::push_l(Register lo, Register hi) { |
383 if (TaggedStackInterpreter) push(frame::TagValue); |
|
384 push(hi); |
317 push(hi); |
385 if (TaggedStackInterpreter) push(frame::TagValue); |
|
386 push(lo); |
318 push(lo); |
387 } |
319 } |
388 |
320 |
389 void InterpreterMacroAssembler::push_f() { |
321 void InterpreterMacroAssembler::push_f() { |
390 if (TaggedStackInterpreter) push(frame::TagValue); |
|
391 // Do not schedule for no AGI! Never write beyond rsp! |
322 // Do not schedule for no AGI! Never write beyond rsp! |
392 subptr(rsp, 1 * wordSize); |
323 subptr(rsp, 1 * wordSize); |
393 fstp_s(Address(rsp, 0)); |
324 fstp_s(Address(rsp, 0)); |
394 } |
325 } |
395 |
326 |
396 void InterpreterMacroAssembler::push_d(Register r) { |
327 void InterpreterMacroAssembler::push_d(Register r) { |
397 if (TaggedStackInterpreter) { |
328 // Do not schedule for no AGI! Never write beyond rsp! |
398 // Double values are stored as: |
329 subptr(rsp, 2 * wordSize); |
399 // tag |
330 fstp_d(Address(rsp, 0)); |
400 // high |
|
401 // tag |
|
402 // low |
|
403 push(frame::TagValue); |
|
404 subptr(rsp, 3 * wordSize); |
|
405 fstp_d(Address(rsp, 0)); |
|
406 // move high word up to slot n-1 |
|
407 movl(r, Address(rsp, 1*wordSize)); |
|
408 movl(Address(rsp, 2*wordSize), r); |
|
409 // move tag |
|
410 movl(Address(rsp, 1*wordSize), frame::TagValue); |
|
411 } else { |
|
412 // Do not schedule for no AGI! Never write beyond rsp! |
|
413 subptr(rsp, 2 * wordSize); |
|
414 fstp_d(Address(rsp, 0)); |
|
415 } |
|
416 } |
331 } |
417 |
332 |
418 |
333 |
419 void InterpreterMacroAssembler::push(TosState state) { |
334 void InterpreterMacroAssembler::push(TosState state) { |
420 verify_oop(rax, state); |
335 verify_oop(rax, state); |
431 default : ShouldNotReachHere(); |
346 default : ShouldNotReachHere(); |
432 } |
347 } |
433 } |
348 } |
434 |
349 |
435 |
350 |
436 // Tagged stack helpers for swap and dup |
351 // Helpers for swap and dup |
437 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, |
352 void InterpreterMacroAssembler::load_ptr(int n, Register val) { |
438 Register tag) { |
|
439 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); |
353 movptr(val, Address(rsp, Interpreter::expr_offset_in_bytes(n))); |
440 if (TaggedStackInterpreter) { |
354 } |
441 movptr(tag, Address(rsp, Interpreter::expr_tag_offset_in_bytes(n))); |
355 |
442 } |
356 void InterpreterMacroAssembler::store_ptr(int n, Register val) { |
443 } |
|
444 |
|
445 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, |
|
446 Register tag) { |
|
447 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); |
357 movptr(Address(rsp, Interpreter::expr_offset_in_bytes(n)), val); |
448 if (TaggedStackInterpreter) { |
358 } |
449 movptr(Address(rsp, Interpreter::expr_tag_offset_in_bytes(n)), tag); |
|
450 } |
|
451 } |
|
452 |
|
453 |
|
454 // Tagged local support |
|
455 void InterpreterMacroAssembler::tag_local(frame::Tag tag, int n) { |
|
456 if (TaggedStackInterpreter) { |
|
457 if (tag == frame::TagCategory2) { |
|
458 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)frame::TagValue); |
|
459 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)frame::TagValue); |
|
460 } else { |
|
461 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)tag); |
|
462 } |
|
463 } |
|
464 } |
|
465 |
|
466 void InterpreterMacroAssembler::tag_local(frame::Tag tag, Register idx) { |
|
467 if (TaggedStackInterpreter) { |
|
468 if (tag == frame::TagCategory2) { |
|
469 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
|
470 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)frame::TagValue); |
|
471 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
|
472 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)frame::TagValue); |
|
473 } else { |
|
474 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
|
475 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)tag); |
|
476 } |
|
477 } |
|
478 } |
|
479 |
|
480 void InterpreterMacroAssembler::tag_local(Register tag, Register idx) { |
|
481 if (TaggedStackInterpreter) { |
|
482 // can only be TagValue or TagReference |
|
483 movptr(Address(rdi, idx, Interpreter::stackElementScale(), |
|
484 Interpreter::local_tag_offset_in_bytes(0)), tag); |
|
485 } |
|
486 } |
|
487 |
|
488 |
|
489 void InterpreterMacroAssembler::tag_local(Register tag, int n) { |
|
490 if (TaggedStackInterpreter) { |
|
491 // can only be TagValue or TagReference |
|
492 movptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), tag); |
|
493 } |
|
494 } |
|
495 |
|
496 #ifdef ASSERT |
|
497 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, int n) { |
|
498 if (TaggedStackInterpreter) { |
|
499 frame::Tag t = tag; |
|
500 if (tag == frame::TagCategory2) { |
|
501 Label nbl; |
|
502 t = frame::TagValue; // change to what is stored in locals |
|
503 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n+1)), (int32_t)t); |
|
504 jcc(Assembler::equal, nbl); |
|
505 stop("Local tag is bad for long/double"); |
|
506 bind(nbl); |
|
507 } |
|
508 Label notBad; |
|
509 cmpptr(Address(rdi, Interpreter::local_tag_offset_in_bytes(n)), (int32_t)t); |
|
510 jcc(Assembler::equal, notBad); |
|
511 // Also compare if the local value is zero, then the tag might |
|
512 // not have been set coming from deopt. |
|
513 cmpptr(Address(rdi, Interpreter::local_offset_in_bytes(n)), 0); |
|
514 jcc(Assembler::equal, notBad); |
|
515 stop("Local tag is bad"); |
|
516 bind(notBad); |
|
517 } |
|
518 } |
|
519 |
|
520 void InterpreterMacroAssembler::verify_local_tag(frame::Tag tag, Register idx) { |
|
521 if (TaggedStackInterpreter) { |
|
522 frame::Tag t = tag; |
|
523 if (tag == frame::TagCategory2) { |
|
524 Label nbl; |
|
525 t = frame::TagValue; // change to what is stored in locals |
|
526 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), |
|
527 Interpreter::local_tag_offset_in_bytes(1)), (int32_t)t); |
|
528 jcc(Assembler::equal, nbl); |
|
529 stop("Local tag is bad for long/double"); |
|
530 bind(nbl); |
|
531 } |
|
532 Label notBad; |
|
533 cmpl(Address(rdi, idx, Interpreter::stackElementScale(), |
|
534 Interpreter::local_tag_offset_in_bytes(0)), (int32_t)t); |
|
535 jcc(Assembler::equal, notBad); |
|
536 // Also compare if the local value is zero, then the tag might |
|
537 // not have been set coming from deopt. |
|
538 cmpptr(Address(rdi, idx, Interpreter::stackElementScale(), |
|
539 Interpreter::local_offset_in_bytes(0)), 0); |
|
540 jcc(Assembler::equal, notBad); |
|
541 stop("Local tag is bad"); |
|
542 bind(notBad); |
|
543 |
|
544 } |
|
545 } |
|
546 #endif // ASSERT |
|
547 |
359 |
548 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { |
360 void InterpreterMacroAssembler::super_call_VM_leaf(address entry_point) { |
549 MacroAssembler::call_VM_leaf_base(entry_point, 0); |
361 MacroAssembler::call_VM_leaf_base(entry_point, 0); |
550 } |
362 } |
551 |
363 |