changeset 4552:e7a0d98ad106

Merge
author mduigou
date Tue, 16 Apr 2013 14:33:26 -0700
parents 124ca22437b1 8a3335663c80
children 82bacd23c0fa
files .jcheck/conf
diffstat 10 files changed, 164 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Fri Apr 12 10:14:42 2013 +0100
+++ b/.hgtags	Tue Apr 16 14:33:26 2013 -0700
@@ -273,6 +273,7 @@
 54240c1b8e87758f28da2c6a569a926fd9e0910a jdk8-b53
 9e3ae661284dc04185b029d85440fe7811f1ed07 hs24-b21
 e8fb566b94667f88462164defa654203f0ab6820 jdk8-b54
+203d2c0ee7c4fe648464fe2c506bd91003b7a5b7 lambda-b56
 09ea7e0752b306b8ae74713aeb4eb6263e1c6836 hs24-b22
 af0c8a0808516317333dcf9af15567cdd52761ce jdk8-b55
 6124ff4218296c91e4a72f1a76c064892d39d61b jdk8-b56
--- a/.jcheck/conf	Fri Apr 12 10:14:42 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-project=jdk8
--- a/src/share/vm/classfile/classFileParser.hpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/classfile/classFileParser.hpp	Tue Apr 16 14:33:26 2013 -0700
@@ -56,6 +56,7 @@
   bool _has_finalizer;
   bool _has_empty_finalizer;
   bool _has_vanilla_constructor;
+  bool _requires_bridges;
   int _max_bootstrap_specifier_index;  // detects BSS values
 
   // class attributes parsed before the instance klass is created:
@@ -95,6 +96,7 @@
     _sde_length = 0;
     // initialize the other flags too:
     _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
+    _requires_bridges = false;
     _max_bootstrap_specifier_index = -1;
     clear_class_metadata();
     _klass = NULL;
--- a/src/share/vm/classfile/defaultMethods.cpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/classfile/defaultMethods.cpp	Tue Apr 16 14:33:26 2013 -0700
@@ -1358,3 +1358,139 @@
   }
 }
 
+static void inject_missing_bridges(
+    GrowableArray<Pair<Method*,Symbol*> >* specifiers,
+    InstanceKlass* klass, TRAPS) {
+
+  GrowableArray<Method*> bridges;
+  BytecodeConstantPool bcp(klass->constants());
+
+  for (int i = 0; i < specifiers->length(); ++i) {
+    Method* target = specifiers->at(i).first;
+    Symbol* sig = specifiers->at(i).second;
+
+    // We don't need a bridge if the method already exists
+    if (klass->find_method(target->name(), sig) == NULL) {
+#ifndef PRODUCT
+      if (TraceBridgeCreation) {
+        tty->print("  Creating bridge to ");
+        print_method(tty, target, true);
+        tty->print_cr(" from signature: %s", sig->as_C_string());
+      }
+#endif
+      BytecodeBuffer buffer;
+      int max_stack = assemble_redirect(&bcp, &buffer, sig, target, CHECK);
+
+      AccessFlags flags = accessFlags_from(JVM_ACC_PUBLIC | JVM_ACC_BRIDGE);
+      Method* bridge = new_method(&bcp, &buffer, target->name(), sig, flags,
+          max_stack, target->size_of_parameters(), ConstMethod::NORMAL, CHECK);
+
+      bridges.push(bridge);
+    }
+  }
+
+  if (bridges.length() > 0) {
+    switchover_constant_pool(&bcp, klass, &bridges, CHECK);
+    merge_in_new_methods(klass, &bridges, CHECK);
+  }
+}
+
+class FindMissingBridges : public HierarchyVisitor<FindMissingBridges> {
+ private:
+  // Context data
+  Thread* THREAD;
+  generic::DescriptorCache* _cache;
+  Method* _method;
+  generic::MethodDescriptor* _method_descriptor;
+  generic::Context _ctx;
+  GrowableArray<Pair<Method*,Symbol*> >* _needed;
+
+ public:
+
+  FindMissingBridges(GrowableArray<Pair<Method*,Symbol*> >* needed,
+      generic::DescriptorCache* cache, Method* method, Thread* thread) :
+        THREAD(thread), _needed(needed), _cache(cache), _method(method),
+        _ctx(cache) {
+    _method_descriptor = cache->descriptor_for(method, thread);
+  }
+
+  void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); }
+  void free_node_data(void* node_data) {
+    PseudoScope::cast(node_data)->destroy();
+  }
+
+  bool visit() {
+    PseudoScope* scope = PseudoScope::cast(current_data());
+
+    InstanceKlass* ik = current_class();
+    InstanceKlass* sub = current_depth() > 0 ? class_at_depth(1) : NULL;
+
+    ContextMark* cm = new ContextMark(_ctx.mark());
+    scope->add_mark(cm); // will restore context when scope is freed
+
+    _ctx.apply_type_arguments(sub, ik, THREAD);
+
+    int end = 0;
+    int start = ik->find_method_by_name(_method->name(), &end);
+    if (start != -1) {
+      for (int i = start; i < end; ++i) {
+        Method* mo = ik->methods()->at(i);
+        generic::MethodDescriptor* md = _cache->descriptor_for(mo, THREAD);
+        if (mo->signature() != _method->signature() &&
+            _method_descriptor->covariant_match(md, &_ctx)) {
+          // TODO: only add methods if they're not present in the class
+          _needed->append(Pair<Method*,Symbol*>(_method, mo->signature()));
+        }
+      }
+    }
+    return true;
+  }
+};
+
+void DefaultMethods::create_missing_bridges(InstanceKlass* klass, TRAPS) {
+
+  ResourceMark rm(THREAD);
+  generic::DescriptorCache cache;
+
+  // Keep entire hierarchy alive for the duration of the computation
+  KeepAliveRegistrar keepAlive(THREAD);
+  KeepAliveVisitor loadKeepAlive(&keepAlive);
+  loadKeepAlive.run(klass);
+
+  if (TraceBridgeCreation) {
+    tty->print_cr("Class %s requires bridge processing",
+        klass->name()->as_klass_external_name());
+#ifdef ASSERT
+    PrintHierarchy printer;
+    printer.run(klass);
+#endif
+  }
+
+  // (target, signature) bridges needed
+  GrowableArray<Pair<Method*,Symbol*> > needed;
+
+  Array<Method*>* methods = klass->methods();
+  for (int i = 0; i < methods->length(); ++i) {
+    Method* specimen = methods->at(i);
+    if (specimen->is_public() &&
+        !specimen->is_overpass() && !specimen->is_static() &&
+        specimen->name() != vmSymbols::object_initializer_name()) {
+#ifndef PRODUCT
+      if (TraceBridgeCreation) {
+        tty->print("  Looking for missing bridges to ");
+        print_method(tty, specimen, false);
+        tty->print_cr("");
+      }
+#endif
+
+      FindMissingBridges finder(&needed, &cache, specimen, CHECK);
+      finder.run(klass);
+    }
+  }
+
+  inject_missing_bridges(&needed, klass, CHECK);
+
+  if (TraceDefaultMethods) {
+    tty->print_cr("Bridge processing complete");
+  }
+}
--- a/src/share/vm/classfile/defaultMethods.hpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/classfile/defaultMethods.hpp	Tue Apr 16 14:33:26 2013 -0700
@@ -53,6 +53,10 @@
   static Method* find_super_default(
       Klass* this_klass, Klass* super_iface,
       Symbol* method_name, Symbol* method_sig, TRAPS);
