src/os/bsd/dtrace/libjvm_db.c
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/os/bsd/dtrace/libjvm_db.c Fri Oct 11 15:44:33 2013
--- new/src/os/bsd/dtrace/libjvm_db.c Fri Oct 11 15:44:33 2013
*** 148,167 ****
--- 148,169 ----
uint64_t Method_vtbl;
uint64_t Use_Compressed_Oops_address;
uint64_t Universe_narrow_oop_base_address;
uint64_t Universe_narrow_oop_shift_address;
! uint64_t CodeCache_heap_address;
! uint64_t CodeCache_heaps_address;
/* Volatiles */
uint8_t Use_Compressed_Oops;
uint64_t Universe_narrow_oop_base;
uint32_t Universe_narrow_oop_shift;
uint64_t CodeCache_low;
! uint64_t CodeCache_high;
! uint64_t CodeCache_segmap_low;
! uint64_t CodeCache_segmap_high;
+ // Code cache heaps
! int32_t Number_of_heaps;
! uint64_t* Heap_low;
! uint64_t* Heap_high;
+ uint64_t* Heap_segmap_low;
+ uint64_t* Heap_segmap_high;
int32_t SIZE_CodeCache_log2_segment;
uint64_t methodPtr;
uint64_t bcx;
*** 273,284 ****
--- 275,287 ----
if (err != PS_OK || vmp->typeName == NULL) {
break;
}
if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) {
if (strcmp("_heap", vmp->fieldName) == 0) {
err = read_pointer(J, vmp->address, &J->CodeCache_heap_address);
+ /* Read _heaps field of type GrowableArray<CodeHeaps*>* */
+ if (strcmp("_heaps", vmp->fieldName) == 0) {
+ err = read_pointer(J, vmp->address, &J->CodeCache_heaps_address);
}
} else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) {
J->Universe_narrow_oop_base_address = vmp->address;
}
*** 313,323 ****
--- 316,328 ----
fail:
return err;
}
static int read_volatiles(jvm_agent_t* J) {
! uint64_t ptr;
! int i;
+ uint64_t array_data;
+ uint64_t code_heap_address;
int err;
err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address);
if (err == PS_OK) {
err = ps_pread(J->P, J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t));
*** 329,401 ****
--- 334,440 ----
err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base);
CHECK_FAIL(err);
err = ps_pread(J->P, J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t));
CHECK_FAIL(err);
err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
OFFSET_VirtualSpace_low, &J->CodeCache_low);
+ /* CodeCache_heaps_address points to GrowableArray<CodeHeaps*>, read _data field
+ pointing to the first entry of type CodeCache* in the array */
+ err = read_pointer(J, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_data, &array_data);
+ /* Read _len field containing the number of code heaps */
+ err = ps_pread(J->P, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_len,
+ &J->Number_of_heaps, sizeof(J->Number_of_heaps));
+
+ /* Allocate memory for heap configurations */
+ J->Heap_low = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
+ J->Heap_high = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
+ J->Heap_segmap_low = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
+ J->Heap_segmap_high = (jvm_agent_t*)calloc(J->Number_of_heaps, sizeof(uint64_t));
+
+ /* Read code heap configurations */
+ for (i = 0; i < J->Number_of_heaps; ++i) {
+ /* Read address of heap */
+ err = read_pointer(J, array_data, &code_heap_address);
+ CHECK_FAIL(err);
+
+ err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
+ OFFSET_VirtualSpace_low, &J->Heap_low[i]);
CHECK_FAIL(err);
! err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory +
! OFFSET_VirtualSpace_high, &J->CodeCache_high);
! err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
! OFFSET_VirtualSpace_high, &J->Heap_high[i]);
CHECK_FAIL(err);
! err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
! OFFSET_VirtualSpace_low, &J->CodeCache_segmap_low);
! err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
! OFFSET_VirtualSpace_low, &J->Heap_segmap_low[i]);
CHECK_FAIL(err);
! err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap +
! OFFSET_VirtualSpace_high, &J->CodeCache_segmap_high);
! err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap +
! OFFSET_VirtualSpace_high, &J->Heap_segmap_high[i]);
CHECK_FAIL(err);
err = ps_pread(J->P, J->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size,
+ /* Increment pointer to next entry */
+ array_data = array_data + POINTER_SIZE;
+ }
+
+ err = ps_pread(J->P, code_heap_address + OFFSET_CodeHeap_log2_segment_size,
&J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment));
CHECK_FAIL(err);
return PS_OK;
fail:
return err;
}
+ static int codeheap_contains(int heap_num, jvm_agent_t* J, uint64_t ptr) {
+ return (J->Heap_low[heap_num] <= ptr && ptr < J->Heap_high[heap_num]);
+ }
static int codecache_contains(jvm_agent_t* J, uint64_t ptr) {
/* make sure the code cache is up to date */
return (J->CodeCache_low <= ptr && ptr < J->CodeCache_high);
+ int i;
+ for (i = 0; i < J->Number_of_heaps; ++i) {
+ if (codeheap_contains(i, J, ptr)) {
+ return 1;
+ }
+ }
+ return 0;
}
! static uint64_t segment_for(int heap_num, jvm_agent_t* J, uint64_t p) {
! return (p - J->CodeCache_low) >> J->SIZE_CodeCache_log2_segment;
! return (p - J->Heap_low[heap_num]) >> J->SIZE_CodeCache_log2_segment;
}
! static uint64_t block_at(int heap_num, jvm_agent_t* J, int i) {
! return J->CodeCache_low + (i << J->SIZE_CodeCache_log2_segment);
! return J->Heap_low[heap_num] + (i << J->SIZE_CodeCache_log2_segment);
}
static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) {
int err;
+ int i;
+ for (i = 0; i < J->Number_of_heaps; ++i) {
*startp = 0;
! if (J->CodeCache_low <= ptr && ptr < J->CodeCache_high) {
! if (codeheap_contains(i, J, ptr)) {
int32_t used;
! uint64_t segment = segment_for(i, J, ptr);
! uint64_t block = J->CodeCache_segmap_low;
! uint64_t block = J->Heap_segmap_low[i];
uint8_t tag;
err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
CHECK_FAIL(err);
if (tag == 0xff)
return PS_OK;
while (tag > 0) {
err = ps_pread(J->P, block + segment, &tag, sizeof(tag));
CHECK_FAIL(err);
segment -= tag;
}
! block = block_at(i, J, segment);
err = ps_pread(J->P, block + OFFSET_HeapBlockHeader_used, &used, sizeof(used));
CHECK_FAIL(err);
if (used) {
*startp = block + SIZE_HeapBlockHeader;
}
}
return PS_OK;
+ }
fail:
return -1;
}
src/os/bsd/dtrace/libjvm_db.c
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File