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 <[email protected]> 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' + } + } + ''' + } }
