changeset 5629:26a060cc58ca

Initial implementation of closed world analysis by iteratively expanding the universe starting at method entry points.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 16 Jun 2012 00:06:48 +0200
parents 65bf69eb147c
children b60a368c8104
files graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/HelloWorldTest.java graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/test/helloworld/HelloWorldTestProgram.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BigBang.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BootImageGenerator.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/UniverseExpansionOp.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/ArrayTypeElement.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/Element.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/FieldElement.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/InvokeElement.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/MethodElement.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/ParameterElement.java graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/PhiElement.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java mx/projects
diffstat 21 files changed, 916 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Sat Jun 16 00:06:48 2012 +0200
@@ -47,6 +47,13 @@
     Constant constantValue(Constant receiver);
 
     /**
+     * Gets the current value of the field if available.
+     * @param receiver object from which this field's value is to be read. This value is ignored if this field is static.
+     * @return the value of this field or {@code null} if the value is not available (e.g., because the field holder is not yet initialized).
+     */
+    Constant getValue(Constant receiver);
+
+    /**
      * Gets the holder of this field as a compiler-runtime interface type.
      * @return the holder of this field
      */
--- a/graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/HelloWorldTest.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/HelloWorldTest.java	Sat Jun 16 00:06:48 2012 +0200
@@ -29,6 +29,6 @@
     public static void main(String[] args) {
         BootImageGenerator generator = new BootImageGenerator();
         generator.addEntryMethod(HelloWorldTestProgram.class, "main", String[].class);
-        generator.logState();
+        generator.printState();
     }
 }
--- a/graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/test/helloworld/HelloWorldTestProgram.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.boot.test/src/com/oracle/graal/boot/test/helloworld/HelloWorldTestProgram.java	Sat Jun 16 00:06:48 2012 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.boot.test.helloworld;
 
