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

src/os/solaris/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 bcx;
 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);


 258   uint64_t gHotSpotVMStructs;
 259   psaddr_t sym_addr;
 260   uint64_t base;
 261   int err;
 262 
 263   err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr);
 264   CHECK_FAIL(err);
 265   err = read_pointer(J, sym_addr, &gHotSpotVMStructs);
 266   CHECK_FAIL(err);
 267   base = gHotSpotVMStructs;
 268 
 269   err = PS_OK;
 270   while (err == PS_OK) {
 271     memset(vmp, 0, sizeof(VMStructEntry));
 272     err = parse_vmstruct_entry(J, base, vmp);
 273     if (err != PS_OK || vmp->typeName == NULL) {
 274       break;
 275     }
 276 
 277     if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
 278       if (strcmp("_heap", vmp->fieldName) == 0) {
 279         err = read_pointer(J, vmp->address, &J->CodeCache_heap_address);

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


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



















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




 348                  &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
 349   CHECK_FAIL(err);
 350 
 351   return PS_OK;
 352 
 353  fail:
 354   return err;
 355 }
 356 



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





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

 373 

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

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




 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 bcx;
 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);


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


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