experiences with prototype
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Feb 6 14:38:56 UTC 2015
Peter,
I think I fixed most of the issues in the way; I've been able to compile
and run some tests successfully.
Attached is a patch of the changes that are required for the code to run
correctly; I had to desugar some constructs (i.e. for-each, non-static
inner class) as all desugared stuff currently has an issue in that javac
won't emit the special sauce that is required by the specializer to
correctly specialize a class. That's an issue with timing of the
compilation pipeline - we are aware of it; but, as it's a no trivial
fix, it means that, for now, it's better not to rely too much of
compiler-desugared code.
Maurizio
On 04/02/15 12:42, Maurizio Cimadamore wrote:
> Compiler fixes have been pushed, I will now look into the runtime
> issues you are getting...
>
> Maurizio
>
> On 04/02/15 10:18, Maurizio Cimadamore wrote:
>> Thanks for the additional feedback, I'll try to get at the bottom of
>> those issues.
>>
>> Maurizio
>>
>> On 04/02/15 08:46, Peter Levart wrote:
>>> Hi Maurizio,
>>>
>>> I have now managed to successfully compile the code. Here's the
>>> updated source:
>>>
>>> http://cr.openjdk.java.net/~plevart/misc/valhala-hacks/javany-src.jar
>>>
>>>
>>> But there's a StringIndexOutOfBoundsException thrown from
>>> specializer when running the following Test:
>>>
>>> public class Test {
>>> public static void main(String[] args) {
>>> List<int> ints = Arrays.asList(new int[]{1, 2, 3, 4, 5, 6,
>>> 7, 8});
>>> Iterator<int> it = ints.iterator();
>>> while (it.hasNext()) {
>>> System.out.println(it.next());
>>> }
>>> }
>>> }
>>>
>>>
>>> Specializing javany.util.List${0=I}; searching for
>>> javany/util/List.class (not found)
>>> Specializing javany.util.List${0=I}; searching for
>>> javany/util/List.class (found)
>>> Specializing javany.util.Collection${0=I}; searching for
>>> javany/util/Collection.class (not found)
>>> Specializing javany.util.Collection${0=I}; searching for
>>> javany/util/Collection.class (found)
>>> Specializing javany.lang.Iterable${0=I}; searching for
>>> javany/lang/Iterable.class (not found)
>>> Specializing javany.lang.Iterable${0=I}; searching for
>>> javany/lang/Iterable.class (found)
>>> Specializing method
>>> javany/util/Arrays$asList${0=I}.asList([Ljava/lang/Object;)Ljavany/util/List;
>>> with class=[] and method=[I]
>>> Specializing javany.util.Arrays$ArrayList${0=I}; searching for
>>> javany/util/Arrays$ArrayList.class (not found)
>>> Specializing javany.util.Arrays$ArrayList${0=I}; searching for
>>> javany/util/Arrays$ArrayList.class (found)
>>> Exception in thread "main"
>>> java.lang.StringIndexOutOfBoundsException: String index out of range: 0
>>> at java.lang.String.charAt(String.java:646)
>>> at
>>> jdk.internal.org.objectweb.asm.signature.SignatureReader.accept(SignatureReader.java:107)
>>> at
>>> valhalla.specializer.SignatureSpecializer.forType(SignatureSpecializer.java:72)
>>> at
>>> valhalla.specializer.Specializer$ManglingMethodVisitor.visitInvokeDynamicInsn(Specializer.java:679)
>>> at
>>> jdk.internal.org.objectweb.asm.ClassReader.readCode(ClassReader.java:1507)
>>> at
>>> jdk.internal.org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1084)
>>> at
>>> jdk.internal.org.objectweb.asm.ClassReader.accept(ClassReader.java:729)
>>> at
>>> valhalla.specializer.Specializer.specialize(Specializer.java:79)
>>> at java.net.URLClassLoader$1.run(URLClassLoader.java:409)
>>> at java.net.URLClassLoader$1.run(URLClassLoader.java:386)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at java.net.URLClassLoader.findClass(URLClassLoader.java:385)
>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:426)
>>> at
>>> sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317)
>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:359)
>>> at
>>> javany.util.Arrays$asList${0=I}/511754216.asList(Arrays.java:810)
>>> at Test.main(Test.java:10)
>>>
>>>
>>> Appart from that, I learned that when the component type of vararg
>>> array is an <any> type variable (for example: <any T> T[]
>>> Arrays.asList(T ... a)), the invocation doesn't compile:
>>>
>>> src/Test.java:10: error: method invoked with incorrect number of
>>> arguments; expected 3, found 1
>>> List<int> ints = Arrays.<int>asList(1, 2, 3);
>>> ^
>>> 1 error
>>>
>>>
>>> Non-specialized code also has problems at runtime:
>>>
>>> public class Test {
>>> public static void main(String[] args) {
>>> List<String> strings = Arrays.<String>asList("a", "b", "c");
>>> Iterator<String> it = strings.iterator();
>>> while (it.hasNext()) {
>>> System.out.println(it.next());
>>> }
>>> }
>>> }
>>>
>>>
>>> Exception in thread "main" java.lang.ClassFormatError: Absent Code
>>> attribute in method that is not native or abstract in class file
>>> javany/util/AbstractList
>>> at java.lang.ClassLoader.defineClass1(Native Method)
>>> at java.lang.ClassLoader.defineClass(ClassLoader.java:762)
>>> at
>>> java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
>>> at java.net.URLClassLoader.defineClass(URLClassLoader.java:537)
>>> at java.net.URLClassLoader.access$300(URLClassLoader.java:78)
>>> at java.net.URLClassLoader$1.run(URLClassLoader.java:438)
>>> at java.net.URLClassLoader$1.run(URLClassLoader.java:386)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at java.net.URLClassLoader.findClass(URLClassLoader.java:385)
>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:426)
>>> at
>>> sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317)
>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:359)
>>> at java.lang.ClassLoader.defineClass1(Native Method)
>>> at java.lang.ClassLoader.defineClass(ClassLoader.java:762)
>>> at
>>> java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
>>> at java.net.URLClassLoader.defineClass(URLClassLoader.java:537)
>>> at java.net.URLClassLoader.access$300(URLClassLoader.java:78)
>>> at java.net.URLClassLoader$1.run(URLClassLoader.java:438)
>>> at java.net.URLClassLoader$1.run(URLClassLoader.java:386)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at java.net.URLClassLoader.findClass(URLClassLoader.java:385)
>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:426)
>>> at
>>> sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:317)
>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:359)
>>> at javany.util.Arrays.asList(Arrays.java:810)
>>> at Test.main(Test.java:10)
>>>
>>>
>>>
>>> Regards, Peter
>>>
>>> On 02/03/2015 10:34 PM, Maurizio Cimadamore wrote:
>>>>
>>>> On 03/02/15 21:05, Peter Levart wrote:
>>>>> Hi Maurizio,
>>>>>
>>>>> I see. I thought this could be a nice idiom for boxing, since the
>>>>> following:
>>>>>
>>>>> (Object) 42
>>>>>
>>>>> ...is legal and results in an Integer object at runtime.
>>>> I'm not saying this will never work - actually the compiler is
>>>> currently accepting this kind of idioms, but the specializer does
>>>> nothing with it, so you'll get runtime errors.
>>>>>
>>>>> But I don't know if a checkcast is actually inserted for (Object).
>>>>> Could javac redundantly do it in case casting to Object is from
>>>>> expression of <any> type and also equip checkcast with BMA
>>>>> indicating the type of expression so that specialization could
>>>>> replace it with boxing code?
>>>> That will be the way forward, yes
>>>>
>>>> Maurizio
>>>>>
>>>>> Regards, Peter
>>>>>
>>>>>
>>>>> On 02/03/2015 08:09 PM, Maurizio Cimadamore wrote:
>>>>>>
>>>>>> On 03/02/15 18:46, Maurizio Cimadamore wrote:
>>>>>>> I will also investigate on the crash you are getting...
>>>>>> Hi Peter,
>>>>>> the crash is coming from this code in AbstractCollection (see
>>>>>> code in bold):
>>>>>>
>>>>>> public boolean contains(Object o) {
>>>>>> __WhereVal(E) {
>>>>>> Iterator<E> it = iterator();
>>>>>> if (o == null) {
>>>>>> return false;
>>>>>> } else {
>>>>>> while (it.hasNext())
>>>>>> *if (o.equals((Object) it.next()))*
>>>>>> return true;
>>>>>> }
>>>>>> return false;
>>>>>> }
>>>>>> __WhereRef(E) {
>>>>>> Iterator<E> it = iterator();
>>>>>> if (o == null) {
>>>>>> while (it.hasNext())
>>>>>> if (it.next() == null)
>>>>>> return true;
>>>>>> } else {
>>>>>> while (it.hasNext())
>>>>>> if (o.equals(it.next()))
>>>>>> return true;
>>>>>> }
>>>>>> return false;
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> I believe that, apart from the obvious javac bug, the code has an
>>>>>> issue, as it.next() is supposed to return a value there, but you
>>>>>> are casting to Object?
>>>>>>
>>>>>> For the records - a simpler test case for the bug is this:
>>>>>>
>>>>>> class Foo<any E> {
>>>>>> E e;
>>>>>> E get() { return e; }
>>>>>>
>>>>>> void test() {
>>>>>> __WhereVal(E) {
>>>>>> Object o = (Object)get();
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> Maurizio
>>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
diff -r src-old/javany/util/AbstractList.java src-new/javany/util/AbstractList.java
331c331
< return new Itr();
---
> return new Itr<>(this);
372c372
< return new ListItr(index);
---
> return new ListItr<>(this, index);
375c375,383
< private class Itr implements Iterator<E> {
---
> private static class Itr<any E> implements Iterator<E> {
>
> AbstractList<E> this$0;
>
> Itr(AbstractList<E> this$0) {
> this.this$0 = this$0;
> expectedModCount = this$0.modCount;
> }
>
393c401
< int expectedModCount = modCount;
---
> int expectedModCount;
396c404
< return cursor != size();
---
> return cursor != this$0.size();
403c411
< E next = get(i);
---
> E next = this$0.get(i);
419c427
< AbstractList.this.remove(lastRet);
---
> this$0.remove(lastRet);
423c431
< expectedModCount = modCount;
---
> expectedModCount = this$0.modCount;
430c438
< if (modCount != expectedModCount)
---
> if (this$0.modCount != expectedModCount)
435,436c443,446
< private class ListItr extends Itr implements ListIterator<E> {
< ListItr(int index) {
---
> private static class ListItr<any E> extends Itr<E> implements ListIterator<E> {
>
> ListItr(AbstractList<E> this$0, int index) {
> super(this$0);
448c458
< E previous = get(i);
---
> E previous = this$0.get(i);
471,472c481,482
< AbstractList.this.set(lastRet, e);
< expectedModCount = modCount;
---
> this$0.set(lastRet, e);
> expectedModCount = this$0.modCount;
483c493
< AbstractList.this.add(i, e);
---
> this$0.add(i, e);
486c496
< expectedModCount = modCount;
---
> expectedModCount = this$0.modCount;
Only in src-new/javany/util: AbstractList.java~
diff -r src-old/javany/util/Arrays.java src-new/javany/util/Arrays.java
823c823
< a = Objects.requireNonNull(array);
---
> a = (E[])Objects.requireNonNull(array);
916c916,917
< for (E e : a) {
---
> for (int i = 0; i < a.length ; i++) {
> E e = a[i];
Only in src-new/javany/util: Arrays.java~
diff -r src-old/javany/util/List.java src-new/javany/util/List.java
482c482,483
< for (E e : a) {
---
> for (int idx = 0; idx < a.length ; idx++) {
> E e = a[idx];
Only in src-new/javany/util: List.java~
diff -r src-old/Test.java src-new/Test.java
9,10c9,18
< public static void main(String[] args) {
< List<String> strings = Arrays.<String>asList("a", "b", "c");
---
> static void testInt() {
> List<int> ints = Arrays.asList(1, 2, 3);
> Iterator<int> it = ints.iterator();
> while (it.hasNext()) {
> System.out.println(it.next());
> }
> }
>
> static void testString() {
> List<String> strings = Arrays.asList("a", "b", "c");
14a23,27
> }
>
> public static void main(String[] args) {
> testString();
> testInt();
More information about the valhalla-dev
mailing list