# HG changeset patch # User Christian Haeubl # Date 1354089699 -3600 # Node ID 3e61ffb9ce29fdb945635085f885c13271116b89 # Parent 15055bdafbfc7e2db40010254d73f1b5cb83b52a# Parent 113eb675c981df6ef5d7ef6a3c18230761bd35e3 Merge. diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TypeCheckHints.java Wed Nov 28 09:01:39 2012 +0100 @@ -111,7 +111,7 @@ * @return true if {@code type} has no subtype(s) */ public static boolean isFinalClass(ResolvedJavaType type) { - if (type.isArrayClass()) { + if (type.isArray()) { return isFinalClass(type.getComponentType()); } return Modifier.isFinal(type.getModifiers()); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/VirtualObject.java Wed Nov 28 09:01:39 2012 +0100 @@ -68,7 +68,7 @@ if (values == null) { buf.append(""); } else { - if (type.isArrayClass()) { + if (type.isArray()) { for (int i = 0; i < values.length; i++) { if (i != 0) { buf.append(','); @@ -112,7 +112,7 @@ private static boolean checkValues(ResolvedJavaType type, Value[] values) { if (values != null) { - if (!type.isArrayClass()) { + if (!type.isArray()) { ResolvedJavaField[] fields = type.getInstanceFields(true); assert fields.length == values.length : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values); for (int i = 0; i < values.length; i++) { diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/RuntimeInterpreterInterface.java --- a/graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/RuntimeInterpreterInterface.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.interpreter/src/com/oracle/graal/api/interpreter/RuntimeInterpreterInterface.java Wed Nov 28 09:01:39 2012 +0100 @@ -100,4 +100,5 @@ void setArrayObject(Object value, long index, Object array); + Class getMirror(ResolvedJavaType type); } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/NameAndSignature.java Wed Nov 28 09:01:39 2012 +0100 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.graal.api.meta.*; + +class NameAndSignature { + final String name; + final Class returnType; + final Class[] parameterTypes; + + public NameAndSignature(Method m) { + this.name = m.getName(); + this.returnType = m.getReturnType(); + this.parameterTypes = m.getParameterTypes(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof NameAndSignature) { + NameAndSignature s = (NameAndSignature) obj; + return s.returnType == returnType && name.equals(s.name) && Arrays.equals(s.parameterTypes, parameterTypes); + } + return false; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(name + "("); + String sep = ""; + for (Class p : parameterTypes) { + sb.append(sep); + sep = ", "; + sb.append(p.getName()); + } + return sb.append(')').append(returnType.getName()).toString(); + } + + public boolean signatureEquals(ResolvedJavaMethod m) { + Signature s = m.getSignature(); + ResolvedJavaType declaringClass = m.getDeclaringClass(); + if (!s.getReturnType(declaringClass).resolve(declaringClass).isClass(returnType)) { + return false; + } + if (s.getParameterCount(false) != parameterTypes.length) { + return false; + } + for (int i = 0; i < parameterTypes.length; i++) { + if (!s.getParameterType(i, declaringClass).resolve(declaringClass).isClass(parameterTypes[i])) { + return false; + } + } + return true; + } +} diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java Wed Nov 28 09:01:39 2012 +0100 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import static com.oracle.graal.api.meta.test.TestMetaAccessProvider.*; +import static org.junit.Assert.*; + +import java.lang.reflect.*; +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; + +/** + * Tests for {@link JavaMethod}. + */ +public class TestJavaMethod { + + public TestJavaMethod() { + } + + public static final Map methods = new HashMap<>(); + public static final Map constructors = new HashMap<>(); + static { + for (Class c : classes) { + for (Method m : c.getDeclaredMethods()) { + ResolvedJavaMethod method = runtime.lookupJavaMethod(m); + methods.put(m, method); + } + for (Constructor m : c.getDeclaredConstructors()) { + constructors.put(m, runtime.lookupJavaConstructor(m)); + } + } + } + + @Test + public void getNameTest() { + for (Map.Entry e : methods.entrySet()) { + String expected = e.getKey().getName(); + String actual = e.getValue().getName(); + assertEquals(expected, actual); + } + } + + @Test + public void getDeclaringClassTest() { + for (Map.Entry e : methods.entrySet()) { + Class expected = e.getKey().getDeclaringClass(); + ResolvedJavaType actual = e.getValue().getDeclaringClass(); + assertTrue(actual.isClass(expected)); + } + } + + @Test + public void getSignatureTest() { + for (Map.Entry e : methods.entrySet()) { + assertTrue(new NameAndSignature(e.getKey()).signatureEquals(e.getValue())); + } + } +} diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java Wed Nov 28 09:01:39 2012 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import static com.oracle.graal.api.meta.test.TestMetaAccessProvider.*; +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; + +/** + * Tests for {@link JavaType}. + */ +public class TestJavaType { + + public TestJavaType() { + } + + @Test + public void getKindTest() { + for (Class c : classes) { + JavaType type = runtime.lookupJavaType(c); + Kind expected = Kind.fromJavaClass(c); + Kind actual = type.getKind(); + assertEquals(expected, actual); + } + } +} diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java Wed Nov 28 09:01:39 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,11 +31,32 @@ import org.junit.*; +import sun.misc.Unsafe; + import com.oracle.graal.api.meta.*; import com.oracle.graal.api.runtime.*; +/** + * Tests for {@link MetaAccessProvider}. + */ +public class TestMetaAccessProvider { -public class TestMetaAccessProvider { + public static final Unsafe unsafe; + static { + Unsafe theUnsafe = null; + try { + theUnsafe = Unsafe.getUnsafe(); + } catch (Exception e) { + try { + Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + theUnsafeField.setAccessible(true); + theUnsafe = (Unsafe) theUnsafeField.get(null); + } catch (Exception e1) { + throw (InternalError) new InternalError("unable to initialize unsafe").initCause(e1); + } + } + unsafe = theUnsafe; + } public TestMetaAccessProvider() { } @@ -165,7 +186,7 @@ assertNotNull(type); assertTrue(type.isClass(c)); assertEquals(c.getModifiers(), type.getModifiers()); - if (!type.isArrayClass()) { + if (!type.isArray()) { assertEquals(type.getName(), toInternalName(c.getName())); assertEquals(toJavaName(type), c.getName()); } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Wed Nov 28 09:01:39 2012 +0100 @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.api.meta.test; + +import static com.oracle.graal.api.meta.test.TestJavaMethod.*; +import static java.lang.reflect.Modifier.*; +import static org.junit.Assert.*; + +import java.lang.reflect.*; +import java.util.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; + +/** + * Tests for {@link ResolvedJavaMethod}. + */ +public class TestResolvedJavaMethod { + + public TestResolvedJavaMethod() { + } + + /** + * @see ResolvedJavaMethod#getCode() + */ + @Test + public void getCodeTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + byte[] code = m.getCode(); + assertNotNull(code); + if (isAbstract(m.getModifiers())) { + assertTrue(code.length == 0); + } else if (!isNative(m.getModifiers())) { + assertTrue(code.length > 0); + } + } + } + + /** + * @see ResolvedJavaMethod#getCodeSize() + */ + @Test + public void getCodeSizeTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + int codeSize = m.getCodeSize(); + if (isAbstract(m.getModifiers())) { + assertTrue(codeSize == 0); + } else if (!isNative(m.getModifiers())) { + assertTrue(codeSize > 0); + } + } + } + + /** + * @see ResolvedJavaMethod#getCompiledCodeSize() + */ + @Test + public void getCompiledCodeSizeTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + int size = m.getCompiledCodeSize(); + if (isAbstract(m.getModifiers())) { + assertTrue(size == 0); + } else { + assertTrue(size >= 0); + } + } + } + + @Test + public void getCompilationComplexityTest() { + // TODO + } + + @Test + public void getMaxLocalsTest() { + // TODO + } + + @Test + public void getMaxStackSizeTest() { + // TODO + } + + @Test + public void getModifiersTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + int expected = e.getKey().getModifiers() & Modifier.methodModifiers(); + int actual = m.getModifiers(); + assertEquals(expected, actual); + } + } + + /** + * @see ResolvedJavaMethod#isClassInitializer() + */ + @Test + public void isClassInitializerTest() { + for (Map.Entry e : methods.entrySet()) { + // Class initializers are hidden from reflection + ResolvedJavaMethod m = e.getValue(); + assertFalse(m.isClassInitializer()); + } + for (Map.Entry e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertFalse(m.isClassInitializer()); + } + } + + @Test + public void isConstructorTest() { + for (Map.Entry e : methods.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertFalse(m.isConstructor()); + } + for (Map.Entry e : constructors.entrySet()) { + ResolvedJavaMethod m = e.getValue(); + assertTrue(m.isConstructor()); + } + } + + @Test + public void canBeStaticallyBoundTest() { + // TODO + } + + @Test + public void getExceptionHandlersTest() { + // TODO + } + + @Test + public void asStackTraceElementTest() { + // TODO + } + + @Test + public void getProfilingInfoTest() { + // TODO + } + + @Test + public void getCompilerStorageTest() { + // TODO + } + + @Test + public void getConstantPoolTest() { + // TODO + } + + @Test + public void getAnnotationTest() { + // TODO + } + + @Test + public void getParameterAnnotationsTest() { + // TODO + } + + @Test + public void getGenericParameterTypesTest() { + // TODO + + } + + @Test + public void canBeInlinedTest() { + // TODO + } +} diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Wed Nov 28 09:01:39 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,12 +36,31 @@ import com.oracle.graal.api.meta.*; +/** + * Tests for {@link ResolvedJavaType}. + */ public class TestResolvedJavaType { public TestResolvedJavaType() { } @Test + public void findInstanceFieldWithOffsetTest() { + for (Class c : classes) { + ResolvedJavaType type = runtime.lookupJavaType(c); + Set reflectionFields = getInstanceFields(c, true); + for (Field f : reflectionFields) { + ResolvedJavaField rf = lookupField(type.getInstanceFields(true), f); + assertNotNull(rf); + long offset = isStatic(f.getModifiers()) ? unsafe.staticFieldOffset(f) : unsafe.objectFieldOffset(f); + ResolvedJavaField result = type.findInstanceFieldWithOffset(offset); + assertNotNull(result); + assertTrue(fieldsEqual(f, result)); + } + } + } + + @Test public void isInterfaceTest() { for (Class c : classes) { ResolvedJavaType type = runtime.lookupJavaType(c); @@ -67,7 +86,7 @@ for (Class c : classes) { ResolvedJavaType type = runtime.lookupJavaType(c); boolean expected = c.isArray(); - boolean actual = type.isArrayClass(); + boolean actual = type.isArray(); assertEquals(expected, actual); } } @@ -239,23 +258,23 @@ static void checkConcreteSubtype(ResolvedJavaType type, Class expected) { ResolvedJavaType subtype = type.findUniqueConcreteSubtype(); - if (type.isInterface() && subtype == null) { - // A runtime may not record the subtype tree for interfaces in which case - // findUniqueConcreteSubtype() will return null for interfaces. - return; + if (subtype == null) { + // findUniqueConcreteSubtype() is conservative + } else { + if (expected == null) { + assertNull(subtype); + } else { + assertTrue(subtype.isClass(expected)); + } } - if (expected == null) { - assertNull(subtype); - } else { - assertTrue(subtype.isClass(expected)); - } - if (!type.isArrayClass()) { + if (!type.isArray()) { ResolvedJavaType arrayType = type.getArrayClass(); - if (subtype == type) { - assertEquals(arrayType.findUniqueConcreteSubtype(), arrayType); + ResolvedJavaType arraySubtype = arrayType.findUniqueConcreteSubtype(); + if (arraySubtype != null) { + assertEquals(arraySubtype, arrayType); } else { - assertNull(arrayType.findUniqueConcreteSubtype()); + // findUniqueConcreteSubtype() method is conservative } } } @@ -350,44 +369,8 @@ static final Map vtables = new HashMap<>(); - static class NameAndSig { - final String name; - final Class returnType; - final Class[] parameterTypes; - public NameAndSig(Method m) { - this.name = m.getName(); - this.returnType = m.getReturnType(); - this.parameterTypes = m.getParameterTypes(); - } - @Override - public boolean equals(Object obj) { - if (obj instanceof NameAndSig) { - NameAndSig s = (NameAndSig) obj; - return s.returnType == returnType && name.equals(s.name) && Arrays.equals(s.parameterTypes, parameterTypes); - } - return false; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(name + "("); - String sep = ""; - for (Class p : parameterTypes) { - sb.append(sep); - sep = ", "; - sb.append(p.getName()); - } - return sb.append(')').append(returnType.getName()).toString(); - } - } - static class VTable { - final Map methods = new HashMap<>(); + final Map methods = new HashMap<>(); } static synchronized VTable getVTable(Class c) { @@ -400,7 +383,7 @@ } for (Method m : c.getDeclaredMethods()) { if (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers())) { - Method overridden = vtable.methods.put(new NameAndSig(m), m); + Method overridden = vtable.methods.put(new NameAndSignature(m), m); if (overridden != null) { //System.out.println(m + " overrides " + overridden); } @@ -413,10 +396,10 @@ static Set findDeclarations(Method impl, Class c) { Set declarations = new HashSet<>(); - NameAndSig implSig = new NameAndSig(impl); + NameAndSignature implSig = new NameAndSignature(impl); if (c != null) { for (Method m : c.getDeclaredMethods()) { - if (new NameAndSig(m).equals(implSig)) { + if (new NameAndSignature(m).equals(implSig)) { declarations.add(m); break; } @@ -475,24 +458,30 @@ return result; } - public static boolean containsField(ResolvedJavaField[] fields, Field f) { + public static boolean fieldsEqual(Field f, ResolvedJavaField rjf) { + return rjf.getDeclaringClass().isClass(f.getDeclaringClass()) && + rjf.getName().equals(f.getName()) && + rjf.getType().resolve(rjf.getDeclaringClass()).isClass(f.getType()); + } + + public static ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) { for (ResolvedJavaField rf : fields) { - if (rf.getName().equals(f.getName()) && rf.getType().resolve(rf.getDeclaringClass()).isClass(f.getType())) { - assert f.getModifiers() == rf.getModifiers() : f; - return true; + if (fieldsEqual(key, rf)) { + assert key.getModifiers() == rf.getModifiers() : key; + return rf; } } - return false; + return null; } - public static boolean containsField(Set fields, ResolvedJavaField rf) { + public static Field lookupField(Set fields, ResolvedJavaField key) { for (Field f : fields) { - if (f.getName().equals(rf.getName()) && rf.getType().resolve(rf.getDeclaringClass()).isClass(f.getType())) { - assert rf.getModifiers() == f.getModifiers() : rf; - return true; + if (fieldsEqual(f, key)) { + assert key.getModifiers() == f.getModifiers() : key; + return f; } } - return false; + return null; } private static boolean isHiddenFromReflection(ResolvedJavaField f) { @@ -513,11 +502,11 @@ Set expected = getInstanceFields(c, includeSuperclasses); ResolvedJavaField[] actual = type.getInstanceFields(includeSuperclasses); for (Field f : expected) { - assertTrue(containsField(actual, f)); + assertNotNull(lookupField(actual, f)); } for (ResolvedJavaField rf : actual) { if (!isHiddenFromReflection(rf)) { - assertEquals(containsField(expected, rf), !rf.isInternal()); + assertEquals(lookupField(expected, rf) != null, !rf.isInternal()); } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java Wed Nov 28 09:01:39 2012 +0100 @@ -43,6 +43,11 @@ ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod); /** + * Provides the {@link ResolvedJavaMethod} for a {@link Constructor} obtained via reflection. + */ + ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor); + + /** * Provides the {@link ResolvedJavaField} for a {@link Field} obtained via reflection. */ ResolvedJavaField lookupJavaField(Field reflectionField); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaUtil.java Wed Nov 28 09:01:39 2012 +0100 @@ -37,19 +37,63 @@ public class MetaUtil { /** - * Returns true if the specified typed is exactly the type {@link java.lang.Object}. + * Gets the {@link Class} mirror for a given resolved type. + * + * @param type the type for which the Java mirror is requested + * @param loader class loader from which the class must be loaded (null means use the class loader of the {@link MetaUtil} class) + * @return the mirror for {@code type} + * @throws NoClassDefFoundError if the mirror is not available */ - public static boolean isJavaLangObject(ResolvedJavaType type) { - boolean result = type.getSuperclass() == null && !type.isInterface() && type.getKind() == Kind.Object; - assert result == type.getName().equals("Ljava/lang/Object;") : type.getName(); - return result; + public static Class getMirrorOrFail(ResolvedJavaType type, ClassLoader loader) throws NoClassDefFoundError { + ResolvedJavaType elementalType = getElementalType(type); + Class elementalClass; + if (elementalType.isPrimitive()) { + elementalClass = type.getKind().toJavaClass(); + } else { + try { + elementalClass = Class.forName(toJavaName(elementalType), true, loader); + } catch (ClassNotFoundException e) { + throw (NoClassDefFoundError) new NoClassDefFoundError().initCause(e); + } + } + if (type.isArray()) { + ResolvedJavaType t = type; + while (t.getComponentType() != null) { + elementalClass = Array.newInstance(elementalClass, 0).getClass(); + t = t.getComponentType(); + } + } + assert elementalClass != null : toJavaName(type); + return elementalClass; } /** - * Determines if a given type represents a primitive type. + * Gets the {@link Class} mirror for a given resolved type. + * + * @param type the type for which the Java mirror is requested + * @param loader class loader from which the class must be loaded (null means use the class loader of the {@link MetaUtil} class) + * @return the mirror for {@code type} or null if it is not available */ - public static boolean isPrimitive(ResolvedJavaType type) { - return type.getSuperclass() == null && !type.isInstanceClass(); + public static Class getMirror(ResolvedJavaType type, ClassLoader loader) { + try { + return getMirrorOrFail(type, loader); + } catch (NoClassDefFoundError e) { + return null; + } + } + + /** + * Gets the elemental type for a given type. + * The elemental type of an array type is the corresponding zero dimensional (e.g., + * the elemental type of {@code int[][][]} is {@code int}). A non-array type is its + * own elemental type. + */ + public static ResolvedJavaType getElementalType(ResolvedJavaType type) { + ResolvedJavaType t = type; + while (t.getComponentType() != null) { + t = t.getComponentType(); + } + return t; } /** @@ -429,15 +473,6 @@ return result; } - public static Class< ? >[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) { - int count = signature.getParameterCount(false); - Class< ? >[] result = new Class< ? >[count]; - for (int i = 0; i < result.length; ++i) { - result[i] = signature.getParameterType(i, accessingClass).resolve(accessingClass).toJava(); - } - return result; - } - /** * Formats some profiling information associated as a string. * diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java Wed Nov 28 09:01:39 2012 +0100 @@ -101,7 +101,14 @@ * * @return {@code true} if this type is an array class */ - boolean isArrayClass(); + boolean isArray(); + + /** + * Checks whether this type is primitive. + * + * @return {@code true} if this type is primitive + */ + boolean isPrimitive(); /** * Returns the Java language modifiers for this type, as an integer. The {@link Modifier} class should be used to @@ -171,13 +178,21 @@ ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType); /** - * Gets the unique concrete subclass of this type. - * + * Attempts to get a unique concrete subclass of this type. + *