+
+  // Finds any missing bridges in a class and creates them on an as-need 
+  // basis.
+  static void create_missing_bridges(InstanceKlass* klass, TRAPS);
 };
 
 #endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
--- a/src/share/vm/classfile/genericSignatures.cpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/classfile/genericSignatures.cpp	Tue Apr 16 14:33:26 2013 -0700
@@ -268,8 +268,15 @@
     Klass* outer = SystemDictionary::find(
         outer_name, class_loader, protection_domain, CHECK_NULL);
     if (outer == NULL && !THREAD->is_Compiler_thread()) {
-      outer = SystemDictionary::resolve_super_or_fail(original_name,
-          outer_name, class_loader, protection_domain, false, CHECK_NULL);
+      if (outer_name == ik->super()->name()) {
+        outer = SystemDictionary::resolve_super_or_fail(original_name, outer_name,
+                                                        class_loader, protection_domain,
+                                                        false, CHECK_NULL);
+      }
+      else {
+        outer = SystemDictionary::resolve_or_fail(outer_name, class_loader,
+                                                  protection_domain, false, CHECK_NULL);
+      }
     }
 
     InstanceKlass* outer_ik;
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue Apr 16 14:33:26 2013 -0700
@@ -142,6 +142,7 @@
   template(tag_runtime_invisible_type_annotations,    "RuntimeInvisibleTypeAnnotations")          \
   template(tag_enclosing_method,                      "EnclosingMethod")                          \
   template(tag_bootstrap_methods,                     "BootstrapMethods")                         \
+  template(tag_requires_bridges,                      "RequiresBridges")                         \
                                                                                                   \
   /* exception klasses: at least all exceptions thrown by the VM have entries here */             \
   template(java_lang_ArithmeticException,             "java/lang/ArithmeticException")            \
--- a/src/share/vm/oops/klassVtable.cpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/oops/klassVtable.cpp	Tue Apr 16 14:33:26 2013 -0700
@@ -519,6 +519,9 @@
 // check if a method is a miranda method, given a class's methods table and it's super
 // the caller must make sure that the method belongs to an interface implemented by the class
 bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) {
+  if (m->is_static() || m->is_private()) {
+    return false;
+  }
   Symbol* name = m->name();
   Symbol* signature = m->signature();
   if (InstanceKlass::find_method(class_methods, name, signature) == NULL) {
--- a/src/share/vm/prims/methodHandles.cpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/prims/methodHandles.cpp	Tue Apr 16 14:33:26 2013 -0700
@@ -187,6 +187,11 @@
     flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
   } else if (mods.is_static()) {
     flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
+    // Check if this method is a lambda method that is genrated as
+    // private static method.
+    if (m->is_private() && m->is_synthetic() && m->method_holder()->is_interface()) {
+      vmindex = klassItable::compute_itable_index(m);
+    }
   } else if (receiver_limit != mklass &&
              !receiver_limit->is_subtype_of(mklass)) {
     return NULL;  // bad receiver limit
--- a/src/share/vm/runtime/globals.hpp	Fri Apr 12 10:14:42 2013 +0100
+++ b/src/share/vm/runtime/globals.hpp	Tue Apr 16 14:33:26 2013 -0700
@@ -3653,6 +3653,9 @@
   develop(bool, VerifyGenericSignatures, false,                             \
           "Abort VM on erroneous or inconsistent generic signatures")       \
                                                                             \
+  develop(bool, TraceBridgeCreation, false,                                 \
+          "Trace the bridge creation processing steps")                     \
+                                                                            \
   product(bool, UseVMInterruptibleIO, false,                                \
           "(Unstable, Solaris-specific) Thread interrupt before or with "   \
           "EINTR for I/O operations results in OS_INTRPT. The default value"\