About extracting common methods to reduce the size of class files

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

About extracting common methods to reduce the size of class files

Daniel Sun
Hi all,

       `$getStaticMetaClass`, `getMetaClass`, `setMetaClass`,
`invokeMethod`, `getProperty`, `setProperty`, etc. are generated for all
groovy classes(implements `groovy.lang.GroovyObject`). In order to reduce
the size of class files and speed up generating class files, I suggest
extracting the implementation of the common methods to the existing
interface `groovy.lang.GroovyObject` by leveraging the power of Java8's
default method feature.

        Any thoughts?

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

paulk_asert
Obviously for 3.0. I like the idea in general. I'd check with Jochen on whether he thinks any future MOP work might change which methods we'd want to extract.

Cheers, Paul.

On Mon, Jan 22, 2018 at 11:12 PM, Daniel Sun <[hidden email]> wrote:
Hi all,

       `$getStaticMetaClass`, `getMetaClass`, `setMetaClass`,
`invokeMethod`, `getProperty`, `setProperty`, etc. are generated for all
groovy classes(implements `groovy.lang.GroovyObject`). In order to reduce
the size of class files and speed up generating class files, I suggest
extracting the implementation of the common methods to the existing
interface `groovy.lang.GroovyObject` by leveraging the power of Java8's
default method feature.

        Any thoughts?

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

Daniel Sun
Looking forward to Jochen's feedback too ;-)

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

Jochen Theodorou
In reply to this post by Daniel Sun
And now with Jochen's feedback ;)

$getStaticMetaClass can I think not be put in an interface. It needs
static information about the exact class this method is in and there is
supposed to be one for each Groovy class we create... if memory serves
me right.

Moving the others to GroovyObject would then be a replacement for
GroovyObjectSupport. You can easily see why interfaces with default
methods does not make that construct a trait. GroovyObjectSupport has a
non-final, non-static, non-public field for the metaclass. Which means
that field cannot be in there. If that field is not in there, then and
get/setMetaClass also not.

get/setProperty as well as invokeMethod are less critical, since they
can use getMetaClass()

But then, what is my idea for Groovy3 here? For me the minimum is to
remove get/setProperty as well as invokeMethod and especially remove
their meaning as Java entry point. I also intend to remove the meta
class in the class itself and have it 100% managed outside. But that
depends.

Historically we had these as convenience for Java. But Java people use
mostly the compiled code anyway and for the others I think it would be
very OK to use something like InvokerHelper instead.

bye Jochen
Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

Daniel Sun
Hi Jochen

> $getStaticMetaClass can I think not be put in an interface. It needs
> static information about the exact class this method is in and there is
> supposed to be one for each Groovy class we create...

While I investigated the implementation of the instance method
`$getStaticMetaClass`, I found It seems that `$getStaticMetaClass` can also
be put in an interface too, because we can get static information via
reflection( e.g. `this.getClass().getField("$staticClassInfo")` )   ;-)

```
  protected synthetic $getStaticMetaClass()Lgroovy/lang/MetaClass;
    ALOAD 0
    INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;
    LDC LTest1;.class
    IF_ACMPEQ L0
    ALOAD 0
    INVOKESTATIC
org/codehaus/groovy/runtime/ScriptBytecodeAdapter.initMetaClass
(Ljava/lang/Object;)Lgroovy/lang/MetaClass;
    ARETURN
   L0
   FRAME SAME
    GETSTATIC Test1.$staticClassInfo :
Lorg/codehaus/groovy/reflection/ClassInfo;
    ASTORE 1
    ALOAD 1
    IFNONNULL L1
    ALOAD 0
    INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;
    INVOKESTATIC org/codehaus/groovy/reflection/ClassInfo.getClassInfo
(Ljava/lang/Class;)Lorg/codehaus/groovy/reflection/ClassInfo;
    DUP
    ASTORE 1
    PUTSTATIC Test1.$staticClassInfo :
Lorg/codehaus/groovy/reflection/ClassInfo;
   L1
   FRAME APPEND [org/codehaus/groovy/reflection/ClassInfo]
    ALOAD 1
    INVOKEVIRTUAL org/codehaus/groovy/reflection/ClassInfo.getMetaClass
()Lgroovy/lang/MetaClass;
    ARETURN
    MAXSTACK = 2
    MAXLOCALS = 2
```

> I also intend to remove the meta
> class in the class itself and have it 100% managed outside. But that
> depends.
It will break many existing code. In addition, that will make Groovy less
object oriented IMHO, e.g. `groovyObj.foo()` VS
`InvokerHelper.invokeMethod(groovyObj, "foo", EMPTY_OBJECT_ARRAY)`, I prefer
the former...

