hotspot/src/share/vm/classfile/javaClasses.cpp
changeset 13391 30245956af37
parent 13293 c2b4f191c489
child 13392 1ef07ae0723d
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Mon Jul 23 13:04:59 2012 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Tue Jul 24 10:51:00 2012 -0700
@@ -126,6 +126,13 @@
   if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) {
     ResourceMark rm;
     tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string());
+#ifndef PRODUCT
+    klass_oop->print();
+    tty->print_cr("all fields:");
+    for (AllFieldStream fs(instanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+      tty->print_cr("  name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
+    }
+#endif //PRODUCT
     fatal("Invalid layout of preloaded class");
   }
   dest_offset = fd.offset();
@@ -1455,6 +1462,7 @@
   nmethod* nm = NULL;
   bool skip_fillInStackTrace_check = false;
   bool skip_throwableInit_check = false;
+  bool skip_hidden = false;
 
   for (frame fr = thread->last_frame(); max_depth != total_count;) {
     methodOop method = NULL;
@@ -1534,6 +1542,12 @@
         skip_throwableInit_check = true;
       }
     }
+    if (method->is_hidden()) {
+      if (skip_hidden)  continue;
+    } else {
+      // start skipping hidden frames after first non-hidden frame
+      skip_hidden = !ShowHiddenFrames;
+    }
     bt.push(method, bci, CHECK);
     total_count++;
   }
@@ -1724,6 +1738,8 @@
   java_lang_StackTraceElement::set_methodName(element(), methodname);
   // Fill in source file name
   Symbol* source = instanceKlass::cast(method->method_holder())->source_file_name();
+  if (ShowHiddenFrames && source == NULL)
+    source = vmSymbols::unknown_class_name();
   oop filename = StringTable::intern(source, CHECK_0);
   java_lang_StackTraceElement::set_fileName(element(), filename);
   // File in source line number
@@ -1736,6 +1752,9 @@
   } else {
     // Returns -1 if no LineNumberTable, and otherwise actual line number
     line_number = method->line_number_from_bci(bci);
+    if (line_number == -1 && ShowHiddenFrames) {
+      line_number = bci + 1000000;
+    }
   }
   java_lang_StackTraceElement::set_lineNumber(element(), line_number);
 
@@ -2377,8 +2396,7 @@
 // Support for java_lang_invoke_MethodHandle
 
 int java_lang_invoke_MethodHandle::_type_offset;
-int java_lang_invoke_MethodHandle::_vmtarget_offset;
-int java_lang_invoke_MethodHandle::_vmentry_offset;
+int java_lang_invoke_MethodHandle::_form_offset;
 
 int java_lang_invoke_MemberName::_clazz_offset;
 int java_lang_invoke_MemberName::_name_offset;
@@ -2387,21 +2405,16 @@
 int java_lang_invoke_MemberName::_vmtarget_offset;
 int java_lang_invoke_MemberName::_vmindex_offset;
 
-int java_lang_invoke_DirectMethodHandle::_vmindex_offset;
-
-int java_lang_invoke_BoundMethodHandle::_argument_offset;
-int java_lang_invoke_BoundMethodHandle::_vmargslot_offset;
-
-int java_lang_invoke_AdapterMethodHandle::_conversion_offset;
-
-int java_lang_invoke_CountingMethodHandle::_vmcount_offset;
+int java_lang_invoke_LambdaForm::_vmentry_offset;
 
 void java_lang_invoke_MethodHandle::compute_offsets() {
   klassOop klass_oop = SystemDictionary::MethodHandle_klass();
   if (klass_oop != NULL && EnableInvokeDynamic) {
-    bool allow_super = false;
-    compute_offset(_type_offset,      klass_oop, vmSymbols::type_name(),      vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
-    METHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
+    compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature());
+    compute_optional_offset(_form_offset, klass_oop, vmSymbols::form_name(), vmSymbols::java_lang_invoke_LambdaForm_signature());
+    if (_form_offset == 0) {
+      EnableInvokeDynamic = false;
+    }
   }
 }
 
@@ -2412,50 +2425,17 @@
     compute_offset(_name_offset,      klass_oop, vmSymbols::name_name(),      vmSymbols::string_signature());
     compute_offset(_type_offset,      klass_oop, vmSymbols::type_name(),      vmSymbols::object_signature());
     compute_offset(_flags_offset,     klass_oop, vmSymbols::flags_name(),     vmSymbols::int_signature());
-    compute_offset(_vmindex_offset,   klass_oop, vmSymbols::vmindex_name(),   vmSymbols::int_signature());
     MEMBERNAME_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
   }
 }
 
