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