144 uint64_t nmethod_vtbl; |
144 uint64_t nmethod_vtbl; |
145 uint64_t CodeBlob_vtbl; |
145 uint64_t CodeBlob_vtbl; |
146 uint64_t BufferBlob_vtbl; |
146 uint64_t BufferBlob_vtbl; |
147 uint64_t RuntimeStub_vtbl; |
147 uint64_t RuntimeStub_vtbl; |
148 |
148 |
|
149 uint64_t Use_Compressed_Oops_address; |
149 uint64_t Universe_methodKlassObj_address; |
150 uint64_t Universe_methodKlassObj_address; |
|
151 uint64_t Universe_narrow_oop_base_address; |
|
152 uint64_t Universe_narrow_oop_shift_address; |
150 uint64_t CodeCache_heap_address; |
153 uint64_t CodeCache_heap_address; |
151 uint64_t Universe_heap_base_address; |
|
152 |
154 |
153 /* Volatiles */ |
155 /* Volatiles */ |
|
156 uint8_t Use_Compressed_Oops; |
154 uint64_t Universe_methodKlassObj; |
157 uint64_t Universe_methodKlassObj; |
155 uint64_t Universe_heap_base; |
158 uint64_t Universe_narrow_oop_base; |
|
159 uint32_t Universe_narrow_oop_shift; |
156 uint64_t CodeCache_low; |
160 uint64_t CodeCache_low; |
157 uint64_t CodeCache_high; |
161 uint64_t CodeCache_high; |
158 uint64_t CodeCache_segmap_low; |
162 uint64_t CodeCache_segmap_low; |
159 uint64_t CodeCache_segmap_high; |
163 uint64_t CodeCache_segmap_high; |
160 |
164 |
277 } |
281 } |
278 } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) { |
282 } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) { |
279 if (strcmp("_methodKlassObj", vmp->fieldName) == 0) { |
283 if (strcmp("_methodKlassObj", vmp->fieldName) == 0) { |
280 J->Universe_methodKlassObj_address = vmp->address; |
284 J->Universe_methodKlassObj_address = vmp->address; |
281 } |
285 } |
282 if (strcmp("_heap_base", vmp->fieldName) == 0) { |
286 if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) { |
283 J->Universe_heap_base_address = vmp->address; |
287 J->Universe_narrow_oop_base_address = vmp->address; |
|
288 } |
|
289 if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) { |
|
290 J->Universe_narrow_oop_shift_address = vmp->address; |
284 } |
291 } |
285 } |
292 } |
286 CHECK_FAIL(err); |
293 CHECK_FAIL(err); |
287 |
294 |
288 base += SIZE_VMStructEntry; |
295 base += SIZE_VMStructEntry; |
296 if (vmp->typeName != NULL) free((void*)vmp->typeName); |
303 if (vmp->typeName != NULL) free((void*)vmp->typeName); |
297 if (vmp->fieldName != NULL) free((void*)vmp->fieldName); |
304 if (vmp->fieldName != NULL) free((void*)vmp->fieldName); |
298 return -1; |
305 return -1; |
299 } |
306 } |
300 |
307 |
|
308 static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) { |
|
309 psaddr_t sym_addr; |
|
310 int err; |
|
311 |
|
312 err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); |
|
313 if (err != PS_OK) goto fail; |
|
314 *valuep = sym_addr; |
|
315 return PS_OK; |
|
316 |
|
317 fail: |
|
318 return err; |
|
319 } |
|
320 |
301 static int read_volatiles(jvm_agent_t* J) { |
321 static int read_volatiles(jvm_agent_t* J) { |
302 uint64_t ptr; |
322 uint64_t ptr; |
303 int err; |
323 int err; |
304 |
324 |
|
325 err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address); |
|
326 if (err == PS_OK) { |
|
327 err = ps_pread(J->P, J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t)); |
|
328 CHECK_FAIL(err); |
|
329 } else { |
|
330 J->Use_Compressed_Oops = 0; |
|
331 } |
|
332 |
305 err = read_pointer(J, J->Universe_methodKlassObj_address, &J->Universe_methodKlassObj); |
333 err = read_pointer(J, J->Universe_methodKlassObj_address, &J->Universe_methodKlassObj); |
306 CHECK_FAIL(err); |
334 CHECK_FAIL(err); |
307 err = read_pointer(J, J->Universe_heap_base_address, &J->Universe_heap_base); |
335 |
308 CHECK_FAIL(err); |
336 err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base); |
|
337 CHECK_FAIL(err); |
|
338 err = ps_pread(J->P, J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t)); |
|
339 CHECK_FAIL(err); |
|
340 |
309 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory + |
341 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory + |
310 OFFSET_VirtualSpace_low, &J->CodeCache_low); |
342 OFFSET_VirtualSpace_low, &J->CodeCache_low); |
311 CHECK_FAIL(err); |
343 CHECK_FAIL(err); |
312 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory + |
344 err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory + |
313 OFFSET_VirtualSpace_high, &J->CodeCache_high); |
345 OFFSET_VirtualSpace_high, &J->CodeCache_high); |
372 |
404 |
373 fail: |
405 fail: |
374 return -1; |
406 return -1; |
375 } |
407 } |
376 |
408 |
377 static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) { |
|
378 psaddr_t sym_addr; |
|
379 int err; |
|
380 |
|
381 err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); |
|
382 if (err != PS_OK) goto fail; |
|
383 *valuep = sym_addr; |
|
384 return PS_OK; |
|
385 |
|
386 fail: |
|
387 return err; |
|
388 } |
|
389 |
|
390 static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) { |
409 static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) { |
391 psaddr_t sym_addr; |
410 psaddr_t sym_addr; |
392 int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); |
411 int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); |
393 if (err == PS_OK) { |
412 if (err == PS_OK) { |
394 err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t)); |
413 err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t)); |
456 } |
475 } |
457 |
476 |
458 static int is_methodOop(jvm_agent_t* J, uint64_t methodOopPtr) { |
477 static int is_methodOop(jvm_agent_t* J, uint64_t methodOopPtr) { |
459 uint64_t klass; |
478 uint64_t klass; |
460 int err; |
479 int err; |
461 // If heap_base is nonnull, this was a compressed oop. |
480 // If UseCompressedOops, this was a compressed oop. |
462 if (J->Universe_heap_base != NULL) { |
481 if (J->Use_Compressed_Oops != 0) { |
463 uint32_t cklass; |
482 uint32_t cklass; |
464 err = read_compressed_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata, |
483 err = read_compressed_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata, |
465 &cklass); |
484 &cklass); |
466 // decode heap oop, same as oop.inline.hpp |
485 // decode heap oop, same as oop.inline.hpp |
467 klass = (uint64_t)((uintptr_t)J->Universe_heap_base + |
486 klass = (uint64_t)((uintptr_t)J->Universe_narrow_oop_base + |
468 ((uintptr_t)cklass << 3)); |
487 ((uintptr_t)cklass << J->Universe_narrow_oop_shift)); |
469 } else { |
488 } else { |
470 err = read_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata, &klass); |
489 err = read_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata, &klass); |
471 } |
490 } |
472 if (err != PS_OK) goto fail; |
491 if (err != PS_OK) goto fail; |
473 return klass == J->Universe_methodKlassObj; |
492 return klass == J->Universe_methodKlassObj; |