Mercurial > hg > release > icedtea7-forest-2.4 > hotspot
changeset 4499:d6cf0e0eee29 hs24-b39
Merge
author | amurillo |
---|---|
date | Fri, 05 Apr 2013 10:32:51 -0700 |
parents | c23596bfe3b8 (current diff) 5c44c9466675 (diff) |
children | 21b442e8b756 |
files | make/windows/projectfiles/kernel/Makefile make/windows/projectfiles/kernel/vm.def make/windows/projectfiles/kernel/vm.dsw |
diffstat | 52 files changed, 874 insertions(+), 317 deletions(-) [+] |
line wrap: on
line diff
--- a/make/hotspot_version Fri Apr 05 09:10:28 2013 -0700 +++ b/make/hotspot_version Fri Apr 05 10:32:51 2013 -0700 @@ -35,7 +35,7 @@ HS_MAJOR_VER=24 HS_MINOR_VER=0 -HS_BUILD_NUMBER=38 +HS_BUILD_NUMBER=39 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/make/windows/build.make Fri Apr 05 09:10:28 2013 -0700 +++ b/make/windows/build.make Fri Apr 05 10:32:51 2013 -0700 @@ -110,8 +110,6 @@ !endif !elseif "$(Variant)" == "tiered" VARIANT_TEXT=Tiered -!elseif "$(Variant)" == "kernel" -VARIANT_TEXT=Kernel !endif ######################################################################### @@ -198,6 +196,12 @@ # End VERSIONINFO parameters +# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK +!ifndef OPENJDK +!if !exists($(WorkSpace)\src\closed) +OPENJDK=true +!endif +!endif # We don't support SA on ia64, and we can't # build it if we are using a version of Vis Studio @@ -284,6 +288,7 @@ @ echo HS_COMPANY=$(COMPANY_NAME) >> $@ @ echo HS_FILEDESC=$(HS_FILEDESC) >> $@ @ echo HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) >> $@ + @ if "$(OPENJDK)" NEQ "" echo OPENJDK=$(OPENJDK) >> $@ @ echo HS_COPYRIGHT=$(HOTSPOT_VM_COPYRIGHT) >> $@ @ echo HS_NAME=$(PRODUCT_NAME) $(JDK_MKTG_VERSION) >> $@ @ echo HS_BUILD_VER=$(HS_BUILD_VER) >> $@ @@ -310,9 +315,9 @@ checks: checkVariant checkWorkSpace checkSA checkVariant: - @ if "$(Variant)"=="" echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false - @ if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "kernel" if "$(Variant)" NEQ "core" \ - echo Need to specify "Variant=[tiered|compiler2|compiler1|kernel|core]" && false + @ if "$(Variant)"=="" echo Need to specify "Variant=[tiered|compiler2|compiler1|core]" && false + @ if "$(Variant)" NEQ "tiered" if "$(Variant)" NEQ "compiler2" if "$(Variant)" NEQ "compiler1" if "$(Variant)" NEQ "core" \ + echo Need to specify "Variant=[tiered|compiler2|compiler1|core]" && false checkWorkSpace: @ if "$(WorkSpace)"=="" echo Need to specify "WorkSpace=..." && false
--- a/make/windows/create.bat Fri Apr 05 09:10:28 2013 -0700 +++ b/make/windows/create.bat Fri Apr 05 10:32:51 2013 -0700 @@ -148,7 +148,7 @@ REM This is now safe to do. :copyfiles -for /D %%i in (compiler1, compiler2, tiered, core, kernel) do ( +for /D %%i in (compiler1, compiler2, tiered, core) do ( if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL ) @@ -156,7 +156,7 @@ REM force regneration of ProjectFile if exist %ProjectFile% del %ProjectFile% -for /D %%i in (compiler1, compiler2, tiered, core, kernel) do ( +for /D %%i in (compiler1, compiler2, tiered, core) do ( echo -- %%i -- echo # Generated file! > %HotSpotBuildSpace%\%%i\local.make echo # Changing a variable below and then deleting %ProjectFile% will cause >> %HotSpotBuildSpace%\%%i\local.make
--- a/make/windows/makefiles/compile.make Fri Apr 05 09:10:28 2013 -0700 +++ b/make/windows/makefiles/compile.make Fri Apr 05 10:32:51 2013 -0700 @@ -221,13 +221,6 @@ !endif !endif -# Compile for space above time. -!if "$(Variant)" == "kernel" -PRODUCT_OPT_OPTION = /O1 /Oy- -FASTDEBUG_OPT_OPTION = /O1 /Oy- -DEBUG_OPT_OPTION = /Od -!endif - # If NO_OPTIMIZATIONS is defined in the environment, turn everything off !ifdef NO_OPTIMIZATIONS PRODUCT_OPT_OPTION = $(DEBUG_OPT_OPTION)
--- a/make/windows/makefiles/product.make Fri Apr 05 09:10:28 2013 -0700 +++ b/make/windows/makefiles/product.make Fri Apr 05 10:32:51 2013 -0700 @@ -51,13 +51,6 @@ # Force resources to be rebuilt every time $(Res_Files): FORCE -# Kernel doesn't need exported vtbl symbols. -!if "$(Variant)" == "kernel" -$(AOUT): $(Res_Files) $(Obj_Files) - $(LD) @<< - $(LD_FLAGS) /out:$@ /implib:$*.lib $(Obj_Files) $(Res_Files) -<< -!else vm.def: $(Obj_Files) sh $(WorkSpace)/make/windows/build_vm_def.sh @@ -65,7 +58,6 @@ $(LD) @<< $(LD_FLAGS) /out:$@ /implib:$*.lib /def:vm.def $(Obj_Files) $(Res_Files) << -!endif !if "$(MT)" != "" # The previous link command created a .manifest file that we want to # insert into the linked artifact so we do not need to track it
--- a/make/windows/makefiles/trace.make Fri Apr 05 09:10:28 2013 -0700 +++ b/make/windows/makefiles/trace.make Fri Apr 05 10:32:51 2013 -0700 @@ -116,8 +116,6 @@ # ######################################################################### cleanall : -!if "$(INCLUDE_TRACE)" == "1" rm $(TraceGeneratedFiles) -!endif
--- a/make/windows/projectfiles/common/Makefile Fri Apr 05 09:10:28 2013 -0700 +++ b/make/windows/projectfiles/common/Makefile Fri Apr 05 10:32:51 2013 -0700 @@ -45,12 +45,11 @@ !endif !endif -!ifndef OPENJDK -!if exist($(WorkSpace)\src\closed) -OPENJDK=false -!else -OPENJDK=true -!endif +# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK +!ifndef OPENJDK +!if !exists($(WorkSpace)\src\closed) +OPENJDK=true +!endif !endif
--- a/make/windows/projectfiles/kernel/Makefile Fri Apr 05 09:10:28 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -# -# Copyright (c) 2007, 2010, 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. -# -# - -!include ../local.make - -!include $(HOTSPOTWORKSPACE)/make/windows/projectfiles/common/Makefile
--- a/make/windows/projectfiles/kernel/vm.def Fri Apr 05 09:10:28 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -; -; This .DEF file is a placeholder for one which is automatically -; generated during the build process. See -; make\windows\build_vm_def.sh and -; make\windows\makefiles\projectcreator.make (esp. the "-prelink" -; options). -;
--- a/make/windows/projectfiles/kernel/vm.dsw Fri Apr 05 09:10:28 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "vm"=.\vm.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### -
--- a/src/os/linux/vm/globals_linux.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/os/linux/vm/globals_linux.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, 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 @@ -40,6 +40,9 @@ product(bool, UseHugeTLBFS, false, \ "Use MAP_HUGETLB for large pages") \ \ + product(bool, LoadExecStackDllInVMThread, true, \ + "Load DLLs with executable-stack attribute in the VM Thread") \ + \ product(bool, UseSHM, false, \ "Use SYSV shared memory for large pages")
--- a/src/os/linux/vm/os_linux.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/os/linux/vm/os_linux.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -43,6 +43,7 @@ #include "runtime/extendedPC.hpp" #include "runtime/globals.hpp" #include "runtime/interfaceSupport.hpp" +#include "runtime/init.hpp" #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" @@ -61,6 +62,7 @@ #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" +#include "utilities/elfFile.hpp" #include "utilities/growableArray.hpp" #include "utilities/vmError.hpp" #ifdef TARGET_ARCH_x86 @@ -1816,20 +1818,101 @@ // in case of error it checks if .dll/.so was built for the // same architecture as Hotspot is running on + +// Remember the stack's state. The Linux dynamic linker will change +// the stack to 'executable' at most once, so we must safepoint only once. +bool os::Linux::_stack_is_executable = false; + +// VM operation that loads a library. This is necessary if stack protection +// of the Java stacks can be lost during loading the library. If we +// do not stop the Java threads, they can stack overflow before the stacks +// are protected again. +class VM_LinuxDllLoad: public VM_Operation { + private: + const char *_filename; + char *_ebuf; + int _ebuflen; + void *_lib; + public: + VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) : + _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {} + VMOp_Type type() const { return VMOp_LinuxDllLoad; } + void doit() { + _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen); + os::Linux::_stack_is_executable = true; + } + void* loaded_library() { return _lib; } +}; + void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { - void * result= ::dlopen(filename, RTLD_LAZY); + void * result = NULL; + bool load_attempted = false; + + // Check whether the library to load might change execution rights + // of the stack. If they are changed, the protection of the stack + // guard pages will be lost. We need a safepoint to fix this. + // + // See Linux man page execstack(8) for more info. + if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) { + ElfFile ef(filename); + if (!ef.specifies_noexecstack()) { + if (!is_init_completed()) { + os::Linux::_stack_is_executable = true; + // This is OK - No Java threads have been created yet, and hence no + // stack guard pages to fix. + // + // This should happen only when you are building JDK7 using a very + // old version of JDK6 (e.g., with JPRT) and running test_gamma. + // + // Dynamic loader will make all stacks executable after + // this function returns, and will not do that again. + assert(Threads::first() == NULL, "no Java threads should exist yet."); + } else { + warning("You have loaded library %s which might have disabled stack guard. " + "The VM will try to fix the stack guard now.\n" + "It's highly recommended that you fix the library with " + "'execstack -c <libfile>', or link it with '-z noexecstack'.", + filename); + + assert(Thread::current()->is_Java_thread(), "must be Java thread"); + JavaThread *jt = JavaThread::current(); + if (jt->thread_state() != _thread_in_native) { + // This happens when a compiler thread tries to load a hsdis-<arch>.so file + // that requires ExecStack. Cannot enter safe point. Let's give up. + warning("Unable to fix stack guard. Giving up."); + } else { + if (!LoadExecStackDllInVMThread) { + // This is for the case where the DLL has an static + // constructor function that executes JNI code. We cannot + // load such DLLs in the VMThread. + result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); + } + + ThreadInVMfromNative tiv(jt); + debug_only(VMNativeEntryWrapper vew;) + + VM_LinuxDllLoad op(filename, ebuf, ebuflen); + VMThread::execute(&op); + if (LoadExecStackDllInVMThread) { + result = op.loaded_library(); + } + load_attempted = true; + } + } + } + } + + if (!load_attempted) { + result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); + } + if (result != NULL) { // Successful loading return result; } Elf32_Ehdr elf_head; - - // Read system error message into ebuf - // It may or may not be overwritten below - ::strncpy(ebuf, ::dlerror(), ebuflen-1); - ebuf[ebuflen-1]='\0'; int diag_msg_max_length=ebuflen-strlen(ebuf); char* diag_msg_buf=ebuf+strlen(ebuf); @@ -1972,6 +2055,47 @@ return NULL; } +void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) { + void * result = ::dlopen(filename, RTLD_LAZY); + if (result == NULL) { + ::strncpy(ebuf, ::dlerror(), ebuflen - 1); + ebuf[ebuflen-1] = '\0'; + } + return result; +} + +void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) { + void * result = NULL; + if (LoadExecStackDllInVMThread) { + result = dlopen_helper(filename, ebuf, ebuflen); + } + + // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a + // library that requires an executable stack, or which does not have this + // stack attribute set, dlopen changes the stack attribute to executable. The + // read protection of the guard pages gets lost. + // + // Need to check _stack_is_executable again as multiple VM_LinuxDllLoad + // may have been queued at the same time. + + if (!_stack_is_executable) { + JavaThread *jt = Threads::first(); + + while (jt) { + if (!jt->stack_guard_zone_unused() && // Stack not yet fully initialized + jt->stack_yellow_zone_enabled()) { // No pending stack overflow exceptions + if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(), + jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) { + warning("Attempt to reguard stack yellow zone failed."); + } + } + jt = jt->next(); + } + } + + return result; +} + /* * glibc-2.0 libdl is not MT safe. If you are building with any glibc, * chances are you might want to run the generated bits against glibc-2.0
--- a/src/os/linux/vm/os_linux.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/os/linux/vm/os_linux.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -94,6 +94,10 @@ static void print_libversion_info(outputStream* st); public: + static bool _stack_is_executable; + static void *dlopen_helper(const char *name, char *ebuf, int ebuflen); + static void *dll_load_in_vmthread(const char *name, char *ebuf, int ebuflen); + static void init_thread_fpu_state(); static int get_fpu_control_word(); static void set_fpu_control_word(int fpu_control);
--- a/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -410,6 +410,11 @@ // to handle_unexpected_exception way down below. thread->disable_stack_red_zone(); tty->print_raw_cr("An irrecoverable stack overflow has occurred."); + + // This is a likely cause, but hard to verify. Let's just print + // it as a hint. + tty->print_raw_cr("Please check if any of your loaded .so files has " + "enabled executable stack (see man page execstack(8))"); } else { // Accessing stack address below sp may cause SEGV if current // thread has MAP_GROWSDOWN stack. This should only happen when
--- a/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/os_cpu/linux_x86/vm/os_linux_x86.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -306,6 +306,11 @@ // to handle_unexpected_exception way down below. thread->disable_stack_red_zone(); tty->print_raw_cr("An irrecoverable stack overflow has occurred."); + + // This is a likely cause, but hard to verify. Let's just print + // it as a hint. + tty->print_raw_cr("Please check if any of your loaded .so files has " + "enabled executable stack (see man page execstack(8))"); } else { // Accessing stack address below sp may cause SEGV if current // thread has MAP_GROWSDOWN stack. This should only happen when
--- a/src/share/tools/ProjectCreator/BuildConfig.java Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/tools/ProjectCreator/BuildConfig.java Fri Apr 05 10:32:51 2013 -0700 @@ -568,36 +568,6 @@ } } -class KernelDebugConfig extends GenericDebugConfig { - String getOptFlag() { - return getCI().getNoOptFlag(); - } - - KernelDebugConfig() { - initNames("kernel", "debug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - - -class KernelFastDebugConfig extends GenericDebugConfig { - String getOptFlag() { - return getCI().getOptFlag(); - } - - KernelFastDebugConfig() { - initNames("kernel", "fastdebug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - - -class KernelProductConfig extends ProductConfig { - KernelProductConfig() { - initNames("kernel", "product", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} abstract class CompilerInterface { abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
--- a/src/share/tools/ProjectCreator/WinGammaPlatform.java Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java Fri Apr 05 10:32:51 2013 -0700 @@ -564,12 +564,6 @@ allConfigs.add(new CoreFastDebugConfig()); allConfigs.add(new CoreProductConfig()); - if (platform.equals("Win32")) { - allConfigs.add(new KernelDebugConfig()); - allConfigs.add(new KernelFastDebugConfig()); - allConfigs.add(new KernelProductConfig()); - } - return allConfigs; }
--- a/src/share/vm/c1/c1_FrameMap.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/c1/c1_FrameMap.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -308,27 +308,6 @@ return sp_offset_for_monitor_base(index) + in_ByteSize(BasicObjectLock::obj_offset_in_bytes()); } -void FrameMap::print_frame_layout() const { - int svar; - tty->print_cr("#####################################"); - tty->print_cr("Frame size in words %d", framesize()); - - if( _num_monitors > 0) { - tty->print_cr("monitor [0]:%d | [%2d]:%d", - in_bytes(sp_offset_for_monitor_base(0)), - in_bytes(sp_offset_for_monitor_base(_num_monitors))); - } - if( _num_spills > 0) { - svar = _num_spills - 1; - if(svar == 0) - tty->print_cr("spill [0]:%d", in_bytes(sp_offset_for_spill(0))); - else - tty->print_cr("spill [0]:%d | [%2d]:%d", in_bytes(sp_offset_for_spill(0)), - svar, - in_bytes(sp_offset_for_spill(svar))); - } -} - // For OopMaps, map a local variable or spill index to an VMReg. // This is the offset from sp() in the frame of the slot for the index,
--- a/src/share/vm/c1/c1_FrameMap.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/c1/c1_FrameMap.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -222,8 +222,6 @@ return make_new_address(sp_offset_for_monitor_object(monitor_index)); } - void print_frame_layout() const; - // Creates Location describing desired slot and returns it via pointer // to Location object. Returns true if the stack frame offset was legal // (as defined by Location::legal_offset_in_bytes()), false otherwise.
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -1695,6 +1695,24 @@ } } +bool CMSCollector::is_external_interruption() { + GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause(); + return GCCause::is_user_requested_gc(cause) || + GCCause::is_serviceability_requested_gc(cause); +} + +void CMSCollector::report_concurrent_mode_interruption() { + if (is_external_interruption()) { + if (PrintGCDetails) { + gclog_or_tty->print(" (concurrent mode interrupted)"); + } + } else { + if (PrintGCDetails) { + gclog_or_tty->print(" (concurrent mode failure)"); + } + _gc_tracer_cm->report_concurrent_mode_failure(); + } +} // The foreground and background collectors need to coordinate in order // to make sure that they do not mutually interfere with CMS collections. @@ -1852,14 +1870,8 @@ } ) - if (PrintGCDetails && first_state > Idling) { - GCCause::Cause cause = GenCollectedHeap::heap()->gc_cause(); - if (GCCause::is_user_requested_gc(cause) || - GCCause::is_serviceability_requested_gc(cause)) { - gclog_or_tty->print(" (concurrent mode interrupted)"); - } else { - gclog_or_tty->print(" (concurrent mode failure)"); - } + if (first_state > Idling) { + report_concurrent_mode_interruption(); } if (should_compact) { @@ -2359,6 +2371,7 @@ CMSTokenSync z(true); // not strictly needed. if (_collectorState == Resizing) { compute_new_size(); + save_heap_summary(); _collectorState = Resetting; } else { assert(_collectorState == Idling, "The state should only change" @@ -2418,16 +2431,31 @@ _cms_start_registered = true; _gc_timer_cm->register_gc_start(os::elapsed_counter()); _gc_tracer_cm->report_gc_start(cause, _gc_timer_cm->gc_start()); + + save_heap_summary(); + report_heap_summary(GCWhen::BeforeGC); } void CMSCollector::register_gc_end() { if (_cms_start_registered) { + report_heap_summary(GCWhen::AfterGC); + _gc_timer_cm->register_gc_end(os::elapsed_counter()); _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); _cms_start_registered = false; } } +void CMSCollector::save_heap_summary() { + GenCollectedHeap* gch = GenCollectedHeap::heap(); + _last_heap_summary = gch->create_heap_summary(); + _last_perm_gen_summary = gch->create_perm_gen_summary(); +} + +void CMSCollector::report_heap_summary(GCWhen::Type when) { + _gc_tracer_cm->report_gc_heap_summary(when, _last_heap_summary, _last_perm_gen_summary); +} + void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) { assert(_foregroundGCIsActive && !_foregroundGCShouldWait, "Foreground collector should be waiting, not executing"); @@ -2514,6 +2542,7 @@ gclog_or_tty->print("Verify before reset: "); Universe::verify(); } + save_heap_summary(); reset(false); assert(_collectorState == Idling, "Collector state should " "have changed");
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -25,8 +25,10 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP +#include "gc_implementation/shared/gcHeapSummary.hpp" #include "gc_implementation/shared/gSpaceCounters.hpp" #include "gc_implementation/shared/gcStats.hpp" +#include "gc_implementation/shared/gcWhen.hpp" #include "gc_implementation/shared/generationCounters.hpp" #include "memory/freeBlockDictionary.hpp" #include "memory/generation.hpp" @@ -615,8 +617,14 @@ ConcurrentGCTimer* _gc_timer_cm; bool _cms_start_registered; + + GCHeapSummary _last_heap_summary; + PermGenSummary _last_perm_gen_summary; + void register_gc_start(GCCause::Cause cause); void register_gc_end(); + void save_heap_summary(); + void report_heap_summary(GCWhen::Type when); protected: ConcurrentMarkSweepGeneration* _cmsGen; // old gen (CMS) @@ -842,6 +850,10 @@ void do_mark_sweep_work(bool clear_all_soft_refs, CollectorState first_state, bool should_start_over); + // Work methods for reporting concurrent mode interruption or failure + bool is_external_interruption(); + void report_concurrent_mode_interruption(); + // If the backgrould GC is active, acquire control from the background // GC and do the collection. void acquire_control_and_collect(bool full, bool clear_all_soft_refs);
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -195,6 +195,7 @@ VM_CMS_Operation::verify_after_gc(); + _collector->save_heap_summary(); _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter()); #ifndef USDT2
--- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -373,6 +373,8 @@ " does not exceed used.end() = " PTR_FORMAT "," " yet last_chunk_index_to_check " INTPTR_FORMAT " exceeds last_chunk_index " INTPTR_FORMAT, + last_block, last_block + last_block_size, + used.end(), last_chunk_index_to_check, last_chunk_index)); assert(sp->used_region().end() > used.end(), err_msg("Expansion did not happen: "
--- a/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/gcHeapSummary.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -32,6 +32,8 @@ HeapWord* _committed_end; HeapWord* _reserved_end; public: + VirtualSpaceSummary() : + _start(NULL), _committed_end(NULL), _reserved_end(NULL) { } VirtualSpaceSummary(HeapWord* start, HeapWord* committed_end, HeapWord* reserved_end) : _start(start), _committed_end(committed_end), _reserved_end(reserved_end) { } @@ -47,6 +49,8 @@ HeapWord* _end; size_t _used; public: + SpaceSummary() : + _start(NULL), _end(NULL), _used(0) { } SpaceSummary(HeapWord* start, HeapWord* end, size_t used) : _start(start), _end(end), _used(used) { } @@ -70,6 +74,8 @@ size_t _used; public: + GCHeapSummary() : + _heap(), _used(0) { } GCHeapSummary(VirtualSpaceSummary& heap_space, size_t used) : _heap(heap_space), _used(used) { } @@ -108,6 +114,8 @@ SpaceSummary _object_space; public: + PermGenSummary() : + _perm_space(), _object_space() { } PermGenSummary(const VirtualSpaceSummary& perm_space, const SpaceSummary& object_space) : _perm_space(perm_space), _object_space(object_space) { }
--- a/src/share/vm/gc_implementation/shared/gcTrace.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -126,6 +126,12 @@ _parallel_old_gc_info.report_dense_prefix(dense_prefix); } +void CMSTracer::report_concurrent_mode_failure() { + assert_set_gc_id(); + + send_concurrent_mode_failure_event(); +} + #ifndef SERIALGC void G1NewTracer::report_yc_type(G1YCType type) { assert_set_gc_id();
--- a/src/share/vm/gc_implementation/shared/gcTrace.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -211,6 +211,11 @@ class CMSTracer : public OldGCTracer { public: CMSTracer() : OldGCTracer(ConcurrentMarkSweep) {} + + void report_concurrent_mode_failure(); + + private: + void send_concurrent_mode_failure_event(); }; class G1OldTracer : public OldGCTracer {
--- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -111,6 +111,14 @@ } } +void CMSTracer::send_concurrent_mode_failure_event() { + EventConcurrentModeFailure e; + if (e.should_commit()) { + e.set_gcId(_shared_gc_info.id()); + e.commit(); + } +} + #ifndef SERIALGC void G1NewTracer::send_g1_young_gc_event() { EventGCG1GarbageCollection e(UNTIMED);
--- a/src/share/vm/memory/cardTableModRefBS.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/memory/cardTableModRefBS.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -693,7 +693,7 @@ if (failed) { if (!failures) { tty->cr(); - tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]"); + tty->print_cr("== CT verification failed: ["PTR_FORMAT","PTR_FORMAT"]", start, end); tty->print_cr("== %sexpecting value: %d", (val_equals) ? "" : "not ", val); failures = true;
--- a/src/share/vm/memory/cardTableRS.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/memory/cardTableRS.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -369,7 +369,7 @@ assert(jp >= _begin && jp < _end, err_msg("Error: jp " PTR_FORMAT " should be within " "[_begin, _end) = [" PTR_FORMAT "," PTR_FORMAT ")", - _begin, _end)); + jp, _begin, _end)); oop obj = oopDesc::load_decode_heap_oop(p); guarantee(obj == NULL || (HeapWord*)obj >= _boundary, err_msg("pointer " PTR_FORMAT " at " PTR_FORMAT " on "
--- a/src/share/vm/memory/heapInspection.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/memory/heapInspection.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -87,7 +87,7 @@ } elt = elt->next(); } - elt = new KlassInfoEntry(k, list()); + elt = new (std::nothrow) KlassInfoEntry(k, list()); // We may be out of space to allocate the new entry. if (elt != NULL) { set_list(elt); @@ -113,12 +113,12 @@ } } -KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) { +KlassInfoTable::KlassInfoTable(HeapWord* ref) { _size = 0; _ref = ref; - _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal); + _buckets = (KlassInfoBucket *) os::malloc(sizeof(KlassInfoBucket) * _num_buckets, mtInternal); if (_buckets != NULL) { - _size = size; + _size = _num_buckets; for (int index = 0; index < _size; index++) { _buckets[index].initialize(); } @@ -177,9 +177,9 @@ return (*e1)->compare(*e1,*e2); } -KlassInfoHisto::KlassInfoHisto(const char* title, int estimatedCount) : +KlassInfoHisto::KlassInfoHisto(const char* title) : _title(title) { - _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true); + _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(_histo_initial_size, true); } KlassInfoHisto::~KlassInfoHisto() { @@ -228,82 +228,104 @@ private: KlassInfoTable* _cit; size_t _missed_count; + BoolObjectClosure* _filter; public: - RecordInstanceClosure(KlassInfoTable* cit) : - _cit(cit), _missed_count(0) {} + RecordInstanceClosure(KlassInfoTable* cit, BoolObjectClosure* filter) : + _cit(cit), _missed_count(0), _filter(filter) {} void do_object(oop obj) { - if (!_cit->record_instance(obj)) { - _missed_count++; + if (should_visit(obj)) { + if (!_cit->record_instance(obj)) { + _missed_count++; + } } } size_t missed_count() { return _missed_count; } + private: + bool should_visit(oop obj) { + return _filter == NULL || _filter->do_object_b(obj); + } }; +HeapWord* HeapInspection::start_of_perm_gen() { + if (is_shared_heap()) { + SharedHeap* sh = SharedHeap::heap(); + return sh->perm_gen()->used_region().start(); + } +#ifndef SERIALGC + ParallelScavengeHeap* psh = (ParallelScavengeHeap*)Universe::heap(); + return psh->perm_gen()->object_space()->used_region().start(); +#else + ShouldNotReachHere(); + return NULL; +#endif // SERIALGC +} + +bool HeapInspection::is_shared_heap() { + CollectedHeap* heap = Universe::heap(); + return heap->kind() == CollectedHeap::G1CollectedHeap || + heap->kind() == CollectedHeap::GenCollectedHeap; +} + +void HeapInspection::prologue() { + if (is_shared_heap()) { + SharedHeap* sh = SharedHeap::heap(); + sh->gc_prologue(false /* !full */); // get any necessary locks, etc. + } +} + +void HeapInspection::epilogue() { + if (is_shared_heap()) { + SharedHeap* sh = SharedHeap::heap(); + sh->gc_epilogue(false /* !full */); // release all acquired locks, etc. + } +} + +size_t HeapInspection::instance_inspection(KlassInfoTable* cit, + KlassInfoClosure* cl, + bool need_prologue, + BoolObjectClosure* filter) { + ResourceMark rm; + + if (need_prologue) { + prologue(); + } + + RecordInstanceClosure ric(cit, filter); + Universe::heap()->object_iterate(&ric); + cit->iterate(cl); + + // need to run epilogue if we run prologue + if (need_prologue) { + epilogue(); + } + + return ric.missed_count(); +} + void HeapInspection::heap_inspection(outputStream* st, bool need_prologue) { ResourceMark rm; - HeapWord* ref; - CollectedHeap* heap = Universe::heap(); - bool is_shared_heap = false; - switch (heap->kind()) { - case CollectedHeap::G1CollectedHeap: - case CollectedHeap::GenCollectedHeap: { - is_shared_heap = true; - SharedHeap* sh = (SharedHeap*)heap; - if (need_prologue) { - sh->gc_prologue(false /* !full */); // get any necessary locks, etc. - } - ref = sh->perm_gen()->used_region().start(); - break; - } -#ifndef SERIALGC - case CollectedHeap::ParallelScavengeHeap: { - ParallelScavengeHeap* psh = (ParallelScavengeHeap*)heap; - ref = psh->perm_gen()->object_space()->used_region().start(); - break; - } -#endif // SERIALGC - default: - ShouldNotReachHere(); // Unexpected heap kind for this op - } - // Collect klass instance info - KlassInfoTable cit(KlassInfoTable::cit_size, ref); + KlassInfoTable cit(start_of_perm_gen()); if (!cit.allocation_failed()) { - // Iterate over objects in the heap - RecordInstanceClosure ric(&cit); - // If this operation encounters a bad object when using CMS, - // consider using safe_object_iterate() which avoids perm gen - // objects that may contain bad references. - Universe::heap()->object_iterate(&ric); + KlassInfoHisto histo("\n" + " num #instances #bytes class name\n" + "----------------------------------------------"); + HistoClosure hc(&histo); - // Report if certain classes are not counted because of - // running out of C-heap for the histogram. - size_t missed_count = ric.missed_count(); + size_t missed_count = instance_inspection(&cit, &hc, need_prologue); if (missed_count != 0) { st->print_cr("WARNING: Ran out of C-heap; undercounted " SIZE_FORMAT " total instances in data below", missed_count); } - // Sort and print klass instance info - KlassInfoHisto histo("\n" - " num #instances #bytes class name\n" - "----------------------------------------------", - KlassInfoHisto::histo_initial_size); - HistoClosure hc(&histo); - cit.iterate(&hc); histo.sort(); histo.print_on(st); } else { st->print_cr("WARNING: Ran out of C-heap; histogram not generated"); } st->flush(); - - if (need_prologue && is_shared_heap) { - SharedHeap* sh = (SharedHeap*)heap; - sh->gc_epilogue(false /* !full */); // release all acquired locks, etc. - } } class FindInstanceClosure : public ObjectClosure {
--- a/src/share/vm/memory/heapInspection.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/memory/heapInspection.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -85,6 +85,7 @@ class KlassInfoTable: public StackObj { private: int _size; + static const int _num_buckets = 20011; // An aligned reference address (typically the least // address in the perm gen) used for hashing klass @@ -96,11 +97,7 @@ KlassInfoEntry* lookup(const klassOop k); public: - // Table size - enum { - cit_size = 20011 - }; - KlassInfoTable(int size, HeapWord* ref); + KlassInfoTable(HeapWord* ref); ~KlassInfoTable(); bool record_instance(const oop obj); void iterate(KlassInfoClosure* cic); @@ -115,12 +112,9 @@ const char* title() const { return _title; } static int sort_helper(KlassInfoEntry** e1, KlassInfoEntry** e2); void print_elements(outputStream* st) const; + static const int _histo_initial_size = 1000; public: - enum { - histo_initial_size = 1000 - }; - KlassInfoHisto(const char* title, - int estimatedCount); + KlassInfoHisto(const char* title); ~KlassInfoHisto(); void add(KlassInfoEntry* cie); void print_on(outputStream* st) const; @@ -131,7 +125,16 @@ class HeapInspection : public AllStatic { public: static void heap_inspection(outputStream* st, bool need_prologue); + static size_t instance_inspection(KlassInfoTable* cit, + KlassInfoClosure* cl, + bool need_prologue, + BoolObjectClosure* filter = NULL); + static HeapWord* start_of_perm_gen(); static void find_instances_at_safepoint(klassOop k, GrowableArray<oop>* result); + private: + static bool is_shared_heap(); + static void prologue(); + static void epilogue(); }; #endif // SHARE_VM_MEMORY_HEAPINSPECTION_HPP
--- a/src/share/vm/opto/compile.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/opto/compile.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -2892,6 +2892,13 @@ } } break; + case Op_MemBarStoreStore: + // Break the link with AllocateNode: it is no longer useful and + // confuses register allocation. + if (n->req() > MemBarNode::Precedent) { + n->set_req(MemBarNode::Precedent, top()); + } + break; default: assert( !n->is_Call(), "" ); assert( !n->is_Mem(), "" );
--- a/src/share/vm/opto/graphKit.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/opto/graphKit.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -3445,7 +3445,6 @@ void GraphKit::final_sync(IdealKit& ideal) { // Final sync IdealKit and graphKit. - __ drain_delay_transform(); sync_kit(ideal); }
--- a/src/share/vm/opto/idealKit.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/opto/idealKit.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -48,9 +48,9 @@ _cvstate = NULL; // We can go memory state free or else we need the entire memory state assert(_initial_memory == NULL || _initial_memory->Opcode() == Op_MergeMem, "memory must be pre-split"); + assert(!_gvn.is_IterGVN(), "IdealKit can't be used during Optimize phase"); int init_size = 5; _pending_cvstates = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0); - _delay_transform = new (C->node_arena()) GrowableArray<Node*>(C->node_arena(), init_size, 0, 0); DEBUG_ONLY(_state = new (C->node_arena()) GrowableArray<int>(C->node_arena(), init_size, 0, 0)); if (!has_declarations) { declarations_done(); @@ -296,19 +296,16 @@ return delay_transform(n); } else { n = gvn().transform(n); - if (!gvn().is_IterGVN()) { - C->record_for_igvn(n); - } + C->record_for_igvn(n); return n; } } //-----------------------------delay_transform----------------------------------- Node* IdealKit::delay_transform(Node* n) { - if (!gvn().is_IterGVN() || !gvn().is_IterGVN()->delay_transform()) { - gvn().set_type(n, n->bottom_type()); - } - _delay_transform->push(n); + // Delay transform until IterativeGVN + gvn().set_type(n, n->bottom_type()); + C->record_for_igvn(n); return n; } @@ -332,17 +329,6 @@ for (uint i = 0; i < m->req(); i++) m->set_req(i, NULL); } -//-----------------------------drain_delay_transform---------------------------- -void IdealKit::drain_delay_transform() { - while (_delay_transform->length() > 0) { - Node* n = _delay_transform->pop(); - gvn().transform(n); - if (!gvn().is_IterGVN()) { - C->record_for_igvn(n); - } - } -} - //-----------------------------IdealVariable---------------------------- IdealVariable::IdealVariable(IdealKit &k) { k.declare(this); @@ -351,9 +337,7 @@ Node* IdealKit::memory(uint alias_idx) { MergeMemNode* mem = merged_memory(); Node* p = mem->memory_at(alias_idx); - if (!gvn().is_IterGVN() || !gvn().is_IterGVN()->delay_transform()) { - _gvn.set_type(p, Type::MEMORY); // must be mapped - } + _gvn.set_type(p, Type::MEMORY); // must be mapped return p; }
--- a/src/share/vm/opto/idealKit.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/opto/idealKit.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -102,7 +102,6 @@ Compile * const C; PhaseGVN &_gvn; GrowableArray<Node*>* _pending_cvstates; // stack of cvstates - GrowableArray<Node*>* _delay_transform; // delay invoking gvn.transform until drain Node* _cvstate; // current cvstate (control, memory and variables) uint _var_ct; // number of variables bool _delay_all_transforms; // flag forcing all transforms to be delayed @@ -121,7 +120,7 @@ void clear(Node* m); // clear a cvstate void stop() { clear(_cvstate); } // clear current cvstate Node* delay_transform(Node* n); - Node* transform(Node* n); // gvn.transform or push node on delay list + Node* transform(Node* n); // gvn.transform or skip it Node* promote_to_phi(Node* n, Node* reg);// Promote "n" to a phi on region "reg" bool was_promoted_to_phi(Node* n, Node* reg) { return (n->is_Phi() && n->in(0) == reg); @@ -146,7 +145,6 @@ IdealKit(GraphKit* gkit, bool delay_all_transforms = false, bool has_declarations = false); ~IdealKit() { stop(); - drain_delay_transform(); } void sync_kit(GraphKit* gkit); @@ -173,7 +171,6 @@ void bind(Node* lab); void goto_(Node* lab, bool bind = false); void declarations_done(); - void drain_delay_transform(); Node* IfTrue(IfNode* iff) { return transform(new (C) IfTrueNode(iff)); } Node* IfFalse(IfNode* iff) { return transform(new (C) IfFalseNode(iff)); } @@ -198,7 +195,11 @@ Node* thread() { return gvn().transform(new (C) ThreadLocalNode()); } // Pointers - Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C) AddPNode(base, ptr, off)); } + + // Raw address should be transformed regardless 'delay_transform' flag + // to produce canonical form CastX2P(offset). + Node* AddP(Node *base, Node *ptr, Node *off) { return _gvn.transform(new (C) AddPNode(base, ptr, off)); } + Node* CmpP(Node* l, Node* r) { return transform(new (C) CmpPNode(l, r)); } #ifdef _LP64 Node* XorX(Node* l, Node* r) { return transform(new (C) XorLNode(l, r)); } @@ -208,8 +209,6 @@ Node* URShiftX(Node* l, Node* r) { return transform(new (C) URShiftXNode(l, r)); } Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); } Node* CastPX(Node* ctl, Node* p) { return transform(new (C) CastP2XNode(ctl, p)); } - // Add a fixed offset to a pointer - Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset); // Memory operations
--- a/src/share/vm/opto/loopnode.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/opto/loopnode.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -2251,6 +2251,11 @@ return; } + // clear out the dead code after build_loop_late + while (_deadlist.size()) { + _igvn.remove_globally_dead_node(_deadlist.pop()); + } + if (stop_early) { assert(do_expensive_nodes, "why are we here?"); if (process_expensive_nodes()) { @@ -2260,9 +2265,7 @@ // nodes again. C->set_major_progress(); } - _igvn.optimize(); - return; } @@ -2273,11 +2276,6 @@ eliminate_useless_predicates(); } - // clear out the dead code - while(_deadlist.size()) { - _igvn.remove_globally_dead_node(_deadlist.pop()); - } - #ifndef PRODUCT C->verify_graph_edges(); if (_verify_me) { // Nested verify pass?
--- a/src/share/vm/opto/macro.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/opto/macro.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -1094,12 +1094,6 @@ Node* klass_node = alloc->in(AllocateNode::KlassNode); Node* initial_slow_test = alloc->in(AllocateNode::InitialTest); - Node* storestore = alloc->storestore(); - if (storestore != NULL) { - // Break this link that is no longer useful and confuses register allocation - storestore->set_req(MemBarNode::Precedent, top()); - } - assert(ctrl != NULL, "must have control"); // We need a Region and corresponding Phi's to merge the slow-path and fast-path results. // they will not be used if "always_slow" is set @@ -1317,7 +1311,7 @@ // No InitializeNode or no stores captured by zeroing // elimination. Simply add the MemBarStoreStore after object // initialization. - MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot, fast_oop_rawmem); + MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot); transform_later(mb); mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
--- a/src/share/vm/opto/phaseX.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/opto/phaseX.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -1166,31 +1166,30 @@ if (progress_state == PROCESS_INPUTS) { // After following inputs, continue to outputs _stack.set_index(PROCESS_OUTPUTS); - // Remove from iterative worklist - _worklist.remove(dead); if (!dead->is_Con()) { // Don't kill cons but uses bool recurse = false; // Remove from hash table _table.hash_delete( dead ); // Smash all inputs to 'dead', isolating him completely - for( uint i = 0; i < dead->req(); i++ ) { + for (uint i = 0; i < dead->req(); i++) { Node *in = dead->in(i); - if( in ) { // Points to something? - dead->set_req(i,NULL); // Kill the edge - if (in->outcnt() == 0 && in != C->top()) {// Made input go dead? + if (in != NULL && in != C->top()) { // Points to something? + int nrep = dead->replace_edge(in, NULL); // Kill edges + assert((nrep > 0), "sanity"); + if (in->outcnt() == 0) { // Made input go dead? _stack.push(in, PROCESS_INPUTS); // Recursively remove recurse = true; } else if (in->outcnt() == 1 && in->has_special_unique_user()) { _worklist.push(in->unique_out()); } else if (in->outcnt() <= 2 && dead->is_Phi()) { - if( in->Opcode() == Op_Region ) + if (in->Opcode() == Op_Region) { _worklist.push(in); - else if( in->is_Store() ) { + } else if (in->is_Store()) { DUIterator_Fast imax, i = in->fast_outs(imax); _worklist.push(in->fast_out(i)); i++; - if(in->outcnt() == 2) { + if (in->outcnt() == 2) { _worklist.push(in->fast_out(i)); i++; } @@ -1209,38 +1208,42 @@ } } } - } - } - C->record_dead_node(dead->_idx); - if (dead->is_macro()) { - C->remove_macro_node(dead); - } - if (dead->is_expensive()) { - C->remove_expensive_node(dead); - } - + } // if (in != NULL && in != C->top()) + } // for (uint i = 0; i < dead->req(); i++) if (recurse) { continue; } - } - // Constant node that has no out-edges and has only one in-edge from - // root is usually dead. However, sometimes reshaping walk makes - // it reachable by adding use edges. So, we will NOT count Con nodes - // as dead to be conservative about the dead node count at any - // given time. - } + } // if (!dead->is_Con()) + } // if (progress_state == PROCESS_INPUTS) // Aggressively kill globally dead uses // (Rather than pushing all the outs at once, we push one at a time, // plus the parent to resume later, because of the indefinite number // of edge deletions per loop trip.) if (dead->outcnt() > 0) { - // Recursively remove + // Recursively remove output edges _stack.push(dead->raw_out(0), PROCESS_INPUTS); } else { + // Finished disconnecting all input and output edges. _stack.pop(); + // Remove dead node from iterative worklist + _worklist.remove(dead); + // Constant node that has no out-edges and has only one in-edge from + // root is usually dead. However, sometimes reshaping walk makes + // it reachable by adding use edges. So, we will NOT count Con nodes + // as dead to be conservative about the dead node count at any + // given time. + if (!dead->is_Con()) { + C->record_dead_node(dead->_idx); + } + if (dead->is_macro()) { + C->remove_macro_node(dead); + } + if (dead->is_expensive()) { + C->remove_expensive_node(dead); + } } - } + } // while (_stack.is_nonempty()) } //------------------------------subsume_node-----------------------------------
--- a/src/share/vm/prims/jvmtiEnter.xsl Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/prims/jvmtiEnter.xsl Fri Apr 05 10:32:51 2013 -0700 @@ -770,7 +770,7 @@ </xsl:text> <xsl:apply-templates select=".." mode="traceError"> <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param> - <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = %0x%x</xsl:with-param> + <xsl:with-param name="comment"> - jthread resolved to NULL - jthread = 0x%x</xsl:with-param> <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param> </xsl:apply-templates> <xsl:text> @@ -779,7 +779,7 @@ </xsl:text> <xsl:apply-templates select=".." mode="traceError"> <xsl:with-param name="err">JVMTI_ERROR_INVALID_THREAD</xsl:with-param> - <xsl:with-param name="comment"> - oop is not a thread - jthread = %0x%x</xsl:with-param> + <xsl:with-param name="comment"> - oop is not a thread - jthread = 0x%x</xsl:with-param> <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param> </xsl:apply-templates> <xsl:text> @@ -791,7 +791,7 @@ <xsl:with-param name="err"> <xsl:text>JVMTI_ERROR_THREAD_NOT_ALIVE</xsl:text> </xsl:with-param> - <xsl:with-param name="comment"> - not a Java thread - jthread = %0x%x</xsl:with-param> + <xsl:with-param name="comment"> - not a Java thread - jthread = 0x%x</xsl:with-param> <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param> </xsl:apply-templates> <xsl:text> @@ -835,7 +835,7 @@ </xsl:text> <xsl:apply-templates select=".." mode="traceError"> <xsl:with-param name="err">JVMTI_ERROR_ILLEGAL_ARGUMENT</xsl:with-param> - <xsl:with-param name="comment"> - negative depth - jthread = %0x%x</xsl:with-param> + <xsl:with-param name="comment"> - negative depth - jthread = 0x%x</xsl:with-param> <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param> </xsl:apply-templates> <xsl:text>
--- a/src/share/vm/runtime/thread.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/runtime/thread.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, 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 @@ -1274,6 +1274,7 @@ void enable_stack_red_zone(); void disable_stack_red_zone(); + inline bool stack_guard_zone_unused(); inline bool stack_yellow_zone_disabled(); inline bool stack_yellow_zone_enabled(); @@ -1741,6 +1742,10 @@ return (CompilerThread*)this; } +inline bool JavaThread::stack_guard_zone_unused() { + return _stack_guard_state == stack_guard_unused; +} + inline bool JavaThread::stack_yellow_zone_disabled() { return _stack_guard_state == stack_guard_yellow_disabled; }
--- a/src/share/vm/runtime/vm_operations.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/runtime/vm_operations.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -95,6 +95,7 @@ template(ReportJavaOutOfMemory) \ template(JFRCheckpoint) \ template(Exit) \ + template(LinuxDllLoad) \ class VM_Operation: public CHeapObj<mtInternal> { public:
--- a/src/share/vm/services/memReporter.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/services/memReporter.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -419,7 +419,7 @@ _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); _output->print("%28s", " "); } else { - _output->print("[" PTR_FORMAT "]%18s", " "); + _output->print("[" PTR_FORMAT "]%18s", pc, " "); } _output->print_cr("(mmap: reserved=%d%s, committed=%d%s)", @@ -596,7 +596,7 @@ _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset); _output->print("%28s", " "); } else { - _output->print("[" PTR_FORMAT "]%18s", " "); + _output->print("[" PTR_FORMAT "]%18s", pc, " "); } }
--- a/src/share/vm/trace/trace.xml Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/trace/trace.xml Fri Apr 05 10:32:51 2013 -0700 @@ -203,6 +203,11 @@ <structvalue type="CopyFailed" field="data" label="data"/> </event> + <event id="ConcurrentModeFailure" path="vm/gc/detailed/concurrent_mode_failure" label="Concurrent Mode Failure" + is_instant="true" description="Concurrent Mode failed"> + <value type="ULONG" field="gcId" label="GC ID" relation="GC_ID"/> + </event> + <event id="GCPhasePause" path="vm/gc/phases/pause" label="GC Phase Pause"> <value type="ULONG" field="gcId" label="GC ID" relation="GC_ID"/> <value type="UTF8" field="name" label="Name" />
--- a/src/share/vm/utilities/elfFile.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/utilities/elfFile.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -197,4 +197,28 @@ return NULL; } +#ifdef LINUX +bool ElfFile::specifies_noexecstack() { + Elf_Phdr phdr; + if (!m_file) return true; + + if (!fseek(m_file, m_elfHdr.e_phoff, SEEK_SET)) { + for (int index = 0; index < m_elfHdr.e_phnum; index ++) { + if (fread((void*)&phdr, sizeof(Elf_Phdr), 1, m_file) != 1) { + m_status = NullDecoder::file_invalid; + return false; + } + if (phdr.p_type == PT_GNU_STACK) { + if (phdr.p_flags == (PF_R | PF_W)) { + return true; + } else { + return false; + } + } + } + } + return false; +} +#endif + #endif // _WINDOWS
--- a/src/share/vm/utilities/elfFile.hpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/utilities/elfFile.hpp Fri Apr 05 10:32:51 2013 -0700 @@ -43,6 +43,7 @@ typedef Elf64_Ehdr Elf_Ehdr; typedef Elf64_Shdr Elf_Shdr; +typedef Elf64_Phdr Elf_Phdr; typedef Elf64_Sym Elf_Sym; #if !defined(_ALLBSD_SOURCE) || defined(__APPLE__) @@ -59,6 +60,7 @@ typedef Elf32_Ehdr Elf_Ehdr; typedef Elf32_Shdr Elf_Shdr; +typedef Elf32_Phdr Elf_Phdr; typedef Elf32_Sym Elf_Sym; #if !defined(_ALLBSD_SOURCE) || defined(__APPLE__) @@ -123,6 +125,14 @@ ElfFile* next() const { return m_next; } void set_next(ElfFile* file) { m_next = file; } + public: + // Returns true if the elf file is marked NOT to require an executable stack, + // or if the file could not be opened. + // Returns false if the elf file requires an executable stack, the stack flag + // is not set at all, or if the file can not be read. + // On systems other than linux it always returns false. + bool specifies_noexecstack() NOT_LINUX({ return false; }); + protected: ElfFile* m_next;
--- a/src/share/vm/utilities/numberSeq.cpp Fri Apr 05 09:10:28 2013 -0700 +++ b/src/share/vm/utilities/numberSeq.cpp Fri Apr 05 10:32:51 2013 -0700 @@ -245,7 +245,7 @@ void NumberSeq::dump_on(outputStream* s) { AbsSeq::dump_on(s); - s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f"); + s->print_cr("\t\t _last = %7.3f, _maximum = %7.3f", _last, _maximum); } void TruncatedSeq::dump_on(outputStream* s) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/gc/heap_inspection/TestPrintClassHistogram.java Fri Apr 05 10:32:51 2013 -0700 @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2013, 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 TestPrintClassHistogram + * @bug 8010294 + * @summary Checks that a class histogram can be printed both before and after + * a GC + * @library /testlibrary + * @run main/othervm TestPrintClassHistogram launch BeforeGC + * @run main/othervm TestPrintClassHistogram launch AfterGC + * @run main/othervm TestPrintClassHistogram launch BeforeGC AfterGC + */ + +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +/* This test uses a "trick" to be able to analyze the output of the test: + * + * The test starts a java process that runs the same code, but the first + * argument is different ("run" instead of "launch"). The change of flags + * will run the test code instead of launching the test again. + */ +public class TestPrintClassHistogram { + public static void main(String[] args) throws Exception { + if (shouldLaunchTest(args)) { + launchTest(args); + return; + } + + // This is the actual test code + System.gc(); + } + + private static boolean shouldLaunchTest(String[] cmdlineArguments) { + return cmdlineArguments[0].equals("launch"); + } + + private static void launchTest(String[] args) throws Exception { + String[] testArgs = createTestArguments(args); + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(testArgs); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldNotContain("WARNING"); + + // There will always be at least one java.lang.Class instance + output.shouldContain("java.lang.Class"); + + // There will always be at least one java.lang.String instance + output.shouldContain("java.lang.String"); + + output.shouldHaveExitValue(0); + } + + private static String[] createTestArguments(String[] cmdlineArguments) { + List<String> cmdlineArgs = Arrays.asList(cmdlineArguments); + List<String> testArgs = new ArrayList<String>(); + + if (cmdlineArgs.contains("BeforeGC")) { + testArgs.add("-XX:+PrintClassHistogramBeforeFullGC"); + } + if (cmdlineArgs.contains("AfterGC")) { + testArgs.add("-XX:+PrintClassHistogramAfterFullGC"); + } + + testArgs.add("TestPrintClassHistogram"); + testArgs.add("run"); + + return testArgs.toArray(new String[testArgs.size()]); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/7107135/Test.java Fri Apr 05 10:32:51 2013 -0700 @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 SAP AG. 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. + */ + +class Test { + + static boolean loadLib(String libName){ + try { + System.loadLibrary(libName); + System.out.println("Loaded library "+ libName + "."); + return true; + } catch (SecurityException e) { + System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n"); + } catch (UnsatisfiedLinkError e) { + System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n"); + } + return false; + } + + public static int counter = 1; + + static int Runner() { + counter = counter * -1; + int i = counter; + if(counter < 2) counter += Runner(); + return i; + } + + public static int run() { + try{ + Runner(); + } catch (StackOverflowError e) { + System.out.println("Caught stack overflow error."); + return 0; + } catch (OutOfMemoryError e) { + return 0; + } + return 2; + } + + public static void main(String argv[]) { + loadLib(argv[0]); + System.exit(run()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/7107135/Test7107135.sh Fri Apr 05 10:32:51 2013 -0700 @@ -0,0 +1,98 @@ +#!/bin/sh + +# +# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011 SAP AG. 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 Test7107135.sh +## @bug 7107135 +## @summary Stack guard pages lost after loading library with executable stack. +## @run shell Test7107135.sh +## + +if [ "${TESTSRC}" = "" ] +then TESTSRC=. +fi + +if [ "${TESTJAVA}" = "" ] +then + PARENT=`dirname \`which java\`` + TESTJAVA=`dirname ${PARENT}` + echo "TESTJAVA not set, selecting " ${TESTJAVA} + echo "If this is incorrect, try setting the variable manually." +fi + +BIT_FLAG="" + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + Linux) + NULL=/dev/null + PS=":" + FS="/" + ;; + *) + NULL=NUL + PS=";" + FS="\\" + echo "Test passed; only valid for Linux" + exit 0; + ;; +esac + +ARCH=`uname -m` + +THIS_DIR=`pwd` + +cp ${TESTSRC}${FS}*.java ${THIS_DIR} +${TESTJAVA}${FS}bin${FS}javac *.java + +gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c +ld -shared -z execstack -o libtest-rwx.so test.o +ld -shared -z noexecstack -o libtest-rw.so test.o + + +LD_LIBRARY_PATH=${THIS_DIR} +echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH} +export LD_LIBRARY_PATH + +# This should not fail. +echo Check testprogram. Expected to pass: +echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw +${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw + +echo +echo Test changing of stack protection: +echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw +${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx + +if [ "$?" == "0" ] +then + echo + echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx + ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx +fi + +exit $?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/7107135/TestMT.java Fri Apr 05 10:32:51 2013 -0700 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 SAP AG. 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. + */ + +class TestMT { + + static boolean loadLib(String libName) { + try { + System.loadLibrary(libName); + System.out.println("Loaded library "+ libName + "."); + return true; + } catch (SecurityException e) { + System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n"); + } catch (UnsatisfiedLinkError e) { + System.out.println("loadLibrary(\"" + libName + "\") throws: " + e + "\n"); + } + return false; + } + + public static int counter = 1; + static int Runner() { + counter = counter * -1; + int i = counter; + if (counter < 2) counter += Runner(); + return i; + } + + public static int run(String msg) { + try { + Runner(); + } catch (StackOverflowError e) { + System.out.println(msg + " caught stack overflow error."); + return 0; + } catch (OutOfMemoryError e) { + return 0; + } + return 2; + } + + public static void main(String argv[]) { + try { + for (int i = 0; i < 20; i++) { + Thread t = new DoStackOverflow("SpawnedThread " + i); + t.start(); + } + run("Main thread"); + loadLib("test-rwx"); + run("Main thread"); + } catch (Exception e) { + System.out.println(e); + } + } + + static class DoStackOverflow extends Thread { + public DoStackOverflow(String name) { + super(name); + } + public void run() { + for (int i = 0; i < 10; ++i) { + TestMT.run(getName()); + yield(); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/7107135/test.c Fri Apr 05 10:32:51 2013 -0700 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2002-2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 SAP AG. 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. + */ + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include "jni.h" +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT jint JNICALL Java_Test_someMethod(JNIEnv *env, jobject mainObject) { + return 3; +} + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/8010389/VMThreadDlopen.java Fri Apr 05 10:32:51 2013 -0700 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2013, 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. + */ + +import java.io.File; + +/* + * @test + * @key regression + * @bug 8010389 + * @run main/othervm -Djava.library.path=. VMThreadDlopen + */ + +public class VMThreadDlopen { + public static void main(String[] args) throws Exception { + File file = new File("libbroken.so"); + file.createNewFile(); + try { + System.loadLibrary("broken"); + } catch (UnsatisfiedLinkError e) { + e.printStackTrace(); + // expected + } + } +}