# HG changeset patch # User dcubed # Date 1426889970 25200 # Node ID 366660027ab5d3036a5161cbfb353fdfdeffe885 # Parent 6952cbf4b762bebbaef5c97e259e2890972cd935# Parent fbe647bcbc25638476102643549515eebc30af7a Merge diff -r 6952cbf4b762 -r 366660027ab5 hotspot/make/solaris/makefiles/dtrace.make --- a/hotspot/make/solaris/makefiles/dtrace.make Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/make/solaris/makefiles/dtrace.make Fri Mar 20 15:19:30 2015 -0700 @@ -130,8 +130,9 @@ $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @echo $(LOG_INFO) Making $@ $(QUIETLY) mkdir -p $(XLIBJVM_DIR) ; \ - $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. \ - $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor + $(CC) $(SYMFLAG) $(ARCHFLAG/$(ISA)) -D$(TYPE) -I. $(EXTRA_CFLAGS) \ + $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c \ + $(EXTRA_LDFLAGS) -lc -lthread -ldoor ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(XLIBJVM_DTRACE_DEBUGINFO) # Do this part in the $(XLIBJVM_DIR) subdir so $(XLIBJVM_DIR) is not @@ -216,8 +217,9 @@ $(LIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(XLIBJVM_DTRACE) $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) @echo $(LOG_INFO) Making $@ - $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. \ - $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor + $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) -D$(TYPE) -I. $(EXTRA_CFLAGS) \ + $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c \ + $(EXTRA_LDFLAGS) -lc -lthread -ldoor ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DTRACE_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DTRACE_DEBUGINFO) $@ diff -r 6952cbf4b762 -r 366660027ab5 hotspot/make/solaris/makefiles/jsig.make --- a/hotspot/make/solaris/makefiles/jsig.make Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/make/solaris/makefiles/jsig.make Fri Mar 20 15:19:30 2015 -0700 @@ -50,7 +50,9 @@ $(LIBJSIG): $(JSIGSRCDIR)/jsig.c $(LIBJSIG_MAPFILE) @echo $(LOG_INFO) Making signal interposition lib... $(QUIETLY) $(CC) $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - $(LFLAGS_JSIG) -o $@ $(JSIGSRCDIR)/jsig.c -ldl + $(EXTRA_CFLAGS) \ + $(LFLAGS_JSIG) $(EXTRA_LDFLAGS) \ + -o $@ $(JSIGSRCDIR)/jsig.c -ldl ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJSIG_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJSIG_DEBUGINFO) $@ diff -r 6952cbf4b762 -r 366660027ab5 hotspot/make/solaris/makefiles/saproc.make --- a/hotspot/make/solaris/makefiles/saproc.make Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/make/solaris/makefiles/saproc.make Fri Mar 20 15:19:30 2015 -0700 @@ -89,6 +89,17 @@ # when actually building on Nevada-B158 or earlier: #SOLARIS_11_B159_OR_LATER=-DSOLARIS_11_B159_OR_LATER +$(SADISOBJ): $(SADISSRCFILES) + $(QUIETLY) $(CC) \ + $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ + -I$(SASRCDIR) \ + -I$(GENERATED) \ + -I$(BOOT_JAVA_HOME)/include \ + -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \ + $(SOLARIS_11_B159_OR_LATER) \ + $(EXTRA_CFLAGS) \ + $(SADISSRCFILES) \ + -c -o $(SADISOBJ) $(LIBSAPROC): $(SASRCFILES) $(SADISOBJ) $(SAMAPFILE) $(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \ @@ -103,23 +114,13 @@ -I$(BOOT_JAVA_HOME)/include \ -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \ $(SOLARIS_11_B159_OR_LATER) \ + $(EXTRA_CXXFLAGS) $(EXTRA_LDFLAGS) \ + $(SADISOBJ) \ $(SASRCFILES) \ - $(SADISOBJ) \ $(SA_LFLAGS) \ -o $@ \ -ldl -ldemangle -lthread -lc -$(SADISOBJ): $(SADISSRCFILES) - $(QUIETLY) $(CC) \ - $(SYMFLAG) $(ARCHFLAG) $(SHARED_FLAG) $(PICFLAG) \ - -I$(SASRCDIR) \ - -I$(GENERATED) \ - -I$(BOOT_JAVA_HOME)/include \ - -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \ - $(SOLARIS_11_B159_OR_LATER) \ - $(SADISSRCFILES) \ - -c -o $(SADISOBJ) - ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1) $(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBSAPROC_DEBUGINFO) $(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBSAPROC_DEBUGINFO) $@ diff -r 6952cbf4b762 -r 366660027ab5 hotspot/make/solaris/makefiles/vm.make --- a/hotspot/make/solaris/makefiles/vm.make Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/make/solaris/makefiles/vm.make Fri Mar 20 15:19:30 2015 -0700 @@ -288,6 +288,8 @@ endif endif +LFLAGS_VM += $(EXTRA_LDFLAGS) + ifdef USE_GCC LINK_VM = $(LINK_LIB.CC) else diff -r 6952cbf4b762 -r 366660027ab5 hotspot/make/windows/makefiles/sa.make --- a/hotspot/make/windows/makefiles/sa.make Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/make/windows/makefiles/sa.make Fri Mar 20 15:19:30 2015 -0700 @@ -91,6 +91,9 @@ SAWINDBG=sawindbg.dll +# Resource file containing VERSIONINFO +SA_Res_Files=.\version.sares + checkAndBuildSA:: $(SAWINDBG) # These do not need to be optimized (don't run a lot of code) and it @@ -126,10 +129,13 @@ # Note that we do not keep sawindbj.obj around as it would then # get included in the dumpbin command in build_vm_def.sh +# Force resources to be rebuilt every time +$(SA_Res_Files): FORCE + # In VS2005 or VS2008 the link command creates a .manifest file that we want # to insert into the linked artifact so we do not need to track it separately. # Use ";#2" for .dll and ";#1" for .exe in the MT command below: -$(SAWINDBG): $(SASRCFILES) +$(SAWINDBG): $(SASRCFILES) $(SA_Res_Files) set INCLUDE=$(SA_INCLUDE)$(INCLUDE) $(CXX) @<< -I"$(BootStrapDir)/include" -I"$(BootStrapDir)/include/win32" @@ -138,7 +144,7 @@ -out:$*.obj << set LIB=$(SA_LIB)$(LIB) - $(LD) -out:$@ -DLL sawindbg.obj sadis.obj dbgeng.lib $(SA_LFLAGS) + $(LD) -out:$@ -DLL sawindbg.obj sadis.obj dbgeng.lib $(SA_LFLAGS) $(SA_Res_Files) !if "$(MT)" != "" $(MT) -manifest $(@F).manifest -outputresource:$(@F);#2 !endif @@ -150,6 +156,9 @@ !endif -@rm -f $*.obj +{$(COMMONSRC)\os\windows\vm}.rc.sares: + @$(RC) $(RC_FLAGS) /D "HS_FNAME=$(SAWINDBG)" /fo"$@" $< + cleanall : rm -rf $(GENERATED)/saclasses rm -rf $(GENERATED)/sa-jdi.jar diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/classfile/javaClasses.cpp --- a/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Mar 20 15:19:30 2015 -0700 @@ -1313,7 +1313,8 @@ } static inline bool version_matches(Method* method, int version) { - return (method->constants()->version() == version && version < MAX_VERSION); + assert(version < MAX_VERSION, "version is too big"); + return method != NULL && (method->constants()->version() == version); } static inline int get_line_number(Method* method, int bci) { @@ -1343,6 +1344,7 @@ typeArrayOop _methods; typeArrayOop _bcis; objArrayOop _mirrors; + typeArrayOop _cprefs; // needed to insulate method name against redefinition int _index; No_Safepoint_Verifier _nsv; @@ -1350,8 +1352,9 @@ enum { trace_methods_offset = java_lang_Throwable::trace_methods_offset, - trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, + trace_bcis_offset = java_lang_Throwable::trace_bcis_offset, trace_mirrors_offset = java_lang_Throwable::trace_mirrors_offset, + trace_cprefs_offset = java_lang_Throwable::trace_cprefs_offset, trace_next_offset = java_lang_Throwable::trace_next_offset, trace_size = java_lang_Throwable::trace_size, trace_chunk_size = java_lang_Throwable::trace_chunk_size @@ -1373,9 +1376,14 @@ assert(mirrors != NULL, "mirror array should be initialized in backtrace"); return mirrors; } + static typeArrayOop get_cprefs(objArrayHandle chunk) { + typeArrayOop cprefs = typeArrayOop(chunk->obj_at(trace_cprefs_offset)); + assert(cprefs != NULL, "cprefs array should be initialized in backtrace"); + return cprefs; + } // constructor for new backtrace - BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL) { + BacktraceBuilder(TRAPS): _methods(NULL), _bcis(NULL), _head(NULL), _mirrors(NULL), _cprefs(NULL) { expand(CHECK); _backtrace = _head; _index = 0; @@ -1385,6 +1393,7 @@ _methods = get_methods(backtrace); _bcis = get_bcis(backtrace); _mirrors = get_mirrors(backtrace); + _cprefs = get_cprefs(backtrace); assert(_methods->length() == _bcis->length() && _methods->length() == _mirrors->length(), "method and source information arrays should match"); @@ -1410,17 +1419,22 @@ objArrayOop mirrors = oopFactory::new_objectArray(trace_chunk_size, CHECK); objArrayHandle new_mirrors(THREAD, mirrors); + typeArrayOop cprefs = oopFactory::new_shortArray(trace_chunk_size, CHECK); + typeArrayHandle new_cprefs(THREAD, cprefs); + if (!old_head.is_null()) { old_head->obj_at_put(trace_next_offset, new_head()); } new_head->obj_at_put(trace_methods_offset, new_methods()); new_head->obj_at_put(trace_bcis_offset, new_bcis()); new_head->obj_at_put(trace_mirrors_offset, new_mirrors()); + new_head->obj_at_put(trace_cprefs_offset, new_cprefs()); _head = new_head(); _methods = new_methods(); _bcis = new_bcis(); _mirrors = new_mirrors(); + _cprefs = new_cprefs(); _index = 0; } @@ -1440,8 +1454,9 @@ method = mhandle(); } - _methods->short_at_put(_index, method->method_idnum()); + _methods->short_at_put(_index, method->orig_method_idnum()); _bcis->int_at_put(_index, merge_bci_and_version(bci, method->constants()->version())); + _cprefs->short_at_put(_index, method->name_index()); // We need to save the mirrors in the backtrace to keep the class // from being unloaded while we still have this stack trace. @@ -1454,27 +1469,26 @@ // Print stack trace element to resource allocated buffer char* java_lang_Throwable::print_stack_element_to_buffer(Handle mirror, - int method_id, int version, int bci) { + int method_id, int version, int bci, int cpref) { // Get strings and string lengths InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror())); const char* klass_name = holder->external_name(); int buf_len = (int)strlen(klass_name); - // The method id may point to an obsolete method, can't get more stack information - Method* method = holder->method_with_idnum(method_id); - if (method == NULL) { - char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); - // This is what the java code prints in this case - added Redefined - sprintf(buf, "\tat %s.null (Redefined)", klass_name); - return buf; - } - - char* method_name = method->name()->as_C_string(); + Method* method = holder->method_with_orig_idnum(method_id, version); + + // The method can be NULL if the requested class version is gone + Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref); + char* method_name = sym->as_C_string(); buf_len += (int)strlen(method_name); + // Use specific ik version as a holder since the mirror might + // refer to version that is now obsolete and no longer accessible + // via the previous versions list. + holder = holder->get_klass_version(version); char* source_file_name = NULL; - if (version_matches(method, version)) { + if (holder != NULL) { Symbol* source = holder->source_file_name(); if (source != NULL) { source_file_name = source->as_C_string(); @@ -1516,17 +1530,18 @@ } void java_lang_Throwable::print_stack_element(outputStream *st, Handle mirror, - int method_id, int version, int bci) { + int method_id, int version, int bci, int cpref) { ResourceMark rm; - char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci); + char* buf = print_stack_element_to_buffer(mirror, method_id, version, bci, cpref); st->print_cr("%s", buf); } void java_lang_Throwable::print_stack_element(outputStream *st, methodHandle method, int bci) { Handle mirror = method->method_holder()->java_mirror(); - int method_id = method->method_idnum(); + int method_id = method->orig_method_idnum(); int version = method->constants()->version(); - print_stack_element(st, mirror, method_id, version, bci); + int cpref = method->name_index(); + print_stack_element(st, mirror, method_id, version, bci, cpref); } const char* java_lang_Throwable::no_stack_trace_message() { @@ -1551,6 +1566,7 @@ typeArrayHandle methods (THREAD, BacktraceBuilder::get_methods(result)); typeArrayHandle bcis (THREAD, BacktraceBuilder::get_bcis(result)); objArrayHandle mirrors (THREAD, BacktraceBuilder::get_mirrors(result)); + typeArrayHandle cprefs (THREAD, BacktraceBuilder::get_cprefs(result)); int length = methods()->length(); for (int index = 0; index < length; index++) { @@ -1560,7 +1576,8 @@ int method = methods->short_at(index); int version = version_at(bcis->int_at(index)); int bci = bci_at(bcis->int_at(index)); - print_stack_element(st, mirror, method, version, bci); + int cpref = cprefs->short_at(index); + print_stack_element(st, mirror, method, version, bci, cpref); } result = objArrayHandle(THREAD, objArrayOop(result->obj_at(trace_next_offset))); } @@ -1837,29 +1854,30 @@ if (chunk == NULL) { THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); } - // Get method id, bci, version and mirror from chunk + // Get method id, bci, version, mirror and cpref from chunk typeArrayOop methods = BacktraceBuilder::get_methods(chunk); typeArrayOop bcis = BacktraceBuilder::get_bcis(chunk); objArrayOop mirrors = BacktraceBuilder::get_mirrors(chunk); + typeArrayOop cprefs = BacktraceBuilder::get_cprefs(chunk); assert(methods != NULL && bcis != NULL && mirrors != NULL, "sanity check"); int method = methods->short_at(chunk_index); int version = version_at(bcis->int_at(chunk_index)); int bci = bci_at(bcis->int_at(chunk_index)); + int cpref = cprefs->short_at(chunk_index); Handle mirror(THREAD, mirrors->obj_at(chunk_index)); // Chunk can be partial full if (mirror.is_null()) { THROW_(vmSymbols::java_lang_IndexOutOfBoundsException(), NULL); } - - oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, CHECK_0); + oop element = java_lang_StackTraceElement::create(mirror, method, version, bci, cpref, CHECK_0); return element; } oop java_lang_StackTraceElement::create(Handle mirror, int method_id, - int version, int bci, TRAPS) { + int version, int bci, int cpref, TRAPS) { // Allocate java.lang.StackTraceElement instance Klass* k = SystemDictionary::StackTraceElement_klass(); assert(k != NULL, "must be loaded in 1.4+"); @@ -1876,17 +1894,13 @@ oop classname = StringTable::intern((char*) str, CHECK_0); java_lang_StackTraceElement::set_declaringClass(element(), classname); - Method* method = holder->method_with_idnum(method_id); - // Method on stack may be obsolete because it was redefined so cannot be - // found by idnum. - if (method == NULL) { - // leave name and fileName null - java_lang_StackTraceElement::set_lineNumber(element(), -1); - return element(); - } + Method* method = holder->method_with_orig_idnum(method_id, version); + + // The method can be NULL if the requested class version is gone + Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref); // Fill in method name - oop methodname = StringTable::intern(method->name(), CHECK_0); + oop methodname = StringTable::intern(sym, CHECK_0); java_lang_StackTraceElement::set_methodName(element(), methodname); if (!version_matches(method, version)) { @@ -1895,6 +1909,11 @@ java_lang_StackTraceElement::set_lineNumber(element(), -1); } else { // Fill in source file name and line number. + // Use specific ik version as a holder since the mirror might + // refer to version that is now obsolete and no longer accessible + // via the previous versions list. + holder = holder->get_klass_version(version); + assert(holder != NULL, "sanity check"); Symbol* source = holder->source_file_name(); if (ShowHiddenFrames && source == NULL) source = vmSymbols::unknown_class_name(); @@ -1909,8 +1928,9 @@ oop java_lang_StackTraceElement::create(methodHandle method, int bci, TRAPS) { Handle mirror (THREAD, method->method_holder()->java_mirror()); - int method_id = method->method_idnum(); - return create(mirror, method_id, method->constants()->version(), bci, THREAD); + int method_id = method->orig_method_idnum(); + int cpref = method->name_index(); + return create(mirror, method_id, method->constants()->version(), bci, cpref, THREAD); } void java_lang_reflect_AccessibleObject::compute_offsets() { diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/classfile/javaClasses.hpp --- a/hotspot/src/share/vm/classfile/javaClasses.hpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Fri Mar 20 15:19:30 2015 -0700 @@ -485,8 +485,9 @@ trace_methods_offset = 0, trace_bcis_offset = 1, trace_mirrors_offset = 2, - trace_next_offset = 3, - trace_size = 4, + trace_cprefs_offset = 3, + trace_next_offset = 4, + trace_size = 5, trace_chunk_size = 32 }; @@ -497,7 +498,7 @@ static int static_unassigned_stacktrace_offset; // Printing - static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci); + static char* print_stack_element_to_buffer(Handle mirror, int method, int version, int bci, int cpref); // StackTrace (programmatic access, new since 1.4) static void clear_stacktrace(oop throwable); // No stack trace available @@ -519,7 +520,7 @@ static void set_message(oop throwable, oop value); static Symbol* detail_message(oop throwable); static void print_stack_element(outputStream *st, Handle mirror, int method, - int version, int bci); + int version, int bci, int cpref); static void print_stack_element(outputStream *st, methodHandle method, int bci); static void print_stack_usage(Handle stream); @@ -1314,7 +1315,7 @@ static void set_lineNumber(oop element, int value); // Create an instance of StackTraceElement - static oop create(Handle mirror, int method, int version, int bci, TRAPS); + static oop create(Handle mirror, int method, int version, int bci, int cpref, TRAPS); static oop create(methodHandle method, int bci, TRAPS); // Debugging diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/classfile/verifier.cpp --- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri Mar 20 15:19:30 2015 -0700 @@ -2236,14 +2236,20 @@ } // Look at the method's handlers. If the bci is in the handler's try block -// then check if the handler_pc is already on the stack. If not, push it. +// then check if the handler_pc is already on the stack. If not, push it +// unless the handler has already been scanned. void ClassVerifier::push_handlers(ExceptionTable* exhandlers, + GrowableArray* handler_list, GrowableArray* handler_stack, u4 bci) { int exlength = exhandlers->length(); for(int x = 0; x < exlength; x++) { if (bci >= exhandlers->start_pc(x) && bci < exhandlers->end_pc(x)) { - handler_stack->append_if_missing(exhandlers->handler_pc(x)); + u4 exhandler_pc = exhandlers->handler_pc(x); + if (!handler_list->contains(exhandler_pc)) { + handler_stack->append_if_missing(exhandler_pc); + handler_list->append(exhandler_pc); + } } } } @@ -2261,6 +2267,10 @@ GrowableArray* bci_stack = new GrowableArray(30); // Create stack for handlers for try blocks containing this handler. GrowableArray* handler_stack = new GrowableArray(30); + // Create list of handlers that have been pushed onto the handler_stack + // so that handlers embedded inside of their own TRY blocks only get + // scanned once. + GrowableArray* handler_list = new GrowableArray(30); // Create list of visited branch opcodes (goto* and if*). GrowableArray* visited_branches = new GrowableArray(30); ExceptionTable exhandlers(_method()); @@ -2279,7 +2289,7 @@ // If the bytecode is in a TRY block, push its handlers so they // will get parsed. - push_handlers(&exhandlers, handler_stack, bci); + push_handlers(&exhandlers, handler_list, handler_stack, bci); switch (opcode) { case Bytecodes::_if_icmpeq: diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/classfile/verifier.hpp --- a/hotspot/src/share/vm/classfile/verifier.hpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/classfile/verifier.hpp Fri Mar 20 15:19:30 2015 -0700 @@ -305,9 +305,10 @@ bool* this_uninit, constantPoolHandle cp, StackMapTable* stackmap_table, TRAPS); - // Used by ends_in_athrow() to push all handlers that contain bci onto - // the handler_stack, if the handler is not already on the stack. + // Used by ends_in_athrow() to push all handlers that contain bci onto the + // handler_stack, if the handler has not already been pushed on the stack. void push_handlers(ExceptionTable* exhandlers, + GrowableArray* handler_list, GrowableArray* handler_stack, u4 bci); diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/oops/instanceKlass.cpp --- a/hotspot/src/share/vm/oops/instanceKlass.cpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Fri Mar 20 15:19:30 2015 -0700 @@ -716,23 +716,6 @@ // Set up method entry points for compiler and interpreter . m->link_method(m, CHECK); - - // This is for JVMTI and unrelated to relocator but the last thing we do -#ifdef ASSERT - if (StressMethodComparator) { - ResourceMark rm(THREAD); - static int nmc = 0; - for (int j = i; j >= 0 && j >= i-4; j--) { - if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); - bool z = MethodComparator::methods_EMCP(m(), - methods()->at(j)); - if (j == i && !z) { - tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); - assert(z, "method must compare equal to itself"); - } - } - } -#endif //ASSERT } } @@ -3725,6 +3708,37 @@ return m; } + +Method* InstanceKlass::method_with_orig_idnum(int idnum) { + if (idnum >= methods()->length()) { + return NULL; + } + Method* m = methods()->at(idnum); + if (m != NULL && m->orig_method_idnum() == idnum) { + return m; + } + // Obsolete method idnum does not match the original idnum + for (int index = 0; index < methods()->length(); ++index) { + m = methods()->at(index); + if (m->orig_method_idnum() == idnum) { + return m; + } + } + // None found, return null for the caller to handle. + return NULL; +} + + +Method* InstanceKlass::method_with_orig_idnum(int idnum, int version) { + InstanceKlass* holder = get_klass_version(version); + if (holder == NULL) { + return NULL; // The version of klass is gone, no method is found + } + Method* method = holder->method_with_orig_idnum(idnum); + return method; +} + + jint InstanceKlass::get_cached_class_file_len() { return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file); } diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/oops/instanceKlass.hpp --- a/hotspot/src/share/vm/oops/instanceKlass.hpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Fri Mar 20 15:19:30 2015 -0700 @@ -329,6 +329,8 @@ Array* methods() const { return _methods; } void set_methods(Array* a) { _methods = a; } Method* method_with_idnum(int idnum); + Method* method_with_orig_idnum(int idnum); + Method* method_with_orig_idnum(int idnum, int version); // method ordering Array* method_ordering() const { return _method_ordering; } @@ -620,6 +622,15 @@ InstanceKlass* previous_versions() const { return _previous_versions; } + InstanceKlass* get_klass_version(int version) { + for (InstanceKlass* ik = this; ik != NULL; ik = ik->previous_versions()) { + if (ik->constants()->version() == version) { + return ik; + } + } + return NULL; + } + bool has_been_redefined() const { return (_misc_flags & _misc_has_been_redefined) != 0; } diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/runtime/arguments.cpp --- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Mar 20 15:19:30 2015 -0700 @@ -240,6 +240,9 @@ * and ignoring the value. Once the JDK version reaches the 'accept_until' * limit, we flatly refuse to admit the existence of the flag. This allows * a flag to die correctly over JDK releases using HSX. + * But now that HSX is no longer supported only options with a future + * accept_until value need to be listed, and the list can be pruned + * on each major release. */ typedef struct { const char* name; @@ -248,63 +251,8 @@ } ObsoleteFlag; static ObsoleteFlag obsolete_jvm_flags[] = { - { "UseTrainGC", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "UseSpecialLargeObjectHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "UseOversizedCarHandling", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "TraceCarAllocation", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "PrintTrainGCProcessingStats", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "LogOfCarSpaceSize", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "OversizedCarThreshold", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "MinTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "DefaultTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "MaxTickInterval", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "DelayTickAdjustment", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "ProcessingToTenuringRatio", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "MinTrainLength", JDK_Version::jdk(5), JDK_Version::jdk(7) }, - { "AppendRatio", JDK_Version::jdk_update(6,10), JDK_Version::jdk(7) }, - { "DefaultMaxRAM", JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) }, - { "DefaultInitialRAMFraction", - JDK_Version::jdk_update(6,18), JDK_Version::jdk(7) }, - { "UseDepthFirstScavengeOrder", - JDK_Version::jdk_update(6,22), JDK_Version::jdk(7) }, - { "HandlePromotionFailure", - JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) }, - { "MaxLiveObjectEvacuationRatio", - JDK_Version::jdk_update(6,24), JDK_Version::jdk(8) }, - { "ForceSharedSpaces", JDK_Version::jdk_update(6,25), JDK_Version::jdk(8) }, - { "UseParallelOldGCCompacting", - JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) }, - { "UseParallelDensePrefixUpdate", - JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) }, - { "UseParallelOldGCDensePrefix", - JDK_Version::jdk_update(6,27), JDK_Version::jdk(8) }, - { "AllowTransitionalJSR292", JDK_Version::jdk(7), JDK_Version::jdk(8) }, - { "UseCompressedStrings", JDK_Version::jdk(7), JDK_Version::jdk(8) }, - { "CMSPermGenPrecleaningEnabled", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "CMSTriggerPermRatio", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "CMSInitiatingPermOccupancyFraction", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "AdaptivePermSizeWeight", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "PermGenPadding", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "PermMarkSweepDeadRatio", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "PermSize", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "MaxPermSize", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "MinPermHeapExpansion", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "MaxPermHeapExpansion", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "CMSRevisitStackSize", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "PrintRevisitStats", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "UseVectoredExceptions", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "UseSplitVerifier", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "UseISM", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "UsePermISM", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "UseMPSS", JDK_Version::jdk(8), JDK_Version::jdk(9) }, - { "UseStringCache", JDK_Version::jdk(8), JDK_Version::jdk(9) }, { "UseOldInlining", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "SafepointPollOffset", JDK_Version::jdk(9), JDK_Version::jdk(10) }, -#ifdef PRODUCT - { "DesiredMethodLimit", - JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) }, -#endif // PRODUCT - { "UseVMInterruptibleIO", JDK_Version::jdk(8), JDK_Version::jdk(9) }, { "UseBoundThreads", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "DefaultThreadPriority", JDK_Version::jdk(9), JDK_Version::jdk(10) }, { "NoYieldsInMicrolock", JDK_Version::jdk(9), JDK_Version::jdk(10) }, diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Mar 20 15:19:30 2015 -0700 @@ -1342,9 +1342,6 @@ product(intx, TraceRedefineClasses, 0, \ "Trace level for JVMTI RedefineClasses") \ \ - develop(bool, StressMethodComparator, false, \ - "Run the MethodComparator on all loaded methods") \ - \ /* change to false by default sometime after Mustang */ \ product(bool, VerifyMergedCPBytecodes, true, \ "Verify bytecodes after RedefineClasses constant pool merging") \ diff -r 6952cbf4b762 -r 366660027ab5 hotspot/src/share/vm/runtime/mutexLocker.cpp --- a/hotspot/src/share/vm/runtime/mutexLocker.cpp Thu Mar 19 15:00:51 2015 -0700 +++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp Fri Mar 20 15:19:30 2015 -0700 @@ -169,7 +169,7 @@ #define def(var, type, pri, vm_block, safepoint_check_allowed ) { \ var = new type(Mutex::pri, #var, vm_block, safepoint_check_allowed); \ assert(_num_mutex < MAX_NUM_MUTEX, "increase MAX_NUM_MUTEX"); \ - _mutex_array[_num_mutex] = var; \ + _mutex_array[_num_mutex++] = var; \ } void mutex_init() { diff -r 6952cbf4b762 -r 366660027ab5 hotspot/test/runtime/handlerInTry/HandlerInTry.jasm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/handlerInTry/HandlerInTry.jasm Fri Mar 20 15:19:30 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. + */ + +/* + * HandlerInTry contains a try block in a ctor whose handler is inside + * the same try block. The try block starts at line 74 (try t2;), ends at + * line 106 (endtry t2;), but its handler starts at line 101 (catch t2 #0;). + */ +super public class HandlerInTry + version 51:0 +{ + +public static final synthetic Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;"; + +public Method "":"(Ljava/lang/Object;)V" + stack 5 locals 5 +{ + invokestatic Method ThreadLocalTransaction.getThreadLocalTransaction:"()Ljava/lang/Object;"; + checkcast class java/lang/Object; + astore_2; + aload_2; + invokestatic Method TransactionLogicDonor.isActiveTransaction:"(Ljava/lang/Object;)Z"; + ifeq L21; + aload_0; + aload_1; + aload_2; + invokespecial Method "":"(Ljava/lang/Object;Ljava/lang/Object;)V"; + return; + L21: stack_frame_type append; + locals_map class java/lang/Object; + aload_2; + getstatic Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;"; + invokestatic Method TransactionLogicDonor.createTransaction:"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; + astore_2; + aload_2; + iconst_1; + pop; + aload_2; + invokestatic Method ThreadLocalTransaction.setThreadLocalTransaction:"(Ljava/lang/Object;)V"; + try t0, t1; + aload_0; + aload_1; + aload_2; + invokespecial Method "":"(Ljava/lang/Object;Ljava/lang/Object;)V"; + aload_2; + pop; + aconst_null; + astore_2; + endtry t0, t1; + invokestatic Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V"; + pop; + goto L107; + catch t0 java/lang/Throwable; + try t2; + stack_frame_type full; + locals_map bogus, class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + astore_3; + aload_2; + pop; + aload_3; + instanceof class ControlFlowError; + ifeq L82; + new class java/lang/NullPointerException; + dup; + invokespecial Method java/lang/NullPointerException."":"()V"; + athrow; + L82: stack_frame_type append; + locals_map class java/lang/Throwable; + aload_3; + instanceof class java/lang/Error; + ifeq L94; + aload_3; + checkcast class java/lang/Error; + athrow; + L94: stack_frame_type same; + aload_3; + checkcast class java/lang/Exception; + athrow; + catch t1 #0; + catch t2 #0; + stack_frame_type full; + locals_map bogus, class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + astore 4; + endtry t2; + invokestatic Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V"; + aload 4; + athrow; + L107: stack_frame_type full; + locals_map class HandlerInTry, class java/lang/Object, null; + return; +} + +} // end Class HandlerInTry diff -r 6952cbf4b762 -r 366660027ab5 hotspot/test/runtime/handlerInTry/IsolatedHandlerInTry.jasm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/handlerInTry/IsolatedHandlerInTry.jasm Fri Mar 20 15:19:30 2015 -0700 @@ -0,0 +1,124 @@ +/* + * 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. + */ + +/* + * IsolatedHandlerInTry contains a try block in a ctor whose handler is inside + * the same try block but the handler can only be reached if an exception + * occurs. The handler does a return. So, a VerifyException should be thrown. + * The try block starts at line 77 (try t2;) and ends at line 113 (endtry t2;). + * Its handler starts at line 107 (catch t2 #0;). The handler can only be reached + * by exception because of the athrow at line 106. + */ +super public class IsolatedHandlerInTry + version 51:0 +{ + +public static final synthetic Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;"; + +public Method "":"(Ljava/lang/Object;)V" + stack 5 locals 5 +{ + invokestatic Method ThreadLocalTransaction.getThreadLocalTransaction:"()Ljava/lang/Object;"; + checkcast class java/lang/Object; + astore_2; + aload_2; + invokestatic Method TransactionLogicDonor.isActiveTransaction:"(Ljava/lang/Object;)Z"; + ifeq L21; + aload_0; + aload_1; + aload_2; + invokespecial Method "":"(Ljava/lang/Object;Ljava/lang/Object;)V"; + return; + L21: stack_frame_type append; + locals_map class java/lang/Object; + aload_2; + getstatic Field ___transactionFactory_2002349702336125:"Ljava/lang/Object;"; + invokestatic Method TransactionLogicDonor.createTransaction:"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; + astore_2; + aload_2; + iconst_1; + pop; + aload_2; + invokestatic Method ThreadLocalTransaction.setThreadLocalTransaction:"(Ljava/lang/Object;)V"; + try t0, t1; + aload_0; + aload_1; + aload_2; + invokespecial Method "":"(Ljava/lang/Object;Ljava/lang/Object;)V"; + aload_2; + pop; + aconst_null; + astore_2; + endtry t0, t1; + invokestatic Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V"; + pop; + goto L107; + catch t0 java/lang/Throwable; + try t2; + stack_frame_type full; + locals_map bogus, class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + astore_3; + aload_2; + pop; + aload_3; + instanceof class ControlFlowError; + ifeq L82; + new class java/lang/NullPointerException; + dup; + invokespecial Method java/lang/NullPointerException."":"()V"; + athrow; + L82: stack_frame_type append; + locals_map class java/lang/Throwable; + aload_3; + instanceof class java/lang/Error; + ifeq L94; + aload_3; + checkcast class java/lang/Error; + athrow; + L94: stack_frame_type same; + aload_3; + checkcast class java/lang/Exception; + catch t1 #0; + stack_frame_type full; + locals_map bogus, class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + athrow; + catch t2 #0; + stack_frame_type full; + locals_map bogus, class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + astore 4; + return; + endtry t2; + stack_frame_type full; + locals_map bogus, class java/lang/Object, class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + invokestatic Method ThreadLocalTransaction.clearThreadLocalTransaction:"()V"; + athrow; + L107: stack_frame_type full; + locals_map class IsolatedHandlerInTry, class java/lang/Object, null; + return; +} + +} // end Class IsolatedHandlerInTry diff -r 6952cbf4b762 -r 366660027ab5 hotspot/test/runtime/handlerInTry/LoadHandlerInTry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/runtime/handlerInTry/LoadHandlerInTry.java Fri Mar 20 15:19:30 2015 -0700 @@ -0,0 +1,86 @@ +/* + * 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 8075118 + * @summary Allow a ctor to call super() from a switch bytecode. + * @compile HandlerInTry.jasm + * @compile IsolatedHandlerInTry.jasm + * @run main/othervm -Xverify:all LoadHandlerInTry + */ + +/* + * This test has two cases: + * + * 1. class HandlerInTry: Class HandlerInTry contains a TRY block in a + * constructor whose handler is inside the same TRY block. The last + * few bytecodes and exception table look like this: + * + * ... + * 87: athrow + * 88: astore 4 + * 90: invokestatic #9 + * 93: aload 4 + * 95: athrow + * 96: return + * Exception table: + * from to target type + * 36 46 53 Class java/lang/Throwable + * 36 46 88 any + * 53 90 88 any + * + * Note that the target for the third handler in the Exception table is + * inside its TRY block. + * Without the fix for bug JDK-8075118, this test will time out. + * + * + * 2. class IsolatedHandlerInTry: Class IsolatedHandlerInTry also contains + * a TRY block in a constructoer whose handler is inside its TRY block. + * But the handler is only reachable if an exception is thrown. The + * handler's bytecodes will not get parsed as part of parsing the TRY + * block. They will only get parsed as a handler for the TRY block. + * Since the isolated handler does a 'return', a VerifyError exception + * should get thrown. + */ + +public class LoadHandlerInTry { + + public static void main(String[] args) throws Exception { + System.out.println("Regression test for bug 8075118"); + try { + Class newClass = Class.forName("HandlerInTry"); + } catch (Exception e) { + System.out.println("Failed: Exception was thrown: " + e.toString()); + throw e; + } + + try { + Class newClass = Class.forName("IsolatedHandlerInTry"); + throw new RuntimeException( + "Failed to throw VerifyError for IsolatedHandlerInTry"); + } catch (java.lang.VerifyError e) { + System.out.println("Passed: VerifyError exception was thrown"); + } + } +}