changeset 23215:488661b9cbda jdk8u65-b02

Merge
author asaha
date Wed, 17 Jun 2015 23:23:12 -0700
parents e3baf4f676e5 06114526675f
children 9dc578eda241
files .hgtags make/hotspot_version
diffstat 10 files changed, 203 insertions(+), 119 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Mon Jun 15 11:38:38 2015 -0700
+++ b/.hgtags	Wed Jun 17 23:23:12 2015 -0700
@@ -705,6 +705,8 @@
 3fa5c654c143fe309e5ddda92adc5fb132365bcf jdk8u60-b18
 b852350a2bc6d5f43006e2be53fb74d148290708 hs25.60-b19
 bd9221771f6e34e63b3b340ffcf9906ccf882dae jdk8u60-b19
+e01a710549a962cee94728271248a7d89fb56c49 hs25.60-b20
+3b6c97747ccc61d189bca64b4afa3ffc13680810 jdk8u60-b20
 0219ab69f00782e5c49687e2fa75138a7ffddea1 jdk8u52-b06
 9b6f44853eed8caba935915c7e710c546b205c8e jdk8u52-b07
 0219ab69f00782e5c49687e2fa75138a7ffddea1 jdk8u65-b00
--- a/make/linux/Makefile	Mon Jun 15 11:38:38 2015 -0700
+++ b/make/linux/Makefile	Wed Jun 17 23:23:12 2015 -0700
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2015, 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
@@ -229,7 +229,7 @@
 # Solaris 2.5.1, 2.6).
 # Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok.
 
-SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3%
+SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% 4%
 OS_VERSION := $(shell uname -r)
 EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION))
 
--- a/src/share/vm/interpreter/linkResolver.cpp	Mon Jun 15 11:38:38 2015 -0700
+++ b/src/share/vm/interpreter/linkResolver.cpp	Wed Jun 17 23:23:12 2015 -0700
@@ -1592,6 +1592,26 @@
   result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
 }
 
+static void wrap_invokedynamic_exception(TRAPS) {
+  if (HAS_PENDING_EXCEPTION) {
+    if (TraceMethodHandles) {
+      tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION));
+      PENDING_EXCEPTION->print();
+    }
+    if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
+      // throw these guys, since they are already wrapped
+      return;
+    }
+    if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
+      // intercept only LinkageErrors which might have failed to wrap
+      return;
+    }
+    // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
+    Handle nested_exception(THREAD, PENDING_EXCEPTION);
+    CLEAR_PENDING_EXCEPTION;
+    THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
+  }
+}
 
 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
   assert(EnableInvokeDynamic, "");
@@ -1607,7 +1627,8 @@
   ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index);
   if (cpce->is_f1_null()) {
     int pool_index = cpce->constant_pool_index();
-    oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK);
+    oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, THREAD);
+    wrap_invokedynamic_exception(CHECK);
     assert(bsm_info != NULL, "");
     // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic.
     bootstrap_specifier = Handle(THREAD, bsm_info);
@@ -1616,7 +1637,8 @@
     methodHandle method(     THREAD, cpce->f1_as_method());
     Handle       appendix(   THREAD, cpce->appendix_if_resolved(pool));
     Handle       method_type(THREAD, cpce->method_type_if_resolved(pool));
-    result.set_handle(method, appendix, method_type, CHECK);
+    result.set_handle(method, appendix, method_type, THREAD);
+    wrap_invokedynamic_exception(CHECK);
     return;
   }
 
@@ -1647,25 +1669,9 @@
                                                      &resolved_appendix,
                                                      &resolved_method_type,
                                                      THREAD);
-  if (HAS_PENDING_EXCEPTION) {
-    if (TraceMethodHandles) {
-      tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION));
-      PENDING_EXCEPTION->print();
-    }
-    if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
-      // throw these guys, since they are already wrapped
-      return;
-    }
-    if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
-      // intercept only LinkageErrors which might have failed to wrap
-      return;
-    }
-    // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
-    Handle nested_exception(THREAD, PENDING_EXCEPTION);
-    CLEAR_PENDING_EXCEPTION;
-    THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
-  }
-  result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
+  wrap_invokedynamic_exception(CHECK);
+  result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
+  wrap_invokedynamic_exception(CHECK);
 }
 
 //------------------------------------------------------------------------------------------------------------------------
--- a/src/share/vm/memory/metaspace.cpp	Mon Jun 15 11:38:38 2015 -0700
+++ b/src/share/vm/memory/metaspace.cpp	Wed Jun 17 23:23:12 2015 -0700
@@ -622,7 +622,8 @@
   Metachunk* _chunks_in_use[NumberOfInUseLists];
   Metachunk* _current_chunk;
 
