diff src/share/vm/code/relocInfo.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 6c97c830fb6f
children cd3d6a6b95d9
line wrap: on
line diff
--- a/src/share/vm/code/relocInfo.cpp	Fri Aug 31 16:39:35 2012 -0700
+++ b/src/share/vm/code/relocInfo.cpp	Sat Sep 01 13:25:18 2012 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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
@@ -439,6 +439,11 @@
         oop_Relocation* r = (oop_Relocation*)reloc();
         return oop_Relocation::spec(r->oop_index(), r->offset() + offset);
       }
+    case relocInfo::metadata_type:
+      {
+        metadata_Relocation* r = (metadata_Relocation*)reloc();
+        return metadata_Relocation::spec(r->metadata_index(), r->offset() + offset);
+      }
     default:
       ShouldNotReachHere();
     }
@@ -578,33 +583,33 @@
   unpack_2_ints(_oop_index, _offset);
 }
 
+void metadata_Relocation::pack_data_to(CodeSection* dest) {
+  short* p = (short*) dest->locs_end();
+  p = pack_2_ints_to(p, _metadata_index, _offset);
+  dest->set_locs_end((relocInfo*) p);
+}
+
+
+void metadata_Relocation::unpack_data() {
+  unpack_2_ints(_metadata_index, _offset);
+}
+
 
 void virtual_call_Relocation::pack_data_to(CodeSection* dest) {
   short*  p     = (short*) dest->locs_end();
   address point =          dest->locs_point();
 
-  // Try to make a pointer NULL first.
-  if (_oop_limit >= point &&
-      _oop_limit <= point + NativeCall::instruction_size) {
-    _oop_limit = NULL;
-  }
-  // If the _oop_limit is NULL, it "defaults" to the end of the call.
-  // See ic_call_Relocation::oop_limit() below.
-
-  normalize_address(_first_oop, dest);
-  normalize_address(_oop_limit, dest);
-  jint x0 = scaled_offset_null_special(_first_oop, point);
-  jint x1 = scaled_offset_null_special(_oop_limit, point);
-  p = pack_2_ints_to(p, x0, x1);
+  normalize_address(_cached_value, dest);
+  jint x0 = scaled_offset_null_special(_cached_value, point);
+  p = pack_1_int_to(p, x0);
   dest->set_locs_end((relocInfo*) p);
 }
 
 
 void virtual_call_Relocation::unpack_data() {
-  jint x0, x1; unpack_2_ints(x0, x1);
+  jint x0 = unpack_1_int();
   address point = addr();
-  _first_oop = x0==0? NULL: address_from_scaled_offset(x0, point);
-  _oop_limit = x1==0? NULL: address_from_scaled_offset(x1, point);
+  _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point);
 }
 
 
@@ -799,100 +804,48 @@
   }
 }
 
