# HG changeset patch # User coleenp # Date 1357681450 28800 # Node ID 185a2c979a0e11150d9312759695c80049e3ab5a # Parent 56114889655951ee803faaf6fa00de6dd1218713# Parent ade95d680b42255a56e8a45891c0aebbc99d8985 Merge diff -r 561148896559 -r 185a2c979a0e make/bsd/makefiles/mapfile-vers-debug --- a/make/bsd/makefiles/mapfile-vers-debug Tue Jan 08 13:38:11 2013 -0500 +++ b/make/bsd/makefiles/mapfile-vers-debug Tue Jan 08 13:44:10 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: *; diff -r 561148896559 -r 185a2c979a0e make/bsd/makefiles/mapfile-vers-product --- a/make/bsd/makefiles/mapfile-vers-product Tue Jan 08 13:38:11 2013 -0500 +++ b/make/bsd/makefiles/mapfile-vers-product Tue Jan 08 13:44:10 2013 -0800 @@ -155,6 +155,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff -r 561148896559 -r 185a2c979a0e make/linux/makefiles/mapfile-vers-debug --- a/make/linux/makefiles/mapfile-vers-debug Tue Jan 08 13:38:11 2013 -0500 +++ b/make/linux/makefiles/mapfile-vers-debug Tue Jan 08 13:44:10 2013 -0800 @@ -151,6 +151,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff -r 561148896559 -r 185a2c979a0e make/linux/makefiles/mapfile-vers-product --- a/make/linux/makefiles/mapfile-vers-product Tue Jan 08 13:38:11 2013 -0500 +++ b/make/linux/makefiles/mapfile-vers-product Tue Jan 08 13:44:10 2013 -0800 @@ -151,6 +151,7 @@ JVM_GetMethodIxNameUTF; JVM_GetMethodIxSignatureUTF; JVM_GetMethodParameterAnnotations; + JVM_GetMethodParameters; JVM_GetPrimitiveArrayElement; JVM_GetProtectionDomain; JVM_GetSockName; diff -r 561148896559 -r 185a2c979a0e make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Tue Jan 08 13:38:11 2013 -0500 +++ b/make/solaris/makefiles/mapfile-vers Tue Jan 08 13:44:10 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: *; diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/classFileParser.cpp Tue Jan 08 13:44:10 2013 -0800 @@ -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 diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/classFileStream.cpp --- a/src/share/vm/classfile/classFileStream.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/classFileStream.cpp Tue Jan 08 13:44:10 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; +} diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/classFileStream.hpp --- a/src/share/vm/classfile/classFileStream.hpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/classFileStream.hpp Tue Jan 08 13:44:10 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; } }; diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/defaultMethods.cpp --- a/src/share/vm/classfile/defaultMethods.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/defaultMethods.cpp Tue Jan 08 13:44:10 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)); diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/javaClasses.cpp --- a/src/share/vm/classfile/javaClasses.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/javaClasses.cpp Tue Jan 08 13:44:10 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(); diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/javaClasses.hpp --- a/src/share/vm/classfile/javaClasses.hpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/javaClasses.hpp Tue Jan 08 13:44:10 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: diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Jan 08 13:44:10 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; } diff -r 561148896559 -r 185a2c979a0e src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Jan 08 13:44:10 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;") \ diff -r 561148896559 -r 185a2c979a0e src/share/vm/oops/constMethod.cpp --- a/src/share/vm/oops/constMethod.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/oops/constMethod.cpp Tue Jan 08 13:44:10 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; } diff -r 561148896559 -r 185a2c979a0e src/share/vm/oops/constMethod.hpp --- a/src/share/vm/oops/constMethod.hpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/oops/constMethod.hpp Tue Jan 08 13:44:10 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) { diff -r 561148896559 -r 185a2c979a0e src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/oops/method.cpp Tue Jan 08 13:44:10 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())); diff -r 561148896559 -r 185a2c979a0e src/share/vm/oops/method.hpp --- a/src/share/vm/oops/method.hpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/oops/method.hpp Tue Jan 08 13:44:10 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(); } diff -r 561148896559 -r 185a2c979a0e src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/prims/jvm.cpp Tue Jan 08 13:44:10 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 ///////////////////////////////////// diff -r 561148896559 -r 185a2c979a0e src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/prims/jvm.h Tue Jan 08 13:44:10 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); diff -r 561148896559 -r 185a2c979a0e src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/runtime/reflection.cpp Tue Jan 08 13:44:10 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) { diff -r 561148896559 -r 185a2c979a0e src/share/vm/runtime/reflection.hpp --- a/src/share/vm/runtime/reflection.hpp Tue Jan 08 13:38:11 2013 -0500 +++ b/src/share/vm/runtime/reflection.hpp Tue Jan 08 13:44:10 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