-void java_lang_invoke_DirectMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::DirectMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    DIRECTMETHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
-  }
-}
-
-void java_lang_invoke_BoundMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::BoundMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(),    true);
-    compute_offset(_argument_offset,  k, vmSymbols::argument_name(),  vmSymbols::object_signature(), true);
+void java_lang_invoke_LambdaForm::compute_offsets() {
+  klassOop klass_oop = SystemDictionary::LambdaForm_klass();
+  if (klass_oop != NULL && EnableInvokeDynamic) {
+    compute_offset(_vmentry_offset, klass_oop, vmSymbols::vmentry_name(), vmSymbols::java_lang_invoke_MemberName_signature());
   }
 }
 
-void java_lang_invoke_AdapterMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::AdapterMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true);
-  }
-}
-
-void java_lang_invoke_CountingMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::CountingMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    compute_offset(_vmcount_offset, k, vmSymbols::vmcount_name(), vmSymbols::int_signature(), true);
-  }
-}
-
-int java_lang_invoke_CountingMethodHandle::vmcount(oop mh) {
-  assert(is_instance(mh), "CMH only");
-  return mh->int_field(_vmcount_offset);
-}
-
-void java_lang_invoke_CountingMethodHandle::set_vmcount(oop mh, int count) {
-  assert(is_instance(mh), "CMH only");
-  mh->int_field_put(_vmcount_offset, count);
-}
-
 oop java_lang_invoke_MethodHandle::type(oop mh) {
   return mh->obj_field(_type_offset);
 }
@@ -2464,31 +2444,14 @@
   mh->obj_field_put(_type_offset, mtype);
 }
 
