提交 4bd6ef6f 编写于 作者: M mgronlun

Merge

...@@ -24,8 +24,9 @@ ...@@ -24,8 +24,9 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.Arguments;
import sun.jvm.hotspot.runtime.VM;
public class JInfo extends Tool { public class JInfo extends Tool {
public JInfo() { public JInfo() {
...@@ -138,14 +139,33 @@ public class JInfo extends Tool { ...@@ -138,14 +139,33 @@ public class JInfo extends Tool {
} }
private void printVMFlags() { private void printVMFlags() {
VM.Flag[] flags = VM.getVM().getCommandLineFlags();
System.out.print("Non-default VM flags: ");
for (VM.Flag flag : flags) {
if (flag.getOrigin() == 0) {
// only print flags which aren't their defaults
continue;
}
if (flag.isBool()) {
String onoff = flag.getBool() ? "+" : "-";
System.out.print("-XX:" + onoff + flag.getName() + " ");
} else {
System.out.print("-XX:" + flag.getName() + "="
+ flag.getValue() + " ");
}
}
System.out.println();
System.out.print("Command line: ");
String str = Arguments.getJVMFlags(); String str = Arguments.getJVMFlags();
if (str != null) { if (str != null) {
System.out.println(str); System.out.print(str + " ");
} }
str = Arguments.getJVMArgs(); str = Arguments.getJVMArgs();
if (str != null) { if (str != null) {
System.out.println(str); System.out.print(str);
} }
System.out.println();
} }
private int mode; private int mode;
......
...@@ -25,11 +25,11 @@ ...@@ -25,11 +25,11 @@
package sun.jvm.hotspot.tools; package sun.jvm.hotspot.tools;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Hashtable;
import sun.jvm.hotspot.*; import sun.jvm.hotspot.HotSpotAgent;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.debugger.DebuggerException;
import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.JVMDebugger;
import sun.jvm.hotspot.runtime.VM;
// generic command line or GUI tool. // generic command line or GUI tool.
// override run & code main as shown below. // override run & code main as shown below.
...@@ -147,6 +147,7 @@ public abstract class Tool implements Runnable { ...@@ -147,6 +147,7 @@ public abstract class Tool implements Runnable {
} }
PrintStream err = System.err; PrintStream err = System.err;
PrintStream out = System.out;
int pid = 0; int pid = 0;
String coreFileName = null; String coreFileName = null;
...@@ -180,18 +181,18 @@ public abstract class Tool implements Runnable { ...@@ -180,18 +181,18 @@ public abstract class Tool implements Runnable {
try { try {
switch (debugeeType) { switch (debugeeType) {
case DEBUGEE_PID: case DEBUGEE_PID:
err.println("Attaching to process ID " + pid + ", please wait..."); out.println("Attaching to process ID " + pid + ", please wait...");
agent.attach(pid); agent.attach(pid);
break; break;
case DEBUGEE_CORE: case DEBUGEE_CORE:
err.println("Attaching to core " + coreFileName + out.println("Attaching to core " + coreFileName +
" from executable " + executableName + ", please wait..."); " from executable " + executableName + ", please wait...");
agent.attach(executableName, coreFileName); agent.attach(executableName, coreFileName);
break; break;
case DEBUGEE_REMOTE: case DEBUGEE_REMOTE:
err.println("Attaching to remote server " + remoteServer + ", please wait..."); out.println("Attaching to remote server " + remoteServer + ", please wait...");
agent.attach(remoteServer); agent.attach(remoteServer);
break; break;
} }
...@@ -218,7 +219,7 @@ public abstract class Tool implements Runnable { ...@@ -218,7 +219,7 @@ public abstract class Tool implements Runnable {
return 1; return 1;
} }
err.println("Debugger attached successfully."); out.println("Debugger attached successfully.");
startInternal(); startInternal();
return 0; return 0;
} }
...@@ -237,14 +238,14 @@ public abstract class Tool implements Runnable { ...@@ -237,14 +238,14 @@ public abstract class Tool implements Runnable {
// Remains of the start mechanism, common to both start methods. // Remains of the start mechanism, common to both start methods.
private void startInternal() { private void startInternal() {
PrintStream err = System.err; PrintStream out = System.out;
VM vm = VM.getVM(); VM vm = VM.getVM();
if (vm.isCore()) { if (vm.isCore()) {
err.println("Core build detected."); out.println("Core build detected.");
} else if (vm.isClientCompiler()) { } else if (vm.isClientCompiler()) {
err.println("Client compiler detected."); out.println("Client compiler detected.");
} else if (vm.isServerCompiler()) { } else if (vm.isServerCompiler()) {
err.println("Server compiler detected."); out.println("Server compiler detected.");
} else { } else {
throw new RuntimeException("Fatal error: " throw new RuntimeException("Fatal error: "
+ "should have been able to detect core/C1/C2 build"); + "should have been able to detect core/C1/C2 build");
...@@ -252,8 +253,8 @@ public abstract class Tool implements Runnable { ...@@ -252,8 +253,8 @@ public abstract class Tool implements Runnable {
String version = vm.getVMRelease(); String version = vm.getVMRelease();
if (version != null) { if (version != null) {
err.print("JVM version is "); out.print("JVM version is ");
err.println(version); out.println(version);
} }
run(); run();
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "prims/jvmtiImpl.hpp" #include "prims/jvmtiImpl.hpp"
#include "runtime/synchronizer.hpp" #include "runtime/synchronizer.hpp"
#include "runtime/thread.hpp" #include "runtime/thread.hpp"
#include "services/threadService.hpp"
#include "utilities/growableArray.hpp" #include "utilities/growableArray.hpp"
...@@ -50,6 +51,7 @@ MetadataOnStackMark::MetadataOnStackMark() { ...@@ -50,6 +51,7 @@ MetadataOnStackMark::MetadataOnStackMark() {
CodeCache::alive_nmethods_do(nmethod::mark_on_stack); CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
CompileBroker::mark_on_stack(); CompileBroker::mark_on_stack();
JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack); JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
ThreadService::metadata_do(Metadata::mark_on_stack);
} }
MetadataOnStackMark::~MetadataOnStackMark() { MetadataOnStackMark::~MetadataOnStackMark() {
......
...@@ -141,7 +141,6 @@ class SymbolPropertyTable; ...@@ -141,7 +141,6 @@ class SymbolPropertyTable;
/* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \ /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \
/* Universe::is_gte_jdk14x_version() is not set up by this point. */ \ /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \
/* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \ /* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \
do_klass(lambda_MagicLambdaImpl_klass, java_lang_invoke_MagicLambdaImpl, Opt ) \
do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \ do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \
do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \ do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \
do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \ do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
......
...@@ -188,10 +188,8 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul ...@@ -188,10 +188,8 @@ bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool shoul
bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) {
Symbol* name = klass->name(); Symbol* name = klass->name();
Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass(); Klass* refl_magic_klass = SystemDictionary::reflect_MagicAccessorImpl_klass();
Klass* lambda_magic_klass = SystemDictionary::lambda_MagicLambdaImpl_klass();
bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass); bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass);
bool is_lambda = lambda_magic_klass != NULL && klass->is_subtype_of(lambda_magic_klass);
return (should_verify_for(klass->class_loader(), should_verify_class) && return (should_verify_for(klass->class_loader(), should_verify_class) &&
// return if the class is a bootstrapping class // return if the class is a bootstrapping class
...@@ -215,9 +213,7 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool shou ...@@ -215,9 +213,7 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool shou
// NOTE: this is called too early in the bootstrapping process to be // NOTE: this is called too early in the bootstrapping process to be
// guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection.
// Also for lambda generated code, gte jdk8 // Also for lambda generated code, gte jdk8
(!is_reflect || VerifyReflectionBytecodes) && (!is_reflect || VerifyReflectionBytecodes));
(!is_lambda || VerifyLambdaBytecodes)
);
} }
Symbol* Verifier::inference_verify( Symbol* Verifier::inference_verify(
......
...@@ -273,7 +273,6 @@ ...@@ -273,7 +273,6 @@
template(java_lang_invoke_Stable_signature, "Ljava/lang/invoke/Stable;") \ template(java_lang_invoke_Stable_signature, "Ljava/lang/invoke/Stable;") \
template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \ template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \ template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \
template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \ /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
template(findMethodHandleType_name, "findMethodHandleType") \ template(findMethodHandleType_name, "findMethodHandleType") \
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \ template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
......
...@@ -70,12 +70,14 @@ void Rewriter::compute_index_maps() { ...@@ -70,12 +70,14 @@ void Rewriter::compute_index_maps() {
} }
// Unrewrite the bytecodes if an error occurs. // Unrewrite the bytecodes if an error occurs.
void Rewriter::restore_bytecodes(TRAPS) { void Rewriter::restore_bytecodes() {
int len = _methods->length(); int len = _methods->length();
bool invokespecial_error = false;
for (int i = len-1; i >= 0; i--) { for (int i = len-1; i >= 0; i--) {
Method* method = _methods->at(i); Method* method = _methods->at(i);
scan_method(method, true, CHECK); scan_method(method, true, &invokespecial_error);
assert(!invokespecial_error, "reversing should not get an invokespecial error");
} }
} }
...@@ -160,22 +162,21 @@ void Rewriter::rewrite_member_reference(address bcp, int offset, bool reverse) { ...@@ -160,22 +162,21 @@ void Rewriter::rewrite_member_reference(address bcp, int offset, bool reverse) {
// These cannot share cpCache entries. It's unclear if all invokespecial to // These cannot share cpCache entries. It's unclear if all invokespecial to
// InterfaceMethodrefs would resolve to the same thing so a new cpCache entry // InterfaceMethodrefs would resolve to the same thing so a new cpCache entry
// is created for each one. This was added with lambda. // is created for each one. This was added with lambda.
void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS) { void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) {
static int count = 0;
address p = bcp + offset; address p = bcp + offset;
if (!reverse) { if (!reverse) {
int cp_index = Bytes::get_Java_u2(p); int cp_index = Bytes::get_Java_u2(p);
if (_pool->tag_at(cp_index).is_interface_method()) {
int cache_index = add_invokespecial_cp_cache_entry(cp_index); int cache_index = add_invokespecial_cp_cache_entry(cp_index);
if (cache_index != (int)(jushort) cache_index) { if (cache_index != (int)(jushort) cache_index) {
THROW_MSG(vmSymbols::java_lang_InternalError(), *invokespecial_error = true;
"This classfile overflows invokespecial for interfaces "
"and cannot be loaded");
} }
Bytes::put_native_u2(p, cache_index); Bytes::put_native_u2(p, cache_index);
} else { } else {
int cache_index = Bytes::get_native_u2(p); rewrite_member_reference(bcp, offset, reverse);
int cp_index = cp_cache_entry_pool_index(cache_index); }
Bytes::put_Java_u2(p, cp_index); } else {
rewrite_member_reference(bcp, offset, reverse);
} }
} }
...@@ -329,7 +330,7 @@ void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide, ...@@ -329,7 +330,7 @@ void Rewriter::maybe_rewrite_ldc(address bcp, int offset, bool is_wide,
// Rewrites a method given the index_map information // Rewrites a method given the index_map information
void Rewriter::scan_method(Method* method, bool reverse, TRAPS) { void Rewriter::scan_method(Method* method, bool reverse, bool* invokespecial_error) {
int nof_jsrs = 0; int nof_jsrs = 0;
bool has_monitor_bytecodes = false; bool has_monitor_bytecodes = false;
...@@ -391,15 +392,7 @@ void Rewriter::scan_method(Method* method, bool reverse, TRAPS) { ...@@ -391,15 +392,7 @@ void Rewriter::scan_method(Method* method, bool reverse, TRAPS) {
} }
case Bytecodes::_invokespecial : { case Bytecodes::_invokespecial : {
int offset = prefix_length + 1; rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error);
address p = bcp + offset;
int cp_index = Bytes::get_Java_u2(p);
// InterfaceMethodref
if (_pool->tag_at(cp_index).is_interface_method()) {
rewrite_invokespecial(bcp, offset, reverse, CHECK);
} else {
rewrite_member_reference(bcp, offset, reverse);
}
break; break;
} }
...@@ -496,11 +489,20 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me ...@@ -496,11 +489,20 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me
// rewrite methods, in two passes // rewrite methods, in two passes
int len = _methods->length(); int len = _methods->length();
bool invokespecial_error = false;
for (int i = len-1; i >= 0; i--) { for (int i = len-1; i >= 0; i--) {
Method* method = _methods->at(i); Method* method = _methods->at(i);
scan_method(method, false, CHECK); // If you get an error here, scan_method(method, false, &invokespecial_error);
// there is no reversing bytecodes if (invokespecial_error) {
// If you get an error here, there is no reversing bytecodes
// This exception is stored for this class and no further attempt is
// made at verifying or rewriting.
THROW_MSG(vmSymbols::java_lang_InternalError(),
"This classfile overflows invokespecial for interfaces "
"and cannot be loaded");
return;
}
} }
// May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref // May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref
...@@ -513,7 +515,7 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me ...@@ -513,7 +515,7 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me
// Restore bytecodes to their unrewritten state if there are exceptions // Restore bytecodes to their unrewritten state if there are exceptions
// rewriting bytecodes or allocating the cpCache // rewriting bytecodes or allocating the cpCache
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
restore_bytecodes(CATCH); restore_bytecodes();
return; return;
} }
...@@ -530,7 +532,7 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me ...@@ -530,7 +532,7 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Me
// relocating bytecodes. If some are relocated, that is ok because that // relocating bytecodes. If some are relocated, that is ok because that
// doesn't affect constant pool to cpCache rewriting. // doesn't affect constant pool to cpCache rewriting.
if (HAS_PENDING_EXCEPTION) { if (HAS_PENDING_EXCEPTION) {
restore_bytecodes(CATCH); restore_bytecodes();
return; return;
} }
// Method might have gotten rewritten. // Method might have gotten rewritten.
......
...@@ -189,18 +189,18 @@ class Rewriter: public StackObj { ...@@ -189,18 +189,18 @@ class Rewriter: public StackObj {
void compute_index_maps(); void compute_index_maps();
void make_constant_pool_cache(TRAPS); void make_constant_pool_cache(TRAPS);
void scan_method(Method* m, bool reverse, TRAPS); void scan_method(Method* m, bool reverse, bool* invokespecial_error);
void rewrite_Object_init(methodHandle m, TRAPS); void rewrite_Object_init(methodHandle m, TRAPS);
void rewrite_member_reference(address bcp, int offset, bool reverse); void rewrite_member_reference(address bcp, int offset, bool reverse);
void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse); void maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse);
void rewrite_invokedynamic(address bcp, int offset, bool reverse); void rewrite_invokedynamic(address bcp, int offset, bool reverse);
void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse); void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse);
void rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS); void rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error);
void patch_invokedynamic_bytecodes(); void patch_invokedynamic_bytecodes();
// Revert bytecodes in case of an exception. // Revert bytecodes in case of an exception.
void restore_bytecodes(TRAPS); void restore_bytecodes();
static methodHandle rewrite_jsrs(methodHandle m, TRAPS); static methodHandle rewrite_jsrs(methodHandle m, TRAPS);
public: public:
......
...@@ -321,6 +321,8 @@ void Flag::print_kind(outputStream* st) { ...@@ -321,6 +321,8 @@ void Flag::print_kind(outputStream* st) {
{ KIND_PRODUCT, "product" }, { KIND_PRODUCT, "product" },
{ KIND_MANAGEABLE, "manageable" }, { KIND_MANAGEABLE, "manageable" },
{ KIND_DIAGNOSTIC, "diagnostic" }, { KIND_DIAGNOSTIC, "diagnostic" },
{ KIND_EXPERIMENTAL, "experimental" },
{ KIND_COMMERCIAL, "commercial" },
{ KIND_NOT_PRODUCT, "notproduct" }, { KIND_NOT_PRODUCT, "notproduct" },
{ KIND_DEVELOP, "develop" }, { KIND_DEVELOP, "develop" },
{ KIND_LP64_PRODUCT, "lp64_product" }, { KIND_LP64_PRODUCT, "lp64_product" },
......
...@@ -3622,9 +3622,6 @@ class CommandLineFlags { ...@@ -3622,9 +3622,6 @@ class CommandLineFlags {
"Temporary flag for transition to AbstractMethodError wrapped " \ "Temporary flag for transition to AbstractMethodError wrapped " \
"in InvocationTargetException. See 6531596") \ "in InvocationTargetException. See 6531596") \
\ \
develop(bool, VerifyLambdaBytecodes, false, \
"Force verification of jdk 8 lambda metafactory bytecodes") \
\
develop(intx, FastSuperclassLimit, 8, \ develop(intx, FastSuperclassLimit, 8, \
"Depth of hardwired instanceof accelerator array") \ "Depth of hardwired instanceof accelerator array") \
\ \
......
...@@ -470,12 +470,6 @@ bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, boo ...@@ -470,12 +470,6 @@ bool Reflection::verify_class_access(Klass* current_class, Klass* new_class, boo
return true; return true;
} }
// Also allow all accesses from
// java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) {
return true;
}
return can_relax_access_check_for(current_class, new_class, classloader_only); return can_relax_access_check_for(current_class, new_class, classloader_only);
} }
...@@ -570,12 +564,6 @@ bool Reflection::verify_field_access(Klass* current_class, ...@@ -570,12 +564,6 @@ bool Reflection::verify_field_access(Klass* current_class,
return true; return true;
} }
// Also allow all accesses from
// java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially.
if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) {
return true;
}
return can_relax_access_check_for( return can_relax_access_check_for(
current_class, field_class, classloader_only); current_class, field_class, classloader_only);
} }
......
...@@ -200,6 +200,12 @@ void ThreadService::oops_do(OopClosure* f) { ...@@ -200,6 +200,12 @@ void ThreadService::oops_do(OopClosure* f) {
} }
} }
void ThreadService::metadata_do(void f(Metadata*)) {
for (ThreadDumpResult* dump = _threaddump_list; dump != NULL; dump = dump->next()) {
dump->metadata_do(f);
}
}
void ThreadService::add_thread_dump(ThreadDumpResult* dump) { void ThreadService::add_thread_dump(ThreadDumpResult* dump) {
MutexLocker ml(Management_lock); MutexLocker ml(Management_lock);
if (_threaddump_list == NULL) { if (_threaddump_list == NULL) {
...@@ -451,9 +457,16 @@ void ThreadDumpResult::oops_do(OopClosure* f) { ...@@ -451,9 +457,16 @@ void ThreadDumpResult::oops_do(OopClosure* f) {
} }
} }
void ThreadDumpResult::metadata_do(void f(Metadata*)) {
for (ThreadSnapshot* ts = _snapshots; ts != NULL; ts = ts->next()) {
ts->metadata_do(f);
}
}
StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) { StackFrameInfo::StackFrameInfo(javaVFrame* jvf, bool with_lock_info) {
_method = jvf->method(); _method = jvf->method();
_bci = jvf->bci(); _bci = jvf->bci();
_class_holder = _method->method_holder()->klass_holder();
_locked_monitors = NULL; _locked_monitors = NULL;
if (with_lock_info) { if (with_lock_info) {
ResourceMark rm; ResourceMark rm;
...@@ -477,6 +490,11 @@ void StackFrameInfo::oops_do(OopClosure* f) { ...@@ -477,6 +490,11 @@ void StackFrameInfo::oops_do(OopClosure* f) {
f->do_oop((oop*) _locked_monitors->adr_at(i)); f->do_oop((oop*) _locked_monitors->adr_at(i));
} }
} }
f->do_oop(&_class_holder);
}
void StackFrameInfo::metadata_do(void f(Metadata*)) {
f(_method);
} }
void StackFrameInfo::print_on(outputStream* st) const { void StackFrameInfo::print_on(outputStream* st) const {
...@@ -620,6 +638,14 @@ void ThreadStackTrace::oops_do(OopClosure* f) { ...@@ -620,6 +638,14 @@ void ThreadStackTrace::oops_do(OopClosure* f) {
} }
} }
void ThreadStackTrace::metadata_do(void f(Metadata*)) {
int length = _frames->length();
for (int i = 0; i < length; i++) {
_frames->at(i)->metadata_do(f);
}
}
ConcurrentLocksDump::~ConcurrentLocksDump() { ConcurrentLocksDump::~ConcurrentLocksDump() {
if (_retain_map_on_free) { if (_retain_map_on_free) {
return; return;
...@@ -823,6 +849,13 @@ void ThreadSnapshot::oops_do(OopClosure* f) { ...@@ -823,6 +849,13 @@ void ThreadSnapshot::oops_do(OopClosure* f) {
} }
} }
void ThreadSnapshot::metadata_do(void f(Metadata*)) {
if (_stack_trace != NULL) {
_stack_trace->metadata_do(f);
}
}
DeadlockCycle::DeadlockCycle() { DeadlockCycle::DeadlockCycle() {
_is_deadlock = false; _is_deadlock = false;
_threads = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JavaThread*>(INITIAL_ARRAY_SIZE, true); _threads = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JavaThread*>(INITIAL_ARRAY_SIZE, true);
......
...@@ -113,6 +113,7 @@ public: ...@@ -113,6 +113,7 @@ public:
// GC support // GC support
static void oops_do(OopClosure* f); static void oops_do(OopClosure* f);
static void metadata_do(void f(Metadata*));
}; };
// Per-thread Statistics for synchronization // Per-thread Statistics for synchronization
...@@ -242,6 +243,7 @@ public: ...@@ -242,6 +243,7 @@ public:
void dump_stack_at_safepoint(int max_depth, bool with_locked_monitors); void dump_stack_at_safepoint(int max_depth, bool with_locked_monitors);
void set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; } void set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; }
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
void metadata_do(void f(Metadata*));
}; };
class ThreadStackTrace : public CHeapObj<mtInternal> { class ThreadStackTrace : public CHeapObj<mtInternal> {
...@@ -265,6 +267,7 @@ class ThreadStackTrace : public CHeapObj<mtInternal> { ...@@ -265,6 +267,7 @@ class ThreadStackTrace : public CHeapObj<mtInternal> {
void dump_stack_at_safepoint(int max_depth); void dump_stack_at_safepoint(int max_depth);
Handle allocate_fill_stack_trace_element_array(TRAPS); Handle allocate_fill_stack_trace_element_array(TRAPS);
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
void metadata_do(void f(Metadata*));
GrowableArray<oop>* jni_locked_monitors() { return _jni_locked_monitors; } GrowableArray<oop>* jni_locked_monitors() { return _jni_locked_monitors; }
int num_jni_locked_monitors() { return (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0); } int num_jni_locked_monitors() { return (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0); }
...@@ -280,6 +283,9 @@ class StackFrameInfo : public CHeapObj<mtInternal> { ...@@ -280,6 +283,9 @@ class StackFrameInfo : public CHeapObj<mtInternal> {
Method* _method; Method* _method;
int _bci; int _bci;
GrowableArray<oop>* _locked_monitors; // list of object monitors locked by this frame GrowableArray<oop>* _locked_monitors; // list of object monitors locked by this frame
// We need to save the mirrors in the backtrace to keep the class
// from being unloaded while we still have this stack trace.
oop _class_holder;
public: public:
...@@ -289,9 +295,10 @@ class StackFrameInfo : public CHeapObj<mtInternal> { ...@@ -289,9 +295,10 @@ class StackFrameInfo : public CHeapObj<mtInternal> {
delete _locked_monitors; delete _locked_monitors;
} }
}; };
Method* method() const { return _method; } Method* method() const { return _method; }
int bci() const { return _bci; } int bci() const { return _bci; }
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
void metadata_do(void f(Metadata*));
int num_locked_monitors() { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); } int num_locked_monitors() { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); }
GrowableArray<oop>* locked_monitors() { return _locked_monitors; } GrowableArray<oop>* locked_monitors() { return _locked_monitors; }
...@@ -354,6 +361,7 @@ class ThreadDumpResult : public StackObj { ...@@ -354,6 +361,7 @@ class ThreadDumpResult : public StackObj {
int num_snapshots() { return _num_snapshots; } int num_snapshots() { return _num_snapshots; }
ThreadSnapshot* snapshots() { return _snapshots; } ThreadSnapshot* snapshots() { return _snapshots; }
void oops_do(OopClosure* f); void oops_do(OopClosure* f);
void metadata_do(void f(Metadata*));
}; };
class DeadlockCycle : public CHeapObj<mtInternal> { class DeadlockCycle : public CHeapObj<mtInternal> {
......
...@@ -172,7 +172,6 @@ public class ConcurrentClassLoadingTest { ...@@ -172,7 +172,6 @@ public class ConcurrentClassLoadingTest {
"java.lang.invoke.LambdaConversionException", "java.lang.invoke.LambdaConversionException",
"java.lang.invoke.LambdaForm", "java.lang.invoke.LambdaForm",
"java.lang.invoke.LambdaMetafactory", "java.lang.invoke.LambdaMetafactory",
"java.lang.invoke.MagicLambdaImpl",
"java.lang.invoke.MemberName", "java.lang.invoke.MemberName",
"java.lang.invoke.MethodHandle", "java.lang.invoke.MethodHandle",
"java.lang.invoke.MethodHandleImpl", "java.lang.invoke.MethodHandleImpl",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册