8005873: JRuby test_respond_to.rb asserts with: MT-unsafe modification of inline cache
authorthartmann
Tue, 03 Jun 2014 14:58:47 +0400
changeset 24696 00479fa7c27f
parent 24695 52e89ad5ccbe
child 24698 4e796dbb16f5
8005873: JRuby test_respond_to.rb asserts with: MT-unsafe modification of inline cache Reviewed-by: vlivanov, jrose, psandoz
jdk/src/share/classes/java/lang/invoke/LambdaForm.java
jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java
--- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java	Tue Jun 03 12:52:59 2014 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java	Tue Jun 03 14:58:47 2014 +0400
@@ -607,7 +607,7 @@
                 assert(m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
                 LambdaForm form = new LambdaForm(sig);
                 form.vmentry = m;
-                mt.form().setCachedLambdaForm(MethodTypeForm.LF_COUNTER, form);
+                form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_COUNTER, form);
                 // FIXME: get rid of PREPARED_FORMS; use MethodTypeForm cache only
                 forms.put(sig, form);
             }
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Jun 03 12:52:59 2014 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Jun 03 14:58:47 2014 +0400
@@ -692,8 +692,7 @@
 
         lform = new LambdaForm("guardWithCatch", lambdaType.parameterCount(), names);
 
-        basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform);
-        return lform;
+        return basicType.form().setCachedLambdaForm(MethodTypeForm.LF_GWC, lform);
     }
 
     static
--- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java	Tue Jun 03 12:52:59 2014 +0400
+++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java	Tue Jun 03 14:58:47 2014 +0400
@@ -91,8 +91,10 @@
         return lambdaForms[which];
     }
 
-    public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
-        // Should we perform some sort of CAS, to avoid racy duplication?
+    synchronized public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
+        // Simulate a CAS, to avoid racy duplication of results.
+        LambdaForm prev = lambdaForms[which];
+        if (prev != null) return prev;
         return lambdaForms[which] = form;
     }