+ * For an {@linkplain #isArray() array} type A, the unique concrete subclass is A if + * the element type of A is primitive or has no subtype. Otherwise there is no unique concrete subclass. + *

+ * For a non-array type T, the result is the unique concrete type in the complete hierarchy of T. + *

+ * A runtime may decide not to manage or walk a large hierarchy and so the result is conservative. + * That is, a non-null result is guaranteed to be the unique concrete class in T's hierarchy + * but a null result does not necessarily imply that there is no unique concrete class in T's hierarchy. *

* If the compiler uses the result of this method for its compilation, it must register an assumption because * dynamic class loading can invalidate the result of this method. * - * @return the exact type of this type, if it exists; {@code null} otherwise + * @return the unique concrete subclass for this type as described above */ ResolvedJavaType findUniqueConcreteSubtype(); @@ -231,7 +246,11 @@ boolean isClass(Class c); /** - * Returns the {@link java.lang.Class} object representing this type. + * Returns the instance field of this class (or one of its super classes) at the given + * offset, or {@code null} if there is no such field. + * + * @param offset the offset of the field to look for + * @return the field with the given offset, or {@code null} if there is no such field. */ - Class< ? > toJava(); + ResolvedJavaField findInstanceFieldWithOffset(long offset); } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Wed Nov 28 09:01:39 2012 +0100 @@ -232,7 +232,7 @@ // - has no callee-saved registers // - has no incoming arguments passed on the stack // - has no instructions with debug info - boolean canOmitFrame = + boolean canOmitFrame = GraalOptions.CanOmitFrame && frameMap.frameSize() == frameMap.initialFrameSize && frameMap.registerConfig.getCalleeSaveLayout().registers.length == 0 && !lir.hasArgInCallerFrame() && diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeInterpreterInterface.java Wed Nov 28 09:01:39 2012 +0100 @@ -40,6 +40,10 @@ this.metaProvider = metaProvider; } + public Class< ? > getMirror(ResolvedJavaType type) { + return ((HotSpotJavaType) type).mirror(); + } + public native Object invoke(ResolvedJavaMethod method, Object... args); public void monitorEnter(Object value) { @@ -53,7 +57,7 @@ } public Object newObject(ResolvedJavaType type) throws InstantiationException { - return unsafe.allocateInstance(type.toJava()); + return unsafe.allocateInstance(getMirror(type)); } public Object getFieldObject(Object base, ResolvedJavaField field) { @@ -286,7 +290,7 @@ return; } ResolvedJavaType type = metaProvider.lookupJavaType(array.getClass()).getComponentType(); - if (!type.toJava().isAssignableFrom(arrayType)) { + if (!getMirror(type).isAssignableFrom(arrayType)) { throw new ArrayStoreException(arrayType.getName()); } } @@ -294,7 +298,7 @@ private void checkArray(Object array, long index) { nullCheck(array); ResolvedJavaType type = metaProvider.lookupJavaType(array.getClass()); - if (!type.isArrayClass()) { + if (!type.isArray()) { throw new ArrayStoreException(array.getClass().getName()); } if (index < 0 || index >= arrayLength(array)) { @@ -315,10 +319,10 @@ return ((HotSpotResolvedJavaField) field).offset(); } - private static Object resolveBase(Object base, ResolvedJavaField field) { + private Object resolveBase(Object base, ResolvedJavaField field) { Object accessorBase = base; if (accessorBase == null) { - accessorBase = field.getDeclaringClass().toJava(); + accessorBase = getMirror(field.getDeclaringClass()); } return accessorBase; } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Wed Nov 28 09:01:39 2012 +0100 @@ -166,6 +166,7 @@ * @return the metaspace Method result for {@code reflectionMethod} */ long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedJavaType[] resultHolder); + long getMetaspaceConstructor(Constructor reflectionConstructor, HotSpotResolvedJavaType[] resultHolder); HotSpotResolvedJavaField getJavaField(Field reflectionField); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Wed Nov 28 09:01:39 2012 +0100 @@ -38,6 +38,9 @@ public native long getMetaspaceMethod(Method reflectionMethod, HotSpotResolvedJavaType[] resultHolder); @Override + public native long getMetaspaceConstructor(Constructor reflectionConstructor, HotSpotResolvedJavaType[] resultHolder); + + @Override public native HotSpotResolvedJavaField getJavaField(Field reflectionMethod); @Override diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Wed Nov 28 09:01:39 2012 +0100 @@ -45,8 +45,6 @@ JavaMethod createUnresolvedJavaMethod(String name, String signature, JavaType holder); - Signature createSignature(String signature); - JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal); ResolvedJavaMethod createResolvedJavaMethod(JavaType holder, long metaspaceMethod); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Nov 28 09:01:39 2012 +0100 @@ -85,7 +85,7 @@ } private static void initMirror(HotSpotTypePrimitive type, long offset) { - Class< ? > mirror = type.toJava(); + Class mirror = type.mirror(); unsafe.putObject(mirror, offset, type); assert unsafe.getObject(mirror, offset) == type; } @@ -444,11 +444,6 @@ } @Override - public Signature createSignature(String signature) { - return new HotSpotSignature(signature); - } - - @Override public JavaField createJavaField(JavaType holder, String name, JavaType type, int offset, int flags, boolean internal) { if (offset != -1) { HotSpotResolvedJavaType resolved = (HotSpotResolvedJavaType) holder; diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotJavaType.java Wed Nov 28 09:01:39 2012 +0100 @@ -41,4 +41,6 @@ public final String getName() { return name; } + + public abstract Class mirror(); } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Wed Nov 28 09:01:39 2012 +0100 @@ -79,7 +79,7 @@ assert Modifier.isStatic(flags); if (constant == null) { if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) { - if (Modifier.isFinal(getModifiers()) || assumeStaticFieldsFinal(holder.toJava())) { + if (Modifier.isFinal(getModifiers()) || assumeStaticFieldsFinal(holder.mirror())) { constant = readValue(receiver); } } @@ -154,7 +154,7 @@ private Field toJava() { try { - return holder.toJava().getDeclaredField(name); + return holder.mirror().getDeclaredField(name); } catch (NoSuchFieldException e) { return null; } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Wed Nov 28 09:01:39 2012 +0100 @@ -258,9 +258,19 @@ return javaMethod == null ? null : javaMethod.getGenericParameterTypes(); } + public Class[] signatureToTypes() { + Signature sig = getSignature(); + int count = sig.getParameterCount(false); + Class< ? >[] result = new Class< ? >[count]; + for (int i = 0; i < result.length; ++i) { + result[i] = ((HotSpotJavaType) sig.getParameterType(i, holder).resolve(holder)).mirror(); + } + return result; + } + private Method toJava() { try { - return holder.toJava().getDeclaredMethod(name, MetaUtil.signatureToTypes(getSignature(), holder)); + return holder.mirror().getDeclaredMethod(name, signatureToTypes()); } catch (NoSuchMethodException e) { return null; } @@ -268,7 +278,7 @@ private Constructor toJavaConstructor() { try { - return holder.toJava().getDeclaredConstructor(MetaUtil.signatureToTypes(getSignature(), holder)); + return holder.mirror().getDeclaredConstructor(signatureToTypes()); } catch (NoSuchMethodException e) { return null; } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java Wed Nov 28 09:01:39 2012 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.meta; +import static com.oracle.graal.api.meta.MetaUtil.*; import static com.oracle.graal.graph.FieldIntrospection.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static java.lang.reflect.Modifier.*; @@ -130,7 +131,7 @@ this.hasFinalizableSubclass = hasFinalizableSubclass; this.sizeOrSpecies = sizeOrSpecies; assert name.charAt(0) != '[' || sizeOrSpecies == ARRAY_SPECIES_VALUE : name + " " + Long.toHexString(sizeOrSpecies); - assert javaMirror.isArray() == isArrayClass(); + assert javaMirror.isArray() == isArray(); assert javaMirror.isInterface() == isInterface(); //System.out.println("0x" + Long.toHexString(metaspaceKlass) + ": " + name); } @@ -159,12 +160,27 @@ return javaComponentType == null ? null : fromClass(javaComponentType); } + private static boolean hasSubtype(ResolvedJavaType type) { + assert !type.isArray() : type; + if (type.isPrimitive()) { + return false; + } + HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); + if (unsafeReadWord(((HotSpotResolvedJavaType) type).metaspaceKlass + config.subklassOffset) != 0) { + return true; + } + return false; + } + @Override public ResolvedJavaType findUniqueConcreteSubtype() { - if (isArrayClass()) { - return getComponentType().findUniqueConcreteSubtype() == getComponentType() ? this : null; + HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); + if (isArray()) { + if (hasSubtype(getElementalType(this))) { + return null; + } + return this; } else { - HotSpotVMConfig config = HotSpotGraalRuntime.getInstance().getConfig(); HotSpotResolvedJavaType type = this; while (isAbstract(type.getModifiers())) { long subklass = unsafeReadWord(type.metaspaceKlass + config.subklassOffset); @@ -176,7 +192,6 @@ if (unsafeReadWord(type.metaspaceKlass + config.subklassOffset) != 0) { return null; } - assert !type.isInterface(); return type; } } @@ -201,9 +216,9 @@ } public HotSpotResolvedJavaType getSupertype() { - if (isArrayClass()) { + if (isArray()) { ResolvedJavaType componentType = getComponentType(); - if (javaMirror == Object[].class || componentType instanceof HotSpotTypePrimitive) { + if (javaMirror == Object[].class || componentType.isPrimitive()) { return (HotSpotResolvedJavaType) fromClass(Object.class); } return (HotSpotResolvedJavaType) ((HotSpotResolvedJavaType) componentType).getSupertype().getArrayClass(); @@ -216,7 +231,7 @@ @Override public ResolvedJavaType findLeastCommonAncestor(ResolvedJavaType otherType) { - if (otherType instanceof HotSpotTypePrimitive) { + if (otherType.isPrimitive()) { return null; } else { HotSpotResolvedJavaType t1 = this; @@ -236,7 +251,7 @@ @Override public ResolvedJavaType asExactType() { - if (isArrayClass()) { + if (isArray()) { return getComponentType().asExactType() != null ? this : null; } return Modifier.isFinal(getModifiers()) ? this : null; @@ -270,7 +285,12 @@ } @Override - public boolean isArrayClass() { + public boolean isPrimitive() { + return false; + } + + @Override + public boolean isArray() { return sizeOrSpecies == ARRAY_SPECIES_VALUE; } @@ -300,7 +320,7 @@ @Override public boolean isInstanceClass() { - return !isArrayClass() && !isInterface(); + return !isArray() && !isInterface(); } @Override @@ -346,7 +366,7 @@ * value gives the size). Must not be called if this is an array or interface type. */ public int instanceSize() { - assert !isArrayClass(); + assert !isArray(); assert !isInterface(); return sizeOrSpecies; } @@ -396,7 +416,7 @@ @Override public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { if (instanceFields == null) { - if (isArrayClass() || isInterface()) { + if (isArray() || isInterface()) { instanceFields = new HotSpotResolvedJavaField[0]; } else { HotSpotResolvedJavaField[] myFields = HotSpotGraalRuntime.getInstance().getCompilerToVM().getInstanceFields(this); @@ -428,7 +448,7 @@ } @Override - public Class< ? > toJava() { + public Class mirror() { return javaMirror; } @@ -466,4 +486,15 @@ public long prototypeMarkWord() { return HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrototypeMarkWord(this); } + + @Override + public ResolvedJavaField findInstanceFieldWithOffset(long offset) { + ResolvedJavaField[] declaredFields = getInstanceFields(true); + for (ResolvedJavaField field : declaredFields) { + if (((HotSpotResolvedJavaField) field).offset() == offset) { + return field; + } + } + return null; + } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Nov 28 09:01:39 2012 +0100 @@ -460,7 +460,7 @@ ValueNode expected = cas.expected(); if (expected.kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) { ResolvedJavaType type = cas.object().objectStamp().type(); - if (type != null && !type.isArrayClass() && type.toJava() != Object.class) { + if (type != null && !type.isArray() && !type.isClass(Object.class)) { // Use a field write barrier since it's not an array store FieldWriteBarrier writeBarrier = graph.add(new FieldWriteBarrier(cas.object())); graph.addAfterFixed(cas, writeBarrier); @@ -491,7 +491,7 @@ ResolvedJavaType arrayType = array.objectStamp().type(); if (arrayType != null && array.objectStamp().isExactType()) { ResolvedJavaType elementType = arrayType.getComponentType(); - if (!MetaUtil.isJavaLangObject(elementType)) { + if (!elementType.isClass(Object.class)) { CheckCastNode checkcast = graph.add(new CheckCastNode(elementType, value, null)); graph.addBeforeFixed(storeIndexed, checkcast); value = checkcast; @@ -533,7 +533,7 @@ if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) { ResolvedJavaType type = object.objectStamp().type(); WriteBarrier writeBarrier; - if (type != null && !type.isArrayClass() && type.toJava() != Object.class) { + if (type != null && !type.isArray() && !type.isClass(Object.class)) { // Use a field write barrier since it's not an array store writeBarrier = graph.add(new FieldWriteBarrier(object)); } else { @@ -602,13 +602,14 @@ ResolvedJavaType holder = method.getDeclaringClass(); String fullName = method.getName() + ((HotSpotSignature) method.getSignature()).asString(); Kind wordKind = graalRuntime.getTarget().wordKind; - if (holder.toJava() == Object.class) { + if (holder.isClass(Object.class)) { if (fullName.equals("getClass()Ljava/lang/Class;")) { ValueNode obj = (ValueNode) parameters.get(0); ObjectStamp stamp = (ObjectStamp) obj.stamp(); if (stamp.nonNull() && stamp.isExactType()) { StructuredGraph graph = new StructuredGraph(); - ValueNode result = ConstantNode.forObject(stamp.type().toJava(), this, graph); + HotSpotJavaType type = (HotSpotJavaType) stamp.type(); + ValueNode result = ConstantNode.forObject(type.mirror(), this, graph); ReturnNode ret = graph.add(new ReturnNode(result)); graph.start().setNext(ret); return graph; @@ -623,7 +624,7 @@ hub.setNext(ret); return graph; } - } else if (holder.toJava() == Class.class) { + } else if (holder.isClass(Class.class)) { if (fullName.equals("getModifiers()I")) { StructuredGraph graph = new StructuredGraph(); LocalNode receiver = graph.unique(new LocalNode(0, StampFactory.objectNonNull())); @@ -638,7 +639,7 @@ klass.setNext(ret); return graph; } - } else if (holder.toJava() == Thread.class) { + } else if (holder.isClass(Thread.class)) { if (fullName.equals("currentThread()Ljava/lang/Thread;")) { StructuredGraph graph = new StructuredGraph(); ReturnNode ret = graph.add(new ReturnNode(graph.unique(new CurrentThread(config.threadObjectOffset, this)))); @@ -677,7 +678,14 @@ return resultHolder[0].createMethod(metaspaceMethod); } - @Override + public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) { + CompilerToVM c2vm = graalRuntime.getCompilerToVM(); + HotSpotResolvedJavaType[] resultHolder = {null}; + long metaspaceMethod = c2vm.getMetaspaceConstructor(reflectionConstructor, resultHolder); + assert metaspaceMethod != 0L; + return resultHolder[0].createMethod(metaspaceMethod); + } + public ResolvedJavaField lookupJavaField(Field reflectionField) { return graalRuntime.getCompilerToVM().getJavaField(reflectionField); } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java Wed Nov 28 09:01:39 2012 +0100 @@ -117,7 +117,7 @@ } JavaType type = argumentTypes[index]; if (type == null || !(type instanceof ResolvedJavaType)) { - type = HotSpotGraalRuntime.getInstance().lookupType(arguments.get(index), (HotSpotResolvedJavaType) accessingClass, true); + type = HotSpotGraalRuntime.getInstance().lookupType(arguments.get(index), (HotSpotResolvedJavaType) accessingClass, false); argumentTypes[index] = type; } return type; @@ -134,7 +134,7 @@ @Override public JavaType getReturnType(ResolvedJavaType accessingClass) { - if (returnTypeCache == null) { + if (returnTypeCache == null || !(returnTypeCache instanceof ResolvedJavaType)) { returnTypeCache = HotSpotGraalRuntime.getInstance().lookupType(returnType, (HotSpotResolvedJavaType) accessingClass, false); } return returnTypeCache; diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypePrimitive.java Wed Nov 28 09:01:39 2012 +0100 @@ -97,11 +97,16 @@ } @Override - public boolean isArrayClass() { + public boolean isArray() { return false; } @Override + public boolean isPrimitive() { + return true; + } + + @Override public boolean isInitialized() { return true; } @@ -123,10 +128,7 @@ @Override public boolean isAssignableTo(ResolvedJavaType other) { - if (other instanceof HotSpotTypePrimitive) { - return other == this; - } - return false; + return other == this; } @Override @@ -165,11 +167,6 @@ } @Override - public Class< ? > toJava() { - return javaMirror; - } - - @Override public boolean isClass(Class c) { return c == javaMirror; } @@ -182,4 +179,14 @@ @Override public void initialize() { } + + @Override + public ResolvedJavaField findInstanceFieldWithOffset(long offset) { + return null; + } + + @Override + public Class mirror() { + return javaMirror; + } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotTypeUnresolved.java Wed Nov 28 09:01:39 2012 +0100 @@ -87,4 +87,9 @@ public ResolvedJavaType resolve(ResolvedJavaType accessingClass) { return (ResolvedJavaType) HotSpotGraalRuntime.getInstance().lookupType(getName(), (HotSpotResolvedJavaType) accessingClass, true); } + + @Override + public Class mirror() { + return ((HotSpotJavaType) resolve(null)).mirror(); + } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DimensionsNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -27,7 +27,6 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.snippets.*; @@ -35,7 +34,7 @@ * Intrinsic for allocating an on-stack array of integers to hold the dimensions * of a multianewarray instruction. */ -public final class DimensionsNode extends FixedWithNextNode implements LIRGenLowerable, MonitorEnter { +public final class DimensionsNode extends FixedWithNextNode implements LIRGenLowerable { private final int rank; diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/IntrinsifyArrayCopyPhase.java Wed Nov 28 09:01:39 2012 +0100 @@ -85,9 +85,9 @@ ResolvedJavaType srcType = src.objectStamp().type(); ResolvedJavaType destType = dest.objectStamp().type(); if (srcType != null - && srcType.isArrayClass() + && srcType.isArray() && destType != null - && destType.isArrayClass()) { + && destType.isArray()) { Kind componentKind = srcType.getComponentType().getKind(); if (srcType.getComponentType() == destType.getComponentType()) { if (componentKind == Kind.Int) { diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/NewObjectSnippets.java Wed Nov 28 09:01:39 2012 +0100 @@ -342,7 +342,7 @@ public void lower(InitializeObjectNode initializeNode, LoweringTool tool) { StructuredGraph graph = (StructuredGraph) initializeNode.graph(); HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) initializeNode.type(); - assert !type.isArrayClass(); + assert !type.isArray(); ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph); int size = type.instanceSize(); assert (size % wordSize()) == 0; diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java --- a/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.interpreter/src/com/oracle/graal/interpreter/BytecodeInterpreter.java Wed Nov 28 09:01:39 2012 +0100 @@ -89,7 +89,7 @@ @Override public Object invoke(InterpreterFrame caller, ResolvedJavaMethod method, Object[] arguments) throws Throwable { - setBackTrace(caller, (Throwable) arguments[0], createStackTraceElements(caller)); + setBackTrace(caller, (Throwable) arguments[0], createStackTraceElements(caller, runtimeInterface)); return null; } }); @@ -942,7 +942,7 @@ setStackTrace(frame, t, elements); setBackTrace(frame, t, null); } else { - setBackTrace(frame, t, createStackTraceElements(frame)); + setBackTrace(frame, t, createStackTraceElements(frame, runtimeInterface)); } } @@ -973,7 +973,7 @@ catchType = resolveType(frame, Bytecodes.INSTANCEOF, (char) handler.catchTypeCPI()); } - if (catchType == null || catchType.toJava().isInstance(t)) { + if (catchType == null || catchType.isInstance(Constant.forObject(t))) { // the first found exception handler is our exception handler return handler; } @@ -982,6 +982,10 @@ return null; } + private Class mirror(ResolvedJavaType type) { + return runtimeInterface.getMirror(type); + } + private InterpreterFrame allocateFrame(InterpreterFrame frame, BytecodeStream bs) { try { InterpreterFrame nextFrame = this.callFrame; @@ -1000,7 +1004,7 @@ traceOp(frame, "Method monitor enter"); } if (Modifier.isStatic(nextFrame.getMethod().getModifiers())) { - runtimeInterface.monitorEnter(nextFrame.getMethod().getDeclaringClass().toJava()); + runtimeInterface.monitorEnter(mirror(nextFrame.getMethod().getDeclaringClass())); } else { Object enterObject = nextFrame.getObject(frame.resolveLocalIndex(0)); assert enterObject != null; @@ -1022,7 +1026,7 @@ traceOp(frame, "Method monitor exit"); } if (Modifier.isStatic(frame.getMethod().getModifiers())) { - runtimeInterface.monitorExit(frame.getMethod().getDeclaringClass().toJava()); + runtimeInterface.monitorExit(mirror(frame.getMethod().getDeclaringClass())); } else { Object exitObject = frame.getObject(frame.resolveLocalIndex(0)); if (exitObject != null) { @@ -1181,7 +1185,7 @@ } private void checkCast(InterpreterFrame frame, char cpi) { - frame.pushObject(resolveType(frame, Bytecodes.CHECKCAST, cpi).toJava().cast(frame.popObject())); + frame.pushObject(mirror(resolveType(frame, Bytecodes.CHECKCAST, cpi)).cast(frame.popObject())); } private ResolvedJavaType resolveType(InterpreterFrame frame, int opcode, char cpi) { @@ -1236,7 +1240,7 @@ assert false : "unspecified case"; } } else if (constant instanceof JavaType) { - frame.pushObject(((JavaType) constant).resolve(method.getDeclaringClass()).toJava()); + frame.pushObject(mirror(((JavaType) constant).resolve(method.getDeclaringClass()))); } else { assert false : "unexpected case"; } @@ -1387,12 +1391,12 @@ for (int i = dimension - 1; i >= 0; i--) { dimensions[i] = frame.popInt(); } - return Array.newInstance(type.toJava(), dimensions); + return Array.newInstance(mirror(type), dimensions); } private ResolvedJavaType getLastDimensionType(ResolvedJavaType type) { ResolvedJavaType result = type; - while (result.isArrayClass()) { + while (result.isArray()) { result = result.getComponentType(); } return result; @@ -1400,7 +1404,7 @@ private Object allocateArray(InterpreterFrame frame, char cpi) { ResolvedJavaType type = resolveType(frame, Bytecodes.ANEWARRAY, cpi); - return Array.newInstance(type.toJava(), frame.popInt()); + return Array.newInstance(runtimeInterface.getMirror(type), frame.popInt()); } private Object allocateNativeArray(InterpreterFrame frame, byte cpi) { @@ -1613,12 +1617,12 @@ } } - private static StackTraceElement[] createStackTraceElements(InterpreterFrame frame) { + private static StackTraceElement[] createStackTraceElements(InterpreterFrame frame, RuntimeInterpreterInterface runtimeInterface) { InterpreterFrame tmp = frame; List elements = new ArrayList<>(); boolean first = false; // filter only first stack elements while (tmp != null) { - if (first || !filterStackElement(tmp)) { + if (first || !filterStackElement(tmp, runtimeInterface)) { first = true; elements.add(tmp.getMethod().asStackTraceElement(tmp.getBCI())); } @@ -1627,8 +1631,8 @@ return elements.toArray(new StackTraceElement[elements.size()]); } - private static boolean filterStackElement(InterpreterFrame frame) { - return Throwable.class.isAssignableFrom(frame.getMethod().getDeclaringClass().toJava()); + private static boolean filterStackElement(InterpreterFrame frame, RuntimeInterpreterInterface runtimeInterface) { + return Throwable.class.isAssignableFrom(runtimeInterface.getMirror(frame.getMethod().getDeclaringClass())); } private ResolvedJavaField findThrowableField(InterpreterFrame frame, String name) { diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Wed Nov 28 09:01:39 2012 +0100 @@ -762,7 +762,7 @@ while (stream.currentBCI() <= block.endBci) { switch (stream.currentBC()) { case RETURN: - if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) { + if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) { // return from Object.init implicitly registers a finalizer // for the receiver if needed, so keep it alive. loadOne(block, 0); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Nov 28 09:01:39 2012 +0100 @@ -145,7 +145,9 @@ private BciBlockMapping createBlockMap() { BciBlockMapping map = new BciBlockMapping(method); map.build(); - Debug.dump(map, MetaUtil.format("After block building %f %R %H.%n(%P)", method)); + if (Debug.isDumpEnabled()) { + Debug.dump(map, MetaUtil.format("After block building %f %R %H.%n(%P)", method)); + } return map; } @@ -1394,7 +1396,7 @@ } private void createReturn() { - if (method.isConstructor() && MetaUtil.isJavaLangObject(method.getDeclaringClass())) { + if (method.isConstructor() && method.getDeclaringClass().isClass(Object.class)) { callRegisterFinalizer(); } Kind returnKind = method.getSignature().getReturnKind().getStackKind(); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxingMethodPool.java Wed Nov 28 09:01:39 2012 +0100 @@ -148,6 +148,6 @@ if (boxing == null) { return false; } - return method.getDeclaringClass().toJava() == boxing.type && method.getName().equals(boxing.unboxMethod); + return method.getDeclaringClass().isClass(boxing.type) && method.getName().equals(boxing.unboxMethod); } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -26,12 +26,13 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * Load of a value from a location specified as an offset relative to an object. * No null check is performed before the load. */ -public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable { +public class UnsafeLoadNode extends FixedWithNextNode implements Lowerable, Virtualizable { @Input private ValueNode object; @Input private ValueNode offset; @@ -75,6 +76,26 @@ tool.getRuntime().lower(this, tool); } + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + ValueNode indexValue = tool.getReplacedValue(offset()); + if (indexValue.isConstant()) { + int fieldIndex = virtual.fieldIndexForOffset(indexValue.asConstant().asLong()); + if (fieldIndex != -1) { + ValueNode result = tool.getVirtualEntry(virtual, fieldIndex); + VirtualObjectNode virtualResult = tool.getVirtualState(result); + if (virtualResult != null) { + tool.replaceWithVirtual(virtualResult); + } else { + tool.replaceWithValue(result); + } + } + } + } + } + @NodeIntrinsic public static native T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -26,12 +26,13 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.virtual.*; /** * Store of a value at a location specified as an offset relative to an object. * No null check is performed before the store. */ -public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable { +public class UnsafeStoreNode extends FixedWithNextNode implements StateSplit, Lowerable, Virtualizable { @Input private ValueNode object; @Input private ValueNode offset; @@ -96,6 +97,21 @@ tool.getRuntime().lower(this, tool); } + @Override + public void virtualize(VirtualizerTool tool) { + VirtualObjectNode virtual = tool.getVirtualState(object()); + if (virtual != null) { + ValueNode indexValue = tool.getReplacedValue(offset()); + if (indexValue.isConstant()) { + int fieldIndex = virtual.fieldIndexForOffset(indexValue.asConstant().asLong()); + if (fieldIndex != -1) { + tool.setVirtualEntry(virtual, fieldIndex, value()); + tool.delete(); + } + } + } + } + // specialized on value type until boxing/unboxing is sorted out in intrinsification @NodeIntrinsic public static native void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -84,7 +84,7 @@ @Override public ObjectDesc[] getAllocations(long nextVirtualId, MetaAccessProvider metaAccess) { if (instanceClass != null) { - assert !instanceClass().isArrayClass(); + assert !instanceClass().isArray(); ResolvedJavaField[] fields = instanceClass().getInstanceFields(true); ValueNode[] state = new ValueNode[fields.length]; for (int i = 0; i < state.length; i++) { diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -54,7 +54,7 @@ super(StampFactory.exactNonNull(type)); this.type = type; this.dimensions = new NodeInputList<>(this, dimensions); - assert dimensions.length > 0 && type.isArrayClass(); + assert dimensions.length > 0 && type.isArray(); } @Override diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/BoxedVirtualObjectNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -58,4 +58,10 @@ assert index == 0; return "value"; } + + @Override + public int fieldIndexForOffset(long constantOffset) { + // (lstadler) unsafe access to a newly created boxing object should only ever touch the value field + return 0; + } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualArrayNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.nodes.virtual; +import sun.misc.*; + import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; @@ -70,4 +72,59 @@ public String fieldName(int index) { return "[" + index + "]"; } + + @Override + public int fieldIndexForOffset(long constantOffset) { + int baseOffset; + int indexScale; + switch (componentType.getKind()) { + case Boolean: + baseOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET; + indexScale = Unsafe.ARRAY_BOOLEAN_INDEX_SCALE; + break; + case Byte: + baseOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET; + indexScale = Unsafe.ARRAY_BYTE_INDEX_SCALE; + break; + case Short: + baseOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET; + indexScale = Unsafe.ARRAY_SHORT_INDEX_SCALE; + break; + case Char: + baseOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET; + indexScale = Unsafe.ARRAY_CHAR_INDEX_SCALE; + break; + case Int: + baseOffset = Unsafe.ARRAY_INT_BASE_OFFSET; + indexScale = Unsafe.ARRAY_INT_INDEX_SCALE; + break; + case Long: + baseOffset = Unsafe.ARRAY_LONG_BASE_OFFSET; + indexScale = Unsafe.ARRAY_LONG_INDEX_SCALE; + break; + case Float: + baseOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET; + indexScale = Unsafe.ARRAY_FLOAT_INDEX_SCALE; + break; + case Double: + baseOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET; + indexScale = Unsafe.ARRAY_DOUBLE_INDEX_SCALE; + break; + case Object: + baseOffset = Unsafe.ARRAY_OBJECT_BASE_OFFSET; + indexScale = Unsafe.ARRAY_OBJECT_INDEX_SCALE; + break; + default: + return -1; + } + long index = constantOffset - baseOffset; + if (index % indexScale != 0) { + return -1; + } + long elementIndex = index / indexScale; + if (elementIndex < 0 || elementIndex >= length) { + return -1; + } + return (int) elementIndex; + } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualInstanceNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -75,4 +75,9 @@ Integer index = fieldMap.get(field); return index == null ? -1 : index; } + + @Override + public int fieldIndexForOffset(long constantOffset) { + return fieldIndex(type.findInstanceFieldWithOffset(constantOffset)); + } } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/VirtualObjectNode.java Wed Nov 28 09:01:39 2012 +0100 @@ -57,4 +57,6 @@ public void materializeAt(@SuppressWarnings("unused") FixedNode fixed) { // nothing to do in here - this method allows subclasses to respond to materialization } + + public abstract int fieldIndexForOffset(long constantOffset); } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/BoxingEliminationPhase.java Wed Nov 28 09:01:39 2012 +0100 @@ -71,7 +71,7 @@ ObjectStamp stamp = phiNode.objectStamp(); if (stamp.nonNull() && stamp.isExactType()) { ResolvedJavaType type = stamp.type(); - if (type != null && type.toJava() == kind.toBoxedJavaClass()) { + if (type != null && type.isClass(kind.toBoxedJavaClass())) { StructuredGraph graph = (StructuredGraph) phiNode.graph(); result = graph.add(new PhiNode(kind, phiNode.merge())); phiReplacements.put(phiNode, result); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Nov 28 09:01:39 2012 +0100 @@ -171,6 +171,7 @@ public static boolean GenAssertionCode = ____; public static boolean AlignCallsForPatching = true; public static boolean ResolveClassBeforeStaticInvoke = true; + public static boolean CanOmitFrame = true; // Translating tableswitch instructions public static int MinimumJumpTableSize = 5; diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/BinaryGraphPrinter.java Wed Nov 28 09:01:39 2012 +0100 @@ -214,17 +214,13 @@ writeByte(POOL_NULL); return; } - if (object instanceof ResolvedJavaType) { - writePoolObject(((ResolvedJavaType) object).toJava()); - return; - } Integer id = constantPool.get(object); if (id == null) { addPoolEntry(object); } else { if (object instanceof Enum) { writeByte(POOL_ENUM); - } else if (object instanceof Class) { + } else if (object instanceof Class || object instanceof JavaType) { writeByte(POOL_CLASS); } else if (object instanceof NodeClass) { writeByte(POOL_NODE_CLASS); @@ -270,6 +266,11 @@ writeByte(POOL_ENUM); writePoolObject(object.getClass()); writeInt(((Enum) object).ordinal()); + } else if (object instanceof JavaType) { + JavaType type = (JavaType) object; + writeByte(POOL_CLASS); + writeString(MetaUtil.toJavaName(type)); + writeByte(KLASS); } else if (object instanceof NodeClass) { NodeClass nodeClass = (NodeClass) object; writeByte(POOL_NODE_CLASS); diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java --- a/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.snippets.test/src/com/oracle/graal/snippets/NewMultiArrayTest.java Wed Nov 28 09:01:39 2012 +0100 @@ -99,9 +99,8 @@ @Override protected Object referenceInvoke(Method method, Object receiver, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (bottomType != null) { - Class< ? > componentType = bottomType.toJava(); try { - return Array.newInstance(componentType, dimensions); + return Array.newInstance(bottomClass, dimensions); } catch (Exception e) { throw new InvocationTargetException(e); } @@ -111,11 +110,13 @@ ResolvedJavaType arrayType; ResolvedJavaType bottomType; + Class bottomClass; int[] dimensions; @Test public void test1() { for (Class clazz : new Class[] {byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) { + bottomClass = clazz; bottomType = runtime.lookupJavaType(clazz); arrayType = bottomType; for (int rank : new int[] {1, 2, 10, 50, 100, 200, 254, 255}) { diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippet.java Wed Nov 28 09:01:39 2012 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.snippets; +import static com.oracle.graal.api.meta.MetaUtil.*; + import java.lang.annotation.*; import java.lang.reflect.*; @@ -80,7 +82,7 @@ if (method.getAnnotation(NodeIntrinsic.class) != null) { return false; } - if (Throwable.class.isAssignableFrom(method.getDeclaringClass().toJava())) { + if (Throwable.class.isAssignableFrom(getMirrorOrFail(method.getDeclaringClass(), null))) { if (method.getName().equals("")) { return false; } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetIntrinsificationPhase.java Wed Nov 28 09:01:39 2012 +0100 @@ -22,6 +22,8 @@ */ package com.oracle.graal.snippets; +import static com.oracle.graal.api.meta.MetaUtil.*; + import java.lang.reflect.*; import java.util.*; @@ -79,6 +81,15 @@ } } + public static Class[] signatureToTypes(Signature signature, ResolvedJavaType accessingClass) { + int count = signature.getParameterCount(false); + Class[] result = new Class< ? >[count]; + for (int i = 0; i < result.length; ++i) { + result[i] = getMirrorOrFail(signature.getParameterType(i, accessingClass).resolve(accessingClass), null); + } + return result; + } + private void tryIntrinsify(Invoke invoke) { ResolvedJavaMethod target = invoke.methodCallTarget().targetMethod(); NodeIntrinsic intrinsic = target.getAnnotation(Node.NodeIntrinsic.class); @@ -87,7 +98,7 @@ assert target.getAnnotation(Fold.class) == null; assert Modifier.isNative(target.getModifiers()) : "node intrinsic " + target + " should be native"; - Class< ? >[] parameterTypes = MetaUtil.signatureToTypes(target.getSignature(), declaringClass); + Class< ? >[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass); ResolvedJavaType returnType = target.getSignature().getReturnType(declaringClass).resolve(declaringClass); // Prepare the arguments for the reflective constructor call on the node class. @@ -104,7 +115,7 @@ // Clean up checkcast instructions inserted by javac if the return type is generic. cleanUpReturnCheckCast(newInstance); } else if (target.getAnnotation(Fold.class) != null) { - Class< ? >[] parameterTypes = MetaUtil.signatureToTypes(target.getSignature(), declaringClass); + Class< ? >[] parameterTypes = signatureToTypes(target.getSignature(), declaringClass); // Prepare the arguments for the reflective method call Object[] arguments = prepareArguments(invoke, parameterTypes, target, true); @@ -115,7 +126,7 @@ } // Call the method - Constant constant = callMethod(target.getSignature().getReturnKind(), declaringClass.toJava(), target.getName(), parameterTypes, receiver, arguments); + Constant constant = callMethod(target.getSignature().getReturnKind(), getMirrorOrFail(declaringClass, null), target.getName(), parameterTypes, receiver, arguments); if (constant != null) { // Replace the invoke with the result of the call @@ -180,7 +191,7 @@ private static Class< ? > getNodeClass(ResolvedJavaMethod target, NodeIntrinsic intrinsic) { Class< ? > result = intrinsic.value(); if (result == NodeIntrinsic.class) { - result = target.getDeclaringClass().toJava(); + return getMirrorOrFail(target.getDeclaringClass(), null); } assert Node.class.isAssignableFrom(result); return result; diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/SnippetTemplate.java Wed Nov 28 09:01:39 2012 +0100 @@ -404,7 +404,7 @@ private static boolean checkVarargs(final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) { Object arg = varargs.getArray(); ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass()); - assert type.isArrayClass() : "varargs parameter must be an array type"; + assert type.isArray() : "varargs parameter must be an array type"; assert type.isInstance(Constant.forObject(arg)) : "value for " + name + " is not a " + MetaUtil.toJavaName(type) + " instance: " + arg; return true; } diff -r 15055bdafbfc -r 3e61ffb9ce29 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Wed Nov 28 09:01:15 2012 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/BlockState.java Wed Nov 28 09:01:39 2012 +0100 @@ -85,7 +85,7 @@ private void materializeChangedBefore(FixedNode fixed, VirtualObjectNode virtual, HashSet deferred, GraphEffectList deferredStores, GraphEffectList materializeEffects) { trace("materializing %s at %s", virtual, fixed); ObjectState obj = getObjectState(virtual); - if (obj.getLockCount() > 0 && obj.virtual.type().isArrayClass()) { + if (obj.getLockCount() > 0 && obj.virtual.type().isArray()) { throw new BailoutException("array materialized with lock"); } diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/code/debugInfo.cpp --- a/src/share/vm/code/debugInfo.cpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/code/debugInfo.cpp Wed Nov 28 09:01:39 2012 +0100 @@ -77,7 +77,11 @@ enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1, CONSTANT_OOP_CODE = 2, CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4, - OBJECT_CODE = 5, OBJECT_ID_CODE = 6 }; + OBJECT_CODE = 5, OBJECT_ID_CODE = 6, +#ifdef GRAAL + DEFERRED_READ_CODE = 7, DEFERRED_WRITE_CODE = 8 +#endif // GRAAL +}; ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) { ScopeValue* result = NULL; @@ -89,6 +93,10 @@ case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream); break; case OBJECT_CODE: result = stream->read_object_value(); break; case OBJECT_ID_CODE: result = stream->get_cached_object(); break; +#ifdef GRAAL + case DEFERRED_READ_CODE: result = new DeferredReadValue(stream); break; + case DEFERRED_WRITE_CODE: result = new DeferredWriteValue(stream); break; +#endif // GRAAL default: ShouldNotReachHere(); } return result; @@ -109,6 +117,63 @@ location().print_on(st); } +#ifdef GRAAL + +// DeferredLocationValue + +DeferredLocationValue::DeferredLocationValue(DebugInfoReadStream* stream) { + _base = read_from(stream); + _index = read_from(stream); + _scale = stream->read_int(); + _disp = stream->read_long(); +} + +void DeferredLocationValue::write_on(DebugInfoWriteStream* stream) { + _base->write_on(stream); + _index->write_on(stream); + stream->write_int(_scale); + stream->write_long(_disp); +} + +void DeferredLocationValue::print_on(outputStream* st) const { + _base->print_on(st); + _index->print_on(st); + st->print("%i %i", _scale, _disp); +} + +// DeferredReadValue + +DeferredReadValue::DeferredReadValue(DebugInfoReadStream* stream) +: DeferredLocationValue(stream) { +} + +void DeferredReadValue::write_on(DebugInfoWriteStream* st) { + DeferredLocationValue::write_on(st); +} + +void DeferredReadValue::print_on(outputStream* st) const { + DeferredLocationValue::print_on(st); +} + +// DeferredWriteValue + +DeferredWriteValue::DeferredWriteValue(DebugInfoReadStream* stream) +: DeferredLocationValue(stream) { + _value = read_from(stream); +} + +void DeferredWriteValue::write_on(DebugInfoWriteStream* st) { + DeferredLocationValue::write_on(st); + _value->write_on(st); +} + +void DeferredWriteValue::print_on(outputStream* st) const { + DeferredLocationValue::print_on(st); + _value->print_on(st); +} + +#endif // GRAAL + // ObjectValue void ObjectValue::read_object(DebugInfoReadStream* stream) { diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/code/debugInfo.hpp --- a/src/share/vm/code/debugInfo.hpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/code/debugInfo.hpp Wed Nov 28 09:01:39 2012 +0100 @@ -61,6 +61,11 @@ // Serialization of debugging information virtual void write_on(DebugInfoWriteStream* stream) = 0; static ScopeValue* read_from(DebugInfoReadStream* stream); + +#ifdef GRAAL + // Printing + virtual void print_on(outputStream* st) const = 0; +#endif // GRAAL }; @@ -83,6 +88,64 @@ void print_on(outputStream* st) const; }; +#ifdef GRAAL + +class DeferredLocationValue: public ScopeValue { +private: + ScopeValue* _base; + ScopeValue* _index; + jint _scale; + jlong _disp; +public: + DeferredLocationValue(ScopeValue* base, ScopeValue* index, jint scale, jlong disp) + : _base(base), _index(index), _scale(scale), _disp(disp) { } + + ScopeValue* base() { return _base; } + ScopeValue* index() { return _index; } + jint scale() { return _scale; } + jlong disp() { return _disp; } + + // Serialization of debugging information + DeferredLocationValue(DebugInfoReadStream* stream); + void write_on(DebugInfoWriteStream* stream); + + // Printing + void print_on(outputStream* st) const; +}; + + +class DeferredReadValue: public DeferredLocationValue { +public: + DeferredReadValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp) + : DeferredLocationValue(base, index, scale, disp) { } + + // Serialization of debugging information + DeferredReadValue(DebugInfoReadStream* stream); + void write_on(DebugInfoWriteStream* stream); + + // Printing + void print_on(outputStream* st) const; +}; + +class DeferredWriteValue: public DeferredLocationValue { +private: + ScopeValue* _value; +public: + DeferredWriteValue(ScopeValue* base, ScopeValue* index, jint scale, jint disp, ScopeValue* value) + : DeferredLocationValue(base, index, scale, disp), _value(value) { } + + ScopeValue* value() { return _value; } + + // Serialization of debugging information + DeferredWriteValue(DebugInfoReadStream* stream); + void write_on(DebugInfoWriteStream* stream); + + // Printing + void print_on(outputStream* st) const; +}; + +#endif // GRAAL + // An ObjectValue describes an object eliminated by escape analysis. diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/code/debugInfoRec.cpp --- a/src/share/vm/code/debugInfoRec.cpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/code/debugInfoRec.cpp Wed Nov 28 09:01:39 2012 +0100 @@ -213,6 +213,29 @@ return result; } +#ifdef GRAAL + +int DebugInformationRecorder::serialize_deferred_writes(GrowableArray* deferred_writes) { + if (deferred_writes == NULL || deferred_writes->is_empty()) return DebugInformationRecorder::serialized_null; + assert(_recording_state == rs_safepoint, "must be recording a safepoint"); + int result = stream()->position(); + assert(result != serialized_null, "sanity"); + stream()->write_int(deferred_writes->length()); + for (int index = 0; index < deferred_writes->length(); index++) { + deferred_writes->at(index)->write_on(stream()); + } + + // (See comment below on DebugInformationRecorder::describe_scope.) + int shared_result = find_sharable_decode_offset(result); + if (shared_result != serialized_null) { + stream()->set_position(result); + result = shared_result; + } + + return result; +} + +#endif // GRAAL #ifndef PRODUCT // These variables are put into one block to reduce relocations @@ -289,7 +312,11 @@ bool return_oop, DebugToken* locals, DebugToken* expressions, - DebugToken* monitors) { + DebugToken* monitors +#ifdef GRAAL + , DebugToken* deferred_writes +#endif // GRAAL + ) { assert(_recording_state != rs_null, "nesting of recording calls"); PcDesc* last_pd = last_pc(); assert(last_pd->pc_offset() == pc_offset, "must be last pc"); @@ -328,6 +355,9 @@ stream()->write_int((intptr_t) locals); stream()->write_int((intptr_t) expressions); stream()->write_int((intptr_t) monitors); +#ifdef GRAAL + stream()->write_int((intptr_t) deferred_writes); +#endif // GRAAL // Here's a tricky bit. We just wrote some bytes. // Wouldn't it be nice to find that we had already @@ -409,6 +439,14 @@ return (DebugToken*) (intptr_t) serialize_monitor_values(monitors); } +#ifdef GRAAL + +DebugToken* DebugInformationRecorder::create_deferred_writes(GrowableArray* deferred_writes) { + assert(!recorders_frozen(), "not frozen yet"); + return (DebugToken*) (intptr_t) serialize_deferred_writes(deferred_writes); +} + +#endif // GRAAL int DebugInformationRecorder::data_size() { debug_only(mark_recorders_frozen()); // mark it "frozen" for asserts diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/code/debugInfoRec.hpp --- a/src/share/vm/code/debugInfoRec.hpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/code/debugInfoRec.hpp Wed Nov 28 09:01:39 2012 +0100 @@ -107,7 +107,11 @@ bool return_oop = false, DebugToken* locals = NULL, DebugToken* expressions = NULL, - DebugToken* monitors = NULL); + DebugToken* monitors = NULL +#ifdef GRAAL + , DebugToken* deferred_writes = NULL +#endif // GRAAL + ); void dump_object_pool(GrowableArray* objects); @@ -120,6 +124,9 @@ // helper fuctions for describe_scope to enable sharing DebugToken* create_scope_values(GrowableArray* values); DebugToken* create_monitor_values(GrowableArray* monitors); +#ifdef GRAAL + DebugToken* create_deferred_writes(GrowableArray* deferred_writes); +#endif // GRAAL // returns the size of the generated scopeDescs. int data_size(); @@ -194,6 +201,9 @@ int serialize_monitor_values(GrowableArray* monitors); int serialize_scope_values(GrowableArray* values); +#ifdef GRAAL + int serialize_deferred_writes(GrowableArray* deferred_writes); +#endif // GRAAL int find_sharable_decode_offset(int stream_offset); #ifndef PRODUCT diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/code/scopeDesc.cpp --- a/src/share/vm/code/scopeDesc.cpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/code/scopeDesc.cpp Wed Nov 28 09:01:39 2012 +0100 @@ -73,6 +73,9 @@ _locals_decode_offset = DebugInformationRecorder::serialized_null; _expressions_decode_offset = DebugInformationRecorder::serialized_null; _monitors_decode_offset = DebugInformationRecorder::serialized_null; +#ifdef GRAAL + _deferred_writes_decode_offset = DebugInformationRecorder::serialized_null; +#endif // GRAAL } else { // decode header DebugInfoReadStream* stream = stream_at(decode_offset()); @@ -85,6 +88,9 @@ _locals_decode_offset = stream->read_int(); _expressions_decode_offset = stream->read_int(); _monitors_decode_offset = stream->read_int(); +#ifdef GRAAL + _deferred_writes_decode_offset = stream->read_int(); +#endif // GRAAL } } @@ -126,6 +132,25 @@ return result; } +#ifdef GRAAL + +GrowableArray* ScopeDesc::decode_deferred_writes(int decode_offset) { + if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; + DebugInfoReadStream* stream = stream_at(decode_offset); + int length = stream->read_int(); + GrowableArray* result = new GrowableArray (length); + for (int index = 0; index < length; index++) { + result->push(new DeferredWriteValue(stream)); + } + return result; +} + +GrowableArray* ScopeDesc::deferred_writes() { + return decode_deferred_writes(_deferred_writes_decode_offset); +} + +#endif // GRAAL + DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const { return new DebugInfoReadStream(_code, decode_offset, _objects); } @@ -225,8 +250,8 @@ } } -#ifdef COMPILER2 - if (DoEscapeAnalysis && is_top() && _objects != NULL) { +#if defined(COMPILER2) || defined(GRAAL) + if (NOT_GRAAL(DoEscapeAnalysis &&) is_top() && _objects != NULL) { tty->print_cr("Objects"); for (int i = 0; i < _objects->length(); i++) { ObjectValue* sv = (ObjectValue*) _objects->at(i); @@ -235,7 +260,20 @@ tty->cr(); } } -#endif // COMPILER2 +#endif // COMPILER2 || GRAAL +#ifdef GRAAL + // deferred writes + { GrowableArray* l = ((ScopeDesc*) this)->deferred_writes(); + if (l != NULL) { + st->print_cr(" Deferred writes"); + for (int index = 0; index < l->length(); index++) { + st->print(" - @%d: ", index); + l->at(index)->print_on(st); + st->cr(); + } + } + } +#endif } #endif diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/code/scopeDesc.hpp --- a/src/share/vm/code/scopeDesc.hpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/code/scopeDesc.hpp Wed Nov 28 09:01:39 2012 +0100 @@ -78,6 +78,9 @@ GrowableArray* expressions(); GrowableArray* monitors(); GrowableArray* objects(); +#ifdef GRAAL + GrowableArray* deferred_writes(); +#endif // GRAAL // Stack walking, returns NULL if this is the outer most scope. ScopeDesc* sender() const; @@ -107,6 +110,9 @@ int _locals_decode_offset; int _expressions_decode_offset; int _monitors_decode_offset; +#ifdef GRAAL + int _deferred_writes_decode_offset; +#endif // GRAAL // Object pool GrowableArray* _objects; @@ -119,6 +125,9 @@ GrowableArray* decode_scope_values(int decode_offset); GrowableArray* decode_monitor_values(int decode_offset); GrowableArray* decode_object_values(int decode_offset); +#ifdef GRAAL + GrowableArray* decode_deferred_writes(int decode_offset); +#endif // GRAAL DebugInfoReadStream* stream_at(int decode_offset) const; diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Wed Nov 28 09:01:39 2012 +0100 @@ -530,9 +530,13 @@ DebugToken* expressions_token = _debug_recorder->create_scope_values(expressions); DebugToken* monitors_token = _debug_recorder->create_monitor_values(monitors); + GrowableArray* deferred_writes = new GrowableArray (); +// deferred_writes->append(new DeferredWriteValue(new LocationValue(Location::new_reg_loc(Location::lng, rax->as_VMReg())), new ConstantIntValue(0), 0, 100, new ConstantIntValue(123))); + DebugToken* deferred_writes_token = _debug_recorder->create_deferred_writes(deferred_writes); + bool throw_exception = BytecodeFrame::rethrowException(frame) == JNI_TRUE; - _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token); + _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, locals_token, expressions_token, monitors_token, deferred_writes_token); } void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Wed Nov 28 09:01:39 2012 +0100 @@ -195,6 +195,17 @@ return (jlong) (address) method(); } +C2V_VMENTRY(jlong, getMetaspaceConstructor, (JNIEnv *, jobject, jobject reflection_ctor_handle, jobject resultHolder)) + oop reflection_ctor = JNIHandles::resolve(reflection_ctor_handle); + oop reflection_holder = java_lang_reflect_Constructor::clazz(reflection_ctor); + int slot = java_lang_reflect_Constructor::slot(reflection_ctor); + Klass* holder = java_lang_Class::as_Klass(reflection_holder); + methodHandle method = InstanceKlass::cast(holder)->method_with_idnum(slot); + Handle type = GraalCompiler::createHotSpotResolvedJavaType(method, CHECK_0); + objArrayOop(JNIHandles::resolve(resultHolder))->obj_at_put(0, type()); + return (jlong) (address) method(); +} + C2V_VMENTRY(jobject, getJavaField, (JNIEnv *, jobject, jobject reflection_field_handle)) oop reflection_field = JNIHandles::resolve(reflection_field_handle); oop reflection_holder = java_lang_reflect_Field::clazz(reflection_field); @@ -892,6 +903,7 @@ #define RUNTIME_CALL "Lcom/oracle/graal/api/code/RuntimeCall;" #define EXCEPTION_HANDLERS "[Lcom/oracle/graal/api/meta/ExceptionHandler;" #define REFLECT_METHOD "Ljava/lang/reflect/Method;" +#define REFLECT_CONSTRUCTOR "Ljava/lang/reflect/Constructor;" #define REFLECT_FIELD "Ljava/lang/reflect/Field;" #define STRING "Ljava/lang/String;" #define OBJECT "Ljava/lang/Object;" @@ -937,6 +949,7 @@ {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, {CC"getResolvedType", CC"("CLASS")"RESOLVED_TYPE, FN_PTR(getResolvedType)}, {CC"getMetaspaceMethod", CC"("REFLECT_METHOD"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getMetaspaceMethod)}, + {CC"getMetaspaceConstructor", CC"("REFLECT_CONSTRUCTOR"["HS_RESOLVED_TYPE")"METASPACE_METHOD, FN_PTR(getMetaspaceConstructor)}, {CC"getJavaField", CC"("REFLECT_FIELD")"HS_RESOLVED_FIELD, FN_PTR(getJavaField)}, {CC"initializeConfiguration", CC"("HS_CONFIG")V", FN_PTR(initializeConfiguration)}, {CC"installCode", CC"("HS_COMP_RESULT HS_INSTALLED_CODE HS_CODE_INFO")"HS_INSTALLED_CODE, FN_PTR(installCode)}, diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Wed Nov 28 09:01:39 2012 +0100 @@ -234,17 +234,6 @@ return (oop) result.get_jobject(); } -oop VMToCompiler::createSignature(Handle name, TRAPS) { - assert(!name.is_null(), "just checking"); - JavaValue result(T_OBJECT); - JavaCallArguments args; - args.push_oop(instance()); - args.push_oop(name); - JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::createSignature_name(), vmSymbols::createSignature_signature(), &args, THREAD); - check_pending_exception("Error while calling createSignature"); - return (oop) result.get_jobject(); -} - oop VMToCompiler::createConstant(Handle kind, jlong value, TRAPS) { JavaValue result(T_OBJECT); JavaCallArguments args; diff -r 15055bdafbfc -r 3e61ffb9ce29 src/share/vm/graal/graalVMToCompiler.hpp --- a/src/share/vm/graal/graalVMToCompiler.hpp Wed Nov 28 09:01:15 2012 +0100 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Wed Nov 28 09:01:39 2012 +0100 @@ -86,9 +86,6 @@ // public abstract JavaType createPrimitiveJavaType(int basicType); static oop createPrimitiveJavaType(int basicType, TRAPS); - // public abstract Signature createSignature(String signature); - static oop createSignature(Handle name, TRAPS); - // public abstract Constant createConstant(Kind kind, long value); static oop createConstant(Handle kind, jlong value, TRAPS);