-  // Maximum number of small chunks to allocate to a SpaceManager
+  // Number of small chunks to allocate to a manager
+  // If class space manager, small chunks are unlimited
   static uint const _small_chunk_limit;
 
   // Sum of all space in allocated chunks
@@ -736,8 +737,6 @@
   // Block allocation and deallocation.
   // Allocates a block from the current chunk
   MetaWord* allocate(size_t word_size);
-  // Allocates a block from a small chunk
-  MetaWord* get_small_chunk_and_allocate(size_t word_size);
 
   // Helper for allocations
   MetaWord* allocate_work(size_t word_size);
@@ -2032,8 +2031,9 @@
 size_t SpaceManager::calc_chunk_size(size_t word_size) {
 
   // Decide between a small chunk and a medium chunk.  Up to
-  // _small_chunk_limit small chunks can be allocated.
-  // After that a medium chunk is preferred.
+  // _small_chunk_limit small chunks can be allocated but
+  // once a medium chunk has been allocated, no more small
+  // chunks will be allocated.
   size_t chunk_word_size;
   if (chunks_in_use(MediumIndex) == NULL &&
       sum_count_in_chunks_in_use(SmallIndex) < _small_chunk_limit) {
@@ -2101,7 +2101,7 @@
                             word_size, words_used, words_left);
   }
 
-  // Get another chunk
+  // Get another chunk out of the virtual space
   size_t grow_chunks_by_words = calc_chunk_size(word_size);
   Metachunk* next = get_new_chunk(word_size, grow_chunks_by_words);
 
@@ -2432,43 +2432,6 @@
   return next;
 }
 
-/*
- * The policy is to allocate up to _small_chunk_limit small chunks
- * after which only medium chunks are allocated.  This is done to
- * reduce fragmentation.  In some cases, this can result in a lot
- * of small chunks being allocated to the point where it's not
- * possible to expand.  If this happens, there may be no medium chunks
- * available and OOME would be thrown.  Instead of doing that,
- * if the allocation request size fits in a small chunk, an attempt
- * will be made to allocate a small chunk.
- */
-MetaWord* SpaceManager::get_small_chunk_and_allocate(size_t word_size) {
-  if (word_size + Metachunk::overhead() > small_chunk_size()) {
-    return NULL;
-  }
-
-  MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
-  MutexLockerEx cl1(expand_lock(), Mutex::_no_safepoint_check_flag);
-
-  Metachunk* chunk = chunk_manager()->chunk_freelist_allocate(small_chunk_size());
-
-  MetaWord* mem = NULL;
-
-  if (chunk != NULL) {
-    // Add chunk to the in-use chunk list and do an allocation from it.
-    // Add to this manager's list of chunks in use.
-    add_chunk(chunk, false);
-    mem = chunk->allocate(word_size);
-
-    inc_used_metrics(word_size);
-
-    // Track metaspace memory usage statistic.
-    track_metaspace_memory_usage();
-  }
-
-  return mem;
-}
-
 MetaWord* SpaceManager::allocate(size_t word_size) {
   MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
 
@@ -3548,18 +3511,7 @@
   }
 
   if (result == NULL) {
-    SpaceManager* sm;
-    if (is_class_space_allocation(mdtype)) {
-      sm = loader_data->metaspace_non_null()->class_vsm();
-    } else {
-      sm = loader_data->metaspace_non_null()->vsm();
-    }
-
-    result = sm->get_small_chunk_and_allocate(word_size);
-
-    if (result == NULL) {
-      report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
-    }
+    report_metadata_oome(loader_data, word_size, type, mdtype, CHECK_NULL);
   }
 
   // Zero initialize.
--- a/src/share/vm/opto/loopTransform.cpp	Mon Jun 15 11:38:38 2015 -0700
+++ b/src/share/vm/opto/loopTransform.cpp	Wed Jun 17 23:23:12 2015 -0700
@@ -1821,7 +1821,10 @@
   // Find the pre-loop limit; we will expand it's iterations to
   // not ever trip low tests.
   Node *p_f = iffm->in(0);
-  assert(p_f->Opcode() == Op_IfFalse, "");
+  // pre loop may have been optimized out
+  if (p_f->Opcode() != Op_IfFalse) {
+    return;
+  }
   CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd();
   assert(pre_end->loopnode()->is_pre_loop(), "");
   Node *pre_opaq1 = pre_end->limit();
