src/os/bsd/dtrace/libjvm_db.c
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8015774 Sdiff src/os/bsd/dtrace

src/os/bsd/dtrace/libjvm_db.c

Print this page




 133   int32_t  metadata_end;
 134   int32_t  scopes_pcs_beg;      /* _scopes_pcs_offset */
 135   int32_t  scopes_pcs_end;
 136 
 137   int      vf_cnt;
 138   Vframe_t vframes[MAX_VFRAMES_CNT];
 139 } Nmethod_t;
 140 
 141 struct jvm_agent {
 142   struct ps_prochandle* P;
 143 
 144   uint64_t nmethod_vtbl;
 145   uint64_t CodeBlob_vtbl;
 146   uint64_t BufferBlob_vtbl;
 147   uint64_t RuntimeStub_vtbl;
 148   uint64_t Method_vtbl;
 149 
 150   uint64_t Use_Compressed_Oops_address;
 151   uint64_t Universe_narrow_oop_base_address;
 152   uint64_t Universe_narrow_oop_shift_address;
 153   uint64_t CodeCache_heap_address;
 154 
 155   /* Volatiles */
 156   uint8_t  Use_Compressed_Oops;
 157   uint64_t Universe_narrow_oop_base;
 158   uint32_t Universe_narrow_oop_shift;
 159   uint64_t CodeCache_low;
 160   uint64_t CodeCache_high;
 161   uint64_t CodeCache_segmap_low;
 162   uint64_t CodeCache_segmap_high;


 163 
 164   int32_t  SIZE_CodeCache_log2_segment;
 165 
 166   uint64_t methodPtr;
 167   uint64_t bcp;
 168 
 169   Nmethod_t *N;                 /*Inlined methods support */
 170   Frame_t   prev_fr;
 171   Frame_t   curr_fr;
 172 };
 173 
 174 static int
 175 read_string(struct ps_prochandle *P,
 176         char *buf,              /* caller's buffer */
 177         size_t size,            /* upper limit on bytes to read */
 178         uintptr_t addr)         /* address in process */
 179 {
 180   int err = PS_OK;
 181   while (size-- > 1 && err == PS_OK) {
 182     err = ps_pread(P, addr, buf, 1);


 261   int err;
 262 
 263   /* Clear *vmp now in case we jump to fail: */
 264   memset(vmp, 0, sizeof(VMStructEntry));
 265 
 266   err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
 267   CHECK_FAIL(err);
 268   err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
 269   CHECK_FAIL(err);
 270   base = gHotSpotVMStructs;
 271 
 272   err = PS_OK;
 273   while (err == PS_OK) {
 274     memset(vmp, 0, sizeof(VMStructEntry));
 275     err = parse_vmstruct_entry(J, base, vmp);
 276     if (err != PS_OK || vmp->typeName == NULL) {
 277       break;
 278     }
 279 
 280     if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
 281       if (strcmp("_heap", vmp->fieldName) == 0) {
 282         err = read_pointer(J, vmp->address, &J->CodeCache_heap_address);

 283       }
 284     } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
 285       if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) {
 286         J->Universe_narrow_oop_base_address = vmp->address;
 287       }
 288       if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) {
 289         J->Universe_narrow_oop_shift_address = vmp->address;
 290       }
 291     }
 292     CHECK_FAIL(err);
 293 
 294     base += SIZE_VMStructEntry;
 295     if (vmp->typeName != NULL) free((void*)vmp->typeName);
 296     if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
 297   }
 298 
 299   return PS_OK;
 300 
 301  fail:
 302   if (vmp->typeName != NULL) free((void*)vmp->typeName);
 303   if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
 304   return -1;
 305 }
 306 
 307 static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) {
 308   psaddr_t sym_addr;
 309   int err;
 310 
 311   err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
 312   if (err != PS_OK) goto fail;
 313   *valuep = sym_addr;
 314   return PS_OK;
 315 
 316  fail:
 317   return err;
 318 }
 319 
 320 static int read_volatiles(jvm_agent_t* J) {
 321   uint64_t ptr;


 322   int err;
 323 
 324   err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address);
 325   if (err == PS_OK) {
 326     err = ps_pread(J->P,  J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
 327     CHECK_FAIL(err);
 328   } else {
 329     J->Use_Compressed_Oops = 0;
 330   }
 331 
 332   err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
 333   CHECK_FAIL(err);
 334   err = ps_pread(J->P,  J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
 335   CHECK_FAIL(err);
 336 
 337   err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
 338                      OFFSET_VirtualSpace_low, &J->CodeCache_low);



















 339   CHECK_FAIL(err);
 340   err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
 341                      OFFSET_VirtualSpace_high, &J->CodeCache_high);
 342   CHECK_FAIL(err);
 343   err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
 344                      OFFSET_VirtualSpace_low, &J->CodeCache_segmap_low);
 345   CHECK_FAIL(err);
 346   err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
 347                      OFFSET_VirtualSpace_high, &J->CodeCache_segmap_high);
 348   CHECK_FAIL(err);
 349 
 350   err = ps_pread(J->P, J->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size,




 351                  &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
 352   CHECK_FAIL(err);
 353 
 354   return PS_OK;
 355 
 356  fail:
 357   return err;
 358 }
 359 



 360 
 361 static int codecache_contains(jvm_agent_t* J, uint64_t ptr) {
 362   /* make sure the code cache is up to date */
 363   return (J->CodeCache_low <= ptr && ptr < J->CodeCache_high);





 364 }
 365 
 366 static uint64_t segment_for(jvm_agent_t* J, uint64_t p) {
 367   return (p - J->CodeCache_low) >> J->SIZE_CodeCache_log2_segment;
 368 }
 369 
 370 static uint64_t block_at(jvm_agent_t* J, int i) {
 371   return J->CodeCache_low + (i << J->SIZE_CodeCache_log2_segment);
 372 }
 373 
 374 static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) {
 375   int err;

 376 

 377   *startp = 0;
 378   if (J->CodeCache_low <= ptr && ptr < J->CodeCache_high) {
 379     int32_t used;
 380     uint64_t segment = segment_for(J, ptr);
 381     uint64_t block = J->CodeCache_segmap_low;
 382     uint8_t tag;
 383     err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
 384     CHECK_FAIL(err);
 385     if (tag == 0xff)
 386       return PS_OK;
 387     while (tag > 0) {
 388       err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
 389       CHECK_FAIL(err);
 390       segment -= tag;
 391     }
 392     block = block_at(J, segment);
 393     err = ps_pread(J->P, block + OFFSET_HeapBlockHeader_used, &used, sizeof(used));
 394     CHECK_FAIL(err);
 395     if (used) {
 396       *startp = block + SIZE_HeapBlockHeader;
 397     }
 398   }
 399   return PS_OK;

 400 
 401  fail:
 402   return -1;
 403 }
 404 
 405 static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) {
 406   psaddr_t sym_addr;
 407   int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
 408   if (err == PS_OK) {
 409     err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t));
 410     return err;
 411   }
 412   *valuep = -1;
 413   return -1;
 414 }
 415 
 416 jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers) {
 417   jvm_agent_t* J;
 418   int err;
 419 




 133   int32_t  metadata_end;
 134   int32_t  scopes_pcs_beg;      /* _scopes_pcs_offset */
 135   int32_t  scopes_pcs_end;
 136 
 137   int      vf_cnt;
 138   Vframe_t vframes[MAX_VFRAMES_CNT];
 139 } Nmethod_t;
 140 
 141 struct jvm_agent {
 142   struct ps_prochandle* P;
 143 
 144   uint64_t nmethod_vtbl;
 145   uint64_t CodeBlob_vtbl;
 146   uint64_t BufferBlob_vtbl;
 147   uint64_t RuntimeStub_vtbl;
 148   uint64_t Method_vtbl;
 149 
 150   uint64_t Use_Compressed_Oops_address;
 151   uint64_t Universe_narrow_oop_base_address;
 152   uint64_t Universe_narrow_oop_shift_address;
 153   uint64_t CodeCache_heaps_address;
 154 
 155   /* Volatiles */
 156   uint8_t  Use_Compressed_Oops;
 157   uint64_t Universe_narrow_oop_base;
 158   uint32_t Universe_narrow_oop_shift;
 159   // Code cache heaps
 160   int32_t  Number_of_heaps;
 161   uint64_t* Heap_low;
 162   uint64_t* Heap_high;
 163   uint64_t* Heap_segmap_low;
 164   uint64_t* Heap_segmap_high;
 165 
 166   int32_t  SIZE_CodeCache_log2_segment;
 167 
 168   uint64_t methodPtr;
 169   uint64_t bcp;
 170 
 171   Nmethod_t *N;                 /*Inlined methods support */
 172   Frame_t   prev_fr;
 173   Frame_t   curr_fr;
 174 };
 175 
 176 static int
 177 read_string(struct ps_prochandle *P,
 178         char *buf,              /* caller's buffer */
 179         size_t size,            /* upper limit on bytes to read */
 180         uintptr_t addr)         /* address in process */
 181 {
 182   int err = PS_OK;
 183   while (size-- > 1 && err == PS_OK) {
 184     err = ps_pread(P, addr, buf, 1);


 263   int err;
 264 
 265   /* Clear *vmp now in case we jump to fail: */
 266   memset(vmp, 0, sizeof(VMStructEntry));
 267 
 268   err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
 269   CHECK_FAIL(err);
 270   err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
 271   CHECK_FAIL(err);
 272   base = gHotSpotVMStructs;
 273 
 274   err = PS_OK;
 275   while (err == PS_OK) {
 276     memset(vmp, 0, sizeof(VMStructEntry));
 277     err = parse_vmstruct_entry(J, base, vmp);
 278     if (err != PS_OK || vmp->typeName == NULL) {
 279       break;
 280     }
 281 
 282     if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
 283       /* Read _heaps field of type GrowableArray<CodeHeaps*>*      */
 284       if (strcmp("_heaps", vmp->fieldName) == 0) {
 285         err = read_pointer(J, vmp->address, &J->CodeCache_heaps_address);
 286       }
 287     } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
 288       if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) {
 289         J->Universe_narrow_oop_base_address = vmp->address;
 290       }
 291       if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) {
 292         J->Universe_narrow_oop_shift_address = vmp->address;
 293       }
 294     }
 295     CHECK_FAIL(err);
 296 
 297     base += SIZE_VMStructEntry;
 298     if (vmp->typeName != NULL) free((void*)vmp->typeName);
 299     if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
 300   }
 301 
 302   return PS_OK;
 303 
 304  fail:
 305   if (vmp->typeName != NULL) free((void*)vmp->typeName);
 306   if (vmp->fieldName != NULL) free((void*)vmp->fieldName);
 307   return -1;
 308 }
 309 
 310 static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) {
 311   psaddr_t sym_addr;
 312   int err;
 313 
 314   err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
 315   if (err != PS_OK) goto fail;
 316   *valuep = sym_addr;
 317   return PS_OK;
 318 
 319  fail:
 320   return err;
 321 }
 322 
 323 static int read_volatiles(jvm_agent_t* J) {
 324   int i;
 325   uint64_t array_data;
 326   uint64_t code_heap_address;
 327   int err;
 328 
 329   err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address);
 330   if (err == PS_OK) {
 331     err = ps_pread(J->P,  J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
 332     CHECK_FAIL(err);
 333   } else {
 334     J->Use_Compressed_Oops = 0;
 335   }
 336 
 337   err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
 338   CHECK_FAIL(err);
 339   err = ps_pread(J->P,  J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
 340   CHECK_FAIL(err);
 341 
 342   /* CodeCache_heaps_address points to GrowableArray<CodeHeaps*>, read _data field
 343      pointing to the first entry of type CodeCache* in the array */
 344   err = read_pointer(J, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_data, &array_data);
 345   /* Read _len field containing the number of code heaps */
 346   err = ps_pread(J->P, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_len,
 347                  &J->Number_of_heaps, sizeof(J->Number_of_heaps));
 348 
 349   /* Allocate memory for heap configurations */
 350   J->Heap_low = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 351   J->Heap_high = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 352   J->Heap_segmap_low = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 353   J->Heap_segmap_high = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
 354 
 355   /* Read code heap configurations */
 356   for (i = 0; i < J->Number_of_heaps; ++i) {
 357     /* Read address of heap */
 358     err = read_pointer(J, array_data, &code_heap_address);
 359     CHECK_FAIL(err);
 360 
 361     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
 362                        OFFSET_VirtualSpace_low, &J->Heap_low[i]);
 363     CHECK_FAIL(err);
 364     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
 365                        OFFSET_VirtualSpace_high, &J->Heap_high[i]);
 366     CHECK_FAIL(err);
 367     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
 368                        OFFSET_VirtualSpace_low, &J->Heap_segmap_low[i]);
 369     CHECK_FAIL(err);
 370     err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
 371                        OFFSET_VirtualSpace_high, &J->Heap_segmap_high[i]);
 372     CHECK_FAIL(err);
 373 
 374     /* Increment pointer to next entry */
 375     array_data = array_data + POINTER_SIZE;
 376   }
 377 
 378   err = ps_pread(J->P, code_heap_address + OFFSET_CodeHeap_log2_segment_size,
 379                  &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
 380   CHECK_FAIL(err);
 381 
 382   return PS_OK;
 383 
 384  fail:
 385   return err;
 386 }
 387 
 388 static int codeheap_contains(int heap_num, jvm_agent_t* J, uint64_t ptr) {
 389   return (J->Heap_low[heap_num] <= ptr && ptr < J->Heap_high[heap_num]);
 390 }
 391 
 392 static int codecache_contains(jvm_agent_t* J, uint64_t ptr) {
 393   int i;
 394   for (i = 0; i < J->Number_of_heaps; ++i) {
 395     if (codeheap_contains(i, J, ptr)) {
 396       return 1;
 397     }
 398   }
 399   return 0;
 400 }
 401 
 402 static uint64_t segment_for(int heap_num, jvm_agent_t* J, uint64_t p) {
 403   return (p - J->Heap_low[heap_num]) >> J->SIZE_CodeCache_log2_segment;
 404 }
 405 
 406 static uint64_t block_at(int heap_num, jvm_agent_t* J, int i) {
 407   return J->Heap_low[heap_num] + (i << J->SIZE_CodeCache_log2_segment);
 408 }
 409 
 410 static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) {
 411   int err;
 412   int i;
 413 
 414   for (i = 0; i < J->Number_of_heaps; ++i) {
 415     *startp = 0;
 416     if (codeheap_contains(i, J, ptr)) {
 417       int32_t used;
 418       uint64_t segment = segment_for(i, J, ptr);
 419       uint64_t block = J->Heap_segmap_low[i];
 420       uint8_t tag;
 421       err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
 422       CHECK_FAIL(err);
 423       if (tag == 0xff)
 424         return PS_OK;
 425       while (tag > 0) {
 426         err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
 427         CHECK_FAIL(err);
 428         segment -= tag;
 429       }
 430       block = block_at(i, J, segment);
 431       err = ps_pread(J->P, block + OFFSET_HeapBlockHeader_used, &used, sizeof(used));
 432       CHECK_FAIL(err);
 433       if (used) {
 434         *startp = block + SIZE_HeapBlockHeader;
 435       }
 436     }
 437     return PS_OK;
 438   }
 439 
 440  fail:
 441   return -1;
 442 }
 443 
 444 static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) {
 445   psaddr_t sym_addr;
 446   int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr);
 447   if (err == PS_OK) {
 448     err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t));
 449     return err;
 450   }
 451   *valuep = -1;
 452   return -1;
 453 }
 454 
 455 jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers) {
 456   jvm_agent_t* J;
 457   int err;
 458 


src/os/bsd/dtrace/libjvm_db.c
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File