[9] RFR(S): 8005873: JRuby test_respond_to.rb asserts with: MT-unsafe modification of inline cache
Tobias Hartmann
tobias.hartmann at oracle.com
Wed May 14 10:33:54 UTC 2014
Hi Remi,
sorry, I accidentally reverted that part.. Here is the correct webrev:
http://cr.openjdk.java.net/~anoll/8005873/webrev.01/
Thanks,
Tobias
On 14.05.2014 12:04, Remi Forax wrote:
> your patch doesn't work !
>
> the array is still allocated as an classical array in the constructor.
>
> cheers,
> Remi
>
> Envoyé avec AquaMail pour Android
> http://www.aqua-mail.com
>
>
> Le 14 mai 2014 11:04:41 Tobias Hartmann <tobias.hartmann at oracle.com> a
> écrit :
>
>> Hi,
>>
>> please review the following patch for bug 8005873.
>>
>> *Problem*
>> Bug: https://bugs.openjdk.java.net/browse/JDK-8005873
>>
>> The test creates multiple threads (~500) that repeatedly execute
>> invokeExact on a method handle referencing a static method. The call
>> to invokeExact is performed through an optimized inline cache
>> (CompiledStaticCall) that points to the LambdaForm generated for the
>> method handle. The IC is first set to interpreted code by
>> CompiledStaticCall::set_to_interpreted(...) but soon updated to refer
>> to the compiled version of the lambda form (-Xcomp).
>>
>> Because tiered compilation is enabled, the VM decides to compile the
>> LambdaForm at a different level and sets the old version to
>> not-entrant. The next call through the IC therefore triggers a
>> re-resolving of the call site finally performing a Java upcall to
>> java.lang.invoke.MethodHandleNatives::linkMethod(...) (see call
>> sequence [1]). A *new* LambdaForm is returned and
>> CompiledStaticCall::set_to_interpreted(...) is executed again to
>> update the IC. The assert is hit because the callee differs.
>>
>> The problem is that there are multiple LambdaForms created for the
>> same invokeExact instruction. Caching in the Java runtime code should
>> guarantee that only one LambdaForm is created and reused.
>> Instrumenting Invokers::invokeHandleForm(...) shows that almost all
>> requests result in a cache miss and return a new LambdaForm.
>>
>> This behaviour is caused by a race condition in
>> Invokers::invokeHandleForm(...). Threads may initially see a cache
>> miss when invoking MethodTypeForm::cachedLambdaForm(...), then create
>> a new LambdaForm and call MethodTypeForm::setCachedLambdaForm(...) to
>> update the cache without checking it again. In a high concurrency
>> setting, this leads to multiple LambdaForms being created for the
>> same invokeExact instruction because the cache entry is overwritten
>> by multiple threads.
>>
>> *Solution*
>> Webrev: http://cr.openjdk.java.net/~anoll/8005873/webrev.00/
>>
>> An AtomicReferenceArray is used to cache the LambdaForms and
>> .get(...) and .compareAndSet(...) are used to retrieve and update the
>> cache entries. This allows only one thread to set the LambdaForm that
>> is then being used by all instances of the invokeExact.
>>
>> *Testing*
>> - Failing test (vm/mlvm/meth/stress/jni/nativeAndMH)
>> - Nashorn + Octane
>> - JPRT
>>
>> Many thanks to Christian Thalinger and Vladimir Ivanov!
>>
>> Best,
>> Tobias
>>
>> [1] Call sequence of reresolving the IC target
>> SharedRuntime::handle_wrong_method(...)
>> -> SharedRuntime::reresolve_call_site(...)
>> -> SharedRuntime::find_callee_method(...)
>> -> SharedRuntime::find_callee_info_helper(...)
>> -> LinkResolver::resolve_invoke(...)
>> -> LinkResolver::resolve_invokehandle(...)
>> -> LinkResolver::resolve_invokehandle(...)
>> -> LinkResolver::lookup_polymorphic_method(...)
>> -> SystemDictionary::find_method_handle_invoker(...)
>> -> Java upcall to java.lang.invoke.MethodHandleNatives::linkMethod(...)
>> -> Invokers::methodHandleInvokeLinkerMethod(...)
>> -> Invokers::invokeHandleForm(...)
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> Backport?
>
>
More information about the hotspot-dev
mailing list