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