-
 public class HelloWorldTestProgram {
     public static void main(String[] args) {
         System.out.println("Hello world!");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BigBang.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,284 @@
+/*
+ * 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.boot;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.java.*;
+
+public class BigBang {
+
+    private static final int THREADS = 1;
+
+    private MetaAccessProvider metaAccessProvider;
+    private int postedOperationCount;
+
+    // Mappings from Graal IR and Graal meta-data to element instances.
+    private Map<Node, Element> sinkMap = new IdentityHashMap<>();
+    private Map<ResolvedJavaField, FieldElement> fieldMap = new IdentityHashMap<>();
+    private Map<ResolvedJavaMethod, MethodElement> methodMap = new IdentityHashMap<>();
+    private Map<ResolvedJavaType, ArrayTypeElement> arrayTypeMap = new IdentityHashMap<>();
+
+    // Processing queue.
+    private ThreadPoolExecutor executor = new ThreadPoolExecutor(THREADS, THREADS, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory());
+
+    public BigBang(MetaAccessProvider metaAccessProvider) {
+        this.metaAccessProvider = metaAccessProvider;
+    }
+
+    public synchronized FieldElement getProcessedField(ResolvedJavaField field) {
+        assert field != null;
+        if (!fieldMap.containsKey(field)) {
+            fieldMap.put(field, new FieldElement(field));
+        }
+        return fieldMap.get(field);
+    }
+
+    public synchronized MethodElement getProcessedMethod(ResolvedJavaMethod method) {
+        assert method != null;
+        if (!methodMap.containsKey(method)) {
+            methodMap.put(method, new MethodElement(method));
+        }
+        return methodMap.get(method);
+    }
+
+    public synchronized ArrayTypeElement getProcessedArrayType(ResolvedJavaType type) {
+        assert type != null;
+        if (!arrayTypeMap.containsKey(type)) {
+            arrayTypeMap.put(type, new ArrayTypeElement(type));
+        }
+        return arrayTypeMap.get(type);
+    }
+
+    public synchronized Element getSinkElement(Node node, Node sourceNode) {
+        if (!sinkMap.containsKey(node)) {
+            Element resultElement = Element.BLACK_HOLE;
+            if (node instanceof PhiNode) {
+                PhiNode phiNode = (PhiNode) node;
+                resultElement = new PhiElement(phiNode);
+            } else if (node instanceof StoreFieldNode) {
+                StoreFieldNode storeFieldNode = (StoreFieldNode) node;
+                resultElement = getProcessedField(storeFieldNode.field());
+            } else if (node instanceof StoreIndexedNode) {
+                StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
+                if (storeIndexedNode.elementKind() == Kind.Object) {
+                    resultElement = getProcessedArrayType(storeIndexedNode.array().stamp().declaredType());
+                }
+            } else if (node instanceof ReturnNode) {
+                ReturnNode returnNode = (ReturnNode) node;
+                ResolvedJavaMethod method = ((StructuredGraph) returnNode.graph()).method();
+                resultElement = getProcessedMethod(method);
+            } else {
+                if (node instanceof FrameState || node instanceof MonitorEnterNode || node instanceof MonitorExitNode || node instanceof LoadFieldNode || node instanceof IsNullNode) {
+                    // OK.
+                } else {
+                    System.out.println("Unknown sink - black hole? " + node);
+                }
+            }
+
+            sinkMap.put(node, resultElement);
+        }
+
+        if (node instanceof StoreIndexedNode) {
+            StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
+            if (storeIndexedNode.value() != sourceNode) {
+                return Element.BLACK_HOLE;
+            }
+        }
+
+        if (node instanceof StoreFieldNode) {
+            StoreFieldNode storeFieldNode = (StoreFieldNode) node;
+            if (storeFieldNode.value() != sourceNode) {
+                return Element.BLACK_HOLE;
+            }
+        }
+        return sinkMap.get(node);
+    }
+
+    public synchronized void registerSourceCallTargetNode(MethodCallTargetNode methodCallTargetNode) {
+        sinkMap.put(methodCallTargetNode, new InvokeElement(methodCallTargetNode));
+    }
+
+    public synchronized void registerSourceNode(Node node) {
+        Element resultElement = null;
+        if (node instanceof LoadFieldNode) {
+            LoadFieldNode loadFieldNode = (LoadFieldNode) node;
+            resultElement = getProcessedField(loadFieldNode.field());
+        } else if (node instanceof LoadIndexedNode) {
+            LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
+            resultElement = getProcessedArrayType(loadIndexedNode.array().stamp().declaredType());
+        } else if (node instanceof LocalNode) {
+            LocalNode localNode = (LocalNode) node;
+            if (localNode.kind() == Kind.Object) {
+                ResolvedJavaMethod method = ((StructuredGraph) localNode.graph()).method();
+                resultElement = getProcessedMethod(method).getParameter(localNode.index());
+                System.out.println("resultElement = " + resultElement + " index= " + localNode.index() + ", node=" + node);
+            }
+        }
+
+        if (resultElement != null) {
+            resultElement.postAddUsage(this, node);
+        }
+    }
+
+    public synchronized void postOperation(UniverseExpansionOp operation) {
+        System.out.println("posting operation " + operation);
+        executor.execute(operation);
+        postedOperationCount++;
+    }
+
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccessProvider;
+    }
+
+    public void finish() {
+        while (true) {
+            try {
+                Thread.sleep(10);
+                boolean terminated;
+                int oldPostedOperationCount;
+                synchronized (this) {
+                    terminated = (executor.getCompletedTaskCount() == postedOperationCount);
+                    oldPostedOperationCount = postedOperationCount;
+                }
+
+                if (terminated) {
+                    checkObjectGraph();
+                    synchronized (this) {
+                        if (postedOperationCount == oldPostedOperationCount) {
+                            System.out.printf("Big bang simulation completed in %d operations.\n", postedOperationCount);
+                            executor.shutdown();
+                            break;
+                        }
+                    }
+                }
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private void checkObjectGraph() {
+        List<FieldElement> originalRoots = new ArrayList<>();
+        synchronized (this) {
+            for (FieldElement field : fieldMap.values()) {
+                if (field.isStatic()) {
+                    originalRoots.add(field);
+                }
+            }
+        }
+
+        Map<Object, Boolean> scannedObjects = new IdentityHashMap<>();
+        for (FieldElement field : originalRoots) {
+            assert field.isStatic();
+            if (field.getUsageCount() > 0 && field.getJavaField().kind() == Kind.Object) {
+                Object value = field.getJavaField().getValue(null).asObject();
+                System.out.printf("Root field %s: %s\n", field, value);
+                scanField(scannedObjects, field, value);
+            }
+        }
+    }
+
+    private void scanField(Map<Object, Boolean> scannedObjects, FieldElement field, Object value) {
+        if (value != null && field.getUsageCount() > 0) {
+            field.registerNewValue(this, value);
+            scan(scannedObjects, value);
+        }
+    }
+
+    private void scan(Map<Object, Boolean> scannedObjects, Object value) {
+        assert value != null;
+        if (scannedObjects.containsKey(value)) {
+            return;
+        }
+
+        scannedObjects.put(value, Boolean.TRUE);
+        ResolvedJavaType type = getMetaAccess().getResolvedJavaType(value.getClass());
+        scan(scannedObjects, value, type);
+    }
+
+    private void scan(Map<Object, Boolean> scannedObjects, Object value, ResolvedJavaType type) {
+        if (type.superType() != null) {
+            scan(scannedObjects, value, type.superType());
+        }
+
+        ResolvedJavaField[] declaredFields = type.declaredFields();
+        for (ResolvedJavaField field : declaredFields) {
+            if (field.kind() == Kind.Object) {
+                FieldElement fieldElement = getProcessedField(field);
+                Object fieldValue = field.getValue(Constant.forObject(value)).asObject();
+                scanField(scannedObjects, fieldElement, fieldValue);
+            }
+        }
+
+    }
+
+    public synchronized void printState() {
+
+        int nativeMethodCount = 0;
+        for (MethodElement methodElement : methodMap.values()) {
+            if (methodElement.hasGraph()) {
+                if (Modifier.isNative(methodElement.getResolvedJavaMethod().accessFlags())) {
+                    System.out.println("Included native method: " + methodElement.getResolvedJavaMethod());
+                    nativeMethodCount++;
+                }
+            }
+        }
+
+        int methodCount = 0;
+        for (MethodElement methodElement : methodMap.values()) {
+            if (methodElement.hasGraph()) {
+                if (!Modifier.isNative(methodElement.getResolvedJavaMethod().accessFlags())) {
+                    System.out.println("Included method: " + methodElement.getResolvedJavaMethod());
+                    methodCount++;
+                }
+            }
+        }
+
+        Set<ResolvedJavaType> includedTypes = new HashSet<>();
+        int fieldCount = 0;
+        for (FieldElement fieldElement : fieldMap.values()) {
+            if (fieldElement.getUsageCount() > 0) {
+                System.out.println("Included field: " + fieldElement.getJavaField());
+                fieldCount++;
+                includedTypes.add(fieldElement.getJavaField().holder());
+            }
+        }
+
+        for (ResolvedJavaType type : includedTypes) {
+            System.out.println("Included type: " + type);
+        }
+
+        System.out.println("Number of included native methods: " + nativeMethodCount);
+        System.out.println("Number of included method: " + methodCount);
+        System.out.println("Number of included fields: " + fieldCount);
+        System.out.println("Number of included types: " + includedTypes.size());
+    }
+}
--- a/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BootImageGenerator.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/BootImageGenerator.java	Sat Jun 16 00:06:48 2012 +0200
@@ -26,13 +26,14 @@
 
 import com.oracle.graal.api.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.debug.*;
+import com.oracle.graal.boot.meta.*;
 
 
 public class BootImageGenerator {
 
     private final BootImageClassLoader classLoader = new BootImageClassLoader();
     private final MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+    private final BigBang bigbang = new BigBang(metaAccess);
 
     public void addEntryMethod(Class<?> clazz, String name, Class<?> ... parameterTypes) {
         Class<?> convertedClass = classLoader.convert(clazz);
@@ -42,17 +43,20 @@
         } catch (NoSuchMethodException | SecurityException e) {
             throw new RuntimeException("Could not find method " + name + " with parameter types " + parameterTypes + " in class " + convertedClass.getCanonicalName());
         }
-        Debug.log("Adding method %s.%s to the boot image", method.getClass().getName(), method.getName());
+        System.out.printf("Adding method %s.%s to the boot image\n", method.getDeclaringClass().getName(), method.getName());
         addEntryMethod(metaAccess.getResolvedJavaMethod(method));
     }
 
 
     private void addEntryMethod(ResolvedJavaMethod javaMethod) {
-
+        MethodElement methodElement = bigbang.getProcessedMethod(javaMethod);
+        methodElement.postParseGraph(bigbang);
+        bigbang.finish();
     }
 
 
-    public void logState() {
-        Debug.log("State");
+    public void printState() {
+        System.out.println("State of boot image generation");
+        bigbang.printState();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/UniverseExpansionOp.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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.boot;
+
+import com.oracle.graal.boot.*;
+
+
+
+public abstract class UniverseExpansionOp implements Runnable {
+
+    public void post(BigBang store) {
+        store.postOperation(this);
+    }
+
+    @Override
+    public void run() {
+        expand();
+    }
+
+    protected abstract void expand();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/ArrayTypeElement.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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.boot.meta;
+
+import com.oracle.graal.api.meta.*;
+
+
+public class ArrayTypeElement extends Element {
+
+    private ResolvedJavaType javaType;
+
+    public ArrayTypeElement(ResolvedJavaType javaType) {
+        super(javaType.componentType());
+        this.javaType = javaType;
+    }
+
+    @Override
+    public String toString() {
+        return javaType + super.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/Element.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2011, 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.boot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.graph.*;
+
+
+public class Element {
+
+    public static final Element BLACK_HOLE = new Element(null);
+
+    protected List<Node> usages = new ArrayList<>(4);
+    protected Set<ResolvedJavaType> seenTypes = new HashSet<>();
+    private ResolvedJavaType declaredType;
+
+    protected Element(ResolvedJavaType declaredType) {
+        this.declaredType = declaredType;
+    }
+
+    public void postUnionTypes(final BigBang bb, final Node sourceNode, final Set<ResolvedJavaType> newSeenTypes) {
+        new UniverseExpansionOp() {
+            @Override
+            protected void expand() {
+                unionTypes(bb, sourceNode, newSeenTypes);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Add new seen types %s from source node %s to element %s", newSeenTypes, sourceNode, Element.this);
+            }
+        }.post(bb);
+    }
+
+    public void postAddUsage(final BigBang bb, final Node usage) {
+        new UniverseExpansionOp() {
+            @Override
+            protected void expand() {
+                addUsage(bb, usage);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Add usage %s to element %s", usage, Element.this);
+            }
+        }.post(bb);
+    }
+
+    protected synchronized void unionTypes(BigBang bb, @SuppressWarnings("unused") Node sourceNode, Set<ResolvedJavaType> newSeenTypes) {
+        if (!seenTypes.containsAll(newSeenTypes)) {
+            if (declaredType != null) {
+                for (ResolvedJavaType seenType : newSeenTypes) {
+                    if (!seenType.isSubtypeOf(declaredType)) {
+                        System.out.println("Wrong type found " + seenType + " where declared type of element " + this + " is " + declaredType);
+                        System.exit(-1);
+                    }
+                }
+            }
+            seenTypes.addAll(newSeenTypes);
+            propagateTypes(bb, newSeenTypes);
+        }
+    }
+
+    protected synchronized void propagateTypes(BigBang bb, Set<ResolvedJavaType> newSeenTypes) {
+        for (Node n : usages) {
+            propagateTypes(bb, n, newSeenTypes);
+        }
+    }
+
+    public synchronized int getUsageCount() {
+        return usages.size();
+    }
+
+    protected synchronized void addUsage(BigBang bb, Node usage) {
+        if (!usages.contains(usage)) {
+            usages.add(usage);
+            propagateTypes(bb, usage, seenTypes);
+        }
+    }
+
+    public static void propagateTypes(BigBang bb, Node n, Set<ResolvedJavaType> types) {
+        if (types.size() != 0) {
+            Set<ResolvedJavaType> newSet = new HashSet<>(types);
+            for (Node use : n.usages()) {
+                Element element = bb.getSinkElement(use, n);
+                assert element != null;
+                if (element != BLACK_HOLE) {
+                    element.postUnionTypes(bb, n, newSet);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/FieldElement.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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.boot.meta;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+
+
+public class FieldElement extends Element {
+
+    protected ResolvedJavaField javaField;
+
+    public FieldElement(ResolvedJavaField javaField) {
+        super(javaField.type().resolve(javaField.holder()));
+        this.javaField = javaField;
+    }
+
+    public boolean isStatic() {
+        return Modifier.isStatic(javaField.accessFlags());
+    }
+
+    public ResolvedJavaField getJavaField() {
+        return javaField;
+    }
+
+    @Override
+    public String toString() {
+        return "Field[" + javaField + "]";
+    }
+
+    public synchronized void registerNewValue(BigBang bb, Object value) {
+        if (value != null) {
+            Class<?> clazz = value.getClass();
+            ResolvedJavaType resolvedType = bb.getMetaAccess().getResolvedJavaType(clazz);
+            if (seenTypes.add(resolvedType)) {
+                Set<ResolvedJavaType> newSeenTypes = new HashSet<>();
+                newSeenTypes.add(resolvedType);
+                super.propagateTypes(bb, newSeenTypes);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/InvokeElement.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,107 @@
+/*
+ * 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.boot.meta;
+
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+
+public class InvokeElement extends Element {
+
+    private MethodCallTargetNode methodCallTarget;
+    private Set<ResolvedJavaMethod> concreteTargets = new HashSet<>();
+    private Set<ResolvedJavaType>[] parameterTypes;
+
+    @SuppressWarnings("unchecked")
+    public InvokeElement(MethodCallTargetNode methodCallTarget) {
+        super(methodCallTarget.isStatic() ? null : methodCallTarget.targetMethod().holder());
+        this.methodCallTarget = methodCallTarget;
+        parameterTypes = new Set[methodCallTarget.arguments().size()];
+    }
+
+    @Override
+    protected synchronized void unionTypes(BigBang bb, Node sourceNode, Set<ResolvedJavaType> newSeenTypes) {
+
+        System.out.println("union invoke element " + this);
+        int index = 0;
+        for (Node arg : methodCallTarget.arguments()) {
+            if (arg == sourceNode) {
+                System.out.println("source node " + sourceNode + " is at index " + index + " declaredType=" + ((ValueNode) sourceNode).stamp().declaredType());
+                unionTypes(bb, sourceNode, newSeenTypes, index);
+            }
+            ++index;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Invoke[bci=" + methodCallTarget.invoke().stateAfter().method() + "," + methodCallTarget.targetMethod() + "]";
+    }
+
+    private void unionTypes(BigBang bb, @SuppressWarnings("unused") Node sourceNode, Set<ResolvedJavaType> newSeenTypes, int index) {
+        if (index == 0 && !methodCallTarget.isStatic()) {
+            for (ResolvedJavaType type : newSeenTypes) {
+                if (seenTypes.add(type)) {
+                    // There is a new receiver type!
+                    ResolvedJavaMethod method = type.resolveMethodImpl(methodCallTarget.targetMethod());
+                    if (method == null) {
+                        System.out.println("!!! type = " + type + " / " + methodCallTarget.targetMethod());
+                    }
+                    if (!concreteTargets.contains(method)) {
+                        concreteTargets.add(method);
+                        // New concrete method.
+                        MethodElement processedMethod = bb.getProcessedMethod(method);
+                        processedMethod.postParseGraph(bb);
+                        // Propagate types that were previously found for the parameters.
+                        for (int i = 0; i < parameterTypes.length; ++i) {
+                            if (parameterTypes[i] != null) {
+                                HashSet<ResolvedJavaType> newSeenTypesTemp = new HashSet<>(parameterTypes[i]);
+                                bb.getProcessedMethod(method).getParameter(i).postUnionTypes(bb, null, newSeenTypesTemp);
+                            }
+                        }
+                    }
+
+                    // Register new type for receiver.
+                    HashSet<ResolvedJavaType> newSeenTypesTemp = new HashSet<>();
+                    newSeenTypesTemp.add(type);
+                    bb.getProcessedMethod(method).getParameter(index).postUnionTypes(bb, null, newSeenTypesTemp);
+                }
+            }
+        } else {
+            if (parameterTypes[index] == null) {
+                parameterTypes[index] = new HashSet<>();
+            }
+            if (parameterTypes[index].addAll(newSeenTypes)) {
+                for (ResolvedJavaMethod method : concreteTargets) {
+                    HashSet<ResolvedJavaType> newSeenTypesTemp = new HashSet<>(newSeenTypes);
+                    bb.getProcessedMethod(method).getParameter(index).postUnionTypes(bb, null, newSeenTypesTemp);
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/MethodElement.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,117 @@
+/*
+ * 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.boot.meta;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.boot.*;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.java.GraphBuilderConfiguration.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+
+
+public class MethodElement extends Element {
+
+    private ParameterElement[] parameters;
+    private Graph graph;
+    private ResolvedJavaMethod resolvedJavaMethod;
+
+    public MethodElement(ResolvedJavaMethod javaMethod) {
+        super(javaMethod.signature().returnType(javaMethod.holder()).resolve(javaMethod.holder()));
+        assert javaMethod != null;
+        this.resolvedJavaMethod = javaMethod;
+        int parameterCount = resolvedJavaMethod.signature().argumentCount(!Modifier.isStatic(resolvedJavaMethod.accessFlags()));
+        parameters = new ParameterElement[parameterCount];
+        for (int i = 0; i < parameters.length; ++i) {
+            parameters[i] = new ParameterElement(resolvedJavaMethod, i);
+        }
+    }
+
+    public ParameterElement getParameter(int index) {
+        return parameters[index];
+    }
+
+    public synchronized boolean hasGraph() {
+        return graph != null;
+    }
+
+    public void postParseGraph(final BigBang bb) {
+        synchronized (this) {
+            if (graph != null) {
+                return;
+            }
+        }
+        new UniverseExpansionOp() {
+            @Override
+            protected void expand() {
+                parseGraph(bb);
+            }
+
+            @Override
+            public String toString() {
+                return String.format("Parsing method %s", resolvedJavaMethod);
+            }
+        }.post(bb);
+    }
+
+    protected synchronized void parseGraph(final BigBang bb) {
+        if (graph != null) {
+            // Graph already exists => quit operation.
+            return;
+        }
+        StructuredGraph newGraph = new StructuredGraph(resolvedJavaMethod);
+        this.graph = newGraph;
+        if (Modifier.isNative(resolvedJavaMethod.accessFlags())) {
+            System.out.println("NATIVE METHOD " + resolvedJavaMethod);
+            return;
+        }
+
+        System.out.println("parsing graph " + resolvedJavaMethod + ", locals=" + resolvedJavaMethod.maxLocals());
+        GraphBuilderConfiguration config = new GraphBuilderConfiguration(ResolvePolicy.Eager, null);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(bb.getMetaAccess(), config, OptimisticOptimizations.NONE);
+        graphBuilderPhase.apply(newGraph);
+        for (MethodCallTargetNode callTargetNode : newGraph.getNodes(MethodCallTargetNode.class)) {
+            bb.registerSourceCallTargetNode(callTargetNode);
+        }
+
+        for (Node node : newGraph.getNodes()) {
+            bb.registerSourceNode(node);
+        }
+
+        for (NewInstanceNode newInstance : newGraph.getNodes(NewInstanceNode.class)) {
+            Set<ResolvedJavaType> types = new HashSet<>();
+            types.add(newInstance.instanceClass());
+            System.out.println("propagate new instance " + newInstance + ", " + newInstance.instanceClass());
+            Element.propagateTypes(bb, newInstance, types);
+        }
+    }
+
+    public ResolvedJavaMethod getResolvedJavaMethod() {
+        return resolvedJavaMethod;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/ParameterElement.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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.boot.meta;
+
+import java.lang.reflect.*;
+
+import com.oracle.graal.api.meta.*;
+
+
+public class ParameterElement extends Element {
+
+    private int index;
+    private ResolvedJavaMethod method;
+
+    public ParameterElement(ResolvedJavaMethod method, int index) {
+        super(calculateDeclaredType(method, index));
+        this.method = method;
+        this.index = index;
+    }
+
+    private static ResolvedJavaType calculateDeclaredType(ResolvedJavaMethod m, int i) {
+        if (Modifier.isStatic(m.accessFlags())) {
+            return m.signature().argumentTypeAt(i, m.holder()).resolve(m.holder());
+        } else {
+            if (i == 0) {
+                return m.holder();
+            }
+            return m.signature().argumentTypeAt(i - 1, m.holder()).resolve(m.holder());
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "[Parameter, index= " + index + " of method " + method + "]";
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.boot/src/com/oracle/graal/boot/meta/PhiElement.java	Sat Jun 16 00:06:48 2012 +0200
@@ -0,0 +1,41 @@
+/*
+ * 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.boot.meta;
+
+import com.oracle.graal.nodes.*;
+
+
+public class PhiElement extends Element {
+
+    private PhiNode phi;
+
+    public PhiElement(PhiNode phi) {
+        super(null);
+        this.phi = phi;
+    }
+
+    @Override
+    public String toString() {
+        return "phi " + phi + super.toString();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Sat Jun 16 00:06:48 2012 +0200
@@ -204,7 +204,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T getCapability(Class<T> clazz) {
-        if (clazz == ExtendedRiRuntime.class) {
+        if (clazz == ExtendedRiRuntime.class || clazz == MetaAccessProvider.class) {
             return (T) getRuntime();
         }
         if (clazz == GraalCompiler.class) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Sat Jun 16 00:06:48 2012 +0200
@@ -66,8 +66,7 @@
             if (constant == null) {
                 if (holder.isInitialized() && holder.toJava() != System.class) {
                     if (Modifier.isFinal(accessFlags()) || assumeStaticFieldsFinal(holder.toJava())) {
-                        Constant encoding = holder.getEncoding(Representation.StaticFields);
-                        constant = this.kind().readUnsafeConstant(encoding.asObject(), offset);
+                        constant = getValue(receiver);
                     }
                 }
             }
@@ -76,12 +75,27 @@
             assert !Modifier.isStatic(accessFlags);
             // TODO (chaeubl) HotSpot does not trust final non-static fields (see ciField.cpp)
             if (Modifier.isFinal(accessFlags())) {
-                return this.kind().readUnsafeConstant(receiver.asObject(), offset);
+                return getValue(receiver);
             }
         }
         return null;
     }
 
+    @Override
+    public Constant getValue(Constant receiver) {
+        if (receiver == null) {
+            assert Modifier.isStatic(accessFlags);
+            if (holder.isInitialized()) {
+                Constant encoding = holder.getEncoding(Representation.StaticFields);
+                return this.kind().readUnsafeConstant(encoding.asObject(), offset);
+            }
+            return null;
+        } else {
+            assert !Modifier.isStatic(accessFlags);
+            return this.kind().readUnsafeConstant(receiver.asObject(), offset);
+        }
+    }
+
     private static boolean assumeStaticFieldsFinal(Class< ? > clazz) {
         return clazz == GraalOptions.class;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Sat Jun 16 00:06:48 2012 +0200
@@ -121,6 +121,7 @@
             case StaticFields:
                 return Constant.forObject(javaMirror);
             default:
+                assert false : "Should not reach here.";
                 return null;
         }
     }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sat Jun 16 00:06:48 2012 +0200
@@ -68,7 +68,7 @@
 
     private StructuredGraph currentGraph;
 
-    private final CodeCacheProvider runtime;
+    private final MetaAccessProvider runtime;
     private ConstantPool constantPool;
     private ResolvedJavaMethod method;
     private ProfilingInfo profilingInfo;
@@ -104,11 +104,12 @@
 
     private Block[] loopHeaders;
 
-    public GraphBuilderPhase(CodeCacheProvider runtime, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
+    public GraphBuilderPhase(MetaAccessProvider runtime, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
         this.graphBuilderConfig = graphBuilderConfig;
         this.optimisticOpts = optimisticOpts;
         this.runtime = runtime;
         this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
+        assert runtime != null;
     }
 
     @Override
@@ -1097,6 +1098,7 @@
     }
 
     private ConstantNode appendConstant(Constant constant) {
+        assert constant != null;
         return ConstantNode.forConstant(constant, runtime, currentGraph);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Sat Jun 16 00:06:48 2012 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
@@ -47,7 +46,7 @@
      * Constructs a new ConstantNode representing the specified constant.
      * @param value the constant
      */
-    protected ConstantNode(Constant value, CodeCacheProvider runtime) {
+    protected ConstantNode(Constant value, MetaAccessProvider runtime) {
         super(StampFactory.forConstant(value, runtime));
         this.value = value;
     }
@@ -65,7 +64,7 @@
         return usages().filter(NodePredicates.isNotA(FrameState.class)).isEmpty();
     }
 
-    public static ConstantNode forConstant(Constant constant, CodeCacheProvider runtime, Graph graph) {
+    public static ConstantNode forConstant(Constant constant, MetaAccessProvider runtime, Graph graph) {
         if (constant.kind == Kind.Object) {
             return graph.unique(new ConstantNode(constant, runtime));
         } else {
@@ -169,7 +168,7 @@
      * @param graph
      * @return a node representing the object
      */
-    public static ConstantNode forObject(Object o, CodeCacheProvider runtime, Graph graph) {
+    public static ConstantNode forObject(Object o, MetaAccessProvider runtime, Graph graph) {
         return graph.unique(new ConstantNode(Constant.forObject(o), runtime));
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Sat Jun 16 00:06:48 2012 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -36,7 +36,7 @@
     /**
      * Constructs a new ExceptionObject instruction.
      */
-    public ExceptionObjectNode(CodeCacheProvider runtime) {
+    public ExceptionObjectNode(MetaAccessProvider runtime) {
         super(StampFactory.declared(runtime.getResolvedJavaType(Throwable.class)));
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Thu Jun 14 18:03:43 2012 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Sat Jun 16 00:06:48 2012 +0200
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.type.GenericStamp.GenericStampType;
@@ -119,7 +118,7 @@
         }
     }
 
-    public static Stamp forConstant(Constant value, CodeCacheProvider runtime) {
+    public static Stamp forConstant(Constant value, MetaAccessProvider runtime) {
         assert value.kind == Kind.Object;
         if (value.kind == Kind.Object) {
             ResolvedJavaType type = value.isNull() ? null : runtime.getTypeOf(value);
--- a/mx/projects	Thu Jun 14 18:03:43 2012 +0200
+++ b/mx/projects	Sat Jun 16 00:06:48 2012 +0200
@@ -147,7 +147,7 @@
 # graal.boot
 project@com.oracle.graal.boot@subDir=graal
 project@com.oracle.graal.boot@sourceDirs=src
-project@com.oracle.graal.boot@dependencies=com.oracle.graal.compiler,com.oracle.graal.api
+project@com.oracle.graal.boot@dependencies=com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.api
 project@com.oracle.graal.boot@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.boot@javaCompliance=1.7