You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/05/04 14:53:47 UTC

[groovy] 01/01: GROOVY-10535: indy: direct linking to `asBoolean()` for [Bb]oolean cast

This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY-10535
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 83039fa5037f886a47a942a69c8c9e143144eaa0
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed May 4 09:39:41 2022 -0500

    GROOVY-10535: indy: direct linking to `asBoolean()` for [Bb]oolean cast
---
 .../v8/IndyGuardsFiltersAndSignatures.java         |  3 +-
 .../org/codehaus/groovy/vmplugin/v8/Selector.java  |  6 +--
 src/test/groovy/bugs/Groovy10535.groovy            | 44 +++++++++++++++++++++-
 3 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java
index c2937943b7..b358d6e4b9 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java
@@ -68,7 +68,7 @@ public class IndyGuardsFiltersAndSignatures {
             META_PROPERTY_GETTER,
             SLOW_META_CLASS_FIND,
             MOP_GET, MOP_INVOKE_CONSTRUCTOR, MOP_INVOKE_METHOD,
-            INTERCEPTABLE_INVOKER, INVOKE_METHOD,
+            INTERCEPTABLE_INVOKER,
             BOOLEAN_IDENTITY, CLASS_FOR_NAME,
             DTT_CAST_TO_TYPE, SAM_CONVERSION,
             HASHSET_CONSTRUCTOR, ARRAYLIST_CONSTRUCTOR,
@@ -94,7 +94,6 @@ public class IndyGuardsFiltersAndSignatures {
             MOP_INVOKE_CONSTRUCTOR = LOOKUP.findVirtual(MetaObjectProtocol.class, "invokeConstructor", MethodType.methodType(Object.class, Object[].class));
             MOP_INVOKE_METHOD = LOOKUP.findVirtual(MetaObjectProtocol.class, "invokeMethod", INVOKER);
             INTERCEPTABLE_INVOKER = LOOKUP.findVirtual(GroovyObject.class, "invokeMethod", MethodType.methodType(Object.class, String.class, Object.class));
-            INVOKE_METHOD = LOOKUP.findStatic(InvokerHelper.class, "invokeMethod", MethodType.methodType(Object.class, Object.class, String.class, Object.class));
 
             BOOLEAN_IDENTITY = MethodHandles.identity(Boolean.class);
             CLASS_FOR_NAME = LOOKUP.findStatic(Class.class, "forName", MethodType.methodType(Class.class, String.class, boolean.class, ClassLoader.class));
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
index f4899bf77f..5a0ccd516a 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
@@ -77,7 +77,6 @@ import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.GRO
 import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.HASHSET_CONSTRUCTOR;
 import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.HAS_CATEGORY_IN_CURRENT_THREAD_GUARD;
 import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.INTERCEPTABLE_INVOKER;
-import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.INVOKE_METHOD;
 import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.IS_NULL;
 import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.META_CLASS_INVOKE_STATIC_METHOD;
 import static org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.META_METHOD_INVOKER;
@@ -269,10 +268,11 @@ public abstract class Selector {
                 thenZero = MethodHandles.identity(staticSourceType).asType(MethodType.methodType(Boolean.class, staticSourceType));
             }
 
-            MethodHandle elseCallAsBoolean = MethodHandles.insertArguments(INVOKE_METHOD, 1, "asBoolean", null).asType(targetType);
+            name = "asBoolean";
+            super.setCallSiteTarget();
+            MethodHandle elseCallAsBoolean = handle;
 
             handle = MethodHandles.guardWithTest(ifNull, thenZero, elseCallAsBoolean);
-            callSite.setTarget(handle); // handle is re-useable for any argument
         }
     }
 
diff --git a/src/test/groovy/bugs/Groovy10535.groovy b/src/test/groovy/bugs/Groovy10535.groovy
index e4afabd0fc..0e85c00f8b 100644
--- a/src/test/groovy/bugs/Groovy10535.groovy
+++ b/src/test/groovy/bugs/Groovy10535.groovy
@@ -23,8 +23,9 @@ import org.junit.Test
 import static groovy.test.GroovyAssert.assertScript
 
 final class Groovy10535 {
+
     @Test
-    void testBooleanTypecast_invokeDynamicOptimization() {
+    void testBooleanTypecast_invokeDynamicOptimization1() {
         assertScript '''
             @groovy.transform.CompileStatic
             class C {
@@ -42,4 +43,45 @@ final class Groovy10535 {
             }
         '''
     }
+
+    @Test
+    void testBooleanTypecast_invokeDynamicOptimization2() {
+        assertScript '''
+            @groovy.transform.CompileStatic
+            class C {
+                static main(args) {
+                    Collection<String> strings = ['x']
+                    for (int i = 0; i <= 200_000; i += 1) {
+                        assert test(strings) !== null
+                    }
+                    strings = null
+                    assert test(strings) === null
+                }
+                static test(Collection<String> values) {
+                    if (values) return 'thing'
+                }
+            }
+        '''
+    }
+
+    @Test
+    void testBooleanTypecast_invokeDynamicOptimization3() {
+        assertScript '''
+            @groovy.transform.CompileStatic
+            class C {
+                static main(args) {
+                    Collection<String> strings
+                    for (int i = 0; i <= 200_000; i += 1) {
+                        strings = [i as String]
+                        assert test(strings) !== null
+                    }
+                    strings = null
+                    assert test(strings) === null
+                }
+                static test(Collection<String> values) {
+                    if (values) return 'thing'
+                }
+            }
+        '''
+    }
 }