changeset 7518:ad04e0ef0f85 hs25.66-b01

Merge
author amurillo
date Thu, 09 Jul 2015 11:10:15 -0700
parents 53643c94fd79 (current diff) a7c52c776c30 (diff)
children 025f9a5e6d9c
files
diffstat 9 files changed, 197 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/make/hotspot_version	Wed Jul 08 14:05:50 2015 +0100
+++ b/make/hotspot_version	Thu Jul 09 11:10:15 2015 -0700
@@ -34,8 +34,8 @@
 HOTSPOT_VM_COPYRIGHT=Copyright 2015
 
 HS_MAJOR_VER=25
-HS_MINOR_VER=60
-HS_BUILD_NUMBER=22
+HS_MINOR_VER=66
+HS_BUILD_NUMBER=01
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/src/os/bsd/vm/jsig.c	Wed Jul 08 14:05:50 2015 +0100
+++ b/src/os/bsd/vm/jsig.c	Thu Jul 09 11:10:15 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -36,6 +36,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <string.h>
 
 #define MAXSIGNUM 32
 #define MASK(sig) ((unsigned int)1 << sig)
@@ -43,6 +44,9 @@
 static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
 static unsigned int jvmsigs = 0; /* signals used by jvm */
 
+static pthread_key_t reentry_flag_key;
+static pthread_once_t reentry_key_init_once = PTHREAD_ONCE_INIT;
+
 /* used to synchronize the installation of signal handlers */
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
@@ -59,6 +63,15 @@
 static bool jvm_signal_installing = false;
 static bool jvm_signal_installed = false;
 