Cheers,
Daniel.Sun




--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

Jochen Theodorou


Am 23.01.2018 um 01:18 schrieb Daniel Sun:

> Hi Jochen
>
>> $getStaticMetaClass can I think not be put in an interface. It needs
>> static information about the exact class this method is in and there is
>> supposed to be one for each Groovy class we create...
>
> While I investigated the implementation of the instance method
> `$getStaticMetaClass`, I found It seems that `$getStaticMetaClass` can also
> be put in an interface too, because we can get static information via
> reflection( e.g. `this.getClass().getField("$staticClassInfo")` )   ;-)
ah, instance method, so I did remember this part wrong, but the field
$staticClassInfo is static. Frankly I question this logic quite a bit
right now let me rewrite the bytecode a bit:

>    protected synthetic $getStaticMetaClass()Lgroovy/lang/MetaClass;
>      if (this.getClass()!=Test1.class) {
>        return ScriptBytecodeAdapter.initMetaClass(this)
>      } else {
>        if (Test1.$staticClassInfo==null) {
>          Test1.$staticClassInfo = ClassInfo.getClassInfo(this.getClass())
>        }
>     }
>     return Test1.$staticClassInfo.getMetaClass()


>> I also intend to remove the meta
>> class in the class itself and have it 100% managed outside. But that
>> depends.
> It will break many existing code. In addition, that will make Groovy less
> object oriented IMHO, e.g. `groovyObj.foo()` VS
> `InvokerHelper.invokeMethod(groovyObj, "foo", EMPTY_OBJECT_ARRAY)`, I prefer
> the former...

Oh you compare wrong. groovyObj.foo() would still work. YOu ahve to compare

InvokerHelper.invokeMethod(groovyObj, "foo", EMPTY_OBJECT_ARRAY)

and

groovyObj.invokeMethod("foo", EMPTY_OBJECT_ARRAY)

I consider that a minor inconvenience on the user side, but a big win
(in terms of cleaning up the MOP) on our side.

bye Jochen
Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

Jochen Theodorou


Am 23.01.2018 um 12:42 schrieb Jochen Theodorou:

>
>
> Am 23.01.2018 um 01:18 schrieb Daniel Sun:
>> Hi Jochen
>>
>>> $getStaticMetaClass can I think not be put in an interface. It needs
>>> static information about the exact class this method is in and there is
>>> supposed to be one for each Groovy class we create...
>>
>> While I investigated the implementation of the instance method
>> `$getStaticMetaClass`, I found It seems that `$getStaticMetaClass` can
>> also
>> be put in an interface too, because we can get static information via
>> reflection( e.g. `this.getClass().getField("$staticClassInfo")` )   ;-)
> ah, instance method, so I did remember this part wrong, but the field
> $staticClassInfo is static. Frankly I question this logic quite a bit
> right now let me rewrite the bytecode a bit:
>
>>    protected synthetic $getStaticMetaClass()Lgroovy/lang/MetaClass;
>>      if (this.getClass()!=Test1.class) {
>>        return ScriptBytecodeAdapter.initMetaClass(this)
>>      } else {
>>        if (Test1.$staticClassInfo==null) {
>>          Test1.$staticClassInfo = ClassInfo.getClassInfo(this.getClass())
>>        }
>>     }
>>     return Test1.$staticClassInfo.getMetaClass()

ahem... insert here, what I actually wanted to say...

These Test1.$staticClassInfo are references to static fields. You do not
need this.getClass() for this, as a subclass defines its own
$staticClassInfo. That means
this.getClass().getField("$staticClassInfo") will always and only choose
the current subclass. If that subclass is in Java, you will save the
metaclass for the Java subclass in the static field, that is supposed to
hold the metaclass for the base class. That's not good.

bye Jochen
Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

Daniel Sun
In reply to this post by Jochen Theodorou
> Oh you compare wrong. groovyObj.foo() would still work.
That's great!

`groovyObj.invokeMethod("foo", EMPTY_OBJECT_ARRAY) ` is not better than
`InvokerHelper.invokeMethod(groovyObj, "foo", EMPTY_OBJECT_ARRAY) `, so I
think it is OK to change :)

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html
Reply | Threaded
Open this post in threaded view
|

Re: About extracting common methods to reduce the size of class files

Daniel Sun
In reply to this post by Jochen Theodorou
> If that subclass is in Java, you will save the
> metaclass for the Java subclass in the static field, that is supposed to
> hold the metaclass for the base class. That's not good.
You're right. I forgot the scenario...

Cheers,
Daniel.Sun



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html