hg: valhalla/valhalla/langtools: BytecodeMapping generation fixes:

Brian Goetz brian.goetz at oracle.com
Tue Jan 6 19:58:50 UTC 2015


Right.  There's a little more (but not much) plumbing needed here. 
We've got the part where a ref-specific method is not propagated into 
the template at specialization time; we need to do the part where 
val-specific methods are hidden when you load the erased class without 
specialization.  As a short-term hack, we'll probably rename these 
methods to something like:

   @Synthetic
   __$TEMPLATE_IGNORE_ME$__foo(...)

where they'll be visible but hopefully not in the way.

Stepping back, the point of implementing specialization (hacks or not) 
is to determine how practical it really is to any-fy our existing 
generic libraries.  My working theory is that if we can anyfy 
Collections and Streams, we've already seen 99% of what can go wrong, 
since these libraries have the "implementation tricks" knob turned up to 
11 (either for performance or compatibility reasons.)

What I expect will happen is, the experiment of trying to convert these 
libraries will generate a half dozen or so "oh, crap" realizations, some 
of which will feed back into new requirements.  But there's only so far 
that envisioning things on the whiteboard will get you.

On 1/6/2015 2:50 PM, Peter Levart wrote:
> I see, thanks.
>
> The problem with my Box<any T> example as it came to me after the fact
> is that the T=reference specialization is not a specialization at all -
> the javac generated template is used as is for the T=reference case
> unchanged - therefore it contains the __WhereVal(T) method too and javac
> is right to refuse to compile a call to it. Perhaps, if I reversed the
> parts and put __WhereVal(T) method in private superclass and
> __WhereRef(T) method in subclass, then it should work for T=reference
> case and probably also for T=primitive case if __WhereRef(T) methods are
> not included in primitive specialization and javac allows me to call the
> inherited method from superclass.
>
> Will try that.
>
>
> Regards, Peter
>
> On 01/06/2015 07:09 PM, Brian Goetz wrote:
>> Also, note: the __WhereRef(T) syntax is intended to be a quick hack,
>> this is definitely not where the syntax is going.  It was just what
>> was easy to implement quickly.
>>
>> On 1/6/2015 12:51 PM, Maurizio Cimadamore wrote:
>>> As you found out, layering support is still missing from the prototype;
>>> you have ability to declare RefOnly/ValOnly members but that's pretty
>>> much about it. It's still quite powerful though, albeit some things
>>> don't work automagically as you'd expect. What you are looking for is a
>>> way to write implementation by parts - and that's the bit that's missing
>>> from the current implementation (we have a rough proof of concept that
>>> does that, but it's not very polished, and the syntax that it supports
>>> is very different from the one described in the document).
>>>
>>> Maurizio
>>>
>>> On 06/01/15 17:27, Peter Levart wrote:
>>>> On 01/06/2015 02:00 PM, maurizio.cimadamore at oracle.com wrote:
>>>>> Changeset: 8331682af2ed
>>>>> Author:    mcimadamore
>>>>> Date:      2015-01-06 12:54 +0000
>>>>> URL:http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/8331682af2ed
>>>>>
>>>>>
>>>>>
>>>>> BytecodeMapping generation fixes:
>>>>> * missing BMA for eq/ne any comparisons nested within logic operators
>>>>> &&/||
>>>>> * missing BMA for field/method access immediately following a
>>>>> constructor call
>>>>> * refactor Items code in order to avoid cast to AnyItem in order to
>>>>> access type info associated with a given item
>>>>> * added tests
>>>>>
>>>>> ! src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
>>>>> ! src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java
>>>>> + test/tools/javac/valhalla/typespec/items/tests/TestBinary.java
>>>>> ! test/tools/javac/valhalla/typespec/items/tests/TestInstanceof.java
>>>>> ! test/tools/javac/valhalla/typespec/items/tests/TestNew.java
>>>>>
>>>>
>>>> Thanks Maurizio,
>>>>
>>>> It works now. But I have another (seems like javac) problem. Since
>>>> layers are not yet implemented (or I just can't seem to figure out how
>>>> to use them), I tried to use __WhereRef(T) and __WhereVal(T) with
>>>> inheritance to simulate them. My 1st goal was to create a Box<any T>
>>>> class that would implement Object.equals() in a way that would use
>>>> Objects.equals() for reference T and '==' for value T. Here's what I
>>>> came up with:
>>>>
>>>> // the Ref "layer"
>>>>
>>>> abstract class RefBoxBase<any T> {
>>>>
>>>>     public abstract T get();
>>>>
>>>>     public __WhereRef(T) int hashCode() {
>>>>         return Objects.hashCode(get());
>>>>     }
>>>>
>>>>     public __WhereRef(T) boolean equals(Object obj) {
>>>>         return (this == obj) ||
>>>>             (obj != null &&
>>>>                 this.getClass() == obj.getClass() &&
>>>>                 Objects.equals(this.get(), ((RefBoxBase<T>) obj).get())
>>>>             );
>>>>     }
>>>> }
>>>>
>>>> // the Val "overlay"
>>>>
>>>> public final class Box<any T> extends RefBoxBase<T> {
>>>>
>>>>     private T value;
>>>>
>>>>     public Box(T value) {
>>>>         this.value = value;
>>>>     }
>>>>
>>>>     public Box() {
>>>>         // leave default value
>>>>     }
>>>>
>>>>     public T get() {
>>>>         return value;
>>>>     }
>>>>
>>>>     public __WhereVal(T) int hashCode() {
>>>>         return 0; // don't know yet how to do something meaningful here
>>>>     }
>>>>
>>>>     public __WhereVal(T) boolean equals(Object obj) {
>>>>         return (this == obj) ||
>>>>             (obj != null &&
>>>>                 this.getClass() == obj.getClass() &&
>>>>                 this.get() == ((Box<T>)obj).get());
>>>>     }
>>>> }
>>>>
>>>>
>>>> And the test:
>>>>
>>>> public class Test {
>>>>     public static void main(String[] args) {
>>>>         System.out.println(new Box<int>(1).equals(new Box<int>(1)));
>>>> // this compiles fine
>>>>
>>>>         System.out.println(new Box<String>("a").equals(new
>>>> Box<String>("a"))); // compilation error
>>>>     }
>>>> }
>>>>
>>>> src/util/Test.java:6: error: bad receiver type Box<String> in
>>>> restricted method call
>>>>         System.out.println(new Box<String>("a").equals(new
>>>> Box<String>("a")));
>>>>                                                       ^
>>>> Note: src/util/RefBoxBase.java uses unchecked or unsafe operations.
>>>> Note: Recompile with -Xlint:unchecked for details.
>>>> 1 error
>>>>
>>>>
>>>> It's true that Box.equals() is restricted for Val receiver, but I
>>>> thought that RefBoxBase.equals() would be "uncovered" in this case an
>>>> inherited in Ref specialization.
>>>>
>>>>
>>>>
>>>> Regards, Peter
>>>>
>>>>
>>>
>


More information about the valhalla-dev mailing list