Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/ppc/vm/interpreter_ppc.cpp
32285 views
/*1* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2012, 2017 SAP AG. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "asm/macroAssembler.inline.hpp"27#include "interpreter/bytecodeHistogram.hpp"28#include "interpreter/interpreter.hpp"29#include "interpreter/interpreterGenerator.hpp"30#include "interpreter/interpreterRuntime.hpp"31#include "interpreter/templateTable.hpp"32#include "oops/arrayOop.hpp"33#include "oops/methodData.hpp"34#include "oops/method.hpp"35#include "oops/oop.inline.hpp"36#include "prims/jvmtiExport.hpp"37#include "prims/jvmtiThreadState.hpp"38#include "prims/methodHandles.hpp"39#include "runtime/arguments.hpp"40#include "runtime/deoptimization.hpp"41#include "runtime/frame.inline.hpp"42#include "runtime/sharedRuntime.hpp"43#include "runtime/stubRoutines.hpp"44#include "runtime/synchronizer.hpp"45#include "runtime/timer.hpp"46#include "runtime/vframeArray.hpp"47#include "utilities/debug.hpp"48#ifdef COMPILER149#include "c1/c1_Runtime1.hpp"50#endif5152#define __ _masm->5354#ifdef PRODUCT55#define BLOCK_COMMENT(str) // nothing56#else57#define BLOCK_COMMENT(str) __ block_comment(str)58#endif5960#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")6162int AbstractInterpreter::BasicType_as_index(BasicType type) {63int i = 0;64switch (type) {65case T_BOOLEAN: i = 0; break;66case T_CHAR : i = 1; break;67case T_BYTE : i = 2; break;68case T_SHORT : i = 3; break;69case T_INT : i = 4; break;70case T_LONG : i = 5; break;71case T_VOID : i = 6; break;72case T_FLOAT : i = 7; break;73case T_DOUBLE : i = 8; break;74case T_OBJECT : i = 9; break;75case T_ARRAY : i = 9; break;76default : ShouldNotReachHere();77}78assert(0 <= i && i < AbstractInterpreter::number_of_result_handlers, "index out of bounds");79return i;80}8182address AbstractInterpreterGenerator::generate_slow_signature_handler() {83// Slow_signature handler that respects the PPC C calling conventions.84//85// We get called by the native entry code with our output register86// area == 8. First we call InterpreterRuntime::get_result_handler87// to copy the pointer to the signature string temporarily to the88// first C-argument and to return the result_handler in89// R3_RET. Since native_entry will copy the jni-pointer to the90// first C-argument slot later on, it is OK to occupy this slot91// temporarilly. Then we copy the argument list on the java92// expression stack into native varargs format on the native stack93// and load arguments into argument registers. Integer arguments in94// the varargs vector will be sign-extended to 8 bytes.95//96// On entry:97// R3_ARG1 - intptr_t* Address of java argument list in memory.98// R15_prev_state - BytecodeInterpreter* Address of interpreter state for99// this method100// R19_method101//102// On exit (just before return instruction):103// R3_RET - contains the address of the result_handler.104// R4_ARG2 - is not updated for static methods and contains "this" otherwise.105// R5_ARG3-R10_ARG8: - When the (i-2)th Java argument is not of type float or double,106// ARGi contains this argument. Otherwise, ARGi is not updated.107// F1_ARG1-F13_ARG13 - contain the first 13 arguments of type float or double.108109const int LogSizeOfTwoInstructions = 3;110111// FIXME: use Argument:: GL: Argument names different numbers!112const int max_fp_register_arguments = 13;113const int max_int_register_arguments = 6; // first 2 are reserved114115const Register arg_java = R21_tmp1;116const Register arg_c = R22_tmp2;117const Register signature = R23_tmp3; // is string118const Register sig_byte = R24_tmp4;119const Register fpcnt = R25_tmp5;120const Register argcnt = R26_tmp6;121const Register intSlot = R27_tmp7;122const Register target_sp = R28_tmp8;123const FloatRegister floatSlot = F0;124125address entry = __ function_entry();126127__ save_LR_CR(R0);128__ save_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));129// We use target_sp for storing arguments in the C frame.130__ mr(target_sp, R1_SP);131__ push_frame_reg_args_nonvolatiles(0, R11_scratch1);132133__ mr(arg_java, R3_ARG1);134135__ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_signature), R16_thread, R19_method);136137// Signature is in R3_RET. Signature is callee saved.138__ mr(signature, R3_RET);139140// Get the result handler.141__ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::get_result_handler), R16_thread, R19_method);142143{144Label L;145// test if static146// _access_flags._flags must be at offset 0.147// TODO PPC port: requires change in shared code.148//assert(in_bytes(AccessFlags::flags_offset()) == 0,149// "MethodDesc._access_flags == MethodDesc._access_flags._flags");150// _access_flags must be a 32 bit value.151assert(sizeof(AccessFlags) == 4, "wrong size");152__ lwa(R11_scratch1/*access_flags*/, method_(access_flags));153// testbit with condition register.154__ testbitdi(CCR0, R0, R11_scratch1/*access_flags*/, JVM_ACC_STATIC_BIT);155__ btrue(CCR0, L);156// For non-static functions, pass "this" in R4_ARG2 and copy it157// to 2nd C-arg slot.158// We need to box the Java object here, so we use arg_java159// (address of current Java stack slot) as argument and don't160// dereference it as in case of ints, floats, etc.161__ mr(R4_ARG2, arg_java);162__ addi(arg_java, arg_java, -BytesPerWord);163__ std(R4_ARG2, _abi(carg_2), target_sp);164__ bind(L);165}166167// Will be incremented directly after loop_start. argcnt=0168// corresponds to 3rd C argument.169__ li(argcnt, -1);170// arg_c points to 3rd C argument171__ addi(arg_c, target_sp, _abi(carg_3));172// no floating-point args parsed so far173__ li(fpcnt, 0);174175Label move_intSlot_to_ARG, move_floatSlot_to_FARG;176Label loop_start, loop_end;177Label do_int, do_long, do_float, do_double, do_dontreachhere, do_object, do_array, do_boxed;178179// signature points to '(' at entry180#ifdef ASSERT181__ lbz(sig_byte, 0, signature);182__ cmplwi(CCR0, sig_byte, '(');183__ bne(CCR0, do_dontreachhere);184#endif185186__ bind(loop_start);187188__ addi(argcnt, argcnt, 1);189__ lbzu(sig_byte, 1, signature);190191__ cmplwi(CCR0, sig_byte, ')'); // end of signature192__ beq(CCR0, loop_end);193194__ cmplwi(CCR0, sig_byte, 'B'); // byte195__ beq(CCR0, do_int);196197__ cmplwi(CCR0, sig_byte, 'C'); // char198__ beq(CCR0, do_int);199200__ cmplwi(CCR0, sig_byte, 'D'); // double201__ beq(CCR0, do_double);202203__ cmplwi(CCR0, sig_byte, 'F'); // float204__ beq(CCR0, do_float);205206__ cmplwi(CCR0, sig_byte, 'I'); // int207__ beq(CCR0, do_int);208209__ cmplwi(CCR0, sig_byte, 'J'); // long210__ beq(CCR0, do_long);211212__ cmplwi(CCR0, sig_byte, 'S'); // short213__ beq(CCR0, do_int);214215__ cmplwi(CCR0, sig_byte, 'Z'); // boolean216__ beq(CCR0, do_int);217218__ cmplwi(CCR0, sig_byte, 'L'); // object219__ beq(CCR0, do_object);220221__ cmplwi(CCR0, sig_byte, '['); // array222__ beq(CCR0, do_array);223224// __ cmplwi(CCR0, sig_byte, 'V'); // void cannot appear since we do not parse the return type225// __ beq(CCR0, do_void);226227__ bind(do_dontreachhere);228229__ unimplemented("ShouldNotReachHere in slow_signature_handler", 120);230231__ bind(do_array);232233{234Label start_skip, end_skip;235236__ bind(start_skip);237__ lbzu(sig_byte, 1, signature);238__ cmplwi(CCR0, sig_byte, '[');239__ beq(CCR0, start_skip); // skip further brackets240__ cmplwi(CCR0, sig_byte, '9');241__ bgt(CCR0, end_skip); // no optional size242__ cmplwi(CCR0, sig_byte, '0');243__ bge(CCR0, start_skip); // skip optional size244__ bind(end_skip);245246__ cmplwi(CCR0, sig_byte, 'L');247__ beq(CCR0, do_object); // for arrays of objects, the name of the object must be skipped248__ b(do_boxed); // otherwise, go directly to do_boxed249}250251__ bind(do_object);252{253Label L;254__ bind(L);255__ lbzu(sig_byte, 1, signature);256__ cmplwi(CCR0, sig_byte, ';');257__ bne(CCR0, L);258}259// Need to box the Java object here, so we use arg_java (address of260// current Java stack slot) as argument and don't dereference it as261// in case of ints, floats, etc.262Label do_null;263__ bind(do_boxed);264__ ld(R0,0, arg_java);265__ cmpdi(CCR0, R0, 0);266__ li(intSlot,0);267__ beq(CCR0, do_null);268__ mr(intSlot, arg_java);269__ bind(do_null);270__ std(intSlot, 0, arg_c);271__ addi(arg_java, arg_java, -BytesPerWord);272__ addi(arg_c, arg_c, BytesPerWord);273__ cmplwi(CCR0, argcnt, max_int_register_arguments);274__ blt(CCR0, move_intSlot_to_ARG);275__ b(loop_start);276277__ bind(do_int);278__ lwa(intSlot, 0, arg_java);279__ std(intSlot, 0, arg_c);280__ addi(arg_java, arg_java, -BytesPerWord);281__ addi(arg_c, arg_c, BytesPerWord);282__ cmplwi(CCR0, argcnt, max_int_register_arguments);283__ blt(CCR0, move_intSlot_to_ARG);284__ b(loop_start);285286__ bind(do_long);287__ ld(intSlot, -BytesPerWord, arg_java);288__ std(intSlot, 0, arg_c);289__ addi(arg_java, arg_java, - 2 * BytesPerWord);290__ addi(arg_c, arg_c, BytesPerWord);291__ cmplwi(CCR0, argcnt, max_int_register_arguments);292__ blt(CCR0, move_intSlot_to_ARG);293__ b(loop_start);294295__ bind(do_float);296__ lfs(floatSlot, 0, arg_java);297#if defined(LINUX)298// Linux uses ELF ABI. Both original ELF and ELFv2 ABIs have float299// in the least significant word of an argument slot.300#if defined(VM_LITTLE_ENDIAN)301__ stfs(floatSlot, 0, arg_c);302#else303__ stfs(floatSlot, 4, arg_c);304#endif305#elif defined(AIX)306// Although AIX runs on big endian CPU, float is in most significant307// word of an argument slot.308__ stfs(floatSlot, 0, arg_c);309#else310#error "unknown OS"311#endif312__ addi(arg_java, arg_java, -BytesPerWord);313__ addi(arg_c, arg_c, BytesPerWord);314__ cmplwi(CCR0, fpcnt, max_fp_register_arguments);315__ blt(CCR0, move_floatSlot_to_FARG);316__ b(loop_start);317318__ bind(do_double);319__ lfd(floatSlot, - BytesPerWord, arg_java);320__ stfd(floatSlot, 0, arg_c);321__ addi(arg_java, arg_java, - 2 * BytesPerWord);322__ addi(arg_c, arg_c, BytesPerWord);323__ cmplwi(CCR0, fpcnt, max_fp_register_arguments);324__ blt(CCR0, move_floatSlot_to_FARG);325__ b(loop_start);326327__ bind(loop_end);328329__ pop_frame();330__ restore_nonvolatile_gprs(R1_SP, _spill_nonvolatiles_neg(r14));331__ restore_LR_CR(R0);332333__ blr();334335Label move_int_arg, move_float_arg;336__ bind(move_int_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)337__ mr(R5_ARG3, intSlot); __ b(loop_start);338__ mr(R6_ARG4, intSlot); __ b(loop_start);339__ mr(R7_ARG5, intSlot); __ b(loop_start);340__ mr(R8_ARG6, intSlot); __ b(loop_start);341__ mr(R9_ARG7, intSlot); __ b(loop_start);342__ mr(R10_ARG8, intSlot); __ b(loop_start);343344__ bind(move_float_arg); // each case must consist of 2 instructions (otherwise adapt LogSizeOfTwoInstructions)345__ fmr(F1_ARG1, floatSlot); __ b(loop_start);346__ fmr(F2_ARG2, floatSlot); __ b(loop_start);347__ fmr(F3_ARG3, floatSlot); __ b(loop_start);348__ fmr(F4_ARG4, floatSlot); __ b(loop_start);349__ fmr(F5_ARG5, floatSlot); __ b(loop_start);350__ fmr(F6_ARG6, floatSlot); __ b(loop_start);351__ fmr(F7_ARG7, floatSlot); __ b(loop_start);352__ fmr(F8_ARG8, floatSlot); __ b(loop_start);353__ fmr(F9_ARG9, floatSlot); __ b(loop_start);354__ fmr(F10_ARG10, floatSlot); __ b(loop_start);355__ fmr(F11_ARG11, floatSlot); __ b(loop_start);356__ fmr(F12_ARG12, floatSlot); __ b(loop_start);357__ fmr(F13_ARG13, floatSlot); __ b(loop_start);358359__ bind(move_intSlot_to_ARG);360__ sldi(R0, argcnt, LogSizeOfTwoInstructions);361__ load_const(R11_scratch1, move_int_arg); // Label must be bound here.362__ add(R11_scratch1, R0, R11_scratch1);363__ mtctr(R11_scratch1/*branch_target*/);364__ bctr();365__ bind(move_floatSlot_to_FARG);366__ sldi(R0, fpcnt, LogSizeOfTwoInstructions);367__ addi(fpcnt, fpcnt, 1);368__ load_const(R11_scratch1, move_float_arg); // Label must be bound here.369__ add(R11_scratch1, R0, R11_scratch1);370__ mtctr(R11_scratch1/*branch_target*/);371__ bctr();372373return entry;374}375376address AbstractInterpreterGenerator::generate_result_handler_for(BasicType type) {377//378// Registers alive379// R3_RET380// LR381//382// Registers updated383// R3_RET384//385386Label done;387address entry = __ pc();388389switch (type) {390case T_BOOLEAN:391// convert !=0 to 1392__ neg(R0, R3_RET);393__ orr(R0, R3_RET, R0);394__ srwi(R3_RET, R0, 31);395break;396case T_BYTE:397// sign extend 8 bits398__ extsb(R3_RET, R3_RET);399break;400case T_CHAR:401// zero extend 16 bits402__ clrldi(R3_RET, R3_RET, 48);403break;404case T_SHORT:405// sign extend 16 bits406__ extsh(R3_RET, R3_RET);407break;408case T_INT:409// sign extend 32 bits410__ extsw(R3_RET, R3_RET);411break;412case T_LONG:413break;414case T_OBJECT:415// JNIHandles::resolve result.416__ resolve_jobject(R3_RET, R11_scratch1, R12_scratch2, /* needs_frame */ true); // kills R31417break;418case T_FLOAT:419break;420case T_DOUBLE:421break;422case T_VOID:423break;424default: ShouldNotReachHere();425}426427__ BIND(done);428__ blr();429430return entry;431}432433// Abstract method entry.434//435address InterpreterGenerator::generate_abstract_entry(void) {436address entry = __ pc();437438//439// Registers alive440// R16_thread - JavaThread*441// R19_method - callee's method (method to be invoked)442// R1_SP - SP prepared such that caller's outgoing args are near top443// LR - return address to caller444//445// Stack layout at this point:446//447// 0 [TOP_IJAVA_FRAME_ABI] <-- R1_SP448// alignment (optional)449// [outgoing Java arguments]450// ...451// PARENT [PARENT_IJAVA_FRAME_ABI]452// ...453//454455// Can't use call_VM here because we have not set up a new456// interpreter state. Make the call to the vm and make it look like457// our caller set up the JavaFrameAnchor.458__ set_top_ijava_frame_at_SP_as_last_Java_frame(R1_SP, R12_scratch2/*tmp*/);459460// Push a new C frame and save LR.461__ save_LR_CR(R0);462__ push_frame_reg_args(0, R11_scratch1);463464// This is not a leaf but we have a JavaFrameAnchor now and we will465// check (create) exceptions afterward so this is ok.466__ call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError),467R16_thread);468469// Pop the C frame and restore LR.470__ pop_frame();471__ restore_LR_CR(R0);472473// Reset JavaFrameAnchor from call_VM_leaf above.474__ reset_last_Java_frame();475476#ifdef CC_INTERP477// Return to frame manager, it will handle the pending exception.478__ blr();479#else480// We don't know our caller, so jump to the general forward exception stub,481// which will also pop our full frame off. Satisfy the interface of482// SharedRuntime::generate_forward_exception()483__ load_const_optimized(R11_scratch1, StubRoutines::forward_exception_entry(), R0);484__ mtctr(R11_scratch1);485__ bctr();486#endif487488return entry;489}490491// Call an accessor method (assuming it is resolved, otherwise drop into492// vanilla (slow path) entry.493address InterpreterGenerator::generate_accessor_entry(void) {494if (!UseFastAccessorMethods && (!FLAG_IS_ERGO(UseFastAccessorMethods))) {495return NULL;496}497498Label Lslow_path, Lacquire;499500const Register501Rclass_or_obj = R3_ARG1,502Rconst_method = R4_ARG2,503Rcodes = Rconst_method,504Rcpool_cache = R5_ARG3,505Rscratch = R11_scratch1,506Rjvmti_mode = Rscratch,507Roffset = R12_scratch2,508Rflags = R6_ARG4,509Rbtable = R7_ARG5;510511static address branch_table[number_of_states];512513address entry = __ pc();514515// Check for safepoint:516// Ditch this, real man don't need safepoint checks.517518// Also check for JVMTI mode519// Check for null obj, take slow path if so.520__ ld(Rclass_or_obj, Interpreter::stackElementSize, CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp));521__ lwz(Rjvmti_mode, thread_(interp_only_mode));522__ cmpdi(CCR1, Rclass_or_obj, 0);523__ cmpwi(CCR0, Rjvmti_mode, 0);524__ crorc(/*CCR0 eq*/2, /*CCR1 eq*/4+2, /*CCR0 eq*/2);525__ beq(CCR0, Lslow_path); // this==null or jvmti_mode!=0526527// Do 2 things in parallel:528// 1. Load the index out of the first instruction word, which looks like this:529// <0x2a><0xb4><index (2 byte, native endianess)>.530// 2. Load constant pool cache base.531__ ld(Rconst_method, in_bytes(Method::const_offset()), R19_method);532__ ld(Rcpool_cache, in_bytes(ConstMethod::constants_offset()), Rconst_method);533534__ lhz(Rcodes, in_bytes(ConstMethod::codes_offset()) + 2, Rconst_method); // Lower half of 32 bit field.535__ ld(Rcpool_cache, ConstantPool::cache_offset_in_bytes(), Rcpool_cache);536537// Get the const pool entry by means of <index>.538const int codes_shift = exact_log2(in_words(ConstantPoolCacheEntry::size()) * BytesPerWord);539__ slwi(Rscratch, Rcodes, codes_shift); // (codes&0xFFFF)<<codes_shift540__ add(Rcpool_cache, Rscratch, Rcpool_cache);541542// Check if cpool cache entry is resolved.543// We are resolved if the indices offset contains the current bytecode.544ByteSize cp_base_offset = ConstantPoolCache::base_offset();545// Big Endian:546__ lbz(Rscratch, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::indices_offset()) + 7 - 2, Rcpool_cache);547__ cmpwi(CCR0, Rscratch, Bytecodes::_getfield);548__ bne(CCR0, Lslow_path);549__ isync(); // Order succeeding loads wrt. load of _indices field from cpool_cache.550551// Finally, start loading the value: Get cp cache entry into regs.552__ ld(Rflags, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::flags_offset()), Rcpool_cache);553__ ld(Roffset, in_bytes(cp_base_offset) + in_bytes(ConstantPoolCacheEntry::f2_offset()), Rcpool_cache);554555// Following code is from templateTable::getfield_or_static556// Load pointer to branch table557__ load_const_optimized(Rbtable, (address)branch_table, Rscratch);558559// Get volatile flag560__ rldicl(Rscratch, Rflags, 64-ConstantPoolCacheEntry::is_volatile_shift, 63); // extract volatile bit561// note: sync is needed before volatile load on PPC64562563// Check field type564__ rldicl(Rflags, Rflags, 64-ConstantPoolCacheEntry::tos_state_shift, 64-ConstantPoolCacheEntry::tos_state_bits);565566#ifdef ASSERT567Label LFlagInvalid;568__ cmpldi(CCR0, Rflags, number_of_states);569__ bge(CCR0, LFlagInvalid);570571__ ld(R9_ARG7, 0, R1_SP);572__ ld(R10_ARG8, 0, R21_sender_SP);573__ cmpd(CCR0, R9_ARG7, R10_ARG8);574__ asm_assert_eq("backlink", 0x543);575#endif // ASSERT576__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.577578// Load from branch table and dispatch (volatile case: one instruction ahead)579__ sldi(Rflags, Rflags, LogBytesPerWord);580__ cmpwi(CCR6, Rscratch, 1); // volatile?581if (support_IRIW_for_not_multiple_copy_atomic_cpu) {582__ sldi(Rscratch, Rscratch, exact_log2(BytesPerInstWord)); // volatile ? size of 1 instruction : 0583}584__ ldx(Rbtable, Rbtable, Rflags);585586if (support_IRIW_for_not_multiple_copy_atomic_cpu) {587__ subf(Rbtable, Rscratch, Rbtable); // point to volatile/non-volatile entry point588}589__ mtctr(Rbtable);590__ bctr();591592#ifdef ASSERT593__ bind(LFlagInvalid);594__ stop("got invalid flag", 0x6541);595596bool all_uninitialized = true,597all_initialized = true;598for (int i = 0; i<number_of_states; ++i) {599all_uninitialized = all_uninitialized && (branch_table[i] == NULL);600all_initialized = all_initialized && (branch_table[i] != NULL);601}602assert(all_uninitialized != all_initialized, "consistency"); // either or603604__ fence(); // volatile entry point (one instruction before non-volatile_entry point)605if (branch_table[vtos] == 0) branch_table[vtos] = __ pc(); // non-volatile_entry point606if (branch_table[dtos] == 0) branch_table[dtos] = __ pc(); // non-volatile_entry point607if (branch_table[ftos] == 0) branch_table[ftos] = __ pc(); // non-volatile_entry point608__ stop("unexpected type", 0x6551);609#endif610611if (branch_table[itos] == 0) { // generate only once612__ align(32, 28, 28); // align load613__ fence(); // volatile entry point (one instruction before non-volatile_entry point)614branch_table[itos] = __ pc(); // non-volatile_entry point615__ lwax(R3_RET, Rclass_or_obj, Roffset);616__ beq(CCR6, Lacquire);617__ blr();618}619620if (branch_table[ltos] == 0) { // generate only once621__ align(32, 28, 28); // align load622__ fence(); // volatile entry point (one instruction before non-volatile_entry point)623branch_table[ltos] = __ pc(); // non-volatile_entry point624__ ldx(R3_RET, Rclass_or_obj, Roffset);625__ beq(CCR6, Lacquire);626__ blr();627}628629if (branch_table[btos] == 0) { // generate only once630__ align(32, 28, 28); // align load631__ fence(); // volatile entry point (one instruction before non-volatile_entry point)632branch_table[btos] = __ pc(); // non-volatile_entry point633__ lbzx(R3_RET, Rclass_or_obj, Roffset);634__ extsb(R3_RET, R3_RET);635__ beq(CCR6, Lacquire);636__ blr();637}638639if (branch_table[ztos] == 0) { // generate only once640__ align(32, 28, 28); // align load641__ fence(); // volatile entry point (one instruction before non-volatile_entry point)642branch_table[ztos] = __ pc(); // non-volatile_entry point643__ lbzx(R3_RET, Rclass_or_obj, Roffset);644__ extsb(R3_RET, R3_RET);645__ beq(CCR6, Lacquire);646__ blr();647}648649if (branch_table[ctos] == 0) { // generate only once650__ align(32, 28, 28); // align load651__ fence(); // volatile entry point (one instruction before non-volatile_entry point)652branch_table[ctos] = __ pc(); // non-volatile_entry point653__ lhzx(R3_RET, Rclass_or_obj, Roffset);654__ beq(CCR6, Lacquire);655__ blr();656}657658if (branch_table[stos] == 0) { // generate only once659__ align(32, 28, 28); // align load660__ fence(); // volatile entry point (one instruction before non-volatile_entry point)661branch_table[stos] = __ pc(); // non-volatile_entry point662__ lhax(R3_RET, Rclass_or_obj, Roffset);663__ beq(CCR6, Lacquire);664__ blr();665}666667if (branch_table[atos] == 0) { // generate only once668__ align(32, 28, 28); // align load669__ fence(); // volatile entry point (one instruction before non-volatile_entry point)670branch_table[atos] = __ pc(); // non-volatile_entry point671__ load_heap_oop(R3_RET, (RegisterOrConstant)Roffset, Rclass_or_obj);672__ verify_oop(R3_RET);673//__ dcbt(R3_RET); // prefetch674__ beq(CCR6, Lacquire);675__ blr();676}677678__ align(32, 12);679__ bind(Lacquire);680__ twi_0(R3_RET);681__ isync(); // acquire682__ blr();683684#ifdef ASSERT685for (int i = 0; i<number_of_states; ++i) {686assert(branch_table[i], "accessor_entry initialization");687//tty->print_cr("accessor_entry: branch_table[%d] = 0x%llx (opcode 0x%llx)", i, branch_table[i], *((unsigned int*)branch_table[i]));688}689#endif690691__ bind(Lslow_path);692__ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), Rscratch);693__ flush();694695return entry;696}697698// Interpreter intrinsic for WeakReference.get().699// 1. Don't push a full blown frame and go on dispatching, but fetch the value700// into R8 and return quickly701// 2. If G1 is active we *must* execute this intrinsic for corrrectness:702// It contains a GC barrier which puts the reference into the satb buffer703// to indicate that someone holds a strong reference to the object the704// weak ref points to!705address InterpreterGenerator::generate_Reference_get_entry(void) {706// Code: _aload_0, _getfield, _areturn707// parameter size = 1708//709// The code that gets generated by this routine is split into 2 parts:710// 1. the "intrinsified" code for G1 (or any SATB based GC),711// 2. the slow path - which is an expansion of the regular method entry.712//713// Notes:714// * In the G1 code we do not check whether we need to block for715// a safepoint. If G1 is enabled then we must execute the specialized716// code for Reference.get (except when the Reference object is null)717// so that we can log the value in the referent field with an SATB718// update buffer.719// If the code for the getfield template is modified so that the720// G1 pre-barrier code is executed when the current method is721// Reference.get() then going through the normal method entry722// will be fine.723// * The G1 code can, however, check the receiver object (the instance724// of java.lang.Reference) and jump to the slow path if null. If the725// Reference object is null then we obviously cannot fetch the referent726// and so we don't need to call the G1 pre-barrier. Thus we can use the727// regular method entry code to generate the NPE.728//729// This code is based on generate_accessor_enty.730731address entry = __ pc();732733const int referent_offset = java_lang_ref_Reference::referent_offset;734guarantee(referent_offset > 0, "referent offset not initialized");735736if (UseG1GC) {737Label slow_path;738739// Debugging not possible, so can't use __ skip_if_jvmti_mode(slow_path, GR31_SCRATCH);740741// In the G1 code we don't check if we need to reach a safepoint. We742// continue and the thread will safepoint at the next bytecode dispatch.743744// If the receiver is null then it is OK to jump to the slow path.745__ ld(R3_RET, Interpreter::stackElementSize, CC_INTERP_ONLY(R17_tos) NOT_CC_INTERP(R15_esp)); // get receiver746747// Check if receiver == NULL and go the slow path.748__ cmpdi(CCR0, R3_RET, 0);749__ beq(CCR0, slow_path);750751// Load the value of the referent field.752__ load_heap_oop(R3_RET, referent_offset, R3_RET);753754// Generate the G1 pre-barrier code to log the value of755// the referent field in an SATB buffer. Note with756// these parameters the pre-barrier does not generate757// the load of the previous value.758759// Restore caller sp for c2i case.760#ifdef ASSERT761__ ld(R9_ARG7, 0, R1_SP);762__ ld(R10_ARG8, 0, R21_sender_SP);763__ cmpd(CCR0, R9_ARG7, R10_ARG8);764__ asm_assert_eq("backlink", 0x544);765#endif // ASSERT766__ mr(R1_SP, R21_sender_SP); // Cut the stack back to where the caller started.767768__ g1_write_barrier_pre(noreg, // obj769noreg, // offset770R3_RET, // pre_val771R11_scratch1, // tmp772R12_scratch2, // tmp773true); // needs_frame774775__ blr();776777// Generate regular method entry.778__ bind(slow_path);779__ branch_to_entry(Interpreter::entry_for_kind(Interpreter::zerolocals), R11_scratch1);780__ flush();781782return entry;783} else {784return generate_accessor_entry();785}786}787788void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {789// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in790// the days we had adapter frames. When we deoptimize a situation where a791// compiled caller calls a compiled caller will have registers it expects792// to survive the call to the callee. If we deoptimize the callee the only793// way we can restore these registers is to have the oldest interpreter794// frame that we create restore these values. That is what this routine795// will accomplish.796797// At the moment we have modified c2 to not have any callee save registers798// so this problem does not exist and this routine is just a place holder.799800assert(f->is_interpreted_frame(), "must be interpreted");801}802803804