src/os/solaris/dtrace/libjvm_db.c

Print this page

        

*** 98,107 **** --- 98,110 ---- #define COMP_METHOD_SIGN '*' #define MAX_VFRAMES_CNT 256 + // Number of code heaps in the code cache + #define HEAP_CNT 3 + typedef struct vframe { uint64_t method; int32_t sender_decode_offset; int32_t methodIdx; int32_t bci;
*** 148,167 **** 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; /* 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; int32_t SIZE_CodeCache_log2_segment; uint64_t methodPtr; uint64_t bcx; --- 151,171 ---- 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[HEAP_CNT]; /* Volatiles */ uint8_t Use_Compressed_Oops; uint64_t Universe_narrow_oop_base; uint32_t Universe_narrow_oop_shift; ! // Code cache heaps ! uint64_t Heap_low[HEAP_CNT]; ! uint64_t Heap_high[HEAP_CNT]; ! uint64_t Heap_segmap_low[HEAP_CNT]; ! uint64_t Heap_segmap_high[HEAP_CNT]; int32_t SIZE_CodeCache_log2_segment; uint64_t methodPtr; uint64_t bcx;
*** 273,284 **** 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); } } 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; } --- 277,293 ---- if (err != PS_OK || vmp->typeName == NULL) { break; } if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) { ! // Read addresses of code cache heaps ! if (strcmp("_heap_non_method", vmp->fieldName) == 0) { ! err = read_pointer(J, vmp->address, &J->CodeCache_heap_address[0]); ! } else if (strcmp("_heap_non_profiled", vmp->fieldName) == 0) { ! err = read_pointer(J, vmp->address, &J->CodeCache_heap_address[1]); ! } else if (strcmp("_heap_profiled", vmp->fieldName) == 0) { ! err = read_pointer(J, vmp->address, &J->CodeCache_heap_address[2]); } } 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; }
*** 329,401 **** 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); CHECK_FAIL(err); ! err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_memory + ! OFFSET_VirtualSpace_high, &J->CodeCache_high); CHECK_FAIL(err); ! err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap + ! OFFSET_VirtualSpace_low, &J->CodeCache_segmap_low); CHECK_FAIL(err); ! err = read_pointer(J, J->CodeCache_heap_address + OFFSET_CodeHeap_segmap + ! OFFSET_VirtualSpace_high, &J->CodeCache_segmap_high); CHECK_FAIL(err); ! err = ps_pread(J->P, J->CodeCache_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 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); } ! static uint64_t segment_for(jvm_agent_t* J, uint64_t p) { ! return (p - J->CodeCache_low) >> J->SIZE_CodeCache_log2_segment; } ! static uint64_t block_at(jvm_agent_t* J, int i) { ! return J->CodeCache_low + (i << J->SIZE_CodeCache_log2_segment); } static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) { int err; *startp = 0; ! if (J->CodeCache_low <= ptr && ptr < J->CodeCache_high) { int32_t used; ! uint64_t segment = segment_for(J, ptr); ! uint64_t block = J->CodeCache_segmap_low; 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(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; } --- 338,424 ---- 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); ! /* Read code heap information */ ! int i; ! for (i = 0; i < HEAP_CNT; ++i) { ! err = read_pointer(J, J->CodeCache_heap_address[i] + OFFSET_CodeHeap_memory + ! OFFSET_VirtualSpace_low, &J->Heap_low[i]); CHECK_FAIL(err); ! err = read_pointer(J, J->CodeCache_heap_address[i] + OFFSET_CodeHeap_memory + ! OFFSET_VirtualSpace_high, &J->Heap_low[i]); CHECK_FAIL(err); ! err = read_pointer(J, J->CodeCache_heap_address[i] + OFFSET_CodeHeap_segmap + ! OFFSET_VirtualSpace_low, &J->Heap_segmap_low[i]); CHECK_FAIL(err); ! err = read_pointer(J, J->CodeCache_heap_address[i] + OFFSET_CodeHeap_segmap + ! OFFSET_VirtualSpace_high, &J->Heap_segmap_high[i]); CHECK_FAIL(err); + } ! err = ps_pread(J->P, J->CodeCache_heap_address[0] + 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) { ! int i; ! for (i = 0; i < HEAP_CNT; ++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->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->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; + for (int i = 0; i < HEAP_CNT; ++i) { *startp = 0; ! if (codeheap_contains(i, J, ptr)) { int32_t used; ! uint64_t segment = segment_for(i, J, ptr); ! 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; }