changeset 9643:b119763a5eb8

8005873: JRuby test_respond_to.rb asserts with: MT-unsafe modification of inline cache Reviewed-by: vlivanov, jrose, psandoz Contributed-by: tobias.hartmann@oracle.com
author vlivanov
date Tue, 03 Jun 2014 16:38:14 +0400
parents dc03eee507f3
children e443dab8be6b
files src/share/classes/java/lang/invoke/LambdaForm.java src/share/classes/java/lang/invoke/MethodHandleImpl.java src/share/classes/java/lang/invoke/MethodTypeForm.java
diffstat 3 files changed, 6 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/LambdaForm.java	Tue Jun 03 13:02:28 2014 +0400
+++ b/src/share/classes/java/lang/invoke/LambdaForm.java	Tue Jun 03 16:38:14 2014 +0400
@@ -482,7 +482,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/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Jun 03 13:02:28 2014 +0400
+++ b/src/share/classes/java/lang/invoke/MethodHandleImpl.java	Tue Jun 03 16:38:14 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/src/share/classes/java/lang/invoke/MethodTypeForm.java	Tue Jun 03 13:02:28 2014 +0400
+++ b/src/share/classes/java/lang/invoke/MethodTypeForm.java	Tue Jun 03 16:38:14 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;
     }