src/share/vm/code/debugInfoRec.hpp

changeset 435
a61af66fc99e
child 1335
9987d9d5eb0e
     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 +};

mercurial