# HG changeset patch # User rbackman # Date 1376897609 -7200 # Node ID 6725044c57252cb48a96e87239e04ad924a90fe6 # Parent 37165c3618a3e05a73e68a8c84fcda6288fa2aeb# Parent 4b2838704fd5bead351bb4b8ee6876fb84aa89fc Merge diff -r 4b2838704fd5 -r 6725044c5725 .hgtags --- a/.hgtags Fri Aug 16 14:11:40 2013 -0700 +++ b/.hgtags Mon Aug 19 09:33:29 2013 +0200 @@ -367,3 +367,5 @@ 530fe88b3b2c710f42810b3580d86a0d83ad6c1c hs25-b44 c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102 7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45 +6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103 +580430d131ccd475e2f2ad4006531b8c4813d102 hs25-b46 diff -r 4b2838704fd5 -r 6725044c5725 make/hotspot_version --- a/make/hotspot_version Fri Aug 16 14:11:40 2013 -0700 +++ b/make/hotspot_version Mon Aug 19 09:33:29 2013 +0200 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=46 +HS_BUILD_NUMBER=47 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r 4b2838704fd5 -r 6725044c5725 make/solaris/makefiles/dtrace.make --- a/make/solaris/makefiles/dtrace.make Fri Aug 16 14:11:40 2013 -0700 +++ b/make/solaris/makefiles/dtrace.make Mon Aug 19 09:33:29 2013 +0200 @@ -283,9 +283,9 @@ $(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \ $(DTraced_Files) ||\ STATUS=$$?;\ - if [ x"$$STATUS" = x"1" -a \ - x`uname -r` = x"5.10" -a \ - x`uname -p` = x"sparc" ]; then\ + if [ x"$$STATUS" = x"1" ]; then \ + if [ x`uname -r` = x"5.10" -a \ + x`uname -p` = x"sparc" ]; then\ echo "*****************************************************************";\ echo "* If you are building server compiler, and the error message is ";\ echo "* \"incorrect ELF machine type...\", you have run into solaris bug ";\ @@ -294,6 +294,20 @@ echo "* environment variable HOTSPOT_DISABLE_DTRACE_PROBES to disable ";\ echo "* dtrace probes for this build.";\ echo "*****************************************************************";\ + elif [ x`uname -r` = x"5.10" ]; then\ + echo "*****************************************************************";\ + echo "* If you are seeing 'syntax error near \"umpiconninfo_t\"' on Solaris";\ + echo "* 10, try doing 'cd /usr/lib/dtrace && gzip mpi.d' as root, ";\ + echo "* or set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\ + echo "* to disable dtrace probes for this build.";\ + echo "*****************************************************************";\ + else \ + echo "*****************************************************************";\ + echo "* If you cannot fix dtrace build issues, try to ";\ + echo "* set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\ + echo "* to disable dtrace probes for this build.";\ + echo "*****************************************************************";\ + fi; \ fi;\ exit $$STATUS # Since some DTraced_Files are in LIBJVM.o and they are touched by this diff -r 4b2838704fd5 -r 6725044c5725 make/windows/create.bat --- a/make/windows/create.bat Fri Aug 16 14:11:40 2013 -0700 +++ b/make/windows/create.bat Mon Aug 19 09:33:29 2013 +0200 @@ -1,6 +1,6 @@ @echo off REM -REM Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. +REM Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. REM REM This code is free software; you can redistribute it and/or modify it @@ -148,7 +148,7 @@ REM This is now safe to do. :copyfiles -for /D %%i in (compiler1, compiler2, tiered, core) do ( +for /D %%i in (compiler1, compiler2, tiered ) 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) do ( +for /D %%i in (compiler1, compiler2, tiered ) 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 diff -r 4b2838704fd5 -r 6725044c5725 make/windows/create_obj_files.sh --- a/make/windows/create_obj_files.sh Fri Aug 16 14:11:40 2013 -0700 +++ b/make/windows/create_obj_files.sh Mon Aug 19 09:33:29 2013 +0200 @@ -73,19 +73,17 @@ BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles ${GENERATED}/tracefiles" -if [ -d "${ALTSRC}/share/vm/jfr" ]; then - BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr" +if [ -d "${ALTSRC}/share/vm/jfr/buffers" ]; then BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/buffers" fi BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods" -CORE_PATHS="${BASE_PATHS}" # shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS. if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then - CORE_PATHS="${CORE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" + BASE_PATHS="${BASE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" fi -CORE_PATHS="${CORE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" +BASE_PATHS="${BASE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`" if [ -d "${ALTSRC}/share/vm/c1" ]; then COMPILER1_PATHS="${ALTSRC}/share/vm/c1" @@ -104,12 +102,11 @@ # Include dirs per type. case "${TYPE}" in - "core") Src_Dirs="${CORE_PATHS}" ;; - "compiler1") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS}" ;; - "compiler2") Src_Dirs="${CORE_PATHS} ${COMPILER2_PATHS}" ;; - "tiered") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;; - "zero") Src_Dirs="${CORE_PATHS}" ;; - "shark") Src_Dirs="${CORE_PATHS}" ;; + "compiler1") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS}" ;; + "compiler2") Src_Dirs="${BASE_PATHS} ${COMPILER2_PATHS}" ;; + "tiered") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;; + "zero") Src_Dirs="${BASE_PATHS}" ;; + "shark") Src_Dirs="${BASE_PATHS}" ;; esac COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*" @@ -122,7 +119,6 @@ # Exclude per type. case "${TYPE}" in - "core") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;; "compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;; "compiler2") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;; "tiered") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;; @@ -149,9 +145,17 @@ Src_Files="${Src_Files}`findsrc ${e}` " done -Obj_Files= +Obj_Files=" " for e in ${Src_Files}; do - Obj_Files="${Obj_Files}${e%\.[!.]*}.obj " + o="${e%\.[!.]*}.obj" + set +e + chk=`expr "${Obj_Files}" : ".* $o"` + set -e + if [ "$chk" != 0 ]; then + echo "# INFO: skipping duplicate $o" + continue + fi + Obj_Files="${Obj_Files}$o " done echo Obj_Files=${Obj_Files} diff -r 4b2838704fd5 -r 6725044c5725 make/windows/makefiles/projectcreator.make --- a/make/windows/makefiles/projectcreator.make Fri Aug 16 14:11:40 2013 -0700 +++ b/make/windows/makefiles/projectcreator.make Mon Aug 19 09:33:29 2013 +0200 @@ -44,10 +44,11 @@ # This is only used internally ProjectCreatorIncludesPRIVATE=\ - -relativeInclude src\closed\share\vm \ - -relativeInclude src\closed\os\windows\vm \ - -relativeInclude src\closed\os_cpu\windows_$(Platform_arch)\vm \ - -relativeInclude src\closed\cpu\$(Platform_arch)\vm \ + -relativeAltSrcInclude src\closed \ + -altRelativeInclude share\vm \ + -altRelativeInclude os\windows\vm \ + -altRelativeInclude os_cpu\windows_$(Platform_arch)\vm \ + -altRelativeInclude cpu\$(Platform_arch)\vm \ -relativeInclude src\share\vm \ -relativeInclude src\share\vm\precompiled \ -relativeInclude src\share\vm\prims\wbtestmethods \ @@ -91,7 +92,7 @@ -disablePch getThread_windows_$(Platform_arch).cpp \ -disablePch_compiler2 opcodes.cpp -# Common options for the IDE builds for core, c1, and c2 +# Common options for the IDE builds for c1, and c2 ProjectCreatorIDEOptions=\ $(ProjectCreatorIDEOptions) \ -sourceBase $(HOTSPOTWORKSPACE) \ @@ -158,18 +159,10 @@ -ignoreFile_TARGET $(Platform_arch_model).ad ################################################## -# Without compiler(core) specific options -################################################## -ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -$(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=core) \ -$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=core) - -################################################## # Client(C1) compiler specific options ################################################## ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler1 COMPILER1 \ - -ignorePath_compiler1 core \ $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1) ################################################## @@ -178,7 +171,6 @@ #NOTE! This list must be kept in sync with GENERATED_NAMES in adlc.make. ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \ -define_compiler2 COMPILER2 \ - -ignorePath_compiler2 core \ -additionalFile_compiler2 $(Platform_arch_model).ad \ -additionalFile_compiler2 ad_$(Platform_arch_model).cpp \ -additionalFile_compiler2 ad_$(Platform_arch_model).hpp \ diff -r 4b2838704fd5 -r 6725044c5725 make/windows/makefiles/trace.make --- a/make/windows/makefiles/trace.make Fri Aug 16 14:11:40 2013 -0700 +++ b/make/windows/makefiles/trace.make Mon Aug 19 09:33:29 2013 +0200 @@ -90,25 +90,25 @@ !if "$(OPENJDK)" == "true" $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating OpenJDK $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp !else $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp $(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp $(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS) - @echo Generating $@ + @echo Generating AltSrc $@ @$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp !endif diff -r 4b2838704fd5 -r 6725044c5725 make/windows/makefiles/vm.make --- a/make/windows/makefiles/vm.make Fri Aug 16 14:11:40 2013 -0700 +++ b/make/windows/makefiles/vm.make Mon Aug 19 09:33:29 2013 +0200 @@ -36,10 +36,6 @@ CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT" !endif -!if "$(Variant)" == "core" -# No need to define anything, CORE is defined as !COMPILER1 && !COMPILER2 -!endif - !if "$(Variant)" == "compiler1" CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1" !endif diff -r 4b2838704fd5 -r 6725044c5725 make/windows/projectfiles/common/Makefile --- a/make/windows/projectfiles/common/Makefile Fri Aug 16 14:11:40 2013 -0700 +++ b/make/windows/projectfiles/common/Makefile Mon Aug 19 09:33:29 2013 +0200 @@ -112,6 +112,7 @@ ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions) $(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class + @if "$(MSC_VER)"=="1500" echo Make sure you have VS2008 SP1 or later, or you may see 'expanded command line too long' @$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions) clean: diff -r 4b2838704fd5 -r 6725044c5725 src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -1887,6 +1887,27 @@ if (ProfileInterpreter) { __ set_method_data_pointer_for_bcp(); } + +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + + __ ldub(Address(Lbcp, 0), G1_scratch); // Load current bytecode + __ cmp_and_br_short(G1_scratch, Bytecodes::_invokestatic, Assembler::notEqual, Assembler::pn, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ call_VM(G1_scratch, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), I0, Lmethod, Lbcp); + + __ br_null(G1_scratch, false, Assembler::pn, L_done); + __ delayed()->nop(); + + __ st_ptr(G1_scratch, Lesp, wordSize); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + // Resume bytecode interpretation at the current bcp __ dispatch_next(vtos); // end of JVMTI PopFrame support diff -r 4b2838704fd5 -r 6725044c5725 src/cpu/x86/vm/templateInterpreter_x86_32.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -1920,6 +1920,29 @@ __ get_thread(thread); __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + const Register local0 = rdi; + + __ cmpb(Address(rsi, 0), Bytecodes::_invokestatic); + __ jcc(Assembler::notEqual, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ get_method(rdx); + __ movptr(rax, Address(local0, 0)); + __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, rsi); + + __ testptr(rax, rax); + __ jcc(Assembler::zero, L_done); + + __ movptr(Address(rbx, 0), rax); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + __ dispatch_next(vtos); // end of PopFrame support diff -r 4b2838704fd5 -r 6725044c5725 src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -1933,6 +1933,29 @@ __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive); +#if INCLUDE_JVMTI + if (EnableInvokeDynamic) { + Label L_done; + const Register local0 = r14; + + __ cmpb(Address(r13, 0), Bytecodes::_invokestatic); + __ jcc(Assembler::notEqual, L_done); + + // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call. + // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL. + + __ get_method(rdx); + __ movptr(rax, Address(local0, 0)); + __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, r13); + + __ testptr(rax, rax); + __ jcc(Assembler::zero, L_done); + + __ movptr(Address(rbx, 0), rax); + __ bind(L_done); + } +#endif // INCLUDE_JVMTI + __ dispatch_next(vtos); // end of PopFrame support diff -r 4b2838704fd5 -r 6725044c5725 src/cpu/zero/vm/entryFrame_zero.hpp --- a/src/cpu/zero/vm/entryFrame_zero.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/cpu/zero/vm/entryFrame_zero.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -58,8 +58,8 @@ JavaCallWrapper* call_wrapper, TRAPS); public: - JavaCallWrapper *call_wrapper() const { - return (JavaCallWrapper *) value_of_word(call_wrapper_off); + JavaCallWrapper **call_wrapper() const { + return (JavaCallWrapper **) addr_of_word(call_wrapper_off); } public: diff -r 4b2838704fd5 -r 6725044c5725 src/cpu/zero/vm/frame_zero.inline.hpp --- a/src/cpu/zero/vm/frame_zero.inline.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/cpu/zero/vm/frame_zero.inline.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -141,7 +141,7 @@ return fp(); } -inline JavaCallWrapper* frame::entry_frame_call_wrapper() const { +inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { return zero_entryframe()->call_wrapper(); } diff -r 4b2838704fd5 -r 6725044c5725 src/cpu/zero/vm/stubGenerator_zero.cpp --- a/src/cpu/zero/vm/stubGenerator_zero.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/cpu/zero/vm/stubGenerator_zero.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -176,6 +176,19 @@ StubRoutines::_oop_arraycopy; } + static int SafeFetch32(int *adr, int errValue) { + int value = errValue; + value = *adr; + return value; + } + + static intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { + intptr_t value = errValue; + value = *adr; + return value; + } + + void generate_initial() { // Generates all stubs and initializes the entry points @@ -225,6 +238,15 @@ // arraycopy stubs used by compilers generate_arraycopy_stubs(); + + // Safefetch stubs. + StubRoutines::_safefetch32_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetch32); + StubRoutines::_safefetch32_fault_pc = NULL; + StubRoutines::_safefetch32_continuation_pc = NULL; + + StubRoutines::_safefetchN_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetchN); + StubRoutines::_safefetchN_fault_pc = NULL; + StubRoutines::_safefetchN_continuation_pc = NULL; } public: diff -r 4b2838704fd5 -r 6725044c5725 src/os/bsd/vm/attachListener_bsd.cpp --- a/src/os/bsd/vm/attachListener_bsd.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/os/bsd/vm/attachListener_bsd.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -445,14 +445,14 @@ void AttachListener::vm_start() { char fn[UNIX_PATH_MAX]; - struct stat64 st; + struct stat st; int ret; int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", os::get_temp_directory(), os::current_process_id()); assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); - RESTARTABLE(::stat64(fn, &st), ret); + RESTARTABLE(::stat(fn, &st), ret); if (ret == 0) { ret = ::unlink(fn); if (ret == -1) { diff -r 4b2838704fd5 -r 6725044c5725 src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/os/windows/vm/os_windows.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -1642,6 +1642,8 @@ void os::win32::print_windows_version(outputStream* st) { OSVERSIONINFOEX osvi; + SYSTEM_INFO si; + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); @@ -1651,6 +1653,18 @@ } int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion; + + ZeroMemory(&si, sizeof(SYSTEM_INFO)); + if (os_vers >= 5002) { + // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could + // find out whether we are running on 64 bit processor or not. + if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) { + os::Kernel32Dll::GetNativeSystemInfo(&si); + } else { + GetSystemInfo(&si); + } + } + if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { switch (os_vers) { case 3051: st->print(" Windows NT 3.51"); break; @@ -1658,57 +1672,48 @@ case 5000: st->print(" Windows 2000"); break; case 5001: st->print(" Windows XP"); break; case 5002: - case 6000: - case 6001: - case 6002: { - // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could - // find out whether we are running on 64 bit processor or not. - SYSTEM_INFO si; - ZeroMemory(&si, sizeof(SYSTEM_INFO)); - if (!os::Kernel32Dll::GetNativeSystemInfoAvailable()){ - GetSystemInfo(&si); + if (osvi.wProductType == VER_NT_WORKSTATION && + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + st->print(" Windows XP x64 Edition"); } else { - os::Kernel32Dll::GetNativeSystemInfo(&si); + st->print(" Windows Server 2003 family"); } - if (os_vers == 5002) { - if (osvi.wProductType == VER_NT_WORKSTATION && - si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" Windows XP x64 Edition"); - else - st->print(" Windows Server 2003 family"); - } else if (os_vers == 6000) { - if (osvi.wProductType == VER_NT_WORKSTATION) - st->print(" Windows Vista"); - else - st->print(" Windows Server 2008"); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else if (os_vers == 6001) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - st->print(" Windows 7"); - } else { - // Unrecognized windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - } - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else if (os_vers == 6002) { - if (osvi.wProductType == VER_NT_WORKSTATION) { - st->print(" Windows 8"); - } else { - st->print(" Windows Server 2012"); - } - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); - } else { // future os - // Unrecognized windows, print out its major and minor versions - st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) - st->print(" , 64 bit"); + break; + + case 6000: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows Vista"); + } else { + st->print(" Windows Server 2008"); } break; - } - default: // future windows, print out its major and minor versions + + case 6001: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 7"); + } else { + st->print(" Windows Server 2008 R2"); + } + break; + + case 6002: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 8"); + } else { + st->print(" Windows Server 2012"); + } + break; + + case 6003: + if (osvi.wProductType == VER_NT_WORKSTATION) { + st->print(" Windows 8.1"); + } else { + st->print(" Windows Server 2012 R2"); + } + break; + + default: // future os + // Unrecognized windows, print out its major and minor versions st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); } } else { @@ -1720,6 +1725,11 @@ st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion); } } + + if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + st->print(" , 64 bit"); + } + st->print(" Build %d", osvi.dwBuildNumber); st->print(" %s", osvi.szCSDVersion); // service pack st->cr(); diff -r 4b2838704fd5 -r 6725044c5725 src/os_cpu/linux_zero/vm/os_linux_zero.cpp --- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -410,16 +410,6 @@ int SpinPause() { } - int SafeFetch32(int *adr, int errValue) { - int value = errValue; - value = *adr; - return value; - } - intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) { - intptr_t value = errValue; - value = *adr; - return value; - } void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) { if (from > to) { diff -r 4b2838704fd5 -r 6725044c5725 src/share/tools/ProjectCreator/BuildConfig.java --- a/src/share/tools/ProjectCreator/BuildConfig.java Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/tools/ProjectCreator/BuildConfig.java Mon Aug 19 09:33:29 2013 +0200 @@ -142,6 +142,69 @@ return rv; } + // Returns true if the specified path refers to a relative alternate + // source file. RelativeAltSrcInclude is usually "src\closed". + public static boolean matchesRelativeAltSrcInclude(String path) { + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + Vector v = getFieldVector(null, "AltRelativeInclude"); + for (String pathPart : v) { + if (path.contains(relativeAltSrcInclude + Util.sep + pathPart)) { + return true; + } + } + return false; + } + + // Returns the relative alternate source file for the specified path. + // Null is returned if the specified path does not have a matching + // alternate source file. + public static String getMatchingRelativeAltSrcFile(String path) { + Vector v = getFieldVector(null, "RelativeAltSrcFileList"); + if (v == null) { + return null; + } + for (String pathPart : v) { + if (path.endsWith(pathPart)) { + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + return relativeAltSrcInclude + Util.sep + pathPart; + } + } + return null; + } + + // Returns true if the specified path has a matching alternate + // source file. + public static boolean matchesRelativeAltSrcFile(String path) { + return getMatchingRelativeAltSrcFile(path) != null; + } + + // Track the specified alternate source file. The source file is + // tracked without the leading .* + // part to make matching regular source files easier. + public static void trackRelativeAltSrcFile(String path) { + String pattern = getFieldString(null, "RelativeAltSrcInclude") + + Util.sep; + int altSrcInd = path.indexOf(pattern); + if (altSrcInd == -1) { + // not an AltSrc path + return; + } + + altSrcInd += pattern.length(); + if (altSrcInd >= path.length()) { + // not a valid AltSrc path + return; + } + + String altSrcFile = path.substring(altSrcInd); + Vector v = getFieldVector(null, "RelativeAltSrcFileList"); + if (v == null || !v.contains(altSrcFile)) { + addFieldVector(null, "RelativeAltSrcFileList", altSrcFile); + } + } + void addTo(Hashtable ht, String key, String value) { ht.put(expandFormat(key), expandFormat(value)); } @@ -272,8 +335,19 @@ private Vector getSourceIncludes() { Vector rv = new Vector(); + String sourceBase = getFieldString(null, "SourceBase"); + + // add relative alternate source include values: + String relativeAltSrcInclude = + getFieldString(null, "RelativeAltSrcInclude"); + Vector asri = new Vector(); + collectRelevantVectors(asri, "AltRelativeInclude"); + for (String f : asri) { + rv.add(sourceBase + Util.sep + relativeAltSrcInclude + + Util.sep + f); + } + Vector ri = new Vector(); - String sourceBase = getFieldString(null, "SourceBase"); collectRelevantVectors(ri, "RelativeInclude"); for (String f : ri) { rv.add(sourceBase + Util.sep + f); @@ -541,35 +615,6 @@ } } -class CoreDebugConfig extends GenericDebugNonKernelConfig { - String getOptFlag() { - return getCI().getNoOptFlag(); - } - - CoreDebugConfig() { - initNames("core", "debug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - -class CoreFastDebugConfig extends GenericDebugNonKernelConfig { - String getOptFlag() { - return getCI().getOptFlag(); - } - - CoreFastDebugConfig() { - initNames("core", "fastdebug", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - -class CoreProductConfig extends ProductConfig { - CoreProductConfig() { - initNames("core", "product", "jvm.dll"); - init(getIncludes(), getDefines()); - } -} - abstract class CompilerInterface { abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir); diff -r 4b2838704fd5 -r 6725044c5725 src/share/tools/ProjectCreator/FileTreeCreator.java --- a/src/share/tools/ProjectCreator/FileTreeCreator.java Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/tools/ProjectCreator/FileTreeCreator.java Mon Aug 19 09:33:29 2013 +0200 @@ -12,11 +12,15 @@ final int startDirLength; Stack attributes = new Stack(); Vector allConfigs; - WinGammaPlatformVC10 wg; + WinGammaPlatform wg; + WinGammaPlatformVC10 wg10; - public FileTreeCreator(Path startDir, Vector allConfigs, WinGammaPlatformVC10 wg) { + public FileTreeCreator(Path startDir, Vector allConfigs, WinGammaPlatform wg) { super(); this.wg = wg; + if (wg instanceof WinGammaPlatformVC10) { + wg10 = (WinGammaPlatformVC10)wg; + } this.allConfigs = allConfigs; this.startDir = startDir; startDirLength = startDir.toAbsolutePath().toString().length(); diff -r 4b2838704fd5 -r 6725044c5725 src/share/tools/ProjectCreator/FileTreeCreatorVC10.java --- a/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java Mon Aug 19 09:33:29 2013 +0200 @@ -1,3 +1,27 @@ +/* + * Copyright (c) 2012, 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 static java.nio.file.FileVisitResult.CONTINUE; import java.io.IOException; @@ -21,6 +45,8 @@ boolean usePch = false; boolean disablePch = false; boolean useIgnore = false; + boolean isAltSrc = false; // only needed as a debugging crumb + boolean isReplacedByAltSrc = false; String fileName = file.getFileName().toString(); // TODO hideFile @@ -30,6 +56,26 @@ usePch = true; } + String fileLoc = vcProjLocation.relativize(file).toString(); + + // isAltSrc and isReplacedByAltSrc applies to all configs for a file + if (BuildConfig.matchesRelativeAltSrcInclude( + file.toAbsolutePath().toString())) { + // current file is an alternate source file so track it + isAltSrc = true; + BuildConfig.trackRelativeAltSrcFile( + file.toAbsolutePath().toString()); + } else if (BuildConfig.matchesRelativeAltSrcFile( + file.toAbsolutePath().toString())) { + // current file is a regular file that matches an alternate + // source file so yack about replacing the regular file + isReplacedByAltSrc = true; + System.out.println("INFO: alternate source file '" + + BuildConfig.getMatchingRelativeAltSrcFile( + file.toAbsolutePath().toString()) + + "' replaces '" + fileLoc + "'"); + } + for (BuildConfig cfg : allConfigs) { if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) { useIgnore = true; @@ -57,10 +103,9 @@ } } - String tagName = wg.getFileTagFromSuffix(fileName); - String fileLoc = vcProjLocation.relativize(file).toString(); + String tagName = wg10.getFileTagFromSuffix(fileName); - if (!useIgnore && !disablePch && !usePch) { + if (!useIgnore && !disablePch && !usePch && !isReplacedByAltSrc) { wg.tag(tagName, new String[] { "Include", fileLoc}); } else { wg.startTag( @@ -78,12 +123,17 @@ if (disablePch) { wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'"); } + if (isReplacedByAltSrc) { + wg.tagData("ExcludedFromBuild", "true", "Condition", + "'$(Configuration)|$(Platform)'=='" + + cfg.get("Name") + "'"); + } } wg.endTag(); } String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString(); - wg.addFilterDependency(fileLoc, filter); + wg10.addFilterDependency(fileLoc, filter); return CONTINUE; } @@ -112,7 +162,7 @@ if (!hide) { String name = startDir.relativize(path.toAbsolutePath()).toString(); if (!"".equals(name)) { - wg.addFilter(name); + wg10.addFilter(name); } attributes.push(newAttr); @@ -137,6 +187,4 @@ public void writeFileTree() throws IOException { Files.walkFileTree(this.startDir, this); } - - - } \ No newline at end of file +} diff -r 4b2838704fd5 -r 6725044c5725 src/share/tools/ProjectCreator/FileTreeCreatorVC7.java --- a/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java Mon Aug 19 09:33:29 2013 +0200 @@ -12,7 +12,7 @@ public class FileTreeCreatorVC7 extends FileTreeCreator { public FileTreeCreatorVC7(Path startDir, Vector allConfigs, WinGammaPlatform wg) { - super(startDir, allConfigs, null); + super(startDir, allConfigs, wg); } @Override diff -r 4b2838704fd5 -r 6725044c5725 src/share/tools/ProjectCreator/ProjectCreator.java --- a/src/share/tools/ProjectCreator/ProjectCreator.java Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/tools/ProjectCreator/ProjectCreator.java Mon Aug 19 09:33:29 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -39,10 +39,15 @@ + "jvm.dll; no trailing slash>"); System.err.println(" If any of the above are specified, " + "they must all be."); + System.err.println(" Note: if '-altRelativeInclude' option below is " + + "used, then the '-relativeAltSrcInclude' option must be used " + + "to specify the alternate source dir, e.g., 'src\\closed'"); System.err.println(" Additional, optional arguments, which can be " + "specified multiple times:"); System.err.println(" -absoluteInclude "); + System.err.println(" -altRelativeInclude "); System.err.println(" -relativeInclude "); System.err.println(" -define "); System.err.println(" If any of the above are specified, "+ "they must all be."); + System.err.println(" Note: if '-altRelativeInclude' option below " + + "is used, then the '-relativeAltSrcInclude' " + + "option must be used to specify the alternate " + + "source dir, e.g., 'src\\closed'"); System.err.println(" Additional, optional arguments, which can be " + "specified multiple times:"); System.err.println(" -absoluteInclude "); + System.err.println(" -altRelativeInclude "); System.err.println(" -relativeInclude "); System.err.println(" -define allConfigs) throws IOException { System.out.println(); - System.out.print(" Writing .vcxproj file: " + projectFileName); + System.out.println(" Writing .vcxproj file: " + projectFileName); String projDir = Util.normalize(new File(projectFileName).getParent()); @@ -114,7 +138,7 @@ endTag(); printWriter.close(); - System.out.println(" Done."); + System.out.println(" Done writing .vcxproj file."); writeFilterFile(projectFileName, projectName, allConfigs, projDir); writeUserFile(projectFileName, allConfigs); diff -r 4b2838704fd5 -r 6725044c5725 src/share/tools/ProjectCreator/WinGammaPlatformVC7.java --- a/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java Mon Aug 19 09:33:29 2013 +0200 @@ -139,19 +139,22 @@ tagV("Tool", cfg.getV("LinkerFlags")); - tag("Tool", - new String[] { - "Name", - "VCPostBuildEventTool", - "Description", - BuildConfig - .getFieldString(null, "PostbuildDescription"), - // Caution: String.replace(String,String) is available - // from JDK5 onwards only - "CommandLine", - cfg.expandFormat(BuildConfig.getFieldString(null, - "PostbuildCommand").replace("\t", - " ")) }); + String postBuildCmd = BuildConfig.getFieldString(null, + "PostbuildCommand"); + if (postBuildCmd != null) { + tag("Tool", + new String[] { + "Name", + "VCPostBuildEventTool", + "Description", + BuildConfig + .getFieldString(null, "PostbuildDescription"), + // Caution: String.replace(String,String) is available + // from JDK5 onwards only + "CommandLine", + cfg.expandFormat(postBuildCmd.replace("\t", + " ")) }); + } tag("Tool", new String[] { "Name", "VCPreBuildEventTool" }); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/classfile/javaClasses.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -2557,6 +2557,26 @@ *offset = value; } +// Support for java_lang_invoke_DirectMethodHandle + +int java_lang_invoke_DirectMethodHandle::_member_offset; + +oop java_lang_invoke_DirectMethodHandle::member(oop dmh) { + oop member_name = NULL; + bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh); + assert(is_dmh, "a DirectMethodHandle oop is expected"); + if (is_dmh) { + member_name = dmh->obj_field(member_offset_in_bytes()); + } + return member_name; +} + +void java_lang_invoke_DirectMethodHandle::compute_offsets() { + Klass* klass_oop = SystemDictionary::DirectMethodHandle_klass(); + if (klass_oop != NULL && EnableInvokeDynamic) { + compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature()); + } +} // Support for java_lang_invoke_MethodHandle @@ -3205,6 +3225,7 @@ java_lang_ThreadGroup::compute_offsets(); if (EnableInvokeDynamic) { java_lang_invoke_MethodHandle::compute_offsets(); + java_lang_invoke_DirectMethodHandle::compute_offsets(); java_lang_invoke_MemberName::compute_offsets(); java_lang_invoke_LambdaForm::compute_offsets(); java_lang_invoke_MethodType::compute_offsets(); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/classfile/javaClasses.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -976,6 +976,32 @@ static int form_offset_in_bytes() { return _form_offset; } }; +// Interface to java.lang.invoke.DirectMethodHandle objects + +class java_lang_invoke_DirectMethodHandle: AllStatic { + friend class JavaClasses; + + private: + static int _member_offset; // the MemberName of this DMH + + static void compute_offsets(); + + public: + // Accessors + static oop member(oop mh); + + // Testers + static bool is_subclass(Klass* klass) { + return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_klass()); + } + static bool is_instance(oop obj) { + return obj != NULL && is_subclass(obj->klass()); + } + + // Accessors for code generation: + static int member_offset_in_bytes() { return _member_offset; } +}; + // Interface to java.lang.invoke.LambdaForm objects // (These are a private interface for managing adapter code generation.) diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -151,6 +151,7 @@ do_klass(reflect_CallerSensitive_klass, sun_reflect_CallerSensitive, Opt ) \ \ /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \ + do_klass(DirectMethodHandle_klass, java_lang_invoke_DirectMethodHandle, Opt ) \ do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \ do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \ do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \ diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -255,6 +255,7 @@ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ + template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \ template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \ template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \ template(java_lang_invoke_MethodHandle, "java/lang/invoke/MethodHandle") \ @@ -352,6 +353,7 @@ template(thread_id_name, "tid") \ template(newInstance0_name, "newInstance0") \ template(limit_name, "limit") \ + template(member_name, "member") \ template(forName_name, "forName") \ template(forName0_name, "forName0") \ template(isJavaIdentifierStart_name, "isJavaIdentifierStart") \ diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -50,6 +50,7 @@ #include "memory/genMarkSweep.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/iterator.hpp" +#include "memory/padded.hpp" #include "memory/referencePolicy.hpp" #include "memory/resourceArea.hpp" #include "memory/tenuredGeneration.hpp" diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -927,11 +927,9 @@ workers->active_workers(), Threads::number_of_non_daemon_threads()); workers->set_active_workers(active_workers); - _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); assert(gch->n_gens() == 2, "Par collection currently only works with single older gen."); + _next_gen = gch->next_gen(this); // Do we have to avoid promotion_undo? if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) { set_avoid_promotion_undo(true); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/parNew/parNewGeneration.hpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -29,6 +29,7 @@ #include "gc_implementation/shared/parGCAllocBuffer.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" #include "memory/defNewGeneration.hpp" +#include "memory/padded.hpp" #include "utilities/taskqueue.hpp" class ChunkArray; diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/parNew/parOopClosures.hpp --- a/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/parNew/parOopClosures.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 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 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PAROOPCLOSURES_HPP #include "memory/genOopClosures.hpp" +#include "memory/padded.hpp" // Closures for ParNewGeneration diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -29,14 +29,16 @@ #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/mutableSpace.hpp" +#include "memory/allocation.inline.hpp" #include "memory/memRegion.hpp" +#include "memory/padded.inline.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" -PSPromotionManager** PSPromotionManager::_manager_array = NULL; -OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; -PSOldGen* PSPromotionManager::_old_gen = NULL; -MutableSpace* PSPromotionManager::_young_space = NULL; +PaddedEnd* PSPromotionManager::_manager_array = NULL; +OopStarTaskQueueSet* PSPromotionManager::_stack_array_depth = NULL; +PSOldGen* PSPromotionManager::_old_gen = NULL; +MutableSpace* PSPromotionManager::_young_space = NULL; void PSPromotionManager::initialize() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); @@ -45,8 +47,10 @@ _old_gen = heap->old_gen(); _young_space = heap->young_gen()->to_space(); + // To prevent false sharing, we pad the PSPromotionManagers + // and make sure that the first instance starts at a cache line. assert(_manager_array == NULL, "Attempt to initialize twice"); - _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1, mtGC); + _manager_array = PaddedArray::create_unfreeable(ParallelGCThreads + 1); guarantee(_manager_array != NULL, "Could not initialize promotion manager"); _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads); @@ -54,26 +58,21 @@ // Create and register the PSPromotionManager(s) for the worker threads. for(uint i=0; iregister_queue(i, _manager_array[i]->claimed_stack_depth()); + stack_array_depth()->register_queue(i, _manager_array[i].claimed_stack_depth()); } - // The VMThread gets its own PSPromotionManager, which is not available // for work stealing. - _manager_array[ParallelGCThreads] = new PSPromotionManager(); - guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager"); } PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) { assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range"); assert(_manager_array != NULL, "Sanity"); - return _manager_array[index]; + return &_manager_array[index]; } PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() { assert(_manager_array != NULL, "Sanity"); - return _manager_array[ParallelGCThreads]; + return &_manager_array[ParallelGCThreads]; } void PSPromotionManager::pre_scavenge() { diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -29,6 +29,8 @@ #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" #include "memory/allocation.hpp" +#include "memory/padded.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/taskqueue.hpp" // @@ -51,14 +53,14 @@ class PSOldGen; class ParCompactionManager; -class PSPromotionManager : public CHeapObj { +class PSPromotionManager VALUE_OBJ_CLASS_SPEC { friend class PSScavenge; friend class PSRefProcTaskExecutor; private: - static PSPromotionManager** _manager_array; - static OopStarTaskQueueSet* _stack_array_depth; - static PSOldGen* _old_gen; - static MutableSpace* _young_space; + static PaddedEnd* _manager_array; + static OopStarTaskQueueSet* _stack_array_depth; + static PSOldGen* _old_gen; + static MutableSpace* _young_space; #if TASKQUEUE_STATS size_t _masked_pushes; diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -32,7 +32,7 @@ inline PSPromotionManager* PSPromotionManager::manager_array(int index) { assert(_manager_array != NULL, "access of NULL manager_array"); assert(index >= 0 && index <= (int)ParallelGCThreads, "out of range manager_array access"); - return _manager_array[index]; + return &_manager_array[index]; } template diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/gc_implementation/shared/objectCountEventSender.cpp --- a/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -32,6 +32,7 @@ #if INCLUDE_SERVICES void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) { +#if INCLUDE_TRACE assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId), "Only call this method if the event is enabled"); @@ -42,6 +43,7 @@ event.set_totalSize(entry->words() * BytesPerWord); event.set_endtime(timestamp); event.commit(); +#endif // INCLUDE_TRACE } bool ObjectCountEventSender::should_send_event() { diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/interpreter/interpreterRuntime.cpp --- a/src/share/vm/interpreter/interpreterRuntime.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -1209,3 +1209,26 @@ size_of_arguments * Interpreter::stackElementSize); IRT_END #endif + +#if INCLUDE_JVMTI +// This is a support of the JVMTI PopFrame interface. +// Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument +// and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters. +// The dmh argument is a reference to a DirectMethoHandle that has a member name field. +IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh, + Method* method, address bcp)) + Bytecodes::Code code = Bytecodes::code_at(method, bcp); + if (code != Bytecodes::_invokestatic) { + return; + } + ConstantPool* cpool = method->constants(); + int cp_index = Bytes::get_native_u2(bcp + 1) + ConstantPool::CPCACHE_INDEX_TAG; + Symbol* cname = cpool->klass_name_at(cpool->klass_ref_index_at(cp_index)); + Symbol* mname = cpool->name_ref_at(cp_index); + + if (MethodHandles::has_member_arg(cname, mname)) { + oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh); + thread->set_vm_result(member_name); + } +IRT_END +#endif // INCLUDE_JVMTI diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/interpreter/interpreterRuntime.hpp --- a/src/share/vm/interpreter/interpreterRuntime.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -95,6 +95,9 @@ static void create_exception(JavaThread* thread, char* name, char* message); static void create_klass_exception(JavaThread* thread, char* name, oopDesc* obj); static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception); +#if INCLUDE_JVMTI + static void member_name_arg_or_null(JavaThread* thread, address dmh, Method* m, address bcp); +#endif static void throw_pending_exception(JavaThread* thread); // Statics & fields diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/cardTableRS.cpp --- a/src/share/vm/memory/cardTableRS.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/cardTableRS.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -310,46 +310,31 @@ _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this); } -void CardTableRS::clear_into_younger(Generation* gen) { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - // Generations younger than gen have been evacuated. We can clear - // card table entries for gen (we know that it has no pointers - // to younger gens) and for those below. The card tables for - // the youngest gen need never be cleared. +void CardTableRS::clear_into_younger(Generation* old_gen) { + assert(old_gen->level() == 1, "Should only be called for the old generation"); + // The card tables for the youngest gen need never be cleared. // There's a bit of subtlety in the clear() and invalidate() // methods that we exploit here and in invalidate_or_clear() // below to avoid missing cards at the fringes. If clear() or // invalidate() are changed in the future, this code should // be revisited. 20040107.ysr - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); - prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion to_be_cleared_mr = g->prev_used_region(); - clear(to_be_cleared_mr); - } + clear(old_gen->prev_used_region()); } -void CardTableRS::invalidate_or_clear(Generation* gen, bool younger) { - GenCollectedHeap* gch = GenCollectedHeap::heap(); - // For each generation gen (and younger) - // invalidate the cards for the currently occupied part - // of that generation and clear the cards for the +void CardTableRS::invalidate_or_clear(Generation* old_gen) { + assert(old_gen->level() == 1, "Should only be called for the old generation"); + // Invalidate the cards for the currently occupied part of + // the old generation and clear the cards for the // unoccupied part of the generation (if any, making use // of that generation's prev_used_region to determine that // region). No need to do anything for the youngest // generation. Also see note#20040107.ysr above. - Generation* g = gen; - for(Generation* prev_gen = gch->prev_gen(g); prev_gen != NULL; - g = prev_gen, prev_gen = gch->prev_gen(g)) { - MemRegion used_mr = g->used_region(); - MemRegion to_be_cleared_mr = g->prev_used_region().minus(used_mr); - if (!to_be_cleared_mr.is_empty()) { - clear(to_be_cleared_mr); - } - invalidate(used_mr); - if (!younger) break; + MemRegion used_mr = old_gen->used_region(); + MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr); + if (!to_be_cleared_mr.is_empty()) { + clear(to_be_cleared_mr); } + invalidate(used_mr); } diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/cardTableRS.hpp --- a/src/share/vm/memory/cardTableRS.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/cardTableRS.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -142,12 +142,12 @@ void verify_aligned_region_empty(MemRegion mr); void clear(MemRegion mr) { _ct_bs->clear(mr); } - void clear_into_younger(Generation* gen); + void clear_into_younger(Generation* old_gen); void invalidate(MemRegion mr, bool whole_heap = false) { _ct_bs->invalidate(mr, whole_heap); } - void invalidate_or_clear(Generation* gen, bool younger); + void invalidate_or_clear(Generation* old_gen); static uintx ct_max_alignment_constraint() { return CardTableModRefBS::ct_max_alignment_constraint(); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/defNewGeneration.cpp --- a/src/share/vm/memory/defNewGeneration.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/defNewGeneration.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -567,8 +567,6 @@ gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); // If the next generation is too full to accommodate promotion // from this generation, pass on collection; let the next generation @@ -901,8 +899,6 @@ if (_next_gen == NULL) { GenCollectedHeap* gch = GenCollectedHeap::heap(); _next_gen = gch->next_gen(this); - assert(_next_gen != NULL, - "This must be the youngest gen, and not the only gen"); } return _next_gen->promotion_attempt_is_safe(used()); } diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/genCollectedHeap.cpp --- a/src/share/vm/memory/genCollectedHeap.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/genCollectedHeap.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -1070,13 +1070,13 @@ void GenCollectedHeap::prepare_for_compaction() { - Generation* scanning_gen = _gens[_n_gens-1]; + guarantee(_n_gens = 2, "Wrong number of generations"); + Generation* old_gen = _gens[1]; // Start by compacting into same gen. - CompactPoint cp(scanning_gen, NULL, NULL); - while (scanning_gen != NULL) { - scanning_gen->prepare_for_compaction(&cp); - scanning_gen = prev_gen(scanning_gen); - } + CompactPoint cp(old_gen, NULL, NULL); + old_gen->prepare_for_compaction(&cp); + Generation* young_gen = _gens[0]; + young_gen->prepare_for_compaction(&cp); } GCStats* GenCollectedHeap::gc_stats(int level) const { @@ -1245,27 +1245,14 @@ generation_iterate(&ep_cl, false); } -oop GenCollectedHeap::handle_failed_promotion(Generation* gen, +oop GenCollectedHeap::handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size) { + guarantee(old_gen->level() == 1, "We only get here with an old generation"); assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); HeapWord* result = NULL; - // First give each higher generation a chance to allocate the promoted object. - Generation* allocator = next_gen(gen); - if (allocator != NULL) { - do { - result = allocator->allocate(obj_size, false); - } while (result == NULL && (allocator = next_gen(allocator)) != NULL); - } - - if (result == NULL) { - // Then give gen and higher generations a chance to expand and allocate the - // object. - do { - result = gen->expand_and_allocate(obj_size, false); - } while (result == NULL && (gen = next_gen(gen)) != NULL); - } + result = old_gen->expand_and_allocate(obj_size, false); if (result != NULL) { Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/genCollectedHeap.hpp --- a/src/share/vm/memory/genCollectedHeap.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/genCollectedHeap.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -368,25 +368,23 @@ // collection. virtual bool is_maximal_no_gc() const; - // Return the generation before "gen", or else NULL. + // Return the generation before "gen". Generation* prev_gen(Generation* gen) const { int l = gen->level(); - if (l == 0) return NULL; - else return _gens[l-1]; + guarantee(l > 0, "Out of bounds"); + return _gens[l-1]; } - // Return the generation after "gen", or else NULL. + // Return the generation after "gen". Generation* next_gen(Generation* gen) const { int l = gen->level() + 1; - if (l == _n_gens) return NULL; - else return _gens[l]; + guarantee(l < _n_gens, "Out of bounds"); + return _gens[l]; } Generation* get_gen(int i) const { - if (i >= 0 && i < _n_gens) - return _gens[i]; - else - return NULL; + guarantee(i >= 0 && i < _n_gens, "Out of bounds"); + return _gens[i]; } int n_gens() const { @@ -485,9 +483,9 @@ // Promotion of obj into gen failed. Try to promote obj to higher // gens in ascending order; return the new location of obj if successful. - // Otherwise, try expand-and-allocate for obj in each generation starting at - // gen; return the new location of obj if successful. Otherwise, return NULL. - oop handle_failed_promotion(Generation* gen, + // Otherwise, try expand-and-allocate for obj in both the young and old + // generation; return the new location of obj if successful. Otherwise, return NULL. + oop handle_failed_promotion(Generation* old_gen, oop obj, size_t obj_size); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/genMarkSweep.cpp --- a/src/share/vm/memory/genMarkSweep.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/genMarkSweep.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -52,8 +52,8 @@ #include "utilities/copy.hpp" #include "utilities/events.hpp" -void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, - bool clear_all_softrefs) { +void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) { + guarantee(level == 1, "We always collect both old and young."); assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint"); GenCollectedHeap* gch = GenCollectedHeap::heap(); @@ -84,11 +84,6 @@ // Capture heap size before collection for printing. size_t gch_prev_used = gch->used(); - // Some of the card table updates below assume that the perm gen is - // also being collected. - assert(level == gch->n_gens() - 1, - "All generations are being collected, ergo perm gen too."); - // Capture used regions for each generation that will be // subject to collection, so that card table adjustments can // be made intelligently (see clear / invalidate further below). @@ -126,17 +121,15 @@ all_empty = all_empty && gch->get_gen(i)->used() == 0; } GenRemSet* rs = gch->rem_set(); + Generation* old_gen = gch->get_gen(level); // Clear/invalidate below make use of the "prev_used_regions" saved earlier. if (all_empty) { // We've evacuated all generations below us. - Generation* g = gch->get_gen(level); - rs->clear_into_younger(g); + rs->clear_into_younger(old_gen); } else { // Invalidate the cards corresponding to the currently used - // region and clear those corresponding to the evacuated region - // of all generations just collected (i.e. level and younger). - rs->invalidate_or_clear(gch->get_gen(level), - true /* younger */); + // region and clear those corresponding to the evacuated region. + rs->invalidate_or_clear(old_gen); } Threads::gc_epilogue(); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/genRemSet.hpp --- a/src/share/vm/memory/genRemSet.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/genRemSet.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -135,7 +135,7 @@ // younger than gen from generations gen and older. // The parameter clear_perm indicates if the perm_gen's // remembered set should also be processed/cleared. - virtual void clear_into_younger(Generation* gen) = 0; + virtual void clear_into_younger(Generation* old_gen) = 0; // Informs the RS that refs in the given "mr" may have changed // arbitrarily, and therefore may contain old-to-young pointers. @@ -146,11 +146,8 @@ // Informs the RS that refs in this generation // may have changed arbitrarily, and therefore may contain - // old-to-young pointers in arbitrary locations. The parameter - // younger indicates if the same should be done for younger generations - // as well. The parameter perm indicates if the same should be done for - // perm gen as well. - virtual void invalidate_or_clear(Generation* gen, bool younger) = 0; + // old-to-young pointers in arbitrary locations. + virtual void invalidate_or_clear(Generation* old_gen) = 0; }; #endif // SHARE_VM_MEMORY_GENREMSET_HPP diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/padded.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/memory/padded.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -0,0 +1,93 @@ +/* + * 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. + * + */ + +#ifndef SHARE_VM_MEMORY_PADDED_HPP +#define SHARE_VM_MEMORY_PADDED_HPP + +#include "memory/allocation.hpp" +#include "utilities/globalDefinitions.hpp" + +// Bytes needed to pad type to avoid cache-line sharing; alignment should be the +// expected cache line size (a power of two). The first addend avoids sharing +// when the start address is not a multiple of alignment; the second maintains +// alignment of starting addresses that happen to be a multiple. +#define PADDING_SIZE(type, alignment) \ + ((alignment) + align_size_up_(sizeof(type), alignment)) + +// Templates to create a subclass padded to avoid cache line sharing. These are +// effective only when applied to derived-most (leaf) classes. + +// When no args are passed to the base ctor. +template +class Padded : public T { + private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; + +// When either 0 or 1 args may be passed to the base ctor. +template +class Padded01 : public T { + public: + Padded01(): T() { } + Padded01(Arg1T arg1): T(arg1) { } + private: + char _pad_buf_[PADDING_SIZE(T, alignment)]; +}; + +// Super class of PaddedEnd when pad_size != 0. +template +class PaddedEndImpl : public T { + private: + char _pad_buf[pad_size]; +}; + +// Super class of PaddedEnd when pad_size == 0. +template +class PaddedEndImpl : public T { + // No padding. +}; + +#define PADDED_END_SIZE(type, alignment) (align_size_up_(sizeof(type), alignment) - sizeof(type)) + +// More memory conservative implementation of Padded. The subclass adds the +// minimal amount of padding needed to make the size of the objects be aligned. +// This will help reducing false sharing, +// if the start address is a multiple of alignment. +template +class PaddedEnd : public PaddedEndImpl { + // C++ don't allow zero-length arrays. The padding is put in a + // super class that is specialized for the pad_size == 0 case. +}; + +// Helper class to create an array of PaddedEnd objects. All elements will +// start at a multiple of alignment and the size will be aligned to alignment. +template +class PaddedArray { + public: + // Creates an aligned padded array. + // The memory can't be deleted since the raw memory chunk is not returned. + static PaddedEnd* create_unfreeable(uint length); +}; + +#endif // SHARE_VM_MEMORY_PADDED_HPP diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/padded.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/memory/padded.inline.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -0,0 +1,49 @@ +/* + * 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. + * + */ + +#include "memory/allocation.inline.hpp" +#include "memory/padded.hpp" +#include "utilities/debug.hpp" +#include "utilities/globalDefinitions.hpp" + +// Creates an aligned padded array. +// The memory can't be deleted since the raw memory chunk is not returned. +template +PaddedEnd* PaddedArray::create_unfreeable(uint length) { + // Check that the PaddedEnd class works as intended. + STATIC_ASSERT(is_size_aligned_(sizeof(PaddedEnd), alignment)); + + // Allocate a chunk of memory large enough to allow for some alignment. + void* chunk = AllocateHeap(length * sizeof(PaddedEnd) + alignment, flags); + + // Make the initial alignment. + PaddedEnd* aligned_padded_array = (PaddedEnd*)align_pointer_up(chunk, alignment); + + // Call the default constructor for each element. + for (uint i = 0; i < length; i++) { + ::new (&aligned_padded_array[i]) T(); + } + + return aligned_padded_array; +} diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/universe.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -105,10 +105,9 @@ Array* Universe::_the_array_interfaces_array = NULL; oop Universe::_the_null_string = NULL; oop Universe::_the_min_jint_string = NULL; -LatestMethodOopCache* Universe::_finalizer_register_cache = NULL; -LatestMethodOopCache* Universe::_loader_addClass_cache = NULL; -LatestMethodOopCache* Universe::_pd_implies_cache = NULL; -ActiveMethodOopsCache* Universe::_reflect_invoke_cache = NULL; +LatestMethodCache* Universe::_finalizer_register_cache = NULL; +LatestMethodCache* Universe::_loader_addClass_cache = NULL; +LatestMethodCache* Universe::_pd_implies_cache = NULL; oop Universe::_out_of_memory_error_java_heap = NULL; oop Universe::_out_of_memory_error_metaspace = NULL; oop Universe::_out_of_memory_error_class_metaspace = NULL; @@ -225,7 +224,6 @@ f->do_ptr((void**)&_the_empty_klass_array); _finalizer_register_cache->serialize(f); _loader_addClass_cache->serialize(f); - _reflect_invoke_cache->serialize(f); _pd_implies_cache->serialize(f); } @@ -649,10 +647,9 @@ // We have a heap so create the Method* caches before // Metaspace::initialize_shared_spaces() tries to populate them. - Universe::_finalizer_register_cache = new LatestMethodOopCache(); - Universe::_loader_addClass_cache = new LatestMethodOopCache(); - Universe::_pd_implies_cache = new LatestMethodOopCache(); - Universe::_reflect_invoke_cache = new ActiveMethodOopsCache(); + Universe::_finalizer_register_cache = new LatestMethodCache(); + Universe::_loader_addClass_cache = new LatestMethodCache(); + Universe::_pd_implies_cache = new LatestMethodCache(); if (UseSharedSpaces) { // Read the data structures supporting the shared spaces (shared @@ -1088,35 +1085,21 @@ vmSymbols::register_method_name(), vmSymbols::register_method_signature()); if (m == NULL || !m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.ref.Finalizer.register", false); + tty->print_cr("Unable to link/verify Finalizer.register method"); + return false; // initialization failed (cannot throw exception yet) } Universe::_finalizer_register_cache->init( - SystemDictionary::Finalizer_klass(), m, CHECK_false); - - // Resolve on first use and initialize class. - // Note: No race-condition here, since a resolve will always return the same result - - // Setup method for security checks - k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_reflect_Method(), true, CHECK_false); - k_h = instanceKlassHandle(THREAD, k); - k_h->link_class(CHECK_false); - m = k_h->find_method(vmSymbols::invoke_name(), vmSymbols::object_object_array_object_signature()); - if (m == NULL || m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.reflect.Method.invoke", false); - } - Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false); + SystemDictionary::Finalizer_klass(), m); // Setup method for registering loaded classes in class loader vector InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); if (m == NULL || m->is_static()) { - THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(), - "java.lang.ClassLoader.addClass", false); + tty->print_cr("Unable to link/verify ClassLoader.addClass method"); + return false; // initialization failed (cannot throw exception yet) } Universe::_loader_addClass_cache->init( - SystemDictionary::ClassLoader_klass(), m, CHECK_false); + SystemDictionary::ClassLoader_klass(), m); // Setup method for checking protection domain InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false); @@ -1132,7 +1115,7 @@ return false; // initialization failed } Universe::_pd_implies_cache->init( - SystemDictionary::ProtectionDomain_klass(), m, CHECK_false);; + SystemDictionary::ProtectionDomain_klass(), m);; } // The folowing is initializing converter functions for serialization in @@ -1455,7 +1438,7 @@ } -void CommonMethodOopCache::init(Klass* k, Method* m, TRAPS) { +void LatestMethodCache::init(Klass* k, Method* m) { if (!UseSharedSpaces) { _klass = k; } @@ -1471,88 +1454,7 @@ } -ActiveMethodOopsCache::~ActiveMethodOopsCache() { - if (_prev_methods != NULL) { - delete _prev_methods; - _prev_methods = NULL; - } -} - - -void ActiveMethodOopsCache::add_previous_version(Method* method) { - assert(Thread::current()->is_VM_thread(), - "only VMThread can add previous versions"); - - // Only append the previous method if it is executing on the stack. - if (method->on_stack()) { - - if (_prev_methods == NULL) { - // This is the first previous version so make some space. - // Start with 2 elements under the assumption that the class - // won't be redefined much. - _prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray(2, true); - } - - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000100, - ("add: %s(%s): adding prev version ref for cached method @%d", - method->name()->as_C_string(), method->signature()->as_C_string(), - _prev_methods->length())); - - _prev_methods->append(method); - } - - - // Since the caller is the VMThread and we are at a safepoint, this is a good - // time to clear out unused method references. - - if (_prev_methods == NULL) return; - - for (int i = _prev_methods->length() - 1; i >= 0; i--) { - Method* method = _prev_methods->at(i); - assert(method != NULL, "weak method ref was unexpectedly cleared"); - - if (!method->on_stack()) { - // This method isn't running anymore so remove it - _prev_methods->remove_at(i); - MetadataFactory::free_metadata(method->method_holder()->class_loader_data(), method); - } else { - // RC_TRACE macro has an embedded ResourceMark - RC_TRACE(0x00000400, - ("add: %s(%s): previous cached method @%d is alive", - method->name()->as_C_string(), method->signature()->as_C_string(), i)); - } - } -} // end add_previous_version() - - -bool ActiveMethodOopsCache::is_same_method(const Method* method) const { - InstanceKlass* ik = InstanceKlass::cast(klass()); - const Method* check_method = ik->method_with_idnum(method_idnum()); - assert(check_method != NULL, "sanity check"); - if (check_method == method) { - // done with the easy case - return true; - } - - if (_prev_methods != NULL) { - // The cached method has been redefined at least once so search - // the previous versions for a match. - for (int i = 0; i < _prev_methods->length(); i++) { - check_method = _prev_methods->at(i); - if (check_method == method) { - // a previous version matches - return true; - } - } - } - - // either no previous versions or no previous version matched - return false; -} - - -Method* LatestMethodOopCache::get_Method() { +Method* LatestMethodCache::get_method() { if (klass() == NULL) return NULL; InstanceKlass* ik = InstanceKlass::cast(klass()); Method* m = ik->method_with_idnum(method_idnum()); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/memory/universe.hpp --- a/src/share/vm/memory/universe.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/memory/universe.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -41,10 +41,11 @@ class DeferredObjAllocEvent; -// Common parts of a Method* cache. This cache safely interacts with -// the RedefineClasses API. -// -class CommonMethodOopCache : public CHeapObj { +// A helper class for caching a Method* when the user of the cache +// only cares about the latest version of the Method*. This cache safely +// interacts with the RedefineClasses API. + +class LatestMethodCache : public CHeapObj { // We save the Klass* and the idnum of Method* in order to get // the current cached Method*. private: @@ -52,12 +53,14 @@ int _method_idnum; public: - CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; } - ~CommonMethodOopCache() { _klass = NULL; _method_idnum = -1; } + LatestMethodCache() { _klass = NULL; _method_idnum = -1; } + ~LatestMethodCache() { _klass = NULL; _method_idnum = -1; } - void init(Klass* k, Method* m, TRAPS); - Klass* klass() const { return _klass; } - int method_idnum() const { return _method_idnum; } + void init(Klass* k, Method* m); + Klass* klass() const { return _klass; } + int method_idnum() const { return _method_idnum; } + + Method* get_method(); // Enhanced Class Redefinition support void classes_do(void f(Klass*)) { @@ -72,39 +75,6 @@ }; -// A helper class for caching a Method* when the user of the cache -// cares about all versions of the Method*. -// -class ActiveMethodOopsCache : public CommonMethodOopCache { - // This subclass adds weak references to older versions of the - // Method* and a query method for a Method*. - - private: - // If the cached Method* has not been redefined, then - // _prev_methods will be NULL. If all of the previous - // versions of the method have been collected, then - // _prev_methods can have a length of zero. - GrowableArray* _prev_methods; - - public: - ActiveMethodOopsCache() { _prev_methods = NULL; } - ~ActiveMethodOopsCache(); - - void add_previous_version(Method* method); - bool is_same_method(const Method* method) const; -}; - - -// A helper class for caching a Method* when the user of the cache -// only cares about the latest version of the Method*. -// -class LatestMethodOopCache : public CommonMethodOopCache { - // This subclass adds a getter method for the latest Method*. - - public: - Method* get_Method(); -}; - // For UseCompressedOops and UseCompressedKlassPointers. struct NarrowPtrStruct { // Base address for oop/klass-within-java-object materialization. @@ -174,10 +144,10 @@ static objArrayOop _the_empty_class_klass_array; // Canonicalized obj array of type java.lang.Class static oop _the_null_string; // A cache of "null" as a Java string static oop _the_min_jint_string; // A cache of "-2147483648" as a Java string - static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects - static LatestMethodOopCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector - static LatestMethodOopCache* _pd_implies_cache; // method for checking protection domain attributes - static ActiveMethodOopsCache* _reflect_invoke_cache; // method for security checks + static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects + static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector + static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes + // preallocated error objects (no backtrace) static oop _out_of_memory_error_java_heap; static oop _out_of_memory_error_metaspace; @@ -334,11 +304,11 @@ static Array* the_array_interfaces_array() { return _the_array_interfaces_array; } static oop the_null_string() { return _the_null_string; } static oop the_min_jint_string() { return _the_min_jint_string; } - static Method* finalizer_register_method() { return _finalizer_register_cache->get_Method(); } - static Method* loader_addClass_method() { return _loader_addClass_cache->get_Method(); } - static Method* protection_domain_implies_method() { return _pd_implies_cache->get_Method(); } - static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; } + static Method* finalizer_register_method() { return _finalizer_register_cache->get_method(); } + static Method* loader_addClass_method() { return _loader_addClass_cache->get_method(); } + + static Method* protection_domain_implies_method() { return _pd_implies_cache->get_method(); } static oop null_ptr_exception_instance() { return _null_ptr_exception_instance; } static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/oops/method.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -983,7 +983,6 @@ bool Method::is_ignored_by_security_stack_walk() const { const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection; - assert(intrinsic_id() != vmIntrinsics::_invoke || Universe::reflect_invoke_cache()->is_same_method((Method*)this), "sanity"); if (intrinsic_id() == vmIntrinsics::_invoke) { // This is Method.invoke() -- ignore it return true; diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Aug 19 09:33:29 2013 +0200 @@ -3217,15 +3217,6 @@ JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); - if (the_class_oop == Universe::reflect_invoke_cache()->klass()) { - // We are redefining java.lang.reflect.Method. Method.invoke() is - // cached and users of the cache care about each active version of - // the method so we have to track this previous version. - // Do this before methods get switched - Universe::reflect_invoke_cache()->add_previous_version( - the_class->method_with_idnum(Universe::reflect_invoke_cache()->method_idnum())); - } - // Deoptimize all compiled code that depends on this class flush_dependent_code(the_class, THREAD); diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/utilities/debug.hpp --- a/src/share/vm/utilities/debug.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/utilities/debug.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -225,6 +225,22 @@ void warning(const char* format, ...); +#ifdef ASSERT +// Compile-time asserts. +template struct StaticAssert; +template <> struct StaticAssert {}; + +// Only StaticAssert is defined, so if cond evaluates to false we get +// a compile time exception when trying to use StaticAssert. +#define STATIC_ASSERT(cond) \ + do { \ + StaticAssert<(cond)> DUMMY_STATIC_ASSERT; \ + (void)DUMMY_STATIC_ASSERT; /* ignore */ \ + } while (false) +#else +#define STATIC_ASSERT(cond) +#endif + // out of shared space reporting enum SharedSpaceType { SharedPermGen, diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/utilities/exceptions.hpp --- a/src/share/vm/utilities/exceptions.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/utilities/exceptions.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -306,6 +306,6 @@ // which preserves pre-existing exceptions and does not allow new // exceptions. -#define EXCEPTION_MARK Thread* THREAD; ExceptionMark __em(THREAD); +#define EXCEPTION_MARK Thread* THREAD = NULL; ExceptionMark __em(THREAD); #endif // SHARE_VM_UTILITIES_EXCEPTIONS_HPP diff -r 4b2838704fd5 -r 6725044c5725 src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp Fri Aug 16 14:11:40 2013 -0700 +++ b/src/share/vm/utilities/globalDefinitions.hpp Mon Aug 19 09:33:29 2013 +0200 @@ -410,6 +410,8 @@ return align_size_down_(size, alignment); } +#define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment))) + // Align objects by rounding up their size, in HeapWord units. #define align_object_size_(size) align_size_up_(size, MinObjAlignment) @@ -428,6 +430,10 @@ return align_size_up(offset, HeapWordsPerLong); } +inline void* align_pointer_up(const void* addr, size_t size) { + return (void*) align_size_up_((uintptr_t)addr, size); +} + // Clamp an address to be within a specific page // 1. If addr is on the page it is returned as is // 2. If addr is above the page_address the start of the *next* page will be returned @@ -449,32 +455,6 @@ // The expected size in bytes of a cache line, used to pad data structures. #define DEFAULT_CACHE_LINE_SIZE 64 -// Bytes needed to pad type to avoid cache-line sharing; alignment should be the -// expected cache line size (a power of two). The first addend avoids sharing -// when the start address is not a multiple of alignment; the second maintains -// alignment of starting addresses that happen to be a multiple. -#define PADDING_SIZE(type, alignment) \ - ((alignment) + align_size_up_(sizeof(type), alignment)) - -// Templates to create a subclass padded to avoid cache line sharing. These are -// effective only when applied to derived-most (leaf) classes. - -// When no args are passed to the base ctor. -template -class Padded: public T { -private: - char _pad_buf_[PADDING_SIZE(T, alignment)]; -}; - -// When either 0 or 1 args may be passed to the base ctor. -template -class Padded01: public T { -public: - Padded01(): T() { } - Padded01(Arg1T arg1): T(arg1) { } -private: - char _pad_buf_[PADDING_SIZE(T, alignment)]; -}; //---------------------------------------------------------------------------------------------------- // Utility macros for compilers diff -r 4b2838704fd5 -r 6725044c5725 test/runtime/7107135/Test7107135.sh --- a/test/runtime/7107135/Test7107135.sh Fri Aug 16 14:11:40 2013 -0700 +++ b/test/runtime/7107135/Test7107135.sh Mon Aug 19 09:33:29 2013 +0200 @@ -53,9 +53,6 @@ fi ;; *) - NULL=NUL - PS=";" - FS="\\" echo "Test passed; only valid for Linux" exit 0; ;; @@ -87,14 +84,16 @@ echo echo Test changing of stack protection: -echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw +echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx +JAVA_RETVAL=$? -if [ "$?" == "0" ] +if [ "$JAVA_RETVAL" == "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 + JAVA_RETVAL=$? fi -exit $? +exit $JAVA_RETVAL diff -r 4b2838704fd5 -r 6725044c5725 test/runtime/RedefineObject/Agent.java --- a/test/runtime/RedefineObject/Agent.java Fri Aug 16 14:11:40 2013 -0700 +++ b/test/runtime/RedefineObject/Agent.java Mon Aug 19 09:33:29 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,6 +22,7 @@ */ import java.security.*; import java.lang.instrument.*; +import java.lang.reflect.*; public class Agent implements ClassFileTransformer { public synchronized byte[] transform(final ClassLoader classLoader, @@ -29,22 +30,34 @@ Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) { - //System.out.println("Transforming class " + className); + System.out.println("Transforming class " + className); return classfileBuffer; } + public static void redefine(String agentArgs, Instrumentation instrumentation, Class to_redefine) { + + try { + instrumentation.retransformClasses(to_redefine); + } catch (Exception e) { + e.printStackTrace(); + } + + } + public static void premain(String agentArgs, Instrumentation instrumentation) { - Agent transformer = new Agent(); - instrumentation.addTransformer(transformer, true); - Class c = Object.class; - try { - instrumentation.retransformClasses(c); - } catch (Exception e) { - e.printStackTrace(); - } + // Redefine java/lang/Object and java/lang/reflect/Method.invoke and + // java/lang/ClassLoader + Class object_class = Object.class; + redefine(agentArgs, instrumentation, object_class); + + Class method_class = Method.class; + redefine(agentArgs, instrumentation, method_class); + + Class loader_class = ClassLoader.class; + redefine(agentArgs, instrumentation, loader_class); instrumentation.removeTransformer(transformer); } @@ -57,5 +70,14 @@ System.gc(); ba.clone(); } + try { + // Use java/lang/reflect/Method.invoke to call + WalkThroughInvoke a = new WalkThroughInvoke(); + Class aclass = WalkThroughInvoke.class; + Method m = aclass.getMethod("stackWalk"); + m.invoke(a); + } catch (Exception x) { + x.printStackTrace(); + } } } diff -r 4b2838704fd5 -r 6725044c5725 test/runtime/RedefineObject/TestRedefineObject.java --- a/test/runtime/RedefineObject/TestRedefineObject.java Fri Aug 16 14:11:40 2013 -0700 +++ b/test/runtime/RedefineObject/TestRedefineObject.java Mon Aug 19 09:33:29 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -26,14 +26,17 @@ /* * Test to redefine java/lang/Object and verify that it doesn't crash on vtable * call on basic array type. + * Test to redefine java/lang/ClassLoader and java/lang/reflect/Method to make + * sure cached versions used afterward are the current version. * * @test * @bug 8005056 + * @bug 8009728 * @library /testlibrary * @build Agent * @run main ClassFileInstaller Agent * @run main TestRedefineObject - * @run main/othervm -javaagent:agent.jar Agent + * @run main/othervm -javaagent:agent.jar -XX:TraceRedefineClasses=5 Agent */ public class TestRedefineObject { public static void main(String[] args) throws Exception { diff -r 4b2838704fd5 -r 6725044c5725 test/runtime/RedefineObject/WalkThroughInvoke.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/RedefineObject/WalkThroughInvoke.java Mon Aug 19 09:33:29 2013 +0200 @@ -0,0 +1,38 @@ +/* + * 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.lang.reflect.*; + +public class WalkThroughInvoke { + public void stackWalk() { + try { + Class b = Object.class; + SecurityManager sm = new SecurityManager(); + // Walks the stack with Method.invoke in the stack (which is the + // purpose of the test) before it gets an AccessControlException. + sm.checkMemberAccess(b, Member.DECLARED); + } catch (java.security.AccessControlException e) { + // Ignoring an 'AccessControlException' exception since + // it is expected as part of this test. + } + } +};