+#define check_status(cmd) \
+  do { \
+    int status = (cmd); \
+    if (status != 0) { \
+      printf("error %s (%d) in " #cmd "\n", strerror(status), status); \
+      exit(1); \
+    } \
+  } while (0)
+
 static void signal_lock() {
   pthread_mutex_lock(&mutex);
   /* When the jvm is installing its set of signal handlers, threads
@@ -74,8 +87,15 @@
   pthread_mutex_unlock(&mutex);
 }
 
+static void reentry_tls_init() {
+    // value for reentry_flag_key will default to NULL (false)
+    check_status(pthread_key_create(&reentry_flag_key, NULL));
+}
+
 static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
                                    bool is_sigset) {
+  sa_handler_t res;
+
   if (os_signal == NULL) {
     if (!is_sigset) {
       os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
@@ -87,7 +107,12 @@
       exit(0);
     }
   }
-  return (*os_signal)(sig, disp);
+  check_status(pthread_once(&reentry_key_init_once, reentry_tls_init));
+  // set reentry_flag_key to non-NULL to show reentry
+  check_status(pthread_setspecific(reentry_flag_key, &res));
+  res = (*os_signal)(sig, disp);
+  check_status(pthread_setspecific(reentry_flag_key, NULL));
+  return res;
 }
 
 static void save_signal_handler(int sig, sa_handler_t disp) {
@@ -161,6 +186,11 @@
   bool sigused;
   struct sigaction oldAct;
 
+  check_status(pthread_once(&reentry_key_init_once, reentry_tls_init));
+  if (pthread_getspecific(reentry_flag_key) != NULL) {
+    return call_os_sigaction(sig, act, oact);
+  }
+
   signal_lock();
 
   sigused = (MASK(sig) & jvmsigs) != 0;
--- a/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Wed Jul 08 14:05:50 2015 +0100
+++ b/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp	Thu Jul 09 11:10:15 2015 -0700
@@ -189,7 +189,7 @@
     return CPUVisitor::visit(nodeh, state);
   }
 
-  PICL(bool is_fujitsu) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
+  PICL(bool is_fujitsu, bool is_sun4v) : _L1_data_cache_line_size(0), _L2_data_cache_line_size(0), _dl_handle(NULL) {
     if (!open_library()) {
       return;
     }
@@ -201,7 +201,7 @@
         if (is_fujitsu) {
           cpu_class = "core";
         }
-        CPUVisitor cpu_visitor(this, os::processor_count());
+        CPUVisitor cpu_visitor(this, (is_sun4v && !is_fujitsu) ? 1 : os::processor_count());
         _picl_walk_tree_by_class(rooth, cpu_class, &cpu_visitor, PICL_visit_cpu_helper);
         if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value?
           _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
@@ -494,7 +494,7 @@
   }
 
   // Figure out cache line sizes using PICL
-  PICL picl((features & sparc64_family_m) != 0);
+  PICL picl((features & sparc64_family_m) != 0, (features & sun4v_m) != 0);
   _L2_data_cache_line_size = picl.L2_data_cache_line_size();
 
   return features;
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Jul 08 14:05:50 2015 +0100
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Thu Jul 09 11:10:15 2015 -0700
@@ -3339,9 +3339,11 @@
   // Not unloading classes this cycle
   assert(!should_unload_classes(), "Inconsitency!");
 
+  // If we are not unloading classes then add SO_AllCodeCache to root
+  // scanning options.
+  add_root_scanning_option(rso);
+
   if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
-    // Include symbols, strings and code cache elements to prevent their resurrection.
-    add_root_scanning_option(rso);
     set_verifying(true);
   } else if (verifying() && !should_verify) {
     // We were verifying, but some verification flags got disabled.
--- a/src/share/vm/oops/instanceKlass.cpp	Wed Jul 08 14:05:50 2015 +0100
+++ b/src/share/vm/oops/instanceKlass.cpp	Thu Jul 09 11:10:15 2015 -0700
@@ -439,6 +439,9 @@
     if (!constants()->is_shared()) {
       MetadataFactory::free_metadata(loader_data, constants());
     }
+    // Delete any cached resolution errors for the constant pool
+    SystemDictionary::delete_resolution_error(constants());
+
     set_constants(NULL);
   }
 
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed Jul 08 14:05:50 2015 +0100
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Jul 09 11:10:15 2015 -0700
@@ -4071,9 +4071,6 @@
     mnt->adjust_method_entries(the_class(), &trace_name_printed);
   }
 
-  // Fix Resolution Error table also to remove old constant pools
-  SystemDictionary::delete_resolution_error(old_constants);
-
   if (the_class->oop_map_cache() != NULL) {
     // Flush references to any obsolete methods from the oop map cache
     // so that obsolete methods are not pinned.
--- a/src/share/vm/runtime/thread.cpp	Wed Jul 08 14:05:50 2015 +0100
+++ b/src/share/vm/runtime/thread.cpp	Thu Jul 09 11:10:15 2015 -0700
@@ -3307,6 +3307,9 @@
 
   extern void JDK_Version_init();
 
+  // Preinitialize version info.
+  VM_Version::early_initialize();
+
   // Check version
   if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
 
--- a/src/share/vm/runtime/vm_version.hpp	Wed Jul 08 14:05:50 2015 +0100
+++ b/src/share/vm/runtime/vm_version.hpp	Thu Jul 09 11:10:15 2015 -0700
@@ -56,6 +56,13 @@
  public:
   static void initialize();
 
+  // This allows for early initialization of VM_Version information
+  // that may be needed later in the initialization sequence but before
+  // full VM_Version initialization is possible. It can not depend on any
+  // other part of the VM being initialized when called. Platforms that
+  // need to specialize this define VM_Version::early_initialize().
+  static void early_initialize() { }
+
   // Name
   static const char* vm_name();
   // Vendor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/RedefineTests/RedefineRunningMethodsWithResolutionErrors.java	Thu Jul 09 11:10:15 2015 -0700
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2014, 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 8076110
+ * @summary Redefine running methods that have cached resolution errors
+ * @library /testlibrary
+ * @modules java.instrument
+ *          java.base/jdk.internal.org.objectweb.asm
+ * @build RedefineClassHelper
+ * @run main RedefineClassHelper
+ * @run main/othervm -javaagent:redefineagent.jar -XX:TraceRedefineClasses=0x600 RedefineRunningMethodsWithResolutionErrors
+ */
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+
+import java.lang.reflect.InvocationTargetException;
+
+public class RedefineRunningMethodsWithResolutionErrors extends ClassLoader implements Opcodes {
+
+    @Override
+    protected Class<?> findClass(String name) throws ClassNotFoundException {
+        if (name.equals("C")) {
+            byte[] b = loadC(false);
+            return defineClass(name, b, 0, b.length);
+        } else {
+            return super.findClass(name);
+        }
+    }
+
+    private static byte[] loadC(boolean redefine) {
+        ClassWriter cw = new ClassWriter(0);
+
+        cw.visit(52, ACC_SUPER | ACC_PUBLIC, "C", null, "java/lang/Object", null);
+        {
+            MethodVisitor mv;
+
+            mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "m", "()V", null, null);
+            mv.visitCode();
+
+            // First time we run we will:
+            // 1) Cache resolution errors
+            // 2) Redefine the class / method
+            // 3) Try to read the resolution errors that were cached
+            //
+            // The redefined method will never run, throw error to be sure
+            if (redefine) {
+                createThrowRuntimeExceptionCode(mv, "The redefined method was called");
+            } else {
+                createMethodBody(mv);
+            }
+            mv.visitMaxs(3, 0);
+            mv.visitEnd();
+        }
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+
+    private static void createMethodBody(MethodVisitor mv) {
+        Label classExists = new Label();
+
+        // Cache resolution errors
+        createLoadNonExistentClassCode(mv, classExists);
+
+        // Redefine our own class and method
+        mv.visitMethodInsn(INVOKESTATIC, "RedefineRunningMethodsWithResolutionErrors", "redefine", "()V");
+
+        // Provoke the same error again to make sure the resolution error cache works
+        createLoadNonExistentClassCode(mv, classExists);
+
+        // Test passed
+        mv.visitInsn(RETURN);
+
+        mv.visitFrame(F_SAME, 0, new Object[0], 0, new Object[0]);
+        mv.visitLabel(classExists);
+
+        createThrowRuntimeExceptionCode(mv, "Loaded class that shouldn't exist (\"NonExistentClass\")");
+    }
+
+    private static void createLoadNonExistentClassCode(MethodVisitor mv, Label classExists) {
+        Label tryLoadBegin = new Label();
+        Label tryLoadEnd = new Label();
+        Label catchLoadBlock = new Label();
+        mv.visitTryCatchBlock(tryLoadBegin, tryLoadEnd, catchLoadBlock, "java/lang/NoClassDefFoundError");
+
+        // Try to load a class that does not exist to provoke resolution errors
+        mv.visitLabel(tryLoadBegin);
+        mv.visitMethodInsn(INVOKESTATIC, "NonExistentClass", "nonExistentMethod", "()V");
+        mv.visitLabel(tryLoadEnd);
+
+        // No NoClassDefFoundError means NonExistentClass existed, which shouldn't happen
+        mv.visitJumpInsn(GOTO, classExists);
+
+        mv.visitFrame(F_SAME1, 0, new Object[0], 1, new Object[] { "java/lang/NoClassDefFoundError" });
+        mv.visitLabel(catchLoadBlock);
+
+        // Ignore the expected NoClassDefFoundError
+        mv.visitInsn(POP);
+    }
+
+    private static void createThrowRuntimeExceptionCode(MethodVisitor mv, String msg) {
+        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
+        mv.visitInsn(DUP);
+        mv.visitLdcInsn(msg);
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
+        mv.visitInsn(ATHROW);
+    }
+
+    private static Class<?> c;
+
+    public static void redefine() throws Exception {
+        RedefineClassHelper.redefineClass(c, loadC(true));
+    }
+
+    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        c = Class.forName("C", true, new RedefineRunningMethodsWithResolutionErrors());
+        c.getMethod("m").invoke(null);
+    }
+}