comparison src/cpu/ppc/vm/interpreter_ppc.cpp @ 17804:fd1b9f02cc91

8036976: PPC64: implement the template interpreter Reviewed-by: kvn, coleenp Contributed-by: axel.siebenborn@sap.com, martin.doerr@sap.com
author goetz
date Mon, 10 Mar 2014 12:58:02 +0100
parents 31e80afe3fed
children 92aa6797d639 63c5920a038d
comparison
equal deleted inserted replaced
17803:31e80afe3fed 17804:fd1b9f02cc91
1 /* 1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2012, 2013 SAP AG. All rights reserved. 3 * Copyright 2012, 2014 SAP AG. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * 5 *
6 * This code is free software; you can redistribute it and/or modify it 6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as 7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
49 #include "utilities/debug.hpp" 49 #include "utilities/debug.hpp"
50 #ifdef COMPILER1 50 #ifdef COMPILER1
51 #include "c1/c1_Runtime1.hpp" 51 #include "c1/c1_Runtime1.hpp"
52 #endif 52 #endif
53 53
54 #ifndef CC_INTERP
55 #error "CC_INTERP must be defined on PPC"
56 #endif
57
58 #define __ _masm-> 54 #define __ _masm->
59 55
60 #ifdef PRODUCT 56 #ifdef PRODUCT
61 #define BLOCK_COMMENT(str) // nothing 57 #define BLOCK_COMMENT(str) // nothing
62 #else 58 #else
145 141
146 // Reload method, it may have moved. 142 // Reload method, it may have moved.
147 #ifdef CC_INTERP 143 #ifdef CC_INTERP
148 __ ld(R19_method, state_(_method)); 144 __ ld(R19_method, state_(_method));
149 #else 145 #else
150 __ unimplemented("slow signature handler 1"); 146 __ ld(R19_method, 0, target_sp);
147 __ ld(R19_method, _ijava_state_neg(method), R19_method);
151 #endif 148 #endif
152 149
153 // Get the result handler. 150 // Get the result handler.
154 __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method); 151 __ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method);
155 152
156 // Reload method, it may have moved. 153 // Reload method, it may have moved.
157 #ifdef CC_INTERP 154 #ifdef CC_INTERP
158 __ ld(R19_method, state_(_method)); 155 __ ld(R19_method, state_(_method));
159 #else 156 #else
160 __ unimplemented("slow signature handler 2"); 157 __ ld(R19_method, 0, target_sp);
158 __ ld(R19_method, _ijava_state_neg(method), R19_method);
161 #endif 159 #endif
162 160
163 { 161 {
164 Label L; 162 Label L;
165 // test if static 163 // test if static
451 address entry = __ pc(); 449 address entry = __ pc();
452 450
453 // 451 //
454 // Registers alive 452 // Registers alive
455 // R16_thread - JavaThread* 453 // R16_thread - JavaThread*
456 // R19_method - callee's methodOop (method to be invoked) 454 // R19_method - callee's method (method to be invoked)
457 // R1_SP - SP prepared such that caller's outgoing args are near top 455 // R1_SP - SP prepared such that caller's outgoing args are near top
458 // LR - return address to caller 456 // LR - return address to caller
459 // 457 //
460 // Stack layout at this point: 458 // Stack layout at this point:
461 // 459 //
489 487
490 #ifdef CC_INTERP 488 #ifdef CC_INTERP
491 // Return to frame manager, it will handle the pending exception. 489 // Return to frame manager, it will handle the pending exception.
492 __ blr(); 490 __ blr();
493 #else 491 #else
494 Unimplemented(); 492 // We don't know our caller, so jump to the general forward exception stub,
493 // which will also pop our full frame off. Satisfy the interface of
494 // SharedRuntime::generate_forward_exception()
495 __ load_const_optimized(R11_scratch1, StubRoutines::forward_exception_entry(), R0);
496 __ mtctr(R11_scratch1);
497 __ bctr();
495 #endif 498 #endif
496 499
497 return entry; 500 return entry;
498 } 501 }
499 502
500 // Call an accessor method (assuming it is resolved, otherwise drop into 503 // Call an accessor method (assuming it is resolved, otherwise drop into
501 // vanilla (slow path) entry. 504 // vanilla (slow path) entry.
502 address InterpreterGenerator::generate_accessor_entry(void) { 505 address InterpreterGenerator::generate_accessor_entry(void) {
503 if(!UseFastAccessorMethods && (!FLAG_IS_ERGO(UseFastAccessorMethods))) 506 if (!UseFastAccessorMethods && (!FLAG_IS_ERGO(UseFastAccessorMethods))) {
504 return NULL; 507 return NULL;
508 }
505 509
506 Label Lslow_path, Lacquire; 510 Label Lslow_path, Lacquire;
507 511
508 const Register 512 const Register
509 Rclass_or_obj = R3_ARG1, 513 Rclass_or_obj = R3_ARG1,
584 __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started. 588 __ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.
585 589
586 // Load from branch table and dispatch (volatile case: one instruction ahead) 590 // Load from branch table and dispatch (volatile case: one instruction ahead)
587 __ sldi(Rflags, Rflags, LogBytesPerWord); 591 __ sldi(Rflags, Rflags, LogBytesPerWord);
588 __ cmpwi(CCR6, Rscratch, 1); // volatile? 592 __ cmpwi(CCR6, Rscratch, 1); // volatile?
589 __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0 593 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
594 __ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0
595 }
590 __ ldx(Rbtable, Rbtable, Rflags); 596 __ ldx(Rbtable, Rbtable, Rflags);
591 597
592 __ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point 598 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
599 __ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point
600 }
593 __ mtctr(Rbtable); 601 __ mtctr(Rbtable);
594 __ bctr(); 602 __ bctr();
595 603
596 #ifdef ASSERT 604 #ifdef ASSERT
597 __ bind(LFlagInvalid); 605 __ bind(LFlagInvalid);
603 all_uninitialized = all_uninitialized && (branch_table[i] == NULL); 611 all_uninitialized = all_uninitialized && (branch_table[i] == NULL);
604 all_initialized = all_initialized && (branch_table[i] != NULL); 612 all_initialized = all_initialized && (branch_table[i] != NULL);
605 } 613 }
606 assert(all_uninitialized != all_initialized, "consistency"); // either or 614 assert(all_uninitialized != all_initialized, "consistency"); // either or
607 615
608 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) 616 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
609 if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point 617 if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point
610 if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point 618 if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point
611 if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point 619 if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point
612 __ stop("unexpected type", 0x6551); 620 __ stop("unexpected type", 0x6551);
613 #endif 621 #endif
614 622
615 if (branch_table[itos] == 0) { // generate only once 623 if (branch_table[itos] == 0) { // generate only once
616 __ align(32, 28, 28); // align load 624 __ align(32, 28, 28); // align load
617 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) 625 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
618 branch_table[itos] = __ pc(); // non-volatile_entry point 626 branch_table[itos] = __ pc(); // non-volatile_entry point
619 __ lwax(R3_RET, Rclass_or_obj, Roffset); 627 __ lwax(R3_RET, Rclass_or_obj, Roffset);
620 __ beq(CCR6, Lacquire); 628 __ beq(CCR6, Lacquire);
621 __ blr(); 629 __ blr();
622 } 630 }
623 631
624 if (branch_table[ltos] == 0) { // generate only once 632 if (branch_table[ltos] == 0) { // generate only once
625 __ align(32, 28, 28); // align load 633 __ align(32, 28, 28); // align load
626 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) 634 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
627 branch_table[ltos] = __ pc(); // non-volatile_entry point 635 branch_table[ltos] = __ pc(); // non-volatile_entry point
628 __ ldx(R3_RET, Rclass_or_obj, Roffset); 636 __ ldx(R3_RET, Rclass_or_obj, Roffset);
629 __ beq(CCR6, Lacquire); 637 __ beq(CCR6, Lacquire);
630 __ blr(); 638 __ blr();
631 } 639 }
632 640
633 if (branch_table[btos] == 0) { // generate only once 641 if (branch_table[btos] == 0) { // generate only once
634 __ align(32, 28, 28); // align load 642 __ align(32, 28, 28); // align load
635 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) 643 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
636 branch_table[btos] = __ pc(); // non-volatile_entry point 644 branch_table[btos] = __ pc(); // non-volatile_entry point
637 __ lbzx(R3_RET, Rclass_or_obj, Roffset); 645 __ lbzx(R3_RET, Rclass_or_obj, Roffset);
638 __ extsb(R3_RET, R3_RET); 646 __ extsb(R3_RET, R3_RET);
639 __ beq(CCR6, Lacquire); 647 __ beq(CCR6, Lacquire);
640 __ blr(); 648 __ blr();
641 } 649 }
642 650
643 if (branch_table[ctos] == 0) { // generate only once 651 if (branch_table[ctos] == 0) { // generate only once
644 __ align(32, 28, 28); // align load 652 __ align(32, 28, 28); // align load
645 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) 653 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
646 branch_table[ctos] = __ pc(); // non-volatile_entry point 654 branch_table[ctos] = __ pc(); // non-volatile_entry point
647 __ lhzx(R3_RET, Rclass_or_obj, Roffset); 655 __ lhzx(R3_RET, Rclass_or_obj, Roffset);
648 __ beq(CCR6, Lacquire); 656 __ beq(CCR6, Lacquire);
649 __ blr(); 657 __ blr();
650 } 658 }
651 659
652 if (branch_table[stos] == 0) { // generate only once 660 if (branch_table[stos] == 0) { // generate only once
653 __ align(32, 28, 28); // align load 661 __ align(32, 28, 28); // align load
654 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) 662 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
655 branch_table[stos] = __ pc(); // non-volatile_entry point 663 branch_table[stos] = __ pc(); // non-volatile_entry point
656 __ lhax(R3_RET, Rclass_or_obj, Roffset); 664 __ lhax(R3_RET, Rclass_or_obj, Roffset);
657 __ beq(CCR6, Lacquire); 665 __ beq(CCR6, Lacquire);
658 __ blr(); 666 __ blr();
659 } 667 }
660 668
661 if (branch_table[atos] == 0) { // generate only once 669 if (branch_table[atos] == 0) { // generate only once
662 __ align(32, 28, 28); // align load 670 __ align(32, 28, 28); // align load
663 __ sync(); // volatile entry point (one instruction before non-volatile_entry point) 671 __ fence(); // volatile entry point (one instruction before non-volatile_entry point)
664 branch_table[atos] = __ pc(); // non-volatile_entry point 672 branch_table[atos] = __ pc(); // non-volatile_entry point
665 __ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj); 673 __ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj);
666 __ verify_oop(R3_RET); 674 __ verify_oop(R3_RET);
667 //__ dcbt(R3_RET); // prefetch 675 //__ dcbt(R3_RET); // prefetch
668 __ beq(CCR6, Lacquire); 676 __ beq(CCR6, Lacquire);
681 //tty->print_cr("accessor_entry: branch_table[%d] = 0x%llx (opcode 0x%llx)", i, branch_table[i], *((unsigned int*)branch_table[i])); 689 //tty->print_cr("accessor_entry: branch_table[%d] = 0x%llx (opcode 0x%llx)", i, branch_table[i], *((unsigned int*)branch_table[i]));
682 } 690 }
683 #endif 691 #endif
684 692
685 __ bind(Lslow_path); 693 __ bind(Lslow_path);
686 assert(Interpreter::entry_for_kind(Interpreter::zerolocals), "Normal entry must have been generated by now"); 694 __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), Rscratch);
687 __ load_const_optimized(Rscratch, Interpreter::entry_for_kind(Interpreter::zerolocals), R0);
688 __ mtctr(Rscratch);
689 __ bctr();
690 __ flush(); 695 __ flush();
691 696
692 return entry; 697 return entry;
693 } 698 }
694 699
771 776
772 __ blr(); 777 __ blr();
773 778
774 // Generate regular method entry. 779 // Generate regular method entry.
775 __ bind(slow_path); 780 __ bind(slow_path);
776 assert(Interpreter::entry_for_kind(Interpreter::zerolocals), "Normal entry must have been generated by now"); 781 __ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);
777 __ load_const_optimized(R11_scratch1, Interpreter::entry_for_kind(Interpreter::zerolocals), R0);
778 __ mtctr(R11_scratch1);
779 __ bctr();
780 __ flush(); 782 __ flush();
781 783
782 return entry; 784 return entry;
783 } else { 785 } else {
784 return generate_accessor_entry(); 786 return generate_accessor_entry();