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	Wed Oct  9 15:17:11 2013
--- new/src/os/bsd/dtrace/libjvm_db.c	Wed Oct  9 15:17:11 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