deoptimization.cpp revision 3719:c3e799c37717
190075Sobrien/* 290075Sobrien * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3169689Skan * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 490075Sobrien * 590075Sobrien * This code is free software; you can redistribute it and/or modify it 690075Sobrien * under the terms of the GNU General Public License version 2 only, as 790075Sobrien * published by the Free Software Foundation. 890075Sobrien * 9132718Skan * This code is distributed in the hope that it will be useful, but WITHOUT 1090075Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11132718Skan * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1290075Sobrien * version 2 for more details (a copy is included in the LICENSE file that 1390075Sobrien * accompanied this code). 1490075Sobrien * 1590075Sobrien * You should have received a copy of the GNU General Public License version 16132718Skan * 2 along with this work; if not, write to the Free Software Foundation, 1790075Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1890075Sobrien * 1990075Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2090075Sobrien * or visit www.oracle.com if you need additional information or have any 2190075Sobrien * questions. 22132718Skan * 23169689Skan */ 24169689Skan 2590075Sobrien#include "precompiled.hpp" 2690075Sobrien#include "classfile/systemDictionary.hpp" 2790075Sobrien#include "code/debugInfoRec.hpp" 2890075Sobrien#include "code/nmethod.hpp" 2990075Sobrien#include "code/pcDesc.hpp" 3090075Sobrien#include "code/scopeDesc.hpp" 3190075Sobrien#include "interpreter/bytecode.hpp" 3290075Sobrien#include "interpreter/interpreter.hpp" 3390075Sobrien#include "interpreter/oopMapCache.hpp" 3490075Sobrien#include "memory/allocation.inline.hpp" 3590075Sobrien#include "memory/oopFactory.hpp" 36132718Skan#include "memory/resourceArea.hpp" 37132718Skan#include "oops/method.hpp" 3890075Sobrien#include "oops/oop.inline.hpp" 3990075Sobrien#include "prims/jvmtiThreadState.hpp" 40146895Skan#include "runtime/biasedLocking.hpp" 4196263Sobrien#include "runtime/compilationPolicy.hpp" 4290075Sobrien#include "runtime/deoptimization.hpp" 4396263Sobrien#include "runtime/interfaceSupport.hpp" 4496263Sobrien#include "runtime/sharedRuntime.hpp" 4596263Sobrien#include "runtime/signature.hpp" 4690075Sobrien#include "runtime/stubRoutines.hpp" 47169689Skan#include "runtime/thread.hpp" 4890075Sobrien#include "runtime/vframe.hpp" 4990075Sobrien#include "runtime/vframeArray.hpp" 5090075Sobrien#include "runtime/vframe_hp.hpp" 5190075Sobrien#include "utilities/events.hpp" 5290075Sobrien#include "utilities/xmlstream.hpp" 5390075Sobrien#ifdef TARGET_ARCH_x86 5490075Sobrien# include "vmreg_x86.inline.hpp" 5590075Sobrien#endif 5690075Sobrien#ifdef TARGET_ARCH_sparc 5790075Sobrien# include "vmreg_sparc.inline.hpp" 5890075Sobrien#endif 5990075Sobrien#ifdef TARGET_ARCH_zero 6090075Sobrien# include "vmreg_zero.inline.hpp" 6190075Sobrien#endif 6290075Sobrien#ifdef TARGET_ARCH_arm 6390075Sobrien# include "vmreg_arm.inline.hpp" 6490075Sobrien#endif 6590075Sobrien#ifdef TARGET_ARCH_ppc 6690075Sobrien# include "vmreg_ppc.inline.hpp" 6790075Sobrien#endif 6890075Sobrien#ifdef COMPILER2 6990075Sobrien#ifdef TARGET_ARCH_MODEL_x86_32 7090075Sobrien# include "adfiles/ad_x86_32.hpp" 7190075Sobrien#endif 7290075Sobrien#ifdef TARGET_ARCH_MODEL_x86_64 7390075Sobrien# include "adfiles/ad_x86_64.hpp" 7490075Sobrien#endif 7590075Sobrien#ifdef TARGET_ARCH_MODEL_sparc 7690075Sobrien# include "adfiles/ad_sparc.hpp" 7790075Sobrien#endif 7890075Sobrien#ifdef TARGET_ARCH_MODEL_zero 7990075Sobrien# include "adfiles/ad_zero.hpp" 8090075Sobrien#endif 8190075Sobrien#ifdef TARGET_ARCH_MODEL_arm 8290075Sobrien# include "adfiles/ad_arm.hpp" 8390075Sobrien#endif 8490075Sobrien#ifdef TARGET_ARCH_MODEL_ppc 8590075Sobrien# include "adfiles/ad_ppc.hpp" 8690075Sobrien#endif 8790075Sobrien#endif 8890075Sobrien 8990075Sobrienbool DeoptimizationMarker::_is_active = false; 9090075Sobrien 9190075SobrienDeoptimization::UnrollBlock::UnrollBlock(int size_of_deoptimized_frame, 9290075Sobrien int caller_adjustment, 9390075Sobrien int caller_actual_parameters, 9490075Sobrien int number_of_frames, 9590075Sobrien intptr_t* frame_sizes, 9690075Sobrien address* frame_pcs, 9790075Sobrien BasicType return_type) { 9890075Sobrien _size_of_deoptimized_frame = size_of_deoptimized_frame; 9990075Sobrien _caller_adjustment = caller_adjustment; 10090075Sobrien _caller_actual_parameters = caller_actual_parameters; 10190075Sobrien _number_of_frames = number_of_frames; 10290075Sobrien _frame_sizes = frame_sizes; 10390075Sobrien _frame_pcs = frame_pcs; 10490075Sobrien _register_block = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2, mtCompiler); 10590075Sobrien _return_type = return_type; 10690075Sobrien _initial_info = 0; 10790075Sobrien // PD (x86 only) 10890075Sobrien _counter_temp = 0; 10990075Sobrien _unpack_kind = 0; 11090075Sobrien _sender_sp_temp = 0; 11190075Sobrien 11290075Sobrien _total_frame_sizes = size_of_frames(); 11390075Sobrien} 11490075Sobrien 11590075Sobrien 11690075SobrienDeoptimization::UnrollBlock::~UnrollBlock() { 11790075Sobrien FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes, mtCompiler); 11890075Sobrien FREE_C_HEAP_ARRAY(intptr_t, _frame_pcs, mtCompiler); 11990075Sobrien FREE_C_HEAP_ARRAY(intptr_t, _register_block, mtCompiler); 12090075Sobrien} 12190075Sobrien 12290075Sobrien 12390075Sobrienintptr_t* Deoptimization::UnrollBlock::value_addr_at(int register_number) const { 12490075Sobrien assert(register_number < RegisterMap::reg_count, "checking register number"); 12590075Sobrien return &_register_block[register_number * 2]; 12690075Sobrien} 12790075Sobrien 12890075Sobrien 12990075Sobrien 13090075Sobrienint Deoptimization::UnrollBlock::size_of_frames() const { 13190075Sobrien // Acount first for the adjustment of the initial frame 13296263Sobrien int result = _caller_adjustment; 13396263Sobrien for (int index = 0; index < number_of_frames(); index++) { 13496263Sobrien result += frame_sizes()[index]; 13596263Sobrien } 13696263Sobrien return result; 13796263Sobrien} 13896263Sobrien 13996263Sobrien 14096263Sobrienvoid Deoptimization::UnrollBlock::print() { 14196263Sobrien ttyLocker ttyl; 14296263Sobrien tty->print_cr("UnrollBlock"); 14390075Sobrien tty->print_cr(" size_of_deoptimized_frame = %d", _size_of_deoptimized_frame); 14490075Sobrien tty->print( " frame_sizes: "); 14590075Sobrien for (int index = 0; index < number_of_frames(); index++) { 14690075Sobrien tty->print("%d ", frame_sizes()[index]); 14790075Sobrien } 14890075Sobrien tty->cr(); 14996263Sobrien} 150117395Skan 15190075Sobrien 15290075Sobrien// In order to make fetch_unroll_info work properly with escape 15390075Sobrien// analysis, The method was changed from JRT_LEAF to JRT_BLOCK_ENTRY and 15490075Sobrien// ResetNoHandleMark and HandleMark were removed from it. The actual reallocation 15590075Sobrien// of previously eliminated objects occurs in realloc_objects, which is 15690075Sobrien// called from the method fetch_unroll_info_helper below. 15790075SobrienJRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread)) 15890075Sobrien // It is actually ok to allocate handles in a leaf method. It causes no safepoints, 15990075Sobrien // but makes the entry a little slower. There is however a little dance we have to 16090075Sobrien // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro 16190075Sobrien 162132718Skan // fetch_unroll_info() is called at the beginning of the deoptimization 16390075Sobrien // handler. Note this fact before we start generating temporary frames 16496263Sobrien // that can confuse an asynchronous stack walker. This counter is 16596263Sobrien // decremented at the end of unpack_frames(). 16690075Sobrien thread->inc_in_deopt_handler(); 16790075Sobrien 16890075Sobrien return fetch_unroll_info_helper(thread); 16990075SobrienJRT_END 17090075Sobrien 17190075Sobrien 17290075Sobrien// This is factored, since it is both called from a JRT_LEAF (deoptimization) and a JRT_ENTRY (uncommon_trap) 17390075SobrienDeoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread* thread) { 17490075Sobrien 17590075Sobrien // Note: there is a safepoint safety issue here. No matter whether we enter 17690075Sobrien // via vanilla deopt or uncommon trap we MUST NOT stop at a safepoint once 17790075Sobrien // the vframeArray is created. 17890075Sobrien // 17990075Sobrien 18090075Sobrien // Allocate our special deoptimization ResourceMark 18190075Sobrien DeoptResourceMark* dmark = new DeoptResourceMark(thread); 18290075Sobrien assert(thread->deopt_mark() == NULL, "Pending deopt!"); 18390075Sobrien thread->set_deopt_mark(dmark); 18490075Sobrien 18590075Sobrien frame stub_frame = thread->last_frame(); // Makes stack walkable as side effect 18690075Sobrien RegisterMap map(thread, true); 18790075Sobrien RegisterMap dummy_map(thread, false); 18890075Sobrien // Now get the deoptee with a valid map 189132718Skan frame deoptee = stub_frame.sender(&map); 190132718Skan // Set the deoptee nmethod 19190075Sobrien assert(thread->deopt_nmethod() == NULL, "Pending deopt!"); 19290075Sobrien thread->set_deopt_nmethod(deoptee.cb()->as_nmethod_or_null()); 19390075Sobrien 19490075Sobrien if (VerifyStack) { 19590075Sobrien thread->validate_frame_layout(); 19690075Sobrien } 19790075Sobrien 19890075Sobrien // Create a growable array of VFrames where each VFrame represents an inlined 19990075Sobrien // Java frame. This storage is allocated with the usual system arena. 20090075Sobrien assert(deoptee.is_compiled_frame(), "Wrong frame type"); 20190075Sobrien GrowableArray<compiledVFrame*>* chunk = new GrowableArray<compiledVFrame*>(10); 20290075Sobrien vframe* vf = vframe::new_vframe(&deoptee, &map, thread); 20390075Sobrien while (!vf->is_top()) { 20490075Sobrien assert(vf->is_compiled_frame(), "Wrong frame type"); 20596263Sobrien chunk->push(compiledVFrame::cast(vf)); 20696263Sobrien vf = vf->sender(); 20790075Sobrien } 20896263Sobrien assert(vf->is_compiled_frame(), "Wrong frame type"); 20996263Sobrien chunk->push(compiledVFrame::cast(vf)); 21096263Sobrien 21190075Sobrien#ifdef COMPILER2 21290075Sobrien // Reallocate the non-escaping objects and restore their fields. Then 21390075Sobrien // relock objects if synchronization on them was eliminated. 21490075Sobrien if (DoEscapeAnalysis || EliminateNestedLocks) { 21590075Sobrien if (EliminateAllocations) { 21690075Sobrien assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); 21790075Sobrien GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects(); 21890075Sobrien 21990075Sobrien // The flag return_oop() indicates call sites which return oop 22090075Sobrien // in compiled code. Such sites include java method calls, 22190075Sobrien // runtime calls (for example, used to allocate new objects/arrays 22290075Sobrien // on slow code path) and any other calls generated in compiled code. 22390075Sobrien // It is not guaranteed that we can get such information here only 22490075Sobrien // by analyzing bytecode in deoptimized frames. This is why this flag 22590075Sobrien // is set during method compilation (see Compile::Process_OopMap_Node()). 22690075Sobrien bool save_oop_result = chunk->at(0)->scope()->return_oop(); 22790075Sobrien Handle return_value; 228132718Skan if (save_oop_result) { 22990075Sobrien // Reallocation may trigger GC. If deoptimization happened on return from 23090075Sobrien // call which returns oop we need to save it since it is not in oopmap. 23190075Sobrien oop result = deoptee.saved_oop_result(&map); 23290075Sobrien assert(result == NULL || result->is_oop(), "must be oop"); 23390075Sobrien return_value = Handle(thread, result); 23490075Sobrien assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); 23590075Sobrien if (TraceDeoptimization) { 23690075Sobrien ttyLocker ttyl; 23790075Sobrien tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread); 23890075Sobrien } 23990075Sobrien } 24090075Sobrien bool reallocated = false; 24190075Sobrien if (objects != NULL) { 24290075Sobrien JRT_BLOCK 24390075Sobrien reallocated = realloc_objects(thread, &deoptee, objects, THREAD); 24490075Sobrien JRT_END 24590075Sobrien } 24690075Sobrien if (reallocated) { 24790075Sobrien reassign_fields(&deoptee, &map, objects); 24890075Sobrien#ifndef PRODUCT 24990075Sobrien if (TraceDeoptimization) { 25096263Sobrien ttyLocker ttyl; 25196263Sobrien tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); 25296263Sobrien print_objects(objects); 25390075Sobrien } 25496263Sobrien#endif 25596263Sobrien } 25690075Sobrien if (save_oop_result) { 25796263Sobrien // Restore result. 25896263Sobrien deoptee.set_saved_oop_result(&map, return_value()); 25996263Sobrien } 26096263Sobrien } 26196263Sobrien if (EliminateLocks) { 26296263Sobrien#ifndef PRODUCT 26396263Sobrien bool first = true; 26496263Sobrien#endif 26596263Sobrien for (int i = 0; i < chunk->length(); i++) { 26696263Sobrien compiledVFrame* cvf = chunk->at(i); 26796263Sobrien assert (cvf->scope() != NULL,"expect only compiled java frames"); 26896263Sobrien GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); 26996263Sobrien if (monitors->is_nonempty()) { 27096263Sobrien relock_objects(monitors, thread); 27196263Sobrien#ifndef PRODUCT 27296263Sobrien if (TraceDeoptimization) { 27396263Sobrien ttyLocker ttyl; 27496263Sobrien for (int j = 0; j < monitors->length(); j++) { 27596263Sobrien MonitorInfo* mi = monitors->at(j); 27696263Sobrien if (mi->eliminated()) { 27796263Sobrien if (first) { 27896263Sobrien first = false; 27996263Sobrien tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); 28096263Sobrien } 28196263Sobrien tty->print_cr(" object <" INTPTR_FORMAT "> locked", mi->owner()); 28296263Sobrien } 28396263Sobrien } 28496263Sobrien } 28596263Sobrien#endif 28696263Sobrien } 28796263Sobrien } 288169689Skan } 28996263Sobrien } 29096263Sobrien#endif // COMPILER2 291169689Skan // Ensure that no safepoint is taken after pointers have been stored 29296263Sobrien // in fields of rematerialized objects. If a safepoint occurs from here on 29396263Sobrien // out the java state residing in the vframeArray will be missed. 29496263Sobrien No_Safepoint_Verifier no_safepoint; 29596263Sobrien 29696263Sobrien vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk); 29796263Sobrien 29896263Sobrien assert(thread->vframe_array_head() == NULL, "Pending deopt!");; 29996263Sobrien thread->set_vframe_array_head(array); 30096263Sobrien 30196263Sobrien // Now that the vframeArray has been created if we have any deferred local writes 30296263Sobrien // added by jvmti then we can free up that structure as the data is now in the 30390075Sobrien // vframeArray 30490075Sobrien 30596263Sobrien if (thread->deferred_locals() != NULL) { 30696263Sobrien GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread->deferred_locals(); 30796263Sobrien int i = 0; 30896263Sobrien do { 30990075Sobrien // Because of inlining we could have multiple vframes for a single frame 31096263Sobrien // and several of the vframes could have deferred writes. Find them all. 31196263Sobrien if (list->at(i)->id() == array->original().id()) { 31296263Sobrien jvmtiDeferredLocalVariableSet* dlv = list->at(i); 31396263Sobrien list->remove_at(i); 31496263Sobrien // individual jvmtiDeferredLocalVariableSet are CHeapObj's 31596263Sobrien delete dlv; 31696263Sobrien } else { 31796263Sobrien i++; 31896263Sobrien } 31996263Sobrien } while ( i < list->length() ); 32096263Sobrien if (list->length() == 0) { 32196263Sobrien thread->set_deferred_locals(NULL); 32296263Sobrien // free the list and elements back to C heap. 32396263Sobrien delete list; 32496263Sobrien } 32596263Sobrien 32696263Sobrien } 32796263Sobrien 32896263Sobrien#ifndef SHARK 32996263Sobrien // Compute the caller frame based on the sender sp of stub_frame and stored frame sizes info. 33096263Sobrien CodeBlob* cb = stub_frame.cb(); 33196263Sobrien // Verify we have the right vframeArray 33296263Sobrien assert(cb->frame_size() >= 0, "Unexpected frame size"); 33396263Sobrien intptr_t* unpack_sp = stub_frame.sp() + cb->frame_size(); 33496263Sobrien 33596263Sobrien // If the deopt call site is a MethodHandle invoke call site we have 33696263Sobrien // to adjust the unpack_sp. 33796263Sobrien nmethod* deoptee_nm = deoptee.cb()->as_nmethod_or_null(); 33896263Sobrien if (deoptee_nm != NULL && deoptee_nm->is_method_handle_return(deoptee.pc())) 33996263Sobrien unpack_sp = deoptee.unextended_sp(); 34096263Sobrien 34196263Sobrien#ifdef ASSERT 34296263Sobrien assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking"); 34396263Sobrien#endif 34496263Sobrien#else 34596263Sobrien intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp(); 34696263Sobrien#endif // !SHARK 34796263Sobrien 34896263Sobrien // This is a guarantee instead of an assert because if vframe doesn't match 34996263Sobrien // we will unpack the wrong deoptimized frame and wind up in strange places 35096263Sobrien // where it will be very difficult to figure out what went wrong. Better 35196263Sobrien // to die an early death here than some very obscure death later when the 35296263Sobrien // trail is cold. 35396263Sobrien // Note: on ia64 this guarantee can be fooled by frames with no memory stack 35496263Sobrien // in that it will fail to detect a problem when there is one. This needs 35596263Sobrien // more work in tiger timeframe. 35696263Sobrien guarantee(array->unextended_sp() == unpack_sp, "vframe_array_head must contain the vframeArray to unpack"); 35796263Sobrien 35896263Sobrien int number_of_frames = array->frames(); 35996263Sobrien 36096263Sobrien // Compute the vframes' sizes. Note that frame_sizes[] entries are ordered from outermost to innermost 36196263Sobrien // virtual activation, which is the reverse of the elements in the vframes array. 36296263Sobrien intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames, mtCompiler); 36396263Sobrien // +1 because we always have an interpreter return address for the final slot. 36496263Sobrien address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1, mtCompiler); 36596263Sobrien int popframe_extra_args = 0; 36696263Sobrien // Create an interpreter return address for the stub to use as its return 36796263Sobrien // address so the skeletal frames are perfectly walkable 36896263Sobrien frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0); 36996263Sobrien 37096263Sobrien // PopFrame requires that the preserved incoming arguments from the recently-popped topmost 37196263Sobrien // activation be put back on the expression stack of the caller for reexecution 37290075Sobrien if (JvmtiExport::can_pop_frame() && thread->popframe_forcing_deopt_reexecution()) { 37396263Sobrien popframe_extra_args = in_words(thread->popframe_preserved_args_size_in_words()); 37490075Sobrien } 37590075Sobrien 37690075Sobrien // Find the current pc for sender of the deoptee. Since the sender may have been deoptimized 37790075Sobrien // itself since the deoptee vframeArray was created we must get a fresh value of the pc rather 37890075Sobrien // than simply use array->sender.pc(). This requires us to walk the current set of frames 37996263Sobrien // 38090075Sobrien frame deopt_sender = stub_frame.sender(&dummy_map); // First is the deoptee frame 38196263Sobrien deopt_sender = deopt_sender.sender(&dummy_map); // Now deoptee caller 38296263Sobrien 38396263Sobrien // It's possible that the number of paramters at the call site is 38496263Sobrien // different than number of arguments in the callee when method 38590075Sobrien // handles are used. If the caller is interpreted get the real 38690075Sobrien // value so that the proper amount of space can be added to it's 38796263Sobrien // frame. 38896263Sobrien bool caller_was_method_handle = false; 38996263Sobrien if (deopt_sender.is_interpreted_frame()) { 39096263Sobrien methodHandle method = deopt_sender.interpreter_frame_method(); 39196263Sobrien Bytecode_invoke cur = Bytecode_invoke_check(method, deopt_sender.interpreter_frame_bci()); 39296263Sobrien if (cur.is_invokedynamic() || cur.is_invokehandle()) { 39396263Sobrien // Method handle invokes may involve fairly arbitrary chains of 39496263Sobrien // calls so it's impossible to know how much actual space the 39596263Sobrien // caller has for locals. 39696263Sobrien caller_was_method_handle = true; 39796263Sobrien } 39896263Sobrien } 39996263Sobrien 40096263Sobrien // 40196263Sobrien // frame_sizes/frame_pcs[0] oldest frame (int or c2i) 40296263Sobrien // frame_sizes/frame_pcs[1] next oldest frame (int) 40396263Sobrien // frame_sizes/frame_pcs[n] youngest frame (int) 40496263Sobrien // 40596263Sobrien // Now a pc in frame_pcs is actually the return address to the frame's caller (a frame 40696263Sobrien // owns the space for the return address to it's caller). Confusing ain't it. 40796263Sobrien // 40896263Sobrien // The vframe array can address vframes with indices running from 40996263Sobrien // 0.._frames-1. Index 0 is the youngest frame and _frame - 1 is the oldest (root) frame. 41096263Sobrien // When we create the skeletal frames we need the oldest frame to be in the zero slot 41196263Sobrien // in the frame_sizes/frame_pcs so the assembly code can do a trivial walk. 41296263Sobrien // so things look a little strange in this loop. 41396263Sobrien // 41496263Sobrien int callee_parameters = 0; 41596263Sobrien int callee_locals = 0; 41696263Sobrien for (int index = 0; index < array->frames(); index++ ) { 41796263Sobrien // frame[number_of_frames - 1 ] = on_stack_size(youngest) 41896263Sobrien // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest)) 41996263Sobrien // frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest))) 42096263Sobrien int caller_parms = callee_parameters; 42196263Sobrien if ((index == array->frames() - 1) && caller_was_method_handle) { 42296263Sobrien caller_parms = 0; 42396263Sobrien } 42496263Sobrien frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms, 42596263Sobrien callee_parameters, 42696263Sobrien callee_locals, 42796263Sobrien index == 0, 42896263Sobrien popframe_extra_args); 42996263Sobrien // This pc doesn't have to be perfect just good enough to identify the frame 43096263Sobrien // as interpreted so the skeleton frame will be walkable 43196263Sobrien // The correct pc will be set when the skeleton frame is completely filled out 43296263Sobrien // The final pc we store in the loop is wrong and will be overwritten below 43396263Sobrien frame_pcs[number_of_frames - 1 - index ] = Interpreter::deopt_entry(vtos, 0) - frame::pc_return_offset; 43496263Sobrien 43596263Sobrien callee_parameters = array->element(index)->method()->size_of_parameters(); 43696263Sobrien callee_locals = array->element(index)->method()->max_locals(); 43796263Sobrien popframe_extra_args = 0; 43896263Sobrien } 43996263Sobrien 44096263Sobrien // Compute whether the root vframe returns a float or double value. 44190075Sobrien BasicType return_type; 44290075Sobrien { 44390075Sobrien HandleMark hm; 44490075Sobrien methodHandle method(thread, array->element(0)->method()); 44590075Sobrien Bytecode_invoke invoke = Bytecode_invoke_check(method, array->element(0)->bci()); 44690075Sobrien return_type = invoke.is_valid() ? invoke.result_type() : T_ILLEGAL; 44790075Sobrien } 44890075Sobrien 44990075Sobrien // Compute information for handling adapters and adjusting the frame size of the caller. 45090075Sobrien int caller_adjustment = 0; 45190075Sobrien 45290075Sobrien // Compute the amount the oldest interpreter frame will have to adjust 45390075Sobrien // its caller's stack by. If the caller is a compiled frame then 45490075Sobrien // we pretend that the callee has no parameters so that the 45590075Sobrien // extension counts for the full amount of locals and not just 45690075Sobrien // locals-parms. This is because without a c2i adapter the parm 45790075Sobrien // area as created by the compiled frame will not be usable by 45890075Sobrien // the interpreter. (Depending on the calling convention there 45990075Sobrien // may not even be enough space). 46090075Sobrien 46190075Sobrien // QQQ I'd rather see this pushed down into last_frame_adjust 46290075Sobrien // and have it take the sender (aka caller). 46390075Sobrien 46490075Sobrien if (deopt_sender.is_compiled_frame() || caller_was_method_handle) { 46590075Sobrien caller_adjustment = last_frame_adjust(0, callee_locals); 46690075Sobrien } else if (callee_locals > callee_parameters) { 46790075Sobrien // The caller frame may need extending to accommodate 46890075Sobrien // non-parameter locals of the first unpacked interpreted frame. 46990075Sobrien // Compute that adjustment. 47090075Sobrien caller_adjustment = last_frame_adjust(callee_parameters, callee_locals); 47190075Sobrien } 47290075Sobrien 47390075Sobrien // If the sender is deoptimized the we must retrieve the address of the handler 47490075Sobrien // since the frame will "magically" show the original pc before the deopt 47590075Sobrien // and we'd undo the deopt. 47690075Sobrien 47790075Sobrien frame_pcs[0] = deopt_sender.raw_pc(); 47890075Sobrien 47990075Sobrien#ifndef SHARK 48090075Sobrien assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc"); 48190075Sobrien#endif // SHARK 48290075Sobrien 48390075Sobrien UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, 48490075Sobrien caller_adjustment * BytesPerWord, 48590075Sobrien caller_was_method_handle ? 0 : callee_parameters, 48690075Sobrien number_of_frames, 48796263Sobrien frame_sizes, 48896263Sobrien frame_pcs, 48990075Sobrien return_type); 49090075Sobrien // On some platforms, we need a way to pass some platform dependent 49190075Sobrien // information to the unpacking code so the skeletal frames come out 49290075Sobrien // correct (initial fp value, unextended sp, ...) 49390075Sobrien info->set_initial_info((intptr_t) array->sender().initial_deoptimization_info()); 49490075Sobrien 49590075Sobrien if (array->frames() > 1) { 49690075Sobrien if (VerifyStack && TraceDeoptimization) { 49790075Sobrien ttyLocker ttyl; 49890075Sobrien tty->print_cr("Deoptimizing method containing inlining"); 49990075Sobrien } 50090075Sobrien } 50190075Sobrien 50290075Sobrien array->set_unroll_block(info); 50390075Sobrien return info; 50490075Sobrien} 50590075Sobrien 50690075Sobrien// Called to cleanup deoptimization data structures in normal case 50790075Sobrien// after unpacking to stack and when stack overflow error occurs 50890075Sobrienvoid Deoptimization::cleanup_deopt_info(JavaThread *thread, 50990075Sobrien vframeArray *array) { 51090075Sobrien 51190075Sobrien // Get array if coming from exception 51290075Sobrien if (array == NULL) { 51390075Sobrien array = thread->vframe_array_head(); 51490075Sobrien } 51590075Sobrien thread->set_vframe_array_head(NULL); 51690075Sobrien 51790075Sobrien // Free the previous UnrollBlock 51890075Sobrien vframeArray* old_array = thread->vframe_array_last(); 51990075Sobrien thread->set_vframe_array_last(array); 52090075Sobrien 52190075Sobrien if (old_array != NULL) { 52296263Sobrien UnrollBlock* old_info = old_array->unroll_block(); 52390075Sobrien old_array->set_unroll_block(NULL); 52490075Sobrien delete old_info; 52590075Sobrien delete old_array; 52690075Sobrien } 52790075Sobrien 52890075Sobrien // Deallocate any resource creating in this routine and any ResourceObjs allocated 52990075Sobrien // inside the vframeArray (StackValueCollections) 53090075Sobrien 53190075Sobrien delete thread->deopt_mark(); 53290075Sobrien thread->set_deopt_mark(NULL); 53390075Sobrien thread->set_deopt_nmethod(NULL); 53490075Sobrien 53590075Sobrien 53690075Sobrien if (JvmtiExport::can_pop_frame()) { 53790075Sobrien#ifndef CC_INTERP 53890075Sobrien // Regardless of whether we entered this routine with the pending 53990075Sobrien // popframe condition bit set, we should always clear it now 54090075Sobrien thread->clear_popframe_condition(); 54190075Sobrien#else 54290075Sobrien // C++ interpeter will clear has_pending_popframe when it enters 54390075Sobrien // with method_resume. For deopt_resume2 we clear it now. 54490075Sobrien if (thread->popframe_forcing_deopt_reexecution()) 54590075Sobrien thread->clear_popframe_condition(); 54690075Sobrien#endif /* CC_INTERP */ 54790075Sobrien } 54890075Sobrien 54990075Sobrien // unpack_frames() is called at the end of the deoptimization handler 55090075Sobrien // and (in C2) at the end of the uncommon trap handler. Note this fact 55190075Sobrien // so that an asynchronous stack walker can work again. This counter is 55290075Sobrien // incremented at the beginning of fetch_unroll_info() and (in C2) at 55390075Sobrien // the beginning of uncommon_trap(). 55490075Sobrien thread->dec_in_deopt_handler(); 55596263Sobrien} 55696263Sobrien 55790075Sobrien 55890075Sobrien// Return BasicType of value being returned 55990075SobrienJRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_mode)) 56090075Sobrien 56190075Sobrien // We are already active int he special DeoptResourceMark any ResourceObj's we 56290075Sobrien // allocate will be freed at the end of the routine. 56390075Sobrien 56496263Sobrien // It is actually ok to allocate handles in a leaf method. It causes no safepoints, 56596263Sobrien // but makes the entry a little slower. There is however a little dance we have to 56696263Sobrien // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro 56796263Sobrien ResetNoHandleMark rnhm; // No-op in release/product versions 56896263Sobrien HandleMark hm; 56996263Sobrien 57090075Sobrien frame stub_frame = thread->last_frame(); 57190075Sobrien 57290075Sobrien // Since the frame to unpack is the top frame of this thread, the vframe_array_head 57390075Sobrien // must point to the vframeArray for the unpack frame. 57490075Sobrien vframeArray* array = thread->vframe_array_head(); 57590075Sobrien 57690075Sobrien#ifndef PRODUCT 57790075Sobrien if (TraceDeoptimization) { 57890075Sobrien ttyLocker ttyl; 57990075Sobrien tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode); 58090075Sobrien } 58190075Sobrien#endif 58290075Sobrien Events::log(thread, "DEOPT UNPACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT " mode %d", 58390075Sobrien stub_frame.pc(), stub_frame.sp(), exec_mode); 58496263Sobrien 58590075Sobrien UnrollBlock* info = array->unroll_block(); 58690075Sobrien 58790075Sobrien // Unpack the interpreter frames and any adapter frame (c2 only) we might create. 58896263Sobrien array->unpack_to_stack(stub_frame, exec_mode, info->caller_actual_parameters()); 58990075Sobrien 59090075Sobrien BasicType bt = info->return_type(); 59190075Sobrien 59290075Sobrien // If we have an exception pending, claim that the return type is an oop 59390075Sobrien // so the deopt_blob does not overwrite the exception_oop. 59490075Sobrien 59596263Sobrien if (exec_mode == Unpack_exception) 59696263Sobrien bt = T_OBJECT; 59790075Sobrien 59890075Sobrien // Cleanup thread deopt data 59990075Sobrien cleanup_deopt_info(thread, array); 60090075Sobrien 60196263Sobrien#ifndef PRODUCT 60290075Sobrien if (VerifyStack) { 60390075Sobrien ResourceMark res_mark; 60490075Sobrien 60590075Sobrien thread->validate_frame_layout(); 60690075Sobrien 60790075Sobrien // Verify that the just-unpacked frames match the interpreter's 60890075Sobrien // notions of expression stack and locals 60990075Sobrien vframeArray* cur_array = thread->vframe_array_last(); 61090075Sobrien RegisterMap rm(thread, false); 61190075Sobrien rm.set_include_argument_oops(false); 61290075Sobrien bool is_top_frame = true; 61390075Sobrien int callee_size_of_parameters = 0; 61490075Sobrien int callee_max_locals = 0; 61590075Sobrien for (int i = 0; i < cur_array->frames(); i++) { 61690075Sobrien vframeArrayElement* el = cur_array->element(i); 61790075Sobrien frame* iframe = el->iframe(); 61890075Sobrien guarantee(iframe->is_interpreted_frame(), "Wrong frame type"); 61990075Sobrien 62090075Sobrien // Get the oop map for this bci 62190075Sobrien InterpreterOopMap mask; 62290075Sobrien int cur_invoke_parameter_size = 0; 62390075Sobrien bool try_next_mask = false; 62490075Sobrien int next_mask_expression_stack_size = -1; 62590075Sobrien int top_frame_expression_stack_adjustment = 0; 62690075Sobrien methodHandle mh(thread, iframe->interpreter_frame_method()); 62790075Sobrien OopMapCache::compute_one_oop_map(mh, iframe->interpreter_frame_bci(), &mask); 628132718Skan BytecodeStream str(mh); 629132718Skan str.set_start(iframe->interpreter_frame_bci()); 630132718Skan int max_bci = mh->code_size(); 63190075Sobrien // Get to the next bytecode if possible 632132718Skan assert(str.bci() < max_bci, "bci in interpreter frame out of bounds"); 63390075Sobrien // Check to see if we can grab the number of outgoing arguments 63490075Sobrien // at an uncommon trap for an invoke (where the compiler 63590075Sobrien // generates debug info before the invoke has executed) 63690075Sobrien Bytecodes::Code cur_code = str.next(); 63790075Sobrien if (cur_code == Bytecodes::_invokevirtual || 63890075Sobrien cur_code == Bytecodes::_invokespecial || 63990075Sobrien cur_code == Bytecodes::_invokestatic || 64090075Sobrien cur_code == Bytecodes::_invokeinterface) { 64190075Sobrien Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci()); 64290075Sobrien Symbol* signature = invoke.signature(); 64390075Sobrien ArgumentSizeComputer asc(signature); 64490075Sobrien cur_invoke_parameter_size = asc.size(); 64590075Sobrien if (cur_code != Bytecodes::_invokestatic) { 64690075Sobrien // Add in receiver 64790075Sobrien ++cur_invoke_parameter_size; 64890075Sobrien } 64990075Sobrien } 65090075Sobrien if (str.bci() < max_bci) { 65190075Sobrien Bytecodes::Code bc = str.next(); 65290075Sobrien if (bc >= 0) { 65390075Sobrien // The interpreter oop map generator reports results before 65490075Sobrien // the current bytecode has executed except in the case of 65590075Sobrien // calls. It seems to be hard to tell whether the compiler 65690075Sobrien // has emitted debug information matching the "state before" 65790075Sobrien // a given bytecode or the state after, so we try both 65890075Sobrien switch (cur_code) { 65990075Sobrien case Bytecodes::_invokevirtual: 66090075Sobrien case Bytecodes::_invokespecial: 66190075Sobrien case Bytecodes::_invokestatic: 66290075Sobrien case Bytecodes::_invokeinterface: 66390075Sobrien case Bytecodes::_athrow: 66490075Sobrien break; 66590075Sobrien default: { 66690075Sobrien InterpreterOopMap next_mask; 66790075Sobrien OopMapCache::compute_one_oop_map(mh, str.bci(), &next_mask); 66890075Sobrien next_mask_expression_stack_size = next_mask.expression_stack_size(); 66990075Sobrien // Need to subtract off the size of the result type of 67090075Sobrien // the bytecode because this is not described in the 67190075Sobrien // debug info but returned to the interpreter in the TOS 67290075Sobrien // caching register 67390075Sobrien BasicType bytecode_result_type = Bytecodes::result_type(cur_code); 67490075Sobrien if (bytecode_result_type != T_ILLEGAL) { 67590075Sobrien top_frame_expression_stack_adjustment = type2size[bytecode_result_type]; 67690075Sobrien } 67790075Sobrien assert(top_frame_expression_stack_adjustment >= 0, ""); 67890075Sobrien try_next_mask = true; 67990075Sobrien break; 68090075Sobrien } 68190075Sobrien } 68290075Sobrien } 68390075Sobrien } 68490075Sobrien 68590075Sobrien // Verify stack depth and oops in frame 68690075Sobrien // This assertion may be dependent on the platform we're running on and may need modification (tested on x86 and sparc) 68796263Sobrien if (!( 68896263Sobrien /* SPARC */ 68990075Sobrien (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + callee_size_of_parameters) || 69090075Sobrien /* x86 */ 69190075Sobrien (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + callee_max_locals) || 69290075Sobrien (try_next_mask && 69390075Sobrien (iframe->interpreter_frame_expression_stack_size() == (next_mask_expression_stack_size - 69490075Sobrien top_frame_expression_stack_adjustment))) || 69590075Sobrien (is_top_frame && (exec_mode == Unpack_exception) && iframe->interpreter_frame_expression_stack_size() == 0) || 69690075Sobrien (is_top_frame && (exec_mode == Unpack_uncommon_trap || exec_mode == Unpack_reexecute) && 69790075Sobrien (iframe->interpreter_frame_expression_stack_size() == mask.expression_stack_size() + cur_invoke_parameter_size)) 69890075Sobrien )) { 69990075Sobrien ttyLocker ttyl; 70090075Sobrien 70190075Sobrien // Print out some information that will help us debug the problem 70290075Sobrien tty->print_cr("Wrong number of expression stack elements during deoptimization"); 70390075Sobrien tty->print_cr(" Error occurred while verifying frame %d (0..%d, 0 is topmost)", i, cur_array->frames() - 1); 70490075Sobrien tty->print_cr(" Fabricated interpreter frame had %d expression stack elements", 70590075Sobrien iframe->interpreter_frame_expression_stack_size()); 70690075Sobrien tty->print_cr(" Interpreter oop map had %d expression stack elements", mask.expression_stack_size()); 70790075Sobrien tty->print_cr(" try_next_mask = %d", try_next_mask); 70890075Sobrien tty->print_cr(" next_mask_expression_stack_size = %d", next_mask_expression_stack_size); 70990075Sobrien tty->print_cr(" callee_size_of_parameters = %d", callee_size_of_parameters); 71090075Sobrien tty->print_cr(" callee_max_locals = %d", callee_max_locals); 71190075Sobrien tty->print_cr(" top_frame_expression_stack_adjustment = %d", top_frame_expression_stack_adjustment); 71290075Sobrien tty->print_cr(" exec_mode = %d", exec_mode); 71390075Sobrien tty->print_cr(" cur_invoke_parameter_size = %d", cur_invoke_parameter_size); 71490075Sobrien tty->print_cr(" Thread = " INTPTR_FORMAT ", thread ID = " UINTX_FORMAT, thread, thread->osthread()->thread_id()); 71590075Sobrien tty->print_cr(" Interpreted frames:"); 71690075Sobrien for (int k = 0; k < cur_array->frames(); k++) { 71790075Sobrien vframeArrayElement* el = cur_array->element(k); 71890075Sobrien tty->print_cr(" %s (bci %d)", el->method()->name_and_sig_as_C_string(), el->bci()); 71990075Sobrien } 72090075Sobrien cur_array->print_on_2(tty); 72190075Sobrien guarantee(false, "wrong number of expression stack elements during deopt"); 72290075Sobrien } 72390075Sobrien VerifyOopClosure verify; 72490075Sobrien iframe->oops_interpreted_do(&verify, &rm, false); 72590075Sobrien callee_size_of_parameters = mh->size_of_parameters(); 72690075Sobrien callee_max_locals = mh->max_locals(); 72790075Sobrien is_top_frame = false; 72890075Sobrien } 72990075Sobrien } 73090075Sobrien#endif /* !PRODUCT */ 73190075Sobrien 73290075Sobrien 73390075Sobrien return bt; 73490075SobrienJRT_END 73590075Sobrien 73690075Sobrien 73790075Sobrienint Deoptimization::deoptimize_dependents() { 73890075Sobrien Threads::deoptimized_wrt_marked_nmethods(); 73990075Sobrien return 0; 74090075Sobrien} 74190075Sobrien 74290075Sobrien 74390075Sobrien#ifdef COMPILER2 74490075Sobrienbool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray<ScopeValue*>* objects, TRAPS) { 74590075Sobrien Handle pending_exception(thread->pending_exception()); 74690075Sobrien const char* exception_file = thread->exception_file(); 74790075Sobrien int exception_line = thread->exception_line(); 74890075Sobrien thread->clear_pending_exception(); 74990075Sobrien 75090075Sobrien for (int i = 0; i < objects->length(); i++) { 75190075Sobrien assert(objects->at(i)->is_object(), "invalid debug information"); 75290075Sobrien ObjectValue* sv = (ObjectValue*) objects->at(i); 75390075Sobrien 75490075Sobrien KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); 75590075Sobrien oop obj = NULL; 75690075Sobrien 75790075Sobrien if (k->oop_is_instance()) { 75890075Sobrien InstanceKlass* ik = InstanceKlass::cast(k()); 75990075Sobrien obj = ik->allocate_instance(CHECK_(false)); 76090075Sobrien } else if (k->oop_is_typeArray()) { 76190075Sobrien typeArrayKlass* ak = typeArrayKlass::cast(k()); 76290075Sobrien assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); 76390075Sobrien int len = sv->field_size() / type2size[ak->element_type()]; 76490075Sobrien obj = ak->allocate(len, CHECK_(false)); 76590075Sobrien } else if (k->oop_is_objArray()) { 76690075Sobrien objArrayKlass* ak = objArrayKlass::cast(k()); 76790075Sobrien obj = ak->allocate(sv->field_size(), CHECK_(false)); 76890075Sobrien } 76990075Sobrien 77090075Sobrien assert(obj != NULL, "allocation failed"); 77190075Sobrien assert(sv->value().is_null(), "redundant reallocation"); 77290075Sobrien sv->set_value(obj); 77390075Sobrien } 77490075Sobrien 77590075Sobrien if (pending_exception.not_null()) { 77690075Sobrien thread->set_pending_exception(pending_exception(), exception_file, exception_line); 77790075Sobrien } 77890075Sobrien 77990075Sobrien return true; 78090075Sobrien} 78190075Sobrien 78290075Sobrien// This assumes that the fields are stored in ObjectValue in the same order 78390075Sobrien// they are yielded by do_nonstatic_fields. 78490075Sobrienclass FieldReassigner: public FieldClosure { 78590075Sobrien frame* _fr; 78690075Sobrien RegisterMap* _reg_map; 78790075Sobrien ObjectValue* _sv; 78890075Sobrien InstanceKlass* _ik; 78990075Sobrien oop _obj; 79090075Sobrien 79190075Sobrien int _i; 79290075Sobrienpublic: 79390075Sobrien FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) : 79490075Sobrien _fr(fr), _reg_map(reg_map), _sv(sv), _obj(obj), _i(0) {} 79590075Sobrien 79690075Sobrien int i() const { return _i; } 79790075Sobrien 79890075Sobrien 79990075Sobrien void do_field(fieldDescriptor* fd) { 80090075Sobrien intptr_t val; 80190075Sobrien StackValue* value = 80290075Sobrien StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i())); 80390075Sobrien int offset = fd->offset(); 80490075Sobrien switch (fd->field_type()) { 80590075Sobrien case T_OBJECT: case T_ARRAY: 80690075Sobrien assert(value->type() == T_OBJECT, "Agreement."); 80790075Sobrien _obj->obj_field_put(offset, value->get_obj()()); 80890075Sobrien break; 80990075Sobrien 81090075Sobrien case T_LONG: case T_DOUBLE: { 81190075Sobrien assert(value->type() == T_INT, "Agreement."); 81290075Sobrien StackValue* low = 81390075Sobrien StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i)); 81490075Sobrien#ifdef _LP64 81590075Sobrien jlong res = (jlong)low->get_int(); 81690075Sobrien#else 81790075Sobrien#ifdef SPARC 81890075Sobrien // For SPARC we have to swap high and low words. 81990075Sobrien jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int()); 82090075Sobrien#else 82190075Sobrien jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); 82290075Sobrien#endif //SPARC 82390075Sobrien#endif 82490075Sobrien _obj->long_field_put(offset, res); 82596263Sobrien break; 82690075Sobrien } 82796263Sobrien // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. 82890075Sobrien case T_INT: case T_FLOAT: // 4 bytes. 82996263Sobrien assert(value->type() == T_INT, "Agreement."); 83096263Sobrien val = value->get_int(); 83196263Sobrien _obj->int_field_put(offset, (jint)*((jint*)&val)); 83296263Sobrien break; 83396263Sobrien 83490075Sobrien case T_SHORT: case T_CHAR: // 2 bytes 83590075Sobrien assert(value->type() == T_INT, "Agreement."); 83690075Sobrien val = value->get_int(); 83790075Sobrien _obj->short_field_put(offset, (jshort)*((jint*)&val)); 83890075Sobrien break; 83990075Sobrien 84090075Sobrien case T_BOOLEAN: case T_BYTE: // 1 byte 84190075Sobrien assert(value->type() == T_INT, "Agreement."); 84290075Sobrien val = value->get_int(); 84396263Sobrien _obj->bool_field_put(offset, (jboolean)*((jint*)&val)); 84490075Sobrien break; 84596263Sobrien 84696263Sobrien default: 84796263Sobrien ShouldNotReachHere(); 84896263Sobrien } 84996263Sobrien _i++; 85096263Sobrien } 85196263Sobrien}; 85290075Sobrien 85390075Sobrien// restore elements of an eliminated type array 85490075Sobrienvoid Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) { 85590075Sobrien int index = 0; 85690075Sobrien intptr_t val; 85790075Sobrien 85890075Sobrien for (int i = 0; i < sv->field_size(); i++) { 85990075Sobrien StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i)); 86090075Sobrien switch(type) { 86190075Sobrien case T_LONG: case T_DOUBLE: { 86290075Sobrien assert(value->type() == T_INT, "Agreement."); 86390075Sobrien StackValue* low = 86490075Sobrien StackValue::create_stack_value(fr, reg_map, sv->field_at(++i)); 86590075Sobrien#ifdef _LP64 86690075Sobrien jlong res = (jlong)low->get_int(); 86790075Sobrien#else 86890075Sobrien#ifdef SPARC 86990075Sobrien // For SPARC we have to swap high and low words. 87090075Sobrien jlong res = jlong_from((jint)low->get_int(), (jint)value->get_int()); 87190075Sobrien#else 87290075Sobrien jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); 87390075Sobrien#endif //SPARC 87490075Sobrien#endif 87590075Sobrien obj->long_at_put(index, res); 87690075Sobrien break; 87790075Sobrien } 87890075Sobrien 87990075Sobrien // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem. 88090075Sobrien case T_INT: case T_FLOAT: // 4 bytes. 88190075Sobrien assert(value->type() == T_INT, "Agreement."); 88290075Sobrien val = value->get_int(); 88390075Sobrien obj->int_at_put(index, (jint)*((jint*)&val)); 88490075Sobrien break; 88590075Sobrien 88690075Sobrien case T_SHORT: case T_CHAR: // 2 bytes 88790075Sobrien assert(value->type() == T_INT, "Agreement."); 88890075Sobrien val = value->get_int(); 88990075Sobrien obj->short_at_put(index, (jshort)*((jint*)&val)); 89090075Sobrien break; 89190075Sobrien 89290075Sobrien case T_BOOLEAN: case T_BYTE: // 1 byte 89390075Sobrien assert(value->type() == T_INT, "Agreement."); 89490075Sobrien val = value->get_int(); 89590075Sobrien obj->bool_at_put(index, (jboolean)*((jint*)&val)); 89690075Sobrien break; 89790075Sobrien 89890075Sobrien default: 89990075Sobrien ShouldNotReachHere(); 90090075Sobrien } 90190075Sobrien index++; 90290075Sobrien } 90390075Sobrien} 90490075Sobrien 90590075Sobrien 90690075Sobrien// restore fields of an eliminated object array 90790075Sobrienvoid Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) { 90890075Sobrien for (int i = 0; i < sv->field_size(); i++) { 90990075Sobrien StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i)); 91090075Sobrien assert(value->type() == T_OBJECT, "object element expected"); 91190075Sobrien obj->obj_at_put(i, value->get_obj()()); 91290075Sobrien } 91390075Sobrien} 91490075Sobrien 91590075Sobrien 91690075Sobrien// restore fields of all eliminated objects and arrays 91790075Sobrienvoid Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray<ScopeValue*>* objects) { 91890075Sobrien for (int i = 0; i < objects->length(); i++) { 91990075Sobrien ObjectValue* sv = (ObjectValue*) objects->at(i); 92090075Sobrien KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); 92190075Sobrien Handle obj = sv->value(); 92290075Sobrien assert(obj.not_null(), "reallocation was missed"); 92390075Sobrien 92490075Sobrien if (k->oop_is_instance()) { 92590075Sobrien InstanceKlass* ik = InstanceKlass::cast(k()); 92690075Sobrien FieldReassigner reassign(fr, reg_map, sv, obj()); 92790075Sobrien ik->do_nonstatic_fields(&reassign); 92890075Sobrien } else if (k->oop_is_typeArray()) { 92990075Sobrien typeArrayKlass* ak = typeArrayKlass::cast(k()); 93090075Sobrien reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type()); 93190075Sobrien } else if (k->oop_is_objArray()) { 93290075Sobrien reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj()); 93390075Sobrien } 93490075Sobrien } 93590075Sobrien} 93690075Sobrien 93790075Sobrien 93890075Sobrien// relock objects for which synchronization was eliminated 93990075Sobrienvoid Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread) { 94090075Sobrien for (int i = 0; i < monitors->length(); i++) { 94190075Sobrien MonitorInfo* mon_info = monitors->at(i); 94290075Sobrien if (mon_info->eliminated()) { 94390075Sobrien assert(mon_info->owner() != NULL, "reallocation was missed"); 94490075Sobrien Handle obj = Handle(mon_info->owner()); 94590075Sobrien markOop mark = obj->mark(); 94690075Sobrien if (UseBiasedLocking && mark->has_bias_pattern()) { 94790075Sobrien // New allocated objects may have the mark set to anonymously biased. 94890075Sobrien // Also the deoptimized method may called methods with synchronization 94990075Sobrien // where the thread-local object is bias locked to the current thread. 95090075Sobrien assert(mark->is_biased_anonymously() || 95190075Sobrien mark->biased_locker() == thread, "should be locked to current thread"); 95290075Sobrien // Reset mark word to unbiased prototype. 95390075Sobrien markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); 95490075Sobrien obj->set_mark(unbiased_prototype); 95590075Sobrien } 95690075Sobrien BasicLock* lock = mon_info->lock(); 95790075Sobrien ObjectSynchronizer::slow_enter(obj, lock, thread); 95890075Sobrien } 95990075Sobrien assert(mon_info->owner()->is_locked(), "object must be locked now"); 96090075Sobrien } 96190075Sobrien} 96290075Sobrien 96390075Sobrien 96490075Sobrien#ifndef PRODUCT 96590075Sobrien// print information about reallocated objects 96690075Sobrienvoid Deoptimization::print_objects(GrowableArray<ScopeValue*>* objects) { 96790075Sobrien fieldDescriptor fd; 96890075Sobrien 96990075Sobrien for (int i = 0; i < objects->length(); i++) { 97090075Sobrien ObjectValue* sv = (ObjectValue*) objects->at(i); 97190075Sobrien KlassHandle k(java_lang_Class::as_Klass(sv->klass()->as_ConstantOopReadValue()->value()())); 97290075Sobrien Handle obj = sv->value(); 97390075Sobrien 97490075Sobrien tty->print(" object <" INTPTR_FORMAT "> of type ", sv->value()()); 97590075Sobrien k->print_value(); 97690075Sobrien tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); 97790075Sobrien tty->cr(); 97890075Sobrien 97990075Sobrien if (Verbose) { 98090075Sobrien k->oop_print_on(obj(), tty); 98190075Sobrien } 98290075Sobrien } 98390075Sobrien} 98490075Sobrien#endif 98590075Sobrien#endif // COMPILER2 98690075Sobrien 98790075SobrienvframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray<compiledVFrame*>* chunk) { 98890075Sobrien Events::log(thread, "DEOPT PACKING pc=" INTPTR_FORMAT " sp=" INTPTR_FORMAT, fr.pc(), fr.sp()); 98990075Sobrien 99090075Sobrien#ifndef PRODUCT 99190075Sobrien if (TraceDeoptimization) { 99290075Sobrien ttyLocker ttyl; 99390075Sobrien tty->print("DEOPT PACKING thread " INTPTR_FORMAT " ", thread); 99490075Sobrien fr.print_on(tty); 99590075Sobrien tty->print_cr(" Virtual frames (innermost first):"); 99690075Sobrien for (int index = 0; index < chunk->length(); index++) { 99790075Sobrien compiledVFrame* vf = chunk->at(index); 99890075Sobrien tty->print(" %2d - ", index); 99990075Sobrien vf->print_value(); 100090075Sobrien int bci = chunk->at(index)->raw_bci(); 100190075Sobrien const char* code_name; 100290075Sobrien if (bci == SynchronizationEntryBCI) { 100390075Sobrien code_name = "sync entry"; 100490075Sobrien } else { 100590075Sobrien Bytecodes::Code code = vf->method()->code_at(bci); 100690075Sobrien code_name = Bytecodes::name(code); 100790075Sobrien } 100890075Sobrien tty->print(" - %s", code_name); 100990075Sobrien tty->print_cr(" @ bci %d ", bci); 101090075Sobrien if (Verbose) { 101190075Sobrien vf->print(); 101290075Sobrien tty->cr(); 101390075Sobrien } 101490075Sobrien } 101590075Sobrien } 101690075Sobrien#endif 101790075Sobrien 101890075Sobrien // Register map for next frame (used for stack crawl). We capture 101990075Sobrien // the state of the deopt'ing frame's caller. Thus if we need to 102090075Sobrien // stuff a C2I adapter we can properly fill in the callee-save 102190075Sobrien // register locations. 102290075Sobrien frame caller = fr.sender(reg_map); 102390075Sobrien int frame_size = caller.sp() - fr.sp(); 102490075Sobrien 102590075Sobrien frame sender = caller; 102690075Sobrien 102790075Sobrien // Since the Java thread being deoptimized will eventually adjust it's own stack, 102890075Sobrien // the vframeArray containing the unpacking information is allocated in the C heap. 102990075Sobrien // For Compiler1, the caller of the deoptimized frame is saved for use by unpack_frames(). 103090075Sobrien vframeArray* array = vframeArray::allocate(thread, frame_size, chunk, reg_map, sender, caller, fr); 103190075Sobrien 103290075Sobrien // Compare the vframeArray to the collected vframes 103390075Sobrien assert(array->structural_compare(thread, chunk), "just checking"); 103490075Sobrien 103590075Sobrien#ifndef PRODUCT 103690075Sobrien if (TraceDeoptimization) { 103790075Sobrien ttyLocker ttyl; 103890075Sobrien tty->print_cr(" Created vframeArray " INTPTR_FORMAT, array); 103990075Sobrien } 104090075Sobrien#endif // PRODUCT 104190075Sobrien 104290075Sobrien return array; 104390075Sobrien} 104490075Sobrien 104590075Sobrien 104690075Sobrienstatic void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) { 104790075Sobrien GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); 104890075Sobrien for (int i = 0; i < monitors->length(); i++) { 104990075Sobrien MonitorInfo* mon_info = monitors->at(i); 105090075Sobrien if (!mon_info->eliminated() && mon_info->owner() != NULL) { 105190075Sobrien objects_to_revoke->append(Handle(mon_info->owner())); 105290075Sobrien } 105390075Sobrien } 105490075Sobrien} 105590075Sobrien 105690075Sobrien 105790075Sobrienvoid Deoptimization::revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map) { 105890075Sobrien if (!UseBiasedLocking) { 105990075Sobrien return; 106090075Sobrien } 106190075Sobrien 106290075Sobrien GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); 106390075Sobrien 106490075Sobrien // Unfortunately we don't have a RegisterMap available in most of 106590075Sobrien // the places we want to call this routine so we need to walk the 106690075Sobrien // stack again to update the register map. 106790075Sobrien if (map == NULL || !map->update_map()) { 106890075Sobrien StackFrameStream sfs(thread, true); 106990075Sobrien bool found = false; 107090075Sobrien while (!found && !sfs.is_done()) { 107190075Sobrien frame* cur = sfs.current(); 107290075Sobrien sfs.next(); 107390075Sobrien found = cur->id() == fr.id(); 107490075Sobrien } 107590075Sobrien assert(found, "frame to be deoptimized not found on target thread's stack"); 107690075Sobrien map = sfs.register_map(); 107790075Sobrien } 107890075Sobrien 107990075Sobrien vframe* vf = vframe::new_vframe(&fr, map, thread); 108090075Sobrien compiledVFrame* cvf = compiledVFrame::cast(vf); 108190075Sobrien // Revoke monitors' biases in all scopes 108290075Sobrien while (!cvf->is_top()) { 108390075Sobrien collect_monitors(cvf, objects_to_revoke); 108490075Sobrien cvf = compiledVFrame::cast(cvf->sender()); 108590075Sobrien } 108690075Sobrien collect_monitors(cvf, objects_to_revoke); 108790075Sobrien 108890075Sobrien if (SafepointSynchronize::is_at_safepoint()) { 108990075Sobrien BiasedLocking::revoke_at_safepoint(objects_to_revoke); 109090075Sobrien } else { 109190075Sobrien BiasedLocking::revoke(objects_to_revoke); 109290075Sobrien } 109390075Sobrien} 109490075Sobrien 109590075Sobrien 109690075Sobrienvoid Deoptimization::revoke_biases_of_monitors(CodeBlob* cb) { 109790075Sobrien if (!UseBiasedLocking) { 109890075Sobrien return; 109990075Sobrien } 110090075Sobrien 110190075Sobrien assert(SafepointSynchronize::is_at_safepoint(), "must only be called from safepoint"); 110290075Sobrien GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>(); 110390075Sobrien for (JavaThread* jt = Threads::first(); jt != NULL ; jt = jt->next()) { 110490075Sobrien if (jt->has_last_Java_frame()) { 110590075Sobrien StackFrameStream sfs(jt, true); 110690075Sobrien while (!sfs.is_done()) { 110790075Sobrien frame* cur = sfs.current(); 110890075Sobrien if (cb->contains(cur->pc())) { 110990075Sobrien vframe* vf = vframe::new_vframe(cur, sfs.register_map(), jt); 111090075Sobrien compiledVFrame* cvf = compiledVFrame::cast(vf); 111190075Sobrien // Revoke monitors' biases in all scopes 111290075Sobrien while (!cvf->is_top()) { 111390075Sobrien collect_monitors(cvf, objects_to_revoke); 111490075Sobrien cvf = compiledVFrame::cast(cvf->sender()); 111590075Sobrien } 111690075Sobrien collect_monitors(cvf, objects_to_revoke); 111790075Sobrien } 111890075Sobrien sfs.next(); 111990075Sobrien } 112090075Sobrien } 112190075Sobrien } 112290075Sobrien BiasedLocking::revoke_at_safepoint(objects_to_revoke); 112390075Sobrien} 112490075Sobrien 112590075Sobrien 112690075Sobrienvoid Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr) { 112790075Sobrien assert(fr.can_be_deoptimized(), "checking frame type"); 112890075Sobrien 112990075Sobrien gather_statistics(Reason_constraint, Action_none, Bytecodes::_illegal); 113090075Sobrien 113190075Sobrien // Patch the nmethod so that when execution returns to it we will 113290075Sobrien // deopt the execution state and return to the interpreter. 113390075Sobrien fr.deoptimize(thread); 113490075Sobrien} 113590075Sobrien 113690075Sobrienvoid Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) { 113790075Sobrien // Deoptimize only if the frame comes from compile code. 113890075Sobrien // Do not deoptimize the frame which is already patched 113990075Sobrien // during the execution of the loops below. 114090075Sobrien if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) { 114190075Sobrien return; 114290075Sobrien } 114390075Sobrien ResourceMark rm; 114490075Sobrien DeoptimizationMarker dm; 114590075Sobrien if (UseBiasedLocking) { 114690075Sobrien revoke_biases_of_monitors(thread, fr, map); 114790075Sobrien } 114890075Sobrien deoptimize_single_frame(thread, fr); 114990075Sobrien 115090075Sobrien} 115190075Sobrien 115290075Sobrien 115390075Sobrienvoid Deoptimization::deoptimize_frame_internal(JavaThread* thread, intptr_t* id) { 115490075Sobrien assert(thread == Thread::current() || SafepointSynchronize::is_at_safepoint(), 115590075Sobrien "can only deoptimize other thread at a safepoint"); 115690075Sobrien // Compute frame and register map based on thread and sp. 115790075Sobrien RegisterMap reg_map(thread, UseBiasedLocking); 115890075Sobrien frame fr = thread->last_frame(); 115990075Sobrien while (fr.id() != id) { 116090075Sobrien fr = fr.sender(®_map); 116190075Sobrien } 116290075Sobrien deoptimize(thread, fr, ®_map); 116390075Sobrien} 116490075Sobrien 116590075Sobrien 116690075Sobrienvoid Deoptimization::deoptimize_frame(JavaThread* thread, intptr_t* id) { 116790075Sobrien if (thread == Thread::current()) { 116890075Sobrien Deoptimization::deoptimize_frame_internal(thread, id); 116990075Sobrien } else { 117090075Sobrien VM_DeoptimizeFrame deopt(thread, id); 117190075Sobrien VMThread::execute(&deopt); 117290075Sobrien } 117390075Sobrien} 117490075Sobrien 117590075Sobrien 117690075Sobrien// JVMTI PopFrame support 117790075SobrienJRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int bytes_to_save, void* start_address)) 117890075Sobrien{ 117990075Sobrien thread->popframe_preserve_args(in_ByteSize(bytes_to_save), start_address); 118090075Sobrien} 118190075SobrienJRT_END 118290075Sobrien 118390075Sobrien 118490075Sobrien#if defined(COMPILER2) || defined(SHARK) 118590075Sobrienvoid Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index, TRAPS) { 118690075Sobrien // in case of an unresolved klass entry, load the class. 118790075Sobrien if (constant_pool->tag_at(index).is_unresolved_klass()) { 118890075Sobrien Klass* tk = constant_pool->klass_at(index, CHECK); 118990075Sobrien return; 119090075Sobrien } 119190075Sobrien 119290075Sobrien if (!constant_pool->tag_at(index).is_symbol()) return; 119390075Sobrien 119490075Sobrien Handle class_loader (THREAD, InstanceKlass::cast(constant_pool->pool_holder())->class_loader()); 119590075Sobrien Symbol* symbol = constant_pool->symbol_at(index); 119690075Sobrien 119790075Sobrien // class name? 119890075Sobrien if (symbol->byte_at(0) != '(') { 119990075Sobrien Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); 120090075Sobrien SystemDictionary::resolve_or_null(symbol, class_loader, protection_domain, CHECK); 120190075Sobrien return; 120290075Sobrien } 120390075Sobrien 120490075Sobrien // then it must be a signature! 120590075Sobrien ResourceMark rm(THREAD); 120690075Sobrien for (SignatureStream ss(symbol); !ss.is_done(); ss.next()) { 120790075Sobrien if (ss.is_object()) { 120890075Sobrien Symbol* class_name = ss.as_symbol(CHECK); 120990075Sobrien Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); 121090075Sobrien SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK); 121190075Sobrien } 121290075Sobrien } 121390075Sobrien} 121490075Sobrien 121590075Sobrien 121690075Sobrienvoid Deoptimization::load_class_by_index(constantPoolHandle constant_pool, int index) { 121790075Sobrien EXCEPTION_MARK; 121890075Sobrien load_class_by_index(constant_pool, index, THREAD); 121990075Sobrien if (HAS_PENDING_EXCEPTION) { 122090075Sobrien // Exception happened during classloading. We ignore the exception here, since it 122190075Sobrien // is going to be rethrown since the current activation is going to be deoptimzied and 122290075Sobrien // the interpreter will re-execute the bytecode. 122390075Sobrien CLEAR_PENDING_EXCEPTION; 122490075Sobrien } 122590075Sobrien} 122690075Sobrien 122790075SobrienJRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint trap_request)) { 122890075Sobrien HandleMark hm; 122990075Sobrien 123090075Sobrien // uncommon_trap() is called at the beginning of the uncommon trap 123190075Sobrien // handler. Note this fact before we start generating temporary frames 123290075Sobrien // that can confuse an asynchronous stack walker. This counter is 123390075Sobrien // decremented at the end of unpack_frames(). 123490075Sobrien thread->inc_in_deopt_handler(); 123590075Sobrien 123690075Sobrien // We need to update the map if we have biased locking. 123790075Sobrien RegisterMap reg_map(thread, UseBiasedLocking); 123890075Sobrien frame stub_frame = thread->last_frame(); 123990075Sobrien frame fr = stub_frame.sender(®_map); 124090075Sobrien // Make sure the calling nmethod is not getting deoptimized and removed 124190075Sobrien // before we are done with it. 124290075Sobrien nmethodLocker nl(fr.pc()); 124390075Sobrien 124490075Sobrien // Log a message 124590075Sobrien Events::log_deopt_message(thread, "Uncommon trap %d fr.pc " INTPTR_FORMAT, 124690075Sobrien trap_request, fr.pc()); 124790075Sobrien 124890075Sobrien { 124990075Sobrien ResourceMark rm; 125090075Sobrien 125190075Sobrien // Revoke biases of any monitors in the frame to ensure we can migrate them 125290075Sobrien revoke_biases_of_monitors(thread, fr, ®_map); 125390075Sobrien 125490075Sobrien DeoptReason reason = trap_request_reason(trap_request); 125590075Sobrien DeoptAction action = trap_request_action(trap_request); 125690075Sobrien jint unloaded_class_index = trap_request_index(trap_request); // CP idx or -1 125790075Sobrien 125890075Sobrien vframe* vf = vframe::new_vframe(&fr, ®_map, thread); 125990075Sobrien compiledVFrame* cvf = compiledVFrame::cast(vf); 126090075Sobrien 126190075Sobrien nmethod* nm = cvf->code(); 126290075Sobrien 126390075Sobrien ScopeDesc* trap_scope = cvf->scope(); 126490075Sobrien methodHandle trap_method = trap_scope->method(); 126590075Sobrien int trap_bci = trap_scope->bci(); 126690075Sobrien Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci); 126790075Sobrien 126890075Sobrien // Record this event in the histogram. 126990075Sobrien gather_statistics(reason, action, trap_bc); 127090075Sobrien 127190075Sobrien // Ensure that we can record deopt. history: 127290075Sobrien bool create_if_missing = ProfileTraps; 127390075Sobrien 127490075Sobrien MethodData* trap_mdo = 127590075Sobrien get_method_data(thread, trap_method, create_if_missing); 127690075Sobrien 127790075Sobrien // Print a bunch of diagnostics, if requested. 127890075Sobrien if (TraceDeoptimization || LogCompilation) { 127990075Sobrien ResourceMark rm; 128090075Sobrien ttyLocker ttyl; 128190075Sobrien char buf[100]; 128290075Sobrien if (xtty != NULL) { 128390075Sobrien xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT"' %s", 128490075Sobrien os::current_thread_id(), 128590075Sobrien format_trap_request(buf, sizeof(buf), trap_request)); 128690075Sobrien nm->log_identity(xtty); 128790075Sobrien } 128890075Sobrien Symbol* class_name = NULL; 128990075Sobrien bool unresolved = false; 129090075Sobrien if (unloaded_class_index >= 0) { 129190075Sobrien constantPoolHandle constants (THREAD, trap_method->constants()); 129290075Sobrien if (constants->tag_at(unloaded_class_index).is_unresolved_klass()) { 129390075Sobrien class_name = constants->klass_name_at(unloaded_class_index); 129490075Sobrien unresolved = true; 129590075Sobrien if (xtty != NULL) 129690075Sobrien xtty->print(" unresolved='1'"); 129790075Sobrien } else if (constants->tag_at(unloaded_class_index).is_symbol()) { 129890075Sobrien class_name = constants->symbol_at(unloaded_class_index); 129990075Sobrien } 130090075Sobrien if (xtty != NULL) 130190075Sobrien xtty->name(class_name); 130290075Sobrien } 130390075Sobrien if (xtty != NULL && trap_mdo != NULL) { 130490075Sobrien // Dump the relevant MDO state. 130590075Sobrien // This is the deopt count for the current reason, any previous 130690075Sobrien // reasons or recompiles seen at this point. 130790075Sobrien int dcnt = trap_mdo->trap_count(reason); 130890075Sobrien if (dcnt != 0) 130990075Sobrien xtty->print(" count='%d'", dcnt); 131090075Sobrien ProfileData* pdata = trap_mdo->bci_to_data(trap_bci); 131190075Sobrien int dos = (pdata == NULL)? 0: pdata->trap_state(); 131290075Sobrien if (dos != 0) { 131390075Sobrien xtty->print(" state='%s'", format_trap_state(buf, sizeof(buf), dos)); 131490075Sobrien if (trap_state_is_recompiled(dos)) { 131590075Sobrien int recnt2 = trap_mdo->overflow_recompile_count(); 131690075Sobrien if (recnt2 != 0) 131790075Sobrien xtty->print(" recompiles2='%d'", recnt2); 131890075Sobrien } 131990075Sobrien } 132090075Sobrien } 132190075Sobrien if (xtty != NULL) { 132290075Sobrien xtty->stamp(); 132390075Sobrien xtty->end_head(); 132490075Sobrien } 132590075Sobrien if (TraceDeoptimization) { // make noise on the tty 132690075Sobrien tty->print("Uncommon trap occurred in"); 132790075Sobrien nm->method()->print_short_name(tty); 132890075Sobrien tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d", 132990075Sobrien fr.pc(), 133090075Sobrien os::current_thread_id(), 133190075Sobrien trap_reason_name(reason), 133290075Sobrien trap_action_name(action), 133390075Sobrien unloaded_class_index); 133490075Sobrien if (class_name != NULL) { 133590075Sobrien tty->print(unresolved ? " unresolved class: " : " symbol: "); 133690075Sobrien class_name->print_symbol_on(tty); 133790075Sobrien } 133890075Sobrien tty->cr(); 133990075Sobrien } 134090075Sobrien if (xtty != NULL) { 134190075Sobrien // Log the precise location of the trap. 134290075Sobrien for (ScopeDesc* sd = trap_scope; ; sd = sd->sender()) { 134390075Sobrien xtty->begin_elem("jvms bci='%d'", sd->bci()); 134490075Sobrien xtty->method(sd->method()); 134590075Sobrien xtty->end_elem(); 134690075Sobrien if (sd->is_top()) break; 134790075Sobrien } 134890075Sobrien xtty->tail("uncommon_trap"); 134990075Sobrien } 135090075Sobrien } 135190075Sobrien // (End diagnostic printout.) 135290075Sobrien 135390075Sobrien // Load class if necessary 135490075Sobrien if (unloaded_class_index >= 0) { 135590075Sobrien constantPoolHandle constants(THREAD, trap_method->constants()); 135690075Sobrien load_class_by_index(constants, unloaded_class_index); 135790075Sobrien } 135890075Sobrien 135990075Sobrien // Flush the nmethod if necessary and desirable. 136090075Sobrien // 136190075Sobrien // We need to avoid situations where we are re-flushing the nmethod 136290075Sobrien // because of a hot deoptimization site. Repeated flushes at the same 136390075Sobrien // point need to be detected by the compiler and avoided. If the compiler 136490075Sobrien // cannot avoid them (or has a bug and "refuses" to avoid them), this 136590075Sobrien // module must take measures to avoid an infinite cycle of recompilation 136690075Sobrien // and deoptimization. There are several such measures: 136790075Sobrien // 136890075Sobrien // 1. If a recompilation is ordered a second time at some site X 136990075Sobrien // and for the same reason R, the action is adjusted to 'reinterpret', 137090075Sobrien // to give the interpreter time to exercise the method more thoroughly. 137190075Sobrien // If this happens, the method's overflow_recompile_count is incremented. 137290075Sobrien // 137390075Sobrien // 2. If the compiler fails to reduce the deoptimization rate, then 137490075Sobrien // the method's overflow_recompile_count will begin to exceed the set 137590075Sobrien // limit PerBytecodeRecompilationCutoff. If this happens, the action 137690075Sobrien // is adjusted to 'make_not_compilable', and the method is abandoned 137790075Sobrien // to the interpreter. This is a performance hit for hot methods, 137890075Sobrien // but is better than a disastrous infinite cycle of recompilations. 137990075Sobrien // (Actually, only the method containing the site X is abandoned.) 138090075Sobrien // 138190075Sobrien // 3. In parallel with the previous measures, if the total number of 138290075Sobrien // recompilations of a method exceeds the much larger set limit 138390075Sobrien // PerMethodRecompilationCutoff, the method is abandoned. 138490075Sobrien // This should only happen if the method is very large and has 138590075Sobrien // many "lukewarm" deoptimizations. The code which enforces this 138690075Sobrien // limit is elsewhere (class nmethod, class Method). 138790075Sobrien // 138890075Sobrien // Note that the per-BCI 'is_recompiled' bit gives the compiler one chance 138990075Sobrien // to recompile at each bytecode independently of the per-BCI cutoff. 139090075Sobrien // 139190075Sobrien // The decision to update code is up to the compiler, and is encoded 139290075Sobrien // in the Action_xxx code. If the compiler requests Action_none 139390075Sobrien // no trap state is changed, no compiled code is changed, and the 139490075Sobrien // computation suffers along in the interpreter. 139590075Sobrien // 139690075Sobrien // The other action codes specify various tactics for decompilation 139790075Sobrien // and recompilation. Action_maybe_recompile is the loosest, and 139890075Sobrien // allows the compiled code to stay around until enough traps are seen, 139990075Sobrien // and until the compiler gets around to recompiling the trapping method. 140090075Sobrien // 140190075Sobrien // The other actions cause immediate removal of the present code. 140290075Sobrien 140390075Sobrien bool update_trap_state = true; 140490075Sobrien bool make_not_entrant = false; 140590075Sobrien bool make_not_compilable = false; 140690075Sobrien bool reprofile = false; 140790075Sobrien switch (action) { 140890075Sobrien case Action_none: 140990075Sobrien // Keep the old code. 1410117395Skan update_trap_state = false; 141190075Sobrien break; 141290075Sobrien case Action_maybe_recompile: 141390075Sobrien // Do not need to invalidate the present code, but we can 141490075Sobrien // initiate another 141590075Sobrien // Start compiler without (necessarily) invalidating the nmethod. 141690075Sobrien // The system will tolerate the old code, but new code should be 141790075Sobrien // generated when possible. 141890075Sobrien break; 141990075Sobrien case Action_reinterpret: 142090075Sobrien // Go back into the interpreter for a while, and then consider 142190075Sobrien // recompiling form scratch. 142290075Sobrien make_not_entrant = true; 142390075Sobrien // Reset invocation counter for outer most method. 142490075Sobrien // This will allow the interpreter to exercise the bytecodes 142590075Sobrien // for a while before recompiling. 142690075Sobrien // By contrast, Action_make_not_entrant is immediate. 142790075Sobrien // 142890075Sobrien // Note that the compiler will track null_check, null_assert, 142990075Sobrien // range_check, and class_check events and log them as if they 143090075Sobrien // had been traps taken from compiled code. This will update 143190075Sobrien // the MDO trap history so that the next compilation will 143290075Sobrien // properly detect hot trap sites. 143390075Sobrien reprofile = true; 143490075Sobrien break; 143590075Sobrien case Action_make_not_entrant: 143690075Sobrien // Request immediate recompilation, and get rid of the old code. 143790075Sobrien // Make them not entrant, so next time they are called they get 143890075Sobrien // recompiled. Unloaded classes are loaded now so recompile before next 143990075Sobrien // time they are called. Same for uninitialized. The interpreter will 144090075Sobrien // link the missing class, if any. 144190075Sobrien make_not_entrant = true; 144290075Sobrien break; 144390075Sobrien case Action_make_not_compilable: 144490075Sobrien // Give up on compiling this method at all. 144590075Sobrien make_not_entrant = true; 144690075Sobrien make_not_compilable = true; 144790075Sobrien break; 144890075Sobrien default: 144990075Sobrien ShouldNotReachHere(); 145090075Sobrien } 145190075Sobrien 145290075Sobrien // Setting +ProfileTraps fixes the following, on all platforms: 145390075Sobrien // 4852688: ProfileInterpreter is off by default for ia64. The result is 145490075Sobrien // infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the 145590075Sobrien // recompile relies on a MethodData* to record heroic opt failures. 145690075Sobrien 145790075Sobrien // Whether the interpreter is producing MDO data or not, we also need 145890075Sobrien // to use the MDO to detect hot deoptimization points and control 145990075Sobrien // aggressive optimization. 146090075Sobrien bool inc_recompile_count = false; 146190075Sobrien ProfileData* pdata = NULL; 146290075Sobrien if (ProfileTraps && update_trap_state && trap_mdo != NULL) { 146390075Sobrien assert(trap_mdo == get_method_data(thread, trap_method, false), "sanity"); 146490075Sobrien uint this_trap_count = 0; 146590075Sobrien bool maybe_prior_trap = false; 146690075Sobrien bool maybe_prior_recompile = false; 146790075Sobrien pdata = query_update_method_data(trap_mdo, trap_bci, reason, 146890075Sobrien //outputs: 146990075Sobrien this_trap_count, 147090075Sobrien maybe_prior_trap, 147190075Sobrien maybe_prior_recompile); 147290075Sobrien // Because the interpreter also counts null, div0, range, and class 147390075Sobrien // checks, these traps from compiled code are double-counted. 1474132718Skan // This is harmless; it just means that the PerXTrapLimit values 147590075Sobrien // are in effect a little smaller than they look. 147690075Sobrien 147790075Sobrien DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason); 147890075Sobrien if (per_bc_reason != Reason_none) { 147990075Sobrien // Now take action based on the partially known per-BCI history. 148090075Sobrien if (maybe_prior_trap 148190075Sobrien && this_trap_count >= (uint)PerBytecodeTrapLimit) { 148290075Sobrien // If there are too many traps at this BCI, force a recompile. 148390075Sobrien // This will allow the compiler to see the limit overflow, and 148490075Sobrien // take corrective action, if possible. The compiler generally 148590075Sobrien // does not use the exact PerBytecodeTrapLimit value, but instead 148690075Sobrien // changes its tactics if it sees any traps at all. This provides 148790075Sobrien // a little hysteresis, delaying a recompile until a trap happens 148890075Sobrien // several times. 148990075Sobrien // 149090075Sobrien // Actually, since there is only one bit of counter per BCI, 149190075Sobrien // the possible per-BCI counts are {0,1,(per-method count)}. 149290075Sobrien // This produces accurate results if in fact there is only 149390075Sobrien // one hot trap site, but begins to get fuzzy if there are 149490075Sobrien // many sites. For example, if there are ten sites each 149590075Sobrien // trapping two or more times, they each get the blame for 149690075Sobrien // all of their traps. 149790075Sobrien make_not_entrant = true; 1498132718Skan } 1499132718Skan 1500132718Skan // Detect repeated recompilation at the same BCI, and enforce a limit. 1501132718Skan if (make_not_entrant && maybe_prior_recompile) { 1502132718Skan // More than one recompile at this point. 1503132718Skan inc_recompile_count = maybe_prior_trap; 1504132718Skan } 1505132718Skan } else { 1506132718Skan // For reasons which are not recorded per-bytecode, we simply 1507132718Skan // force recompiles unconditionally. 1508132718Skan // (Note that PerMethodRecompilationCutoff is enforced elsewhere.) 1509132718Skan make_not_entrant = true; 1510132718Skan } 1511132718Skan 1512132718Skan // Go back to the compiler if there are too many traps in this method. 1513132718Skan if (this_trap_count >= (uint)PerMethodTrapLimit) { 1514132718Skan // If there are too many traps in this method, force a recompile. 1515132718Skan // This will allow the compiler to see the limit overflow, and 1516132718Skan // take corrective action, if possible. 1517132718Skan // (This condition is an unlikely backstop only, because the 1518132718Skan // PerBytecodeTrapLimit is more likely to take effect first, 1519132718Skan // if it is applicable.) 1520132718Skan make_not_entrant = true; 1521132718Skan } 1522132718Skan 1523132718Skan // Here's more hysteresis: If there has been a recompile at 1524132718Skan // this trap point already, run the method in the interpreter 1525132718Skan // for a while to exercise it more thoroughly. 1526132718Skan if (make_not_entrant && maybe_prior_recompile && maybe_prior_trap) { 1527132718Skan reprofile = true; 1528132718Skan } 1529132718Skan 1530132718Skan } 1531132718Skan 1532132718Skan // Take requested actions on the method: 1533132718Skan 1534132718Skan // Recompile 1535132718Skan if (make_not_entrant) { 1536132718Skan if (!nm->make_not_entrant()) { 1537132718Skan return; // the call did not change nmethod's state 1538132718Skan } 1539132718Skan 1540132718Skan if (pdata != NULL) { 1541132718Skan // Record the recompilation event, if any. 1542132718Skan int tstate0 = pdata->trap_state(); 1543132718Skan int tstate1 = trap_state_set_recompiled(tstate0, true); 1544132718Skan if (tstate1 != tstate0) 1545132718Skan pdata->set_trap_state(tstate1); 1546132718Skan } 1547132718Skan } 1548132718Skan 1549132718Skan if (inc_recompile_count) { 1550132718Skan trap_mdo->inc_overflow_recompile_count(); 1551132718Skan if ((uint)trap_mdo->overflow_recompile_count() > 1552132718Skan (uint)PerBytecodeRecompilationCutoff) { 1553132718Skan // Give up on the method containing the bad BCI. 1554132718Skan if (trap_method() == nm->method()) { 1555132718Skan make_not_compilable = true; 1556132718Skan } else { 1557132718Skan trap_method->set_not_compilable(CompLevel_full_optimization); 1558132718Skan // But give grace to the enclosing nm->method(). 1559132718Skan } 1560132718Skan } 1561132718Skan } 1562132718Skan 1563132718Skan // Reprofile 1564132718Skan if (reprofile) { 1565132718Skan CompilationPolicy::policy()->reprofile(trap_scope, nm->is_osr_method()); 1566132718Skan } 1567132718Skan 1568132718Skan // Give up compiling 1569132718Skan if (make_not_compilable && !nm->method()->is_not_compilable(CompLevel_full_optimization)) { 1570132718Skan assert(make_not_entrant, "consistent"); 1571132718Skan nm->method()->set_not_compilable(CompLevel_full_optimization); 157290075Sobrien } 157390075Sobrien 157490075Sobrien } // Free marked resources 157590075Sobrien 157690075Sobrien} 157790075SobrienJRT_END 157890075Sobrien 157990075SobrienMethodData* 158090075SobrienDeoptimization::get_method_data(JavaThread* thread, methodHandle m, 158190075Sobrien bool create_if_missing) { 158290075Sobrien Thread* THREAD = thread; 158390075Sobrien MethodData* mdo = m()->method_data(); 158490075Sobrien if (mdo == NULL && create_if_missing && !HAS_PENDING_EXCEPTION) { 158590075Sobrien // Build an MDO. Ignore errors like OutOfMemory; 158690075Sobrien // that simply means we won't have an MDO to update. 158790075Sobrien Method::build_interpreter_method_data(m, THREAD); 158890075Sobrien if (HAS_PENDING_EXCEPTION) { 158990075Sobrien assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); 159090075Sobrien CLEAR_PENDING_EXCEPTION; 159190075Sobrien } 159290075Sobrien mdo = m()->method_data(); 159390075Sobrien } 159490075Sobrien return mdo; 159590075Sobrien} 159690075Sobrien 159790075SobrienProfileData* 159890075SobrienDeoptimization::query_update_method_data(MethodData* trap_mdo, 159990075Sobrien int trap_bci, 160090075Sobrien Deoptimization::DeoptReason reason, 160190075Sobrien //outputs: 160290075Sobrien uint& ret_this_trap_count, 160390075Sobrien bool& ret_maybe_prior_trap, 160490075Sobrien bool& ret_maybe_prior_recompile) { 160590075Sobrien uint prior_trap_count = trap_mdo->trap_count(reason); 160690075Sobrien uint this_trap_count = trap_mdo->inc_trap_count(reason); 160790075Sobrien 160890075Sobrien // If the runtime cannot find a place to store trap history, 160990075Sobrien // it is estimated based on the general condition of the method. 161090075Sobrien // If the method has ever been recompiled, or has ever incurred 161190075Sobrien // a trap with the present reason , then this BCI is assumed 161290075Sobrien // (pessimistically) to be the culprit. 161390075Sobrien bool maybe_prior_trap = (prior_trap_count != 0); 161490075Sobrien bool maybe_prior_recompile = (trap_mdo->decompile_count() != 0); 161590075Sobrien ProfileData* pdata = NULL; 161690075Sobrien 161790075Sobrien 161890075Sobrien // For reasons which are recorded per bytecode, we check per-BCI data. 161990075Sobrien DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason); 162090075Sobrien if (per_bc_reason != Reason_none) { 162190075Sobrien // Find the profile data for this BCI. If there isn't one, 162290075Sobrien // try to allocate one from the MDO's set of spares. 162390075Sobrien // This will let us detect a repeated trap at this point. 162490075Sobrien pdata = trap_mdo->allocate_bci_to_data(trap_bci); 162590075Sobrien 162690075Sobrien if (pdata != NULL) { 162790075Sobrien // Query the trap state of this profile datum. 162890075Sobrien int tstate0 = pdata->trap_state(); 162990075Sobrien if (!trap_state_has_reason(tstate0, per_bc_reason)) 163090075Sobrien maybe_prior_trap = false; 1631132718Skan if (!trap_state_is_recompiled(tstate0)) 163290075Sobrien maybe_prior_recompile = false; 1633132718Skan 1634132718Skan // Update the trap state of this profile datum. 163590075Sobrien int tstate1 = tstate0; 163690075Sobrien // Record the reason. 163790075Sobrien tstate1 = trap_state_add_reason(tstate1, per_bc_reason); 163890075Sobrien // Store the updated state on the MDO, for next time. 163990075Sobrien if (tstate1 != tstate0) 164090075Sobrien pdata->set_trap_state(tstate1); 164190075Sobrien } else { 164290075Sobrien if (LogCompilation && xtty != NULL) { 164390075Sobrien ttyLocker ttyl; 1644132718Skan // Missing MDP? Leave a small complaint in the log. 164590075Sobrien xtty->elem("missing_mdp bci='%d'", trap_bci); 1646132718Skan } 1647132718Skan } 164890075Sobrien } 164990075Sobrien 165090075Sobrien // Return results: 165190075Sobrien ret_this_trap_count = this_trap_count; 165290075Sobrien ret_maybe_prior_trap = maybe_prior_trap; 165390075Sobrien ret_maybe_prior_recompile = maybe_prior_recompile; 165490075Sobrien return pdata; 165590075Sobrien} 165690075Sobrien 165790075Sobrienvoid 165890075SobrienDeoptimization::update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason) { 165990075Sobrien ResourceMark rm; 166090075Sobrien // Ignored outputs: 166190075Sobrien uint ignore_this_trap_count; 166290075Sobrien bool ignore_maybe_prior_trap; 166390075Sobrien bool ignore_maybe_prior_recompile; 166490075Sobrien query_update_method_data(trap_mdo, trap_bci, 166590075Sobrien (DeoptReason)reason, 166690075Sobrien ignore_this_trap_count, 166790075Sobrien ignore_maybe_prior_trap, 166890075Sobrien ignore_maybe_prior_recompile); 166990075Sobrien} 167090075Sobrien 167190075SobrienDeoptimization::UnrollBlock* Deoptimization::uncommon_trap(JavaThread* thread, jint trap_request) { 167290075Sobrien 167390075Sobrien // Still in Java no safepoints 167490075Sobrien { 167590075Sobrien // This enters VM and may safepoint 167690075Sobrien uncommon_trap_inner(thread, trap_request); 167790075Sobrien } 167890075Sobrien return fetch_unroll_info_helper(thread); 167990075Sobrien} 168090075Sobrien 168190075Sobrien// Local derived constants. 168290075Sobrien// Further breakdown of DataLayout::trap_state, as promised by DataLayout. 168390075Sobrienconst int DS_REASON_MASK = DataLayout::trap_mask >> 1; 168490075Sobrienconst int DS_RECOMPILE_BIT = DataLayout::trap_mask - DS_REASON_MASK; 168590075Sobrien 168690075Sobrien//---------------------------trap_state_reason--------------------------------- 168790075SobrienDeoptimization::DeoptReason 168890075SobrienDeoptimization::trap_state_reason(int trap_state) { 168990075Sobrien // This assert provides the link between the width of DataLayout::trap_bits 169090075Sobrien // and the encoding of "recorded" reasons. It ensures there are enough 169190075Sobrien // bits to store all needed reasons in the per-BCI MDO profile. 169290075Sobrien assert(DS_REASON_MASK >= Reason_RECORDED_LIMIT, "enough bits"); 169390075Sobrien int recompile_bit = (trap_state & DS_RECOMPILE_BIT); 169490075Sobrien trap_state -= recompile_bit; 169590075Sobrien if (trap_state == DS_REASON_MASK) { 169690075Sobrien return Reason_many; 169790075Sobrien } else { 169890075Sobrien assert((int)Reason_none == 0, "state=0 => Reason_none"); 169990075Sobrien return (DeoptReason)trap_state; 170090075Sobrien } 170190075Sobrien} 170290075Sobrien//-------------------------trap_state_has_reason------------------------------- 170390075Sobrienint Deoptimization::trap_state_has_reason(int trap_state, int reason) { 170490075Sobrien assert(reason_is_recorded_per_bytecode((DeoptReason)reason), "valid reason"); 170590075Sobrien assert(DS_REASON_MASK >= Reason_RECORDED_LIMIT, "enough bits"); 170690075Sobrien int recompile_bit = (trap_state & DS_RECOMPILE_BIT); 1707169689Skan trap_state -= recompile_bit; 1708169689Skan if (trap_state == DS_REASON_MASK) { 1709169689Skan return -1; // true, unspecifically (bottom of state lattice) 1710169689Skan } else if (trap_state == reason) { 1711169689Skan return 1; // true, definitely 1712169689Skan } else if (trap_state == 0) { 1713169689Skan return 0; // false, definitely (top of state lattice) 171490075Sobrien } else { 171590075Sobrien return 0; // false, definitely 171690075Sobrien } 171790075Sobrien} 171890075Sobrien//-------------------------trap_state_add_reason------------------------------- 171990075Sobrienint Deoptimization::trap_state_add_reason(int trap_state, int reason) { 172090075Sobrien assert(reason_is_recorded_per_bytecode((DeoptReason)reason) || reason == Reason_many, "valid reason"); 172190075Sobrien int recompile_bit = (trap_state & DS_RECOMPILE_BIT); 172290075Sobrien trap_state -= recompile_bit; 172390075Sobrien if (trap_state == DS_REASON_MASK) { 172490075Sobrien return trap_state + recompile_bit; // already at state lattice bottom 172590075Sobrien } else if (trap_state == reason) { 172690075Sobrien return trap_state + recompile_bit; // the condition is already true 172790075Sobrien } else if (trap_state == 0) { 172890075Sobrien return reason + recompile_bit; // no condition has yet been true 172990075Sobrien } else { 173090075Sobrien return DS_REASON_MASK + recompile_bit; // fall to state lattice bottom 173190075Sobrien } 173290075Sobrien} 173390075Sobrien//-----------------------trap_state_is_recompiled------------------------------ 1734117395Skanbool Deoptimization::trap_state_is_recompiled(int trap_state) { 1735117395Skan return (trap_state & DS_RECOMPILE_BIT) != 0; 1736117395Skan} 1737117395Skan//-----------------------trap_state_set_recompiled----------------------------- 1738117395Skanint Deoptimization::trap_state_set_recompiled(int trap_state, bool z) { 1739117395Skan if (z) return trap_state | DS_RECOMPILE_BIT; 1740117395Skan else return trap_state & ~DS_RECOMPILE_BIT; 1741117395Skan} 1742117395Skan//---------------------------format_trap_state--------------------------------- 1743117395Skan// This is used for debugging and diagnostics, including hotspot.log output. 1744117395Skanconst char* Deoptimization::format_trap_state(char* buf, size_t buflen, 1745117395Skan int trap_state) { 1746117395Skan DeoptReason reason = trap_state_reason(trap_state); 1747117395Skan bool recomp_flag = trap_state_is_recompiled(trap_state); 1748117395Skan // Re-encode the state from its decoded components. 1749117395Skan int decoded_state = 0; 1750117395Skan if (reason_is_recorded_per_bytecode(reason) || reason == Reason_many) 1751117395Skan decoded_state = trap_state_add_reason(decoded_state, reason); 1752117395Skan if (recomp_flag) 1753117395Skan decoded_state = trap_state_set_recompiled(decoded_state, recomp_flag); 1754117395Skan // If the state re-encodes properly, format it symbolically. 1755117395Skan // Because this routine is used for debugging and diagnostics, 1756117395Skan // be robust even if the state is a strange value. 1757122180Skan size_t len; 1758122180Skan if (decoded_state != trap_state) { 1759122180Skan // Random buggy state that doesn't decode?? 1760122180Skan len = jio_snprintf(buf, buflen, "#%d", trap_state); 1761122180Skan } else { 1762122180Skan len = jio_snprintf(buf, buflen, "%s%s", 1763122180Skan trap_reason_name(reason), 1764122180Skan recomp_flag ? " recompiled" : ""); 1765169689Skan } 1766169689Skan if (len >= buflen) 1767169689Skan buf[buflen-1] = '\0'; 176890075Sobrien return buf; 176990075Sobrien} 177090075Sobrien 177190075Sobrien 177290075Sobrien//--------------------------------statics-------------------------------------- 177390075SobrienDeoptimization::DeoptAction Deoptimization::_unloaded_action 177490075Sobrien = Deoptimization::Action_reinterpret; 177590075Sobrienconst char* Deoptimization::_trap_reason_name[Reason_LIMIT] = { 177696263Sobrien // Note: Keep this in sync. with enum DeoptReason. 177790075Sobrien "none", 177890075Sobrien "null_check", 177996263Sobrien "null_assert", 178096263Sobrien "range_check", 178190075Sobrien "class_check", 178290075Sobrien "array_check", 178390075Sobrien "intrinsic", 178490075Sobrien "bimorphic", 178590075Sobrien "unloaded", 178690075Sobrien "uninitialized", 178790075Sobrien "unreached", 178890075Sobrien "unhandled", 178990075Sobrien "constraint", 179090075Sobrien "div0_check", 1791169689Skan "age", 1792169689Skan "predicate", 179390075Sobrien "loop_limit_check" 179490075Sobrien}; 179590075Sobrienconst char* Deoptimization::_trap_action_name[Action_LIMIT] = { 179690075Sobrien // Note: Keep this in sync. with enum DeoptAction. 179790075Sobrien "none", 179890075Sobrien "maybe_recompile", 1799132718Skan "reinterpret", 1800132718Skan "make_not_entrant", 1801132718Skan "make_not_compilable" 1802132718Skan}; 180390075Sobrien 180490075Sobrienconst char* Deoptimization::trap_reason_name(int reason) { 180590075Sobrien if (reason == Reason_many) return "many"; 180690075Sobrien if ((uint)reason < Reason_LIMIT) 1807169689Skan return _trap_reason_name[reason]; 180890075Sobrien static char buf[20]; 1809169689Skan sprintf(buf, "reason%d", reason); 181090075Sobrien return buf; 181190075Sobrien} 181290075Sobrienconst char* Deoptimization::trap_action_name(int action) { 181390075Sobrien if ((uint)action < Action_LIMIT) 1814132718Skan return _trap_action_name[action]; 1815132718Skan static char buf[20]; 181690075Sobrien sprintf(buf, "action%d", action); 181790075Sobrien return buf; 181890075Sobrien} 181990075Sobrien 182090075Sobrien// This is used for debugging and diagnostics, including hotspot.log output. 182190075Sobrienconst char* Deoptimization::format_trap_request(char* buf, size_t buflen, 182290075Sobrien int trap_request) { 182390075Sobrien jint unloaded_class_index = trap_request_index(trap_request); 182490075Sobrien const char* reason = trap_reason_name(trap_request_reason(trap_request)); 182590075Sobrien const char* action = trap_action_name(trap_request_action(trap_request)); 182690075Sobrien size_t len; 182790075Sobrien if (unloaded_class_index < 0) { 182890075Sobrien len = jio_snprintf(buf, buflen, "reason='%s' action='%s'", 182990075Sobrien reason, action); 183090075Sobrien } else { 183190075Sobrien len = jio_snprintf(buf, buflen, "reason='%s' action='%s' index='%d'", 183290075Sobrien reason, action, unloaded_class_index); 183390075Sobrien } 183490075Sobrien if (len >= buflen) 183596263Sobrien buf[buflen-1] = '\0'; 183696263Sobrien return buf; 183796263Sobrien} 183896263Sobrien 183996263Sobrienjuint Deoptimization::_deoptimization_hist 184096263Sobrien [Deoptimization::Reason_LIMIT] 184196263Sobrien [1 + Deoptimization::Action_LIMIT] 184296263Sobrien [Deoptimization::BC_CASE_LIMIT] 184390075Sobrien = {0}; 184490075Sobrien 184590075Sobrienenum { 184690075Sobrien LSB_BITS = 8, 184790075Sobrien LSB_MASK = right_n_bits(LSB_BITS) 184890075Sobrien}; 184990075Sobrien 185090075Sobrienvoid Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action, 185190075Sobrien Bytecodes::Code bc) { 185290075Sobrien assert(reason >= 0 && reason < Reason_LIMIT, "oob"); 185390075Sobrien assert(action >= 0 && action < Action_LIMIT, "oob"); 185490075Sobrien _deoptimization_hist[Reason_none][0][0] += 1; // total 185590075Sobrien _deoptimization_hist[reason][0][0] += 1; // per-reason total 185690075Sobrien juint* cases = _deoptimization_hist[reason][1+action]; 185790075Sobrien juint* bc_counter_addr = NULL; 185890075Sobrien juint bc_counter = 0; 185990075Sobrien // Look for an unused counter, or an exact match to this BC. 186090075Sobrien if (bc != Bytecodes::_illegal) { 186190075Sobrien for (int bc_case = 0; bc_case < BC_CASE_LIMIT; bc_case++) { 186290075Sobrien juint* counter_addr = &cases[bc_case]; 186390075Sobrien juint counter = *counter_addr; 186490075Sobrien if ((counter == 0 && bc_counter_addr == NULL) 186590075Sobrien || (Bytecodes::Code)(counter & LSB_MASK) == bc) { 186690075Sobrien // this counter is either free or is already devoted to this BC 186790075Sobrien bc_counter_addr = counter_addr; 186890075Sobrien bc_counter = counter | bc; 186990075Sobrien } 187090075Sobrien } 187190075Sobrien } 187290075Sobrien if (bc_counter_addr == NULL) { 187390075Sobrien // Overflow, or no given bytecode. 187490075Sobrien bc_counter_addr = &cases[BC_CASE_LIMIT-1]; 187590075Sobrien bc_counter = (*bc_counter_addr & ~LSB_MASK); // clear LSB 187690075Sobrien } 187790075Sobrien *bc_counter_addr = bc_counter + (1 << LSB_BITS); 187890075Sobrien} 187990075Sobrien 188090075Sobrienjint Deoptimization::total_deoptimization_count() { 188190075Sobrien return _deoptimization_hist[Reason_none][0][0]; 188290075Sobrien} 188390075Sobrien 188490075Sobrienjint Deoptimization::deoptimization_count(DeoptReason reason) { 188590075Sobrien assert(reason >= 0 && reason < Reason_LIMIT, "oob"); 188690075Sobrien return _deoptimization_hist[reason][0][0]; 188790075Sobrien} 1888122180Skan 1889122180Skanvoid Deoptimization::print_statistics() { 1890122180Skan juint total = total_deoptimization_count(); 1891122180Skan juint account = total; 1892122180Skan if (total != 0) { 189390075Sobrien ttyLocker ttyl; 189490075Sobrien if (xtty != NULL) xtty->head("statistics type='deoptimization'"); 189590075Sobrien tty->print_cr("Deoptimization traps recorded:"); 189690075Sobrien #define PRINT_STAT_LINE(name, r) \ 189790075Sobrien tty->print_cr(" %4d (%4.1f%%) %s", (int)(r), ((r) * 100.0) / total, name); 189890075Sobrien PRINT_STAT_LINE("total", total); 189990075Sobrien // For each non-zero entry in the histogram, print the reason, 190090075Sobrien // the action, and (if specifically known) the type of bytecode. 190190075Sobrien for (int reason = 0; reason < Reason_LIMIT; reason++) { 190290075Sobrien for (int action = 0; action < Action_LIMIT; action++) { 190390075Sobrien juint* cases = _deoptimization_hist[reason][1+action]; 190490075Sobrien for (int bc_case = 0; bc_case < BC_CASE_LIMIT; bc_case++) { 190590075Sobrien juint counter = cases[bc_case]; 1906132718Skan if (counter != 0) { 190790075Sobrien char name[1*K]; 1908132718Skan Bytecodes::Code bc = (Bytecodes::Code)(counter & LSB_MASK); 190990075Sobrien if (bc_case == BC_CASE_LIMIT && (int)bc == 0) 191090075Sobrien bc = Bytecodes::_illegal; 191190075Sobrien sprintf(name, "%s/%s/%s", 191290075Sobrien trap_reason_name(reason), 191390075Sobrien trap_action_name(action), 191490075Sobrien Bytecodes::is_defined(bc)? Bytecodes::name(bc): "other"); 191590075Sobrien juint r = counter >> LSB_BITS; 191690075Sobrien tty->print_cr(" %40s: " UINT32_FORMAT " (%.1f%%)", name, r, (r * 100.0) / total); 191790075Sobrien account -= r; 191890075Sobrien } 191990075Sobrien } 192090075Sobrien } 192190075Sobrien } 192290075Sobrien if (account != 0) { 192390075Sobrien PRINT_STAT_LINE("unaccounted", account); 192490075Sobrien } 192590075Sobrien #undef PRINT_STAT_LINE 192690075Sobrien if (xtty != NULL) xtty->tail("statistics"); 192790075Sobrien } 192890075Sobrien} 192990075Sobrien#else // COMPILER2 || SHARK 193090075Sobrien 193190075Sobrien 193290075Sobrien// Stubs for C1 only system. 193390075Sobrienbool Deoptimization::trap_state_is_recompiled(int trap_state) { 193490075Sobrien return false; 193590075Sobrien} 193690075Sobrien 193790075Sobrienconst char* Deoptimization::trap_reason_name(int reason) { 193890075Sobrien return "unknown"; 193990075Sobrien} 194090075Sobrien 194190075Sobrienvoid Deoptimization::print_statistics() { 194290075Sobrien // no output 194390075Sobrien} 1944122180Skan 1945122180Skanvoid 1946122180SkanDeoptimization::update_method_data_from_interpreter(MethodData* trap_mdo, int trap_bci, int reason) { 1947122180Skan // no udpate 1948122180Skan} 194990075Sobrien 195090075Sobrienint Deoptimization::trap_state_has_reason(int trap_state, int reason) { 195190075Sobrien return 0; 195290075Sobrien} 195390075Sobrien 195490075Sobrienvoid Deoptimization::gather_statistics(DeoptReason reason, DeoptAction action, 195590075Sobrien Bytecodes::Code bc) { 195690075Sobrien // no update 195790075Sobrien} 195890075Sobrien 195990075Sobrienconst char* Deoptimization::format_trap_state(char* buf, size_t buflen, 196090075Sobrien int trap_state) { 196190075Sobrien jio_snprintf(buf, buflen, "#%d", trap_state); 196290075Sobrien return buf; 196390075Sobrien} 196490075Sobrien 196590075Sobrien#endif // COMPILER2 || SHARK 196690075Sobrien