hotspot/src/os/solaris/dtrace/libjvm_db.c

Print this page
rev 611 : Merge

@@ -1,10 +1,10 @@
 #ifdef USE_PRAGMA_IDENT_SRC
 #pragma ident "@(#)libjvm_db.c  1.29 07/05/05 17:04:38 JVM"
 #endif
 /*
- * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -149,13 +149,15 @@
   uint64_t BufferBlob_vtbl;
   uint64_t RuntimeStub_vtbl;
 
   uint64_t Universe_methodKlassObj_address;
   uint64_t CodeCache_heap_address;
+  uint64_t Universe_heap_base_address;
 
   /* Volatiles */
   uint64_t Universe_methodKlassObj;
+  uint64_t Universe_heap_base;
   uint64_t CodeCache_low;
   uint64_t CodeCache_high;
   uint64_t CodeCache_segmap_low;
   uint64_t CodeCache_segmap_high;
 

@@ -167,11 +169,10 @@
   Nmethod_t *N;                 /*Inlined methods support */
   Frame_t   prev_fr;
   Frame_t   curr_fr;
 };
 
-
 static int
 read_string(struct ps_prochandle *P,
         char *buf,              /* caller's buffer */
         size_t size,            /* upper limit on bytes to read */
         uintptr_t addr)         /* address in process */

@@ -186,10 +187,18 @@
     buf += 1;
   }
   return -1;
 }
 
+static int read_compressed_pointer(jvm_agent_t* J, uint64_t base, uint32_t *ptr) {
+  int err = -1;
+  uint32_t ptr32;
+  err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t));
+  *ptr = ptr32;
+  return err;
+}
+
 static int read_pointer(jvm_agent_t* J, uint64_t base, uint64_t* ptr) {
   int err = -1;
   uint32_t ptr32;
 
   switch (DATA_MODEL) {

@@ -271,10 +280,13 @@
       }
     } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) {
       if (strcmp("_methodKlassObj", vmp->fieldName) == 0) {
         J->Universe_methodKlassObj_address = vmp->address;
       }
+      if (strcmp("_heap_base", vmp->fieldName) == 0) {
+        J->Universe_heap_base_address = vmp->address;
+      }
     }
     CHECK_FAIL(err);
 
     base += SIZE_VMStructEntry;
     if (vmp->typeName != NULL) free((void*)vmp->typeName);

@@ -293,10 +305,12 @@
   uint64_t ptr;
   int err;
 
   err = read_pointer(J, J->Universe_methodKlassObj_address, &J->Universe_methodKlassObj);
   CHECK_FAIL(err);
+  err = read_pointer(J, J->Universe_heap_base_address, &J->Universe_heap_base);
+  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);

@@ -445,11 +459,21 @@
 }
 
 static int is_methodOop(jvm_agent_t* J, uint64_t methodOopPtr) {
   uint64_t klass;
   int err;
-  err = read_pointer(J, methodOopPtr + OFFSET_oopDesc_klass, &klass);
+  // If heap_base is nonnull, this was a compressed oop.
+  if (J->Universe_heap_base != NULL) {
+    uint32_t cklass;
+    err = read_compressed_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata,
+          &cklass);
+    // decode heap oop, same as oop.inline.hpp
+    klass = (uint64_t)((uintptr_t)J->Universe_heap_base +
+            ((uintptr_t)cklass << 3));
+  } else {
+    err = read_pointer(J, methodOopPtr + OFFSET_oopDesc_metadata, &klass);
+  }
   if (err != PS_OK) goto fail;
   return klass == J->Universe_methodKlassObj;
 
  fail:
   return 0;