Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/zero/vm/frame_zero.cpp
32285 views
/*1* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.2* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.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 "code/scopeDesc.hpp"27#include "interpreter/interpreter.hpp"28#include "interpreter/interpreterRuntime.hpp"29#include "memory/resourceArea.hpp"30#include "oops/markOop.hpp"31#include "oops/method.hpp"32#include "oops/oop.inline.hpp"33#include "runtime/frame.inline.hpp"34#include "runtime/handles.inline.hpp"35#include "runtime/javaCalls.hpp"36#include "runtime/monitorChunk.hpp"37#include "runtime/signature.hpp"38#include "runtime/stubCodeGenerator.hpp"39#include "runtime/stubRoutines.hpp"40#include "vmreg_zero.inline.hpp"41#ifdef COMPILER142#include "c1/c1_Runtime1.hpp"43#include "runtime/vframeArray.hpp"44#endif4546#ifdef ASSERT47void RegisterMap::check_location_valid() {48ShouldNotCallThis();49}50#endif5152bool frame::is_interpreted_frame() const {53return zeroframe()->is_interpreter_frame();54}5556bool frame::is_fake_stub_frame() const {57return zeroframe()->is_fake_stub_frame();58}5960frame frame::sender_for_entry_frame(RegisterMap *map) const {61assert(zeroframe()->is_entry_frame(), "wrong type of frame");62assert(map != NULL, "map must be set");63assert(!entry_frame_is_first(), "next Java fp must be non zero");64assert(entry_frame_call_wrapper()->anchor()->last_Java_sp() == sender_sp(),65"sender should be next Java frame");66map->clear();67assert(map->include_argument_oops(), "should be set by clear");68return frame(zeroframe()->next(), sender_sp());69}7071frame frame::sender_for_nonentry_frame(RegisterMap *map) const {72assert(zeroframe()->is_interpreter_frame() ||73zeroframe()->is_shark_frame() ||74zeroframe()->is_fake_stub_frame(), "wrong type of frame");75return frame(zeroframe()->next(), sender_sp());76}7778frame frame::sender(RegisterMap* map) const {79// Default is not to follow arguments; the various80// sender_for_xxx methods update this accordingly.81map->set_include_argument_oops(false);8283if (is_entry_frame())84return sender_for_entry_frame(map);85else86return sender_for_nonentry_frame(map);87}8889#ifdef CC_INTERP90BasicObjectLock* frame::interpreter_frame_monitor_begin() const {91return get_interpreterState()->monitor_base();92}9394BasicObjectLock* frame::interpreter_frame_monitor_end() const {95return (BasicObjectLock*) get_interpreterState()->stack_base();96}97#endif // CC_INTERP9899void frame::patch_pc(Thread* thread, address pc) {100101if (pc != NULL) {102_cb = CodeCache::find_blob(pc);103SharkFrame* sharkframe = zeroframe()->as_shark_frame();104sharkframe->set_pc(pc);105_pc = pc;106_deopt_state = is_deoptimized;107108} else {109// We borrow this call to set the thread pointer in the interpreter110// state; the hook to set up deoptimized frames isn't supplied it.111assert(pc == NULL, "should be");112get_interpreterState()->set_thread((JavaThread *) thread);113}114}115116bool frame::safe_for_sender(JavaThread *thread) {117ShouldNotCallThis();118return false;119}120121void frame::pd_gc_epilog() {122}123124bool frame::is_interpreted_frame_valid(JavaThread *thread) const {125ShouldNotCallThis();126return false;127}128129BasicType frame::interpreter_frame_result(oop* oop_result,130jvalue* value_result) {131assert(is_interpreted_frame(), "interpreted frame expected");132Method* method = interpreter_frame_method();133BasicType type = method->result_type();134intptr_t* tos_addr = (intptr_t *) interpreter_frame_tos_address();135oop obj;136137switch (type) {138case T_VOID:139break;140case T_BOOLEAN:141value_result->z = *(jboolean *) tos_addr;142break;143case T_BYTE:144value_result->b = *(jbyte *) tos_addr;145break;146case T_CHAR:147value_result->c = *(jchar *) tos_addr;148break;149case T_SHORT:150value_result->s = *(jshort *) tos_addr;151break;152case T_INT:153value_result->i = *(jint *) tos_addr;154break;155case T_LONG:156value_result->j = *(jlong *) tos_addr;157break;158case T_FLOAT:159value_result->f = *(jfloat *) tos_addr;160break;161case T_DOUBLE:162value_result->d = *(jdouble *) tos_addr;163break;164165case T_OBJECT:166case T_ARRAY:167if (method->is_native()) {168obj = get_interpreterState()->oop_temp();169}170else {171oop* obj_p = (oop *) tos_addr;172obj = (obj_p == NULL) ? (oop) NULL : *obj_p;173}174assert(obj == NULL || Universe::heap()->is_in(obj), "sanity check");175*oop_result = obj;176break;177178default:179ShouldNotReachHere();180}181182return type;183}184185int frame::frame_size(RegisterMap* map) const {186#ifdef PRODUCT187ShouldNotCallThis();188#endif // PRODUCT189return 0; // make javaVFrame::print_value work190}191192intptr_t* frame::interpreter_frame_tos_at(jint offset) const {193int index = (Interpreter::expr_offset_in_bytes(offset) / wordSize);194return &interpreter_frame_tos_address()[index];195}196197void frame::zero_print_on_error(int frame_index,198outputStream* st,199char* buf,200int buflen) const {201// Divide the buffer between the field and the value202buflen >>= 1;203char *fieldbuf = buf;204char *valuebuf = buf + buflen;205206// Print each word of the frame207for (intptr_t *addr = sp(); addr <= fp(); addr++) {208int offset = fp() - addr;209210// Fill in default values, then try and improve them211snprintf(fieldbuf, buflen, "word[%d]", offset);212snprintf(valuebuf, buflen, PTR_FORMAT, *addr);213zeroframe()->identify_word(frame_index, offset, fieldbuf, valuebuf, buflen);214fieldbuf[buflen - 1] = '\0';215valuebuf[buflen - 1] = '\0';216217// Print the result218st->print_cr(" " PTR_FORMAT ": %-21s = %s", p2i(addr), fieldbuf, valuebuf);219}220}221222void ZeroFrame::identify_word(int frame_index,223int offset,224char* fieldbuf,225char* valuebuf,226int buflen) const {227switch (offset) {228case next_frame_off:229strncpy(fieldbuf, "next_frame", buflen);230break;231232case frame_type_off:233strncpy(fieldbuf, "frame_type", buflen);234if (is_entry_frame())235strncpy(valuebuf, "ENTRY_FRAME", buflen);236else if (is_interpreter_frame())237strncpy(valuebuf, "INTERPRETER_FRAME", buflen);238else if (is_shark_frame())239strncpy(valuebuf, "SHARK_FRAME", buflen);240else if (is_fake_stub_frame())241strncpy(valuebuf, "FAKE_STUB_FRAME", buflen);242break;243244default:245if (is_entry_frame()) {246as_entry_frame()->identify_word(247frame_index, offset, fieldbuf, valuebuf, buflen);248}249else if (is_interpreter_frame()) {250as_interpreter_frame()->identify_word(251frame_index, offset, fieldbuf, valuebuf, buflen);252}253else if (is_shark_frame()) {254as_shark_frame()->identify_word(255frame_index, offset, fieldbuf, valuebuf, buflen);256}257else if (is_fake_stub_frame()) {258as_fake_stub_frame()->identify_word(259frame_index, offset, fieldbuf, valuebuf, buflen);260}261}262}263264void EntryFrame::identify_word(int frame_index,265int offset,266char* fieldbuf,267char* valuebuf,268int buflen) const {269switch (offset) {270case call_wrapper_off:271strncpy(fieldbuf, "call_wrapper", buflen);272break;273274default:275snprintf(fieldbuf, buflen, "local[%d]", offset - 3);276}277}278279void InterpreterFrame::identify_word(int frame_index,280int offset,281char* fieldbuf,282char* valuebuf,283int buflen) const {284interpreterState istate = interpreter_state();285bool is_valid = istate->self_link() == istate;286intptr_t *addr = addr_of_word(offset);287288// Fixed part289if (addr >= (intptr_t *) istate) {290const char *field = istate->name_of_field_at_address((address) addr);291if (field) {292if (is_valid && !strcmp(field, "_method")) {293istate->method()->name_and_sig_as_C_string(valuebuf, buflen);294}295else if (is_valid && !strcmp(field, "_bcp") && istate->bcp()) {296snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",297(intptr_t) istate->bcp(),298istate->method()->bci_from(istate->bcp()));299}300snprintf(fieldbuf, buflen, "%sistate->%s",301field[strlen(field) - 1] == ')' ? "(": "", field);302}303else if (addr == (intptr_t *) istate) {304strncpy(fieldbuf, "(vtable for istate)", buflen);305}306return;307}308309// Variable part310if (!is_valid)311return;312313// JNI stuff314if (istate->method()->is_native() && addr < istate->stack_base()) {315address hA = istate->method()->signature_handler();316if (hA != NULL) {317if (hA != (address) InterpreterRuntime::slow_signature_handler) {318InterpreterRuntime::SignatureHandler *handler =319InterpreterRuntime::SignatureHandler::from_handlerAddr(hA);320321intptr_t *params = istate->stack_base() - handler->argument_count();322if (addr >= params) {323int param = addr - params;324const char *desc = "";325if (param == 0)326desc = " (JNIEnv)";327else if (param == 1) {328if (istate->method()->is_static())329desc = " (mirror)";330else331desc = " (this)";332}333snprintf(fieldbuf, buflen, "parameter[%d]%s", param, desc);334return;335}336337for (int i = 0; i < handler->argument_count(); i++) {338if (params[i] == (intptr_t) addr) {339snprintf(fieldbuf, buflen, "unboxed parameter[%d]", i);340return;341}342}343}344}345return;346}347348// Monitors and stack349identify_vp_word(frame_index, addr,350(intptr_t *) istate->monitor_base(),351istate->stack_base(),352fieldbuf, buflen);353}354355void SharkFrame::identify_word(int frame_index,356int offset,357char* fieldbuf,358char* valuebuf,359int buflen) const {360// Fixed part361switch (offset) {362case pc_off:363strncpy(fieldbuf, "pc", buflen);364if (method()->is_method()) {365nmethod *code = method()->code();366if (code && code->pc_desc_at(pc())) {367SimpleScopeDesc ssd(code, pc());368snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",369(intptr_t) pc(), ssd.bci());370}371}372return;373374case unextended_sp_off:375strncpy(fieldbuf, "unextended_sp", buflen);376return;377378case method_off:379strncpy(fieldbuf, "method", buflen);380if (method()->is_method()) {381method()->name_and_sig_as_C_string(valuebuf, buflen);382}383return;384385case oop_tmp_off:386strncpy(fieldbuf, "oop_tmp", buflen);387return;388}389390// Variable part391if (method()->is_method()) {392identify_vp_word(frame_index, addr_of_word(offset),393addr_of_word(header_words + 1),394unextended_sp() + method()->max_stack(),395fieldbuf, buflen);396}397}398399void ZeroFrame::identify_vp_word(int frame_index,400intptr_t* addr,401intptr_t* monitor_base,402intptr_t* stack_base,403char* fieldbuf,404int buflen) const {405// Monitors406if (addr >= stack_base && addr < monitor_base) {407int monitor_size = frame::interpreter_frame_monitor_size();408int last_index = (monitor_base - stack_base) / monitor_size - 1;409int index = last_index - (addr - stack_base) / monitor_size;410intptr_t monitor = (intptr_t) (411(BasicObjectLock *) monitor_base - 1 - index);412intptr_t offset = (intptr_t) addr - monitor;413414if (offset == BasicObjectLock::obj_offset_in_bytes())415snprintf(fieldbuf, buflen, "monitor[%d]->_obj", index);416else if (offset == BasicObjectLock::lock_offset_in_bytes())417snprintf(fieldbuf, buflen, "monitor[%d]->_lock", index);418419return;420}421422// Expression stack423if (addr < stack_base) {424snprintf(fieldbuf, buflen, "%s[%d]",425frame_index == 0 ? "stack_word" : "local",426(int) (stack_base - addr - 1));427return;428}429}430431#ifndef PRODUCT432433void frame::describe_pd(FrameValues& values, int frame_no) {434435}436437#endif438439intptr_t *frame::initial_deoptimization_info() {440// unused... but returns fp() to minimize changes introduced by 7087445441return fp();442}443444#ifndef PRODUCT445// This is a generic constructor which is only used by pns() in debug.cpp.446frame::frame(void* sp, void* fp, void* pc) {447Unimplemented();448}449#endif450451452