-
Type:
Enhancement
-
Resolution: Won't Fix
-
Priority:
P4
-
Affects Version/s: None
-
Component/s: core-libs
-
None
ported from NASHORN-644:
Right now the constructors are unncessarily complex. We should treat NativeObjects like normal ScriptObjects. Not only is this more compact and produces way less bytecode, it also removes the need for special constructor in Property$AccessProperty where there are null getters or setters that have to be created on the fly.
Sundar:
Are you suggesting to process nasgen annotations etc @runtime ?
or just call MapCreator to fill in maps instead of directly calling newMap and making method handles etc. manually.
Marcus:
Just de-bloat the <clinit>s and stop using the newProperty accessor that is only made for nasgen
Sundar:
I spent sometime looking at current MapCreator for possible usage in nasgen. My observations based on whatever I read:
1. MapCreator uses reflection to fill up getter and setter handles. nasgen currently uses explicit getter and setter methods ( G$foo and S$foo ) and fill 'direct' method handles. Is is okay to use reflection? Wouldn't that slow up initialization/start because NativeFoo constructors are all initialized by global? This is also applicable for generated classes. In the past, it was observed that field method handles were slower. Has that changed now?
2. There are also @Getter and @Setter methods which are turned into user defined Java getter/setter for properties. Do we have to have a hybrid scheme of filling? i.e., partially filled by MapCreator and fill in resulting map for @Getter/@Setter handles?
3. We have specific type (double type) constant properties in NativeMath. It appears we may have use always 'Object' to use MapCreator. Can we handle specific type properties? Or am I missing something?
4. How much of saving of <clinit> bytecodes expected? Is it worth doing this given that <clinit> gets executed only once? At the max 20 properties per built-in/native object (after splitting to prototype, constructor, instance it may be even lesser?). Has the big <clinit> been observed to be a problem in any specific benchmark?
Marcus:
1) It is not reflection, it is MethodHandles. This is the standard way to create a getter and setter and avoid weaving bytecode. As this is done in <clinit> only, I think the possible amount of slowdown is completely insignificant. I benchmarked startup for normal objects both with weaving bytecode and using MethodHandles. There was no discernable difference.I am not worried here, and less explicit bytecode is architecturally better.
2) We don't as of the now - I can build something.
3) We can handle them, but I think only in the dual field world. It is easy, however, to add special cases.
4) 50%-ish. Maybe a little bit more.
I can try to poc something.
Right now the constructors are unncessarily complex. We should treat NativeObjects like normal ScriptObjects. Not only is this more compact and produces way less bytecode, it also removes the need for special constructor in Property$AccessProperty where there are null getters or setters that have to be created on the fly.
Sundar:
Are you suggesting to process nasgen annotations etc @runtime ?
or just call MapCreator to fill in maps instead of directly calling newMap and making method handles etc. manually.
Marcus:
Just de-bloat the <clinit>s and stop using the newProperty accessor that is only made for nasgen
Sundar:
I spent sometime looking at current MapCreator for possible usage in nasgen. My observations based on whatever I read:
1. MapCreator uses reflection to fill up getter and setter handles. nasgen currently uses explicit getter and setter methods ( G$foo and S$foo ) and fill 'direct' method handles. Is is okay to use reflection? Wouldn't that slow up initialization/start because NativeFoo constructors are all initialized by global? This is also applicable for generated classes. In the past, it was observed that field method handles were slower. Has that changed now?
2. There are also @Getter and @Setter methods which are turned into user defined Java getter/setter for properties. Do we have to have a hybrid scheme of filling? i.e., partially filled by MapCreator and fill in resulting map for @Getter/@Setter handles?
3. We have specific type (double type) constant properties in NativeMath. It appears we may have use always 'Object' to use MapCreator. Can we handle specific type properties? Or am I missing something?
4. How much of saving of <clinit> bytecodes expected? Is it worth doing this given that <clinit> gets executed only once? At the max 20 properties per built-in/native object (after splitting to prototype, constructor, instance it may be even lesser?). Has the big <clinit> been observed to be a problem in any specific benchmark?
Marcus:
1) It is not reflection, it is MethodHandles. This is the standard way to create a getter and setter and avoid weaving bytecode. As this is done in <clinit> only, I think the possible amount of slowdown is completely insignificant. I benchmarked startup for normal objects both with weaving bytecode and using MethodHandles. There was no discernable difference.I am not worried here, and less explicit bytecode is architecturally better.
2) We don't as of the now - I can build something.
3) We can handle them, but I think only in the dual field world. It is easy, however, to add special cases.
4) 50%-ish. Maybe a little bit more.
I can try to poc something.