Mercurial > hg > graal-jvmci-8
diff agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java @ 6782:5a98bf7d847b
6879063: SA should use hsdis for disassembly
Summary: We should in SA to use hsdis for it like the JVM does to replace the current java based disassembler.
Reviewed-by: twisti, jrose, sla
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 24 Sep 2012 12:44:00 -0700 |
parents | da91efe96a93 |
children | bd7a7ce2e264 |
line wrap: on
line diff
--- a/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Thu Sep 20 03:49:15 2012 -0700 +++ b/agent/src/share/classes/sun/jvm/hotspot/code/NMethod.java Mon Sep 24 12:44:00 2012 -0700 @@ -351,6 +351,82 @@ return bestGuessPCDesc; } + PCDesc find_pc_desc(long pc, boolean approximate) { + return find_pc_desc_internal(pc, approximate); + } + + // Finds a PcDesc with real-pc equal to "pc" + PCDesc find_pc_desc_internal(long pc, boolean approximate) { + long base_address = VM.getAddressValue(codeBegin()); + int pc_offset = (int) (pc - base_address); + + // Fallback algorithm: quasi-linear search for the PcDesc + // Find the last pc_offset less than the given offset. + // The successor must be the required match, if there is a match at all. + // (Use a fixed radix to avoid expensive affine pointer arithmetic.) + Address lower = scopesPCsBegin(); + Address upper = scopesPCsEnd(); + upper = upper.addOffsetTo(-pcDescSize); // exclude final sentinel + if (lower.greaterThan(upper)) return null; // native method; no PcDescs at all + + // Take giant steps at first (4096, then 256, then 16, then 1) + int LOG2_RADIX = 4; + int RADIX = (1 << LOG2_RADIX); + Address mid; + for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) { + while ((mid = lower.addOffsetTo(step * pcDescSize)).lessThan(upper)) { + PCDesc m = new PCDesc(mid); + if (m.getPCOffset() < pc_offset) { + lower = mid; + } else { + upper = mid; + break; + } + } + } + // Sneak up on the value with a linear search of length ~16. + while (true) { + mid = lower.addOffsetTo(pcDescSize); + PCDesc m = new PCDesc(mid); + if (m.getPCOffset() < pc_offset) { + lower = mid; + } else { + upper = mid; + break; + } + } + + PCDesc u = new PCDesc(upper); + if (match_desc(u, pc_offset, approximate)) { + return u; + } else { + return null; + } + } + + // ScopeDesc retrieval operation + PCDesc pc_desc_at(long pc) { return find_pc_desc(pc, false); } + // pc_desc_near returns the first PCDesc at or after the givne pc. + PCDesc pc_desc_near(long pc) { return find_pc_desc(pc, true); } + + // Return a the last scope in (begin..end] + public ScopeDesc scope_desc_in(long begin, long end) { + PCDesc p = pc_desc_near(begin+1); + if (p != null && VM.getAddressValue(p.getRealPC(this)) <= end) { + return new ScopeDesc(this, p.getScopeDecodeOffset(), p.getObjDecodeOffset(), p.getReexecute()); + } + return null; + } + + static boolean match_desc(PCDesc pc, int pc_offset, boolean approximate) { + if (!approximate) { + return pc.getPCOffset() == pc_offset; + } else { + PCDesc prev = new PCDesc(pc.getAddress().addOffsetTo(-pcDescSize)); + return prev.getPCOffset() < pc_offset && pc_offset <= pc.getPCOffset(); + } + } + /** This is only for use by the debugging system, and is only intended for use in the topmost frame, where we are not guaranteed to be at a PC for which we have a PCDesc. It finds