hotspot/src/os/solaris/dtrace/libjvm_db.c
changeset 26796 666464578742
parent 25720 28c69e9cf5e2
child 26809 8d3de4de954d
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c	Tue Sep 16 14:39:11 2014 +0200
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c	Wed Sep 17 08:00:07 2014 +0200
@@ -150,16 +150,18 @@
   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;
 
@@ -278,8 +280,9 @@
     }
 
     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) {
@@ -318,7 +321,9 @@
 }
 
 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);
@@ -334,20 +339,43 @@
   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);
+  /* 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 = ps_pread(J->P, J->CodeCache_heap_address + OFFSET_CodeHeap_log2_segment_size,
+    err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
+                       OFFSET_VirtualSpace_low, &J->Heap_low[i]);
+    CHECK_FAIL(err);
+    err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory +
+                       OFFSET_VirtualSpace_high, &J->Heap_high[i]);
+    CHECK_FAIL(err);
+    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, code_heap_address + OFFSET_CodeHeap_segmap +
+                       OFFSET_VirtualSpace_high, &J->Heap_segmap_high[i]);
+    CHECK_FAIL(err);
+
+    /* 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);
 
@@ -357,46 +385,57 @@
   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 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 uint64_t segment_for(jvm_agent_t* J, uint64_t p) {
-  return (p - J->CodeCache_low) >> J->SIZE_CodeCache_log2_segment;
+static int codecache_contains(jvm_agent_t* J, uint64_t ptr) {
+  int i;
+  for (i = 0; i < J->Number_of_heaps; ++i) {
+    if (codeheap_contains(i, J, ptr)) {
+      return 1;
+    }
+  }
+  return 0;
 }
 
-static uint64_t block_at(jvm_agent_t* J, int i) {
-  return J->CodeCache_low + (i << J->SIZE_CodeCache_log2_segment);
+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;
+  int i;
 
-  *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) {
+  for (i = 0; i < J->Number_of_heaps; ++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);
-      segment -= tag;
+      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;
+      }
     }
-    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;
   }
-  return PS_OK;
 
  fail:
   return -1;