265 /** This is only for use by the debugging system, and is only 266 intended for use in the topmost frame, where we are not 267 guaranteed to be at a PC for which we have a PCDesc. It finds 268 the PCDesc with realPC closest to the current PC. */ 269 public PCDesc getPCDescNearDbg(Address pc) { 270 PCDesc bestGuessPCDesc = null; 271 long bestDistance = 0; 272 for (Address p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) { 273 PCDesc pcDesc = new PCDesc(p); 274 // In case pc is null 275 long distance = -pcDesc.getRealPC(this).minus(pc); 276 if ((bestGuessPCDesc == null) || 277 ((distance >= 0) && (distance < bestDistance))) { 278 bestGuessPCDesc = pcDesc; 279 bestDistance = distance; 280 } 281 } 282 return bestGuessPCDesc; 283 } 284 285 /** This is only for use by the debugging system, and is only 286 intended for use in the topmost frame, where we are not 287 guaranteed to be at a PC for which we have a PCDesc. It finds 288 the ScopeDesc closest to the current PC. NOTE that this may 289 return NULL for compiled methods which don't have any 290 ScopeDescs! */ 291 public ScopeDesc getScopeDescNearDbg(Address pc) { 292 PCDesc pd = getPCDescNearDbg(pc); 293 if (pd == null) return null; 294 return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute()); 295 } 296 297 public Map/*<Address, PcDesc>*/ getSafepoints() { 298 Map safepoints = new HashMap(); // Map<Address, PcDesc> 299 sun.jvm.hotspot.debugger.Address p = null; 300 for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); 301 p = p.addOffsetTo(pcDescSize)) { 302 PCDesc pcDesc = new PCDesc(p); 303 sun.jvm.hotspot.debugger.Address pc = pcDesc.getRealPC(this); 304 safepoints.put(pc, pcDesc); 305 } 306 return safepoints; 307 } 308 309 // FIXME: add getPCOffsetForBCI() 310 // FIXME: add embeddedOopAt() 311 // FIXME: add isDependentOn() 312 // FIXME: add isPatchableAt() 313 314 /** Support for code generation. Only here for proof-of-concept. */ 315 public static int getEntryPointOffset() { return (int) entryPointField.getOffset(); } 316 public static int getVerifiedEntryPointOffset() { return (int) verifiedEntryPointField.getOffset(); } 317 public static int getOSREntryPointOffset() { return (int) osrEntryPointField.getOffset(); } 318 public static int getEntryBCIOffset() { return (int) entryBCIField.getOffset(); } | 265 /** This is only for use by the debugging system, and is only 266 intended for use in the topmost frame, where we are not 267 guaranteed to be at a PC for which we have a PCDesc. It finds 268 the PCDesc with realPC closest to the current PC. */ 269 public PCDesc getPCDescNearDbg(Address pc) { 270 PCDesc bestGuessPCDesc = null; 271 long bestDistance = 0; 272 for (Address p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); p = p.addOffsetTo(pcDescSize)) { 273 PCDesc pcDesc = new PCDesc(p); 274 // In case pc is null 275 long distance = -pcDesc.getRealPC(this).minus(pc); 276 if ((bestGuessPCDesc == null) || 277 ((distance >= 0) && (distance < bestDistance))) { 278 bestGuessPCDesc = pcDesc; 279 bestDistance = distance; 280 } 281 } 282 return bestGuessPCDesc; 283 } 284 285 PCDesc find_pc_desc(long pc, boolean approximate) { 286 return find_pc_desc_internal(pc, approximate); 287 } 288 289 static long addressToLong(sun.jvm.hotspot.debugger.Address addr) { 290 return VM.getVM().getDebugger().getAddressValue(addr); 291 } 292 293 // Finds a PcDesc with real-pc equal to "pc" 294 PCDesc find_pc_desc_internal(long pc, boolean approximate) { 295 long base_address = addressToLong(instructionsBegin()); 296 int pc_offset = (int) (pc - base_address); 297 298 // Fallback algorithm: quasi-linear search for the PcDesc 299 // Find the last pc_offset less than the given offset. 300 // The successor must be the required match, if there is a match at all. 301 // (Use a fixed radix to avoid expensive affine pointer arithmetic.) 302 Address lower = scopesPCsBegin(); 303 Address upper = scopesPCsEnd(); 304 upper = upper.addOffsetTo(-pcDescSize); // exclude final sentinel 305 if (lower.greaterThan(upper)) return null; // native method; no PcDescs at all 306 307 // Take giant steps at first (4096, then 256, then 16, then 1) 308 int LOG2_RADIX = 4; 309 int RADIX = (1 << LOG2_RADIX); 310 Address mid; 311 for (int step = (1 << (LOG2_RADIX*3)); step > 1; step >>= LOG2_RADIX) { 312 while ((mid = lower.addOffsetTo(step * pcDescSize)).lessThan(upper)) { 313 PCDesc m = new PCDesc(mid); 314 if (m.getPCOffset() < pc_offset) { 315 lower = mid; 316 } else { 317 upper = mid; 318 break; 319 } 320 } 321 } 322 323 // Sneak up on the value with a linear search of length ~16. 324 while (true) { 325 mid = lower.addOffsetTo(pcDescSize); 326 PCDesc m = new PCDesc(mid); 327 if (m.getPCOffset() < pc_offset) { 328 lower = mid; 329 } else { 330 upper = mid; 331 break; 332 } 333 } 334 335 PCDesc u = new PCDesc(upper); 336 if (match_desc(u, pc_offset, approximate)) { 337 return u; 338 } else { 339 return null; 340 } 341 } 342 343 344 // ScopeDesc retrieval operation 345 PCDesc pc_desc_at(long pc) { return find_pc_desc(pc, false); } 346 // pc_desc_near returns the first PCDesc at or after the givne pc. 347 PCDesc pc_desc_near(long pc) { return find_pc_desc(pc, true); } 348 349 // Return a the last scope in (begin..end] 350 public ScopeDesc scope_desc_in(long begin, long end) { 351 PCDesc p = pc_desc_near(begin+1); 352 if (p != null && addressToLong(p.getRealPC(this)) <= end) { 353 return new ScopeDesc(this, p.getScopeDecodeOffset(), p.getReexecute()); 354 } 355 return null; 356 } 357 358 static boolean match_desc(PCDesc pc, int pc_offset, boolean approximate) { 359 if (!approximate) 360 return pc.getPCOffset() == pc_offset; 361 else { 362 PCDesc prev = new PCDesc(pc.getAddress().addOffsetTo(-pcDescSize)); 363 return prev.getPCOffset() < pc_offset && pc_offset <= pc.getPCOffset(); 364 } 365 } 366 367 /** This is only for use by the debugging system, and is only 368 intended for use in the topmost frame, where we are not 369 guaranteed to be at a PC for which we have a PCDesc. It finds 370 the ScopeDesc closest to the current PC. NOTE that this may 371 return NULL for compiled methods which don't have any 372 ScopeDescs! */ 373 public ScopeDesc getScopeDescNearDbg(Address pc) { 374 PCDesc pd = getPCDescNearDbg(pc); 375 if (pd == null) return null; 376 return new ScopeDesc(this, pd.getScopeDecodeOffset(), pd.getReexecute()); 377 } 378 379 public Map/*<Address, PCDesc>*/ getSafepoints() { 380 Map safepoints = new HashMap(); // Map<Address, PCDesc> 381 sun.jvm.hotspot.debugger.Address p = null; 382 for (p = scopesPCsBegin(); p.lessThan(scopesPCsEnd()); 383 p = p.addOffsetTo(pcDescSize)) { 384 PCDesc pcDesc = new PCDesc(p); 385 sun.jvm.hotspot.debugger.Address pc = pcDesc.getRealPC(this); 386 safepoints.put(pc, pcDesc); 387 } 388 return safepoints; 389 } 390 391 // FIXME: add getPCOffsetForBCI() 392 // FIXME: add embeddedOopAt() 393 // FIXME: add isDependentOn() 394 // FIXME: add isPatchableAt() 395 396 /** Support for code generation. Only here for proof-of-concept. */ 397 public static int getEntryPointOffset() { return (int) entryPointField.getOffset(); } 398 public static int getVerifiedEntryPointOffset() { return (int) verifiedEntryPointField.getOffset(); } 399 public static int getOSREntryPointOffset() { return (int) osrEntryPointField.getOffset(); } 400 public static int getEntryBCIOffset() { return (int) entryBCIField.getOffset(); } |