Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/sparc/vm/frame_sparc.cpp
32285 views
/*1* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "interpreter/interpreter.hpp"26#include "memory/resourceArea.hpp"27#include "oops/markOop.hpp"28#include "oops/method.hpp"29#include "oops/oop.inline.hpp"30#include "prims/methodHandles.hpp"31#include "runtime/frame.inline.hpp"32#include "runtime/handles.inline.hpp"33#include "runtime/javaCalls.hpp"34#include "runtime/monitorChunk.hpp"35#include "runtime/signature.hpp"36#include "runtime/stubCodeGenerator.hpp"37#include "runtime/stubRoutines.hpp"38#include "vmreg_sparc.inline.hpp"39#ifdef COMPILER140#include "c1/c1_Runtime1.hpp"41#include "runtime/vframeArray.hpp"42#endif4344void RegisterMap::pd_clear() {45if (_thread->has_last_Java_frame()) {46frame fr = _thread->last_frame();47_window = fr.sp();48} else {49_window = NULL;50}51_younger_window = NULL;52}535455// Unified register numbering scheme: each 32-bits counts as a register56// number, so all the V9 registers take 2 slots.57const static int R_L_nums[] = {0+040,2+040,4+040,6+040,8+040,10+040,12+040,14+040};58const static int R_I_nums[] = {0+060,2+060,4+060,6+060,8+060,10+060,12+060,14+060};59const static int R_O_nums[] = {0+020,2+020,4+020,6+020,8+020,10+020,12+020,14+020};60const static int R_G_nums[] = {0+000,2+000,4+000,6+000,8+000,10+000,12+000,14+000};61static RegisterMap::LocationValidType bad_mask = 0;62static RegisterMap::LocationValidType R_LIO_mask = 0;63static bool register_map_inited = false;6465static void register_map_init() {66if (!register_map_inited) {67register_map_inited = true;68int i;69for (i = 0; i < 8; i++) {70assert(R_L_nums[i] < RegisterMap::location_valid_type_size, "in first chunk");71assert(R_I_nums[i] < RegisterMap::location_valid_type_size, "in first chunk");72assert(R_O_nums[i] < RegisterMap::location_valid_type_size, "in first chunk");73assert(R_G_nums[i] < RegisterMap::location_valid_type_size, "in first chunk");74}7576bad_mask |= (1LL << R_O_nums[6]); // SP77bad_mask |= (1LL << R_O_nums[7]); // cPC78bad_mask |= (1LL << R_I_nums[6]); // FP79bad_mask |= (1LL << R_I_nums[7]); // rPC80bad_mask |= (1LL << R_G_nums[2]); // TLS81bad_mask |= (1LL << R_G_nums[7]); // reserved by libthread8283for (i = 0; i < 8; i++) {84R_LIO_mask |= (1LL << R_L_nums[i]);85R_LIO_mask |= (1LL << R_I_nums[i]);86R_LIO_mask |= (1LL << R_O_nums[i]);87}88}89}909192address RegisterMap::pd_location(VMReg regname) const {93register_map_init();9495assert(regname->is_reg(), "sanity check");96// Only the GPRs get handled this way97if( !regname->is_Register())98return NULL;99100// don't talk about bad registers101if ((bad_mask & ((LocationValidType)1 << regname->value())) != 0) {102return NULL;103}104105// Convert to a GPR106Register reg;107int second_word = 0;108// 32-bit registers for in, out and local109if (!regname->is_concrete()) {110// HMM ought to return NULL for any non-concrete (odd) vmreg111// this all tied up in the fact we put out double oopMaps for112// register locations. When that is fixed we'd will return NULL113// (or assert here).114reg = regname->prev()->as_Register();115#ifdef _LP64116second_word = sizeof(jint);117#else118return NULL;119#endif // _LP64120} else {121reg = regname->as_Register();122}123if (reg->is_out()) {124assert(_younger_window != NULL, "Younger window should be available");125return second_word + (address)&_younger_window[reg->after_save()->sp_offset_in_saved_window()];126}127if (reg->is_local() || reg->is_in()) {128assert(_window != NULL, "Window should be available");129return second_word + (address)&_window[reg->sp_offset_in_saved_window()];130}131// Only the window'd GPRs get handled this way; not the globals.132return NULL;133}134135136#ifdef ASSERT137void RegisterMap::check_location_valid() {138register_map_init();139assert((_location_valid[0] & bad_mask) == 0, "cannot have special locations for SP,FP,TLS,etc.");140}141#endif142143// We are shifting windows. That means we are moving all %i to %o,144// getting rid of all current %l, and keeping all %g. This is only145// complicated if any of the location pointers for these are valid.146// The normal case is that everything is in its standard register window147// home, and _location_valid[0] is zero. In that case, this routine148// does exactly nothing.149void RegisterMap::shift_individual_registers() {150if (!update_map()) return; // this only applies to maps with locations151register_map_init();152check_location_valid();153154LocationValidType lv = _location_valid[0];155LocationValidType lv0 = lv;156157lv &= ~R_LIO_mask; // clear %l, %o, %i regs158159// if we cleared some non-%g locations, we may have to do some shifting160if (lv != lv0) {161// copy %i0-%i5 to %o0-%o5, if they have special locations162// This can happen in within stubs which spill argument registers163// around a dynamic link operation, such as resolve_opt_virtual_call.164for (int i = 0; i < 8; i++) {165if (lv0 & (1LL << R_I_nums[i])) {166_location[R_O_nums[i]] = _location[R_I_nums[i]];167lv |= (1LL << R_O_nums[i]);168}169}170}171172_location_valid[0] = lv;173check_location_valid();174}175176bool frame::safe_for_sender(JavaThread *thread) {177178address _SP = (address) sp();179address _FP = (address) fp();180address _UNEXTENDED_SP = (address) unextended_sp();181// sp must be within the stack182bool sp_safe = (_SP <= thread->stack_base()) &&183(_SP >= thread->stack_base() - thread->stack_size());184185if (!sp_safe) {186return false;187}188189// unextended sp must be within the stack and above or equal sp190bool unextended_sp_safe = (_UNEXTENDED_SP <= thread->stack_base()) &&191(_UNEXTENDED_SP >= _SP);192193if (!unextended_sp_safe) return false;194195// an fp must be within the stack and above (but not equal) sp196bool fp_safe = (_FP <= thread->stack_base()) &&197(_FP > _SP);198199// We know sp/unextended_sp are safe only fp is questionable here200201// If the current frame is known to the code cache then we can attempt to202// to construct the sender and do some validation of it. This goes a long way203// toward eliminating issues when we get in frame construction code204205if (_cb != NULL ) {206207// First check if frame is complete and tester is reliable208// Unfortunately we can only check frame complete for runtime stubs and nmethod209// other generic buffer blobs are more problematic so we just assume they are210// ok. adapter blobs never have a frame complete and are never ok.211212if (!_cb->is_frame_complete_at(_pc)) {213if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) {214return false;215}216}217218// Could just be some random pointer within the codeBlob219if (!_cb->code_contains(_pc)) {220return false;221}222223// Entry frame checks224if (is_entry_frame()) {225// an entry frame must have a valid fp.226227if (!fp_safe) {228return false;229}230231// Validate the JavaCallWrapper an entry frame must have232233address jcw = (address)entry_frame_call_wrapper();234235bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > _FP);236237return jcw_safe;238239}240241intptr_t* younger_sp = sp();242intptr_t* _SENDER_SP = sender_sp(); // sender is actually just _FP243bool adjusted_stack = is_interpreted_frame();244245address sender_pc = (address)younger_sp[I7->sp_offset_in_saved_window()] + pc_return_offset;246247248// We must always be able to find a recognizable pc249CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);250if (sender_pc == NULL || sender_blob == NULL) {251return false;252}253254// Could be a zombie method255if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {256return false;257}258259// It should be safe to construct the sender though it might not be valid260261frame sender(_SENDER_SP, younger_sp, adjusted_stack);262263// Do we have a valid fp?264address sender_fp = (address) sender.fp();265266// an fp must be within the stack and above (but not equal) current frame's _FP267268bool sender_fp_safe = (sender_fp <= thread->stack_base()) &&269(sender_fp > _FP);270271if (!sender_fp_safe) {272return false;273}274275276// If the potential sender is the interpreter then we can do some more checking277if (Interpreter::contains(sender_pc)) {278return sender.is_interpreted_frame_valid(thread);279}280281// Could just be some random pointer within the codeBlob282if (!sender.cb()->code_contains(sender_pc)) {283return false;284}285286// We should never be able to see an adapter if the current frame is something from code cache287if (sender_blob->is_adapter_blob()) {288return false;289}290291if( sender.is_entry_frame()) {292// Validate the JavaCallWrapper an entry frame must have293294address jcw = (address)sender.entry_frame_call_wrapper();295296bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > sender_fp);297298return jcw_safe;299}300301// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size302// because you must allocate window space303304if (sender_blob->frame_size() <= 0) {305assert(!sender_blob->is_nmethod(), "should count return address at least");306return false;307}308309// The sender should positively be an nmethod or call_stub. On sparc we might in fact see something else.310// The cause of this is because at a save instruction the O7 we get is a leftover from an earlier311// window use. So if a runtime stub creates two frames (common in fastdebug/debug) then we see the312// stale pc. So if the sender blob is not something we'd expect we have little choice but to declare313// the stack unwalkable. pd_get_top_frame_for_signal_handler tries to recover from this by unwinding314// that initial frame and retrying.315316if (!sender_blob->is_nmethod()) {317return false;318}319320// Could put some more validation for the potential non-interpreted sender321// frame we'd create by calling sender if I could think of any. Wait for next crash in forte...322323// One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb324325// We've validated the potential sender that would be created326327return true;328329}330331// Must be native-compiled frame. Since sender will try and use fp to find332// linkages it must be safe333334if (!fp_safe) return false;335336// could try and do some more potential verification of native frame if we could think of some...337338return true;339}340341// constructors342343// Construct an unpatchable, deficient frame344void frame::init(intptr_t* sp, address pc, CodeBlob* cb) {345#ifdef _LP64346assert( (((intptr_t)sp & (wordSize-1)) == 0), "frame constructor passed an invalid sp");347#endif348_sp = sp;349_younger_sp = NULL;350_pc = pc;351_cb = cb;352_sp_adjustment_by_callee = 0;353assert(pc == NULL && cb == NULL || pc != NULL, "can't have a cb and no pc!");354if (_cb == NULL && _pc != NULL ) {355_cb = CodeCache::find_blob(_pc);356}357_deopt_state = unknown;358#ifdef ASSERT359if ( _cb != NULL && _cb->is_nmethod()) {360// Without a valid unextended_sp() we can't convert the pc to "original"361assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant broken");362}363#endif // ASSERT364}365366frame::frame(intptr_t* sp, unpatchable_t, address pc, CodeBlob* cb) {367init(sp, pc, cb);368}369370frame::frame(intptr_t* sp, intptr_t* younger_sp, bool younger_frame_is_interpreted) :371_sp(sp),372_younger_sp(younger_sp),373_deopt_state(unknown),374_sp_adjustment_by_callee(0) {375if (younger_sp == NULL) {376// make a deficient frame which doesn't know where its PC is377_pc = NULL;378_cb = NULL;379} else {380_pc = (address)younger_sp[I7->sp_offset_in_saved_window()] + pc_return_offset;381assert( (intptr_t*)younger_sp[FP->sp_offset_in_saved_window()] == (intptr_t*)((intptr_t)sp - STACK_BIAS), "younger_sp must be valid");382// Any frame we ever build should always "safe" therefore we should not have to call383// find_blob_unsafe384// In case of native stubs, the pc retrieved here might be385// wrong. (the _last_native_pc will have the right value)386// So do not put add any asserts on the _pc here.387}388389if (_pc != NULL)390_cb = CodeCache::find_blob(_pc);391392// Check for MethodHandle call sites.393if (_cb != NULL) {394nmethod* nm = _cb->as_nmethod_or_null();395if (nm != NULL) {396if (nm->is_deopt_mh_entry(_pc) || nm->is_method_handle_return(_pc)) {397_sp_adjustment_by_callee = (intptr_t*) ((intptr_t) sp[L7_mh_SP_save->sp_offset_in_saved_window()] + STACK_BIAS) - sp;398// The SP is already adjusted by this MH call site, don't399// overwrite this value with the wrong interpreter value.400younger_frame_is_interpreted = false;401}402}403}404405if (younger_frame_is_interpreted) {406// compute adjustment to this frame's SP made by its interpreted callee407_sp_adjustment_by_callee = (intptr_t*) ((intptr_t) younger_sp[I5_savedSP->sp_offset_in_saved_window()] + STACK_BIAS) - sp;408}409410// It is important that the frame is fully constructed when we do411// this lookup as get_deopt_original_pc() needs a correct value for412// unextended_sp() which uses _sp_adjustment_by_callee.413if (_pc != NULL) {414address original_pc = nmethod::get_deopt_original_pc(this);415if (original_pc != NULL) {416_pc = original_pc;417_deopt_state = is_deoptimized;418} else {419_deopt_state = not_deoptimized;420}421}422}423424#ifndef PRODUCT425// This is a generic constructor which is only used by pns() in debug.cpp.426frame::frame(void* sp, void* fp, void* pc) {427init((intptr_t*)sp, (address)pc, NULL);428}429#endif430431bool frame::is_interpreted_frame() const {432return Interpreter::contains(pc());433}434435// sender_sp436437intptr_t* frame::interpreter_frame_sender_sp() const {438assert(is_interpreted_frame(), "interpreted frame expected");439return fp();440}441442#ifndef CC_INTERP443void frame::set_interpreter_frame_sender_sp(intptr_t* sender_sp) {444assert(is_interpreted_frame(), "interpreted frame expected");445Unimplemented();446}447#endif // CC_INTERP448449frame frame::sender_for_entry_frame(RegisterMap *map) const {450assert(map != NULL, "map must be set");451// Java frame called from C; skip all C frames and return top C452// frame of that chunk as the sender453JavaFrameAnchor* jfa = entry_frame_call_wrapper()->anchor();454assert(!entry_frame_is_first(), "next Java fp must be non zero");455assert(jfa->last_Java_sp() > _sp, "must be above this frame on stack");456intptr_t* last_Java_sp = jfa->last_Java_sp();457// Since we are walking the stack now this nested anchor is obviously walkable458// even if it wasn't when it was stacked.459if (!jfa->walkable()) {460// Capture _last_Java_pc (if needed) and mark anchor walkable.461jfa->capture_last_Java_pc(_sp);462}463assert(jfa->last_Java_pc() != NULL, "No captured pc!");464map->clear();465map->make_integer_regs_unsaved();466map->shift_window(last_Java_sp, NULL);467assert(map->include_argument_oops(), "should be set by clear");468return frame(last_Java_sp, frame::unpatchable, jfa->last_Java_pc());469}470471frame frame::sender_for_interpreter_frame(RegisterMap *map) const {472ShouldNotCallThis();473return sender(map);474}475476frame frame::sender_for_compiled_frame(RegisterMap *map) const {477ShouldNotCallThis();478return sender(map);479}480481frame frame::sender(RegisterMap* map) const {482assert(map != NULL, "map must be set");483484assert(CodeCache::find_blob_unsafe(_pc) == _cb, "inconsistent");485486// Default is not to follow arguments; update it accordingly below487map->set_include_argument_oops(false);488489if (is_entry_frame()) return sender_for_entry_frame(map);490491intptr_t* younger_sp = sp();492intptr_t* sp = sender_sp();493494// Note: The version of this operation on any platform with callee-save495// registers must update the register map (if not null).496// In order to do this correctly, the various subtypes of497// of frame (interpreted, compiled, glue, native),498// must be distinguished. There is no need on SPARC for499// such distinctions, because all callee-save registers are500// preserved for all frames via SPARC-specific mechanisms.501//502// *** HOWEVER, *** if and when we make any floating-point503// registers callee-saved, then we will have to copy over504// the RegisterMap update logic from the Intel code.505506// The constructor of the sender must know whether this frame is interpreted so it can set the507// sender's _sp_adjustment_by_callee field. An osr adapter frame was originally508// interpreted but its pc is in the code cache (for c1 -> osr_frame_return_id stub), so it must be509// explicitly recognized.510511512bool frame_is_interpreted = is_interpreted_frame();513if (frame_is_interpreted) {514map->make_integer_regs_unsaved();515map->shift_window(sp, younger_sp);516} else if (_cb != NULL) {517// Update the locations of implicitly saved registers to be their518// addresses in the register save area.519// For %o registers, the addresses of %i registers in the next younger520// frame are used.521map->shift_window(sp, younger_sp);522if (map->update_map()) {523// Tell GC to use argument oopmaps for some runtime stubs that need it.524// For C1, the runtime stub might not have oop maps, so set this flag525// outside of update_register_map.526map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));527if (_cb->oop_maps() != NULL) {528OopMapSet::update_register_map(this, map);529}530}531}532return frame(sp, younger_sp, frame_is_interpreted);533}534535536void frame::patch_pc(Thread* thread, address pc) {537if(thread == Thread::current()) {538StubRoutines::Sparc::flush_callers_register_windows_func()();539}540if (TracePcPatching) {541// QQQ this assert is invalid (or too strong anyway) sice _pc could542// be original pc and frame could have the deopt pc.543// assert(_pc == *O7_addr() + pc_return_offset, "frame has wrong pc");544tty->print_cr("patch_pc at address 0x%x [0x%x -> 0x%x] ", O7_addr(), _pc, pc);545}546_cb = CodeCache::find_blob(pc);547*O7_addr() = pc - pc_return_offset;548_cb = CodeCache::find_blob(_pc);549address original_pc = nmethod::get_deopt_original_pc(this);550if (original_pc != NULL) {551assert(original_pc == _pc, "expected original to be stored before patching");552_deopt_state = is_deoptimized;553} else {554_deopt_state = not_deoptimized;555}556}557558559static bool sp_is_valid(intptr_t* old_sp, intptr_t* young_sp, intptr_t* sp) {560return (((intptr_t)sp & (2*wordSize-1)) == 0 &&561sp <= old_sp &&562sp >= young_sp);563}564565566/*567Find the (biased) sp that is just younger than old_sp starting at sp.568If not found return NULL. Register windows are assumed to be flushed.569*/570intptr_t* frame::next_younger_sp_or_null(intptr_t* old_sp, intptr_t* sp) {571572intptr_t* previous_sp = NULL;573intptr_t* orig_sp = sp;574575int max_frames = (old_sp - sp) / 16; // Minimum frame size is 16576int max_frame2 = max_frames;577while(sp != old_sp && sp_is_valid(old_sp, orig_sp, sp)) {578if (max_frames-- <= 0)579// too many frames have gone by; invalid parameters given to this function580break;581previous_sp = sp;582sp = (intptr_t*)sp[FP->sp_offset_in_saved_window()];583sp = (intptr_t*)((intptr_t)sp + STACK_BIAS);584}585586return (sp == old_sp ? previous_sp : NULL);587}588589/*590Determine if "sp" is a valid stack pointer. "sp" is assumed to be younger than591"valid_sp". So if "sp" is valid itself then it should be possible to walk frames592from "sp" to "valid_sp". The assumption is that the registers windows for the593thread stack in question are flushed.594*/595bool frame::is_valid_stack_pointer(intptr_t* valid_sp, intptr_t* sp) {596return next_younger_sp_or_null(valid_sp, sp) != NULL;597}598599600bool frame::interpreter_frame_equals_unpacked_fp(intptr_t* fp) {601assert(is_interpreted_frame(), "must be interpreter frame");602return this->fp() == fp;603}604605606void frame::pd_gc_epilog() {607if (is_interpreted_frame()) {608// set constant pool cache entry for interpreter609Method* m = interpreter_frame_method();610611*interpreter_frame_cpoolcache_addr() = m->constants()->cache();612}613}614615616bool frame::is_interpreted_frame_valid(JavaThread* thread) const {617#ifdef CC_INTERP618// Is there anything to do?619#else620assert(is_interpreted_frame(), "Not an interpreted frame");621// These are reasonable sanity checks622if (fp() == 0 || (intptr_t(fp()) & (2*wordSize-1)) != 0) {623return false;624}625if (sp() == 0 || (intptr_t(sp()) & (2*wordSize-1)) != 0) {626return false;627}628629const intptr_t interpreter_frame_initial_sp_offset = interpreter_frame_vm_local_words;630if (fp() + interpreter_frame_initial_sp_offset < sp()) {631return false;632}633// These are hacks to keep us out of trouble.634// The problem with these is that they mask other problems635if (fp() <= sp()) { // this attempts to deal with unsigned comparison above636return false;637}638// do some validation of frame elements639640// first the method641642Method* m = *interpreter_frame_method_addr();643644// validate the method we'd find in this potential sender645if (!m->is_valid_method()) return false;646647// stack frames shouldn't be much larger than max_stack elements648649if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {650return false;651}652653// validate bci/bcx654655intptr_t bcx = interpreter_frame_bcx();656if (m->validate_bci_from_bcx(bcx) < 0) {657return false;658}659660// validate ConstantPoolCache*661ConstantPoolCache* cp = *interpreter_frame_cache_addr();662if (cp == NULL || !cp->is_metaspace_object()) return false;663664// validate locals665666address locals = (address) *interpreter_frame_locals_addr();667668if (locals > thread->stack_base() || locals < (address) fp()) return false;669670// We'd have to be pretty unlucky to be mislead at this point671#endif /* CC_INTERP */672return true;673}674675676// Windows have been flushed on entry (but not marked). Capture the pc that677// is the return address to the frame that contains "sp" as its stack pointer.678// This pc resides in the called of the frame corresponding to "sp".679// As a side effect we mark this JavaFrameAnchor as having flushed the windows.680// This side effect lets us mark stacked JavaFrameAnchors (stacked in the681// call_helper) as flushed when we have flushed the windows for the most682// recent (i.e. current) JavaFrameAnchor. This saves useless flushing calls683// and lets us find the pc just once rather than multiple times as it did684// in the bad old _post_Java_state days.685//686void JavaFrameAnchor::capture_last_Java_pc(intptr_t* sp) {687if (last_Java_sp() != NULL && last_Java_pc() == NULL) {688// try and find the sp just younger than _last_Java_sp689intptr_t* _post_Java_sp = frame::next_younger_sp_or_null(last_Java_sp(), sp);690// Really this should never fail otherwise VM call must have non-standard691// frame linkage (bad) or stack is not properly flushed (worse).692guarantee(_post_Java_sp != NULL, "bad stack!");693_last_Java_pc = (address) _post_Java_sp[ I7->sp_offset_in_saved_window()] + frame::pc_return_offset;694695}696set_window_flushed();697}698699void JavaFrameAnchor::make_walkable(JavaThread* thread) {700if (walkable()) return;701// Eventually make an assert702guarantee(Thread::current() == (Thread*)thread, "only current thread can flush its registers");703// We always flush in case the profiler wants it but we won't mark704// the windows as flushed unless we have a last_Java_frame705intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();706if (last_Java_sp() != NULL ) {707capture_last_Java_pc(sp);708}709}710711intptr_t* frame::entry_frame_argument_at(int offset) const {712// convert offset to index to deal with tsi713int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize);714715intptr_t* LSP = (intptr_t*) sp()[Lentry_args->sp_offset_in_saved_window()];716return &LSP[index+1];717}718719720BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {721assert(is_interpreted_frame(), "interpreted frame expected");722Method* method = interpreter_frame_method();723BasicType type = method->result_type();724725if (method->is_native()) {726// Prior to notifying the runtime of the method_exit the possible result727// value is saved to l_scratch and d_scratch.728729#ifdef CC_INTERP730interpreterState istate = get_interpreterState();731intptr_t* l_scratch = (intptr_t*) &istate->_native_lresult;732intptr_t* d_scratch = (intptr_t*) &istate->_native_fresult;733#else /* CC_INTERP */734intptr_t* l_scratch = fp() + interpreter_frame_l_scratch_fp_offset;735intptr_t* d_scratch = fp() + interpreter_frame_d_scratch_fp_offset;736#endif /* CC_INTERP */737738address l_addr = (address)l_scratch;739#ifdef _LP64740// On 64-bit the result for 1/8/16/32-bit result types is in the other741// word half742l_addr += wordSize/2;743#endif744745switch (type) {746case T_OBJECT:747case T_ARRAY: {748#ifdef CC_INTERP749*oop_result = istate->_oop_temp;750#else751oop obj = cast_to_oop(at(interpreter_frame_oop_temp_offset));752assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");753*oop_result = obj;754#endif // CC_INTERP755break;756}757758case T_BOOLEAN : { jint* p = (jint*)l_addr; value_result->z = (jboolean)((*p) & 0x1); break; }759case T_BYTE : { jint* p = (jint*)l_addr; value_result->b = (jbyte)((*p) & 0xff); break; }760case T_CHAR : { jint* p = (jint*)l_addr; value_result->c = (jchar)((*p) & 0xffff); break; }761case T_SHORT : { jint* p = (jint*)l_addr; value_result->s = (jshort)((*p) & 0xffff); break; }762case T_INT : value_result->i = *(jint*)l_addr; break;763case T_LONG : value_result->j = *(jlong*)l_scratch; break;764case T_FLOAT : value_result->f = *(jfloat*)d_scratch; break;765case T_DOUBLE : value_result->d = *(jdouble*)d_scratch; break;766case T_VOID : /* Nothing to do */ break;767default : ShouldNotReachHere();768}769} else {770intptr_t* tos_addr = interpreter_frame_tos_address();771772switch(type) {773case T_OBJECT:774case T_ARRAY: {775oop obj = cast_to_oop(*tos_addr);776assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");777*oop_result = obj;778break;779}780case T_BOOLEAN : { jint* p = (jint*)tos_addr; value_result->z = (jboolean)((*p) & 0x1); break; }781case T_BYTE : { jint* p = (jint*)tos_addr; value_result->b = (jbyte)((*p) & 0xff); break; }782case T_CHAR : { jint* p = (jint*)tos_addr; value_result->c = (jchar)((*p) & 0xffff); break; }783case T_SHORT : { jint* p = (jint*)tos_addr; value_result->s = (jshort)((*p) & 0xffff); break; }784case T_INT : value_result->i = *(jint*)tos_addr; break;785case T_LONG : value_result->j = *(jlong*)tos_addr; break;786case T_FLOAT : value_result->f = *(jfloat*)tos_addr; break;787case T_DOUBLE : value_result->d = *(jdouble*)tos_addr; break;788case T_VOID : /* Nothing to do */ break;789default : ShouldNotReachHere();790}791};792793return type;794}795796// Lesp pointer is one word lower than the top item on the stack.797intptr_t* frame::interpreter_frame_tos_at(jint offset) const {798int index = (Interpreter::expr_offset_in_bytes(offset)/wordSize) - 1;799return &interpreter_frame_tos_address()[index];800}801802803#ifndef PRODUCT804805#define DESCRIBE_FP_OFFSET(name) \806values.describe(frame_no, fp() + frame::name##_offset, #name)807808void frame::describe_pd(FrameValues& values, int frame_no) {809for (int w = 0; w < frame::register_save_words; w++) {810values.describe(frame_no, sp() + w, err_msg("register save area word %d", w), 1);811}812813if (is_interpreted_frame()) {814DESCRIBE_FP_OFFSET(interpreter_frame_d_scratch_fp);815DESCRIBE_FP_OFFSET(interpreter_frame_l_scratch_fp);816DESCRIBE_FP_OFFSET(interpreter_frame_padding);817DESCRIBE_FP_OFFSET(interpreter_frame_oop_temp);818819// esp, according to Lesp (e.g. not depending on bci), if seems valid820intptr_t* esp = *interpreter_frame_esp_addr();821if ((esp >= sp()) && (esp < fp())) {822values.describe(-1, esp, "*Lesp");823}824}825826if (!is_compiled_frame()) {827if (frame::callee_aggregate_return_pointer_words != 0) {828values.describe(frame_no, sp() + frame::callee_aggregate_return_pointer_sp_offset, "callee_aggregate_return_pointer_word");829}830for (int w = 0; w < frame::callee_register_argument_save_area_words; w++) {831values.describe(frame_no, sp() + frame::callee_register_argument_save_area_sp_offset + w,832err_msg("callee_register_argument_save_area_words %d", w));833}834}835}836837#endif838839intptr_t *frame::initial_deoptimization_info() {840// unused... but returns fp() to minimize changes introduced by 7087445841return fp();842}843844845