-
-RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
-                                                oop* &oop_addr, bool *is_optimized) {
-  assert(ic_call != NULL, "ic_call address must be set");
-  assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
-  if (nm == NULL) {
-    CodeBlob* code;
-    if (ic_call != NULL) {
-      code = CodeCache::find_blob(ic_call);
-    } else if (first_oop != NULL) {
-      code = CodeCache::find_blob(first_oop);
-    }
-    nm = code->as_nmethod_or_null();
-    assert(nm != NULL, "address to parse must be in nmethod");
-  }
-  assert(ic_call   == NULL || nm->contains(ic_call),   "must be in nmethod");
-  assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod");
-
-  address oop_limit = NULL;
-
-  if (ic_call != NULL) {
-    // search for the ic_call at the given address
-    RelocIterator iter(nm, ic_call, ic_call+1);
-    bool ret = iter.next();
-    assert(ret == true, "relocInfo must exist at this address");
-    assert(iter.addr() == ic_call, "must find ic_call");
-    if (iter.type() == relocInfo::virtual_call_type) {
-      virtual_call_Relocation* r = iter.virtual_call_reloc();
-      first_oop = r->first_oop();
-      oop_limit = r->oop_limit();
-      *is_optimized = false;
+// meta data versions
+Metadata** metadata_Relocation::metadata_addr() {
+  int n = _metadata_index;
+  if (n == 0) {
+    // metadata is stored in the code stream
+    return (Metadata**) pd_address_in_code();
     } else {
-      assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
-      *is_optimized = true;
-      oop_addr = NULL;
-      first_oop = NULL;
-      return iter;
+    // metadata is stored in table at nmethod::metadatas_begin
+    return code()->metadata_addr_at(n);
     }
   }
 
-  // search for the first_oop, to get its oop_addr
-  RelocIterator all_oops(nm, first_oop);
-  RelocIterator iter = all_oops;
-  iter.set_limit(first_oop+1);
-  bool found_oop = false;
-  while (iter.next()) {
-    if (iter.type() == relocInfo::oop_type) {
-      assert(iter.addr() == first_oop, "must find first_oop");
-      oop_addr = iter.oop_reloc()->oop_addr();
-      found_oop = true;
-      break;
-    }
-  }
-  assert(found_oop, "must find first_oop");
 
-  bool did_reset = false;
-  while (ic_call == NULL) {
-    // search forward for the ic_call matching the given first_oop
-    while (iter.next()) {
-      if (iter.type() == relocInfo::virtual_call_type) {
-        virtual_call_Relocation* r = iter.virtual_call_reloc();
-        if (r->first_oop() == first_oop) {
-          ic_call   = r->addr();
-          oop_limit = r->oop_limit();
-          break;
-        }
-      }
-    }
-    guarantee(!did_reset, "cannot find ic_call");
-    iter = RelocIterator(nm); // search the whole nmethod
-    did_reset = true;
+Metadata* metadata_Relocation::metadata_value() {
+  Metadata* v = *metadata_addr();
+  // clean inline caches store a special pseudo-null
+  if (v == (Metadata*)Universe::non_oop_word())  v = NULL;
+  return v;
   }
 
-  assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
-  all_oops.set_limit(oop_limit);
-  return all_oops;
+
+void metadata_Relocation::fix_metadata_relocation() {
+  if (!metadata_is_immediate()) {
+    // get the metadata from the pool, and re-insert it into the instruction:
+    pd_fix_value(value());
+  }
 }
 
 
-address virtual_call_Relocation::first_oop() {
-  assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
-  return _first_oop;
+void metadata_Relocation::verify_metadata_relocation() {
+  if (!metadata_is_immediate()) {
+    // get the metadata from the pool, and re-insert it into the instruction:
+    verify_value(value());
+  }
 }
 
-
-address virtual_call_Relocation::oop_limit() {
-  if (_oop_limit == NULL)
-    return addr() + NativeCall::instruction_size;
-  else
-    return _oop_limit;
+address virtual_call_Relocation::cached_value() {
+  assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call");
+  return _cached_value;
 }
 
 
-
 void virtual_call_Relocation::clear_inline_cache() {
   // No stubs for ICs
   // Clean IC
@@ -1139,6 +1092,25 @@
       }
       break;
     }
+  case relocInfo::metadata_type:
+    {
+      metadata_Relocation* r = metadata_reloc();
+      Metadata** metadata_addr  = NULL;
+      Metadata*    raw_metadata   = NULL;
+      Metadata*    metadata_value = NULL;
+      if (code() != NULL || r->metadata_is_immediate()) {
+        metadata_addr  = r->metadata_addr();
+        raw_metadata   = *metadata_addr;
+        metadata_value = r->metadata_value();
+      }
+      tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]",
+                 metadata_addr, (address)raw_metadata, r->offset());
+      if (metadata_value != NULL) {
+        tty->print("metadata_value=" INTPTR_FORMAT ": ", (address)metadata_value);
+        metadata_value->print_value_on(tty);
+      }
+      break;
+    }
   case relocInfo::external_word_type:
   case relocInfo::internal_word_type:
   case relocInfo::section_word_type:
@@ -1157,8 +1129,8 @@
   case relocInfo::virtual_call_type:
     {
       virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
-      tty->print(" | [destination=" INTPTR_FORMAT " first_oop=" INTPTR_FORMAT " oop_limit=" INTPTR_FORMAT "]",
-                 r->destination(), r->first_oop(), r->oop_limit());
+      tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT "]",
+                 r->destination(), r->cached_value());
       break;
     }
   case relocInfo::static_stub_type: