# HG changeset patch # User acorn # Date 1357772794 18000 # Node ID 1f6d10b4cc0c09430d5e0a62678796dcc2e9d4c6 # Parent 0b54ffe4c2d37fe7609fb4369813af6650a850ef# Parent 0c93d4818214c9407ca9c855ec21016be00f716d Merge diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c make/bsd/makefiles/mapfile-vers-debug --- a/make/bsd/makefiles/mapfile-vers-debug Fri Jan 04 17:04:46 2013 -0800 +++ b/make/bsd/makefiles/mapfile-vers-debug Wed Jan 09 18:06:34 2013 -0500 @@ -1,5 +1,5 @@ # -# @(#)mapfile-vers-debug 1.18 07/10/25 16:47:35 +# @(#)mapfile-vers-debug 1.18 07/10/25 16:47:35 # # @@ -126,8 +126,9 @@ JVM_GetClassModifiers; JVM_GetClassName; JVM_GetClassNameUTF; - JVM_GetClassSignature; + JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; @@ -154,6 +155,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; @@ -283,7 +285,7 @@ # This is for Forte Analyzer profiling support. AsyncGetCallTrace; - # INSERT VTABLE SYMBOLS HERE + # INSERT VTABLE SYMBOLS HERE local: *; diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c make/bsd/makefiles/mapfile-vers-product --- a/make/bsd/makefiles/mapfile-vers-product Fri Jan 04 17:04:46 2013 -0800 +++ b/make/bsd/makefiles/mapfile-vers-product Wed Jan 09 18:06:34 2013 -0500 @@ -128,6 +128,7 @@ JVM_GetClassNameUTF; JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; @@ -154,6 +155,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c make/linux/makefiles/mapfile-vers-debug --- a/make/linux/makefiles/mapfile-vers-debug Fri Jan 04 17:04:46 2013 -0800 +++ b/make/linux/makefiles/mapfile-vers-debug Wed Jan 09 18:06:34 2013 -0500 @@ -124,6 +124,7 @@ JVM_GetClassNameUTF; JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; @@ -150,6 +151,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c make/linux/makefiles/mapfile-vers-product --- a/make/linux/makefiles/mapfile-vers-product Fri Jan 04 17:04:46 2013 -0800 +++ b/make/linux/makefiles/mapfile-vers-product Wed Jan 09 18:06:34 2013 -0500 @@ -124,6 +124,7 @@ JVM_GetClassNameUTF; JVM_GetClassSignature; JVM_GetClassSigners; + JVM_GetClassTypeAnnotations; JVM_GetComponentType; JVM_GetDeclaredClasses; JVM_GetDeclaringClass; @@ -150,6 +151,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Fri Jan 04 17:04:46 2013 -0800 +++ b/make/solaris/makefiles/mapfile-vers Wed Jan 09 18:06:34 2013 -0500 @@ -26,235 +26,237 @@ SUNWprivate_1.1 { global: - # JNI + # JNI JNI_CreateJavaVM; JNI_GetCreatedJavaVMs; JNI_GetDefaultJavaVMInitArgs; - - # JVM - JVM_Accept; - JVM_ActiveProcessorCount; - JVM_AllocateNewArray; - JVM_AllocateNewObject; - JVM_ArrayCopy; - JVM_AssertionStatusDirectives; - JVM_Available; - JVM_Bind; - JVM_ClassDepth; - JVM_ClassLoaderDepth; - JVM_Clone; - JVM_Close; - JVM_CX8Field; - JVM_CompileClass; - JVM_CompileClasses; - JVM_CompilerCommand; - JVM_Connect; - JVM_ConstantPoolGetClassAt; - JVM_ConstantPoolGetClassAtIfLoaded; - JVM_ConstantPoolGetDoubleAt; - JVM_ConstantPoolGetFieldAt; - JVM_ConstantPoolGetFieldAtIfLoaded; - JVM_ConstantPoolGetFloatAt; - JVM_ConstantPoolGetIntAt; - JVM_ConstantPoolGetLongAt; - JVM_ConstantPoolGetMethodAt; - JVM_ConstantPoolGetMethodAtIfLoaded; - JVM_ConstantPoolGetMemberRefInfoAt; - JVM_ConstantPoolGetSize; - JVM_ConstantPoolGetStringAt; - JVM_ConstantPoolGetUTF8At; - JVM_CountStackFrames; - JVM_CurrentClassLoader; - JVM_CurrentLoadedClass; - JVM_CurrentThread; - JVM_CurrentTimeMillis; - JVM_DefineClass; - JVM_DefineClassWithSource; - JVM_DefineClassWithSourceCond; - JVM_DesiredAssertionStatus; - JVM_DisableCompiler; - JVM_DoPrivileged; - JVM_DTraceGetVersion; - JVM_DTraceActivate; - JVM_DTraceIsProbeEnabled; - JVM_DTraceIsSupported; - JVM_DTraceDispose; - JVM_DumpAllStacks; - JVM_DumpThreads; - JVM_EnableCompiler; - JVM_Exit; - JVM_FillInStackTrace; - JVM_FindClassFromClass; - JVM_FindClassFromClassLoader; - JVM_FindClassFromBootLoader; - JVM_FindLibraryEntry; - JVM_FindLoadedClass; - JVM_FindPrimitiveClass; - JVM_FindSignal; - JVM_FreeMemory; - JVM_GC; - JVM_GetAllThreads; - JVM_GetArrayElement; - JVM_GetArrayLength; - JVM_GetCPClassNameUTF; - JVM_GetCPFieldClassNameUTF; - JVM_GetCPFieldModifiers; - JVM_GetCPFieldNameUTF; - JVM_GetCPFieldSignatureUTF; - JVM_GetCPMethodClassNameUTF; - JVM_GetCPMethodModifiers; - JVM_GetCPMethodNameUTF; - JVM_GetCPMethodSignatureUTF; - JVM_GetCallerClass; - JVM_GetClassAccessFlags; - JVM_GetClassAnnotations; - JVM_GetClassCPEntriesCount; - JVM_GetClassCPTypes; - JVM_GetClassConstantPool; - JVM_GetClassContext; - JVM_GetClassDeclaredConstructors; - JVM_GetClassDeclaredFields; - JVM_GetClassDeclaredMethods; - JVM_GetClassFieldsCount; - JVM_GetClassInterfaces; - JVM_GetClassLoader; - JVM_GetClassMethodsCount; - JVM_GetClassModifiers; - JVM_GetClassName; - JVM_GetClassNameUTF; - JVM_GetClassSignature; - JVM_GetClassSigners; - JVM_GetComponentType; - JVM_GetDeclaredClasses; - JVM_GetDeclaringClass; - JVM_GetEnclosingMethodInfo; - JVM_GetFieldAnnotations; - JVM_GetFieldIxModifiers; - JVM_GetHostName; - JVM_GetInheritedAccessControlContext; - JVM_GetInterfaceVersion; - JVM_GetLastErrorString; - JVM_GetManagement; - JVM_GetMethodAnnotations; - JVM_GetMethodDefaultAnnotationValue; - JVM_GetMethodIxArgsSize; - JVM_GetMethodIxByteCode; - JVM_GetMethodIxByteCodeLength; - JVM_GetMethodIxExceptionIndexes; - JVM_GetMethodIxExceptionTableEntry; - JVM_GetMethodIxExceptionTableLength; - JVM_GetMethodIxExceptionsCount; - JVM_GetMethodIxLocalsCount; - JVM_GetMethodIxMaxStack; - JVM_GetMethodIxModifiers; - JVM_GetMethodIxNameUTF; - JVM_GetMethodIxSignatureUTF; - JVM_GetMethodParameterAnnotations; - JVM_GetPrimitiveArrayElement; - JVM_GetProtectionDomain; - JVM_GetSockName; - JVM_GetSockOpt; - JVM_GetStackAccessControlContext; - JVM_GetStackTraceDepth; - JVM_GetStackTraceElement; - JVM_GetSystemPackage; - JVM_GetSystemPackages; - JVM_GetThreadStateNames; - JVM_GetThreadStateValues; - JVM_GetVersionInfo; - JVM_Halt; - JVM_HoldsLock; - JVM_IHashCode; - JVM_InitAgentProperties; - JVM_InitProperties; - JVM_InitializeCompiler; - JVM_InitializeSocketLibrary; - JVM_InternString; - JVM_Interrupt; - JVM_InvokeMethod; - JVM_IsArrayClass; - JVM_IsConstructorIx; - JVM_IsInterface; - JVM_IsInterrupted; - JVM_IsNaN; - JVM_IsPrimitiveClass; - JVM_IsSameClassPackage; - JVM_IsSilentCompiler; - JVM_IsSupportedJNIVersion; - JVM_IsThreadAlive; - JVM_LatestUserDefinedLoader; - JVM_Listen; - JVM_LoadClass0; - JVM_LoadLibrary; - JVM_Lseek; - JVM_MaxObjectInspectionAge; - JVM_MaxMemory; - JVM_MonitorNotify; - JVM_MonitorNotifyAll; - JVM_MonitorWait; - JVM_NativePath; - JVM_NanoTime; - JVM_NewArray; - JVM_NewInstanceFromConstructor; - JVM_NewMultiArray; - JVM_OnExit; - JVM_Open; - JVM_PrintStackTrace; - JVM_RaiseSignal; - JVM_RawMonitorCreate; - JVM_RawMonitorDestroy; - JVM_RawMonitorEnter; - JVM_RawMonitorExit; - JVM_Read; - JVM_Recv; - JVM_RecvFrom; - JVM_RegisterSignal; - JVM_ReleaseUTF; - JVM_ResolveClass; - JVM_ResumeThread; - JVM_Send; - JVM_SendTo; - JVM_SetArrayElement; - JVM_SetClassSigners; - JVM_SetLength; + + # JVM + JVM_Accept; + JVM_ActiveProcessorCount; + JVM_AllocateNewArray; + JVM_AllocateNewObject; + JVM_ArrayCopy; + JVM_AssertionStatusDirectives; + JVM_Available; + JVM_Bind; + JVM_ClassDepth; + JVM_ClassLoaderDepth; + JVM_Clone; + JVM_Close; + JVM_CX8Field; + JVM_CompileClass; + JVM_CompileClasses; + JVM_CompilerCommand; + JVM_Connect; + JVM_ConstantPoolGetClassAt; + JVM_ConstantPoolGetClassAtIfLoaded; + JVM_ConstantPoolGetDoubleAt; + JVM_ConstantPoolGetFieldAt; + JVM_ConstantPoolGetFieldAtIfLoaded; + JVM_ConstantPoolGetFloatAt; + JVM_ConstantPoolGetIntAt; + JVM_ConstantPoolGetLongAt; + JVM_ConstantPoolGetMethodAt; + JVM_ConstantPoolGetMethodAtIfLoaded; + JVM_ConstantPoolGetMemberRefInfoAt; + JVM_ConstantPoolGetSize; + JVM_ConstantPoolGetStringAt; + JVM_ConstantPoolGetUTF8At; + JVM_CountStackFrames; + JVM_CurrentClassLoader; + JVM_CurrentLoadedClass; + JVM_CurrentThread; + JVM_CurrentTimeMillis; + JVM_DefineClass; + JVM_DefineClassWithSource; + JVM_DefineClassWithSourceCond; + JVM_DesiredAssertionStatus; + JVM_DisableCompiler; + JVM_DoPrivileged; + JVM_DTraceGetVersion; + JVM_DTraceActivate; + JVM_DTraceIsProbeEnabled; + JVM_DTraceIsSupported; + JVM_DTraceDispose; + JVM_DumpAllStacks; + JVM_DumpThreads; + JVM_EnableCompiler; + JVM_Exit; + JVM_FillInStackTrace; + JVM_FindClassFromClass; + JVM_FindClassFromClassLoader; + JVM_FindClassFromBootLoader; + JVM_FindLibraryEntry; + JVM_FindLoadedClass; + JVM_FindPrimitiveClass; + JVM_FindSignal; + JVM_FreeMemory; + JVM_GC; + JVM_GetAllThreads; + JVM_GetArrayElement; + JVM_GetArrayLength; + JVM_GetCPClassNameUTF; + JVM_GetCPFieldClassNameUTF; + JVM_GetCPFieldModifiers; + JVM_GetCPFieldNameUTF; + JVM_GetCPFieldSignatureUTF; + JVM_GetCPMethodClassNameUTF; + JVM_GetCPMethodModifiers; + JVM_GetCPMethodNameUTF; + JVM_GetCPMethodSignatureUTF; + JVM_GetCallerClass; + JVM_GetClassAccessFlags; + JVM_GetClassAnnotations; + JVM_GetClassCPEntriesCount; + JVM_GetClassCPTypes; + JVM_GetClassConstantPool; + JVM_GetClassContext; + JVM_GetClassDeclaredConstructors; + JVM_GetClassDeclaredFields; + JVM_GetClassDeclaredMethods; + JVM_GetClassFieldsCount; + JVM_GetClassInterfaces; + JVM_GetClassLoader; + JVM_GetClassMethodsCount; + JVM_GetClassModifiers; + JVM_GetClassName; + JVM_GetClassNameUTF; + JVM_GetClassSignature; + JVM_GetClassSigners; + JVM_GetComponentType; + JVM_GetClassTypeAnnotations; + JVM_GetDeclaredClasses; + JVM_GetDeclaringClass; + JVM_GetEnclosingMethodInfo; + JVM_GetFieldAnnotations; + JVM_GetFieldIxModifiers; + JVM_GetHostName; + JVM_GetInheritedAccessControlContext; + JVM_GetInterfaceVersion; + JVM_GetLastErrorString; + JVM_GetManagement; + JVM_GetMethodAnnotations; + JVM_GetMethodDefaultAnnotationValue; + JVM_GetMethodIxArgsSize; + JVM_GetMethodIxByteCode; + JVM_GetMethodIxByteCodeLength; + JVM_GetMethodIxExceptionIndexes; + JVM_GetMethodIxExceptionTableEntry; + JVM_GetMethodIxExceptionTableLength; + JVM_GetMethodIxExceptionsCount; + JVM_GetMethodIxLocalsCount; + JVM_GetMethodIxMaxStack; + JVM_GetMethodIxModifiers; + JVM_GetMethodIxNameUTF; + JVM_GetMethodIxSignatureUTF; + JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; + JVM_GetPrimitiveArrayElement; + JVM_GetProtectionDomain; + JVM_GetSockName; + JVM_GetSockOpt; + JVM_GetStackAccessControlContext; + JVM_GetStackTraceDepth; + JVM_GetStackTraceElement; + JVM_GetSystemPackage; + JVM_GetSystemPackages; + JVM_GetThreadStateNames; + JVM_GetThreadStateValues; + JVM_GetVersionInfo; + JVM_Halt; + JVM_HoldsLock; + JVM_IHashCode; + JVM_InitAgentProperties; + JVM_InitProperties; + JVM_InitializeCompiler; + JVM_InitializeSocketLibrary; + JVM_InternString; + JVM_Interrupt; + JVM_InvokeMethod; + JVM_IsArrayClass; + JVM_IsConstructorIx; + JVM_IsInterface; + JVM_IsInterrupted; + JVM_IsNaN; + JVM_IsPrimitiveClass; + JVM_IsSameClassPackage; + JVM_IsSilentCompiler; + JVM_IsSupportedJNIVersion; + JVM_IsThreadAlive; + JVM_LatestUserDefinedLoader; + JVM_Listen; + JVM_LoadClass0; + JVM_LoadLibrary; + JVM_Lseek; + JVM_MaxObjectInspectionAge; + JVM_MaxMemory; + JVM_MonitorNotify; + JVM_MonitorNotifyAll; + JVM_MonitorWait; + JVM_NativePath; + JVM_NanoTime; + JVM_NewArray; + JVM_NewInstanceFromConstructor; + JVM_NewMultiArray; + JVM_OnExit; + JVM_Open; + JVM_PrintStackTrace; + JVM_RaiseSignal; + JVM_RawMonitorCreate; + JVM_RawMonitorDestroy; + JVM_RawMonitorEnter; + JVM_RawMonitorExit; + JVM_Read; + JVM_Recv; + JVM_RecvFrom; + JVM_RegisterSignal; + JVM_ReleaseUTF; + JVM_ResolveClass; + JVM_ResumeThread; + JVM_Send; + JVM_SendTo; + JVM_SetArrayElement; + JVM_SetClassSigners; + JVM_SetLength; JVM_SetNativeThreadName; - JVM_SetPrimitiveArrayElement; - JVM_SetProtectionDomain; - JVM_SetSockOpt; - JVM_SetThreadPriority; - JVM_Sleep; - JVM_Socket; - JVM_SocketAvailable; - JVM_SocketClose; - JVM_SocketShutdown; - JVM_StartThread; - JVM_StopThread; - JVM_SuspendThread; - JVM_SupportsCX8; - JVM_Sync; - JVM_Timeout; - JVM_TotalMemory; - JVM_TraceInstructions; - JVM_TraceMethodCalls; - JVM_UnloadLibrary; - JVM_Write; - JVM_Yield; - JVM_handle_solaris_signal; + JVM_SetPrimitiveArrayElement; + JVM_SetProtectionDomain; + JVM_SetSockOpt; + JVM_SetThreadPriority; + JVM_Sleep; + JVM_Socket; + JVM_SocketAvailable; + JVM_SocketClose; + JVM_SocketShutdown; + JVM_StartThread; + JVM_StopThread; + JVM_SuspendThread; + JVM_SupportsCX8; + JVM_Sync; + JVM_Timeout; + JVM_TotalMemory; + JVM_TraceInstructions; + JVM_TraceMethodCalls; + JVM_UnloadLibrary; + JVM_Write; + JVM_Yield; + JVM_handle_solaris_signal; - # miscellaneous functions - jio_fprintf; - jio_printf; - jio_snprintf; - jio_vfprintf; - jio_vsnprintf; + # miscellaneous functions + jio_fprintf; + jio_printf; + jio_snprintf; + jio_vfprintf; + jio_vsnprintf; - # Needed because there is no JVM interface for this. - sysThreadAvailableStackWithSlack; + # Needed because there is no JVM interface for this. + sysThreadAvailableStackWithSlack; - # This is for Forte Analyzer profiling support. - AsyncGetCallTrace; + # This is for Forte Analyzer profiling support. + AsyncGetCallTrace; - # INSERT VTABLE SYMBOLS HERE + # INSERT VTABLE SYMBOLS HERE local: *; diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/os/bsd/vm/os_bsd.cpp --- a/src/os/bsd/vm/os_bsd.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/os/bsd/vm/os_bsd.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -298,12 +298,12 @@ // The next steps are taken in the product version: // - // Obtain the JAVA_HOME value from the location of libjvm[_g].so. + // Obtain the JAVA_HOME value from the location of libjvm.so. // This library should be located at: - // /jre/lib//{client|server}/libjvm[_g].so. + // /jre/lib//{client|server}/libjvm.so. // // If "/jre/lib/" appears at the right place in the path, then we - // assume libjvm[_g].so is installed in a JDK and we use this path. + // assume libjvm.so is installed in a JDK and we use this path. // // Otherwise exit with message: "Could not create the Java virtual machine." // @@ -313,9 +313,9 @@ // instead of exit check for $JAVA_HOME environment variable. // // If it is defined and we are able to locate $JAVA_HOME/jre/lib/, - // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so - // it looks like libjvm[_g].so is installed there - // /jre/lib//hotspot/libjvm[_g].so. + // then we append a fake suffix "hotspot/libjvm.so" to this path so + // it looks like libjvm.so is installed there + // /jre/lib//hotspot/libjvm.so. // // Otherwise exit. // @@ -1228,7 +1228,7 @@ return getcwd(buf, buflen); } -// check if addr is inside libjvm[_g].so +// check if addr is inside libjvm.so bool os::address_is_in_vm(address addr) { static address libjvm_base_addr; Dl_info dlinfo; @@ -1689,7 +1689,7 @@ static char saved_jvm_path[MAXPATHLEN] = {0}; -// Find the full path to the current module, libjvm or libjvm_g +// Find the full path to the current module, libjvm void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -1732,10 +1732,9 @@ char* jrelib_p; int len; - // Check the current module name "libjvm" or "libjvm_g". + // Check the current module name "libjvm" p = strrchr(buf, '/'); assert(strstr(p, "/libjvm") == p, "invalid library name"); - p = strstr(p, "_g") ? "_g" : ""; rp = realpath(java_home_var, buf); if (rp == NULL) @@ -1764,11 +1763,9 @@ // to complete the path to JVM being overridden. Otherwise fallback // to the path to the current library. if (0 == access(buf, F_OK)) { - // Use current module name "libjvm[_g]" instead of - // "libjvm"debug_only("_g")"" since for fastdebug version - // we should have "libjvm" but debug_only("_g") adds "_g"! + // Use current module name "libjvm" len = strlen(buf); - snprintf(buf + len, buflen-len, "/libjvm%s%s", p, JNI_LIB_SUFFIX); + snprintf(buf + len, buflen-len, "/libjvm%s", JNI_LIB_SUFFIX); } else { // Fall back to path of current library rp = realpath(dli_fname, buf); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/os/linux/vm/os_linux.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -321,12 +321,12 @@ // The next steps are taken in the product version: // - // Obtain the JAVA_HOME value from the location of libjvm[_g].so. + // Obtain the JAVA_HOME value from the location of libjvm.so. // This library should be located at: - // /jre/lib//{client|server}/libjvm[_g].so. + // /jre/lib//{client|server}/libjvm.so. // // If "/jre/lib/" appears at the right place in the path, then we - // assume libjvm[_g].so is installed in a JDK and we use this path. + // assume libjvm.so is installed in a JDK and we use this path. // // Otherwise exit with message: "Could not create the Java virtual machine." // @@ -336,9 +336,9 @@ // instead of exit check for $JAVA_HOME environment variable. // // If it is defined and we are able to locate $JAVA_HOME/jre/lib/, - // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so - // it looks like libjvm[_g].so is installed there - // /jre/lib//hotspot/libjvm[_g].so. + // then we append a fake suffix "hotspot/libjvm.so" to this path so + // it looks like libjvm.so is installed there + // /jre/lib//hotspot/libjvm.so. // // Otherwise exit. // @@ -1679,7 +1679,7 @@ return getcwd(buf, buflen); } -// check if addr is inside libjvm[_g].so +// check if addr is inside libjvm.so bool os::address_is_in_vm(address addr) { static address libjvm_base_addr; Dl_info dlinfo; @@ -2180,7 +2180,7 @@ static char saved_jvm_path[MAXPATHLEN] = {0}; -// Find the full path to the current module, libjvm.so or libjvm_g.so +// Find the full path to the current module, libjvm.so void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -2223,10 +2223,9 @@ char* jrelib_p; int len; - // Check the current module name "libjvm.so" or "libjvm_g.so". + // Check the current module name "libjvm.so". p = strrchr(buf, '/'); assert(strstr(p, "/libjvm") == p, "invalid library name"); - p = strstr(p, "_g") ? "_g" : ""; rp = realpath(java_home_var, buf); if (rp == NULL) @@ -2242,11 +2241,9 @@ } if (0 == access(buf, F_OK)) { - // Use current module name "libjvm[_g].so" instead of - // "libjvm"debug_only("_g")".so" since for fastdebug version - // we should have "libjvm.so" but debug_only("_g") adds "_g"! + // Use current module name "libjvm.so" len = strlen(buf); - snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); + snprintf(buf + len, buflen-len, "/hotspot/libjvm.so"); } else { // Go back to path of .so rp = realpath(dli_fname, buf); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/os/solaris/vm/os_solaris.cpp --- a/src/os/solaris/vm/os_solaris.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/os/solaris/vm/os_solaris.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -734,12 +734,12 @@ // The next steps are taken in the product version: // - // Obtain the JAVA_HOME value from the location of libjvm[_g].so. + // Obtain the JAVA_HOME value from the location of libjvm.so. // This library should be located at: - // /jre/lib//{client|server}/libjvm[_g].so. + // /jre/lib//{client|server}/libjvm.so. // // If "/jre/lib/" appears at the right place in the path, then we - // assume libjvm[_g].so is installed in a JDK and we use this path. + // assume libjvm.so is installed in a JDK and we use this path. // // Otherwise exit with message: "Could not create the Java virtual machine." // @@ -749,9 +749,9 @@ // instead of exit check for $JAVA_HOME environment variable. // // If it is defined and we are able to locate $JAVA_HOME/jre/lib/, - // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so - // it looks like libjvm[_g].so is installed there - // /jre/lib//hotspot/libjvm[_g].so. + // then we append a fake suffix "hotspot/libjvm.so" to this path so + // it looks like libjvm.so is installed there + // /jre/lib//hotspot/libjvm.so. // // Otherwise exit. // @@ -1934,7 +1934,7 @@ return getcwd(buf, buflen); } -// check if addr is inside libjvm[_g].so +// check if addr is inside libjvm.so bool os::address_is_in_vm(address addr) { static address libjvm_base_addr; Dl_info dlinfo; @@ -2474,7 +2474,7 @@ static char saved_jvm_path[MAXPATHLEN] = { 0 }; -// Find the full path to the current module, libjvm.so or libjvm_g.so +// Find the full path to the current module, libjvm.so void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAXPATHLEN) { @@ -2522,10 +2522,9 @@ strcpy(cpu_arch, "amd64"); } #endif - // Check the current module name "libjvm.so" or "libjvm_g.so". + // Check the current module name "libjvm.so". p = strrchr(buf, '/'); assert(strstr(p, "/libjvm") == p, "invalid library name"); - p = strstr(p, "_g") ? "_g" : ""; realpath(java_home_var, buf); // determine if this is a legacy image or modules image @@ -2538,11 +2537,9 @@ } if (0 == access(buf, F_OK)) { - // Use current module name "libjvm[_g].so" instead of - // "libjvm"debug_only("_g")".so" since for fastdebug version - // we should have "libjvm.so" but debug_only("_g") adds "_g"! + // Use current module name "libjvm.so" len = strlen(buf); - snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); + snprintf(buf + len, buflen-len, "/hotspot/libjvm.so"); } else { // Go back to path of .so realpath((char *)dlinfo.dli_fname, buf); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/os/windows/vm/os_windows.cpp --- a/src/os/windows/vm/os_windows.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/os/windows/vm/os_windows.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -182,7 +182,7 @@ if (!getenv("_ALT_JAVA_HOME_DIR", home_dir, MAX_PATH)) { os::jvm_path(home_dir, sizeof(home_dir)); - // Found the full path to jvm[_g].dll. + // Found the full path to jvm.dll. // Now cut the path to /jre if we can. *(strrchr(home_dir, '\\')) = '\0'; /* get rid of \jvm.dll */ pslash = strrchr(home_dir, '\\'); @@ -1715,7 +1715,7 @@ static char saved_jvm_path[MAX_PATH] = {0}; -// Find the full path to the current module, jvm.dll or jvm_g.dll +// Find the full path to the current module, jvm.dll void os::jvm_path(char *buf, jint buflen) { // Error checking. if (buflen < MAX_PATH) { diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/tools/ProjectCreator/ProjectCreator.java --- a/src/share/tools/ProjectCreator/ProjectCreator.java Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/tools/ProjectCreator/ProjectCreator.java Wed Jan 09 18:06:34 2013 -0500 @@ -36,7 +36,7 @@ + "into .dsp file, substituting for path given in " + "-sourceBase. Example: HotSpotWorkSpace>"); System.err.println(" -dllLoc "); + + "jvm.dll; no trailing slash>"); System.err.println(" If any of the above are specified, " + "they must all be."); System.err.println(" Additional, optional arguments, which can be " diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -906,6 +906,7 @@ bool* is_synthetic_addr, u2* generic_signature_index_addr, AnnotationArray** field_annotations, + AnnotationArray** field_type_annotations, ClassFileParser::FieldAnnotationCollector* parsed_annotations, TRAPS) { ClassFileStream* cfs = stream(); @@ -917,6 +918,10 @@ int runtime_visible_annotations_length = 0; u1* runtime_invisible_annotations = NULL; int runtime_invisible_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; while (attributes_count--) { cfs->guarantee_more(6, CHECK); // attribute_name_index, attribute_length u2 attribute_name_index = cfs->get_u2_fast(); @@ -971,6 +976,16 @@ runtime_invisible_annotations = cfs->get_u1_buffer(); assert(runtime_invisible_annotations != NULL, "null invisible annotations"); cfs->skip_u1(runtime_invisible_annotations_length, CHECK); + } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + runtime_visible_type_annotations_length = attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); + } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); } else { cfs->skip_u1(attribute_length, CHECK); // Skip unknown attributes } @@ -988,6 +1003,12 @@ runtime_invisible_annotations, runtime_invisible_annotations_length, CHECK); + *field_type_annotations = assemble_annotations(loader_data, + runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK); return; } @@ -1084,6 +1105,7 @@ bool is_interface, FieldAllocationCount *fac, Array** fields_annotations, + Array** fields_type_annotations, u2* java_fields_count_ptr, TRAPS) { ClassFileStream* cfs = stream(); cfs->guarantee_more(2, CHECK_NULL); // length @@ -1119,6 +1141,7 @@ THREAD, u2, total_fields * (FieldInfo::field_slots + 1)); AnnotationArray* field_annotations = NULL; + AnnotationArray* field_type_annotations = NULL; // The generic signature slots start after all other fields' data. int generic_signature_slot = total_fields * FieldInfo::field_slots; int num_generic_signature = 0; @@ -1160,7 +1183,7 @@ cp, attributes_count, is_static, signature_index, &constantvalue_index, &is_synthetic, &generic_signature_index, &field_annotations, - &parsed_annotations, + &field_type_annotations, &parsed_annotations, CHECK_NULL); if (field_annotations != NULL) { if (*fields_annotations == NULL) { @@ -1170,6 +1193,14 @@ } (*fields_annotations)->at_put(n, field_annotations); } + if (field_type_annotations != NULL) { + if (*fields_type_annotations == NULL) { + *fields_type_annotations = MetadataFactory::new_array( + loader_data, length, NULL, + CHECK_NULL); + } + (*fields_type_annotations)->at_put(n, field_type_annotations); + } if (is_synthetic) { access_flags.set_is_synthetic(); } @@ -1831,6 +1862,7 @@ AnnotationArray** method_annotations, AnnotationArray** method_parameter_annotations, AnnotationArray** method_default_annotations, + AnnotationArray** method_type_annotations, TRAPS) { ClassFileStream* cfs = stream(); methodHandle nullHandle; @@ -1903,6 +1935,8 @@ u2** localvariable_table_start; u2* localvariable_type_table_length; u2** localvariable_type_table_start; + u2 method_parameters_length = 0; + u1* method_parameters_data = NULL; bool parsed_code_attribute = false; bool parsed_checked_exceptions_attribute = false; bool parsed_stackmap_attribute = false; @@ -1918,6 +1952,10 @@ int runtime_visible_parameter_annotations_length = 0; u1* runtime_invisible_parameter_annotations = NULL; int runtime_invisible_parameter_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; u1* annotation_default = NULL; int annotation_default_length = 0; @@ -2108,6 +2146,14 @@ parse_checked_exceptions(&checked_exceptions_length, method_attribute_length, cp, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_method_parameters()) { + method_parameters_length = cfs->get_u1_fast(); + method_parameters_data = cfs->get_u1_buffer(); + cfs->skip_u2_fast(method_parameters_length); + cfs->skip_u4_fast(method_parameters_length); + // ignore this attribute if it cannot be reflected + if (!SystemDictionary::Parameter_klass_loaded()) + method_parameters_length = 0; } else if (method_attribute_name == vmSymbols::tag_synthetic()) { if (method_attribute_length != 0) { classfile_parse_error( @@ -2159,6 +2205,17 @@ annotation_default = cfs->get_u1_buffer(); assert(annotation_default != NULL, "null annotation default"); cfs->skip_u1(annotation_default_length, CHECK_(nullHandle)); + } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) { + runtime_visible_type_annotations_length = method_attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + // No need for the VM to parse Type annotations + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_(nullHandle)); + } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) { + runtime_invisible_type_annotations_length = method_attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK_(nullHandle)); } else { // Skip unknown attributes cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); @@ -2184,7 +2241,8 @@ Method* m = Method::allocate( loader_data, code_length, access_flags, linenumber_table_length, total_lvt_length, exception_table_length, checked_exceptions_length, - generic_signature_index, ConstMethod::NORMAL, CHECK_(nullHandle)); + method_parameters_length, generic_signature_index, + ConstMethod::NORMAL, CHECK_(nullHandle)); ClassLoadingService::add_class_method_size(m->size()*HeapWordSize); @@ -2232,6 +2290,18 @@ exception_table_start, size); } + // Copy method parameters + if (method_parameters_length > 0) { + MethodParametersElement* elem = m->constMethod()->method_parameters_start(); + for(int i = 0; i < method_parameters_length; i++) { + elem[i].name_cp_index = + Bytes::get_Java_u2(method_parameters_data); + method_parameters_data += 2; + elem[i].flags = Bytes::get_Java_u4(method_parameters_data); + method_parameters_data += 4; + } + } + // Copy checked exceptions if (checked_exceptions_length > 0) { int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); @@ -2333,6 +2403,12 @@ NULL, 0, CHECK_(nullHandle)); + *method_type_annotations = assemble_annotations(loader_data, + runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK_(nullHandle)); if (name == vmSymbols::finalize_method_name() && signature == vmSymbols::void_method_signature()) { @@ -2364,12 +2440,14 @@ Array** methods_annotations, Array** methods_parameter_annotations, Array** methods_default_annotations, + Array** methods_type_annotations, bool* has_default_methods, TRAPS) { ClassFileStream* cfs = stream(); AnnotationArray* method_annotations = NULL; AnnotationArray* method_parameter_annotations = NULL; AnnotationArray* method_default_annotations = NULL; + AnnotationArray* method_type_annotations = NULL; cfs->guarantee_more(2, CHECK_NULL); // length u2 length = cfs->get_u2_fast(); if (length == 0) { @@ -2386,6 +2464,7 @@ &method_annotations, &method_parameter_annotations, &method_default_annotations, + &method_type_annotations, CHECK_NULL); if (method->is_final()) { @@ -2411,7 +2490,13 @@ MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); } (*methods_default_annotations)->at_put(index, method_default_annotations); + if (*methods_type_annotations == NULL) { + *methods_type_annotations = + MetadataFactory::new_array(loader_data, length, NULL, CHECK_NULL); + } + (*methods_type_annotations)->at_put(index, method_type_annotations); } + if (_need_verify && length > 1) { // Check duplicated methods ResourceMark rm(THREAD); @@ -2445,6 +2530,7 @@ Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, TRAPS) { int length = methods->length(); // If JVMTI original method ordering or sharing is enabled we have to @@ -2463,7 +2549,8 @@ // Note that the ordering is not alphabetical, see Symbol::fast_compare Method::sort_methods(methods, methods_annotations, methods_parameter_annotations, - methods_default_annotations); + methods_default_annotations, + methods_type_annotations); // If JVMTI original method ordering or sharing is enabled construct int // array remembering the original ordering @@ -2728,6 +2815,10 @@ int runtime_visible_annotations_length = 0; u1* runtime_invisible_annotations = NULL; int runtime_invisible_annotations_length = 0; + u1* runtime_visible_type_annotations = NULL; + int runtime_visible_type_annotations_length = 0; + u1* runtime_invisible_type_annotations = NULL; + int runtime_invisible_type_annotations_length = 0; u1* inner_classes_attribute_start = NULL; u4 inner_classes_attribute_length = 0; u2 enclosing_method_class_index = 0; @@ -2834,6 +2925,17 @@ classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK); parsed_bootstrap_methods_attribute = true; parse_classfile_bootstrap_methods_attribute(loader_data, cp, attribute_length, CHECK); + } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) { + runtime_visible_type_annotations_length = attribute_length; + runtime_visible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_visible_type_annotations != NULL, "null visible type annotations"); + // No need for the VM to parse Type annotations + cfs->skip_u1(runtime_visible_type_annotations_length, CHECK); + } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_type_annotations()) { + runtime_invisible_type_annotations_length = attribute_length; + runtime_invisible_type_annotations = cfs->get_u1_buffer(); + assert(runtime_invisible_type_annotations != NULL, "null invisible type annotations"); + cfs->skip_u1(runtime_invisible_type_annotations_length, CHECK); } else { // Unknown attribute cfs->skip_u1(attribute_length, CHECK); @@ -2850,6 +2952,13 @@ runtime_invisible_annotations_length, CHECK); set_class_annotations(annotations); + AnnotationArray* type_annotations = assemble_annotations(loader_data, + runtime_visible_type_annotations, + runtime_visible_type_annotations_length, + runtime_invisible_type_annotations, + runtime_invisible_type_annotations_length, + CHECK); + set_class_type_annotations(type_annotations); if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) { u2 num_of_classes = parse_classfile_inner_classes_attribute( @@ -2956,6 +3065,7 @@ TempNewSymbol& parsed_name, bool verify, TRAPS) { + // When a retransformable agent is attached, JVMTI caches the // class bytes that existed before the first retransformation. // If RedefineClasses() was used before the retransformable @@ -3190,7 +3300,9 @@ // Fields (offsets are filled in later) FieldAllocationCount fac; Array* fields_annotations = NULL; + Array* fields_type_annotations = NULL; Array* fields = parse_fields(loader_data, class_name, cp, access_flags.is_interface(), &fac, &fields_annotations, + &fields_type_annotations, &java_fields_count, CHECK_(nullHandle)); // Methods @@ -3202,6 +3314,7 @@ Array* methods_annotations = NULL; Array* methods_parameter_annotations = NULL; Array* methods_default_annotations = NULL; + Array* methods_type_annotations = NULL; Array* methods = parse_methods(loader_data, cp, access_flags.is_interface(), &promoted_flags, @@ -3209,6 +3322,7 @@ &methods_annotations, &methods_parameter_annotations, &methods_default_annotations, + &methods_type_annotations, &has_default_methods, CHECK_(nullHandle)); @@ -3270,6 +3384,7 @@ methods_annotations, methods_parameter_annotations, methods_default_annotations, + methods_type_annotations, CHECK_(nullHandle)); // promote flags from parse_methods() to the klass' flags @@ -3687,11 +3802,13 @@ if (is_anonymous()) // I am well known to myself cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve + // Allocate an annotation type if needed. if (fields_annotations != NULL || methods_annotations != NULL || methods_parameter_annotations != NULL || - methods_default_annotations != NULL) { - // Allocate an annotation type if needed. + methods_default_annotations != NULL || + fields_type_annotations != NULL || + methods_type_annotations != NULL) { Annotations* anno = Annotations::allocate(loader_data, fields_annotations, methods_annotations, methods_parameter_annotations, @@ -3701,6 +3818,16 @@ this_klass->set_annotations(NULL); } + if (fields_type_annotations != NULL || + methods_type_annotations != NULL) { + assert(this_klass->annotations() != NULL, "annotations should have been allocated"); + Annotations* anno = Annotations::allocate(loader_data, + fields_type_annotations, + methods_type_annotations, + NULL, + NULL, CHECK_(nullHandle)); + this_klass->annotations()->set_type_annotations(anno); + } this_klass->set_minor_version(minor_version); this_klass->set_major_version(major_version); @@ -3725,6 +3852,7 @@ // Fill in field values obtained by parse_classfile_attributes if (parsed_annotations.has_any_annotations()) parsed_annotations.apply_to(this_klass); + // Create annotations if (_annotations != NULL && this_klass->annotations() == NULL) { Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); @@ -3732,6 +3860,19 @@ } apply_parsed_class_attributes(this_klass); + // Create type annotations + if (_type_annotations != NULL) { + if (this_klass->annotations() == NULL) { + Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); + this_klass->set_annotations(anno); + } + if (this_klass->annotations()->type_annotations() == NULL) { + Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); + this_klass->annotations()->set_type_annotations(anno); + } + this_klass->annotations()->type_annotations()->set_class_annotations(_type_annotations); + } + // Miranda methods if ((num_miranda_methods > 0) || // if this class introduced new miranda methods or diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/classFileParser.hpp --- a/src/share/vm/classfile/classFileParser.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/classFileParser.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -64,6 +64,7 @@ int _sde_length; Array* _inner_classes; AnnotationArray* _annotations; + AnnotationArray* _type_annotations; void set_class_synthetic_flag(bool x) { _synthetic_flag = x; } void set_class_sourcefile(Symbol* x) { _sourcefile = x; } @@ -71,12 +72,14 @@ void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; } void set_class_inner_classes(Array* x) { _inner_classes = x; } void set_class_annotations(AnnotationArray* x) { _annotations = x; } + void set_class_type_annotations(AnnotationArray* x) { _type_annotations = x; } void init_parsed_class_attributes() { _synthetic_flag = false; _sourcefile = NULL; _generic_signature = NULL; _sde_buffer = NULL; _sde_length = 0; + _annotations = _type_annotations = NULL; // initialize the other flags too: _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false; _max_bootstrap_specifier_index = -1; @@ -163,6 +166,7 @@ bool* is_synthetic_addr, u2* generic_signature_index_addr, AnnotationArray** field_annotations, + AnnotationArray** field_type_annotations, FieldAnnotationCollector* parsed_annotations, TRAPS); Array* parse_fields(ClassLoaderData* loader_data, @@ -170,6 +174,7 @@ constantPoolHandle cp, bool is_interface, FieldAllocationCount *fac, Array** fields_annotations, + Array** fields_type_annotations, u2* java_fields_count_ptr, TRAPS); // Method parsing @@ -180,6 +185,7 @@ AnnotationArray** method_annotations, AnnotationArray** method_parameter_annotations, AnnotationArray** method_default_annotations, + AnnotationArray** method_type_annotations, TRAPS); Array* parse_methods(ClassLoaderData* loader_data, constantPoolHandle cp, @@ -189,6 +195,7 @@ Array** methods_annotations, Array** methods_parameter_annotations, Array** methods_default_annotations, + Array** methods_type_annotations, bool* has_default_method, TRAPS); Array* sort_methods(ClassLoaderData* loader_data, @@ -196,6 +203,7 @@ Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, TRAPS); u2* parse_exception_table(ClassLoaderData* loader_data, u4 code_length, u4 exception_table_length, diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/classFileStream.cpp --- a/src/share/vm/classfile/classFileStream.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/classFileStream.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -93,3 +93,10 @@ } _current += length * 2; } + +void ClassFileStream::skip_u4(int length, TRAPS) { + if (_need_verify) { + guarantee_more(length * 4, CHECK); + } + _current += length * 4; +} diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/classFileStream.hpp --- a/src/share/vm/classfile/classFileStream.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/classFileStream.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -133,6 +133,11 @@ _current += 2 * length; } + void skip_u4(int length, TRAPS); + void skip_u4_fast(int length) { + _current += 4 * length; + } + // Tells whether eos is reached bool at_eos() const { return _current == _buffer_end; } }; diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/defaultMethods.cpp --- a/src/share/vm/classfile/defaultMethods.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/defaultMethods.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -1148,7 +1148,8 @@ int code_length = bytecodes->length(); Method* m = Method::allocate(cp->pool_holder()->class_loader_data(), - code_length, flags, 0, 0, 0, 0, 0, mt, CHECK_NULL); + code_length, flags, 0, 0, 0, 0, 0, 0, + mt, CHECK_NULL); m->set_constants(NULL); // This will get filled in later m->set_name_index(cp->utf8(name)); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/javaClasses.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -1813,10 +1813,12 @@ annotations_offset = -1; parameter_annotations_offset = -1; annotation_default_offset = -1; + type_annotations_offset = -1; compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); compute_optional_offset(annotation_default_offset, k, vmSymbols::annotation_default_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Method::create(TRAPS) { @@ -1962,6 +1964,22 @@ method->obj_field_put(annotation_default_offset, value); } +bool java_lang_reflect_Method::has_type_annotations_field() { + return (type_annotations_offset >= 0); +} + +oop java_lang_reflect_Method::type_annotations(oop method) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + return method->obj_field(type_annotations_offset); +} + +void java_lang_reflect_Method::set_type_annotations(oop method, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + method->obj_field_put(type_annotations_offset, value); +} + void java_lang_reflect_Constructor::compute_offsets() { Klass* k = SystemDictionary::reflect_Constructor_klass(); compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); @@ -1973,9 +1991,11 @@ signature_offset = -1; annotations_offset = -1; parameter_annotations_offset = -1; + type_annotations_offset = -1; compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); compute_optional_offset(parameter_annotations_offset, k, vmSymbols::parameter_annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Constructor::create(TRAPS) { @@ -2086,6 +2106,22 @@ method->obj_field_put(parameter_annotations_offset, value); } +bool java_lang_reflect_Constructor::has_type_annotations_field() { + return (type_annotations_offset >= 0); +} + +oop java_lang_reflect_Constructor::type_annotations(oop constructor) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + return constructor->obj_field(type_annotations_offset); +} + +void java_lang_reflect_Constructor::set_type_annotations(oop constructor, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + constructor->obj_field_put(type_annotations_offset, value); +} + void java_lang_reflect_Field::compute_offsets() { Klass* k = SystemDictionary::reflect_Field_klass(); compute_offset(clazz_offset, k, vmSymbols::clazz_name(), vmSymbols::class_signature()); @@ -2096,8 +2132,10 @@ // The generic signature and annotations fields are only present in 1.5 signature_offset = -1; annotations_offset = -1; + type_annotations_offset = -1; compute_optional_offset(signature_offset, k, vmSymbols::signature_name(), vmSymbols::string_signature()); compute_optional_offset(annotations_offset, k, vmSymbols::annotations_name(), vmSymbols::byte_array_signature()); + compute_optional_offset(type_annotations_offset, k, vmSymbols::type_annotations_name(), vmSymbols::byte_array_signature()); } Handle java_lang_reflect_Field::create(TRAPS) { @@ -2192,6 +2230,21 @@ field->obj_field_put(annotations_offset, value); } +bool java_lang_reflect_Field::has_type_annotations_field() { + return (type_annotations_offset >= 0); +} + +oop java_lang_reflect_Field::type_annotations(oop field) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + return field->obj_field(type_annotations_offset); +} + +void java_lang_reflect_Field::set_type_annotations(oop field, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(has_type_annotations_field(), "type_annotations field must be present"); + field->obj_field_put(type_annotations_offset, value); +} void sun_reflect_ConstantPool::compute_offsets() { Klass* k = SystemDictionary::reflect_ConstantPool_klass(); @@ -2202,6 +2255,66 @@ } } +void java_lang_reflect_Parameter::compute_offsets() { + Klass* k = SystemDictionary::reflect_Parameter_klass(); + if(NULL != k) { + compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); + compute_offset(modifiers_offset, k, vmSymbols::modifiers_name(), vmSymbols::int_signature()); + compute_offset(index_offset, k, vmSymbols::index_name(), vmSymbols::int_signature()); + compute_offset(executable_offset, k, vmSymbols::executable_name(), vmSymbols::executable_signature()); + } +} + +Handle java_lang_reflect_Parameter::create(TRAPS) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + Symbol* name = vmSymbols::java_lang_reflect_Parameter(); + Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); + instanceKlassHandle klass (THREAD, k); + // Ensure it is initialized + klass->initialize(CHECK_NH); + return klass->allocate_instance_handle(CHECK_NH); +} + +oop java_lang_reflect_Parameter::name(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->obj_field(name_offset); +} + +void java_lang_reflect_Parameter::set_name(oop param, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->obj_field_put(name_offset, value); +} + +int java_lang_reflect_Parameter::modifiers(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->int_field(modifiers_offset); +} + +void java_lang_reflect_Parameter::set_modifiers(oop param, int value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->int_field_put(modifiers_offset, value); +} + +int java_lang_reflect_Parameter::index(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->int_field(index_offset); +} + +void java_lang_reflect_Parameter::set_index(oop param, int value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->int_field_put(index_offset, value); +} + +oop java_lang_reflect_Parameter::executable(oop param) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return param->obj_field(executable_offset); +} + +void java_lang_reflect_Parameter::set_executable(oop param, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + param->obj_field_put(executable_offset, value); +} + Handle sun_reflect_ConstantPool::create(TRAPS) { assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); @@ -2857,6 +2970,7 @@ int java_lang_reflect_Method::annotations_offset; int java_lang_reflect_Method::parameter_annotations_offset; int java_lang_reflect_Method::annotation_default_offset; +int java_lang_reflect_Method::type_annotations_offset; int java_lang_reflect_Constructor::clazz_offset; int java_lang_reflect_Constructor::parameterTypes_offset; int java_lang_reflect_Constructor::exceptionTypes_offset; @@ -2865,6 +2979,7 @@ int java_lang_reflect_Constructor::signature_offset; int java_lang_reflect_Constructor::annotations_offset; int java_lang_reflect_Constructor::parameter_annotations_offset; +int java_lang_reflect_Constructor::type_annotations_offset; int java_lang_reflect_Field::clazz_offset; int java_lang_reflect_Field::name_offset; int java_lang_reflect_Field::type_offset; @@ -2872,6 +2987,11 @@ int java_lang_reflect_Field::modifiers_offset; int java_lang_reflect_Field::signature_offset; int java_lang_reflect_Field::annotations_offset; +int java_lang_reflect_Field::type_annotations_offset; +int java_lang_reflect_Parameter::name_offset; +int java_lang_reflect_Parameter::modifiers_offset; +int java_lang_reflect_Parameter::index_offset; +int java_lang_reflect_Parameter::executable_offset; int java_lang_boxing_object::value_offset; int java_lang_boxing_object::long_value_offset; int java_lang_ref_Reference::referent_offset; @@ -3056,6 +3176,8 @@ sun_reflect_ConstantPool::compute_offsets(); sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets(); } + if (JDK_Version::is_jdk18x_version()) + java_lang_reflect_Parameter::compute_offsets(); // generated interpreter code wants to know about the offsets we just computed: AbstractAssembler::update_delayed_values(); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/javaClasses.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -554,6 +554,7 @@ static int annotations_offset; static int parameter_annotations_offset; static int annotation_default_offset; + static int type_annotations_offset; static void compute_offsets(); @@ -599,6 +600,10 @@ static oop annotation_default(oop method); static void set_annotation_default(oop method, oop value); + static bool has_type_annotations_field(); + static oop type_annotations(oop method); + static void set_type_annotations(oop method, oop value); + // Debugging friend class JavaClasses; }; @@ -618,6 +623,7 @@ static int signature_offset; static int annotations_offset; static int parameter_annotations_offset; + static int type_annotations_offset; static void compute_offsets(); @@ -653,6 +659,10 @@ static oop parameter_annotations(oop method); static void set_parameter_annotations(oop method, oop value); + static bool has_type_annotations_field(); + static oop type_annotations(oop constructor); + static void set_type_annotations(oop constructor, oop value); + // Debugging friend class JavaClasses; }; @@ -671,6 +681,7 @@ static int modifiers_offset; static int signature_offset; static int annotations_offset; + static int type_annotations_offset; static void compute_offsets(); @@ -710,10 +721,45 @@ static oop annotation_default(oop method); static void set_annotation_default(oop method, oop value); + static bool has_type_annotations_field(); + static oop type_annotations(oop field); + static void set_type_annotations(oop field, oop value); + // Debugging friend class JavaClasses; }; +class java_lang_reflect_Parameter { + private: + // Note that to reduce dependencies on the JDK we compute these + // offsets at run-time. + static int name_offset; + static int modifiers_offset; + static int index_offset; + static int executable_offset; + + static void compute_offsets(); + + public: + // Allocation + static Handle create(TRAPS); + + // Accessors + static oop name(oop field); + static void set_name(oop field, oop value); + + static int index(oop reflect); + static void set_index(oop reflect, int value); + + static int modifiers(oop reflect); + static void set_modifiers(oop reflect, int value); + + static oop executable(oop constructor); + static void set_executable(oop constructor, oop value); + + friend class JavaClasses; +}; + // Interface to sun.reflect.ConstantPool objects class sun_reflect_ConstantPool { private: diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -131,6 +131,7 @@ do_klass(Properties_klass, java_util_Properties, Pre ) \ do_klass(reflect_AccessibleObject_klass, java_lang_reflect_AccessibleObject, Pre ) \ do_klass(reflect_Field_klass, java_lang_reflect_Field, Pre ) \ + do_klass(reflect_Parameter_klass, java_lang_reflect_Parameter, Opt ) \ do_klass(reflect_Method_klass, java_lang_reflect_Method, Pre ) \ do_klass(reflect_Constructor_klass, java_lang_reflect_Constructor, Pre ) \ \ @@ -459,6 +460,7 @@ // Tells whether ClassLoader.checkPackageAccess is present static bool has_checkPackageAccess() { return _has_checkPackageAccess; } + static bool Parameter_klass_loaded() { return WK_KLASS(reflect_Parameter_klass) != NULL; } static bool Class_klass_loaded() { return WK_KLASS(Class_klass) != NULL; } static bool Cloneable_klass_loaded() { return WK_KLASS(Cloneable_klass) != NULL; } static bool Object_klass_loaded() { return WK_KLASS(Object_klass) != NULL; } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -86,6 +86,7 @@ template(java_lang_reflect_Method, "java/lang/reflect/Method") \ template(java_lang_reflect_Constructor, "java/lang/reflect/Constructor") \ template(java_lang_reflect_Field, "java/lang/reflect/Field") \ + template(java_lang_reflect_Parameter, "java/lang/reflect/Parameter") \ template(java_lang_reflect_Array, "java/lang/reflect/Array") \ template(java_lang_StringBuffer, "java/lang/StringBuffer") \ template(java_lang_StringBuilder, "java/lang/StringBuilder") \ @@ -126,6 +127,7 @@ template(tag_line_number_table, "LineNumberTable") \ template(tag_local_variable_table, "LocalVariableTable") \ template(tag_local_variable_type_table, "LocalVariableTypeTable") \ + template(tag_method_parameters, "MethodParameters") \ template(tag_stack_map_table, "StackMapTable") \ template(tag_synthetic, "Synthetic") \ template(tag_deprecated, "Deprecated") \ @@ -136,6 +138,8 @@ template(tag_runtime_visible_parameter_annotations, "RuntimeVisibleParameterAnnotations") \ template(tag_runtime_invisible_parameter_annotations,"RuntimeInvisibleParameterAnnotations") \ template(tag_annotation_default, "AnnotationDefault") \ + template(tag_runtime_visible_type_annotations, "RuntimeVisibleTypeAnnotations") \ + template(tag_runtime_invisible_type_annotations, "RuntimeInvisibleTypeAnnotations") \ template(tag_enclosing_method, "EnclosingMethod") \ template(tag_bootstrap_methods, "BootstrapMethods") \ \ @@ -233,12 +237,17 @@ /* Support for annotations (JDK 1.5 and above) */ \ \ template(annotations_name, "annotations") \ + template(index_name, "index") \ + template(executable_name, "executable") \ template(parameter_annotations_name, "parameterAnnotations") \ template(annotation_default_name, "annotationDefault") \ template(sun_reflect_ConstantPool, "sun/reflect/ConstantPool") \ template(ConstantPool_name, "constantPoolOop") \ template(sun_reflect_UnsafeStaticFieldAccessorImpl, "sun/reflect/UnsafeStaticFieldAccessorImpl")\ template(base_name, "base") \ + /* Type Annotations (JDK 8 and above) */ \ + template(type_annotations_name, "typeAnnotations") \ + \ \ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ @@ -470,6 +479,7 @@ template(class_signature, "Ljava/lang/Class;") \ template(string_signature, "Ljava/lang/String;") \ template(reference_signature, "Ljava/lang/ref/Reference;") \ + template(executable_signature, "Ljava/lang/reflect/Executable;") \ template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \ template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \ template(int_StringBuilder_signature, "(I)Ljava/lang/StringBuilder;") \ diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/interpreter/rewriter.cpp --- a/src/share/vm/interpreter/rewriter.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/interpreter/rewriter.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -27,13 +27,8 @@ #include "interpreter/interpreter.hpp" #include "interpreter/rewriter.hpp" #include "memory/gcLocker.hpp" -#include "memory/metadataFactory.hpp" -#include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/generateOopMap.hpp" -#include "oops/objArrayOop.hpp" -#include "oops/oop.inline.hpp" -#include "prims/methodComparator.hpp" #include "prims/methodHandles.hpp" // Computes a CPC map (new_index -> original_index) for constant pool entries @@ -402,13 +397,6 @@ } -void Rewriter::rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) { - ResourceMark rm(THREAD); - Rewriter rw(klass, cpool, methods, CHECK); - // (That's all, folks.) -} - - Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) : _klass(klass), _pool(cpool), @@ -453,46 +441,25 @@ restore_bytecodes(); return; } -} -// Relocate jsr/rets in a method. This can't be done with the rewriter -// stage because it can throw other exceptions, leaving the bytecodes -// pointing at constant pool cache entries. -// Link and check jvmti dependencies while we're iterating over the methods. -// JSR292 code calls with a different set of methods, so two entry points. -void Rewriter::relocate_and_link(instanceKlassHandle this_oop, TRAPS) { - relocate_and_link(this_oop, this_oop->methods(), THREAD); -} - -void Rewriter::relocate_and_link(instanceKlassHandle this_oop, - Array* methods, TRAPS) { - int len = methods->length(); + // Relocate after everything, but still do this under the is_rewritten flag, + // so methods with jsrs in custom class lists in aren't attempted to be + // rewritten in the RO section of the shared archive. + // Relocated bytecodes don't have to be restored, only the cp cache entries for (int i = len-1; i >= 0; i--) { - methodHandle m(THREAD, methods->at(i)); + methodHandle m(THREAD, _methods->at(i)); if (m->has_jsrs()) { - m = rewrite_jsrs(m, CHECK); + m = rewrite_jsrs(m, THREAD); + // Restore bytecodes to their unrewritten state if there are exceptions + // relocating bytecodes. If some are relocated, that is ok because that + // doesn't affect constant pool to cpCache rewriting. + if (HAS_PENDING_EXCEPTION) { + restore_bytecodes(); + return; + } // Method might have gotten rewritten. methods->at_put(i, m()); } - - // Set up method entry points for compiler and interpreter . - m->link_method(m, CHECK); - - // This is for JVMTI and unrelated to relocator but the last thing we do -#ifdef ASSERT - if (StressMethodComparator) { - static int nmc = 0; - for (int j = i; j >= 0 && j >= i-4; j--) { - if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); - bool z = MethodComparator::methods_EMCP(m(), - methods->at(j)); - if (j == i && !z) { - tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); - assert(z, "method must compare equal to itself"); - } - } - } -#endif //ASSERT } } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/interpreter/rewriter.hpp --- a/src/share/vm/interpreter/rewriter.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/interpreter/rewriter.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -158,14 +158,6 @@ public: // Driver routine: static void rewrite(instanceKlassHandle klass, TRAPS); - static void rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS); - - // Second pass, not gated by is_rewritten flag - static void relocate_and_link(instanceKlassHandle klass, TRAPS); - // JSR292 version to call with it's own methods. - static void relocate_and_link(instanceKlassHandle klass, - Array* methods, TRAPS); - }; #endif // SHARE_VM_INTERPRETER_REWRITER_HPP diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/memory/filemap.cpp --- a/src/share/vm/memory/filemap.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/memory/filemap.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -119,6 +119,7 @@ _header._magic = 0xf00baba2; _header._version = _current_version; _header._alignment = alignment; + _header._obj_alignment = ObjectAlignmentInBytes; // The following fields are for sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's @@ -211,7 +212,11 @@ // Remove the existing file in case another process has it open. remove(_full_path); +#ifdef _WINDOWS // if 0444 is used on Windows, then remove() will fail. + int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0744); +#else int fd = open(_full_path, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0444); +#endif if (fd < 0) { fail_stop("Unable to create shared archive file %s.", _full_path); } @@ -370,9 +375,8 @@ return rs; } // the reserved virtual memory is for mapping class data sharing archive - if (MemTracker::is_on()) { - MemTracker::record_virtual_memory_type((address)rs.base(), mtClassShared); - } + MemTracker::record_virtual_memory_type((address)rs.base(), mtClassShared); + return rs; } @@ -394,6 +398,11 @@ fail_continue(err_msg("Unable to map %s shared space at required address.", shared_region_name[i])); return NULL; } +#ifdef _WINDOWS + // This call is Windows-only because the memory_type gets recorded for the other platforms + // in method FileMapInfo::reserve_shared_memory(), which is not called on Windows. + MemTracker::record_virtual_memory_type((address)base, mtClassShared); +#endif return base; } @@ -465,6 +474,12 @@ " version or build of HotSpot."); return false; } + if (_header._obj_alignment != ObjectAlignmentInBytes) { + fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" + " does not equal the current ObjectAlignmentInBytes of %d.", + _header._obj_alignment, ObjectAlignmentInBytes); + return false; + } // Cannot verify interpreter yet, as it can only be created after the GC // heap has been initialized. diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/memory/filemap.hpp --- a/src/share/vm/memory/filemap.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/memory/filemap.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -63,6 +63,7 @@ int _magic; // identify file type. int _version; // (from enum, above.) size_t _alignment; // how shared archive should be aligned + int _obj_alignment; // value of ObjectAlignmentInBytes struct space_info { int _file_offset; // sizeof(this) rounded to vm page size diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/memory/metaspaceShared.cpp --- a/src/share/vm/memory/metaspaceShared.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/memory/metaspaceShared.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -689,9 +689,15 @@ bool MetaspaceShared::map_shared_spaces(FileMapInfo* mapinfo) { size_t image_alignment = mapinfo->alignment(); - // Map in the shared memory and then map the regions on top of it +#ifndef _WINDOWS + // Map in the shared memory and then map the regions on top of it. + // On Windows, don't map the memory here because it will cause the + // mappings of the regions to fail. ReservedSpace shared_rs = mapinfo->reserve_shared_memory(); if (!shared_rs.is_reserved()) return false; +#endif + + assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces"); // Map each shared region if ((_ro_base = mapinfo->map_region(ro)) != NULL && @@ -708,8 +714,10 @@ if (_rw_base != NULL) mapinfo->unmap_region(rw); if (_md_base != NULL) mapinfo->unmap_region(md); if (_mc_base != NULL) mapinfo->unmap_region(mc); +#ifndef _WINDOWS // Release the entire mapped region shared_rs.release(); +#endif // If -Xshare:on is specified, print out the error message and exit VM, // otherwise, set UseSharedSpaces to false and continue. if (RequireSharedSpaces) { diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/annotations.cpp --- a/src/share/vm/oops/annotations.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/annotations.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -61,6 +61,9 @@ free_contents(loader_data, methods_annotations()); free_contents(loader_data, methods_parameter_annotations()); free_contents(loader_data, methods_default_annotations()); + + // Recursively deallocate optional Annotations linked through this one + MetadataFactory::free_metadata(loader_data, type_annotations()); } // Set the annotation at 'idnum' to 'anno'. diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/annotations.hpp --- a/src/share/vm/oops/annotations.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/annotations.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -38,7 +38,8 @@ typedef Array AnnotationArray; // Class to hold the various types of annotations. The only metadata that points -// to this is InstanceKlass. +// to this is InstanceKlass, or another Annotations instance if this is a +// a type_annotation instance. class Annotations: public MetaspaceObj { @@ -58,6 +59,8 @@ // such annotations. // Index is the idnum, which is initially the same as the methods array index. Array* _methods_default_annotations; + // Type annotations for this class, or null if none. + Annotations* _type_annotations; // Constructor where some some values are known to not be null Annotations(Array* fa, Array* ma, @@ -66,7 +69,8 @@ _fields_annotations(fa), _methods_annotations(ma), _methods_parameter_annotations(mpa), - _methods_default_annotations(mda) {} + _methods_default_annotations(mda), + _type_annotations(NULL) {} public: // Allocate instance of this class @@ -81,22 +85,26 @@ static int size() { return sizeof(Annotations) / wordSize; } // Constructor to initialize to null - Annotations() : _class_annotations(NULL), _fields_annotations(NULL), + Annotations() : _class_annotations(NULL), + _fields_annotations(NULL), _methods_annotations(NULL), _methods_parameter_annotations(NULL), - _methods_default_annotations(NULL) {} + _methods_default_annotations(NULL), + _type_annotations(NULL) {} AnnotationArray* class_annotations() const { return _class_annotations; } Array* fields_annotations() const { return _fields_annotations; } Array* methods_annotations() const { return _methods_annotations; } Array* methods_parameter_annotations() const { return _methods_parameter_annotations; } Array* methods_default_annotations() const { return _methods_default_annotations; } + Annotations* type_annotations() const { return _type_annotations; } void set_class_annotations(AnnotationArray* md) { _class_annotations = md; } void set_fields_annotations(Array* md) { _fields_annotations = md; } void set_methods_annotations(Array* md) { _methods_annotations = md; } void set_methods_parameter_annotations(Array* md) { _methods_parameter_annotations = md; } void set_methods_default_annotations(Array* md) { _methods_default_annotations = md; } + void set_type_annotations(Annotations* annos) { _type_annotations = annos; } // Redefine classes support AnnotationArray* get_method_annotations_of(int idnum) @@ -129,6 +137,7 @@ inline AnnotationArray* get_method_annotations_from(int idnum, Array* annos); void set_annotations(Array* md, Array** md_p) { *md_p = md; } + bool is_klass() const { return false; } private: void set_methods_annotations_of(instanceKlassHandle ik, int idnum, AnnotationArray* anno, diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/constMethod.cpp --- a/src/share/vm/oops/constMethod.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/constMethod.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -39,18 +39,21 @@ int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType method_type, TRAPS) { int size = ConstMethod::size(byte_code_size, - compressed_line_number_size, - localvariable_table_length, - exception_table_length, - checked_exceptions_length, - generic_signature_index); + compressed_line_number_size, + localvariable_table_length, + exception_table_length, + checked_exceptions_length, + method_parameters_length, + generic_signature_index); return new (loader_data, size, true, THREAD) ConstMethod( byte_code_size, compressed_line_number_size, localvariable_table_length, - exception_table_length, checked_exceptions_length, generic_signature_index, + exception_table_length, checked_exceptions_length, + method_parameters_length, generic_signature_index, method_type, size); } @@ -59,6 +62,7 @@ int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType method_type, int size) { @@ -74,7 +78,8 @@ checked_exceptions_length, compressed_line_number_size, localvariable_table_length, - exception_table_length); + exception_table_length, + method_parameters_length); set_method_type(method_type); assert(this->size() == size, "wrong size for object"); } @@ -92,11 +97,12 @@ // How big must this constMethodObject be? int ConstMethod::size(int code_size, - int compressed_line_number_size, - int local_variable_table_length, - int exception_table_length, - int checked_exceptions_length, - u2 generic_signature_index) { + int compressed_line_number_size, + int local_variable_table_length, + int exception_table_length, + int checked_exceptions_length, + int method_parameters_length, + u2 generic_signature_index) { int extra_bytes = code_size; if (compressed_line_number_size > 0) { extra_bytes += compressed_line_number_size; @@ -117,6 +123,10 @@ if (generic_signature_index != 0) { extra_bytes += sizeof(u2); } + if (method_parameters_length > 0) { + extra_bytes += sizeof(u2); + extra_bytes += method_parameters_length * sizeof(MethodParametersElement); + } int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord; return align_object_size(header_size() + extra_words); } @@ -143,6 +153,18 @@ u2* ConstMethod::checked_exceptions_length_addr() const { // Located immediately before the generic signature index. assert(has_checked_exceptions(), "called only if table is present"); + if(has_method_parameters()) { + // If method parameters present, locate immediately before them. + return (u2*)method_parameters_start() - 1; + } else { + // Else, the exception table is at the end of the constMethod. + return has_generic_signature() ? (last_u2_element() - 1) : + last_u2_element(); + } +} + +u2* ConstMethod::method_parameters_length_addr() const { + assert(has_method_parameters(), "called only if table is present"); return has_generic_signature() ? (last_u2_element() - 1) : last_u2_element(); } @@ -153,11 +175,15 @@ // If checked_exception present, locate immediately before them. return (u2*) checked_exceptions_start() - 1; } else { - // Else, the exception table is at the end of the constMethod or - // immediately before the generic signature index. + if(has_method_parameters()) { + // If method parameters present, locate immediately before them. + return (u2*)method_parameters_start() - 1; + } else { + // Else, the exception table is at the end of the constMethod. return has_generic_signature() ? (last_u2_element() - 1) : last_u2_element(); } + } } u2* ConstMethod::localvariable_table_length_addr() const { @@ -170,12 +196,16 @@ // If checked_exception present, locate immediately before them. return (u2*) checked_exceptions_start() - 1; } else { - // Else, the linenumber table is at the end of the constMethod or - // immediately before the generic signature index. + if(has_method_parameters()) { + // If method parameters present, locate immediately before them. + return (u2*)method_parameters_start() - 1; + } else { + // Else, the exception table is at the end of the constMethod. return has_generic_signature() ? (last_u2_element() - 1) : last_u2_element(); } } + } } // Update the flags to indicate the presence of these optional fields. @@ -183,29 +213,57 @@ int checked_exceptions_len, int compressed_line_number_size, int localvariable_table_len, - int exception_table_len) { - // Must be done in the order below, otherwise length_addr accessors - // will not work. Only set bit in header if length is positive. + int exception_table_len, + int method_parameters_len) { assert(_flags == 0, "Error"); - if (compressed_line_number_size > 0) { + if (compressed_line_number_size > 0) _flags |= _has_linenumber_table; - } - if (generic_signature_index != 0) { + if (generic_signature_index != 0) _flags |= _has_generic_signature; + if (method_parameters_len > 0) + _flags |= _has_method_parameters; + if (checked_exceptions_len > 0) + _flags |= _has_checked_exceptions; + if (exception_table_len > 0) + _flags |= _has_exception_table; + if (localvariable_table_len > 0) + _flags |= _has_localvariable_table; + + // This code is extremely brittle and should possibly be revised. + // The *_length_addr functions walk backwards through the + // constMethod data, using each of the length indexes ahead of them, + // as well as the flags variable. Therefore, the indexes must be + // initialized in reverse order, or else they will compute the wrong + // offsets. Moving the initialization of _flags into a separate + // block solves *half* of the problem, but the following part will + // still break if the order is not exactly right. + // + // Also, the servicability agent needs to be informed anytime + // anything is added here. It might be advisable to have some sort + // of indication of this inline. + if (generic_signature_index != 0) *(generic_signature_index_addr()) = generic_signature_index; - } - if (checked_exceptions_len > 0) { - _flags |= _has_checked_exceptions; + // New data should probably go here. + if (method_parameters_len > 0) + *(method_parameters_length_addr()) = method_parameters_len; + if (checked_exceptions_len > 0) *(checked_exceptions_length_addr()) = checked_exceptions_len; - } - if (exception_table_len > 0) { - _flags |= _has_exception_table; + if (exception_table_len > 0) *(exception_table_length_addr()) = exception_table_len; - } - if (localvariable_table_len > 0) { - _flags |= _has_localvariable_table; + if (localvariable_table_len > 0) *(localvariable_table_length_addr()) = localvariable_table_len; - } +} + +int ConstMethod::method_parameters_length() const { + return has_method_parameters() ? *(method_parameters_length_addr()) : 0; +} + +MethodParametersElement* ConstMethod::method_parameters_start() const { + u2* addr = method_parameters_length_addr(); + u2 length = *addr; + assert(length > 0, "should only be called if table is present"); + addr -= length * sizeof(MethodParametersElement) / sizeof(u2); + return (MethodParametersElement*) addr; } @@ -298,6 +356,10 @@ } guarantee(compressed_table_end <= m_end, "invalid method layout"); // Verify checked exceptions, exception table and local variable tables + if (has_method_parameters()) { + u2* addr = method_parameters_length_addr(); + guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); + } if (has_checked_exceptions()) { u2* addr = checked_exceptions_length_addr(); guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); @@ -318,6 +380,8 @@ uncompressed_table_start = (u2*) exception_table_start(); } else if (has_checked_exceptions()) { uncompressed_table_start = (u2*) checked_exceptions_start(); + } else if (has_method_parameters()) { + uncompressed_table_start = (u2*) method_parameters_start(); } else { uncompressed_table_start = (u2*) m_end; } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/constMethod.hpp --- a/src/share/vm/oops/constMethod.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/constMethod.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -77,9 +77,18 @@ // | (access flags bit tells whether table is present) | // | (indexed from end of ConstMethod*) | // |------------------------------------------------------| +// | method parameters elements + length (length last) | +// | (length is u2, elements are u2, u4 structures) | +// | (see class MethodParametersElement) | +// | (access flags bit tells whether table is present) | +// | (indexed from end of ConstMethod*) | +// |------------------------------------------------------| // | generic signature index (u2) | // | (indexed from start of constMethodOop) | // |------------------------------------------------------| +// +// IMPORTANT: If anything gets added here, there need to be changes to +// ensure that ServicabilityAgent doesn't get broken as a result! // Utitily class decribing elements in checked exceptions table inlined in Method*. @@ -109,6 +118,13 @@ u2 catch_type_index; }; +// Utility class describing elements in method parameters +class MethodParametersElement VALUE_OBJ_CLASS_SPEC { + public: + u2 name_cp_index; + u4 flags; +}; + class ConstMethod : public MetaspaceObj { friend class VMStructs; @@ -123,7 +139,8 @@ _has_localvariable_table = 4, _has_exception_table = 8, _has_generic_signature = 16, - _is_overpass = 32 + _has_method_parameters = 32, + _is_overpass = 64 }; // Bit vector of signature @@ -160,6 +177,7 @@ int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType is_overpass, int size); @@ -171,6 +189,7 @@ int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, MethodType mt, TRAPS); @@ -182,7 +201,8 @@ int checked_exceptions_len, int compressed_line_number_size, int localvariable_table_len, - int exception_table_len); + int exception_table_len, + int method_parameters_length); bool has_generic_signature() const { return (_flags & _has_generic_signature) != 0; } @@ -199,6 +219,9 @@ bool has_exception_handler() const { return (_flags & _has_exception_table) != 0; } + bool has_method_parameters() const + { return (_flags & _has_method_parameters) != 0; } + MethodType method_type() const { return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS; } @@ -284,10 +307,11 @@ // Size needed static int size(int code_size, int compressed_line_number_size, - int local_variable_table_length, - int exception_table_length, - int checked_exceptions_length, - u2 generic_signature_index); + int local_variable_table_length, + int exception_table_length, + int checked_exceptions_length, + int method_parameters_length, + u2 generic_signature_index); int size() const { return _constMethod_size;} void set_constMethod_size(int size) { _constMethod_size = size; } @@ -308,6 +332,7 @@ u2* checked_exceptions_length_addr() const; u2* localvariable_table_length_addr() const; u2* exception_table_length_addr() const; + u2* method_parameters_length_addr() const; // checked exceptions int checked_exceptions_length() const; @@ -321,6 +346,10 @@ int exception_table_length() const; ExceptionTableElement* exception_table_start() const; + // method parameters table + int method_parameters_length() const; + MethodParametersElement* method_parameters_start() const; + // byte codes void set_code(address code) { if (code_size() > 0) { diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -47,6 +47,7 @@ #include "oops/symbol.hpp" #include "prims/jvmtiExport.hpp" #include "prims/jvmtiRedefineClassesTrace.hpp" +#include "prims/methodComparator.hpp" #include "runtime/fieldDescriptor.hpp" #include "runtime/handles.inline.hpp" #include "runtime/javaCalls.hpp" @@ -160,6 +161,8 @@ #endif // ndef DTRACE_ENABLED +volatile int InstanceKlass::_total_instanceKlass_count = 0; + Klass* InstanceKlass::allocate_instance_klass(ClassLoaderData* loader_data, int vtable_len, int itable_len, @@ -203,6 +206,7 @@ access_flags, !host_klass.is_null()); } + Atomic::inc(&_total_instanceKlass_count); return ik; } @@ -361,6 +365,9 @@ set_protection_domain(NULL); set_signers(NULL); set_init_lock(NULL); + + // We should deallocate the Annotations instance + MetadataFactory::free_metadata(loader_data, annotations()); set_annotations(NULL); } @@ -599,7 +606,7 @@ } // relocate jsrs and link methods after they are all rewritten - this_oop->relocate_and_link_methods(CHECK_false); + this_oop->link_methods(CHECK_false); // Initialize the vtable and interface table after // methods have been rewritten since rewrite may @@ -647,10 +654,31 @@ // Now relocate and link method entry points after class is rewritten. // This is outside is_rewritten flag. In case of an exception, it can be // executed more than once. -void InstanceKlass::relocate_and_link_methods(TRAPS) { - assert(is_loaded(), "must be loaded"); - instanceKlassHandle this_oop(THREAD, this); - Rewriter::relocate_and_link(this_oop, CHECK); +void InstanceKlass::link_methods(TRAPS) { + int len = methods()->length(); + for (int i = len-1; i >= 0; i--) { + methodHandle m(THREAD, methods()->at(i)); + + // Set up method entry points for compiler and interpreter . + m->link_method(m, CHECK); + + // This is for JVMTI and unrelated to relocator but the last thing we do +#ifdef ASSERT + if (StressMethodComparator) { + ResourceMark rm(THREAD); + static int nmc = 0; + for (int j = i; j >= 0 && j >= i-4; j--) { + if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); + bool z = MethodComparator::methods_EMCP(m(), + methods()->at(j)); + if (j == i && !z) { + tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); + assert(z, "method must compare equal to itself"); + } + } + } +#endif //ASSERT + } } @@ -2306,6 +2334,9 @@ if (_array_name != NULL) _array_name->decrement_refcount(); if (_source_file_name != NULL) _source_file_name->decrement_refcount(); if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass); + + assert(_total_instanceKlass_count >= 1, "Sanity check"); + Atomic::dec(&_total_instanceKlass_count); } void InstanceKlass::set_source_file_name(Symbol* n) { diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -31,6 +31,7 @@ #include "oops/fieldInfo.hpp" #include "oops/instanceOop.hpp" #include "oops/klassVtable.hpp" +#include "runtime/atomic.hpp" #include "runtime/handles.hpp" #include "runtime/os.hpp" #include "utilities/accessFlags.hpp" @@ -170,6 +171,11 @@ initialization_error // error happened during initialization }; + static int number_of_instance_classes() { return _total_instanceKlass_count; } + + private: + static volatile int _total_instanceKlass_count; + protected: // Protection domain. oop _protection_domain; @@ -454,7 +460,7 @@ bool link_class_or_fail(TRAPS); // returns false on failure void unlink_class(); void rewrite_class(TRAPS); - void relocate_and_link_methods(TRAPS); + void link_methods(TRAPS); Method* class_initializer(); // set the class to initialized if no static initializer is present @@ -657,6 +663,10 @@ if (annotations() == NULL) return NULL; return annotations()->fields_annotations(); } + Annotations* type_annotations() const { + if (annotations() == NULL) return NULL; + return annotations()->type_annotations(); + } // allocation instanceOop allocate_instance(TRAPS); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/method.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -64,6 +64,7 @@ int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, ConstMethod::MethodType method_type, TRAPS) { @@ -75,6 +76,7 @@ localvariable_table_length, exception_table_length, checked_exceptions_length, + method_parameters_length, generic_signature_index, method_type, CHECK_NULL); @@ -1035,8 +1037,10 @@ methodHandle m; { - Method* m_oop = Method::allocate(loader_data, 0, accessFlags_from(flags_bits), - 0, 0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty)); + Method* m_oop = Method::allocate(loader_data, 0, + accessFlags_from(flags_bits), + 0, 0, 0, 0, 0, 0, + ConstMethod::NORMAL, CHECK_(empty)); m = methodHandle(THREAD, m_oop); } m->set_constants(cp()); @@ -1088,6 +1092,7 @@ int checked_exceptions_len = m->checked_exceptions_length(); int localvariable_len = m->localvariable_table_length(); int exception_table_len = m->exception_table_length(); + int method_parameters_len = m->method_parameters_length(); ClassLoaderData* loader_data = m->method_holder()->class_loader_data(); Method* newm_oop = Method::allocate(loader_data, @@ -1097,6 +1102,7 @@ localvariable_len, exception_table_len, checked_exceptions_len, + method_parameters_len, generic_signature_index, m->method_type(), CHECK_(methodHandle())); @@ -1331,13 +1337,15 @@ Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, bool idempotent) { int length = methods->length(); if (length > 1) { bool do_annotations = false; if (methods_annotations != NULL || methods_parameter_annotations != NULL || - methods_default_annotations != NULL) { + methods_default_annotations != NULL || + methods_type_annotations != NULL) { do_annotations = true; } if (do_annotations) { @@ -1356,6 +1364,7 @@ assert(methods_annotations == NULL || methods_annotations->length() == methods->length(), ""); assert(methods_parameter_annotations == NULL || methods_parameter_annotations->length() == methods->length(), ""); assert(methods_default_annotations == NULL || methods_default_annotations->length() == methods->length(), ""); + assert(methods_type_annotations == NULL || methods_type_annotations->length() == methods->length(), ""); if (do_annotations) { ResourceMark rm; // Allocate temporary storage @@ -1363,6 +1372,7 @@ reorder_based_on_method_index(methods, methods_annotations, temp_array); reorder_based_on_method_index(methods, methods_parameter_annotations, temp_array); reorder_based_on_method_index(methods, methods_default_annotations, temp_array); + reorder_based_on_method_index(methods, methods_type_annotations, temp_array); } // Reset method ordering diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/oops/method.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -160,6 +160,7 @@ int localvariable_table_length, int exception_table_length, int checked_exceptions_length, + int method_parameters_length, u2 generic_signature_index, ConstMethod::MethodType method_type, TRAPS); @@ -225,6 +226,13 @@ } return ik->annotations()->get_method_default_annotations_of(method_idnum()); } + AnnotationArray* type_annotations() const { + InstanceKlass* ik = method_holder(); + Annotations* type_annos = ik->type_annotations(); + if (type_annos == NULL) + return NULL; + return type_annos->get_method_annotations_of(method_idnum()); +} #ifdef CC_INTERP void set_result_index(BasicType type); @@ -473,6 +481,12 @@ void print_codes_on(outputStream* st) const PRODUCT_RETURN; void print_codes_on(int from, int to, outputStream* st) const PRODUCT_RETURN; + // method parameters + int method_parameters_length() const + { return constMethod()->method_parameters_length(); } + MethodParametersElement* method_parameters_start() const + { return constMethod()->method_parameters_start(); } + // checked exceptions int checked_exceptions_length() const { return constMethod()->checked_exceptions_length(); } @@ -790,6 +804,7 @@ Array* methods_annotations, Array* methods_parameter_annotations, Array* methods_default_annotations, + Array* methods_type_annotations, bool idempotent = false); // Deallocation function for redefine classes or if an error occurs diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/prims/jvm.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -1515,7 +1515,7 @@ JVM_END -static Method* jvm_get_method_common(jobject method, TRAPS) { +static Method* jvm_get_method_common(jobject method) { // some of this code was adapted from from jni_FromReflectedMethod oop reflected = JNIHandles::resolve_non_null(method); @@ -1533,8 +1533,7 @@ } Klass* k = java_lang_Class::as_Klass(mirror); - KlassHandle kh(THREAD, k); - Method* m = InstanceKlass::cast(kh())->method_with_idnum(slot); + Method* m = InstanceKlass::cast(k)->method_with_idnum(slot); if (m == NULL) { assert(false, "cannot find method"); return NULL; // robustness @@ -1548,7 +1547,7 @@ JVMWrapper("JVM_GetMethodAnnotations"); // method is a handle to a java.lang.reflect.Method object - Method* m = jvm_get_method_common(method, CHECK_NULL); + Method* m = jvm_get_method_common(method); return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->annotations(), THREAD)); JVM_END @@ -1558,7 +1557,7 @@ JVMWrapper("JVM_GetMethodDefaultAnnotationValue"); // method is a handle to a java.lang.reflect.Method object - Method* m = jvm_get_method_common(method, CHECK_NULL); + Method* m = jvm_get_method_common(method); return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->annotation_default(), THREAD)); JVM_END @@ -1568,11 +1567,54 @@ JVMWrapper("JVM_GetMethodParameterAnnotations"); // method is a handle to a java.lang.reflect.Method object - Method* m = jvm_get_method_common(method, CHECK_NULL); + Method* m = jvm_get_method_common(method); return (jbyteArray) JNIHandles::make_local(env, Annotations::make_java_array(m->parameter_annotations(), THREAD)); JVM_END +/* Type use annotations support (JDK 1.8) */ + +JVM_ENTRY(jbyteArray, JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls)) + assert (cls != NULL, "illegal class"); + JVMWrapper("JVM_GetClassTypeAnnotations"); + ResourceMark rm(THREAD); + // Return null for arrays and primitives + if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { + Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); + if (k->oop_is_instance()) { + typeArrayOop a = Annotations::make_java_array(InstanceKlass::cast(k)->type_annotations()->class_annotations(), CHECK_NULL); + return (jbyteArray) JNIHandles::make_local(env, a); + } + } + return NULL; +JVM_END + +JVM_ENTRY(jobjectArray, JVM_GetMethodParameters(JNIEnv *env, jobject method)) +{ + JVMWrapper("JVM_GetMethodParameters"); + // method is a handle to a java.lang.reflect.Method object + Method* method_ptr = jvm_get_method_common(method); + methodHandle mh (THREAD, method_ptr); + Handle reflected_method (THREAD, JNIHandles::resolve_non_null(method)); + const int num_params = mh->method_parameters_length(); + + if(0 != num_params) { + objArrayOop result_oop = oopFactory::new_objArray(SystemDictionary::reflect_Parameter_klass(), num_params, CHECK_NULL); + objArrayHandle result (THREAD, result_oop); + + for(int i = 0; i < num_params; i++) { + MethodParametersElement* params = mh->method_parameters_start(); + Symbol* const sym = mh->constants()->symbol_at(params[i].name_cp_index); + oop param = Reflection::new_parameter(reflected_method, i, sym, + params[i].flags, CHECK_NULL); + result->obj_at_put(i, param); + } + return (jobjectArray)JNIHandles::make_local(env, result()); + } else { + return (jobjectArray)NULL; + } +} +JVM_END // New (JDK 1.4) reflection implementation ///////////////////////////////////// diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/prims/jvm.h Wed Jan 09 18:06:34 2013 -0500 @@ -86,6 +86,8 @@ #define JVM_INTERFACE_VERSION 4 +JNIEXPORT jobjectArray JNICALL +JVM_GetMethodParameters(JNIEnv *env, jobject method); JNIEXPORT jint JNICALL JVM_GetInterfaceVersion(void); @@ -519,6 +521,10 @@ JNIEXPORT jbyteArray JNICALL JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method); +/* Type use annotations support (JDK 1.8) */ + +JNIEXPORT jbyteArray JNICALL +JVM_GetClassTypeAnnotations(JNIEnv *env, jclass cls); /* * New (JDK 1.4) reflection implementation diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/prims/jvmtiRedefineClasses.cpp --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -1043,7 +1043,7 @@ Rewriter::rewrite(scratch_class, THREAD); if (!HAS_PENDING_EXCEPTION) { - Rewriter::relocate_and_link(scratch_class, THREAD); + scratch_class->link_methods(THREAD); } if (HAS_PENDING_EXCEPTION) { Symbol* ex_name = PENDING_EXCEPTION->klass()->name(); @@ -3338,7 +3338,20 @@ the_class->set_access_flags(flags); } - // Replace annotation fields value + // Since there is currently no rewriting of type annotations indexes + // into the CP, we null out type annotations on scratch_class before + // we swap annotations with the_class rather than facing the + // possibility of shipping annotations with broken indexes to + // Java-land. + Annotations* new_annotations = scratch_class->annotations(); + if (new_annotations != NULL) { + Annotations* new_type_annotations = new_annotations->type_annotations(); + if (new_type_annotations != NULL) { + MetadataFactory::free_metadata(scratch_class->class_loader_data(), new_type_annotations); + new_annotations->set_type_annotations(NULL); + } + } + // Swap annotation fields values Annotations* old_annotations = the_class->annotations(); the_class->set_annotations(scratch_class->annotations()); scratch_class->set_annotations(old_annotations); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/runtime/arguments.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -1326,14 +1326,14 @@ // then a saved space from compressed oops. if ((int)ObjectAlignmentInBytes > 256) { jio_fprintf(defaultStream::error_stream(), - "error: ObjectAlignmentInBytes=%d must not be greater then 256\n", + "error: ObjectAlignmentInBytes=%d must not be greater than 256\n", (int)ObjectAlignmentInBytes); return false; } // In case page size is very small. if ((int)ObjectAlignmentInBytes >= os::vm_page_size()) { jio_fprintf(defaultStream::error_stream(), - "error: ObjectAlignmentInBytes=%d must be less then page size %d\n", + "error: ObjectAlignmentInBytes=%d must be less than page size %d\n", (int)ObjectAlignmentInBytes, os::vm_page_size()); return false; } @@ -3010,11 +3010,6 @@ FLAG_SET_DEFAULT(UseLargePages, false); } - // Add 2M to any size for SharedReadOnlySize to get around the JPRT setting - if (DumpSharedSpaces && !FLAG_IS_DEFAULT(SharedReadOnlySize)) { - SharedReadOnlySize = 14*M; - } - if (DumpSharedSpaces) { if (RequireSharedSpaces) { warning("cannot dump shared archive while using shared archive"); @@ -3051,7 +3046,6 @@ strcpy(shared_archive_path, jvm_path); strcat(shared_archive_path, os::file_separator()); strcat(shared_archive_path, "classes"); - DEBUG_ONLY(strcat(shared_archive_path, "_g");) strcat(shared_archive_path, ".jsa"); SharedArchivePath = shared_archive_path; diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/runtime/fieldDescriptor.cpp --- a/src/share/vm/runtime/fieldDescriptor.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/runtime/fieldDescriptor.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -65,6 +65,17 @@ return md->at(index()); } +AnnotationArray* fieldDescriptor::type_annotations() const { + InstanceKlass* ik = field_holder(); + Annotations* type_annos = ik->type_annotations(); + if (type_annos == NULL) + return NULL; + Array* md = type_annos->fields_annotations(); + if (md == NULL) + return NULL; + return md->at(index()); +} + constantTag fieldDescriptor::initial_value_tag() const { return constants()->tag_at(initial_value_index()); } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/runtime/fieldDescriptor.hpp --- a/src/share/vm/runtime/fieldDescriptor.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/runtime/fieldDescriptor.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -68,6 +68,7 @@ Symbol* generic_signature() const; int index() const { return _index; } AnnotationArray* annotations() const; + AnnotationArray* type_annotations() const; // Initial field value bool has_initial_value() const { return field()->initval_index() != 0; } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/runtime/globals.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -1823,7 +1823,7 @@ \ product(intx, CMSIsTooFullPercentage, 98, \ "An absolute ceiling above which CMS will always consider the " \ - "perm gen ripe for collection") \ + "unloading of classes when class unloading is enabled") \ \ develop(bool, CMSTestInFreeList, false, \ "Check if the coalesced range is already in the " \ @@ -1892,13 +1892,13 @@ "Metadata deallocation alot interval") \ \ develop(bool, TraceMetadataChunkAllocation, false, \ - "Trace humongous metadata allocations") \ + "Trace chunk metadata allocations") \ \ product(bool, TraceMetadataHumongousAllocation, false, \ "Trace humongous metadata allocations") \ \ develop(bool, TraceMetavirtualspaceAllocation, false, \ - "Trace humongous metadata allocations") \ + "Trace virtual space metadata allocations") \ \ notproduct(bool, ExecuteInternalVMTests, false, \ "Enable execution of internal VM tests.") \ @@ -3531,10 +3531,10 @@ /* Shared spaces */ \ \ product(bool, UseSharedSpaces, true, \ - "Use shared spaces in the permanent generation") \ + "Use shared spaces for metadata") \ \ product(bool, RequireSharedSpaces, false, \ - "Require shared spaces in the permanent generation") \ + "Require shared spaces for metadata") \ \ product(bool, DumpSharedSpaces, false, \ "Special mode: JVM reads a class list, loads classes, builds " \ @@ -3545,16 +3545,16 @@ "Print usage of shared spaces") \ \ product(uintx, SharedReadWriteSize, NOT_LP64(12*M) LP64_ONLY(16*M), \ - "Size of read-write space in permanent generation (in bytes)") \ + "Size of read-write space for metadata (in bytes)") \ \ product(uintx, SharedReadOnlySize, NOT_LP64(12*M) LP64_ONLY(16*M), \ - "Size of read-only space in permanent generation (in bytes)") \ + "Size of read-only space for metadata (in bytes)") \ \ product(uintx, SharedMiscDataSize, NOT_LP64(2*M) LP64_ONLY(4*M), \ - "Size of the shared data area adjacent to the heap (in bytes)") \ + "Size of the shared miscellaneous data area (in bytes)") \ \ product(uintx, SharedMiscCodeSize, 120*K, \ - "Size of the shared code area adjacent to the heap (in bytes)") \ + "Size of the shared miscellaneous code area (in bytes)") \ \ product(uintx, SharedDummyBlockSize, 0, \ "Size of dummy block used to shift heap addresses (in bytes)") \ diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/runtime/handles.inline.hpp --- a/src/share/vm/runtime/handles.inline.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/runtime/handles.inline.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -80,6 +80,8 @@ _thread = Thread::current(); \ } \ _thread->metadata_handles()->push((Metadata*)_value); \ + } else { \ + _thread = NULL; \ } \ } \ inline name##Handle& name##Handle::operator=(const name##Handle &s) { \ @@ -94,6 +96,8 @@ _thread = Thread::current(); \ } \ _thread->metadata_handles()->push((Metadata*)_value); \ + } else { \ + _thread = NULL; \ } \ return *this; \ } \ diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/runtime/reflection.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -771,6 +771,10 @@ typeArrayOop an_oop = Annotations::make_java_array(method->annotation_default(), CHECK_NULL); java_lang_reflect_Method::set_annotation_default(mh(), an_oop); } + if (java_lang_reflect_Method::has_type_annotations_field()) { + typeArrayOop an_oop = Annotations::make_java_array(method->type_annotations(), CHECK_NULL); + java_lang_reflect_Method::set_type_annotations(mh(), an_oop); + } return mh(); } @@ -849,6 +853,21 @@ typeArrayOop an_oop = Annotations::make_java_array(fd->annotations(), CHECK_NULL); java_lang_reflect_Field::set_annotations(rh(), an_oop); } + if (java_lang_reflect_Field::has_type_annotations_field()) { + typeArrayOop an_oop = Annotations::make_java_array(fd->type_annotations(), CHECK_NULL); + java_lang_reflect_Field::set_type_annotations(rh(), an_oop); + } + return rh(); +} + +oop Reflection::new_parameter(Handle method, int index, Symbol* sym, + int flags, TRAPS) { + Handle name = java_lang_String::create_from_symbol(sym, CHECK_NULL); + Handle rh = java_lang_reflect_Parameter::create(CHECK_NULL); + java_lang_reflect_Parameter::set_name(rh(), name()); + java_lang_reflect_Parameter::set_modifiers(rh(), flags); + java_lang_reflect_Parameter::set_executable(rh(), method()); + java_lang_reflect_Parameter::set_index(rh(), index); return rh(); } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/runtime/reflection.hpp --- a/src/share/vm/runtime/reflection.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/runtime/reflection.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -118,6 +118,10 @@ static oop new_constructor(methodHandle method, TRAPS); // Create a java.lang.reflect.Field object based on a field descriptor static oop new_field(fieldDescriptor* fd, bool intern_name, TRAPS); + // Create a java.lang.reflect.Parameter object based on a + // MethodParameterElement + static oop new_parameter(Handle method, int index, Symbol* sym, + int flags, TRAPS); private: // method resolution for invoke diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memBaseline.cpp --- a/src/share/vm/services/memBaseline.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memBaseline.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -22,7 +22,6 @@ * */ #include "precompiled.hpp" -#include "classfile/systemDictionary.hpp" #include "memory/allocation.hpp" #include "services/memBaseline.hpp" #include "services/memTracker.hpp" @@ -349,7 +348,7 @@ reset(); _baselined = baseline_malloc_summary(snapshot._alloc_ptrs) && baseline_vm_summary(snapshot._vm_ptrs); - _number_of_classes = SystemDictionary::number_of_classes(); + _number_of_classes = snapshot.number_of_classes(); if (!summary_only && MemTracker::track_callsite() && _baselined) { _baselined = baseline_malloc_details(snapshot._alloc_ptrs) && diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memRecorder.cpp --- a/src/share/vm/services/memRecorder.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memRecorder.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -84,10 +84,13 @@ } delete _pointer_records; } - if (_next != NULL) { - delete _next; + // delete all linked recorders + while (_next != NULL) { + MemRecorder* tmp = _next; + _next = _next->next(); + tmp->set_next(NULL); + delete tmp; } - Atomic::dec(&_instance_count); } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memRecorder.hpp --- a/src/share/vm/services/memRecorder.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memRecorder.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -203,6 +203,7 @@ friend class MemSnapshot; friend class MemTracker; friend class MemTrackWorker; + friend class GenerationData; protected: // the array that holds memory records diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memSnapshot.cpp --- a/src/share/vm/services/memSnapshot.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memSnapshot.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -384,6 +384,7 @@ _staging_area.init(); _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock"); NOT_PRODUCT(_untracked_count = 0;) + _number_of_classes = 0; } MemSnapshot::~MemSnapshot() { @@ -479,7 +480,7 @@ // promote data to next generation -bool MemSnapshot::promote() { +bool MemSnapshot::promote(int number_of_classes) { assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check"); assert(_staging_area.malloc_data() != NULL && _staging_area.vm_data() != NULL, "Just check"); @@ -496,6 +497,7 @@ NOT_PRODUCT(check_malloc_pointers();) _staging_area.clear(); + _number_of_classes = number_of_classes; return promoted; } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memSnapshot.hpp --- a/src/share/vm/services/memSnapshot.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memSnapshot.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -355,6 +355,9 @@ // the lock to protect this snapshot Monitor* _lock; + // the number of instance classes + int _number_of_classes; + NOT_PRODUCT(size_t _untracked_count;) friend class MemBaseline; @@ -375,8 +378,9 @@ // merge a per-thread memory recorder into staging area bool merge(MemRecorder* rec); // promote staged data to snapshot - bool promote(); + bool promote(int number_of_classes); + int number_of_classes() const { return _number_of_classes; } void wait(long timeout) { assert(_lock != NULL, "Just check"); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memTrackWorker.cpp --- a/src/share/vm/services/memTrackWorker.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memTrackWorker.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -29,6 +29,16 @@ #include "utilities/decoder.hpp" #include "utilities/vmError.hpp" + +void GenerationData::reset() { + _number_of_classes = 0; + while (_recorder_list != NULL) { + MemRecorder* tmp = _recorder_list; + _recorder_list = _recorder_list->next(); + MemTracker::release_thread_recorder(tmp); + } +} + MemTrackWorker::MemTrackWorker() { // create thread uses cgc thread type for now. We should revisit // the option, or create new thread type. @@ -39,7 +49,7 @@ if (!has_error()) { _head = _tail = 0; for(int index = 0; index < MAX_GENERATIONS; index ++) { - _gen[index] = NULL; + ::new ((void*)&_gen[index]) GenerationData(); } } NOT_PRODUCT(_sync_point_count = 0;) @@ -49,10 +59,7 @@ MemTrackWorker::~MemTrackWorker() { for (int index = 0; index < MAX_GENERATIONS; index ++) { - MemRecorder* rc = _gen[index]; - if (rc != NULL) { - delete rc; - } + _gen[index].reset(); } } @@ -90,12 +97,7 @@ { // take a recorder from earliest generation in buffer ThreadCritical tc; - rec = _gen[_head]; - if (rec != NULL) { - _gen[_head] = rec->next(); - } - assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count, - "infinite loop after dequeue"); + rec = _gen[_head].next_recorder(); } if (rec != NULL) { // merge the recorder into staging area @@ -109,16 +111,20 @@ // no more recorder to merge, promote staging area // to snapshot if (_head != _tail) { + long number_of_classes; { ThreadCritical tc; - if (_gen[_head] != NULL || _head == _tail) { + if (_gen[_head].has_more_recorder() || _head == _tail) { continue; } + number_of_classes = _gen[_head].number_of_classes(); + _gen[_head].reset(); + // done with this generation, increment _head pointer _head = (_head + 1) % MAX_GENERATIONS; } // promote this generation data to snapshot - if (!snapshot->promote()) { + if (!snapshot->promote(number_of_classes)) { // failed to promote, means out of memory MemTracker::shutdown(MemTracker::NMT_out_of_memory); } @@ -126,8 +132,8 @@ snapshot->wait(1000); ThreadCritical tc; // check if more data arrived - if (_gen[_head] == NULL) { - _gen[_head] = MemTracker::get_pending_recorders(); + if (!_gen[_head].has_more_recorder()) { + _gen[_head].add_recorders(MemTracker::get_pending_recorders()); } } } @@ -147,7 +153,7 @@ // 1. add all recorders in pending queue to current generation // 2. increase generation -void MemTrackWorker::at_sync_point(MemRecorder* rec) { +void MemTrackWorker::at_sync_point(MemRecorder* rec, int number_of_classes) { NOT_PRODUCT(_sync_point_count ++;) assert(count_recorder(rec) <= MemRecorder::_instance_count, "pending queue has infinite loop"); @@ -155,23 +161,15 @@ bool out_of_generation_buffer = false; // check shutdown state inside ThreadCritical if (MemTracker::shutdown_in_progress()) return; + + _gen[_tail].set_number_of_classes(number_of_classes); // append the recorders to the end of the generation - if( rec != NULL) { - MemRecorder* cur_head = _gen[_tail]; - if (cur_head == NULL) { - _gen[_tail] = rec; - } else { - while (cur_head->next() != NULL) { - cur_head = cur_head->next(); - } - cur_head->set_next(rec); - } - } - assert(count_recorder(rec) <= MemRecorder::_instance_count, + _gen[_tail].add_recorders(rec); + assert(count_recorder(_gen[_tail].peek()) <= MemRecorder::_instance_count, "after add to current generation has infinite loop"); // we have collected all recorders for this generation. If there is data, // we need to increment _tail to start a new generation. - if (_gen[_tail] != NULL || _head == _tail) { + if (_gen[_tail].has_more_recorder() || _head == _tail) { _tail = (_tail + 1) % MAX_GENERATIONS; out_of_generation_buffer = (_tail == _head); } @@ -194,7 +192,7 @@ int MemTrackWorker::count_pending_recorders() const { int count = 0; for (int index = 0; index < MAX_GENERATIONS; index ++) { - MemRecorder* head = _gen[index]; + MemRecorder* head = _gen[index].peek(); if (head != NULL) { count += count_recorder(head); } diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memTrackWorker.hpp --- a/src/share/vm/services/memTrackWorker.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memTrackWorker.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -32,17 +32,58 @@ // Maximum MAX_GENERATIONS generation data can be tracked. #define MAX_GENERATIONS 512 +class GenerationData : public _ValueObj { + private: + int _number_of_classes; + MemRecorder* _recorder_list; + + public: + GenerationData(): _number_of_classes(0), _recorder_list(NULL) { } + + inline int number_of_classes() const { return _number_of_classes; } + inline void set_number_of_classes(long num) { _number_of_classes = num; } + + inline MemRecorder* next_recorder() { + if (_recorder_list == NULL) { + return NULL; + } else { + MemRecorder* tmp = _recorder_list; + _recorder_list = _recorder_list->next(); + return tmp; + } + } + + inline bool has_more_recorder() const { + return (_recorder_list != NULL); + } + + // add recorders to this generation + void add_recorders(MemRecorder* head) { + if (head != NULL) { + if (_recorder_list == NULL) { + _recorder_list = head; + } else { + MemRecorder* tmp = _recorder_list; + for (; tmp->next() != NULL; tmp = tmp->next()); + tmp->set_next(head); + } + } + } + + void reset(); + + NOT_PRODUCT(MemRecorder* peek() const { return _recorder_list; }) +}; class MemTrackWorker : public NamedThread { private: - // circular buffer. This buffer contains recorders to be merged into global + // circular buffer. This buffer contains generation data to be merged into global // snaphsot. - // Each slot holds a linked list of memory recorders, that contains one - // generation of memory data. - MemRecorder* _gen[MAX_GENERATIONS]; - int _head, _tail; // head and tail pointers to above circular buffer + // Each slot holds a generation + GenerationData _gen[MAX_GENERATIONS]; + int _head, _tail; // head and tail pointers to above circular buffer - bool _has_error; + bool _has_error; public: MemTrackWorker(); @@ -56,7 +97,7 @@ inline bool has_error() const { return _has_error; } // task at synchronization point - void at_sync_point(MemRecorder* pending_recorders); + void at_sync_point(MemRecorder* pending_recorders, int number_of_classes); // for debugging purpose, they are not thread safe. NOT_PRODUCT(static int count_recorder(const MemRecorder* head);) diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memTracker.cpp --- a/src/share/vm/services/memTracker.cpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memTracker.cpp Wed Jan 09 18:06:34 2013 -0500 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "oops/instanceKlass.hpp" #include "runtime/atomic.hpp" #include "runtime/interfaceSupport.hpp" #include "runtime/mutexLocker.hpp" @@ -485,7 +486,7 @@ } // check _worker_thread with lock to avoid racing condition if (_worker_thread != NULL) { - _worker_thread->at_sync_point(pending_recorders); + _worker_thread->at_sync_point(pending_recorders, InstanceKlass::number_of_instance_classes()); } assert(SequenceGenerator::peek() == 1, "Should not have memory activities during sync-point"); diff -r 0b54ffe4c2d3 -r 1f6d10b4cc0c src/share/vm/services/memTracker.hpp --- a/src/share/vm/services/memTracker.hpp Fri Jan 04 17:04:46 2013 -0800 +++ b/src/share/vm/services/memTracker.hpp Wed Jan 09 18:06:34 2013 -0500 @@ -142,6 +142,7 @@ * MemTracker is the 'gate' class to native memory tracking runtime. */ class MemTracker : AllStatic { + friend class GenerationData; friend class MemTrackWorker; friend class MemSnapshot; friend class SyncThreadRecorderClosure;