/* * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef SHARE_CODE_SCOPEDESC_HPP #define SHARE_CODE_SCOPEDESC_HPP #include "code/debugInfo.hpp" #include "code/pcDesc.hpp" #include "oops/method.hpp" #include "utilities/growableArray.hpp" // SimpleScopeDesc is used when all you need to extract from // a given pc,nmethod pair is a Method* and a bci. This is // quite a bit faster than allocating a full ScopeDesc, but // very limited in abilities. class SimpleScopeDesc : public StackObj { private: Method* _method; int _bci; public: SimpleScopeDesc(CompiledMethod* code, address pc) { PcDesc* pc_desc = code->pc_desc_at(pc); assert(pc_desc != NULL, "Must be able to find matching PcDesc"); DebugInfoReadStream buffer(code, pc_desc->scope_decode_offset()); int ignore_sender = buffer.read_int(); _method = buffer.read_method(); _bci = buffer.read_bci(); } Method* method() { return _method; } int bci() { return _bci; } }; // ScopeDescs contain the information that makes source-level debugging of // nmethods possible; each scopeDesc describes a method activation class ScopeDesc : public ResourceObj { public: // Constructor ScopeDesc(const CompiledMethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool rethrow_exception, bool return_oop, bool return_vt); // Calls above, giving default value of "serialized_null" to the // "obj_decode_offset" argument. (We don't use a default argument to // avoid a .hpp-.hpp dependency.) ScopeDesc(const CompiledMethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop, bool return_vt); // Direct access to scope ScopeDesc* at_offset(int decode_offset) { return new ScopeDesc(this, decode_offset); } // JVM state Method* method() const { return _method; } int bci() const { return _bci; } bool should_reexecute() const { return _reexecute; } bool rethrow_exception() const { return _rethrow_exception; } bool return_oop() const { return _return_oop; } bool return_vt() const { return _return_vt; } GrowableArray* locals(); GrowableArray* expressions(); GrowableArray* monitors(); GrowableArray* objects(); // Stack walking, returns NULL if this is the outer most scope. ScopeDesc* sender() const; // Returns where the scope was decoded int decode_offset() const { return _decode_offset; } int sender_decode_offset() const { return _sender_decode_offset; } // Tells whether sender() returns NULL bool is_top() const; private: void initialize(const ScopeDesc* parent, int decode_offset); // Alternative constructors ScopeDesc(const ScopeDesc* parent); ScopeDesc(const ScopeDesc* parent, int decode_offset); // JVM state Method* _method; int _bci; bool _reexecute; bool _rethrow_exception; bool _return_oop; bool _return_vt; // Decoding offsets int _decode_offset; int _sender_decode_offset; int _locals_decode_offset; int _expressions_decode_offset; int _monitors_decode_offset; // Object pool GrowableArray* _objects; // Nmethod information const CompiledMethod* _code; // Decoding operations void decode_body(); GrowableArray* decode_scope_values(int decode_offset); GrowableArray* decode_monitor_values(int decode_offset); GrowableArray* decode_object_values(int decode_offset); DebugInfoReadStream* stream_at(int decode_offset) const; public: // Verification void verify(); #ifndef PRODUCT public: // Printing support void print_on(outputStream* st) const; void print_on(outputStream* st, PcDesc* pd) const; void print_value_on(outputStream* st) const; #endif }; #endif // SHARE_CODE_SCOPEDESC_HPP