Path: blob/master/src/hotspot/share/code/debugInfoRec.hpp
40931 views
/*1* Copyright (c) 1998, 2021, 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_CODE_DEBUGINFOREC_HPP25#define SHARE_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 "oops/oop.hpp"34#include "utilities/growableArray.hpp"3536class OopMap;37class OopMapSet;3839//** The DebugInformationRecorder collects debugging information40// for a compiled method.41// Debugging information is used for:42// - garbage collecting compiled frames43// - stack tracing across compiled frames44// - deoptimizating compiled frames45//46// The implementation requires the compiler to use the recorder47// in the following order:48// 1) Describe debug information for safepoints at increasing addresses.49// a) Add safepoint entry (use add_safepoint or add_non_safepoint)50// b) Describe scopes for that safepoint51// - create locals if needed (use create_scope_values)52// - create expressions if needed (use create_scope_values)53// - create monitor stack if needed (use create_monitor_values)54// - describe scope (use describe_scope)55// "repeat last four steps for all scopes"56// "outer most scope first and inner most scope last"57// NB: nodes from create_scope_values and create_locations58// can be reused for simple sharing.59// - mark the end of the scopes (end_safepoint or end_non_safepoint)60// 2) Use oop_size, metadata_size, data_size, pcs_size to create the nmethod61// and finally migrate the debugging information into the nmethod62// by calling copy_to.6364class DebugToken; // Opaque datatype for stored:65// - GrowableArray<ScopeValue*>66// - GrowableArray<MonitorValue*>6768// Alias for InvocationEntryBci.69// Both constants are used for a pseudo-BCI which refers70// to the state just _before_ a method is entered.71// SynchronizationEntryBCI is used where the emphasis72// is on the implicit monitorenter of a synchronized method.73const int SynchronizationEntryBCI = InvocationEntryBci;7475class DIR_Chunk; // private class, a nugget of collected information7677class DebugInformationRecorder: public ResourceObj {78public:79// constructor80DebugInformationRecorder(OopRecorder* oop_recorder);8182// adds an oopmap at a specific offset83void add_oopmap(int pc_offset, OopMap* map);8485// adds a jvm mapping at pc-offset, for a safepoint only86void add_safepoint(int pc_offset, OopMap* map);8788// adds a jvm mapping at pc-offset, for a non-safepoint (profile point)89void add_non_safepoint(int pc_offset);9091// Describes debugging information for a scope at the given pc_offset.92// Calls must be in non-decreasing order of pc_offset.93// If there are several calls at a single pc_offset,94// then they occur in the same order as they were performed by the JVM,95// with the most recent (innermost) call being described last.96// For a safepoint, the pc_offset must have been mentioned97// previously by add_safepoint.98// Otherwise, the pc_offset must have been mentioned previously99// by add_non_safepoint, and the locals, expressions, and monitors100// must all be null.101void describe_scope(int pc_offset,102const methodHandle& methodH,103ciMethod* method,104int bci,105bool reexecute,106bool rethrow_exception = false,107bool is_method_handle_invoke = false,108bool is_optimized_linkToNative = false,109bool return_oop = false,110bool has_ea_local_in_scope = false,111bool arg_escape = false,112DebugToken* locals = NULL,113DebugToken* expressions = NULL,114DebugToken* monitors = NULL);115116117void dump_object_pool(GrowableArray<ScopeValue*>* objects);118119// This call must follow every add_safepoint,120// after any intervening describe_scope calls.121void end_safepoint(int pc_offset) { end_scopes(pc_offset, true); }122void end_non_safepoint(int pc_offset) { end_scopes(pc_offset, false); }123124// helper fuctions for describe_scope to enable sharing125DebugToken* create_scope_values(GrowableArray<ScopeValue*>* values);126DebugToken* create_monitor_values(GrowableArray<MonitorValue*>* monitors);127128// returns the size of the generated scopeDescs.129int data_size();130int pcs_size();131int oop_size() { return oop_recorder()->oop_size(); }132int metadata_size() { return oop_recorder()->metadata_size(); }133134// copy the generated debugging information to nmethod135void copy_to(nmethod* nm);136137// verifies the debug information138void verify(const nmethod* code);139140static void print_statistics() PRODUCT_RETURN;141142// Method for setting oopmaps to temporarily preserve old handling of oopmaps143OopMapSet *_oopmaps;144void set_oopmaps(OopMapSet *oopmaps) { _oopmaps = oopmaps; }145146OopRecorder* oop_recorder() { return _oop_recorder; }147148int last_pc_offset() { return last_pc()->pc_offset(); }149150bool recording_non_safepoints() { return _recording_non_safepoints; }151152PcDesc* pcs() const { return _pcs; }153int pcs_length() const { return _pcs_length; }154155DebugInfoWriteStream* stream() const { return _stream; }156157158private:159friend class ScopeDesc;160friend class vframeStreamCommon;161friend class DIR_Chunk;162163// True if we are recording non-safepoint scopes.164// This flag is set if DebugNonSafepoints is true, or if165// JVMTI post_compiled_method_load events are enabled.166const bool _recording_non_safepoints;167168DebugInfoWriteStream* _stream;169170OopRecorder* _oop_recorder;171172// Scopes that have been described so far.173GrowableArray<DIR_Chunk*>* _all_chunks;174DIR_Chunk* _next_chunk;175DIR_Chunk* _next_chunk_limit;176177#ifdef ASSERT178enum { rs_null, rs_safepoint, rs_non_safepoint };179int _recording_state;180#endif181182PcDesc* _pcs;183int _pcs_size;184int _pcs_length;185// Note: Would use GrowableArray<PcDesc>, but structs are not supported.186187// PC of most recent real safepoint before the current one,188// updated after end_scopes.189int _prev_safepoint_pc;190191PcDesc* last_pc() {192guarantee(_pcs_length > 0, "a safepoint must be declared already");193return &_pcs[_pcs_length-1];194}195PcDesc* prev_pc() {196guarantee(_pcs_length > 1, "a safepoint must be declared already");197return &_pcs[_pcs_length-2];198}199void add_new_pc_offset(int pc_offset);200void end_scopes(int pc_offset, bool is_safepoint);201202int serialize_monitor_values(GrowableArray<MonitorValue*>* monitors);203int serialize_scope_values(GrowableArray<ScopeValue*>* values);204int find_sharable_decode_offset(int stream_offset);205206#ifndef PRODUCT207bool recorders_frozen();208void mark_recorders_frozen();209#endif // PRODUCT210211public:212enum { serialized_null = 0 };213};214215#endif // SHARE_CODE_DEBUGINFOREC_HPP216217218