1/*
2 * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25package sun.jvm.hotspot.code;
26
27import java.io.*;
28import java.util.*;
29import sun.jvm.hotspot.debugger.*;
30import sun.jvm.hotspot.oops.*;
31import sun.jvm.hotspot.runtime.*;
32import sun.jvm.hotspot.types.*;
33import sun.jvm.hotspot.utilities.*;
34
35public class NMethod extends CompiledMethod {
36  private static long          pcDescSize;
37  /** != InvocationEntryBci if this nmethod is an on-stack replacement method */
38  private static CIntegerField entryBCIField;
39  /** To support simple linked-list chaining of nmethods */
40  private static AddressField  osrLinkField;
41  private static AddressField  scavengeRootLinkField;
42  private static JByteField    scavengeRootStateField;
43
44  /** Offsets for different nmethod parts */
45  private static CIntegerField exceptionOffsetField;
46  private static CIntegerField origPCOffsetField;
47  private static CIntegerField stubOffsetField;
48  private static CIntegerField oopsOffsetField;
49  private static CIntegerField metadataOffsetField;
50  private static CIntegerField scopesPCsOffsetField;
51  private static CIntegerField dependenciesOffsetField;
52  private static CIntegerField handlerTableOffsetField;
53  private static CIntegerField nulChkTableOffsetField;
54  private static CIntegerField nmethodEndOffsetField;
55
56  /** Offsets for entry points */
57  /** Entry point with class check */
58  private static AddressField  entryPointField;
59  /** Entry point without class check */
60  private static AddressField  verifiedEntryPointField;
61  /** Entry point for on stack replacement */
62  private static AddressField  osrEntryPointField;
63
64  // FIXME: add access to flags (how?)
65
66  /** NMethod Flushing lock (if non-zero, then the nmethod is not removed) */
67  private static JIntField     lockCountField;
68
69  /** not_entrant method removal. Each mark_sweep pass will update
70      this mark to current sweep invocation count if it is seen on the
71      stack.  An not_entrant method can be removed when there is no
72      more activations, i.e., when the _stack_traversal_mark is less than
73      current sweep traversal index. */
74  private static CIntegerField stackTraversalMarkField;
75
76  private static CIntegerField compLevelField;
77
78  static {
79    VM.registerVMInitializedObserver(new Observer() {
80        public void update(Observable o, Object data) {
81          initialize(VM.getVM().getTypeDataBase());
82        }
83      });
84  }
85
86  private static void initialize(TypeDataBase db) {
87    Type type = db.lookupType("nmethod");
88
89    entryBCIField               = type.getCIntegerField("_entry_bci");
90    osrLinkField                = type.getAddressField("_osr_link");
91    scavengeRootLinkField       = type.getAddressField("_scavenge_root_link");
92    scavengeRootStateField      = type.getJByteField("_scavenge_root_state");
93
94    exceptionOffsetField        = type.getCIntegerField("_exception_offset");
95    origPCOffsetField           = type.getCIntegerField("_orig_pc_offset");
96    stubOffsetField             = type.getCIntegerField("_stub_offset");
97    oopsOffsetField             = type.getCIntegerField("_oops_offset");
98    metadataOffsetField         = type.getCIntegerField("_metadata_offset");
99    scopesPCsOffsetField        = type.getCIntegerField("_scopes_pcs_offset");
100    dependenciesOffsetField     = type.getCIntegerField("_dependencies_offset");
101    handlerTableOffsetField     = type.getCIntegerField("_handler_table_offset");
102    nulChkTableOffsetField      = type.getCIntegerField("_nul_chk_table_offset");
103    nmethodEndOffsetField       = type.getCIntegerField("_nmethod_end_offset");
104    entryPointField             = type.getAddressField("_entry_point");
105    verifiedEntryPointField     = type.getAddressField("_verified_entry_point");
106    osrEntryPointField          = type.getAddressField("_osr_entry_point");
107    lockCountField              = type.getJIntField("_lock_count");
108    stackTraversalMarkField     = type.getCIntegerField("_stack_traversal_mark");
109    compLevelField              = type.getCIntegerField("_comp_level");
110    pcDescSize = db.lookupType("PcDesc").getSize();
111  }
112
113  public NMethod(Address addr) {
114    super(addr);
115  }
116
117  // Accessors
118  public Address getAddress() {
119    return addr;
120  }
121
122  // Type info
123  public boolean isNMethod()      { return true;                    }
124  public boolean isJavaMethod()   { return !getMethod().isNative(); }
125  public boolean isNativeMethod() { return getMethod().isNative();  }
126  public boolean isOSRMethod()    { return getEntryBCI() != VM.getVM().getInvocationEntryBCI(); }
127
128  /** Boundaries for different parts */
129  public Address constantsBegin()       { return contentBegin();                                     }
130  public Address constantsEnd()         { return getEntryPoint();                                    }
131  public Address instsBegin()           { return codeBegin();                                        }
132  public Address instsEnd()             { return headerBegin().addOffsetTo(getStubOffset());         }
133  public Address exceptionBegin()       { return headerBegin().addOffsetTo(getExceptionOffset());    }
134  public Address stubBegin()            { return headerBegin().addOffsetTo(getStubOffset());         }
135  public Address stubEnd()              { return headerBegin().addOffsetTo(getOopsOffset());         }
136  public Address oopsBegin()            { return headerBegin().addOffsetTo(getOopsOffset());         }
137  public Address oopsEnd()              { return headerBegin().addOffsetTo(getMetadataOffset());     }
138  public Address metadataBegin()        { return headerBegin().addOffsetTo(getMetadataOffset());     }
139  public Address metadataEnd()          { return scopesDataBegin();                                  }
140  public Address scopesDataEnd()        { return headerBegin().addOffsetTo(getScopesPCsOffset());    }
141  public Address scopesPCsBegin()       { return headerBegin().addOffsetTo(getScopesPCsOffset());    }
142  public Address scopesPCsEnd()         { return headerBegin().addOffsetTo(getDependenciesOffset()); }
143  public Address dependenciesBegin()    { return headerBegin().addOffsetTo(getDependenciesOffset()); }
144  public Address dependenciesEnd()      { return headerBegin().addOffsetTo(getHandlerTableOffset()); }
145  public Address handlerTableBegin()    { return headerBegin().addOffsetTo(getHandlerTableOffset()); }
146  public Address handlerTableEnd()      { return headerBegin().addOffsetTo(getNulChkTableOffset());  }
147  public Address nulChkTableBegin()     { return headerBegin().addOffsetTo(getNulChkTableOffset());  }
148  public Address nulChkTableEnd()       { return headerBegin().addOffsetTo(getNMethodEndOffset());   }
149
150  public int constantsSize()            { return (int) constantsEnd()   .minus(constantsBegin());    }
151  public int instsSize()                { return (int) instsEnd()       .minus(instsBegin());        }
152  public int stubSize()                 { return (int) stubEnd()        .minus(stubBegin());         }
153  public int oopsSize()                 { return (int) oopsEnd()        .minus(oopsBegin());         }
154  public int metadataSize()             { return (int) metadataEnd()    .minus(metadataBegin());     }
155  public int scopesDataSize()           { return (int) scopesDataEnd()  .minus(scopesDataBegin());   }
156  public int scopesPCsSize()            { return (int) scopesPCsEnd()   .minus(scopesPCsBegin());    }
157  public int dependenciesSize()         { return (int) dependenciesEnd().minus(dependenciesBegin()); }
158  public int handlerTableSize()         { return (int) handlerTableEnd().minus(handlerTableBegin()); }
159  public int nulChkTableSize()          { return (int) nulChkTableEnd() .minus(nulChkTableBegin());  }
160  public int origPCOffset()             { return (int) origPCOffsetField.getValue(addr);             }
161
162  public int totalSize() {
163    return
164      constantsSize()    +
165      instsSize()        +
166      stubSize()         +
167      scopesDataSize()   +
168      scopesPCsSize()    +
169      dependenciesSize() +
170      handlerTableSize() +
171      nulChkTableSize();
172  }
173
174  public boolean constantsContains   (Address addr) { return constantsBegin()   .lessThanOrEqual(addr) && constantsEnd()   .greaterThan(addr); }
175  public boolean instsContains       (Address addr) { return instsBegin()       .lessThanOrEqual(addr) && instsEnd()       .greaterThan(addr); }
176  public boolean stubContains        (Address addr) { return stubBegin()        .lessThanOrEqual(addr) && stubEnd()        .greaterThan(addr); }
177  public boolean oopsContains        (Address addr) { return oopsBegin()        .lessThanOrEqual(addr) && oopsEnd()        .greaterThan(addr); }
178  public boolean metadataContains    (Address addr) { return metadataBegin()    .lessThanOrEqual(addr) && metadataEnd()    .greaterThan(addr); }
179  public boolean scopesDataContains  (Address addr) { return scopesDataBegin()  .lessThanOrEqual(addr) && scopesDataEnd()  .greaterThan(addr); }
180  public boolean scopesPCsContains   (Address addr) { return scopesPCsBegin()   .lessThanOrEqual(addr) && scopesPCsEnd()   .greaterThan(addr); }
181  public boolean handlerTableContains(Address addr) { return handlerTableBegin().lessThanOrEqual(addr) && handlerTableEnd().greaterThan(addr); }
182  public boolean nulChkTableContains (Address addr) { return nulChkTableBegin() .lessThanOrEqual(addr) && nulChkTableEnd() .greaterThan(addr); }
183
184  public int getOopsLength() { return (int) (oopsSize() / VM.getVM().getOopSize()); }
185  public int getMetadataLength() { return (int) (metadataSize() / VM.getVM().getOopSize()); }
186
187  /** Entry points */
188  public Address getEntryPoint()         { return entryPointField.getValue(addr);         }
189  public Address getVerifiedEntryPoint() { return verifiedEntryPointField.getValue(addr); }
190
191  /** Support for oops in scopes and relocs. Note: index 0 is reserved for null. */
192  public OopHandle getOopAt(int index) {
193    if (index == 0) return null;
194    if (Assert.ASSERTS_ENABLED) {
195      Assert.that(index > 0 && index <= getOopsLength(), "must be a valid non-zero index");
196    }
197    return oopsBegin().getOopHandleAt((index - 1) * VM.getVM().getOopSize());
198  }
199
200  /** Support for metadata in scopes and relocs. Note: index 0 is reserved for null. */
201  public Address getMetadataAt(int index) {
202    if (index == 0) return null;
203    if (Assert.ASSERTS_ENABLED) {
204      Assert.that(index > 0 && index <= getMetadataLength(), "must be a valid non-zero index");
205    }
206    return metadataBegin().getAddressAt((index - 1) * VM.getVM().getOopSize());
207  }
208
209  public Method getMethodAt(int index) {
210    return (Method)Metadata.instantiateWrapperFor(getMetadataAt(index));
211  }
212
213  // FIXME: add interpreter_entry_point()
214  // FIXME: add lazy_interpreter_entry_point() for C2
215
216  // **********
217  // * FIXME: * ADD ACCESS TO FLAGS!!!!
218  // **********
219  // public boolean isInUse();
220  // public boolean isAlive();
221  // public boolean isNotEntrant();
222  // public boolean isZombie();
223
224  // ********************************
225  // * MAJOR FIXME: MAJOR HACK HERE *
226  // ********************************
227  public boolean isZombie() { return false; }
228
229  // public boolean isUnloaded();
230  // public boolean isYoung();
231  // public boolean isOld();
232  // public int     age();
233  // public boolean isMarkedForDeoptimization();
234  // public boolean isMarkedForUnloading();
235  // public int     level();
236  // public int     version();
237
238  // FIXME: add mutators for above
239  // FIXME: add exception cache access?
240
241  /** On-stack replacement support */
242  // FIXME: add mutators
243  public int getOSREntryBCI() {
244    if (Assert.ASSERTS_ENABLED) {
245      Assert.that(getEntryBCI() != VM.getVM().getInvocationEntryBCI(), "wrong kind of nmethod");
246    }
247    return getEntryBCI();
248  }
249
250  public NMethod getOSRLink() {
251    return (NMethod) VMObjectFactory.newObject(NMethod.class, osrLinkField.getValue(addr));
252  }
253
254  public NMethod getScavengeRootLink() {
255    return (NMethod) VMObjectFactory.newObject(NMethod.class, scavengeRootLinkField.getValue(addr));
256  }
257
258  public int getScavengeRootState() {
259    return (int) scavengeRootStateField.getValue(addr);
260  }
261
262  // MethodHandle
263  public boolean isMethodHandleReturn(Address returnPc) {
264    // Hard to read a bit fields from Java and it's only there for performance
265    // so just go directly to the PCDesc
266    // if (!hasMethodHandleInvokes())  return false;
267    PCDesc pd = getPCDescAt(returnPc);
268    if (pd == null)
269      return false;
270    return pd.isMethodHandleInvoke();
271  }
272
273  // Deopt
274  // Return true is the PC is one would expect if the frame is being deopted.
275  public boolean isDeoptPc      (Address pc) { return isDeoptEntry(pc) || isDeoptMhEntry(pc); }
276  public boolean isDeoptEntry   (Address pc) { return pc == deoptHandlerBegin(); }
277  public boolean isDeoptMhEntry (Address pc) { return pc == deoptMhHandlerBegin(); }
278
279  /** Tells whether frames described by this nmethod can be
280      deoptimized. Note: native wrappers cannot be deoptimized. */
281  public boolean canBeDeoptimized() { return isJavaMethod(); }
282
283  // FIXME: add inline cache support
284  // FIXME: add flush()
285
286  public boolean isLockedByVM() { return lockCountField.getValue(addr) > 0; }
287
288  // FIXME: add mark_as_seen_on_stack
289  // FIXME: add can_not_entrant_be_converted
290
291  // FIXME: add GC support
292  //  void follow_roots_or_mark_for_unloading(bool unloading_occurred, bool& marked_for_unloading);
293  //  void follow_root_or_mark_for_unloading(oop* root, bool unloading_occurred, bool& marked_for_unloading);
294  //  void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, void f(oop*));
295  //  void adjust_pointers();
296
297  /** Finds a PCDesc with real-pc equal to "pc" */
298  public PCDesc getPCDescAt(Address pc) {
299    // FIXME: consider adding cache like the one down in the VM
300    for (Address p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) {
301      PCDesc pcDesc = new PCDesc(p);
302      if (pcDesc.getRealPC(this).equals(pc)) {
303        return pcDesc;
304      }
305    }
306    return null;
307  }
308
309  /** ScopeDesc for an instruction */
310  public ScopeDesc getScopeDescAt(Address pc) {
311    PCDesc pd = getPCDescAt(pc);
312    if (Assert.ASSERTS_ENABLED) {
313      Assert.that(pd != null, "scope must be present");
314    }
315    return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
316  }
317
318  /** This is only for use by the debugging system, and is only
319      intended for use in the topmost frame, where we are not
320      guaranteed to be at a PC for which we have a PCDesc. It finds
321      the PCDesc with realPC closest to the current PC. */
322  public PCDesc getPCDescNearDbg(Address pc) {
323    PCDesc bestGuessPCDesc = null;
324    long bestDistance = 0;
325    for (Address p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) {
326      PCDesc pcDesc = new PCDesc(p);
327      // In case pc is null
328      long distance = -pcDesc.getRealPC(this).minus(pc);
329      if ((bestGuessPCDesc == null) ||
330          ((distance >= 0) && (distance < bestDistance))) {
331        bestGuessPCDesc = pcDesc;
332        bestDistance    = distance;
333      }
334    }
335    return bestGuessPCDesc;
336  }
337
338  PCDesc find_pc_desc(long pc, boolean approximate) {
339    return find_pc_desc_internal(pc, approximate);
340  }
341
342  // Finds a PcDesc with real-pc equal to "pc"
343  PCDesc find_pc_desc_internal(long pc, boolean approximate) {
344    long base_address = VM.getAddressValue(codeBegin());
345    int pc_offset = (int) (pc - base_address);
346
347    // Fallback algorithm: quasi-linear search for the PcDesc
348    // Find the last pc_offset less than the given offset.
349    // The successor must be the required match, if there is a match at all.
350    // (Use a fixed radix to avoid expensive affine pointer arithmetic.)
351    Address lower = scopesPCsBegin();
352    Address upper = scopesPCsEnd();
353    upper = upper.addOffsetTo(-pcDescSize); // exclude final sentinel
354    if (lower.greaterThan(upper))  return null;  // native method; no PcDescs at all
355
356    // Take giant steps at first (4096, then 256, then 16, then 1)
357    int LOG2_RADIX = 4;
358    int RADIX = (1 << LOG2_RADIX);
359    Address mid;
360    for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) {
361      while ((mid = lower.addOffsetTo(step * pcDescSize)).lessThan(upper)) {
362        PCDesc m = new PCDesc(mid);
363        if (m.getPCOffset() < pc_offset) {
364          lower = mid;
365        } else {
366          upper = mid;
367          break;
368        }
369      }
370    }
371    // Sneak up on the value with a linear search of length ~16.
372    while (true) {
373      mid = lower.addOffsetTo(pcDescSize);
374      PCDesc m = new PCDesc(mid);
375      if (m.getPCOffset() < pc_offset) {
376        lower = mid;
377      } else {
378        upper = mid;
379        break;
380      }
381    }
382
383    PCDesc u = new PCDesc(upper);
384    if (match_desc(u, pc_offset, approximate)) {
385      return u;
386    } else {
387      return null;
388    }
389  }
390
391  // ScopeDesc retrieval operation
392  PCDesc pc_desc_at(long pc)   { return find_pc_desc(pc, false); }
393  // pc_desc_near returns the first PCDesc at or after the givne pc.
394  PCDesc pc_desc_near(long pc) { return find_pc_desc(pc, true); }
395
396  // Return a the last scope in (begin..end]
397  public ScopeDesc scope_desc_in(long begin, long end) {
398    PCDesc p = pc_desc_near(begin+1);
399    if (p != null && VM.getAddressValue(p.getRealPC(this)) <= end) {
400      return new ScopeDesc(this, p.getScopeDecodeOffset(), p.getObjDecodeOffset(), p.getReexecute());
401    }
402    return null;
403  }
404
405  static boolean match_desc(PCDesc pc, int pc_offset, boolean approximate) {
406    if (!approximate) {
407      return pc.getPCOffset() == pc_offset;
408    } else {
409      PCDesc prev = new PCDesc(pc.getAddress().addOffsetTo(-pcDescSize));
410       return prev.getPCOffset() < pc_offset && pc_offset <= pc.getPCOffset();
411    }
412  }
413
414  /** This is only for use by the debugging system, and is only
415      intended for use in the topmost frame, where we are not
416      guaranteed to be at a PC for which we have a PCDesc. It finds
417      the ScopeDesc closest to the current PC. NOTE that this may
418      return NULL for compiled methods which don't have any
419      ScopeDescs! */
420  public ScopeDesc getScopeDescNearDbg(Address pc) {
421    PCDesc pd = getPCDescNearDbg(pc);
422    if (pd == null) return null;
423    return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getObjDecodeOffset(), pd.getReexecute());
424  }
425
426  public Map/*<Address, PCDesc>*/ getSafepoints() {
427    Map safepoints = new HashMap(); // Map<Address, PCDesc>
428    sun.jvm.hotspot.debugger.Address p = null;
429    for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd());
430         p = p.addOffsetTo(pcDescSize)) {
431       PCDesc pcDesc = new PCDesc(p);
432       sun.jvm.hotspot.debugger.Address pc = pcDesc.getRealPC(this);
433       safepoints.put(pc, pcDesc);
434    }
435    return safepoints;
436  }
437
438  // FIXME: add getPCOffsetForBCI()
439  // FIXME: add embeddedOopAt()
440  // FIXME: add isDependentOn()
441  // FIXME: add isPatchableAt()
442
443  /** Support for code generation. Only here for proof-of-concept. */
444  public static int getEntryPointOffset()            { return (int) entryPointField.getOffset();            }
445  public static int getVerifiedEntryPointOffset()    { return (int) verifiedEntryPointField.getOffset();    }
446  public static int getOSREntryPointOffset()         { return (int) osrEntryPointField.getOffset();         }
447  public static int getEntryBCIOffset()              { return (int) entryBCIField.getOffset();              }
448
449  public void print() {
450    printOn(System.out);
451  }
452
453  protected void printComponentsOn(PrintStream tty) {
454    // FIXME: add relocation information
455    tty.println(" content: [" + contentBegin() + ", " + contentEnd() + "), " +
456                " code: [" + codeBegin() + ", " + codeEnd() + "), " +
457                " data: [" + dataBegin() + ", " + dataEnd() + "), " +
458                " oops: [" + oopsBegin() + ", " + oopsEnd() + "), " +
459                " frame size: " + getFrameSize());
460  }
461
462  public String toString() {
463    Method method = getMethod();
464    return "NMethod for " +
465            method.getMethodHolder().getName().asString() + "." +
466            method.getName().asString() + method.getSignature().asString() + "==>n" +
467            super.toString();
468  }
469
470  public String flagsToString() {
471    // FIXME need access to flags...
472    return "";
473  }
474
475  public String getName() {
476    Method method = getMethod();
477    return "NMethod for " +
478           method.getMethodHolder().getName().asString() + "." +
479           method.getName().asString() +
480           method.getSignature().asString();
481  }
482
483  public void dumpReplayData(PrintStream out) {
484    HashMap h = new HashMap();
485    for (int i = 1; i < getMetadataLength(); i++) {
486      Metadata meta = Metadata.instantiateWrapperFor(getMetadataAt(i));
487      System.err.println(meta);
488      if (h.get(meta) != null) continue;
489      h.put(meta, meta);
490      if (meta instanceof InstanceKlass) {
491        ((InstanceKlass)meta).dumpReplayData(out);
492      } else if (meta instanceof Method) {
493        ((Method)meta).dumpReplayData(out);
494        MethodData mdo = ((Method)meta).getMethodData();
495        if (mdo != null) {
496          mdo.dumpReplayData(out);
497        }
498      }
499    }
500    Method method = getMethod();
501    if (h.get(method) == null) {
502      method.dumpReplayData(out);
503      MethodData mdo = method.getMethodData();
504      if (mdo != null) {
505        mdo.dumpReplayData(out);
506      }
507    }
508    if (h.get(method.getMethodHolder()) == null) {
509      ((InstanceKlass)method.getMethodHolder()).dumpReplayData(out);
510    }
511    Klass holder = method.getMethodHolder();
512    out.println("compile " + holder.getName().asString() + " " +
513                OopUtilities.escapeString(method.getName().asString()) + " " +
514                method.getSignature().asString() + " " +
515                getEntryBCI() + " " + getCompLevel());
516
517  }
518
519  //--------------------------------------------------------------------------------
520  // Internals only below this point
521  //
522
523  private int getEntryBCI()           { return (int) entryBCIField          .getValue(addr); }
524  private int getExceptionOffset()    { return (int) exceptionOffsetField   .getValue(addr); }
525  private int getStubOffset()         { return (int) stubOffsetField        .getValue(addr); }
526  private int getOopsOffset()         { return (int) oopsOffsetField        .getValue(addr); }
527  private int getMetadataOffset()     { return (int) metadataOffsetField    .getValue(addr); }
528  private int getScopesPCsOffset()    { return (int) scopesPCsOffsetField   .getValue(addr); }
529  private int getDependenciesOffset() { return (int) dependenciesOffsetField.getValue(addr); }
530  private int getHandlerTableOffset() { return (int) handlerTableOffsetField.getValue(addr); }
531  private int getNulChkTableOffset()  { return (int) nulChkTableOffsetField .getValue(addr); }
532  private int getNMethodEndOffset()   { return (int) nmethodEndOffsetField  .getValue(addr); }
533  private int getCompLevel()          { return (int) compLevelField         .getValue(addr); }
534}
535