# HG changeset patch # User mgronlun # Date 1385148396 -3600 # Node ID aa933e6b061d6e8655b7f6031c574fbbd6f6fc09 # Parent fca8f47992291f41b15cb5dd5728780dce5d6bfa# Parent 39656499282381d3a12eeebf5b178ec7732c6bff Merge diff -r fca8f4799229 -r aa933e6b061d agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Wed Nov 20 12:46:08 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Fri Nov 22 20:26:36 2013 +0100 @@ -24,8 +24,9 @@ package sun.jvm.hotspot.tools; -import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.debugger.JVMDebugger; +import sun.jvm.hotspot.runtime.Arguments; +import sun.jvm.hotspot.runtime.VM; public class JInfo extends Tool { public JInfo() { @@ -138,14 +139,33 @@ } 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(); if (str != null) { - System.out.println(str); + System.out.print(str + " "); } str = Arguments.getJVMArgs(); if (str != null) { - System.out.println(str); + System.out.print(str); } + System.out.println(); } private int mode; diff -r fca8f4799229 -r aa933e6b061d agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Wed Nov 20 12:46:08 2013 +0100 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Fri Nov 22 20:26:36 2013 +0100 @@ -25,11 +25,11 @@ package sun.jvm.hotspot.tools; import java.io.PrintStream; -import java.util.Hashtable; -import sun.jvm.hotspot.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.HotSpotAgent; +import sun.jvm.hotspot.debugger.DebuggerException; +import sun.jvm.hotspot.debugger.JVMDebugger; +import sun.jvm.hotspot.runtime.VM; // generic command line or GUI tool. // override run & code main as shown below. @@ -147,6 +147,7 @@ } PrintStream err = System.err; + PrintStream out = System.out; int pid = 0; String coreFileName = null; @@ -180,18 +181,18 @@ try { switch (debugeeType) { case DEBUGEE_PID: - err.println("Attaching to process ID " + pid + ", please wait..."); + out.println("Attaching to process ID " + pid + ", please wait..."); agent.attach(pid); break; case DEBUGEE_CORE: - err.println("Attaching to core " + coreFileName + + out.println("Attaching to core " + coreFileName + " from executable " + executableName + ", please wait..."); agent.attach(executableName, coreFileName); break; case DEBUGEE_REMOTE: - err.println("Attaching to remote server " + remoteServer + ", please wait..."); + out.println("Attaching to remote server " + remoteServer + ", please wait..."); agent.attach(remoteServer); break; } @@ -218,7 +219,7 @@ return 1; } - err.println("Debugger attached successfully."); + out.println("Debugger attached successfully."); startInternal(); return 0; } @@ -237,14 +238,14 @@ // Remains of the start mechanism, common to both start methods. private void startInternal() { - PrintStream err = System.err; + PrintStream out = System.out; VM vm = VM.getVM(); if (vm.isCore()) { - err.println("Core build detected."); + out.println("Core build detected."); } else if (vm.isClientCompiler()) { - err.println("Client compiler detected."); + out.println("Client compiler detected."); } else if (vm.isServerCompiler()) { - err.println("Server compiler detected."); + out.println("Server compiler detected."); } else { throw new RuntimeException("Fatal error: " + "should have been able to detect core/C1/C2 build"); @@ -252,8 +253,8 @@ String version = vm.getVMRelease(); if (version != null) { - err.print("JVM version is "); - err.println(version); + out.print("JVM version is "); + out.println(version); } run(); diff -r fca8f4799229 -r aa933e6b061d src/share/vm/classfile/metadataOnStackMark.cpp --- a/src/share/vm/classfile/metadataOnStackMark.cpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/classfile/metadataOnStackMark.cpp Fri Nov 22 20:26:36 2013 +0100 @@ -30,6 +30,7 @@ #include "prims/jvmtiImpl.hpp" #include "runtime/synchronizer.hpp" #include "runtime/thread.hpp" +#include "services/threadService.hpp" #include "utilities/growableArray.hpp" @@ -50,6 +51,7 @@ CodeCache::alive_nmethods_do(nmethod::mark_on_stack); CompileBroker::mark_on_stack(); JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack); + ThreadService::metadata_do(Metadata::mark_on_stack); } MetadataOnStackMark::~MetadataOnStackMark() { diff -r fca8f4799229 -r aa933e6b061d src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Nov 22 20:26:36 2013 +0100 @@ -141,7 +141,6 @@ /* 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. */ \ /* 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_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \ do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \ diff -r fca8f4799229 -r aa933e6b061d src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/classfile/verifier.cpp Fri Nov 22 20:26:36 2013 +0100 @@ -188,10 +188,8 @@ bool Verifier::is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class) { Symbol* name = klass->name(); 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_lambda = lambda_magic_klass != NULL && klass->is_subtype_of(lambda_magic_klass); return (should_verify_for(klass->class_loader(), should_verify_class) && // return if the class is a bootstrapping class @@ -215,9 +213,7 @@ // NOTE: this is called too early in the bootstrapping process to be // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection. // Also for lambda generated code, gte jdk8 - (!is_reflect || VerifyReflectionBytecodes) && - (!is_lambda || VerifyLambdaBytecodes) - ); + (!is_reflect || VerifyReflectionBytecodes)); } Symbol* Verifier::inference_verify( diff -r fca8f4799229 -r aa933e6b061d src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Nov 22 20:26:36 2013 +0100 @@ -273,7 +273,6 @@ 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_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: */ \ template(findMethodHandleType_name, "findMethodHandleType") \ template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \ diff -r fca8f4799229 -r aa933e6b061d src/share/vm/interpreter/rewriter.cpp --- a/src/share/vm/interpreter/rewriter.cpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/interpreter/rewriter.cpp Fri Nov 22 20:26:36 2013 +0100 @@ -70,12 +70,14 @@ } // Unrewrite the bytecodes if an error occurs. -void Rewriter::restore_bytecodes(TRAPS) { +void Rewriter::restore_bytecodes() { int len = _methods->length(); + bool invokespecial_error = false; for (int i = len-1; i >= 0; 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 @@ // These cannot share cpCache entries. It's unclear if all invokespecial to // InterfaceMethodrefs would resolve to the same thing so a new cpCache entry // is created for each one. This was added with lambda. -void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, TRAPS) { - static int count = 0; +void Rewriter::rewrite_invokespecial(address bcp, int offset, bool reverse, bool* invokespecial_error) { address p = bcp + offset; if (!reverse) { 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); if (cache_index != (int)(jushort) cache_index) { - THROW_MSG(vmSymbols::java_lang_InternalError(), - "This classfile overflows invokespecial for interfaces " - "and cannot be loaded"); + *invokespecial_error = true; } Bytes::put_native_u2(p, cache_index); } else { - int cache_index = Bytes::get_native_u2(p); - int cp_index = cp_cache_entry_pool_index(cache_index); - Bytes::put_Java_u2(p, cp_index); + rewrite_member_reference(bcp, offset, reverse); + } + } else { + rewrite_member_reference(bcp, offset, reverse); } } @@ -329,7 +330,7 @@ // 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; bool has_monitor_bytecodes = false; @@ -391,15 +392,7 @@ } case Bytecodes::_invokespecial : { - int offset = prefix_length + 1; - 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); - } + rewrite_invokespecial(bcp, prefix_length+1, reverse, invokespecial_error); break; } @@ -496,11 +489,20 @@ // rewrite methods, in two passes int len = _methods->length(); + bool invokespecial_error = false; for (int i = len-1; i >= 0; i--) { Method* method = _methods->at(i); - scan_method(method, false, CHECK); // If you get an error here, - // there is no reversing bytecodes + scan_method(method, false, &invokespecial_error); + 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 @@ -513,7 +515,7 @@ // Restore bytecodes to their unrewritten state if there are exceptions // rewriting bytecodes or allocating the cpCache if (HAS_PENDING_EXCEPTION) { - restore_bytecodes(CATCH); + restore_bytecodes(); return; } @@ -530,7 +532,7 @@ // relocating bytecodes. If some are relocated, that is ok because that // doesn't affect constant pool to cpCache rewriting. if (HAS_PENDING_EXCEPTION) { - restore_bytecodes(CATCH); + restore_bytecodes(); return; } // Method might have gotten rewritten. diff -r fca8f4799229 -r aa933e6b061d src/share/vm/interpreter/rewriter.hpp --- a/src/share/vm/interpreter/rewriter.hpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/interpreter/rewriter.hpp Fri Nov 22 20:26:36 2013 +0100 @@ -189,18 +189,18 @@ void compute_index_maps(); 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_member_reference(address bcp, int offset, 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 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(); // Revert bytecodes in case of an exception. - void restore_bytecodes(TRAPS); + void restore_bytecodes(); static methodHandle rewrite_jsrs(methodHandle m, TRAPS); public: diff -r fca8f4799229 -r aa933e6b061d src/share/vm/runtime/globals.cpp --- a/src/share/vm/runtime/globals.cpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/runtime/globals.cpp Fri Nov 22 20:26:36 2013 +0100 @@ -321,6 +321,8 @@ { KIND_PRODUCT, "product" }, { KIND_MANAGEABLE, "manageable" }, { KIND_DIAGNOSTIC, "diagnostic" }, + { KIND_EXPERIMENTAL, "experimental" }, + { KIND_COMMERCIAL, "commercial" }, { KIND_NOT_PRODUCT, "notproduct" }, { KIND_DEVELOP, "develop" }, { KIND_LP64_PRODUCT, "lp64_product" }, diff -r fca8f4799229 -r aa933e6b061d src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/runtime/globals.hpp Fri Nov 22 20:26:36 2013 +0100 @@ -3622,9 +3622,6 @@ "Temporary flag for transition to AbstractMethodError wrapped " \ "in InvocationTargetException. See 6531596") \ \ - develop(bool, VerifyLambdaBytecodes, false, \ - "Force verification of jdk 8 lambda metafactory bytecodes") \ - \ develop(intx, FastSuperclassLimit, 8, \ "Depth of hardwired instanceof accelerator array") \ \ diff -r fca8f4799229 -r aa933e6b061d src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/runtime/reflection.cpp Fri Nov 22 20:26:36 2013 +0100 @@ -470,12 +470,6 @@ 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); } @@ -570,12 +564,6 @@ 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, field_class, classloader_only); } diff -r fca8f4799229 -r aa933e6b061d src/share/vm/services/threadService.cpp --- a/src/share/vm/services/threadService.cpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/services/threadService.cpp Fri Nov 22 20:26:36 2013 +0100 @@ -200,6 +200,12 @@ } } +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) { MutexLocker ml(Management_lock); if (_threaddump_list == NULL) { @@ -451,9 +457,16 @@ } } +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) { _method = jvf->method(); _bci = jvf->bci(); + _class_holder = _method->method_holder()->klass_holder(); _locked_monitors = NULL; if (with_lock_info) { ResourceMark rm; @@ -477,6 +490,11 @@ 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 { @@ -620,6 +638,14 @@ } } +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() { if (_retain_map_on_free) { return; @@ -823,6 +849,13 @@ } } +void ThreadSnapshot::metadata_do(void f(Metadata*)) { + if (_stack_trace != NULL) { + _stack_trace->metadata_do(f); + } +} + + DeadlockCycle::DeadlockCycle() { _is_deadlock = false; _threads = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(INITIAL_ARRAY_SIZE, true); diff -r fca8f4799229 -r aa933e6b061d src/share/vm/services/threadService.hpp --- a/src/share/vm/services/threadService.hpp Wed Nov 20 12:46:08 2013 +0100 +++ b/src/share/vm/services/threadService.hpp Fri Nov 22 20:26:36 2013 +0100 @@ -113,6 +113,7 @@ // GC support static void oops_do(OopClosure* f); + static void metadata_do(void f(Metadata*)); }; // Per-thread Statistics for synchronization @@ -242,6 +243,7 @@ void dump_stack_at_safepoint(int max_depth, bool with_locked_monitors); void set_concurrent_locks(ThreadConcurrentLocks* l) { _concurrent_locks = l; } void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); }; class ThreadStackTrace : public CHeapObj { @@ -265,6 +267,7 @@ void dump_stack_at_safepoint(int max_depth); Handle allocate_fill_stack_trace_element_array(TRAPS); void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); GrowableArray* jni_locked_monitors() { return _jni_locked_monitors; } int num_jni_locked_monitors() { return (_jni_locked_monitors != NULL ? _jni_locked_monitors->length() : 0); } @@ -280,6 +283,9 @@ Method* _method; int _bci; GrowableArray* _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: @@ -289,9 +295,10 @@ delete _locked_monitors; } }; - Method* method() const { return _method; } + Method* method() const { return _method; } int bci() const { return _bci; } void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); int num_locked_monitors() { return (_locked_monitors != NULL ? _locked_monitors->length() : 0); } GrowableArray* locked_monitors() { return _locked_monitors; } @@ -354,6 +361,7 @@ int num_snapshots() { return _num_snapshots; } ThreadSnapshot* snapshots() { return _snapshots; } void oops_do(OopClosure* f); + void metadata_do(void f(Metadata*)); }; class DeadlockCycle : public CHeapObj { diff -r fca8f4799229 -r aa933e6b061d test/compiler/jsr292/ConcurrentClassLoadingTest.java --- a/test/compiler/jsr292/ConcurrentClassLoadingTest.java Wed Nov 20 12:46:08 2013 +0100 +++ b/test/compiler/jsr292/ConcurrentClassLoadingTest.java Fri Nov 22 20:26:36 2013 +0100 @@ -172,7 +172,6 @@ "java.lang.invoke.LambdaConversionException", "java.lang.invoke.LambdaForm", "java.lang.invoke.LambdaMetafactory", - "java.lang.invoke.MagicLambdaImpl", "java.lang.invoke.MemberName", "java.lang.invoke.MethodHandle", "java.lang.invoke.MethodHandleImpl",