Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/code/debugInfoRec.hpp
32285 views
/*1* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_VM_CODE_DEBUGINFOREC_HPP25#define SHARE_VM_CODE_DEBUGINFOREC_HPP2627#include "ci/ciClassList.hpp"28#include "ci/ciInstanceKlass.hpp"29#include "ci/ciMethod.hpp"30#include "code/debugInfo.hpp"31#include "code/location.hpp"32#include "code/pcDesc.hpp"33#include "compiler/oopMap.hpp"34#include "oops/oop.hpp"35#include "utilities/growableArray.hpp"3637//** The DebugInformationRecorder collects debugging information38// for a compiled method.39// Debugging information is used for:40// - garbage collecting compiled frames41// - stack tracing across compiled frames42// - deoptimizating compiled frames43//44// The implementation requires the compiler to use the recorder45// in the following order:46// 1) Describe debug information for safepoints at increasing addresses.47// a) Add safepoint entry (use add_safepoint or add_non_safepoint)48// b) Describe scopes for that safepoint49// - create locals if needed (use create_scope_values)50// - create expressions if needed (use create_scope_values)51// - create monitor stack if needed (use create_monitor_values)52// - describe scope (use describe_scope)53// "repeat last four steps for all scopes"54// "outer most scope first and inner most scope last"55// NB: nodes from create_scope_values and create_locations56// can be reused for simple sharing.57// - mark the end of the scopes (end_safepoint or end_non_safepoint)58// 2) Use oop_size, metadata_size, data_size, pcs_size to create the nmethod59// and finally migrate the debugging information into the nmethod60// by calling copy_to.6162class DebugToken; // Opaque datatype for stored:63// - GrowableArray<ScopeValue*>64// - GrowableArray<MonitorValue*>6566// Alias for InvocationEntryBci.67// Both constants are used for a pseudo-BCI which refers68// to the state just _before_ a method is entered.69// SynchronizationEntryBCI is used where the emphasis70// is on the implicit monitorenter of a synchronized method.71const int SynchronizationEntryBCI = InvocationEntryBci;7273class DIR_Chunk; // private class, a nugget of collected information7475class DebugInformationRecorder: public ResourceObj {76public:77// constructor78DebugInformationRecorder(OopRecorder* oop_recorder);7980// adds an oopmap at a specific offset81void add_oopmap(int pc_offset, OopMap* map);8283// adds a jvm mapping at pc-offset, for a safepoint only84void add_safepoint(int pc_offset, OopMap* map);8586// adds a jvm mapping at pc-offset, for a non-safepoint (profile point)87void add_non_safepoint(int pc_offset);8889// Describes debugging information for a scope at the given pc_offset.90// Calls must be in non-decreasing order of pc_offset.91// If there are several calls at a single pc_offset,92// then they occur in the same order as they were performed by the JVM,93// with the most recent (innermost) call being described last.94// For a safepoint, the pc_offset must have been mentioned95// previously by add_safepoint.96// Otherwise, the pc_offset must have been mentioned previously97// by add_non_safepoint, and the locals, expressions, and monitors98// must all be null.99void describe_scope(int pc_offset,100ciMethod* method,101int bci,102bool reexecute,103bool is_method_handle_invoke = false,104bool return_oop = false,105DebugToken* locals = NULL,106DebugToken* expressions = NULL,107DebugToken* monitors = NULL);108109110void dump_object_pool(GrowableArray<ScopeValue*>* objects);111112// This call must follow every add_safepoint,113// after any intervening describe_scope calls.114void end_safepoint(int pc_offset) { end_scopes(pc_offset, true); }115void end_non_safepoint(int pc_offset) { end_scopes(pc_offset, false); }116117// helper fuctions for describe_scope to enable sharing118DebugToken* create_scope_values(GrowableArray<ScopeValue*>* values);119DebugToken* create_monitor_values(GrowableArray<MonitorValue*>* monitors);120121// returns the size of the generated scopeDescs.122int data_size();123int pcs_size();124int oop_size() { return oop_recorder()->oop_size(); }125int metadata_size() { return oop_recorder()->metadata_size(); }126127// copy the generated debugging information to nmethod128void copy_to(nmethod* nm);129130// verifies the debug information131void verify(const nmethod* code);132133static void print_statistics() PRODUCT_RETURN;134135// Method for setting oopmaps to temporarily preserve old handling of oopmaps136OopMapSet *_oopmaps;137void set_oopmaps(OopMapSet *oopmaps) { _oopmaps = oopmaps; }138139OopRecorder* oop_recorder() { return _oop_recorder; }140141int last_pc_offset() { return last_pc()->pc_offset(); }142143bool recording_non_safepoints() { return _recording_non_safepoints; }144145private:146friend class ScopeDesc;147friend class vframeStreamCommon;148friend class DIR_Chunk;149150// True if we are recording non-safepoint scopes.151// This flag is set if DebugNonSafepoints is true, or if152// JVMTI post_compiled_method_load events are enabled.153const bool _recording_non_safepoints;154155DebugInfoWriteStream* _stream;156157DebugInfoWriteStream* stream() const { return _stream; }158159OopRecorder* _oop_recorder;160161// Scopes that have been described so far.162GrowableArray<DIR_Chunk*>* _all_chunks;163GrowableArray<DIR_Chunk*>* _shared_chunks;164DIR_Chunk* _next_chunk;165DIR_Chunk* _next_chunk_limit;166167#ifdef ASSERT168enum { rs_null, rs_safepoint, rs_non_safepoint };169int _recording_state;170#endif171172PcDesc* _pcs;173int _pcs_size;174int _pcs_length;175// Note: Would use GrowableArray<PcDesc>, but structs are not supported.176177// PC of most recent real safepoint before the current one,178// updated after end_scopes.179int _prev_safepoint_pc;180181PcDesc* last_pc() {182guarantee(_pcs_length > 0, "a safepoint must be declared already");183return &_pcs[_pcs_length-1];184}185PcDesc* prev_pc() {186guarantee(_pcs_length > 1, "a safepoint must be declared already");187return &_pcs[_pcs_length-2];188}189void add_new_pc_offset(int pc_offset);190void end_scopes(int pc_offset, bool is_safepoint);191192int serialize_monitor_values(GrowableArray<MonitorValue*>* monitors);193int serialize_scope_values(GrowableArray<ScopeValue*>* values);194int find_sharable_decode_offset(int stream_offset);195196#ifndef PRODUCT197bool recorders_frozen();198void mark_recorders_frozen();199#endif // PRODUCT200201public:202enum { serialized_null = 0 };203};204205#endif // SHARE_VM_CODE_DEBUGINFOREC_HPP206207208