--- a/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug Wed Jan 09 12:10:25 2013 -0800
@@ -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,7 +126,7 @@
JVM_GetClassModifiers;
JVM_GetClassName;
JVM_GetClassNameUTF;
- JVM_GetClassSignature;
+ JVM_GetClassSignature;
JVM_GetClassSigners;
JVM_GetClassTypeAnnotations;
JVM_GetComponentType;
@@ -155,6 +155,7 @@
JVM_GetMethodIxNameUTF;
JVM_GetMethodIxSignatureUTF;
JVM_GetMethodParameterAnnotations;
+ JVM_GetMethodParameters;
JVM_GetPrimitiveArrayElement;
JVM_GetProtectionDomain;
JVM_GetSockName;
@@ -284,7 +285,7 @@
# This is for Forte Analyzer profiling support.
AsyncGetCallTrace;
- # INSERT VTABLE SYMBOLS HERE
+ # INSERT VTABLE SYMBOLS HERE
local:
*;
--- a/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/make/bsd/makefiles/mapfile-vers-product Wed Jan 09 12:10:25 2013 -0800
@@ -155,6 +155,7 @@
JVM_GetMethodIxNameUTF;
JVM_GetMethodIxSignatureUTF;
JVM_GetMethodParameterAnnotations;
+ JVM_GetMethodParameters;
JVM_GetPrimitiveArrayElement;
JVM_GetProtectionDomain;
JVM_GetSockName;
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug Wed Jan 09 12:10:25 2013 -0800
@@ -151,6 +151,7 @@
JVM_GetMethodIxNameUTF;
JVM_GetMethodIxSignatureUTF;
JVM_GetMethodParameterAnnotations;
+ JVM_GetMethodParameters;
JVM_GetPrimitiveArrayElement;
JVM_GetProtectionDomain;
JVM_GetSockName;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product Wed Jan 09 12:10:25 2013 -0800
@@ -151,6 +151,7 @@
JVM_GetMethodIxNameUTF;
JVM_GetMethodIxSignatureUTF;
JVM_GetMethodParameterAnnotations;
+ JVM_GetMethodParameters;
JVM_GetPrimitiveArrayElement;
JVM_GetProtectionDomain;
JVM_GetSockName;
--- a/hotspot/make/solaris/makefiles/mapfile-vers Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/make/solaris/makefiles/mapfile-vers Wed Jan 09 12:10:25 2013 -0800
@@ -26,236 +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_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_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:
*;
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1935,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;
@@ -2144,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(
@@ -2231,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);
@@ -2279,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);
@@ -3042,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
@@ -3888,7 +3912,10 @@
// check that if this class is an interface then it doesn't have static methods
if (this_klass->is_interface()) {
- check_illegal_static_method(this_klass, CHECK_(nullHandle));
+ /* An interface in a JAVA 8 classfile can be static */
+ if (_major_version < JAVA_8_VERSION) {
+ check_illegal_static_method(this_klass, CHECK_(nullHandle));
+ }
}
@@ -4442,6 +4469,7 @@
const bool is_bridge = (flags & JVM_ACC_BRIDGE) != 0;
const bool is_strict = (flags & JVM_ACC_STRICT) != 0;
const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0;
+ const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION;
const bool major_gte_8 = _major_version >= JAVA_8_VERSION;
const bool is_initializer = (name == vmSymbols::object_initializer_name());
@@ -4449,11 +4477,33 @@
bool is_illegal = false;
if (is_interface) {
- if (!is_public || is_static || is_final || is_native ||
- ((is_synchronized || is_strict) && major_gte_15 &&
- (!major_gte_8 || is_abstract)) ||
- (!major_gte_8 && !is_abstract)) {
- is_illegal = true;
+ if (major_gte_8) {
+ // Class file version is JAVA_8_VERSION or later Methods of
+ // interfaces may set any of the flags except ACC_PROTECTED,
+ // ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must
+ // have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set.
+ if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */
+ (is_native || is_protected || is_final || is_synchronized) ||
+ // If a specific method of a class or interface has its
+ // ACC_ABSTRACT flag set, it must not have any of its
+ // ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC,
+ // ACC_STRICT, or ACC_SYNCHRONIZED flags set. No need to
+ // check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as
+ // those flags are illegal irrespective of ACC_ABSTRACT being set or not.
+ (is_abstract && (is_private || is_static || is_strict))) {
+ is_illegal = true;
+ }
+ } else if (major_gte_15) {
+ // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION)
+ if (!is_public || is_static || is_final || is_synchronized ||
+ is_native || !is_abstract || is_strict) {
+ is_illegal = true;
+ }
+ } else {
+ // Class file version is pre-JAVA_1_5_VERSION
+ if (!is_public || is_static || is_final || is_native || !is_abstract) {
+ is_illegal = true;
+ }
}
} else { // not interface
if (is_initializer) {
--- a/hotspot/src/share/vm/classfile/classFileStream.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/classFileStream.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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;
+}
--- a/hotspot/src/share/vm/classfile/classFileStream.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/classFileStream.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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; }
};
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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));
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -2255,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");
@@ -2928,6 +2988,10 @@
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;
@@ -3112,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();
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -729,6 +729,37 @@
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:
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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; }
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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") \
@@ -235,6 +237,8 @@
/* 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") \
@@ -475,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;") \
--- a/hotspot/src/share/vm/memory/filemap.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/memory/filemap.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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
@@ -473,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.
--- a/hotspot/src/share/vm/memory/filemap.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/memory/filemap.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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
--- a/hotspot/src/share/vm/oops/constMethod.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/oops/constMethod.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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;
}
--- a/hotspot/src/share/vm/oops/constMethod.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/oops/constMethod.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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) {
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -161,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,
@@ -204,6 +206,7 @@
access_flags, !host_klass.is_null());
}
+ Atomic::inc(&_total_instanceKlass_count);
return ik;
}
@@ -2331,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) {
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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;
--- a/hotspot/src/share/vm/oops/method.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/oops/method.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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()));
--- a/hotspot/src/share/vm/oops/method.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/oops/method.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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);
@@ -480,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(); }
--- a/hotspot/src/share/vm/prims/jvm.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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,7 +1567,7 @@
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
@@ -1590,6 +1589,32 @@
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 /////////////////////////////////////
--- a/hotspot/src/share/vm/prims/jvm.h Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/prims/jvm.h Wed Jan 09 12:10:25 2013 -0800
@@ -86,6 +86,8 @@
#define JVM_INTERFACE_VERSION 4
+JNIEXPORT jobjectArray JNICALL
+JVM_GetMethodParameters(JNIEnv *env, jobject method);
JNIEXPORT jint JNICALL
JVM_GetInterfaceVersion(void);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -1331,14 +1331,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;
}
@@ -2997,11 +2997,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");
--- a/hotspot/src/share/vm/runtime/globals.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -1830,7 +1830,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 " \
@@ -1899,13 +1899,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.") \
@@ -3537,10 +3537,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 " \
@@ -3551,16 +3551,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)") \
--- a/hotspot/src/share/vm/runtime/reflection.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/runtime/reflection.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -860,6 +860,17 @@
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();
+}
+
methodHandle Reflection::resolve_interface_call(instanceKlassHandle klass, methodHandle method,
KlassHandle recv_klass, Handle receiver, TRAPS) {
--- a/hotspot/src/share/vm/runtime/reflection.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/runtime/reflection.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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
--- a/hotspot/src/share/vm/services/memBaseline.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memBaseline.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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) &&
--- a/hotspot/src/share/vm/services/memRecorder.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memRecorder.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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);
}
--- a/hotspot/src/share/vm/services/memRecorder.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memRecorder.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -203,6 +203,7 @@
friend class MemSnapshot;
friend class MemTracker;
friend class MemTrackWorker;
+ friend class GenerationData;
protected:
// the array that holds memory records
--- a/hotspot/src/share/vm/services/memSnapshot.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memSnapshot.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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;
}
--- a/hotspot/src/share/vm/services/memSnapshot.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memSnapshot.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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");
--- a/hotspot/src/share/vm/services/memTrackWorker.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memTrackWorker.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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);
}
--- a/hotspot/src/share/vm/services/memTrackWorker.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memTrackWorker.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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);)
--- a/hotspot/src/share/vm/services/memTracker.cpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memTracker.cpp Wed Jan 09 12:10:25 2013 -0800
@@ -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");
--- a/hotspot/src/share/vm/services/memTracker.hpp Wed Jan 09 14:46:55 2013 -0500
+++ b/hotspot/src/share/vm/services/memTracker.hpp Wed Jan 09 12:10:25 2013 -0800
@@ -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;