Mercurial > hg > truffle
comparison src/cpu/ppc/vm/sharedRuntime_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 a433eb716ce1 |
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, 2013, 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. |
955 | 955 |
956 // Jump to the interpreter just as if interpreter was doing it. | 956 // Jump to the interpreter just as if interpreter was doing it. |
957 | 957 |
958 #ifdef CC_INTERP | 958 #ifdef CC_INTERP |
959 const Register tos = R17_tos; | 959 const Register tos = R17_tos; |
960 #else | |
961 const Register tos = R15_esp; | |
962 __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1); | |
960 #endif | 963 #endif |
961 | 964 |
962 // load TOS | 965 // load TOS |
963 __ addi(tos, R1_SP, st_off); | 966 __ addi(tos, R1_SP, st_off); |
964 | 967 |
973 int total_args_passed, | 976 int total_args_passed, |
974 int comp_args_on_stack, | 977 int comp_args_on_stack, |
975 const BasicType *sig_bt, | 978 const BasicType *sig_bt, |
976 const VMRegPair *regs) { | 979 const VMRegPair *regs) { |
977 | 980 |
978 // Load method's entry-point from methodOop. | 981 // Load method's entry-point from method. |
979 __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method); | 982 __ ld(R12_scratch2, in_bytes(Method::from_compiled_offset()), R19_method); |
980 __ mtctr(R12_scratch2); | 983 __ mtctr(R12_scratch2); |
981 | 984 |
982 // We will only enter here from an interpreted frame and never from after | 985 // We will only enter here from an interpreted frame and never from after |
983 // passing thru a c2i. Azul allowed this but we do not. If we lose the | 986 // passing thru a c2i. Azul allowed this but we do not. If we lose the |
994 // save code can segv when fxsave instructions find improperly | 997 // save code can segv when fxsave instructions find improperly |
995 // aligned stack pointer. | 998 // aligned stack pointer. |
996 | 999 |
997 #ifdef CC_INTERP | 1000 #ifdef CC_INTERP |
998 const Register ld_ptr = R17_tos; | 1001 const Register ld_ptr = R17_tos; |
1002 #else | |
1003 const Register ld_ptr = R15_esp; | |
999 #endif | 1004 #endif |
1005 | |
1000 const Register value_regs[] = { R22_tmp2, R23_tmp3, R24_tmp4, R25_tmp5, R26_tmp6 }; | 1006 const Register value_regs[] = { R22_tmp2, R23_tmp3, R24_tmp4, R25_tmp5, R26_tmp6 }; |
1001 const int num_value_regs = sizeof(value_regs) / sizeof(Register); | 1007 const int num_value_regs = sizeof(value_regs) / sizeof(Register); |
1002 int value_regs_index = 0; | 1008 int value_regs_index = 0; |
1003 | 1009 |
1004 int ld_offset = total_args_passed*wordSize; | 1010 int ld_offset = total_args_passed*wordSize; |
1085 } | 1091 } |
1086 } | 1092 } |
1087 } | 1093 } |
1088 } | 1094 } |
1089 | 1095 |
1090 BLOCK_COMMENT("Store method oop"); | 1096 BLOCK_COMMENT("Store method"); |
1091 // Store method oop into thread->callee_target. | 1097 // Store method into thread->callee_target. |
1092 // We might end up in handle_wrong_method if the callee is | 1098 // We might end up in handle_wrong_method if the callee is |
1093 // deoptimized as we race thru here. If that happens we don't want | 1099 // deoptimized as we race thru here. If that happens we don't want |
1094 // to take a safepoint because the caller frame will look | 1100 // to take a safepoint because the caller frame will look |
1095 // interpreted and arguments are now "compiled" so it is much better | 1101 // interpreted and arguments are now "compiled" so it is much better |
1096 // to make this transition invisible to the stack walking | 1102 // to make this transition invisible to the stack walking |
2615 __ std(pc_reg, _abi(lr), R1_SP); | 2621 __ std(pc_reg, _abi(lr), R1_SP); |
2616 __ push_frame(frame_size_reg, R0/*tmp*/); | 2622 __ push_frame(frame_size_reg, R0/*tmp*/); |
2617 #ifdef CC_INTERP | 2623 #ifdef CC_INTERP |
2618 __ std(R1_SP, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); | 2624 __ std(R1_SP, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); |
2619 #else | 2625 #else |
2620 Unimplemented(); | 2626 #ifdef ASSERT |
2627 __ load_const_optimized(pc_reg, 0x5afe); | |
2628 __ std(pc_reg, _ijava_state_neg(ijava_reserved), R1_SP); | |
2621 #endif | 2629 #endif |
2630 __ std(R1_SP, _ijava_state_neg(sender_sp), R1_SP); | |
2631 #endif // CC_INTERP | |
2622 __ addi(number_of_frames_reg, number_of_frames_reg, -1); | 2632 __ addi(number_of_frames_reg, number_of_frames_reg, -1); |
2623 __ addi(frame_sizes_reg, frame_sizes_reg, wordSize); | 2633 __ addi(frame_sizes_reg, frame_sizes_reg, wordSize); |
2624 __ addi(pcs_reg, pcs_reg, wordSize); | 2634 __ addi(pcs_reg, pcs_reg, wordSize); |
2625 } | 2635 } |
2626 | 2636 |
2688 // In the case where we have resized a c2i frame above, the optional | 2698 // In the case where we have resized a c2i frame above, the optional |
2689 // alignment below the locals has size 32 (why?). | 2699 // alignment below the locals has size 32 (why?). |
2690 __ std(R12_scratch2, _abi(lr), R1_SP); | 2700 __ std(R12_scratch2, _abi(lr), R1_SP); |
2691 | 2701 |
2692 // Initialize initial_caller_sp. | 2702 // Initialize initial_caller_sp. |
2703 #ifdef CC_INTERP | |
2693 __ std(frame_size_reg/*old_sp*/, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); | 2704 __ std(frame_size_reg/*old_sp*/, _parent_ijava_frame_abi(initial_caller_sp), R1_SP); |
2705 #else | |
2706 #ifdef ASSERT | |
2707 __ load_const_optimized(pc_reg, 0x5afe); | |
2708 __ std(pc_reg, _ijava_state_neg(ijava_reserved), R1_SP); | |
2709 #endif | |
2710 __ std(frame_size_reg, _ijava_state_neg(sender_sp), R1_SP); | |
2711 #endif // CC_INTERP | |
2694 | 2712 |
2695 #ifdef ASSERT | 2713 #ifdef ASSERT |
2696 // Make sure that there is at least one entry in the array. | 2714 // Make sure that there is at least one entry in the array. |
2697 __ cmpdi(CCR0, number_of_frames_reg, 0); | 2715 __ cmpdi(CCR0, number_of_frames_reg, 0); |
2698 __ asm_assert_ne("array_size must be > 0", 0x205); | 2716 __ asm_assert_ne("array_size must be > 0", 0x205); |
2909 | 2927 |
2910 // stack: (top interpreter frame, ..., optional interpreter frame, | 2928 // stack: (top interpreter frame, ..., optional interpreter frame, |
2911 // optional c2i, caller of deoptee, ...). | 2929 // optional c2i, caller of deoptee, ...). |
2912 | 2930 |
2913 // Initialize R14_state. | 2931 // Initialize R14_state. |
2932 #ifdef CC_INTERP | |
2914 __ ld(R14_state, 0, R1_SP); | 2933 __ ld(R14_state, 0, R1_SP); |
2915 __ addi(R14_state, R14_state, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); | 2934 __ addi(R14_state, R14_state, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); |
2916 // Also inititialize R15_prev_state. | 2935 // Also inititialize R15_prev_state. |
2917 __ restore_prev_state(); | 2936 __ restore_prev_state(); |
2937 #else | |
2938 __ restore_interpreter_state(R11_scratch1); | |
2939 __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1); | |
2940 #endif // CC_INTERP | |
2941 | |
2918 | 2942 |
2919 // Return to the interpreter entry point. | 2943 // Return to the interpreter entry point. |
2920 __ blr(); | 2944 __ blr(); |
2921 __ flush(); | 2945 __ flush(); |
2922 #else // COMPILER2 | 2946 #else // COMPILER2 |
3031 __ restore_LR_CR(R11_scratch1); | 3055 __ restore_LR_CR(R11_scratch1); |
3032 | 3056 |
3033 // stack: (top interpreter frame, ..., optional interpreter frame, | 3057 // stack: (top interpreter frame, ..., optional interpreter frame, |
3034 // optional c2i, caller of deoptee, ...). | 3058 // optional c2i, caller of deoptee, ...). |
3035 | 3059 |
3060 #ifdef CC_INTERP | |
3036 // Initialize R14_state, ... | 3061 // Initialize R14_state, ... |
3037 __ ld(R11_scratch1, 0, R1_SP); | 3062 __ ld(R11_scratch1, 0, R1_SP); |
3038 __ addi(R14_state, R11_scratch1, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); | 3063 __ addi(R14_state, R11_scratch1, -frame::interpreter_frame_cinterpreterstate_size_in_bytes()); |
3039 // also initialize R15_prev_state. | 3064 // also initialize R15_prev_state. |
3040 __ restore_prev_state(); | 3065 __ restore_prev_state(); |
3066 #else | |
3067 __ restore_interpreter_state(R11_scratch1); | |
3068 __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R11_scratch1); | |
3069 #endif // CC_INTERP | |
3070 | |
3041 // Return to the interpreter entry point. | 3071 // Return to the interpreter entry point. |
3042 __ blr(); | 3072 __ blr(); |
3043 | 3073 |
3044 masm->flush(); | 3074 masm->flush(); |
3045 | 3075 |
3113 // Exception pending | 3143 // Exception pending |
3114 RegisterSaver::restore_live_registers_and_pop_frame(masm, | 3144 RegisterSaver::restore_live_registers_and_pop_frame(masm, |
3115 frame_size_in_bytes, | 3145 frame_size_in_bytes, |
3116 /*restore_ctr=*/true); | 3146 /*restore_ctr=*/true); |
3117 | 3147 |
3118 | |
3119 BLOCK_COMMENT(" Jump to forward_exception_entry."); | 3148 BLOCK_COMMENT(" Jump to forward_exception_entry."); |
3120 // Jump to forward_exception_entry, with the issuing PC in LR | 3149 // Jump to forward_exception_entry, with the issuing PC in LR |
3121 // so it looks like the original nmethod called forward_exception_entry. | 3150 // so it looks like the original nmethod called forward_exception_entry. |
3122 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); | 3151 __ b64_patchable(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); |
3123 | 3152 |
3198 | 3227 |
3199 __ mtctr(R3_RET); // Ctr will not be touched by restore_live_registers_and_pop_frame. | 3228 __ mtctr(R3_RET); // Ctr will not be touched by restore_live_registers_and_pop_frame. |
3200 | 3229 |
3201 RegisterSaver::restore_live_registers_and_pop_frame(masm, frame_size_in_bytes, /*restore_ctr*/ false); | 3230 RegisterSaver::restore_live_registers_and_pop_frame(masm, frame_size_in_bytes, /*restore_ctr*/ false); |
3202 | 3231 |
3203 // Get the returned methodOop. | 3232 // Get the returned method. |
3204 __ get_vm_result_2(R19_method); | 3233 __ get_vm_result_2(R19_method); |
3205 | 3234 |
3206 __ bctr(); | 3235 __ bctr(); |
3207 | 3236 |
3208 | 3237 |