1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/code/debugInfoRec.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,182 @@ 1.4 +/* 1.5 + * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +//** The DebugInformationRecorder collects debugging information 1.29 +// for a compiled method. 1.30 +// Debugging information is used for: 1.31 +// - garbage collecting compiled frames 1.32 +// - stack tracing across compiled frames 1.33 +// - deoptimizating compiled frames 1.34 +// 1.35 +// The implementation requires the compiler to use the recorder 1.36 +// in the following order: 1.37 +// 1) Describe debug information for safepoints at increasing addresses. 1.38 +// a) Add safepoint entry (use add_safepoint or add_non_safepoint) 1.39 +// b) Describe scopes for that safepoint 1.40 +// - create locals if needed (use create_scope_values) 1.41 +// - create expressions if needed (use create_scope_values) 1.42 +// - create monitor stack if needed (use create_monitor_values) 1.43 +// - describe scope (use describe_scope) 1.44 +// "repeat last four steps for all scopes" 1.45 +// "outer most scope first and inner most scope last" 1.46 +// NB: nodes from create_scope_values and create_locations 1.47 +// can be reused for simple sharing. 1.48 +// - mark the end of the scopes (end_safepoint or end_non_safepoint) 1.49 +// 2) Use oop_size, data_size, pcs_size to create the nmethod and 1.50 +// finally migrate the debugging information into the nmethod 1.51 +// by calling copy_to. 1.52 + 1.53 +class DebugToken; // Opaque datatype for stored: 1.54 + // - GrowableArray<ScopeValue*> 1.55 + // - GrowableArray<MonitorValue*> 1.56 + 1.57 +// Alias for InvocationEntryBci. 1.58 +// Both constants are used for a pseudo-BCI which refers 1.59 +// to the state just _before_ a method is entered. 1.60 +// SynchronizationEntryBCI is used where the emphasis 1.61 +// is on the implicit monitorenter of a synchronized method. 1.62 +const int SynchronizationEntryBCI = InvocationEntryBci; 1.63 + 1.64 +class DIR_Chunk; // private class, a nugget of collected information 1.65 + 1.66 +class DebugInformationRecorder: public ResourceObj { 1.67 + public: 1.68 + // constructor 1.69 + DebugInformationRecorder(OopRecorder* oop_recorder); 1.70 + 1.71 + // adds an oopmap at a specific offset 1.72 + void add_oopmap(int pc_offset, OopMap* map); 1.73 + 1.74 + // adds a jvm mapping at pc-offset, for a safepoint only 1.75 + void add_safepoint(int pc_offset, OopMap* map); 1.76 + 1.77 + // adds a jvm mapping at pc-offset, for a non-safepoint (profile point) 1.78 + void add_non_safepoint(int pc_offset); 1.79 + 1.80 + // Describes debugging information for a scope at the given pc_offset. 1.81 + // Calls must be in non-decreasing order of pc_offset. 1.82 + // If there are several calls at a single pc_offset, 1.83 + // then they occur in the same order as they were performed by the JVM, 1.84 + // with the most recent (innermost) call being described last. 1.85 + // For a safepoint, the pc_offset must have been mentioned 1.86 + // previously by add_safepoint. 1.87 + // Otherwise, the pc_offset must have been mentioned previously 1.88 + // by add_non_safepoint, and the locals, expressions, and monitors 1.89 + // must all be null. 1.90 + void describe_scope(int pc_offset, 1.91 + ciMethod* method, 1.92 + int bci, 1.93 + DebugToken* locals = NULL, 1.94 + DebugToken* expressions = NULL, 1.95 + DebugToken* monitors = NULL); 1.96 + 1.97 + 1.98 + void dump_object_pool(GrowableArray<ScopeValue*>* objects); 1.99 + 1.100 + // This call must follow every add_safepoint, 1.101 + // after any intervening describe_scope calls. 1.102 + void end_safepoint(int pc_offset) { end_scopes(pc_offset, true); } 1.103 + void end_non_safepoint(int pc_offset) { end_scopes(pc_offset, false); } 1.104 + 1.105 + // helper fuctions for describe_scope to enable sharing 1.106 + DebugToken* create_scope_values(GrowableArray<ScopeValue*>* values); 1.107 + DebugToken* create_monitor_values(GrowableArray<MonitorValue*>* monitors); 1.108 + 1.109 + // returns the size of the generated scopeDescs. 1.110 + int data_size(); 1.111 + int pcs_size(); 1.112 + int oop_size() { return oop_recorder()->oop_size(); } 1.113 + 1.114 + // copy the generated debugging information to nmethod 1.115 + void copy_to(nmethod* nm); 1.116 + 1.117 + // verifies the debug information 1.118 + void verify(const nmethod* code); 1.119 + 1.120 + static void print_statistics() PRODUCT_RETURN; 1.121 + 1.122 + // Method for setting oopmaps to temporarily preserve old handling of oopmaps 1.123 + OopMapSet *_oopmaps; 1.124 + void set_oopmaps(OopMapSet *oopmaps) { _oopmaps = oopmaps; } 1.125 + 1.126 + OopRecorder* oop_recorder() { return _oop_recorder; } 1.127 + 1.128 + int last_pc_offset() { return last_pc()->pc_offset(); } 1.129 + 1.130 + bool recording_non_safepoints() { return _recording_non_safepoints; } 1.131 + 1.132 + private: 1.133 + friend class ScopeDesc; 1.134 + friend class vframeStreamCommon; 1.135 + friend class DIR_Chunk; 1.136 + 1.137 + // True if we are recording non-safepoint scopes. 1.138 + // This flag is set if DebugNonSafepoints is true, or if 1.139 + // JVMTI post_compiled_method_load events are enabled. 1.140 + const bool _recording_non_safepoints; 1.141 + 1.142 + DebugInfoWriteStream* _stream; 1.143 + 1.144 + DebugInfoWriteStream* stream() const { return _stream; } 1.145 + 1.146 + OopRecorder* _oop_recorder; 1.147 + 1.148 + // Scopes that have been described so far. 1.149 + GrowableArray<DIR_Chunk*>* _all_chunks; 1.150 + GrowableArray<DIR_Chunk*>* _shared_chunks; 1.151 + DIR_Chunk* _next_chunk; 1.152 + DIR_Chunk* _next_chunk_limit; 1.153 + 1.154 +#ifdef ASSERT 1.155 + enum { rs_null, rs_safepoint, rs_non_safepoint }; 1.156 + int _recording_state; 1.157 +#endif 1.158 + 1.159 + PcDesc* _pcs; 1.160 + int _pcs_size; 1.161 + int _pcs_length; 1.162 + // Note: Would use GrowableArray<PcDesc>, but structs are not supported. 1.163 + 1.164 + // PC of most recent real safepoint before the current one, 1.165 + // updated after end_scopes. 1.166 + int _prev_safepoint_pc; 1.167 + 1.168 + PcDesc* last_pc() { 1.169 + guarantee(_pcs_length > 0, "a safepoint must be declared already"); 1.170 + return &_pcs[_pcs_length-1]; 1.171 + } 1.172 + PcDesc* prev_pc() { 1.173 + guarantee(_pcs_length > 1, "a safepoint must be declared already"); 1.174 + return &_pcs[_pcs_length-2]; 1.175 + } 1.176 + void add_new_pc_offset(int pc_offset); 1.177 + void end_scopes(int pc_offset, bool is_safepoint); 1.178 + 1.179 + int serialize_monitor_values(GrowableArray<MonitorValue*>* monitors); 1.180 + int serialize_scope_values(GrowableArray<ScopeValue*>* values); 1.181 + int find_sharable_decode_offset(int stream_offset); 1.182 + 1.183 + public: 1.184 + enum { serialized_null = 0 }; 1.185 +};