Mercurial > hg > truffle
comparison src/cpu/sparc/vm/interp_masm_sparc.cpp @ 1506:2338d41fbd81
6943304: remove tagged stack interpreter
Reviewed-by: coleenp, never, gbenson
author | twisti |
---|---|
date | Fri, 30 Apr 2010 08:37:24 -0700 |
parents | c640000b7cc1 |
children | c18cbe5936b8 ab102d5d923e |
comparison
equal
deleted
inserted
replaced
1505:0c5b3cf3c1f5 | 1506:2338d41fbd81 |
---|---|
48 void InterpreterMacroAssembler::compute_extra_locals_size_in_bytes(Register args_size, Register locals_size, Register delta) { | 48 void InterpreterMacroAssembler::compute_extra_locals_size_in_bytes(Register args_size, Register locals_size, Register delta) { |
49 // Note: this algorithm is also used by C1's OSR entry sequence. | 49 // Note: this algorithm is also used by C1's OSR entry sequence. |
50 // Any changes should also be applied to CodeEmitter::emit_osr_entry(). | 50 // Any changes should also be applied to CodeEmitter::emit_osr_entry(). |
51 assert_different_registers(args_size, locals_size); | 51 assert_different_registers(args_size, locals_size); |
52 // max_locals*2 for TAGS. Assumes that args_size has already been adjusted. | 52 // max_locals*2 for TAGS. Assumes that args_size has already been adjusted. |
53 if (TaggedStackInterpreter) sll(locals_size, 1, locals_size); | |
54 subcc(locals_size, args_size, delta);// extra space for non-arguments locals in words | 53 subcc(locals_size, args_size, delta);// extra space for non-arguments locals in words |
55 // Use br/mov combination because it works on both V8 and V9 and is | 54 // Use br/mov combination because it works on both V8 and V9 and is |
56 // faster. | 55 // faster. |
57 Label skip_move; | 56 Label skip_move; |
58 br(Assembler::negative, true, Assembler::pt, skip_move); | 57 br(Assembler::negative, true, Assembler::pt, skip_move); |
317 | 316 |
318 #ifdef _LP64 | 317 #ifdef _LP64 |
319 ldf(FloatRegisterImpl::D, r1, offset, d); | 318 ldf(FloatRegisterImpl::D, r1, offset, d); |
320 #else | 319 #else |
321 ldf(FloatRegisterImpl::S, r1, offset, d); | 320 ldf(FloatRegisterImpl::S, r1, offset, d); |
322 ldf(FloatRegisterImpl::S, r1, offset + Interpreter::stackElementSize(), d->successor()); | 321 ldf(FloatRegisterImpl::S, r1, offset + Interpreter::stackElementSize, d->successor()); |
323 #endif | 322 #endif |
324 } | 323 } |
325 | 324 |
326 // Known good alignment in _LP64 but unknown otherwise | 325 // Known good alignment in _LP64 but unknown otherwise |
327 void InterpreterMacroAssembler::store_unaligned_double(FloatRegister d, Register r1, int offset) { | 326 void InterpreterMacroAssembler::store_unaligned_double(FloatRegister d, Register r1, int offset) { |
328 assert_not_delayed(); | 327 assert_not_delayed(); |
329 | 328 |
330 #ifdef _LP64 | 329 #ifdef _LP64 |
331 stf(FloatRegisterImpl::D, d, r1, offset); | 330 stf(FloatRegisterImpl::D, d, r1, offset); |
332 // store something more useful here | 331 // store something more useful here |
333 debug_only(stx(G0, r1, offset+Interpreter::stackElementSize());) | 332 debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);) |
334 #else | 333 #else |
335 stf(FloatRegisterImpl::S, d, r1, offset); | 334 stf(FloatRegisterImpl::S, d, r1, offset); |
336 stf(FloatRegisterImpl::S, d->successor(), r1, offset + Interpreter::stackElementSize()); | 335 stf(FloatRegisterImpl::S, d->successor(), r1, offset + Interpreter::stackElementSize); |
337 #endif | 336 #endif |
338 } | 337 } |
339 | 338 |
340 | 339 |
341 // Known good alignment in _LP64 but unknown otherwise | 340 // Known good alignment in _LP64 but unknown otherwise |
343 assert_not_delayed(); | 342 assert_not_delayed(); |
344 #ifdef _LP64 | 343 #ifdef _LP64 |
345 ldx(r1, offset, rd); | 344 ldx(r1, offset, rd); |
346 #else | 345 #else |
347 ld(r1, offset, rd); | 346 ld(r1, offset, rd); |
348 ld(r1, offset + Interpreter::stackElementSize(), rd->successor()); | 347 ld(r1, offset + Interpreter::stackElementSize, rd->successor()); |
349 #endif | 348 #endif |
350 } | 349 } |
351 | 350 |
352 // Known good alignment in _LP64 but unknown otherwise | 351 // Known good alignment in _LP64 but unknown otherwise |
353 void InterpreterMacroAssembler::store_unaligned_long(Register l, Register r1, int offset) { | 352 void InterpreterMacroAssembler::store_unaligned_long(Register l, Register r1, int offset) { |
354 assert_not_delayed(); | 353 assert_not_delayed(); |
355 | 354 |
356 #ifdef _LP64 | 355 #ifdef _LP64 |
357 stx(l, r1, offset); | 356 stx(l, r1, offset); |
358 // store something more useful here | 357 // store something more useful here |
359 debug_only(stx(G0, r1, offset+Interpreter::stackElementSize());) | 358 debug_only(stx(G0, r1, offset+Interpreter::stackElementSize);) |
360 #else | 359 #else |
361 st(l, r1, offset); | 360 st(l, r1, offset); |
362 st(l->successor(), r1, offset + Interpreter::stackElementSize()); | 361 st(l->successor(), r1, offset + Interpreter::stackElementSize); |
363 #endif | 362 #endif |
364 } | 363 } |
365 | |
366 #ifdef ASSERT | |
367 void InterpreterMacroAssembler::verify_stack_tag(frame::Tag t, | |
368 Register r, | |
369 Register scratch) { | |
370 if (TaggedStackInterpreter) { | |
371 Label ok, long_ok; | |
372 ld_ptr(Lesp, Interpreter::expr_tag_offset_in_bytes(0), r); | |
373 if (t == frame::TagCategory2) { | |
374 cmp(r, G0); | |
375 brx(Assembler::equal, false, Assembler::pt, long_ok); | |
376 delayed()->ld_ptr(Lesp, Interpreter::expr_tag_offset_in_bytes(1), r); | |
377 stop("stack long/double tag value bad"); | |
378 bind(long_ok); | |
379 cmp(r, G0); | |
380 } else if (t == frame::TagValue) { | |
381 cmp(r, G0); | |
382 } else { | |
383 assert_different_registers(r, scratch); | |
384 mov(t, scratch); | |
385 cmp(r, scratch); | |
386 } | |
387 brx(Assembler::equal, false, Assembler::pt, ok); | |
388 delayed()->nop(); | |
389 // Also compare if the stack value is zero, then the tag might | |
390 // not have been set coming from deopt. | |
391 ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(0), r); | |
392 cmp(r, G0); | |
393 brx(Assembler::equal, false, Assembler::pt, ok); | |
394 delayed()->nop(); | |
395 stop("Stack tag value is bad"); | |
396 bind(ok); | |
397 } | |
398 } | |
399 #endif // ASSERT | |
400 | 364 |
401 void InterpreterMacroAssembler::pop_i(Register r) { | 365 void InterpreterMacroAssembler::pop_i(Register r) { |
402 assert_not_delayed(); | 366 assert_not_delayed(); |
403 // Uses destination register r for scratch | |
404 debug_only(verify_stack_tag(frame::TagValue, r)); | |
405 ld(Lesp, Interpreter::expr_offset_in_bytes(0), r); | 367 ld(Lesp, Interpreter::expr_offset_in_bytes(0), r); |
406 inc(Lesp, Interpreter::stackElementSize()); | 368 inc(Lesp, Interpreter::stackElementSize); |
407 debug_only(verify_esp(Lesp)); | 369 debug_only(verify_esp(Lesp)); |
408 } | 370 } |
409 | 371 |
410 void InterpreterMacroAssembler::pop_ptr(Register r, Register scratch) { | 372 void InterpreterMacroAssembler::pop_ptr(Register r, Register scratch) { |
411 assert_not_delayed(); | 373 assert_not_delayed(); |
412 // Uses destination register r for scratch | |
413 debug_only(verify_stack_tag(frame::TagReference, r, scratch)); | |
414 ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(0), r); | 374 ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(0), r); |
415 inc(Lesp, Interpreter::stackElementSize()); | 375 inc(Lesp, Interpreter::stackElementSize); |
416 debug_only(verify_esp(Lesp)); | 376 debug_only(verify_esp(Lesp)); |
417 } | 377 } |
418 | 378 |
419 void InterpreterMacroAssembler::pop_l(Register r) { | 379 void InterpreterMacroAssembler::pop_l(Register r) { |
420 assert_not_delayed(); | 380 assert_not_delayed(); |
421 // Uses destination register r for scratch | |
422 debug_only(verify_stack_tag(frame::TagCategory2, r)); | |
423 load_unaligned_long(Lesp, Interpreter::expr_offset_in_bytes(0), r); | 381 load_unaligned_long(Lesp, Interpreter::expr_offset_in_bytes(0), r); |
424 inc(Lesp, 2*Interpreter::stackElementSize()); | 382 inc(Lesp, 2*Interpreter::stackElementSize); |
425 debug_only(verify_esp(Lesp)); | 383 debug_only(verify_esp(Lesp)); |
426 } | 384 } |
427 | 385 |
428 | 386 |
429 void InterpreterMacroAssembler::pop_f(FloatRegister f, Register scratch) { | 387 void InterpreterMacroAssembler::pop_f(FloatRegister f, Register scratch) { |
430 assert_not_delayed(); | 388 assert_not_delayed(); |
431 debug_only(verify_stack_tag(frame::TagValue, scratch)); | |
432 ldf(FloatRegisterImpl::S, Lesp, Interpreter::expr_offset_in_bytes(0), f); | 389 ldf(FloatRegisterImpl::S, Lesp, Interpreter::expr_offset_in_bytes(0), f); |
433 inc(Lesp, Interpreter::stackElementSize()); | 390 inc(Lesp, Interpreter::stackElementSize); |
434 debug_only(verify_esp(Lesp)); | 391 debug_only(verify_esp(Lesp)); |
435 } | 392 } |
436 | 393 |
437 | 394 |
438 void InterpreterMacroAssembler::pop_d(FloatRegister f, Register scratch) { | 395 void InterpreterMacroAssembler::pop_d(FloatRegister f, Register scratch) { |
439 assert_not_delayed(); | 396 assert_not_delayed(); |
440 debug_only(verify_stack_tag(frame::TagCategory2, scratch)); | |
441 load_unaligned_double(Lesp, Interpreter::expr_offset_in_bytes(0), f); | 397 load_unaligned_double(Lesp, Interpreter::expr_offset_in_bytes(0), f); |
442 inc(Lesp, 2*Interpreter::stackElementSize()); | 398 inc(Lesp, 2*Interpreter::stackElementSize); |
443 debug_only(verify_esp(Lesp)); | 399 debug_only(verify_esp(Lesp)); |
444 } | 400 } |
445 | 401 |
446 | 402 |
447 // (Note use register first, then decrement so dec can be done during store stall) | |
448 void InterpreterMacroAssembler::tag_stack(Register r) { | |
449 if (TaggedStackInterpreter) { | |
450 st_ptr(r, Lesp, Interpreter::tag_offset_in_bytes()); | |
451 } | |
452 } | |
453 | |
454 void InterpreterMacroAssembler::tag_stack(frame::Tag t, Register r) { | |
455 if (TaggedStackInterpreter) { | |
456 assert (frame::TagValue == 0, "TagValue must be zero"); | |
457 if (t == frame::TagValue) { | |
458 st_ptr(G0, Lesp, Interpreter::tag_offset_in_bytes()); | |
459 } else if (t == frame::TagCategory2) { | |
460 st_ptr(G0, Lesp, Interpreter::tag_offset_in_bytes()); | |
461 // Tag next slot down too | |
462 st_ptr(G0, Lesp, -Interpreter::stackElementSize() + Interpreter::tag_offset_in_bytes()); | |
463 } else { | |
464 assert_different_registers(r, O3); | |
465 mov(t, O3); | |
466 st_ptr(O3, Lesp, Interpreter::tag_offset_in_bytes()); | |
467 } | |
468 } | |
469 } | |
470 | |
471 void InterpreterMacroAssembler::push_i(Register r) { | 403 void InterpreterMacroAssembler::push_i(Register r) { |
472 assert_not_delayed(); | 404 assert_not_delayed(); |
473 debug_only(verify_esp(Lesp)); | 405 debug_only(verify_esp(Lesp)); |
474 tag_stack(frame::TagValue, r); | 406 st(r, Lesp, 0); |
475 st( r, Lesp, Interpreter::value_offset_in_bytes()); | 407 dec(Lesp, Interpreter::stackElementSize); |
476 dec( Lesp, Interpreter::stackElementSize()); | |
477 } | 408 } |
478 | 409 |
479 void InterpreterMacroAssembler::push_ptr(Register r) { | 410 void InterpreterMacroAssembler::push_ptr(Register r) { |
480 assert_not_delayed(); | 411 assert_not_delayed(); |
481 tag_stack(frame::TagReference, r); | 412 st_ptr(r, Lesp, 0); |
482 st_ptr( r, Lesp, Interpreter::value_offset_in_bytes()); | 413 dec(Lesp, Interpreter::stackElementSize); |
483 dec( Lesp, Interpreter::stackElementSize()); | |
484 } | |
485 | |
486 void InterpreterMacroAssembler::push_ptr(Register r, Register tag) { | |
487 assert_not_delayed(); | |
488 tag_stack(tag); | |
489 st_ptr(r, Lesp, Interpreter::value_offset_in_bytes()); | |
490 dec( Lesp, Interpreter::stackElementSize()); | |
491 } | 414 } |
492 | 415 |
493 // remember: our convention for longs in SPARC is: | 416 // remember: our convention for longs in SPARC is: |
494 // O0 (Otos_l1) has high-order part in first word, | 417 // O0 (Otos_l1) has high-order part in first word, |
495 // O1 (Otos_l2) has low-order part in second word | 418 // O1 (Otos_l2) has low-order part in second word |
496 | 419 |
497 void InterpreterMacroAssembler::push_l(Register r) { | 420 void InterpreterMacroAssembler::push_l(Register r) { |
498 assert_not_delayed(); | 421 assert_not_delayed(); |
499 debug_only(verify_esp(Lesp)); | 422 debug_only(verify_esp(Lesp)); |
500 tag_stack(frame::TagCategory2, r); | 423 // Longs are stored in memory-correct order, even if unaligned. |
501 // Longs are in stored in memory-correct order, even if unaligned. | 424 int offset = -Interpreter::stackElementSize; |
502 // and may be separated by stack tags. | |
503 int offset = -Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); | |
504 store_unaligned_long(r, Lesp, offset); | 425 store_unaligned_long(r, Lesp, offset); |
505 dec(Lesp, 2 * Interpreter::stackElementSize()); | 426 dec(Lesp, 2 * Interpreter::stackElementSize); |
506 } | 427 } |
507 | 428 |
508 | 429 |
509 void InterpreterMacroAssembler::push_f(FloatRegister f) { | 430 void InterpreterMacroAssembler::push_f(FloatRegister f) { |
510 assert_not_delayed(); | 431 assert_not_delayed(); |
511 debug_only(verify_esp(Lesp)); | 432 debug_only(verify_esp(Lesp)); |
512 tag_stack(frame::TagValue, Otos_i); | 433 stf(FloatRegisterImpl::S, f, Lesp, 0); |
513 stf(FloatRegisterImpl::S, f, Lesp, Interpreter::value_offset_in_bytes()); | 434 dec(Lesp, Interpreter::stackElementSize); |
514 dec(Lesp, Interpreter::stackElementSize()); | |
515 } | 435 } |
516 | 436 |
517 | 437 |
518 void InterpreterMacroAssembler::push_d(FloatRegister d) { | 438 void InterpreterMacroAssembler::push_d(FloatRegister d) { |
519 assert_not_delayed(); | 439 assert_not_delayed(); |
520 debug_only(verify_esp(Lesp)); | 440 debug_only(verify_esp(Lesp)); |
521 tag_stack(frame::TagCategory2, Otos_i); | 441 // Longs are stored in memory-correct order, even if unaligned. |
522 // Longs are in stored in memory-correct order, even if unaligned. | 442 int offset = -Interpreter::stackElementSize; |
523 // and may be separated by stack tags. | |
524 int offset = -Interpreter::stackElementSize() + Interpreter::value_offset_in_bytes(); | |
525 store_unaligned_double(d, Lesp, offset); | 443 store_unaligned_double(d, Lesp, offset); |
526 dec(Lesp, 2 * Interpreter::stackElementSize()); | 444 dec(Lesp, 2 * Interpreter::stackElementSize); |
527 } | 445 } |
528 | 446 |
529 | 447 |
530 void InterpreterMacroAssembler::push(TosState state) { | 448 void InterpreterMacroAssembler::push(TosState state) { |
531 interp_verify_oop(Otos_i, state, __FILE__, __LINE__); | 449 interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
559 } | 477 } |
560 interp_verify_oop(Otos_i, state, __FILE__, __LINE__); | 478 interp_verify_oop(Otos_i, state, __FILE__, __LINE__); |
561 } | 479 } |
562 | 480 |
563 | 481 |
564 // Tagged stack helpers for swap and dup | 482 // Helpers for swap and dup |
565 void InterpreterMacroAssembler::load_ptr_and_tag(int n, Register val, | 483 void InterpreterMacroAssembler::load_ptr(int n, Register val) { |
566 Register tag) { | |
567 ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(n), val); | 484 ld_ptr(Lesp, Interpreter::expr_offset_in_bytes(n), val); |
568 if (TaggedStackInterpreter) { | 485 } |
569 ld_ptr(Lesp, Interpreter::expr_tag_offset_in_bytes(n), tag); | 486 void InterpreterMacroAssembler::store_ptr(int n, Register val) { |
570 } | |
571 } | |
572 void InterpreterMacroAssembler::store_ptr_and_tag(int n, Register val, | |
573 Register tag) { | |
574 st_ptr(val, Lesp, Interpreter::expr_offset_in_bytes(n)); | 487 st_ptr(val, Lesp, Interpreter::expr_offset_in_bytes(n)); |
575 if (TaggedStackInterpreter) { | |
576 st_ptr(tag, Lesp, Interpreter::expr_tag_offset_in_bytes(n)); | |
577 } | |
578 } | 488 } |
579 | 489 |
580 | 490 |
581 void InterpreterMacroAssembler::load_receiver(Register param_count, | 491 void InterpreterMacroAssembler::load_receiver(Register param_count, |
582 Register recv) { | 492 Register recv) { |
583 | 493 sll(param_count, Interpreter::logStackElementSize, param_count); |
584 sll(param_count, Interpreter::logStackElementSize(), param_count); | |
585 if (TaggedStackInterpreter) { | |
586 add(param_count, Interpreter::value_offset_in_bytes(), param_count); // get obj address | |
587 } | |
588 ld_ptr(Lesp, param_count, recv); // gets receiver Oop | 494 ld_ptr(Lesp, param_count, recv); // gets receiver Oop |
589 } | 495 } |
590 | 496 |
591 void InterpreterMacroAssembler::empty_expression_stack() { | 497 void InterpreterMacroAssembler::empty_expression_stack() { |
592 // Reset Lesp. | 498 // Reset Lesp. |
603 br(Assembler::notZero, false, Assembler::pt, done); | 509 br(Assembler::notZero, false, Assembler::pt, done); |
604 delayed()->nop(); | 510 delayed()->nop(); |
605 | 511 |
606 // Compute max expression stack+register save area | 512 // Compute max expression stack+register save area |
607 lduh(Lmethod, in_bytes(methodOopDesc::max_stack_offset()), Gframe_size); // Load max stack. | 513 lduh(Lmethod, in_bytes(methodOopDesc::max_stack_offset()), Gframe_size); // Load max stack. |
608 if (TaggedStackInterpreter) sll ( Gframe_size, 1, Gframe_size); // max_stack * 2 for TAGS | |
609 add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size ); | 514 add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size ); |
610 | 515 |
611 // | 516 // |
612 // now set up a stack frame with the size computed above | 517 // now set up a stack frame with the size computed above |
613 // | 518 // |
2016 // done copying stack | 1921 // done copying stack |
2017 } | 1922 } |
2018 } | 1923 } |
2019 | 1924 |
2020 // Locals | 1925 // Locals |
2021 #ifdef ASSERT | |
2022 void InterpreterMacroAssembler::verify_local_tag(frame::Tag t, | |
2023 Register base, | |
2024 Register scratch, | |
2025 int n) { | |
2026 if (TaggedStackInterpreter) { | |
2027 Label ok, long_ok; | |
2028 // Use dst for scratch | |
2029 assert_different_registers(base, scratch); | |
2030 ld_ptr(base, Interpreter::local_tag_offset_in_bytes(n), scratch); | |
2031 if (t == frame::TagCategory2) { | |
2032 cmp(scratch, G0); | |
2033 brx(Assembler::equal, false, Assembler::pt, long_ok); | |
2034 delayed()->ld_ptr(base, Interpreter::local_tag_offset_in_bytes(n+1), scratch); | |
2035 stop("local long/double tag value bad"); | |
2036 bind(long_ok); | |
2037 // compare second half tag | |
2038 cmp(scratch, G0); | |
2039 } else if (t == frame::TagValue) { | |
2040 cmp(scratch, G0); | |
2041 } else { | |
2042 assert_different_registers(O3, base, scratch); | |
2043 mov(t, O3); | |
2044 cmp(scratch, O3); | |
2045 } | |
2046 brx(Assembler::equal, false, Assembler::pt, ok); | |
2047 delayed()->nop(); | |
2048 // Also compare if the local value is zero, then the tag might | |
2049 // not have been set coming from deopt. | |
2050 ld_ptr(base, Interpreter::local_offset_in_bytes(n), scratch); | |
2051 cmp(scratch, G0); | |
2052 brx(Assembler::equal, false, Assembler::pt, ok); | |
2053 delayed()->nop(); | |
2054 stop("Local tag value is bad"); | |
2055 bind(ok); | |
2056 } | |
2057 } | |
2058 #endif // ASSERT | |
2059 | |
2060 void InterpreterMacroAssembler::access_local_ptr( Register index, Register dst ) { | 1926 void InterpreterMacroAssembler::access_local_ptr( Register index, Register dst ) { |
2061 assert_not_delayed(); | 1927 assert_not_delayed(); |
2062 sll(index, Interpreter::logStackElementSize(), index); | 1928 sll(index, Interpreter::logStackElementSize, index); |
2063 sub(Llocals, index, index); | 1929 sub(Llocals, index, index); |
2064 debug_only(verify_local_tag(frame::TagReference, index, dst)); | 1930 ld_ptr(index, 0, dst); |
2065 ld_ptr(index, Interpreter::value_offset_in_bytes(), dst); | |
2066 // Note: index must hold the effective address--the iinc template uses it | 1931 // Note: index must hold the effective address--the iinc template uses it |
2067 } | 1932 } |
2068 | 1933 |
2069 // Just like access_local_ptr but the tag is a returnAddress | 1934 // Just like access_local_ptr but the tag is a returnAddress |
2070 void InterpreterMacroAssembler::access_local_returnAddress(Register index, | 1935 void InterpreterMacroAssembler::access_local_returnAddress(Register index, |
2071 Register dst ) { | 1936 Register dst ) { |
2072 assert_not_delayed(); | 1937 assert_not_delayed(); |
2073 sll(index, Interpreter::logStackElementSize(), index); | 1938 sll(index, Interpreter::logStackElementSize, index); |
2074 sub(Llocals, index, index); | 1939 sub(Llocals, index, index); |
2075 debug_only(verify_local_tag(frame::TagValue, index, dst)); | 1940 ld_ptr(index, 0, dst); |
2076 ld_ptr(index, Interpreter::value_offset_in_bytes(), dst); | |
2077 } | 1941 } |
2078 | 1942 |
2079 void InterpreterMacroAssembler::access_local_int( Register index, Register dst ) { | 1943 void InterpreterMacroAssembler::access_local_int( Register index, Register dst ) { |
2080 assert_not_delayed(); | 1944 assert_not_delayed(); |
2081 sll(index, Interpreter::logStackElementSize(), index); | 1945 sll(index, Interpreter::logStackElementSize, index); |
2082 sub(Llocals, index, index); | 1946 sub(Llocals, index, index); |
2083 debug_only(verify_local_tag(frame::TagValue, index, dst)); | 1947 ld(index, 0, dst); |
2084 ld(index, Interpreter::value_offset_in_bytes(), dst); | |
2085 // Note: index must hold the effective address--the iinc template uses it | 1948 // Note: index must hold the effective address--the iinc template uses it |
2086 } | 1949 } |
2087 | 1950 |
2088 | 1951 |
2089 void InterpreterMacroAssembler::access_local_long( Register index, Register dst ) { | 1952 void InterpreterMacroAssembler::access_local_long( Register index, Register dst ) { |
2090 assert_not_delayed(); | 1953 assert_not_delayed(); |
2091 sll(index, Interpreter::logStackElementSize(), index); | 1954 sll(index, Interpreter::logStackElementSize, index); |
2092 sub(Llocals, index, index); | 1955 sub(Llocals, index, index); |
2093 debug_only(verify_local_tag(frame::TagCategory2, index, dst)); | |
2094 // First half stored at index n+1 (which grows down from Llocals[n]) | 1956 // First half stored at index n+1 (which grows down from Llocals[n]) |
2095 load_unaligned_long(index, Interpreter::local_offset_in_bytes(1), dst); | 1957 load_unaligned_long(index, Interpreter::local_offset_in_bytes(1), dst); |
2096 } | 1958 } |
2097 | 1959 |
2098 | 1960 |
2099 void InterpreterMacroAssembler::access_local_float( Register index, FloatRegister dst ) { | 1961 void InterpreterMacroAssembler::access_local_float( Register index, FloatRegister dst ) { |
2100 assert_not_delayed(); | 1962 assert_not_delayed(); |
2101 sll(index, Interpreter::logStackElementSize(), index); | 1963 sll(index, Interpreter::logStackElementSize, index); |
2102 sub(Llocals, index, index); | 1964 sub(Llocals, index, index); |
2103 debug_only(verify_local_tag(frame::TagValue, index, G1_scratch)); | 1965 ldf(FloatRegisterImpl::S, index, 0, dst); |
2104 ldf(FloatRegisterImpl::S, index, Interpreter::value_offset_in_bytes(), dst); | |
2105 } | 1966 } |
2106 | 1967 |
2107 | 1968 |
2108 void InterpreterMacroAssembler::access_local_double( Register index, FloatRegister dst ) { | 1969 void InterpreterMacroAssembler::access_local_double( Register index, FloatRegister dst ) { |
2109 assert_not_delayed(); | 1970 assert_not_delayed(); |
2110 sll(index, Interpreter::logStackElementSize(), index); | 1971 sll(index, Interpreter::logStackElementSize, index); |
2111 sub(Llocals, index, index); | 1972 sub(Llocals, index, index); |
2112 debug_only(verify_local_tag(frame::TagCategory2, index, G1_scratch)); | |
2113 load_unaligned_double(index, Interpreter::local_offset_in_bytes(1), dst); | 1973 load_unaligned_double(index, Interpreter::local_offset_in_bytes(1), dst); |
2114 } | 1974 } |
2115 | 1975 |
2116 | 1976 |
2117 #ifdef ASSERT | 1977 #ifdef ASSERT |
2133 stop("regsave area is being clobbered"); | 1993 stop("regsave area is being clobbered"); |
2134 bind(L); | 1994 bind(L); |
2135 } | 1995 } |
2136 #endif // ASSERT | 1996 #endif // ASSERT |
2137 | 1997 |
2138 void InterpreterMacroAssembler::tag_local(frame::Tag t, | |
2139 Register base, | |
2140 Register src, | |
2141 int n) { | |
2142 if (TaggedStackInterpreter) { | |
2143 // have to store zero because local slots can be reused (rats!) | |
2144 if (t == frame::TagValue) { | |
2145 st_ptr(G0, base, Interpreter::local_tag_offset_in_bytes(n)); | |
2146 } else if (t == frame::TagCategory2) { | |
2147 st_ptr(G0, base, Interpreter::local_tag_offset_in_bytes(n)); | |
2148 st_ptr(G0, base, Interpreter::local_tag_offset_in_bytes(n+1)); | |
2149 } else { | |
2150 // assert that we don't stomp the value in 'src' | |
2151 // O3 is arbitrary because it's not used. | |
2152 assert_different_registers(src, base, O3); | |
2153 mov( t, O3); | |
2154 st_ptr(O3, base, Interpreter::local_tag_offset_in_bytes(n)); | |
2155 } | |
2156 } | |
2157 } | |
2158 | |
2159 | 1998 |
2160 void InterpreterMacroAssembler::store_local_int( Register index, Register src ) { | 1999 void InterpreterMacroAssembler::store_local_int( Register index, Register src ) { |
2161 assert_not_delayed(); | 2000 assert_not_delayed(); |
2162 sll(index, Interpreter::logStackElementSize(), index); | 2001 sll(index, Interpreter::logStackElementSize, index); |
2163 sub(Llocals, index, index); | 2002 sub(Llocals, index, index); |
2164 debug_only(check_for_regarea_stomp(index, Interpreter::value_offset_in_bytes(), FP, G1_scratch, G4_scratch);) | 2003 debug_only(check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch);) |
2165 tag_local(frame::TagValue, index, src); | 2004 st(src, index, 0); |
2166 st(src, index, Interpreter::value_offset_in_bytes()); | 2005 } |
2167 } | 2006 |
2168 | 2007 void InterpreterMacroAssembler::store_local_ptr( Register index, Register src ) { |
2169 void InterpreterMacroAssembler::store_local_ptr( Register index, Register src, | 2008 assert_not_delayed(); |
2170 Register tag ) { | 2009 sll(index, Interpreter::logStackElementSize, index); |
2171 assert_not_delayed(); | |
2172 sll(index, Interpreter::logStackElementSize(), index); | |
2173 sub(Llocals, index, index); | 2010 sub(Llocals, index, index); |
2174 #ifdef ASSERT | 2011 #ifdef ASSERT |
2175 check_for_regarea_stomp(index, Interpreter::value_offset_in_bytes(), FP, G1_scratch, G4_scratch); | 2012 check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch); |
2176 #endif | 2013 #endif |
2177 st_ptr(src, index, Interpreter::value_offset_in_bytes()); | 2014 st_ptr(src, index, 0); |
2178 // Store tag register directly | 2015 } |
2179 if (TaggedStackInterpreter) { | 2016 |
2180 st_ptr(tag, index, Interpreter::tag_offset_in_bytes()); | 2017 |
2181 } | 2018 |
2182 } | 2019 void InterpreterMacroAssembler::store_local_ptr( int n, Register src ) { |
2183 | 2020 st_ptr(src, Llocals, Interpreter::local_offset_in_bytes(n)); |
2184 | |
2185 | |
2186 void InterpreterMacroAssembler::store_local_ptr( int n, Register src, | |
2187 Register tag ) { | |
2188 st_ptr(src, Llocals, Interpreter::local_offset_in_bytes(n)); | |
2189 if (TaggedStackInterpreter) { | |
2190 st_ptr(tag, Llocals, Interpreter::local_tag_offset_in_bytes(n)); | |
2191 } | |
2192 } | 2021 } |
2193 | 2022 |
2194 void InterpreterMacroAssembler::store_local_long( Register index, Register src ) { | 2023 void InterpreterMacroAssembler::store_local_long( Register index, Register src ) { |
2195 assert_not_delayed(); | 2024 assert_not_delayed(); |
2196 sll(index, Interpreter::logStackElementSize(), index); | 2025 sll(index, Interpreter::logStackElementSize, index); |
2197 sub(Llocals, index, index); | 2026 sub(Llocals, index, index); |
2198 #ifdef ASSERT | 2027 #ifdef ASSERT |
2199 check_for_regarea_stomp(index, Interpreter::local_offset_in_bytes(1), FP, G1_scratch, G4_scratch); | 2028 check_for_regarea_stomp(index, Interpreter::local_offset_in_bytes(1), FP, G1_scratch, G4_scratch); |
2200 #endif | 2029 #endif |
2201 tag_local(frame::TagCategory2, index, src); | |
2202 store_unaligned_long(src, index, Interpreter::local_offset_in_bytes(1)); // which is n+1 | 2030 store_unaligned_long(src, index, Interpreter::local_offset_in_bytes(1)); // which is n+1 |
2203 } | 2031 } |
2204 | 2032 |
2205 | 2033 |
2206 void InterpreterMacroAssembler::store_local_float( Register index, FloatRegister src ) { | 2034 void InterpreterMacroAssembler::store_local_float( Register index, FloatRegister src ) { |
2207 assert_not_delayed(); | 2035 assert_not_delayed(); |
2208 sll(index, Interpreter::logStackElementSize(), index); | 2036 sll(index, Interpreter::logStackElementSize, index); |
2209 sub(Llocals, index, index); | 2037 sub(Llocals, index, index); |
2210 #ifdef ASSERT | 2038 #ifdef ASSERT |
2211 check_for_regarea_stomp(index, Interpreter::value_offset_in_bytes(), FP, G1_scratch, G4_scratch); | 2039 check_for_regarea_stomp(index, 0, FP, G1_scratch, G4_scratch); |
2212 #endif | 2040 #endif |
2213 tag_local(frame::TagValue, index, G1_scratch); | 2041 stf(FloatRegisterImpl::S, src, index, 0); |
2214 stf(FloatRegisterImpl::S, src, index, Interpreter::value_offset_in_bytes()); | |
2215 } | 2042 } |
2216 | 2043 |
2217 | 2044 |
2218 void InterpreterMacroAssembler::store_local_double( Register index, FloatRegister src ) { | 2045 void InterpreterMacroAssembler::store_local_double( Register index, FloatRegister src ) { |
2219 assert_not_delayed(); | 2046 assert_not_delayed(); |
2220 sll(index, Interpreter::logStackElementSize(), index); | 2047 sll(index, Interpreter::logStackElementSize, index); |
2221 sub(Llocals, index, index); | 2048 sub(Llocals, index, index); |
2222 #ifdef ASSERT | 2049 #ifdef ASSERT |
2223 check_for_regarea_stomp(index, Interpreter::local_offset_in_bytes(1), FP, G1_scratch, G4_scratch); | 2050 check_for_regarea_stomp(index, Interpreter::local_offset_in_bytes(1), FP, G1_scratch, G4_scratch); |
2224 #endif | 2051 #endif |
2225 tag_local(frame::TagCategory2, index, G1_scratch); | |
2226 store_unaligned_double(src, index, Interpreter::local_offset_in_bytes(1)); | 2052 store_unaligned_double(src, index, Interpreter::local_offset_in_bytes(1)); |
2227 } | 2053 } |
2228 | 2054 |
2229 | 2055 |
2230 int InterpreterMacroAssembler::top_most_monitor_byte_offset() { | 2056 int InterpreterMacroAssembler::top_most_monitor_byte_offset() { |