提交 dd232dfe 编写于 作者: A amurillo

Merge

...@@ -34,8 +34,8 @@ ...@@ -34,8 +34,8 @@
HOTSPOT_VM_COPYRIGHT=Copyright 2015 HOTSPOT_VM_COPYRIGHT=Copyright 2015
HS_MAJOR_VER=25 HS_MAJOR_VER=25
HS_MINOR_VER=60 HS_MINOR_VER=66
HS_BUILD_NUMBER=22 HS_BUILD_NUMBER=01
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=8 JDK_MINOR_VER=8
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h>
#define MAXSIGNUM 32 #define MAXSIGNUM 32
#define MASK(sig) ((unsigned int)1 << sig) #define MASK(sig) ((unsigned int)1 << sig)
...@@ -43,6 +44,9 @@ ...@@ -43,6 +44,9 @@
static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */ static struct sigaction sact[MAXSIGNUM]; /* saved signal handlers */
static unsigned int jvmsigs = 0; /* signals used by jvm */ 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 */ /* used to synchronize the installation of signal handlers */
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
...@@ -59,6 +63,15 @@ static sigaction_t os_sigaction = 0; /* os's version of sigaction() */ ...@@ -59,6 +63,15 @@ static sigaction_t os_sigaction = 0; /* os's version of sigaction() */
static bool jvm_signal_installing = false; static bool jvm_signal_installing = false;
static bool jvm_signal_installed = 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() { static void signal_lock() {
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
/* When the jvm is installing its set of signal handlers, threads /* When the jvm is installing its set of signal handlers, threads
...@@ -74,8 +87,15 @@ static void signal_unlock() { ...@@ -74,8 +87,15 @@ static void signal_unlock() {
pthread_mutex_unlock(&mutex); 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, static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
bool is_sigset) { bool is_sigset) {
sa_handler_t res;
if (os_signal == NULL) { if (os_signal == NULL) {
if (!is_sigset) { if (!is_sigset) {
os_signal = (signal_t)dlsym(RTLD_NEXT, "signal"); os_signal = (signal_t)dlsym(RTLD_NEXT, "signal");
...@@ -87,7 +107,12 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp, ...@@ -87,7 +107,12 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp,
exit(0); 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) { static void save_signal_handler(int sig, sa_handler_t disp) {
...@@ -161,6 +186,11 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { ...@@ -161,6 +186,11 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) {
bool sigused; bool sigused;
struct sigaction oldAct; 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(); signal_lock();
sigused = (MASK(sig) & jvmsigs) != 0; sigused = (MASK(sig) & jvmsigs) != 0;
......
...@@ -189,7 +189,7 @@ public: ...@@ -189,7 +189,7 @@ public:
return CPUVisitor::visit(nodeh, state); 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()) { if (!open_library()) {
return; return;
} }
...@@ -201,7 +201,7 @@ public: ...@@ -201,7 +201,7 @@ public:
if (is_fujitsu) { if (is_fujitsu) {
cpu_class = "core"; 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); _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? if (cpu_visitor.l1_visitor()->is_assigned()) { // Is there a value?
_L1_data_cache_line_size = cpu_visitor.l1_visitor()->value(); _L1_data_cache_line_size = cpu_visitor.l1_visitor()->value();
...@@ -494,7 +494,7 @@ int VM_Version::platform_features(int features) { ...@@ -494,7 +494,7 @@ int VM_Version::platform_features(int features) {
} }
// Figure out cache line sizes using PICL // 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(); _L2_data_cache_line_size = picl.L2_data_cache_line_size();
return features; return features;
......
...@@ -3339,9 +3339,11 @@ void CMSCollector::setup_cms_unloading_and_verification_state() { ...@@ -3339,9 +3339,11 @@ void CMSCollector::setup_cms_unloading_and_verification_state() {
// Not unloading classes this cycle // Not unloading classes this cycle
assert(!should_unload_classes(), "Inconsitency!"); assert(!should_unload_classes(), "Inconsitency!");
if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) { // If we are not unloading classes then add SO_AllCodeCache to root
// Include symbols, strings and code cache elements to prevent their resurrection. // scanning options.
add_root_scanning_option(rso); add_root_scanning_option(rso);
if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
set_verifying(true); set_verifying(true);
} else if (verifying() && !should_verify) { } else if (verifying() && !should_verify) {
// We were verifying, but some verification flags got disabled. // We were verifying, but some verification flags got disabled.
......
...@@ -439,6 +439,9 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) { ...@@ -439,6 +439,9 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
if (!constants()->is_shared()) { if (!constants()->is_shared()) {
MetadataFactory::free_metadata(loader_data, constants()); MetadataFactory::free_metadata(loader_data, constants());
} }
// Delete any cached resolution errors for the constant pool
SystemDictionary::delete_resolution_error(constants());
set_constants(NULL); set_constants(NULL);
} }
......
...@@ -4071,9 +4071,6 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass, ...@@ -4071,9 +4071,6 @@ void VM_RedefineClasses::redefine_single_class(jclass the_jclass,
mnt->adjust_method_entries(the_class(), &trace_name_printed); 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) { if (the_class->oop_map_cache() != NULL) {
// Flush references to any obsolete methods from the oop map cache // Flush references to any obsolete methods from the oop map cache
// so that obsolete methods are not pinned. // so that obsolete methods are not pinned.
......
...@@ -3307,6 +3307,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { ...@@ -3307,6 +3307,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
extern void JDK_Version_init(); extern void JDK_Version_init();
// Preinitialize version info.
VM_Version::early_initialize();
// Check version // Check version
if (!is_supported_jni_version(args->version)) return JNI_EVERSION; if (!is_supported_jni_version(args->version)) return JNI_EVERSION;
......
...@@ -56,6 +56,13 @@ class Abstract_VM_Version: AllStatic { ...@@ -56,6 +56,13 @@ class Abstract_VM_Version: AllStatic {
public: public:
static void initialize(); 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 // Name
static const char* vm_name(); static const char* vm_name();
// Vendor // Vendor
......
/*
* 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);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册