-// fetch type.form.vmslots, which is the number of JVM stack slots
-// required to carry the arguments of this MH
-int java_lang_invoke_MethodHandle::vmslots(oop mh) {
-  oop mtype = type(mh);
-  if (mtype == NULL)  return 0;  // Java code would get NPE
-  oop form = java_lang_invoke_MethodType::form(mtype);
-  if (form == NULL)   return 0;  // Java code would get NPE
-  return java_lang_invoke_MethodTypeForm::vmslots(form);
+oop java_lang_invoke_MethodHandle::form(oop mh) {
+  assert(_form_offset != 0, "");
+  return mh->obj_field(_form_offset);
 }
 
-// fetch the low-level entry point for this mh
-MethodHandleEntry* java_lang_invoke_MethodHandle::vmentry(oop mh) {
-  return (MethodHandleEntry*) mh->address_field(_vmentry_offset);
-}
-
-void java_lang_invoke_MethodHandle::set_vmentry(oop mh, MethodHandleEntry* me) {
-  assert(_vmentry_offset != 0, "must be present");
-
-  // This is always the final step that initializes a valid method handle:
-  mh->release_address_field_put(_vmentry_offset, (address) me);
-
-  // There should be enough memory barriers on exit from native methods
-  // to ensure that the MH is fully initialized to all threads before
-  // Java code can publish it in global data structures.
-  // But just in case, we use release_address_field_put.
+void java_lang_invoke_MethodHandle::set_form(oop mh, oop lform) {
+  assert(_form_offset != 0, "");
+  mh->obj_field_put(_form_offset, lform);
 }
 
 /// MemberName accessors
@@ -2540,57 +2503,40 @@
 
 void java_lang_invoke_MemberName::set_vmtarget(oop mname, oop ref) {
   assert(is_instance(mname), "wrong type");
+#ifdef ASSERT
+  // check the type of the vmtarget
+  if (ref != NULL) {
+    switch (flags(mname) & (MN_IS_METHOD |
+                            MN_IS_CONSTRUCTOR |
+                            MN_IS_FIELD)) {
+    case MN_IS_METHOD:
+    case MN_IS_CONSTRUCTOR:
+      assert(ref->is_method(), "should be a method");
+      break;
+    case MN_IS_FIELD:
+      assert(ref->is_klass(), "should be a class");
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+  }
+#endif //ASSERT
   mname->obj_field_put(_vmtarget_offset, ref);
 }
 
-int java_lang_invoke_MemberName::vmindex(oop mname) {
-  assert(is_instance(mname), "wrong type");
-  return mname->int_field(_vmindex_offset);
-}
-
-void java_lang_invoke_MemberName::set_vmindex(oop mname, int index) {
+intptr_t java_lang_invoke_MemberName::vmindex(oop mname) {
   assert(is_instance(mname), "wrong type");
-  mname->int_field_put(_vmindex_offset, index);
-}
-
-oop java_lang_invoke_MethodHandle::vmtarget(oop mh) {
-  assert(is_instance(mh), "MH only");
-  return mh->obj_field(_vmtarget_offset);
-}
-
-void java_lang_invoke_MethodHandle::set_vmtarget(oop mh, oop ref) {
-  assert(is_instance(mh), "MH only");
-  mh->obj_field_put(_vmtarget_offset, ref);
-}
-
-int java_lang_invoke_DirectMethodHandle::vmindex(oop mh) {
-  assert(is_instance(mh), "DMH only");
-  return mh->int_field(_vmindex_offset);
+  return (intptr_t) mname->address_field(_vmindex_offset);
 }
 
-void java_lang_invoke_DirectMethodHandle::set_vmindex(oop mh, int index) {
-  assert(is_instance(mh), "DMH only");
-  mh->int_field_put(_vmindex_offset, index);
-}
-
-int java_lang_invoke_BoundMethodHandle::vmargslot(oop mh) {
-  assert(is_instance(mh), "BMH only");
-  return mh->int_field(_vmargslot_offset);
+void java_lang_invoke_MemberName::set_vmindex(oop mname, intptr_t index) {
+  assert(is_instance(mname), "wrong type");
+  mname->address_field_put(_vmindex_offset, (address) index);
 }
 
-oop java_lang_invoke_BoundMethodHandle::argument(oop mh) {
-  assert(is_instance(mh), "BMH only");
-  return mh->obj_field(_argument_offset);
-}
-
-int java_lang_invoke_AdapterMethodHandle::conversion(oop mh) {
-  assert(is_instance(mh), "AMH only");
-  return mh->int_field(_conversion_offset);
-}
-
-void java_lang_invoke_AdapterMethodHandle::set_conversion(oop mh, int conv) {
-  assert(is_instance(mh), "AMH only");
-  mh->int_field_put(_conversion_offset, conv);
+oop java_lang_invoke_LambdaForm::vmentry(oop lform) {
+  assert(is_instance(lform), "wrong type");
+  return lform->obj_field(_vmentry_offset);
 }
 
 
@@ -2598,14 +2544,12 @@
 
 int java_lang_invoke_MethodType::_rtype_offset;
 int java_lang_invoke_MethodType::_ptypes_offset;
-int java_lang_invoke_MethodType::_form_offset;
 
 void java_lang_invoke_MethodType::compute_offsets() {
   klassOop k = SystemDictionary::MethodType_klass();
   if (k != NULL) {
     compute_offset(_rtype_offset,  k, vmSymbols::rtype_name(),  vmSymbols::class_signature());
     compute_offset(_ptypes_offset, k, vmSymbols::ptypes_name(), vmSymbols::class_array_signature());
-    compute_offset(_form_offset,   k, vmSymbols::form_name(),   vmSymbols::java_lang_invoke_MethodTypeForm_signature());
   }
 }
 
@@ -2635,6 +2579,8 @@
 }
 
 bool java_lang_invoke_MethodType::equals(oop mt1, oop mt2) {
+  if (mt1 == mt2)
+    return true;
   if (rtype(mt1) != rtype(mt2))
     return false;
   if (ptype_count(mt1) != ptype_count(mt2))
@@ -2656,11 +2602,6 @@
   return (objArrayOop) mt->obj_field(_ptypes_offset);
 }
 
-oop java_lang_invoke_MethodType::form(oop mt) {
-  assert(is_instance(mt), "must be a MethodType");
-  return mt->obj_field(_form_offset);
-}
-
 oop java_lang_invoke_MethodType::ptype(oop mt, int idx) {
   return ptypes(mt)->obj_at(idx);
 }
@@ -2669,62 +2610,20 @@
   return ptypes(mt)->length();
 }
 
-
-
-// Support for java_lang_invoke_MethodTypeForm
-
-int java_lang_invoke_MethodTypeForm::_vmslots_offset;
-int java_lang_invoke_MethodTypeForm::_vmlayout_offset;
-int java_lang_invoke_MethodTypeForm::_erasedType_offset;
-int java_lang_invoke_MethodTypeForm::_genericInvoker_offset;
-
-void java_lang_invoke_MethodTypeForm::compute_offsets() {
-  klassOop k = SystemDictionary::MethodTypeForm_klass();
-  if (k != NULL) {
-    compute_optional_offset(_vmslots_offset,    k, vmSymbols::vmslots_name(),    vmSymbols::int_signature(), true);
-    compute_optional_offset(_vmlayout_offset,   k, vmSymbols::vmlayout_name(),   vmSymbols::object_signature());
-    compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true);
-    compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true);
-    if (_genericInvoker_offset == 0)  _genericInvoker_offset = -1;  // set to explicit "empty" value
-    METHODTYPEFORM_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
+int java_lang_invoke_MethodType::ptype_slot_count(oop mt) {
+  objArrayOop pts = ptypes(mt);
+  int count = pts->length();
+  int slots = 0;
+  for (int i = 0; i < count; i++) {
+    BasicType bt = java_lang_Class::as_BasicType(pts->obj_at(i));
+    slots += type2size[bt];
   }
-}
-
-int java_lang_invoke_MethodTypeForm::vmslots(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  assert(_vmslots_offset > 0, "");
-  return mtform->int_field(_vmslots_offset);
+  return slots;
 }
 
-oop java_lang_invoke_MethodTypeForm::vmlayout(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  assert(_vmlayout_offset > 0, "");
-  return mtform->obj_field(_vmlayout_offset);
-}
-
-oop java_lang_invoke_MethodTypeForm::init_vmlayout(oop mtform, oop cookie) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  oop previous = vmlayout(mtform);
-  if (previous != NULL) {
-    return previous;  // someone else beat us to it
-  }
-  HeapWord* cookie_addr = (HeapWord*) mtform->obj_field_addr<oop>(_vmlayout_offset);
-  OrderAccess::storestore();  // make sure our copy is fully committed
-  previous = oopDesc::atomic_compare_exchange_oop(cookie, cookie_addr, previous);
-  if (previous != NULL) {
-    return previous;  // someone else beat us to it
-  }
-  return cookie;
-}
-
-oop java_lang_invoke_MethodTypeForm::erasedType(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  return mtform->obj_field(_erasedType_offset);
-}
-
-oop java_lang_invoke_MethodTypeForm::genericInvoker(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  return mtform->obj_field(_genericInvoker_offset);
+int java_lang_invoke_MethodType::rtype_slot_count(oop mt) {
+  BasicType bt = java_lang_Class::as_BasicType(rtype(mt));
+  return type2size[bt];
 }
 
 
@@ -2798,10 +2697,26 @@
 }
 
 oop java_lang_ClassLoader::parent(oop loader) {
-  assert(loader->is_oop(), "loader must be oop");
+  assert(is_instance(loader), "loader must be oop");
   return loader->obj_field(parent_offset);
 }
 
+bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) {
+  assert(is_instance(loader), "loader must be oop");
+  assert(cl == NULL || is_instance(cl), "cl argument must be oop");
+  oop acl = loader;
+  debug_only(jint loop_count = 0);
+  // This loop taken verbatim from ClassLoader.java:
+  do {
+    acl = parent(acl);
+    if (cl == acl) {
+      return true;
+    }
+    assert(++loop_count > 0, "loop_count overflow");
+  } while (acl != NULL);
+  return false;
+}
+
 
 // For class loader classes, parallelCapable defined
 // based on non-null field
@@ -3061,13 +2976,9 @@
   if (EnableInvokeDynamic) {
     java_lang_invoke_MethodHandle::compute_offsets();
     java_lang_invoke_MemberName::compute_offsets();
-    java_lang_invoke_DirectMethodHandle::compute_offsets();
-    java_lang_invoke_BoundMethodHandle::compute_offsets();
-    java_lang_invoke_AdapterMethodHandle::compute_offsets();
+    java_lang_invoke_LambdaForm::compute_offsets();
     java_lang_invoke_MethodType::compute_offsets();
-    java_lang_invoke_MethodTypeForm::compute_offsets();
     java_lang_invoke_CallSite::compute_offsets();
-    java_lang_invoke_CountingMethodHandle::compute_offsets();
   }
   java_security_AccessControlContext::compute_offsets();
   // Initialize reflection classes. The layouts of these classes
@@ -3295,7 +3206,14 @@
     }
   }
   ResourceMark rm;
-  tty->print_cr("Invalid layout of %s at %s", instanceKlass::cast(klass_oop)->external_name(), name()->as_C_string());
+  tty->print_cr("Invalid layout of %s at %s/%s%s", instanceKlass::cast(klass_oop)->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : "");
+#ifndef PRODUCT
+  klass_oop->print();
+  tty->print_cr("all fields:");
+  for (AllFieldStream fs(instanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+    tty->print_cr("  name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
+  }
+#endif //PRODUCT
   fatal("Invalid layout of preloaded class");
   return -1;
 }