You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Shil Sinha (JIRA)" <ji...@apache.org> on 2016/01/14 02:29:40 UTC

[jira] [Assigned] (GROOVY-7705) CompileStatic closure accessing "thisObject" private field: setProperty instead of synthetic method

     [ https://issues.apache.org/jira/browse/GROOVY-7705?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Shil Sinha reassigned GROOVY-7705:
----------------------------------

    Assignee: Shil Sinha  (was: Cédric Champeau)

> CompileStatic closure accessing "thisObject" private field: setProperty instead of synthetic method
> ---------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-7705
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7705
>             Project: Groovy
>          Issue Type: Bug
>          Components: Static compilation
>    Affects Versions: 2.4.5
>            Reporter: Jason Winnebeck
>            Assignee: Shil Sinha
>
> When a closure sets the private field of a class, it does it via a ScriptBytecodeAdapter.setGroovyObjectProperty on the closure object itself, whereas when getting a private field of the class it uses a synthetic "pfaccess$0" method.
> Source:
> {code:title=Source}
> @CompileStatic
> class SetFromClosure {
> 	private int x
> 	void doIt() {
> 		def closure = {
> 			x = 5
> 			println x
> 		}
> 		closure()
> 	}
> }
> {code}
> Decompiled result of closure class (via Fernflower in IntelliJ):
> {code}
> class SetFromClosure$_doIt_closure1 extends Closure implements GeneratedClosure {
>   public SetFromClosure$_doIt_closure1(Object _outerInstance, Object _thisObject) {
>     super(_outerInstance, _thisObject);
>   }
>   public Object doCall(Object it) {
>     byte var2 = 5;
>     ScriptBytecodeAdapter.setGroovyObjectProperty(Integer.valueOf(var2), SetFromClosure$_doIt_closure1.class, this, (String)"x");
>     DefaultGroovyMethods.println((SetFromClosure)this.getThisObject(), Integer.valueOf(SetFromClosure.pfaccess$0((SetFromClosure)this.getThisObject())));
>     return null;
>   }
>   public Object call(Object args) {
>     return this.doCall(args);
>   }
>   public Object call() {
>     return this.doCall((Object)null);
>   }
>   public Object doCall() {
>     return this.doCall((Object)null);
>   }
> }
> {code}
> Workaround is to remove "private" keyword on the variable declaration, which causes Groovy to generate public getter and setter. In that mode, the static compiler does generate direct calls to both the getter and the setter. In one example within my project the performance speedup was 10x with this workaround. The only thing I notice in the workaround that is odd is that instead of normal Java casts used, ScriptBytecodeAdapter.castToType is used on "getThisObject" before calling the getters or setters.
> This issue could possibly related to GROOVY-6825, but in that case it's an inner class, and the issue description (currently) is not clear enough to see if it's also generating a setProperty call.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)