--- a/src/share/vm/opto/type.cpp	Mon Jun 15 11:38:38 2015 -0700
+++ b/src/share/vm/opto/type.cpp	Wed Jun 17 23:23:12 2015 -0700
@@ -1180,11 +1180,11 @@
   // Certain normalizations keep us sane when comparing types.
   // The 'SMALLINT' covers constants and also CC and its relatives.
   if (lo <= hi) {
-    if ((juint)(hi - lo) <= SMALLINT)  w = Type::WidenMin;
-    if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT
+    if (((juint)hi - lo) <= SMALLINT)  w = Type::WidenMin;
+    if (((juint)hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT
   } else {
-    if ((juint)(lo - hi) <= SMALLINT)  w = Type::WidenMin;
-    if ((juint)(lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT
+    if (((juint)lo - hi) <= SMALLINT)  w = Type::WidenMin;
+    if (((juint)lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT
   }
   return w;
 }
@@ -1438,11 +1438,11 @@
   // Certain normalizations keep us sane when comparing types.
   // The 'SMALLINT' covers constants.
   if (lo <= hi) {
-    if ((julong)(hi - lo) <= SMALLINT)   w = Type::WidenMin;
-    if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG
+    if (((julong)hi - lo) <= SMALLINT)   w = Type::WidenMin;
+    if (((julong)hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG
   } else {
-    if ((julong)(lo - hi) <= SMALLINT)   w = Type::WidenMin;
-    if ((julong)(lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG
+    if (((julong)lo - hi) <= SMALLINT)   w = Type::WidenMin;
+    if (((julong)lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG
   }
   return w;
 }
--- a/src/share/vm/prims/jni.cpp	Mon Jun 15 11:38:38 2015 -0700
+++ b/src/share/vm/prims/jni.cpp	Wed Jun 17 23:23:12 2015 -0700
@@ -1325,39 +1325,32 @@
     Method* m = Method::resolve_jmethod_id(method_id);
     number_of_parameters = m->size_of_parameters();
     Klass* holder = m->method_holder();
-    if (!(holder)->is_interface()) {
+    if (call_type != JNI_VIRTUAL) {
+        selected_method = m;
+    } else if (!m->has_itable_index()) {
       // non-interface call -- for that little speed boost, don't handlize
       debug_only(No_Safepoint_Verifier nosafepoint;)
-      if (call_type == JNI_VIRTUAL) {
-        // jni_GetMethodID makes sure class is linked and initialized
-        // so m should have a valid vtable index.
-        assert(!m->has_itable_index(), "");
-        int vtbl_index = m->vtable_index();
-        if (vtbl_index != Method::nonvirtual_vtable_index) {
-          Klass* k = h_recv->klass();
-          // k might be an arrayKlassOop but all vtables start at
-          // the same place. The cast is to avoid virtual call and assertion.
-          InstanceKlass *ik = (InstanceKlass*)k;
-          selected_method = ik->method_at_vtable(vtbl_index);
-        } else {
-          // final method
-          selected_method = m;
-        }
+      // jni_GetMethodID makes sure class is linked and initialized
+      // so m should have a valid vtable index.
+      assert(m->valid_vtable_index(), "no valid vtable index");
+      int vtbl_index = m->vtable_index();
+      if (vtbl_index != Method::nonvirtual_vtable_index) {
+        Klass* k = h_recv->klass();
+        // k might be an arrayKlassOop but all vtables start at
+        // the same place. The cast is to avoid virtual call and assertion.
+        InstanceKlass *ik = (InstanceKlass*)k;
+        selected_method = ik->method_at_vtable(vtbl_index);
       } else {
-        // JNI_NONVIRTUAL call
+        // final method
         selected_method = m;
       }
     } else {
       // interface call
       KlassHandle h_holder(THREAD, holder);
 
-      if (call_type == JNI_VIRTUAL) {
-        int itbl_index = m->itable_index();
-        Klass* k = h_recv->klass();
-        selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
-      } else {
-        selected_method = m;
-      }
+      int itbl_index = m->itable_index();
+      Klass* k = h_recv->klass();
+      selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
     }
   }
 
--- a/src/share/vm/runtime/interfaceSupport.cpp	Mon Jun 15 11:38:38 2015 -0700
+++ b/src/share/vm/runtime/interfaceSupport.cpp	Wed Jun 17 23:23:12 2015 -0700
@@ -185,19 +185,22 @@
 
 # endif
 
-
+// invocation counter for InterfaceSupport::deoptimizeAll/zombieAll functions
 int deoptimizeAllCounter = 0;
 int zombieAllCounter = 0;
 
-
 void InterfaceSupport::zombieAll() {
-  if (is_init_completed() && zombieAllCounter > ZombieALotInterval) {
+  // This method is called by all threads when a thread make
+  // transition to VM state (for example, runtime calls).
+  // Divide number of calls by number of threads to avoid
+  // dependence of ZombieAll events frequency on number of threads.
+  int value = zombieAllCounter / Threads::number_of_threads();
+  if (is_init_completed() && value > ZombieALotInterval) {
     zombieAllCounter = 0;
     VM_ZombieAll op;
     VMThread::execute(&op);
-  } else {
-    zombieAllCounter++;
   }
+  zombieAllCounter++;
 }
 
 void InterfaceSupport::unlinkSymbols() {
@@ -206,12 +209,17 @@
 }
 
 void InterfaceSupport::deoptimizeAll() {
-  if (is_init_completed() ) {
-    if (DeoptimizeALot && deoptimizeAllCounter > DeoptimizeALotInterval) {
+  // This method is called by all threads when a thread make
+  // transition to VM state (for example, runtime calls).
+  // Divide number of calls by number of threads to avoid
+  // dependence of DeoptimizeAll events frequency on number of threads.
+  int value = deoptimizeAllCounter / Threads::number_of_threads();
+  if (is_init_completed()) {
+    if (DeoptimizeALot && value > DeoptimizeALotInterval) {
       deoptimizeAllCounter = 0;
       VM_DeoptimizeAll op;
       VMThread::execute(&op);
-    } else if (DeoptimizeRandom && (deoptimizeAllCounter & 0x1f) == (os::random() & 0x1f)) {
+    } else if (DeoptimizeRandom && (value & 0x1F) == (os::random() & 0x1F)) {
       VM_DeoptimizeAll op;
       VMThread::execute(&op);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/invokedynamic/BootstrapMethodErrorTest.java	Wed Jun 17 23:23:12 2015 -0700
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8051045
+ * @summary Test that exceptions from invokedynamic are wrapped in BootstrapMethodError
+ * @modules java.base/jdk.internal.org.objectweb.asm
+ * @run main BootstrapMethodErrorTest
+ */
+
+import java.lang.reflect.Method;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Handle;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+public class BootstrapMethodErrorTest extends ClassLoader implements Opcodes {
+
+  @Override
+  public Class findClass(String name) throws ClassNotFoundException {
+    byte[] b;
+    try {
+      b = loadClassData(name);
+    } catch (Throwable th) {
+      throw new ClassNotFoundException("Loading error", th);
+    }
+    return defineClass(name, b, 0, b.length);
+  }
+
+  private byte[] loadClassData(String name) throws Exception {
+    ClassWriter cw = new ClassWriter(0);
+    MethodVisitor mv;
+
+    if (name.equals("C")) {
+      cw.visit(52, ACC_SUPER | ACC_PUBLIC, "C", null, "java/lang/Object", null);
+      {
+        mv = cw.visitMethod(ACC_PRIVATE | ACC_STATIC, "m", "()V", null, null);
+        mv.visitCode();
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 1);
+        mv.visitEnd();
+      }
+      cw.visitEnd();
+      return cw.toByteArray();
+    } else if (name.equals("Exec")) {
+      cw.visit(52, ACC_SUPER | ACC_PUBLIC, "Exec", null, "java/lang/Object", null);
+      {
+        mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "invokeRef", "()V", null, null);
+        mv.visitCode();
+        Handle h = new Handle(H_INVOKESTATIC, "C", "m", "()V");
+        mv.visitInvokeDynamicInsn("C", "()V", h);
+        mv.visitInsn(RETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+      }
+      cw.visitEnd();
+      return cw.toByteArray();
+    }
+    return null;
+  }
+
+  public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException {
+    new BootstrapMethodErrorTest().test();
+  }
+
+  public void test() throws ClassNotFoundException, IllegalAccessException, NoSuchMethodException {
+    Class.forName("C", true, this);
+    Class<?> exec = Class.forName("Exec", true, this);
+
+    try {
+      exec.getMethod("invokeRef").invoke(null);
+    } catch (Throwable e) {
+      Throwable c = e.getCause();
+      if (c == null) {
+        throw new RuntimeException(
+            "Expected BootstrapMethodError wrapped in an InvocationTargetException but it wasn't wrapped", e);
+      } else if (c instanceof BootstrapMethodError) {
+        // Only way to pass test, all else should throw
+        return;
+      } else {
+        throw new RuntimeException(
+            "Expected BootstrapMethodError but got another Error: "
+            + c.getClass().getName(),
+            c);
+      }
+    }
+    throw new RuntimeException("Expected BootstrapMethodError but no Error at all was thrown");
+  }
+}
--- a/test/test_env.sh	Mon Jun 15 11:38:38 2015 -0700
+++ b/test/test_env.sh	Wed Jun 17 23:23:12 2015 -0700
@@ -191,6 +191,11 @@
 then
   VM_CPU="ia64"
 fi
+grep "aarch64" vm_version.out > ${NULL}
+if [ $? = 0 ]
+then
+  VM_CPU="aarch64"
+fi
 export VM_TYPE VM_BITS VM_OS VM_CPU
 echo "VM_TYPE=${VM_TYPE}"
 echo "VM_BITS=${VM_BITS}"