Mercurial > hg > graal-compiler
changeset 14571:24431a9b878c
Merge with 5e04917e66165ef93fe7b61030c4d89a08b3d53c
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Mon, 17 Mar 2014 12:40:35 -0700 |
parents | c828417b7037 (current diff) 5e04917e6616 (diff) |
children | 1d35a2b84553 |
files | graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java |
diffstat | 122 files changed, 1716 insertions(+), 1075 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGELOG.md Mon Mar 17 12:39:25 2014 -0700 +++ b/CHANGELOG.md Mon Mar 17 12:40:35 2014 -0700 @@ -7,7 +7,16 @@ * Made graph caching compilation-local. ### Truffle -* ... +* New API TruffleRuntime#createCallNode to create call nodes and to give the runtime system control over its implementation. +* New API RootNode#getCachedCallNodes to get a weak set of CallNodes that have registered to call the RootNode. +* New API to split the AST of a call-site context sensitively. CallNode#split, CallNode#isSplittable, CallNode#getSplitCallTarget, CallNode#getCurrentCallTarget, RootNode#isSplittable, RootNode#split. +* New API to inline a call-site into the call-graph. CallNode#isInlinable, CallNode#inline, CallNode#isInlined. +* New API for the runtime environment to register CallTargets as caller to the RootNode. CallNode#registerCallTarget. +* Improved API for counting nodes in Truffle ASTS. NodeUtil#countNodes can be used with a NodeFilter filter Nodes. +* New API to declare the cost of a Node for use in runtime environment specific heuristics. See NodeCost, Node#getCost() and NodeInfo#cost(). +* Removed old API for NodeInfo#Kind and NodeInfo#kind(). As a replacement the new Node cost API can be used. + + ## Version 0.1 5-Feb-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/b124e22eb772)
--- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Mon Mar 17 12:40:35 2014 -0700 @@ -146,7 +146,6 @@ case Short: case Int: case Long: - case NarrowOop: case Object: return true; }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Mon Mar 17 12:40:35 2014 -0700 @@ -198,8 +198,6 @@ return 8; case Object: return wordSize; - case NarrowOop: - return wordSize / 2; default: return 0; }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java Mon Mar 17 12:40:35 2014 -0700 @@ -71,7 +71,7 @@ * CSA * @param registers the registers that can be saved in the CSA */ - public CalleeSaveLayout(Architecture architecture, int frameOffsetToCSA, int size, int slotSize, Register... registers) { + public CalleeSaveLayout(TargetDescription target, int frameOffsetToCSA, int size, int slotSize, Register... registers) { this.frameOffsetToCSA = frameOffsetToCSA; assert slotSize == 0 || CodeUtil.isPowerOf2(slotSize); this.slotSize = slotSize; @@ -88,8 +88,8 @@ if (offset > maxOffset) { maxOffset = offset; } - PlatformKind kind = architecture.getLargestStorableKind(reg.getRegisterCategory()); - offset += architecture.getSizeInBytes(kind); + PlatformKind kind = target.arch.getLargestStorableKind(reg.getRegisterCategory()); + offset += target.getSizeInBytes(kind); } if (size == -1) { this.size = offset; @@ -106,8 +106,8 @@ int index = offset / slotSize; regNumToIndex[reg.number] = index; indexToReg[index] = reg; - PlatformKind kind = architecture.getLargestStorableKind(reg.getRegisterCategory()); - offset += architecture.getSizeInBytes(kind); + PlatformKind kind = target.arch.getLargestStorableKind(reg.getRegisterCategory()); + offset += target.getSizeInBytes(kind); } }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Mon Mar 17 12:40:35 2014 -0700 @@ -22,6 +22,7 @@ */ package com.oracle.graal.api.code; +import com.oracle.graal.api.code.CompilationResult.Data; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.meta.*; @@ -85,6 +86,11 @@ boolean needsDataPatch(Constant constant); /** + * Create a {@link Data} item for a {@link Constant}, that can be used in a {@link DataPatch}. + */ + Data createDataItem(Constant constant, int alignment); + + /** * Gets a description of the target architecture. */ TargetDescription getTarget();
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Mon Mar 17 12:40:35 2014 -0700 @@ -281,6 +281,17 @@ } } + public static class NumberedRefMapFormatter implements RefMapFormatter { + + public String formatStackSlot(int frameRefMapIndex) { + return "s" + frameRefMapIndex; + } + + public String formatRegister(int regRefMapIndex) { + return "r" + regRefMapIndex; + } + } + /** * Appends a formatted debug info to a {@link StringBuilder}. * @@ -288,7 +299,11 @@ * @param info the debug info to format and append to {@code sb} * @return the value of {@code sb} */ - public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatter) { + public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatterArg) { + RefMapFormatter formatter = formatterArg; + if (formatter == null) { + formatter = new NumberedRefMapFormatter(); + } String nl = NEW_LINE; ReferenceMap refMap = info.getReferenceMap(); if (refMap != null && refMap.hasRegisterRefMap()) {
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Mon Mar 17 12:40:35 2014 -0700 @@ -28,6 +28,7 @@ import java.nio.*; import java.util.*; +import com.oracle.graal.api.code.CodeUtil.*; import com.oracle.graal.api.meta.*; /** @@ -152,66 +153,64 @@ return alignment; } - public abstract int getSize(Architecture arch); + public abstract int getSize(TargetDescription target); - public abstract void emit(Architecture arch, ByteBuffer buffer); + public abstract Kind getKind(); + + public abstract void emit(TargetDescription target, ByteBuffer buffer); } - public static final class ConstantData extends Data { + /** + * Represents a Java primitive value used in a {@link DataPatch}. This implementation uses + * {@link Kind#getByteCount()} bytes to encode each value. + */ + public static final class PrimitiveData extends Data { public final Constant constant; - public ConstantData(Constant constant, int alignment) { + public PrimitiveData(Constant constant, int alignment) { super(alignment); + assert constant.getKind().isPrimitive(); this.constant = constant; } @Override - public int getSize(Architecture arch) { - return arch.getSizeInBytes(constant.getPlatformKind()); + public int getSize(TargetDescription target) { + return constant.getKind().getByteCount(); + } + + @Override + public Kind getKind() { + return constant.getKind(); } @Override - public void emit(Architecture arch, ByteBuffer buffer) { + public void emit(TargetDescription target, ByteBuffer buffer) { switch (constant.getKind()) { case Boolean: - assert getSize(arch) == 1; buffer.put(constant.asBoolean() ? (byte) 1 : (byte) 0); break; case Byte: - assert getSize(arch) == 1; buffer.put((byte) constant.asInt()); break; case Char: - assert getSize(arch) == 2; buffer.putChar((char) constant.asInt()); break; case Short: - assert getSize(arch) == 2; buffer.putShort((short) constant.asInt()); break; case Int: - assert getSize(arch) == 4; buffer.putInt(constant.asInt()); break; case Long: - assert getSize(arch) == 8; buffer.putLong(constant.asLong()); break; case Float: - assert getSize(arch) == 4; buffer.putFloat(constant.asFloat()); break; case Double: - assert getSize(arch) == 8; buffer.putDouble(constant.asDouble()); break; - case Object: - // placeholder for oop value - for (int i = 0; i < getSize(arch); i++) { - buffer.put((byte) 0); - } - break; } } @@ -219,6 +218,24 @@ public String toString() { return constant.toString(); } + + @Override + public int hashCode() { + return constant.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof PrimitiveData) { + PrimitiveData other = (PrimitiveData) obj; + return constant.equals(other.constant); + } else { + return false; + } + } } public static final class RawData extends Data { @@ -231,12 +248,17 @@ } @Override - public int getSize(Architecture arch) { + public int getSize(TargetDescription target) { return data.length; } @Override - public void emit(Architecture arch, ByteBuffer buffer) { + public Kind getKind() { + return Kind.Illegal; + } + + @Override + public void emit(TargetDescription target, ByteBuffer buffer) { buffer.put(data); } @@ -250,6 +272,24 @@ } return ret.toString(); } + + @Override + public int hashCode() { + return Arrays.hashCode(data); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof RawData) { + RawData other = (RawData) obj; + return Arrays.equals(data, other.data); + } else { + return false; + } + } } /** @@ -260,53 +300,18 @@ public static final class DataPatch extends Site { private static final long serialVersionUID = 5771730331604867476L; - public Data externalData; - public Constant inlineData; - - DataPatch(int pcOffset, Data externalData) { - this(pcOffset, externalData, null); - } - - DataPatch(int pcOffset, Constant inlineData) { - this(pcOffset, null, inlineData); - } - - private DataPatch(int pcOffset, Data externalData, Constant inlineData) { - super(pcOffset); - assert (externalData == null) != (inlineData == null) : "data patch can not be both external and inlined"; - this.externalData = externalData; - this.inlineData = inlineData; - } + public Data data; + public boolean inline; - public Constant getConstant() { - if (inlineData != null) { - return inlineData; - } else if (externalData instanceof ConstantData) { - return ((ConstantData) externalData).constant; - } else { - return null; - } - } - - public int getAlignment() { - if (externalData instanceof ConstantData) { - return ((ConstantData) externalData).getAlignment(); - } else { - return 0; - } - } - - public String getDataString() { - if (inlineData != null) { - return inlineData.toString(); - } else { - return externalData.toString(); - } + public DataPatch(int pcOffset, Data data, boolean inline) { + super(pcOffset); + this.data = data; + this.inline = inline; } @Override public String toString() { - return String.format("%d[<data patch referring to data %s>]", pcOffset, getDataString()); + return String.format("%d[<data patch referring to %s data %s>]", pcOffset, inline ? "inline" : "external", data.toString()); } } @@ -538,18 +543,18 @@ */ public void recordDataReference(int codePos, Data data) { assert codePos >= 0 && data != null; - dataReferences.add(new DataPatch(codePos, data)); + dataReferences.add(new DataPatch(codePos, data, false)); } /** * Records a reference to an inlined constant in the code section (e.g. to load a constant oop). * * @param codePos the position in the code where the inlined constant occurs - * @param constant the constant that is referenced + * @param data the data that is referenced */ - public void recordInlineData(int codePos, Constant constant) { - assert codePos >= 0 && constant != null; - dataReferences.add(new DataPatch(codePos, constant)); + public void recordInlineData(int codePos, Data data) { + assert codePos >= 0 && data != null; + dataReferences.add(new DataPatch(codePos, data, true)); } /** @@ -691,14 +696,15 @@ if (info != null) { ReferenceMap refMap = info.getReferenceMap(); if (refMap != null) { + RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter(); if (refMap.hasFrameRefMap()) { sb.append(" stackMap["); - refMap.appendFrameMap(sb, null); + refMap.appendFrameMap(sb, formatter); sb.append(']'); } if (refMap.hasRegisterRefMap()) { sb.append(" registerMap["); - refMap.appendRegisterMap(sb, null); + refMap.appendRegisterMap(sb, formatter); sb.append(']'); } }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Mon Mar 17 12:40:35 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, 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 @@ -22,123 +22,20 @@ */ package com.oracle.graal.api.code; -import java.io.*; -import java.util.*; - import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; - -public class ReferenceMap implements Serializable { - - private static final long serialVersionUID = -1052183095979496819L; - - /** - * Contains 2 bits per register. - * <ul> - * <li>bit0 = 0: contains no references</li> - * <li>bit0 = 1, bit1 = 0: contains a wide oop</li> - * <li>bit0 = 1, bit1 = 1: contains a narrow oop</li> - * </ul> - */ - private final BitSet registerRefMap; - - /** - * Contains 3 bits per stack slot. - * <ul> - * <li>bit0 = 0: contains no references</li> - * <li>bit0 = 1, bit1+2 = 0: contains a wide oop</li> - * <li>bit0 = 1, bit1 = 1: contains a narrow oop in the lower half</li> - * <li>bit0 = 1, bit2 = 1: contains a narrow oop in the upper half</li> - * </ul> - */ - private final BitSet frameRefMap; +import com.oracle.graal.api.meta.*; - public ReferenceMap(int registerCount, int frameSlotCount) { - if (registerCount > 0) { - this.registerRefMap = new BitSet(registerCount * 2); - } else { - this.registerRefMap = null; - } - this.frameRefMap = new BitSet(frameSlotCount * 3); - } +public interface ReferenceMap { - public void setRegister(int idx, boolean narrow) { - registerRefMap.set(2 * idx); - if (narrow) { - registerRefMap.set(2 * idx + 1); - } - } + void setRegister(int idx, PlatformKind kind); - public void setStackSlot(int idx, boolean narrow1, boolean narrow2) { - frameRefMap.set(3 * idx); - if (narrow1) { - frameRefMap.set(3 * idx + 1); - } - if (narrow2) { - frameRefMap.set(3 * idx + 2); - } - } - - public boolean hasRegisterRefMap() { - return registerRefMap != null && registerRefMap.size() > 0; - } + void setStackSlot(int offset, PlatformKind kind); - public boolean hasFrameRefMap() { - return frameRefMap != null && frameRefMap.size() > 0; - } - - public interface Iterator { - void register(int idx, boolean narrow); - - void stackSlot(int idx, boolean narrow1, boolean narrow2); - } + boolean hasRegisterRefMap(); - public void iterate(Iterator iterator) { - if (hasRegisterRefMap()) { - for (int i = 0; i < registerRefMap.size() / 2; i++) { - if (registerRefMap.get(2 * i)) { - iterator.register(i, registerRefMap.get(2 * i + 1)); - } - } - } - if (hasFrameRefMap()) { - for (int i = 0; i < frameRefMap.size() / 3; i++) { - if (frameRefMap.get(3 * i)) { - iterator.stackSlot(i, frameRefMap.get(3 * i + 1), frameRefMap.get(3 * i + 2)); - } - } - } - } - - private static class NumberedRefMapFormatter implements RefMapFormatter { + boolean hasFrameRefMap(); - public String formatStackSlot(int frameRefMapIndex) { - return "s" + frameRefMapIndex; - } - - public String formatRegister(int regRefMapIndex) { - return "r" + regRefMapIndex; - } - } - - public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg) { - RefMapFormatter formatter = formatterArg; - if (formatter == null) { - formatter = new NumberedRefMapFormatter(); - } + void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg); - for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 2)) { - sb.append(' ').append(formatter.formatRegister(reg / 2)); - } - } - - public void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg) { - RefMapFormatter formatter = formatterArg; - if (formatter == null) { - formatter = new NumberedRefMapFormatter(); - } - - for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 3)) { - sb.append(' ').append(formatter.formatStackSlot(slot / 3)); - } - } + void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg); }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java Mon Mar 17 12:40:35 2014 -0700 @@ -28,7 +28,7 @@ * Represents the target machine for a compiler, including the CPU architecture, the size of * pointers and references, alignment of stacks, caches, etc. */ -public class TargetDescription { +public abstract class TargetDescription { public final Architecture arch; @@ -81,4 +81,10 @@ this.implicitNullCheckLimit = implicitNullCheckLimit; this.inlineObjects = inlineObjects; } + + public int getSizeInBytes(PlatformKind kind) { + return arch.getSizeInBytes(kind); + } + + public abstract ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount); }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Mon Mar 17 12:40:35 2014 -0700 @@ -77,22 +77,6 @@ } } - /** - * @see ResolvedJavaMethod#getCompiledCodeSize() - */ - @Test - public void getCompiledCodeSizeTest() { - for (Map.Entry<Method, ResolvedJavaMethod> 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 getModifiersTest() { for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Mon Mar 17 12:40:35 2014 -0700 @@ -159,7 +159,6 @@ case Double: return asDouble(); case Object: - case NarrowOop: return object; case Illegal: return this; @@ -172,7 +171,7 @@ if (!ignoreKind && getKind() != other.getKind()) { return false; } - if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) { + if (getKind() == Kind.Object) { return object == other.object; } return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation(); @@ -235,12 +234,12 @@ /** * Returns the object reference this constant represents. The constant must have kind - * {@link Kind#Object} or {@link Kind#NarrowOop}. + * {@link Kind#Object}. * * @return the constant value */ public Object asObject() { - assert getKind() == Kind.Object || getKind() == Kind.NarrowOop; + assert getKind() == Kind.Object; return object; } @@ -250,7 +249,7 @@ * @return null if this constant is not primitive or has no annotation */ public Object getPrimitiveAnnotation() { - return getKind() == Kind.Object || getKind() == Kind.NarrowOop ? null : object; + return getKind() == Kind.Object ? null : object; } /** @@ -260,7 +259,7 @@ */ @Override public int hashCode() { - if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) { + if (getKind() == Kind.Object) { return System.identityHashCode(object); } return (int) primitive * getKind().ordinal(); @@ -394,16 +393,6 @@ } /** - * Creates a boxed narrow oop constant. - * - * @param o the object value to box - * @return a boxed copy of {@code value} - */ - public static Constant forNarrowOop(Object o) { - return new Constant(Kind.NarrowOop, o, 0L); - } - - /** * Creates an annotated int or long constant. An annotation enables a client to associate some * extra semantic or debugging information with a primitive. An annotated primitive constant is * never {@linkplain #equals(Object) equal} to a non-annotated constant. @@ -463,8 +452,6 @@ return forDouble((Double) value); case Object: return forObject(value); - case NarrowOop: - return forNarrowOop(value); default: throw new RuntimeException("cannot create Constant for boxed " + kind + " value"); } @@ -497,8 +484,6 @@ return LONG_0; case Object: return NULL_OBJECT; - case NarrowOop: - return forNarrowOop(null); default: throw new IllegalArgumentException(kind.toString()); }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java Mon Mar 17 12:40:35 2014 -0700 @@ -99,4 +99,12 @@ public void setMature() { // Do nothing } + + public boolean setCompilerIRSize(Class<?> irType, int nodeCount) { + return false; + } + + public int getCompilerIRSize(Class<?> irType) { + return -1; + } }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Mon Mar 17 12:40:35 2014 -0700 @@ -57,9 +57,6 @@ /** The Object kind, also used for arrays. */ Object('a', "Object", false, null, null), - /** The narrow oop kind. */ - NarrowOop('n', "NarrowOop", false, null, null), - /** The void float kind. */ Void('v', "void", false, java.lang.Void.TYPE, java.lang.Void.class), @@ -149,10 +146,10 @@ /** * Checks whether this represent an Object of some sort. * - * @return {@code true} if this is {@link #Object} or {@link #NarrowOop}. + * @return {@code true} if this is {@link #Object}. */ public boolean isObject() { - return this == Kind.Object || this == Kind.NarrowOop; + return this == Kind.Object; } /**
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Mon Mar 17 12:40:35 2014 -0700 @@ -114,6 +114,25 @@ int getDeoptimizationCount(DeoptimizationReason reason); /** + * Records the size of the compiler intermediate representation (IR) associated with this + * method. + * + * @param irType the IR type for which the size is being recorded + * @param irSize the IR size to be recorded. The unit depends on the IR. + * @return whether recording this information for {@code irType} is supported + */ + boolean setCompilerIRSize(Class<?> irType, int irSize); + + /** + * Gets the size of the compiler intermediate representation (IR) associated with this method + * last recorded by {@link #setCompilerIRSize(Class, int)}. + * + * @param irType the IR type for which the size is being requested + * @return the requested IR size or -1 if it is unavailable for {@code irType} + */ + int getCompilerIRSize(Class<?> irType); + + /** * Returns true if the profiling information can be assumed as sufficiently accurate. * * @return true if the profiling information was recorded often enough mature enough, false @@ -124,6 +143,5 @@ /** * Force data to be treated as mature if possible. */ - void setMature(); }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Mon Mar 17 12:40:35 2014 -0700 @@ -24,7 +24,6 @@ import java.lang.annotation.*; import java.lang.reflect.*; -import java.util.*; /** * Represents a resolved Java method. Methods, like fields and types, are resolved through @@ -54,13 +53,6 @@ int getCodeSize(); /** - * Returns the size of the compiled machine code of this method. - * - * @return the size of the compiled machine code in bytes, or 0 if no compiled code exists. - */ - int getCompiledCodeSize(); - - /** * Returns the {@link ResolvedJavaType} object representing the class or interface that declares * this method. */ @@ -144,12 +136,6 @@ void reprofile(); /** - * Returns a map that the compiler can use to store objects that should survive the current - * compilation. - */ - Map<Object, Object> getCompilerStorage(); - - /** * Returns the constant pool of this method. */ ConstantPool getConstantPool();
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Mon Mar 17 12:40:35 2014 -0700 @@ -27,7 +27,7 @@ import org.junit.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.ConstantData; +import com.oracle.graal.api.code.CompilationResult.PrimitiveData; import com.oracle.graal.api.code.CompilationResult.RawData; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; @@ -59,7 +59,7 @@ public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) { AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig); Register ret = registerConfig.getReturnRegister(Kind.Double); - compResult.recordDataReference(asm.position(), new ConstantData(Constant.forDouble(84.72), 8)); + compResult.recordDataReference(asm.position(), new PrimitiveData(Constant.forDouble(84.72), 8)); asm.movdbl(ret, asm.getPlaceholder()); asm.ret(0); return asm.close(true);
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Mon Mar 17 12:40:35 2014 -0700 @@ -261,7 +261,7 @@ private AMD64Address trigPrologue(Register value) { assert value.getRegisterCategory() == AMD64.XMM; AMD64Address tmp = new AMD64Address(AMD64.rsp); - subq(AMD64.rsp, target.arch.getSizeInBytes(Kind.Double)); + subq(AMD64.rsp, target.getSizeInBytes(Kind.Double)); movdbl(tmp, value); fldd(tmp); return tmp; @@ -271,7 +271,7 @@ assert dest.getRegisterCategory() == AMD64.XMM; fstpd(tmp); movdbl(dest, tmp); - addq(AMD64.rsp, target.arch.getSizeInBytes(Kind.Double)); + addq(AMD64.rsp, target.getSizeInBytes(Kind.Double)); } /**
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Mon Mar 17 12:40:35 2014 -0700 @@ -264,9 +264,6 @@ case Byte: prefix = "s8"; break; - case NarrowOop: - prefix = "u32"; - break; default: throw GraalInternalError.shouldNotReachHere(); }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 17 12:40:35 2014 -0700 @@ -198,11 +198,6 @@ suites.getLowTier().apply(graph, lowTierContext); graph.maybeCompress(); - // we do not want to store statistics about OSR compilations because it may prevent inlining - if (!graph.isOSR()) { - InliningPhase.storeStatisticsAfterLowTier(graph); - } - SchedulePhase schedule = new SchedulePhase(); schedule.apply(graph); Debug.dump(schedule, "final schedule"); @@ -298,14 +293,9 @@ for (int i = 0; i < dms.length; i++) { dms[i] = Debug.metric("DataPatches-" + Kind.values()[i].toString()); } - DebugMetric dmRaw = Debug.metric("DataPatches-raw"); for (DataPatch dp : ldp) { - if (dp.getConstant() != null) { - dms[dp.getConstant().getKind().ordinal()].add(1); - } else { - dmRaw.add(1); - } + dms[dp.data.getKind().ordinal()].add(1); } Debug.metric("CompilationResults").increment();
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Mon Mar 17 12:40:35 2014 -0700 @@ -25,15 +25,12 @@ import static com.oracle.graal.compiler.phases.HighTier.Options.*; import static com.oracle.graal.phases.GraalOptions.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.loop.phases.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.options.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.phases.verify.*; import com.oracle.graal.virtual.phases.ea.*; public class HighTier extends PhaseSuite<HighTierContext> { @@ -41,8 +38,6 @@ public static class Options { // @formatter:off - @Option(help = "") - public static final OptionValue<Boolean> VerifyUsageWithEquals = new OptionValue<>(true); @Option(help = "Enable inlining") public static final OptionValue<Boolean> Inline = new OptionValue<>(true); // @formatter:on @@ -51,11 +46,6 @@ public HighTier() { CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue()); - if (VerifyUsageWithEquals.getValue()) { - appendPhase(new VerifyUsageWithEquals(Value.class)); - appendPhase(new VerifyUsageWithEquals(Register.class)); - } - if (OptCanonicalizer.getValue()) { appendPhase(canonicalizer); }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Mon Mar 17 12:40:35 2014 -0700 @@ -89,7 +89,7 @@ final int stackFrameAlignment = 16; final int implicitNullCheckLimit = 4096; final boolean inlineObjects = true; - return new TargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + return new HotSpotTargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int); } @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Mon Mar 17 12:40:35 2014 -0700 @@ -473,8 +473,6 @@ protected static Constant compress(Constant c, CompressEncoding encoding) { if (c.getKind() == Kind.Long) { return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation()); - } else if (c.getKind() == Kind.Object) { - return Constant.forNarrowOop(c.asObject()); } else { throw GraalInternalError.shouldNotReachHere(); } @@ -523,8 +521,7 @@ if (canStoreConstant(c, isCompressed)) { if (isCompressed) { if (c.getKind() == Kind.Object) { - Constant value = c.isNull() ? c : compress(c, config.getOopEncoding()); - append(new StoreCompressedConstantOp(kind, storeAddress, value, state)); + append(new StoreCompressedConstantOp(kind, storeAddress, c, state)); } else if (c.getKind() == Kind.Long) { // It's always a good idea to directly store compressed constants since they // have to be materialized as 64 bits encoded otherwise.
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Mon Mar 17 12:40:35 2014 -0700 @@ -33,6 +33,7 @@ import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.hotspot.data.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; @@ -51,6 +52,9 @@ public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) { if (kind == Kind.Long) { if (NumUtil.isInt(input.asLong())) { + if (input.getPrimitiveAnnotation() != null) { + crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), input.getPrimitiveAnnotation(), true)); + } masm.movl(address.toAddress(), (int) input.asLong()); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); @@ -59,7 +63,7 @@ if (input.isNull()) { masm.movl(address.toAddress(), 0); } else if (crb.target.inlineObjects) { - crb.recordInlineDataInCode(input); + crb.recordInlineDataInCode(new OopData(0, input.asObject(), true)); masm.movl(address.toAddress(), 0xDEADDEAD); } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Mon Mar 17 12:40:35 2014 -0700 @@ -33,6 +33,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.nodes.type.*; public class AMD64HotSpotRegisterConfig implements RegisterConfig { @@ -61,9 +62,16 @@ return categorized.get(kind); } + PlatformKind primitiveKind; + if (kind == NarrowOopStamp.NarrowOop) { + primitiveKind = Kind.Int; + } else { + primitiveKind = kind; + } + ArrayList<Register> list = new ArrayList<>(); for (Register reg : getAllocatableRegisters()) { - if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) { + if (architecture.canStoreValue(reg.getRegisterCategory(), primitiveKind)) { list.add(reg); } } @@ -211,7 +219,7 @@ if (locations[i] == null) { locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out); - currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize); + currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); } }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Mon Mar 17 12:40:35 2014 -0700 @@ -62,7 +62,7 @@ final int stackFrameAlignment = 8; final int implicitNullCheckLimit = 0; final boolean inlineObjects = true; - return new TargetDescription(new HSAIL(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + return new HotSpotTargetDescription(new HSAIL(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int); } public String getArchitecture() {
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Mon Mar 17 12:40:35 2014 -0700 @@ -162,7 +162,7 @@ if (canStoreConstant(c, isCompressed)) { if (isCompressed) { if ((c.getKind() == Kind.Object) && c.isNull()) { - append(new StoreConstantOp(Kind.NarrowOop, storeAddress, c, state)); + append(new StoreConstantOp(Kind.Int, storeAddress, Constant.forInt(0), state)); } else { throw GraalInternalError.shouldNotReachHere("can't handle: " + access); }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Mon Mar 17 12:40:35 2014 -0700 @@ -59,7 +59,7 @@ final int stackFrameAlignment = 1; final int implicitNullCheckLimit = 0; final boolean inlineObjects = true; - return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + return new HotSpotTargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int); } public String getArchitecture() {
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Mon Mar 17 12:40:35 2014 -0700 @@ -133,7 +133,7 @@ if (locations[i] == null) { locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out); - currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize); + currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Mon Mar 17 12:40:35 2014 -0700 @@ -42,7 +42,7 @@ final int stackFrameAlignment = 16; final int implicitNullCheckLimit = 4096; final boolean inlineObjects = true; - return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects); + return new HotSpotTargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int); } public HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend host) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java Mon Mar 17 12:40:35 2014 -0700 @@ -34,6 +34,6 @@ @Override protected RegisterConfig createRegisterConfig() { - return new SPARCHotSpotRegisterConfig(getTarget().arch, runtime.getConfig()); + return new SPARCHotSpotRegisterConfig(getTarget(), runtime.getConfig()); } }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Mon Mar 17 12:40:35 2014 -0700 @@ -130,10 +130,10 @@ return registers; } - public SPARCHotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) { - this.architecture = architecture; + public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) { + this.architecture = target.arch; - csl = new CalleeSaveLayout(architecture, -1, -1, architecture.getWordSize(), calleeSaveRegisters); + csl = new CalleeSaveLayout(target, -1, -1, target.arch.getWordSize(), calleeSaveRegisters); allocatable = initAllocatable(config.useCompressedOops); attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters); } @@ -203,7 +203,7 @@ if (locations[i] == null) { locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out); - currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize); + currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); } }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Mon Mar 17 12:40:35 2014 -0700 @@ -49,7 +49,7 @@ protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, compResult.getName(), true); - HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(runtime().getTarget().arch, hsMethod, compResult); + HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(runtime().getTarget(), hsMethod, compResult); CodeInstallResult result = runtime().getCompilerToVM().installCode(compiledNmethod, installedCode, null); Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Mon Mar 17 12:40:35 2014 -0700 @@ -102,10 +102,10 @@ } } - public void finish(HotSpotResolvedJavaMethod method) { + public void finish(HotSpotResolvedJavaMethod method, HotSpotInstalledCode code) { if (ENABLED) { duration = System.nanoTime() - startTime; - codeSize = method.getCompiledCodeSize(); + codeSize = (int) code.getCodeSize(); memoryUsed = getThreadAllocatedBytes() - threadAllocatedBytesStart; if (current.get().getLast() != this) { throw new RuntimeException("mismatch in finish()");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Mar 17 12:40:35 2014 -0700 @@ -54,6 +54,8 @@ public class CompilationTask implements Runnable, Comparable { + private static final long TIMESTAMP_START = System.currentTimeMillis(); + // Keep static finals in a group with withinEnqueue as the last one. CompilationTask can be // called from within it's own clinit so it needs to be careful about accessing state. Once // withinEnqueue is non-null we assume that CompilationTask is fully initialized. @@ -279,8 +281,12 @@ try (TimerCloseable b = CodeInstallationTime.start()) { installedCode = installMethod(result); + if (!isOSR) { + ProfilingInfo profile = method.getProfilingInfo(); + profile.setCompilerIRSize(StructuredGraph.class, graph.getNodeCount()); + } } - stats.finish(method); + stats.finish(method, installedCode); } catch (BailoutException bailout) { BAILOUTS.increment(); if (ExitVMOnBailout.getValue()) { @@ -326,7 +332,24 @@ private void printCompilation() { final boolean isOSR = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; final int mod = method.getModifiers(); - TTY.println(String.format("%7d %4d %c%c%c%c%c %s %s(%d bytes)", 0, id, isOSR ? '%' : ' ', Modifier.isSynchronized(mod) ? 's' : ' ', ' ', ' ', Modifier.isNative(mod) ? 'n' : ' ', + String compilerName = ""; + if (HotSpotCIPrintCompilerName.getValue()) { + compilerName = "Graal:"; + } + HotSpotVMConfig config = backend.getRuntime().getConfig(); + int compLevel = config.compilationLevelFullOptimization; + char compLevelChar; + if (config.tieredCompilation) { + compLevelChar = '-'; + if (compLevel != -1) { + compLevelChar = (char) ('0' + compLevel); + } + } else { + compLevelChar = ' '; + } + boolean hasExceptionHandlers = method.getExceptionHandlers().length > 0; + TTY.println(String.format("%s%7d %4d %c%c%c%c%c%c %s %s(%d bytes)", compilerName, (System.currentTimeMillis() - TIMESTAMP_START), id, isOSR ? '%' : ' ', + Modifier.isSynchronized(mod) ? 's' : ' ', hasExceptionHandlers ? '!' : ' ', blocking ? 'b' : ' ', Modifier.isNative(mod) ? 'n' : ' ', compLevelChar, MetaUtil.format("%H::%n(%p)", method), isOSR ? "@ " + entryBCI + " " : "", method.getCodeSize())); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Mon Mar 17 12:40:35 2014 -0700 @@ -22,21 +22,17 @@ */ package com.oracle.graal.hotspot; -import java.nio.*; import java.util.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CompilationResult.CodeAnnotation; import com.oracle.graal.api.code.CompilationResult.CodeComment; -import com.oracle.graal.api.code.CompilationResult.Data; -import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.ExceptionHandler; import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.code.CompilationResult.JumpTable; import com.oracle.graal.api.code.CompilationResult.Mark; import com.oracle.graal.api.code.CompilationResult.Site; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.asm.*; +import com.oracle.graal.hotspot.data.*; /** * A {@link CompilationResult} with additional HotSpot-specific information required for installing @@ -53,111 +49,6 @@ public final DataSection dataSection; - /** - * Represents a reference to the data section. Before the code is installed, all {@link Data} - * items referenced by a {@link DataPatch} are put into the data section of the method, and - * replaced by {@link HotSpotData}. - */ - public static final class HotSpotData extends Data { - - /** - * The offset of the data item in the data section. - */ - public int offset; - - /** - * If the data item is an oop that needs to be patched by the runtime, this field contains - * the reference to the object. - */ - public Constant constant; - - public HotSpotData(int offset) { - super(0); - this.offset = offset; - } - - @Override - public int getSize(Architecture arch) { - return 0; - } - - @Override - public void emit(Architecture arch, ByteBuffer buffer) { - } - } - - /** - * Represents the data section of a method. - */ - public static final class DataSection { - - /** - * The minimum alignment required for this data section. - */ - public final int sectionAlignment; - - /** - * The raw data contained in the data section. - */ - public final byte[] data; - - /** - * A list of locations where oop pointers need to be patched by the runtime. - */ - public final HotSpotData[] patches; - - public DataSection(Architecture arch, Site[] sites) { - int size = 0; - int patchCount = 0; - List<DataPatch> externalDataList = new ArrayList<>(); - - // find all external data items and determine total size of data section - for (Site site : sites) { - if (site instanceof DataPatch) { - DataPatch dataPatch = (DataPatch) site; - if (dataPatch.externalData != null) { - Data d = dataPatch.externalData; - size = NumUtil.roundUp(size, d.getAlignment()); - size += d.getSize(arch); - externalDataList.add(dataPatch); - if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) { - patchCount++; - } - } - } - } - - data = new byte[size]; - patches = new HotSpotData[patchCount]; - ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder()); - int index = 0; - int patchIndex = 0; - int alignment = 0; - - // build data section - for (DataPatch dataPatch : externalDataList) { - Data d = dataPatch.externalData; - - alignment = Math.max(alignment, d.getAlignment()); - index = NumUtil.roundUp(index, d.getAlignment()); - buffer.position(index); - - HotSpotData hsData = new HotSpotData(index); - if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) { - // record patch location for oop pointers - hsData.constant = dataPatch.getConstant(); - patches[patchIndex++] = hsData; - } - dataPatch.externalData = hsData; - - index += d.getSize(arch); - d.emit(arch, buffer); - } - - this.sectionAlignment = alignment; - } - } - public static class Comment { public final String text; @@ -169,10 +60,10 @@ } } - public HotSpotCompiledCode(Architecture arch, CompilationResult compResult) { + public HotSpotCompiledCode(TargetDescription target, CompilationResult compResult) { this.comp = compResult; sites = getSortedSites(compResult); - dataSection = new DataSection(arch, sites); + dataSection = new DataSection(target, sites); if (compResult.getExceptionHandlers().isEmpty()) { exceptionHandlers = null; } else {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Mon Mar 17 12:40:35 2014 -0700 @@ -35,8 +35,8 @@ public final int entryBCI; public final int id; - public HotSpotCompiledNmethod(Architecture arch, HotSpotResolvedJavaMethod method, CompilationResult compResult) { - super(arch, compResult); + public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult) { + super(target, compResult); this.method = method; this.entryBCI = compResult.getEntryBCI(); this.id = compResult.getId();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Mon Mar 17 12:40:35 2014 -0700 @@ -26,7 +26,7 @@ import com.oracle.graal.api.code.CompilationResult.Call; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.Infopoint; -import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.data.*; import com.oracle.graal.hotspot.stubs.*; /** @@ -38,8 +38,8 @@ public final String stubName; - public HotSpotCompiledRuntimeStub(Architecture arch, Stub stub, CompilationResult compResult) { - super(arch, compResult); + public HotSpotCompiledRuntimeStub(TargetDescription target, Stub stub, CompilationResult compResult) { + super(target, compResult); assert checkStubInvariants(compResult); this.stubName = stub.toString(); } @@ -50,11 +50,7 @@ private boolean checkStubInvariants(CompilationResult compResult) { assert compResult.getExceptionHandlers().isEmpty(); for (DataPatch data : compResult.getDataReferences()) { - Constant constant = data.getConstant(); - if (constant != null) { - assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant; - assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant; - } + assert !(data.data instanceof PatchedData) : this + " cannot have embedded object or metadata constant: " + data.data; } for (Infopoint infopoint : compResult.getInfopoints()) { assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Mar 17 12:40:35 2014 -0700 @@ -235,6 +235,9 @@ if (HotSpotPrintInlining.getValue() == false) { HotSpotPrintInlining.setValue(config.printInlining); } + if (HotSpotCIPrintCompilerName.getValue() == false) { + HotSpotCIPrintCompilerName.setValue(config.printCompilerName); + } if (Boolean.valueOf(System.getProperty("graal.printconfig"))) { printConfig(config);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2009, 2014, 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.hotspot; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.nodes.type.*; + +public class HotSpotReferenceMap implements ReferenceMap, Serializable { + + private static final long serialVersionUID = -1052183095979496819L; + + /** + * Contains 2 bits per register. + * <ul> + * <li>bit0 = 0: contains no references</li> + * <li>bit0 = 1, bit1 = 0: contains a wide oop</li> + * <li>bit0 = 1, bit1 = 1: contains a narrow oop</li> + * </ul> + */ + private final BitSet registerRefMap; + + /** + * Contains 3 bits per stack slot. + * <ul> + * <li>bit0 = 0: contains no references</li> + * <li>bit0 = 1, bit1+2 = 0: contains a wide oop</li> + * <li>bit0 = 1, bit1 = 1: contains a narrow oop in the lower half</li> + * <li>bit0 = 1, bit2 = 1: contains a narrow oop in the upper half</li> + * </ul> + */ + private final BitSet frameRefMap; + + private final int frameSlotSize; + + public HotSpotReferenceMap(int registerCount, int frameSlotCount, int frameSlotSize) { + if (registerCount > 0) { + this.registerRefMap = new BitSet(registerCount * 2); + } else { + this.registerRefMap = null; + } + this.frameRefMap = new BitSet(frameSlotCount * 3); + this.frameSlotSize = frameSlotSize; + } + + public void setRegister(int idx, PlatformKind kind) { + if (kind == Kind.Object) { + registerRefMap.set(2 * idx); + } else if (kind == NarrowOopStamp.NarrowOop) { + registerRefMap.set(2 * idx); + registerRefMap.set(2 * idx + 1); + } + } + + public void setStackSlot(int offset, PlatformKind kind) { + int idx = offset / frameSlotSize; + if (kind == Kind.Object) { + assert offset % frameSlotSize == 0; + frameRefMap.set(3 * idx); + } else if (kind == NarrowOopStamp.NarrowOop) { + frameRefMap.set(3 * idx); + if (offset % frameSlotSize == 0) { + frameRefMap.set(3 * idx + 1); + } else { + assert offset % frameSlotSize == frameSlotSize / 2; + frameRefMap.set(3 * idx + 2); + } + } + } + + public boolean hasRegisterRefMap() { + return registerRefMap != null && registerRefMap.size() > 0; + } + + public boolean hasFrameRefMap() { + return frameRefMap != null && frameRefMap.size() > 0; + } + + public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatter) { + for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 2)) { + sb.append(' ').append(formatter.formatRegister(reg / 2)); + } + } + + public void appendFrameMap(StringBuilder sb, RefMapFormatter formatter) { + for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 3)) { + sb.append(' ').append(formatter.formatStackSlot(slot / 3)); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2014, 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.hotspot; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.nodes.type.*; + +public class HotSpotTargetDescription extends TargetDescription { + + private final PlatformKind rawNarrowOopKind; + + public HotSpotTargetDescription(Architecture arch, boolean isMP, int stackAlignment, int implicitNullCheckLimit, boolean inlineObjects, PlatformKind rawNarrowOopKind) { + super(arch, isMP, stackAlignment, implicitNullCheckLimit, inlineObjects); + this.rawNarrowOopKind = rawNarrowOopKind; + } + + @Override + public int getSizeInBytes(PlatformKind kind) { + if (kind == NarrowOopStamp.NarrowOop) { + return super.getSizeInBytes(rawNarrowOopKind); + } else { + return super.getSizeInBytes(kind); + } + } + + @Override + public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) { + return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapBitCount() : 0, stackSlotCount, wordSize); + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Mar 17 12:40:35 2014 -0700 @@ -709,10 +709,12 @@ @HotSpotVMFlag(name = "DontCompileHugeMethods") @Stable public boolean dontCompileHugeMethods; @HotSpotVMFlag(name = "HugeMethodLimit") @Stable public int hugeMethodLimit; @HotSpotVMFlag(name = "PrintCompilation") @Stable public boolean printCompilation; + @HotSpotVMFlag(name = "CIPrintCompilerName") @Stable public boolean printCompilerName; @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining; @HotSpotVMFlag(name = "GraalUseFastLocking") @Stable public boolean useFastLocking; @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable; @HotSpotVMFlag(name = "GPUOffload") @Stable public boolean gpuOffload; + @HotSpotVMFlag(name = "TieredCompilation") @Stable public boolean tieredCompilation; @HotSpotVMFlag(name = "UseTLAB") @Stable public boolean useTLAB; @HotSpotVMFlag(name = "UseBiasedLocking") @Stable public boolean useBiasedLocking; @@ -1189,6 +1191,7 @@ @HotSpotVMField(name = "MethodData::_data_size", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataDataSize; @HotSpotVMField(name = "MethodData::_data[0]", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopDataOffset; @HotSpotVMField(name = "MethodData::_trap_hist._array[0]", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopTrapHistoryOffset; + @HotSpotVMField(name = "MethodData::_graal_node_count", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataGraalNodeCountOffset; @HotSpotVMField(name = "nmethod::_verified_entry_point", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodEntryOffset; @HotSpotVMField(name = "nmethod::_comp_level", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodCompLevelOffset;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Mon Mar 17 12:40:35 2014 -0700 @@ -252,14 +252,6 @@ boolean hasFinalizableSubclass(long metaspaceKlass); /** - * Gets the compiled code size for a method. - * - * @param metaspaceMethod the metaspace Method object to query - * @return the compiled code size the method - */ - int getCompiledCodeSize(long metaspaceMethod); - - /** * Gets the metaspace Method object corresponding to a given {@link Class} object and slot * number. *
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Mon Mar 17 12:40:35 2014 -0700 @@ -111,9 +111,6 @@ public native long getClassInitializer(long metaspaceKlass); @Override - public native int getCompiledCodeSize(long metaspaceMethod); - - @Override public native long getMaxCallTargetOffset(long address); // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2014, 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.hotspot.data; + +import java.nio.*; +import java.util.*; + +import com.oracle.graal.api.code.CompilationResult.Data; +import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.CompilationResult.Site; +import com.oracle.graal.api.code.*; +import com.oracle.graal.asm.*; + +/** + * Represents the data section of a method. + */ +public final class DataSection { + + /** + * The minimum alignment required for this data section. + */ + public final int sectionAlignment; + + /** + * The raw data contained in the data section. + */ + public final byte[] data; + + /** + * A list of locations where oop pointers need to be patched by the runtime. + */ + public final DataPatch[] patches; + + public DataSection(TargetDescription target, Site[] sites) { + int size = 0; + int patchCount = 0; + List<DataPatch> externalDataList = new ArrayList<>(); + + // find all external data items and determine total size of data section + for (Site site : sites) { + if (site instanceof DataPatch) { + DataPatch dataPatch = (DataPatch) site; + Data d = dataPatch.data; + if (dataPatch.inline) { + assert d instanceof PatchedData : "unnecessary data patch"; + } else { + size = NumUtil.roundUp(size, d.getAlignment()); + size += d.getSize(target); + externalDataList.add(dataPatch); + if (d instanceof PatchedData) { + patchCount++; + } + } + } + } + + data = new byte[size]; + patches = new DataPatch[patchCount]; + ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder()); + int index = 0; + int patchIndex = 0; + int alignment = 0; + + // build data section + for (DataPatch dataPatch : externalDataList) { + assert !dataPatch.inline; + Data d = dataPatch.data; + + alignment = Math.max(alignment, d.getAlignment()); + index = NumUtil.roundUp(index, d.getAlignment()); + buffer.position(index); + + DataSectionReference reference = new DataSectionReference(index); + if (d instanceof PatchedData) { + // record patch location + patches[patchIndex++] = new DataPatch(index, d, true); + } + dataPatch.data = reference; + + index += d.getSize(target); + d.emit(target, buffer); + } + + this.sectionAlignment = alignment; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014, 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.hotspot.data; + +import java.nio.*; + +import com.oracle.graal.api.code.CompilationResult.Data; +import com.oracle.graal.api.code.CompilationResult.DataPatch; +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; + +/** + * Represents a reference to the data section. Before the code is installed, all {@link Data} items + * referenced by a {@link DataPatch} are put into the data section of the method, and replaced by + * {@link DataSectionReference}. + */ +public class DataSectionReference extends Data { + + public final int offset; + + protected DataSectionReference(int offset) { + super(0); + this.offset = offset; + } + + @Override + public int getSize(TargetDescription target) { + return 0; + } + + @Override + public Kind getKind() { + return Kind.Illegal; + } + + @Override + public void emit(TargetDescription target, ByteBuffer buffer) { + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, 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.hotspot.data; + +import java.nio.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; + +/** + * A data item that represents a metaspace pointer. + */ +public class MetaspaceData extends PatchedData { + + public final long value; + public final Object annotation; + public final boolean compressed; + + public MetaspaceData(int alignment, long value, Object annotation, boolean compressed) { + super(alignment); + assert annotation != null; + this.value = value; + this.annotation = annotation; + this.compressed = compressed; + } + + @Override + public int getSize(TargetDescription target) { + if (compressed) { + return target.getSizeInBytes(Kind.Int); + } else { + return target.getSizeInBytes(target.wordKind); + } + } + + @Override + public Kind getKind() { + return Kind.Long; + } + + @Override + public void emit(TargetDescription target, ByteBuffer buffer) { + switch (getSize(target)) { + case 4: + buffer.putInt((int) value); + break; + case 8: + buffer.putLong(value); + break; + default: + throw GraalInternalError.shouldNotReachHere("unexpected metaspace pointer size"); + } + } + + @Override + public String toString() { + return (compressed ? "NarrowPointer[0x" + Integer.toHexString((int) value) : "Pointer[0x" + Long.toHexString(value)) + "]{" + annotation + "}"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, 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.hotspot.data; + +import java.nio.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.nodes.type.*; + +/** + * A data item that represents an oop value. + */ +public class OopData extends PatchedData { + + public final Object object; + public final boolean compressed; + + public OopData(int alignment, Object object, boolean compressed) { + super(alignment); + this.object = object; + this.compressed = compressed; + } + + @Override + public int getSize(TargetDescription target) { + if (compressed) { + return target.getSizeInBytes(NarrowOopStamp.NarrowOop); + } else { + return target.getSizeInBytes(Kind.Object); + } + } + + @Override + public Kind getKind() { + return Kind.Object; + } + + @Override + public void emit(TargetDescription target, ByteBuffer buffer) { + switch (getSize(target)) { + case 4: + buffer.putInt(0xDEADDEAD); + break; + case 8: + buffer.putLong(0xDEADDEADDEADDEADL); + break; + default: + throw GraalInternalError.shouldNotReachHere("unexpected oop size"); + } + } + + @Override + public String toString() { + return (compressed ? "NarrowOop[" : "Oop[") + Kind.Object.format(object) + "]"; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2014, 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.hotspot.data; + +import com.oracle.graal.api.code.CompilationResult.Data; + +/** + * Represents a data item that needs to be patched. + */ +public abstract class PatchedData extends Data { + + protected PatchedData(int alignment) { + super(alignment); + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Mon Mar 17 12:40:35 2014 -0700 @@ -29,14 +29,17 @@ import com.oracle.graal.api.code.CodeUtil.DefaultRefMapFormatter; import com.oracle.graal.api.code.CodeUtil.RefMapFormatter; import com.oracle.graal.api.code.CompilationResult.Call; +import com.oracle.graal.api.code.CompilationResult.Data; import com.oracle.graal.api.code.CompilationResult.DataPatch; import com.oracle.graal.api.code.CompilationResult.Infopoint; import com.oracle.graal.api.code.CompilationResult.Mark; +import com.oracle.graal.api.code.CompilationResult.PrimitiveData; import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; +import com.oracle.graal.hotspot.data.*; import com.oracle.graal.java.*; import com.oracle.graal.printer.*; @@ -82,7 +85,7 @@ } } for (DataPatch site : compResult.getDataReferences()) { - hcf.addOperandComment(site.pcOffset, "{" + site.getDataString() + "}"); + hcf.addOperandComment(site.pcOffset, "{" + site.data.toString() + "}"); } for (Mark mark : compResult.getMarks()) { hcf.addComment(mark.pcOffset, getMarkName(mark)); @@ -173,7 +176,7 @@ compResult.setId(method.allocateCompileId(compResult.getEntryBCI())); } HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), true); - runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target.arch, method, compResult), installedCode, method.getSpeculationLog()); + runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult), installedCode, method.getSpeculationLog()); return logOrDump(installedCode, compResult); } @@ -184,7 +187,7 @@ compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI())); } HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); - CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target.arch, hotspotMethod, compResult), code, log); + CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, hotspotMethod, compResult), code, log); if (result != CodeInstallResult.OK) { return null; } @@ -203,7 +206,7 @@ compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI())); } HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true); - HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target.arch, javaMethod, compResult); + HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target, javaMethod, compResult); CompilerToVM vm = runtime.getCompilerToVM(); CodeInstallResult result = vm.installCode(compiled, code, null); if (result != CodeInstallResult.OK) { @@ -216,6 +219,16 @@ return constant.getPrimitiveAnnotation() != null; } + public Data createDataItem(Constant constant, int alignment) { + if (constant.getPrimitiveAnnotation() != null) { + return new MetaspaceData(alignment, constant.asLong(), constant.getPrimitiveAnnotation(), false); + } else if (constant.getKind().isObject()) { + return new OopData(alignment, constant.asObject(), false); + } else { + return new PrimitiveData(constant, alignment); + } + } + @Override public TargetDescription getTarget() { return target;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Mon Mar 17 12:40:35 2014 -0700 @@ -700,9 +700,9 @@ public int getScalingFactor(Kind kind) { if (useCompressedOops() && kind == Kind.Object) { - return this.runtime.getTarget().arch.getSizeInBytes(Kind.Int); + return this.runtime.getTarget().getSizeInBytes(Kind.Int); } else { - return this.runtime.getTarget().arch.getSizeInBytes(kind); + return this.runtime.getTarget().getSizeInBytes(kind); } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Mon Mar 17 12:40:35 2014 -0700 @@ -299,7 +299,7 @@ ResolvedJavaType elementType = lookupJavaType.getComponentType(); Kind elementKind = elementType.getKind(); final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind); - int sizeOfElement = HotSpotGraalRuntime.runtime().getTarget().arch.getSizeInBytes(elementKind); + int sizeOfElement = HotSpotGraalRuntime.runtime().getTarget().getSizeInBytes(elementKind); int alignment = HotSpotGraalRuntime.runtime().getTarget().wordSize; int log2ElementSize = CodeUtil.log2(sizeOfElement); return NewObjectSnippets.computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Mon Mar 17 12:40:35 2014 -0700 @@ -825,4 +825,12 @@ super(runtime().getConfig().dataLayoutArgInfoDataTag, ARG_INFO_DATA_SIZE); } } + + public void setCompiledGraphSize(int nodeCount) { + unsafe.putInt(metaspaceMethodData + config.methodDataGraalNodeCountOffset, nodeCount); + } + + public int getCompiledGraphSize() { + return unsafe.getInt(metaspaceMethodData + config.methodDataGraalNodeCountOffset); + } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Mon Mar 17 12:40:35 2014 -0700 @@ -43,7 +43,12 @@ private static final long serialVersionUID = -1784683588947054103L; + /** + * This (indirect) Method* reference is safe since class redefinition preserves all methods + * associated with nmethods in the code cache. + */ private final HotSpotResolvedJavaMethod method; + private final boolean isDefault; private final boolean isExternal; private final String name;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java Mon Mar 17 12:40:35 2014 -0700 @@ -25,6 +25,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.nodes.*; public final class HotSpotProfilingInfo extends CompilerObject implements ProfilingInfo { @@ -205,4 +206,21 @@ public void setMature() { isMature = true; } + + @Override + public boolean setCompilerIRSize(Class<?> irType, int size) { + if (irType == StructuredGraph.class) { + methodData.setCompiledGraphSize(size); + return true; + } + return false; + } + + @Override + public int getCompilerIRSize(Class<?> irType) { + if (irType == StructuredGraph.class) { + return methodData.getCompiledGraphSize(); + } + return -1; + } }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Mon Mar 17 12:40:35 2014 -0700 @@ -28,8 +28,6 @@ import java.lang.annotation.*; import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; @@ -59,7 +57,6 @@ private boolean forceInline; private boolean dontInline; private boolean ignoredBySecurityStackWalk; - private Map<Object, Object> compilerStorage; private HotSpotMethodData methodData; private byte[] code; private SpeculationLog speculationLog; @@ -356,10 +353,6 @@ return signature; } - public int getCompiledCodeSize() { - return runtime().getCompilerToVM().getCompiledCodeSize(metaspaceMethod); - } - /** * Gets the value of {@code Method::_code}. * @@ -433,14 +426,6 @@ } @Override - public Map<Object, Object> getCompilerStorage() { - if (compilerStorage == null) { - compilerStorage = new ConcurrentHashMap<>(); - } - return compilerStorage; - } - - @Override public ConstantPool getConstantPool() { return constantPool; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2014, 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.hotspot.nodes.type; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; + +public class NarrowOopStamp extends ObjectStamp { + + public static final PlatformKind NarrowOop = new PlatformKind() { + + public String name() { + return "NarrowOop"; + } + + @Override + public String toString() { + return name(); + } + }; + + private final CompressEncoding encoding; + + public NarrowOopStamp(ObjectStamp stamp, CompressEncoding encoding) { + this(stamp.type(), stamp.isExactType(), stamp.nonNull(), stamp.alwaysNull(), encoding); + } + + public NarrowOopStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull, CompressEncoding encoding) { + super(type, exactType, nonNull, alwaysNull); + this.encoding = encoding; + } + + public Stamp uncompressed() { + return new ObjectStamp(type(), isExactType(), nonNull(), alwaysNull()); + } + + public CompressEncoding getEncoding() { + return encoding; + } + + @Override + public Stamp unrestricted() { + return new NarrowOopStamp((ObjectStamp) super.unrestricted(), encoding); + } + + @Override + public Kind getStackKind() { + return Kind.Object; + } + + @Override + public PlatformKind getPlatformKind(LIRTypeTool tool) { + return NarrowOop; + } + + @Override + public String toString() { + StringBuilder str = new StringBuilder(); + str.append('n'); + str.append(super.toString()); + return str.toString(); + } + + @Override + public Stamp meet(Stamp otherStamp) { + if (this == otherStamp) { + return this; + } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.meet(this); + } + if (!isCompatible(otherStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + return new NarrowOopStamp((ObjectStamp) super.meet(otherStamp), encoding); + } + + @Override + public Stamp join(Stamp otherStamp) { + if (this == otherStamp) { + return this; + } + if (otherStamp instanceof IllegalStamp) { + return otherStamp.join(this); + } + if (!isCompatible(otherStamp)) { + return StampFactory.illegal(Kind.Illegal); + } + return new NarrowOopStamp((ObjectStamp) super.join(otherStamp), encoding); + } + + @Override + public boolean isCompatible(Stamp other) { + if (this == other) { + return true; + } + if (other instanceof NarrowOopStamp) { + NarrowOopStamp narrow = (NarrowOopStamp) other; + return encoding.equals(narrow.encoding); + } + return false; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + encoding.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + NarrowOopStamp other = (NarrowOopStamp) obj; + if (!encoding.equals(other.encoding)) { + return false; + } + return super.equals(other); + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Mon Mar 17 12:40:35 2014 -0700 @@ -73,11 +73,11 @@ Node currentNode = iterator.next(); assert !isSafepoint(currentNode) : "Write barrier must be present " + write; if (useG1GC()) { - if (!(currentNode instanceof G1PostWriteBarrier) || ((currentNode instanceof G1PostWriteBarrier) && !validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode))) { + if (!(currentNode instanceof G1PostWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode))) { expandFrontier(frontier, currentNode); } } else { - if (!(currentNode instanceof SerialWriteBarrier) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode)) || + if (!(currentNode instanceof SerialWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode)) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode))) { expandFrontier(frontier, currentNode); }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Mon Mar 17 12:40:35 2014 -0700 @@ -153,7 +153,7 @@ try (Scope s = Debug.scope("CodeInstall")) { Stub stub = Stub.this; HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub); - HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(backend.getTarget().arch, stub, compResult); + HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(backend.getTarget(), stub, compResult); CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null); if (result != CodeInstallResult.OK) {
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Mon Mar 17 12:40:35 2014 -0700 @@ -168,7 +168,7 @@ Kind kind = arg.getKind(); if (kind == Kind.Double || kind == Kind.Long) { regPrefix = "$d"; - } else if (kind == Kind.Int || kind == Kind.Float || kind == Kind.NarrowOop) { + } else if (kind == Kind.Int || kind == Kind.Float) { regPrefix = "$s"; } else { regPrefix = "$d"; @@ -193,7 +193,6 @@ case Int: case Long: case Object: - case NarrowOop: return true; } } else if (category == FPU) {
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Mon Mar 17 12:40:35 2014 -0700 @@ -123,7 +123,7 @@ if (locations[i] == null) { locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out); - currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize); + currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize); } } @@ -150,7 +150,6 @@ case Short: case Byte: case Float: - case NarrowOop: return regBitness32.clone(); case Long: case Double:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/DecompilerTest.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, 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.java.decompiler.test; + +import java.lang.reflect.*; + +import org.junit.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.runtime.*; +import com.oracle.graal.java.decompiler.test.example.*; +import com.oracle.graal.printer.*; +import com.oracle.graal.runtime.*; + +@Ignore +public class DecompilerTest { + + public static void doTest(String name) { + try { + DebugEnvironment.initialize(System.out); + MetaAccessProvider metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); + Method method = Example.class.getDeclaredMethod(name, new Class[]{int.class, int.class}); + final ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method); + TestUtil.compileMethod(javaMethod); + } catch (NoSuchMethodException e) { + Assert.fail(); + } catch (SecurityException e) { + Assert.fail(); + } + } + + @Test + public void test01() { + doTest("loop7"); + } + + @Test + public void test02() { + doTest("loop6"); + } + + @Test + public void test03() { + doTest("loop5"); + } + + @Test + public void test04() { + doTest("loop4"); + } + + @Test + public void test05() { + doTest("loop3"); + } + + @Test + public void test06() { + doTest("loop2"); + } + + @Test + public void test07() { + doTest("loop"); + } + + @Test + public void test08() { + doTest("if0"); + } + + @Test + public void test09() { + doTest("if1"); + } + + @Test + public void test10() { + doTest("if2"); + } + + @Test + public void test11() { + doTest("if3"); + } + + @Test + public void test12() { + doTest("if4"); + } +}
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java Mon Mar 17 12:39:25 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2013, 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.java.decompiler.test; - -import java.lang.reflect.*; - -import com.oracle.graal.api.meta.*; -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.java.decompiler.test.example.*; -import com.oracle.graal.printer.*; -import com.oracle.graal.runtime.*; - -public class Test { - - /** - * @param args - * @throws SecurityException - * @throws NoSuchMethodException - */ - public static void main(String[] args) throws NoSuchMethodException, SecurityException { - DebugEnvironment.initialize(System.out); - MetaAccessProvider metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess(); - Method method = Example.class.getDeclaredMethod("loop7", new Class[]{int.class, int.class}); - final ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method); - TestUtil.compileMethod(javaMethod); - } -}
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Mon Mar 17 12:40:35 2014 -0700 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.compiler.GraalCompiler.*; + import com.oracle.graal.api.code.*; import com.oracle.graal.api.code.CallingConvention.Type; import com.oracle.graal.api.meta.*;
--- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerIfSimplify.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerIfSimplify.java Mon Mar 17 12:40:35 2014 -0700 @@ -68,7 +68,7 @@ // TODO(mg) // thenBlocks and elseBlocks can be both empty --> causes an AssertionError DecompilerIfBlock ifBlock = new DecompilerIfBlock(block.getBlock(), decompiler, thenBlocks, elseBlocks, infoStream); - if (thenBlocks.contains(block.getBlock()) || elseBlocks.contains(block.getBlock())) { + if (thenBlocks.contains(block) || elseBlocks.contains(block)) { throw new AssertionError(); } blocks.add(ifBlock);
--- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/block/DecompilerIfBlock.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/block/DecompilerIfBlock.java Mon Mar 17 12:40:35 2014 -0700 @@ -158,7 +158,20 @@ @Override public boolean contains(Block b) { - return b == block || thenBranch.contains(b) || elseBranch.contains(b); + if (b == block) { + return true; + } + for (DecompilerBlock i : thenBranch) { + if (i.block == b) { + return true; + } + } + for (DecompilerBlock i : elseBranch) { + if (i.block == b) { + return true; + } + } + return false; } @Override
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Mon Mar 17 12:40:35 2014 -0700 @@ -205,7 +205,7 @@ return null; } - PhiNode phi = graph.addWithoutUnique(new PhiNode(currentValue.kind(), block)); + PhiNode phi = graph.addWithoutUnique(new PhiNode(currentValue.stamp().unrestricted(), block)); for (int i = 0; i < block.phiPredecessorCount(); i++) { phi.addInput(currentValue); } @@ -303,7 +303,7 @@ } assert !block.isPhiAtMerge(value) : "phi function for this block already created"; - PhiNode phi = graph.addWithoutUnique(new PhiNode(value.kind(), block)); + PhiNode phi = graph.addWithoutUnique(new PhiNode(value.stamp().unrestricted(), block)); phi.addInput(value); return phi; }
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Mon Mar 17 12:40:35 2014 -0700 @@ -237,13 +237,6 @@ throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to object ref"); } break; - case NarrowOop: - if (input.isNull()) { - masm.emitStoreImmediate(kind, 0L, address.toAddress()); - } else { - throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to object ref"); - } - break; default: throw GraalInternalError.shouldNotReachHere(); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Mon Mar 17 12:40:35 2014 -0700 @@ -170,7 +170,7 @@ // Without this, frameNeedsAllocating() would never return true. int total = 0; for (StackSlot s : freedSlots) { - total += target.arch.getSizeInBytes(s.getKind()); + total += target.getSizeInBytes(s.getKind()); } if (total == spillSize - initialSpillSize) { // reset spill area size @@ -256,7 +256,7 @@ * @return the size in bytes */ protected int spillSlotSize(PlatformKind kind) { - return target.arch.getSizeInBytes(kind); + return target.getSizeInBytes(kind); } /** @@ -347,8 +347,8 @@ } } - public ReferenceMap initReferenceMap(boolean canHaveRegisters) { - ReferenceMap refMap = new ReferenceMap(canHaveRegisters ? target.arch.getRegisterReferenceMapBitCount() : 0, frameSize() / target.wordSize); + public ReferenceMap initReferenceMap(boolean hasRegisters) { + ReferenceMap refMap = target.createReferenceMap(hasRegisters, frameSize() / target.wordSize); for (StackSlot slot : objectStackSlots) { setReference(slot, refMap); } @@ -364,22 +364,14 @@ * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}. */ public void setReference(Value location, ReferenceMap refMap) { - Kind kind = location.getKind(); - if (kind == Kind.Object || kind == Kind.NarrowOop) { - if (isRegister(location)) { - refMap.setRegister(asRegister(location).number, kind == Kind.NarrowOop); - } else if (isStackSlot(location)) { - if (kind == Kind.NarrowOop) { - int offset = offsetForStackSlot(asStackSlot(location)); - assert offset % target.wordSize == 0 || offset % target.wordSize == target.wordSize / 2; - refMap.setStackSlot(offset / target.wordSize, offset % target.wordSize == 0, offset % target.wordSize != 0); - } else { - int index = indexForStackSlot(asStackSlot(location)); - refMap.setStackSlot(index, false, false); - } - } else { - assert isConstant(location); - } + PlatformKind kind = location.getPlatformKind(); + if (isRegister(location)) { + refMap.setRegister(asRegister(location).number, kind); + } else if (isStackSlot(location)) { + int offset = offsetForStackSlot(asStackSlot(location)); + refMap.setStackSlot(offset, kind); + } else { + assert isConstant(location); } } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Mon Mar 17 12:40:35 2014 -0700 @@ -27,7 +27,6 @@ import java.util.*; import com.oracle.graal.api.code.*; -import com.oracle.graal.api.code.CompilationResult.ConstantData; import com.oracle.graal.api.code.CompilationResult.Data; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; @@ -157,6 +156,10 @@ } public void recordInlineDataInCode(Constant data) { + recordInlineDataInCode(codeCache.createDataItem(data, 0)); + } + + public void recordInlineDataInCode(Data data) { assert data != null; int pos = asm.position(); Debug.log("Inline data in code: pos = %d, data = %s", pos, data); @@ -165,7 +168,7 @@ public AbstractAddress recordDataReferenceInCode(Constant data, int alignment) { assert data != null; - return recordDataReferenceInCode(new ConstantData(data, alignment)); + return recordDataReferenceInCode(codeCache.createDataItem(data, alignment)); } public AbstractAddress recordDataReferenceInCode(Data data) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Mon Mar 17 12:40:35 2014 -0700 @@ -332,7 +332,7 @@ PhiNode phi; switch (vpn.type()) { case Value: - phi = graph.addWithoutUnique(new PhiNode(vpn.kind(), merge)); + phi = graph.addWithoutUnique(new PhiNode(vpn.stamp(), merge)); break; case Guard: phi = graph.addWithoutUnique(new PhiNode(vpn.type(), merge));
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Mon Mar 17 12:40:35 2014 -0700 @@ -170,7 +170,7 @@ PhiNode ret; switch (phi.type()) { case Value: - ret = new PhiNode(phi.kind(), merge); + ret = new PhiNode(phi.stamp(), merge); break; case Guard: ret = new PhiNode(PhiType.Guard, merge);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Mon Mar 17 12:40:35 2014 -0700 @@ -22,7 +22,6 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodes.calc.*; @@ -53,15 +52,11 @@ private final PhiType type; /** - * Create a value phi ({@link PhiType#Value}) with the specified kind. + * Create a value phi ({@link PhiType#Value}) with the specified stamp. * - * @param kind the kind of the value + * @param stamp the stamp of the value * @param merge the merge that the new phi belongs to */ - public PhiNode(Kind kind, MergeNode merge) { - this(StampFactory.forKind(kind), merge); - } - public PhiNode(Stamp stamp, MergeNode merge) { super(stamp); assert stamp != StampFactory.forVoid(); @@ -186,7 +181,7 @@ public void addInput(ValueNode x) { assert !(x instanceof PhiNode) || ((PhiNode) x).merge() instanceof LoopBeginNode || ((PhiNode) x).merge() != this.merge(); - assert x.kind() == kind() || type != PhiType.Value; + assert x.stamp().isCompatible(stamp()) || type != PhiType.Value; values.add(x); }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Mon Mar 17 12:40:35 2014 -0700 @@ -85,8 +85,9 @@ if (stamp instanceof IllegalStamp) { IllegalStamp other = (IllegalStamp) stamp; return kind == other.kind; + } else { + return stamp.isCompatible(this); } - return false; } @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Mon Mar 17 12:40:35 2014 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.cfg.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; @@ -55,8 +56,8 @@ if (target instanceof AbstractDeoptimizeNode) { merge = graph.add(new MergeNode()); EndNode firstEnd = graph.add(new EndNode()); - reasonActionPhi = graph.addWithoutUnique(new PhiNode(Kind.Int, merge)); - speculationPhi = graph.addWithoutUnique(new PhiNode(Kind.Object, merge)); + reasonActionPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Int), merge)); + speculationPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Object), merge)); merge.addForwardEnd(firstEnd); reasonActionPhi.addInput(((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess())); speculationPhi.addInput(((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess()));
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Mon Mar 17 12:40:35 2014 -0700 @@ -91,14 +91,6 @@ return inliningCount; } - public static void storeStatisticsAfterLowTier(StructuredGraph graph) { - ResolvedJavaMethod method = graph.method(); - if (method != null) { - CompiledMethodInfo info = compiledMethodInfo(graph.method()); - info.setLowLevelNodeCount(graph.getNodeCount()); - } - } - @Override protected void run(final StructuredGraph graph, final HighTierContext context) { final InliningData data = new InliningData(graph, context.getAssumptions()); @@ -310,15 +302,6 @@ return newGraph; } - private static synchronized CompiledMethodInfo compiledMethodInfo(ResolvedJavaMethod m) { - CompiledMethodInfo info = (CompiledMethodInfo) m.getCompilerStorage().get(CompiledMethodInfo.class); - if (info == null) { - info = new CompiledMethodInfo(); - m.getCompilerStorage().put(CompiledMethodInfo.class, info); - } - return info; - } - private abstract static class AbstractInliningPolicy implements InliningPolicy { protected final Map<Invoke, Double> hints; @@ -371,7 +354,12 @@ protected static int previousLowLevelGraphSize(InlineInfo info) { int size = 0; for (int i = 0; i < info.numberOfMethods(); i++) { - size += compiledMethodInfo(info.methodAt(i)).lowLevelNodeCount(); + ResolvedJavaMethod m = info.methodAt(i); + ProfilingInfo profile = m.getProfilingInfo(); + int compiledGraphSize = profile.getCompilerIRSize(StructuredGraph.class); + if (compiledGraphSize > 0) { + size += compiledGraphSize; + } } return size; } @@ -864,21 +852,4 @@ return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "<null method>") + remainingInvokes; } } - - private static class CompiledMethodInfo { - - private int lowLevelNodes; - - public CompiledMethodInfo() { - } - - public int lowLevelNodeCount() { - return lowLevelNodes; - } - - public void setLowLevelNodeCount(int lowLevelNodes) { - this.lowLevelNodes = lowLevelNodes; - } - - } }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Mon Mar 17 12:40:35 2014 -0700 @@ -625,7 +625,7 @@ PhiNode returnValuePhi = null; if (invoke.asNode().kind() != Kind.Void) { - returnValuePhi = graph.addWithoutUnique(new PhiNode(invoke.asNode().kind(), returnMerge)); + returnValuePhi = graph.addWithoutUnique(new PhiNode(invoke.asNode().stamp().unrestricted(), returnMerge)); } MergeNode exceptionMerge = null; @@ -638,7 +638,7 @@ FixedNode exceptionSux = exceptionEdge.next(); graph.addBeforeFixed(exceptionSux, exceptionMerge); - exceptionObjectPhi = graph.addWithoutUnique(new PhiNode(Kind.Object, exceptionMerge)); + exceptionObjectPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Object), exceptionMerge)); exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, Kind.Object, exceptionObjectPhi)); } @@ -1486,7 +1486,7 @@ if (returnNode.result() != null) { if (returnValuePhi == null) { - returnValuePhi = merge.graph().addWithoutUnique(new PhiNode(returnNode.result().kind(), merge)); + returnValuePhi = merge.graph().addWithoutUnique(new PhiNode(returnNode.result().stamp().unrestricted(), merge)); } returnValuePhi.addInput(returnNode.result()); }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Mon Mar 17 12:40:35 2014 -0700 @@ -312,6 +312,8 @@ Mark preLoweringMark = node.graph().getMark(); ((Lowerable) node).lower(loweringTool); if (loweringTool.guardAnchor.asNode().isDeleted()) { + // TODO nextNode could be deleted but this is not currently supported + assert nextNode.isAlive(); loweringTool.guardAnchor = BeginNode.prevBegin(nextNode); } assert checkPostNodeLowering(node, loweringTool, preLoweringMark, unscheduledUsages);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java Mon Mar 17 12:40:35 2014 -0700 @@ -87,7 +87,7 @@ } if (lastLocationAccess instanceof PhiNode) { PhiNode phi = (PhiNode) lastLocationAccess; - PhiNode newPhi = phi.graph().addWithoutUnique(new PhiNode(n.kind(), phi.merge())); + PhiNode newPhi = phi.graph().addWithoutUnique(new PhiNode(n.stamp().unrestricted(), phi.merge())); nodeMap.set(phi, newPhi); for (ValueNode value : phi.values()) { newPhi.addInput(getValue(n, (MemoryNode) value, nodeMap));
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Mon Mar 17 12:40:35 2014 -0700 @@ -486,7 +486,7 @@ // introduce a new phi PhiNode newPhi = bottomPhis.get(node); if (newPhi == null) { - newPhi = graph.addWithoutUnique(new PhiNode(node.kind(), newBottomMerge)); + newPhi = graph.addWithoutUnique(new PhiNode(node.stamp().unrestricted(), newBottomMerge)); bottomPhis.put(node, newPhi); newPhi.addInput(node); }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Mar 17 12:40:35 2014 -0700 @@ -177,6 +177,8 @@ @Option(help = "") public static final OptionValue<Boolean> HotSpotPrintCompilation = new OptionValue<>(false); @Option(help = "") + public static final OptionValue<Boolean> HotSpotCIPrintCompilerName = new OptionValue<>(false); + @Option(help = "") public static final OptionValue<Boolean> HotSpotPrintInlining = new OptionValue<>(false); // Register allocator debugging
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Mon Mar 17 12:40:35 2014 -0700 @@ -85,7 +85,7 @@ private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) { try { - assert node.isAlive() : node + " not alive"; + assert node == null || node.isAlive() : node + " not alive"; if (node != null && !visited.isMarked(node)) { if (floatingOnly && node instanceof FixedNode) { throw new GraalInternalError("unexpected reference to fixed node: %s (this indicates an unexpected cycle)", node);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Mon Mar 17 12:40:35 2014 -0700 @@ -134,16 +134,17 @@ */ protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) { StringBuilder sb = new StringBuilder(); + RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter(); if (refMap != null && refMap.hasRegisterRefMap()) { sb.append("reg-ref-map:"); - refMap.appendRegisterMap(sb, arch != null ? new ArchitectureRegFormatter(arch) : null); + refMap.appendRegisterMap(sb, arch != null ? new ArchitectureRegFormatter(arch) : formatter); sb.append("\n"); } if (refMap != null && refMap.hasFrameRefMap()) { sb.append("frame-ref-map:"); - refMap.appendFrameMap(sb, null); + refMap.appendFrameMap(sb, formatter); sb.append("\n"); }
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java Mon Mar 17 12:40:35 2014 -0700 @@ -35,6 +35,7 @@ public class DecompilerDebugDumpHandler implements DebugDumpHandler { + public static boolean printToNowhere; private final PrintStream infoPrintStream = System.out; private File file; private FileOutputStream fos; @@ -55,6 +56,15 @@ filter = filter.substring(0, filter.indexOf("Phase")); } + if (printToNowhere) { + printStream = new PrintStream(new OutputStream() { + @Override + public void write(int b) throws IOException { + // DO NOTHING + } + }); + } + if (printStream == null) { fileName = "decompilerDump_" + uniqueId.incrementAndGet() + "_" + System.currentTimeMillis() + ".txt"; file = new File(fileName);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Mon Mar 17 12:40:35 2014 -0700 @@ -1012,12 +1012,6 @@ // Re-wire the control flow graph around the replacee FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode); replacee.replaceAtPredecessor(firstCFGNodeDuplicate); - FixedNode next = null; - if (replacee instanceof FixedWithNextNode) { - FixedWithNextNode fwn = (FixedWithNextNode) replacee; - next = fwn.next(); - fwn.setNext(null); - } if (replacee instanceof StateSplit) { for (StateSplit sideEffectNode : sideEffectNodes) { @@ -1052,6 +1046,12 @@ replacer.replace(replacee, returnValue, mmap); } if (returnDuplicate.isAlive()) { + FixedNode next = null; + if (replacee instanceof FixedWithNextNode) { + FixedWithNextNode fwn = (FixedWithNextNode) replacee; + next = fwn.next(); + fwn.setNext(null); + } returnDuplicate.clearInputs(); returnDuplicate.replaceAndDelete(next); }
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Mon Mar 17 12:40:35 2014 -0700 @@ -162,7 +162,6 @@ case Int: case Long: case Object: - case NarrowOop: return true; } } else if (category == FPU) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Mon Mar 17 12:40:35 2014 -0700 @@ -28,7 +28,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.impl.*; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; +import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter; /** * Call target that is optimized by Graal upon surpassing a specific invocation threshold. @@ -85,6 +85,11 @@ return new DefaultOptimizedCallNode(target); } + @Override + public boolean isInlinable() { + return true; + } + private static final class DefaultOptimizedCallNode extends OptimizedCallNode { private boolean trySplit = true; @@ -135,7 +140,7 @@ if (isMaxSingleCall()) { return true; } - return countPolymorphic() >= 1 || countGeneric() > 0; + return countPolymorphic() >= 1; } @Override @@ -143,11 +148,6 @@ trySplit = true; } - @Override - protected void notifyCallNodeAdded() { - trySplit = true; - } - private boolean isMaxSingleCall() { final AtomicInteger count = new AtomicInteger(0); getCurrentCallTarget().getRootNode().accept(new NodeVisitor() { @@ -163,11 +163,12 @@ } private int countPolymorphic() { - return NodeUtil.countNodes(getCallTarget().getRootNode(), null, Kind.POLYMORPHIC, false); - } - - private int countGeneric() { - return NodeUtil.countNodes(getCallTarget().getRootNode(), null, Kind.GENERIC, false); + return NodeUtil.countNodes(getCallTarget().getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + NodeCost cost = node.getCost(); + return cost == NodeCost.POLYMORPHIC || cost == NodeCost.MEGAMORPHIC; + } + }); } @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Mon Mar 17 12:40:35 2014 -0700 @@ -34,7 +34,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.impl.*; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; +import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter; /** * Call target that is optimized by Graal upon surpassing a specific invocation threshold. @@ -428,11 +428,11 @@ target.getRootNode().accept(new NodeVisitor() { public boolean visit(Node node) { - Kind kind = node.getKind(); - if (kind == Kind.POLYMORPHIC || kind == Kind.GENERIC) { + NodeCost kind = node.getCost(); + if (kind == NodeCost.POLYMORPHIC || kind == NodeCost.MEGAMORPHIC) { Map<String, Object> props = new LinkedHashMap<>(); props.put("simpleName", node.getClass().getSimpleName()); - String msg = kind == Kind.GENERIC ? "generic" : "polymorphic"; + String msg = kind == NodeCost.MEGAMORPHIC ? "megamorphic" : "polymorphic"; log(0, msg, node.toString(), props); } if (node instanceof CallNode) { @@ -461,8 +461,20 @@ } static void addASTSizeProperty(RootNode target, Map<String, Object> properties) { + int polymorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + return node.getCost() == NodeCost.POLYMORPHIC; + } + }, true); + + int megamorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() { + public boolean isCounted(Node node) { + return node.getCost() == NodeCost.MEGAMORPHIC; + } + }, true); + String value = String.format("%4d (%d/%d)", NodeUtil.countNodes(target.getRootNode(), null, true), // - NodeUtil.countNodes(target.getRootNode(), null, Kind.POLYMORPHIC, true), NodeUtil.countNodes(target.getRootNode(), null, Kind.GENERIC, true)); // + polymorphicCount, megamorphicCount); // properties.put("ASTSize", value); }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Mon Mar 17 12:40:35 2014 -0700 @@ -162,7 +162,7 @@ } } if (phi) { - PhiNode phiNode = getCachedPhi(entry, value.kind()); + PhiNode phiNode = getCachedPhi(entry, value.stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); for (int i = 0; i < states.size(); i++) { afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this)); @@ -194,7 +194,7 @@ values[i] = value; } - PhiNode phiNode = getCachedPhi(new ReadCacheEntry(identity, phi), values[0].kind()); + PhiNode phiNode = getCachedPhi(new ReadCacheEntry(identity, phi), values[0].stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi"); for (int i = 0; i < values.length; i++) { afterMergeEffects.addPhiInput(phiNode, values[i]);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Mon Mar 17 12:40:35 2014 -0700 @@ -35,6 +35,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.spi.Virtualizable.EscapeState; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.util.*; @@ -284,10 +285,10 @@ super(mergeBlock); } - protected <T> PhiNode getCachedPhi(T virtual, Kind kind) { + protected <T> PhiNode getCachedPhi(T virtual, Stamp stamp) { PhiNode result = materializedPhis.get(virtual); if (result == null) { - result = new PhiNode(kind, merge); + result = new PhiNode(stamp, merge); materializedPhis.put(virtual, result); } return result; @@ -363,7 +364,7 @@ if (uniqueMaterializedValue != null) { newState.addObject(object, new ObjectState(object, uniqueMaterializedValue, EscapeState.Materialized, null)); } else { - PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object); + PhiNode materializedValuePhi = getCachedPhi(object, StampFactory.forKind(Kind.Object)); mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi"); for (int i = 0; i < objStates.length; i++) { ObjectState obj = objStates[i]; @@ -458,7 +459,7 @@ for (int i = 1; i < objStates.length; i++) { ValueNode[] fields = objStates[i].getEntries(); if (phis[valueIndex] == null && values[valueIndex] != fields[valueIndex]) { - phis[valueIndex] = new PhiNode(values[valueIndex].kind(), merge); + phis[valueIndex] = new PhiNode(values[valueIndex].stamp().unrestricted(), merge); } } if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) { @@ -487,7 +488,7 @@ return materialized; } else { // not compatible: materialize in all predecessors - PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object); + PhiNode materializedValuePhi = getCachedPhi(object, StampFactory.forKind(Kind.Object)); for (int i = 0; i < blockStates.size(); i++) { ObjectState obj = objStates[i]; Block predecessor = mergeBlock.getPredecessors().get(i);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Mar 17 12:40:35 2014 -0700 @@ -33,6 +33,7 @@ import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.CacheEntry; @@ -196,10 +197,10 @@ super(mergeBlock); } - protected <T> PhiNode getCachedPhi(T virtual, Kind kind) { + protected <T> PhiNode getCachedPhi(T virtual, Stamp stamp) { PhiNode result = materializedPhis.get(virtual); if (result == null) { - result = new PhiNode(kind, merge); + result = new PhiNode(stamp, merge); materializedPhis.put(virtual, result); } return result; @@ -229,7 +230,7 @@ } } if (phi) { - PhiNode phiNode = getCachedPhi(entry, value.kind()); + PhiNode phiNode = getCachedPhi(entry, value.stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCache"); for (int i = 0; i < states.size(); i++) { afterMergeEffects.addPhiInput(phiNode, states.get(i).getCacheEntry(key)); @@ -262,7 +263,7 @@ } CacheEntry<?> newIdentifier = identifier.duplicateWithObject(phi); - PhiNode phiNode = getCachedPhi(newIdentifier, values[0].kind()); + PhiNode phiNode = getCachedPhi(newIdentifier, values[0].stamp().unrestricted()); mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi"); for (int i = 0; i < values.length; i++) { afterMergeEffects.addPhiInput(phiNode, values[i]);
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Mon Mar 17 12:40:35 2014 -0700 @@ -69,7 +69,7 @@ @Override public void generate(LIRGeneratorTool generator) { assert kind() != input.kind(); - assert generator.target().arch.getSizeInBytes(kind()) == generator.target().arch.getSizeInBytes(input.kind()); + assert generator.target().getSizeInBytes(kind()) == generator.target().getSizeInBytes(input.kind()); AllocatableValue result = generator.newVariable(kind()); generator.emitMove(result, generator.operand(input));
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Mon Mar 17 12:40:35 2014 -0700 @@ -33,7 +33,6 @@ import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; public class PolymorphicTest { @@ -55,7 +54,7 @@ assertEquals("(boolean,boolean)", executeWith(node, false, false)); assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals(Kind.SPECIALIZED, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); + assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -65,7 +64,7 @@ TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance()); assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); + assertEquals(NodeCost.NONE, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -76,7 +75,7 @@ assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(boolean,boolean)", executeWith(node, true, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); + assertEquals(NodeCost.NONE, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -88,7 +87,7 @@ assertEquals("(int,boolean)", executeWith(node, 42, false)); assertEquals("(boolean,boolean)", executeWith(node, true, false)); assertEquals("(int,int)", executeWith(node, 42, 42)); - assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); + assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -97,7 +96,7 @@ public void testGenericInitial() { TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance()); assertEquals("(generic,generic)", executeWith(node, "1", "1")); - assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); + assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost()); assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight()); } @@ -108,7 +107,7 @@ assertEquals("(boolean,int)", executeWith(node, false, 42)); assertEquals("(boolean,boolean)", executeWith(node, false, false)); assertEquals("(generic,generic)", executeWith(node, "", "")); - assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); + assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost()); /* Assertions for bug GRAAL-425 */ assertParent(node.getNode(), node.getNode().getLeft()); assertParent(node.getNode(), node.getNode().getRight());
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Mon Mar 17 12:40:35 2014 -0700 @@ -32,7 +32,6 @@ import com.oracle.truffle.api.dsl.test.PolymorphicTest2Factory.Node1Factory; import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; public class PolymorphicTest2 { @@ -43,7 +42,7 @@ assertEquals(21, executeWith(node, false, false)); assertEquals(42, executeWith(node, 21, 21)); assertEquals("(boolean,int)", executeWith(node, false, 42)); - assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind()); + assertEquals(NodeCost.NONE, node.getNode().getCost()); } @SuppressWarnings("unused")
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Mon Mar 17 12:40:35 2014 -0700 @@ -25,7 +25,6 @@ package com.oracle.truffle.api; import com.oracle.truffle.api.nodes.*; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; /** * Class containing general Truffle options. @@ -56,29 +55,29 @@ public static String TraceRewritesFilterClass = System.getProperty("truffle.TraceRewritesFilterClass"); /** - * Filters rewrites which does not contain the {@link Kind} in its source {@link NodeInfo}. If - * no {@link NodeInfo} is defined the element is filtered if the filter value is set. + * Filters rewrites which does not contain the {@link NodeCost} in its source {@link NodeInfo}. + * If no {@link NodeInfo} is defined the element is filtered if the filter value is set. * <p> * Can be set with - * {@code -Dtruffle.TraceRewritesFilterFromKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}. + * {@code -Dtruffle.TraceRewritesFilterFromCost=NONE|MONOMORPHIC|POLYMORPHIC|MEGAMORPHIC}. */ - public static NodeInfo.Kind TraceRewritesFilterFromKind = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterFromKind")); + public static NodeCost TraceRewritesFilterFromCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterFromCost")); /** - * Filters rewrites which does not contain the {@link Kind} in its target {@link NodeInfo}. If - * no {@link NodeInfo} is defined the element is filtered if the filter value is set. + * Filters rewrites which does not contain the {@link NodeCost} in its target {@link NodeInfo}. + * If no {@link NodeInfo} is defined the element is filtered if the filter value is set. * <p> * Can be set with * {@code -Dtruffle.TraceRewritesFilterToKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}. */ - public static NodeInfo.Kind TraceRewritesFilterToKind = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToKind")); + public static NodeCost TraceRewritesFilterToCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToCost")); - private static NodeInfo.Kind parseNodeInfoKind(String kind) { + private static NodeCost parseNodeInfoKind(String kind) { if (kind == null) { return null; } - return NodeInfo.Kind.valueOf(kind); + return NodeCost.valueOf(kind); } }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java Mon Mar 17 12:40:35 2014 -0700 @@ -64,6 +64,11 @@ } @Override + public boolean isInlinable() { + return false; + } + + @Override public String toString() { return getParent() != null ? getParent().toString() : super.toString(); }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java Mon Mar 17 12:40:35 2014 -0700 @@ -28,13 +28,18 @@ import com.oracle.truffle.api.frame.*; /** - * This node represents a call to a static {@link CallTarget}. This node should be used whenever a - * {@link CallTarget} is considered constant at a certain location in the tree. This enables the - * Truffle runtime to perform inlining or other optimizations for this call-site. This class is - * intended to be implemented by truffle runtime implementors and not by guest language - * implementors. + * Represents a call to a {@link CallTarget} in the Truffle AST. Addtionally to calling the + * {@link CallTarget} this {@link Node} enables the runtime system to implement further + * optimizations. Optimizations that can possibly applied to a {@link CallNode} are inlining and + * splitting. Inlining inlines this call site into the call graph of the parent {@link CallTarget}. + * Splitting duplicates the {@link CallTarget} using {@link RootNode#split()} to collect call site + * sensitive profiling information. * - * @see #create(CallTarget) to create a CallNode instance. + * Please note: This class is not intended to be subclassed by guest language implementations. + * + * @see TruffleRuntime#createCallNode(CallTarget) + * @see #inline() + * @see #split() */ public abstract class CallNode extends Node { @@ -45,7 +50,7 @@ } /** - * Calls this constant target passing a caller frame and arguments. + * Calls the inner {@link CallTarget} returned by {@link #getCurrentCallTarget()}. * * @param caller the caller frame * @param arguments the arguments that should be passed to the callee @@ -65,27 +70,63 @@ } /** - * @return true if this {@link CallNode} was already inlined. + * Returns <code>true</code> if the underlying runtime system supports inlining for the + * {@link CallTarget} in this {@link CallNode}. + * + * @return true if inlining is supported. + */ + public abstract boolean isInlinable(); + + /** + * Returns <code>true</code> if the {@link CallTarget} in this {@link CallNode} is inlined. A + * {@link CallNode} can either be inlined manually by invoking {@link #inline()} or by the + * runtime system which may at any point decide to inline. + * + * @return true if this method was inlined else false. */ public abstract boolean isInlined(); + /** + * Enforces the runtime system to inline the {@link CallTarget} at this call site. If the + * runtime system does not support inlining or it is already inlined this method has no effect. + */ public abstract void inline(); + /** + * Returns <code>true</code> if this {@link CallNode} can be split. A {@link CallNode} can only + * be split if the runtime system supports splitting and if the {@link RootNode} contained the + * {@link CallTarget} returns <code>true</code> for {@link RootNode#isSplittable()}. + * + * @return <code>true</code> if the target can be split + */ public abstract boolean isSplittable(); + /** + * Enforces the runtime system to split the {@link CallTarget}. If the {@link CallNode} is not + * splittable this methods has no effect. + */ public abstract boolean split(); + /** + * Returns <code>true</code> if the target of the {@link CallNode} was split. + * + * @return if the target was split + */ public final boolean isSplit() { return getSplitCallTarget() != null; } + /** + * Returns the splitted {@link CallTarget} if this method is split. + * + * @return the split {@link CallTarget} + */ public abstract CallTarget getSplitCallTarget(); /** * Returns the used call target when {@link #call(PackedFrame, Arguments)} is invoked. If the - * {@link CallNode} was split this method returns the {@link CallTarget} returned by - * {@link #getSplitCallTarget()}. If not split this method returns the original supplied - * {@link CallTarget}. + * {@link CallTarget} was split this method returns the {@link CallTarget} returned by + * {@link #getSplitCallTarget()}. * * @return the used {@link CallTarget} when node is called */ @@ -98,6 +139,22 @@ } } + /** + * Returns the {@link RootNode} associated with {@link CallTarget} returned by + * {@link #getCurrentCallTarget()}. If the stored {@link CallTarget} does not contain a + * {@link RootNode} this method returns <code>null</code>. + * + * @see #getCurrentCallTarget() + * @return the root node of the used call target + */ + public final RootNode getCurrentRootNode() { + CallTarget target = getCurrentCallTarget(); + if (target instanceof RootCallTarget) { + return ((RootCallTarget) target).getRootNode(); + } + return null; + } + @Override protected void onReplace(Node newNode, String reason) { super.onReplace(newNode, reason); @@ -114,6 +171,9 @@ registerCallTarget((CallNode) newNode); } + /** + * Internal API for the runtime system. + */ protected static final void registerCallTarget(CallNode newNode) { RootNode newRoot = newNode.getCurrentRootNode(); if (newRoot != null) { @@ -121,51 +181,4 @@ } } - protected void notifyCallNodeAdded() { - - } - - /** - * Returns the {@link RootNode} associated with {@link CallTarget} returned by - * {@link #getCurrentCallTarget()}. - * - * @see #getCurrentCallTarget() - * @return the root node of the used call target - */ - public final RootNode getCurrentRootNode() { - CallTarget target = getCurrentCallTarget(); - if (target instanceof RootCallTarget) { - return ((RootCallTarget) target).getRootNode(); - } - return null; - } - - /** - * @deprecated always returns <code>true</code> now. - */ - @Deprecated - public boolean isInlinable() { - return true; - } - - /** - * @deprecated instead use {@link #getCurrentRootNode()} and check for {@link #isInlined()} for - * true. - */ - @Deprecated - public RootNode getInlinedRoot() { - if (!isInlined()) { - return null; - } - return getCurrentRootNode(); - } - - /** - * @deprecated use {@link TruffleRuntime#createCallNode(CallTarget)} instead - */ - @Deprecated - public static CallNode create(CallTarget target) { - return Truffle.getRuntime().createCallNode(target); - } - }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Mon Mar 17 12:40:35 2014 -0700 @@ -214,7 +214,7 @@ setNodeProperty(node, "name", node.getClass().getSimpleName().replaceFirst("Node$", "")); NodeInfo nodeInfo = node.getClass().getAnnotation(NodeInfo.class); if (nodeInfo != null) { - setNodeProperty(node, "kind", nodeInfo.kind()); + setNodeProperty(node, "cost", nodeInfo.cost()); if (!nodeInfo.shortName().isEmpty()) { setNodeProperty(node, "shortName", nodeInfo.shortName()); }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Mon Mar 17 12:40:35 2014 -0700 @@ -29,7 +29,6 @@ import java.util.*; import com.oracle.truffle.api.*; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; /** * Abstract base class for all Truffle nodes. @@ -82,12 +81,20 @@ this.sourceSection = section; } - public Kind getKind() { + /** + * Returns a rough estimate for the cost of this {@link Node}. This estimate can be used by + * runtime systems or guest languages to implement heuristics based on Truffle ASTs. This method + * is intended to be overridden by subclasses. The default implementation returns the value of + * {@link NodeInfo#cost()} of the {@link NodeInfo} annotation declared at the subclass. If no + * {@link NodeInfo} annotation is declared the method returns {@link NodeCost#MONOMORPHIC} as a + * default value. + */ + public NodeCost getCost() { NodeInfo info = getClass().getAnnotation(NodeInfo.class); if (info != null) { - return info.kind(); + return info.cost(); } - return Kind.SPECIALIZED; + return NodeCost.MONOMORPHIC; } /** @@ -277,61 +284,54 @@ } private void traceRewrite(Node newNode, String reason) { - Class<? extends Node> from = getClass(); - Class<? extends Node> to = newNode.getClass(); - if (TruffleOptions.TraceRewritesFilterFromKind != null) { - if (filterByKind(from, TruffleOptions.TraceRewritesFilterFromKind)) { + if (TruffleOptions.TraceRewritesFilterFromCost != null) { + if (filterByKind(this, TruffleOptions.TraceRewritesFilterFromCost)) { return; } } - if (TruffleOptions.TraceRewritesFilterToKind != null) { - if (filterByKind(to, TruffleOptions.TraceRewritesFilterToKind)) { + if (TruffleOptions.TraceRewritesFilterToCost != null) { + if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) { return; } } String filter = TruffleOptions.TraceRewritesFilterClass; + Class<? extends Node> from = getClass(); + Class<? extends Node> to = newNode.getClass(); if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) { return; } PrintStream out = System.out; - out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s.%n", this.toString(), formatNodeInfo(from), formatNodeInfo(to), reason); + out.printf("[truffle] rewrite %-50s |From %-40s |To %-40s |Reason %s.%n", this.toString(), formatNodeInfo(this), formatNodeInfo(newNode), reason); } - private static String formatNodeInfo(Class<? extends Node> clazz) { - NodeInfo nodeInfo = clazz.getAnnotation(NodeInfo.class); - String kind = "?"; - if (nodeInfo != null) { - switch (nodeInfo.kind()) { - case GENERIC: - kind = "G"; - break; - case SPECIALIZED: - kind = "S"; - break; - case UNINITIALIZED: - kind = "U"; - break; - case POLYMORPHIC: - kind = "P"; - break; - default: - kind = "?"; - break; - } + private static String formatNodeInfo(Node node) { + String cost = "?"; + switch (node.getCost()) { + case NONE: + cost = "G"; + break; + case MONOMORPHIC: + cost = "M"; + break; + case POLYMORPHIC: + cost = "P"; + break; + case MEGAMORPHIC: + cost = "G"; + break; + default: + cost = "?"; + break; } - return kind + " " + clazz.getSimpleName(); + return cost + " " + node.getClass().getSimpleName(); } - private static boolean filterByKind(Class<?> clazz, Kind kind) { - NodeInfo info = clazz.getAnnotation(NodeInfo.class); - if (info != null) { - return info.kind() != kind; - } - return true; + private static boolean filterByKind(Node node, NodeCost cost) { + return node.getCost() == cost; } private static boolean filterByContainsClassName(Class<? extends Node> from, String filter) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCost.java Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,69 @@ +/* + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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.truffle.api.nodes; + +import com.oracle.truffle.api.*; + +/** + * Represents a rough estimate for the cost of a {@link Node}. This estimate can be used by runtime + * systems or guest languages to implement heuristics based on Truffle ASTs. + * + * @see Node#getCost() + */ +public enum NodeCost { + + /** + * This node has literally no costs and should be ignored for heuristics. This is particularly + * useful for wrapper and profiling nodes which should not influence the heuristics. + */ + NONE, + + /** + * This node has a {@link CompilerDirectives#transferToInterpreter()} or + * {@link CompilerDirectives#transferToInterpreterAndInvalidate()} as its first unconditional + * statement. + */ + UNINITIALIZED, + + /** + * This node represents a specialized monomorphic version of an operation. + */ + MONOMORPHIC, + + /** + * This node represents a polymorphic version of an operation. For multiple chained polymorphic + * nodes the first may return {@link #MONOMORPHIC} and all addtional nodes should return + * {@link #POLYMORPHIC}. + */ + POLYMORPHIC, + + /** + * This node represents a megamorphic version of an operation. This value should only be used if + * the operation implementation supports monomorphism and polymorphism otherwise + * {@link #MONOMORPHIC} should be used instead. + */ + MEGAMORPHIC; + +}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java Mon Mar 17 12:40:35 2014 -0700 @@ -40,10 +40,13 @@ */ String shortName() default ""; - Kind kind() default Kind.SPECIALIZED; - - public enum Kind { - UNINITIALIZED, SPECIALIZED, POLYMORPHIC, GENERIC - } + /** + * Provides a rough estimate for the cost of the annotated {@link Node}. This estimate can be + * used by runtime systems or guest languages to implement heuristics based on Truffle ASTs. + * + * @see Node#getCost() + * @see NodeCost + */ + NodeCost cost() default NodeCost.MONOMORPHIC; }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Mon Mar 17 12:40:35 2014 -0700 @@ -34,7 +34,6 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.nodes.Node.Children; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; /** * Utility class that manages the special access methods for node instances. @@ -452,48 +451,6 @@ return null; } - /** - * @deprecated will be removed, exposed Truffle runtime specific functionality. - */ - @Deprecated - public static List<CallTarget> findOutermostCallTargets(Node node) { - RootNode root = node.getRootNode(); - if (root == null) { - return Collections.emptyList(); - } - List<CallTarget> roots = new ArrayList<>(); - roots.add(root.getCallTarget()); - for (CallNode callNode : root.getCachedCallNodes()) { - if (callNode.isInlined()) { - roots.addAll(findOutermostCallTargets(callNode)); - } - } - return roots; - } - - /** - * @deprecated will be removed, exposed Truffle runtime specific functionality. - */ - @Deprecated - public static RootNode findOutermostRootNode(Node node) { - Node parent = node; - while (parent != null) { - if (parent instanceof RootNode) { - RootNode root = (RootNode) parent; - @SuppressWarnings("deprecation") - Node next = root.getParentInlinedCall(); - if (next != null) { - parent = next; - } else { - return root; - } - } else { - parent = parent.getParent(); - } - } - return null; - } - public static <T> T findParent(Node start, Class<T> clazz) { Node parent = start.getParent(); if (parent == null) { @@ -614,39 +571,43 @@ } public static int countNodes(Node root) { - return countNodes(root, null, null, false); + return countNodes(root, null, false); } - public static int countNodes(Node root, Class<?> clazz, Kind nodeKind, boolean countInlinedCallNodes) { - NodeCountVisitor nodeCount = new NodeCountVisitor(clazz, nodeKind, countInlinedCallNodes); + public static int countNodes(Node root, NodeCountFilter filter) { + return countNodes(root, filter, false); + } + + public static int countNodes(Node root, NodeCountFilter filter, boolean visitInlinedCallNodes) { + NodeCountVisitor nodeCount = new NodeCountVisitor(filter, visitInlinedCallNodes); root.accept(nodeCount); return nodeCount.nodeCount; } - public static int countNodes(Node root, Class<?> clazz, boolean countInlinedCallNodes) { - return countNodes(root, clazz, null, countInlinedCallNodes); + public interface NodeCountFilter { + + boolean isCounted(Node node); + } private static final class NodeCountVisitor implements NodeVisitor { - private final boolean inspectInlinedCalls; + private final boolean visitInlinedCallNodes; int nodeCount; - private final Kind kind; - private final Class<?> clazz; + private final NodeCountFilter filter; - private NodeCountVisitor(Class<?> clazz, Kind kind, boolean inspectInlinedCalls) { - this.clazz = clazz; - this.kind = kind; - this.inspectInlinedCalls = inspectInlinedCalls; + private NodeCountVisitor(NodeCountFilter filter, boolean visitInlinedCallNodes) { + this.filter = filter; + this.visitInlinedCallNodes = visitInlinedCallNodes; } @Override public boolean visit(Node node) { - if ((clazz == null || clazz.isInstance(node)) && (kind == null || isKind(node))) { + if (filter == null || filter.isCounted(node)) { nodeCount++; } - if (inspectInlinedCalls && node instanceof CallNode) { + if (visitInlinedCallNodes && node instanceof CallNode) { CallNode call = (CallNode) node; if (call.isInlined()) { Node target = ((RootCallTarget) call.getCurrentCallTarget()).getRootNode(); @@ -659,9 +620,6 @@ return true; } - private boolean isKind(Node n) { - return kind == n.getKind(); - } } public static void printInliningTree(final PrintStream stream, RootNode root) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Mon Mar 17 12:40:35 2014 -0700 @@ -36,7 +36,7 @@ */ public abstract class RootNode extends Node { - private CallTarget callTarget; + private RootCallTarget callTarget; private final FrameDescriptor frameDescriptor; /* @@ -62,36 +62,24 @@ } /** - * @deprecated Not required anymore. Do not use. + * Creates a split {@link RootNode} based on the current {@link RootNode}. This method should + * return an AST that was never executed and must not be shared with other {@link RootNode} or + * {@link CallTarget} instances. This method is intended to be overridden by a subclass. + * + * @return the split {@link RootNode} */ - @Deprecated - public RootNode inline() { - if (!isInlinable()) { - throw new UnsupportedOperationException("Inlining is not enabled."); - } - return split(); + public RootNode split() { + throw new UnsupportedOperationException(); } /** - * @deprecated Not required anymore. Do not use. - */ - @Deprecated - public int getInlineNodeCount() { - return 0; - } - - /** - * @deprecated Not required anymore. Do not use. + * Returns <code>true</code> if this {@link RootNode} can be split. A {@link RootNode} can be + * split inside of a {@link CallTarget} that is invoked using a {@link CallNode}. If this method + * returns <code>true</code> a proper implementation of {@link #split()} must also be provided. + * This method is intended to be overridden by a subclass. + * + * @return <code>true</code> if splittable else <code>false</code>. */ - @Deprecated - public boolean isInlinable() { - return true; - } - - public RootNode split() { - return NodeUtil.cloneNode(this); - } - public boolean isSplittable() { return false; } @@ -100,7 +88,7 @@ * Reports the execution count of a loop that is a child of this node. The optimization * heuristics can use the loop count to guide compilation and inlining. */ - public void reportLoopCount(int count) { + public final void reportLoopCount(int count) { if (getCallTarget() instanceof LoopCountReceiver) { ((LoopCountReceiver) getCallTarget()).reportLoopCount(count); } @@ -114,7 +102,7 @@ */ public abstract Object execute(VirtualFrame frame); - public CallTarget getCallTarget() { + public final RootCallTarget getCallTarget() { return callTarget; } @@ -122,17 +110,17 @@ return frameDescriptor; } - public final void setCallTarget(CallTarget callTarget) { + public final void setCallTarget(RootCallTarget callTarget) { this.callTarget = callTarget; } /* Internal API. Do not use. */ - void addCachedCallNode(CallNode callSite) { + final void addCachedCallNode(CallNode callSite) { this.cachedCallNodes.add(callSite); } /* Internal API. Do not use. */ - void removeCachedCallNode(CallNode callSite) { + final void removeCachedCallNode(CallNode callSite) { this.cachedCallNodes.remove(callSite); } @@ -148,11 +136,4 @@ return Collections.unmodifiableSet(cachedCallNodes); } - /** - * @deprecated use {@link #getCachedCallNodes()} instead. - */ - @Deprecated - public final CallNode getParentInlinedCall() { - return cachedCallNodes.isEmpty() ? null : cachedCallNodes.iterator().next(); - } }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Mon Mar 17 12:40:35 2014 -0700 @@ -52,7 +52,7 @@ private final DeclaredType childAnnotation; private final DeclaredType childrenAnnotation; private final DeclaredType nodeInfoAnnotation; - private final DeclaredType nodeInfoKind; + private final DeclaredType nodeCost; private final TypeMirror compilerDirectives; private final TypeMirror compilerAsserts; private final DeclaredType slowPath; @@ -75,7 +75,7 @@ assumption = getRequired(context, Assumption.class); invalidAssumption = getRequired(context, InvalidAssumptionException.class); nodeInfoAnnotation = getRequired(context, NodeInfo.class); - nodeInfoKind = getRequired(context, NodeInfo.Kind.class); + nodeCost = getRequired(context, NodeCost.class); slowPath = getRequired(context, SlowPath.class); sourceSection = getRequired(context, SourceSection.class); truffleOptions = getRequired(context, TruffleOptions.class); @@ -107,8 +107,8 @@ return false; } - public DeclaredType getNodeInfoKind() { - return nodeInfoKind; + public DeclaredType getNodeCost() { + return nodeCost; } private DeclaredType getRequired(ProcessorContext context, Class clazz) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java Mon Mar 17 12:40:35 2014 -0700 @@ -267,11 +267,9 @@ if (parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) { write(f.getSimpleName()); if (init != null) { - if (init != null) { - write("("); - init.acceptCodeElementScanner(this, p); - write(")"); - } + write("("); + init.acceptCodeElementScanner(this, p); + write(")"); } } else { Element enclosing = f.getEnclosingElement();
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Mon Mar 17 12:39:25 2014 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Mon Mar 17 12:40:35 2014 -0700 @@ -32,7 +32,6 @@ import javax.lang.model.util.*; import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.NodeInfo.Kind; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.ast.*; @@ -223,7 +222,6 @@ } } ActualParameter sourceParameter = sourceMethod.findParameter(parameter.getLocalName()); - assert parameter != null; if (castedValues && sourceParameter != null) { builder.string(valueName(sourceParameter, parameter)); @@ -954,28 +952,28 @@ clazz.add(createGenericExecute(node, rootGroup)); } - clazz.add(createGetKind(node, null, Kind.SPECIALIZED)); + clazz.add(createGetCost(node, null, NodeCost.MONOMORPHIC)); } protected boolean needsInvokeCopyConstructorMethod() { return getModel().getNode().isPolymorphic(); } - protected CodeExecutableElement createGetKind(NodeData node, SpecializationData specialization, Kind kind) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeInfoKind(), "getKind"); - - TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeInfoKind(); + protected CodeExecutableElement createGetCost(NodeData node, SpecializationData specialization, NodeCost cost) { + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeCost(), "getCost"); + + TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeCost(); CodeTreeBuilder builder = method.createBuilder(); if (node.isPolymorphic() && specialization == null) { // assume next0 exists - builder.startIf().string("next0 != null && next0.getKind() == ").staticReference(nodeInfoKind, "SPECIALIZED").end(); + builder.startIf().string("next0 != null && next0.getCost() == ").staticReference(nodeInfoKind, "MONOMORPHIC").end(); builder.startBlock(); builder.startReturn().staticReference(nodeInfoKind, "POLYMORPHIC").end(); builder.end(); } - builder.startReturn().staticReference(nodeInfoKind, kind.name()).end(); + builder.startReturn().staticReference(nodeInfoKind, cost.name()).end(); return method; } @@ -2476,7 +2474,7 @@ } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); - clazz.getAnnotationMirrors().add(createNodeInfo(node, Kind.POLYMORPHIC)); + clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.NONE)); for (ActualParameter polymorphParameter : polymorph.getSignatureParameters()) { if (!polymorphParameter.getTypeSystemType().isGeneric()) { @@ -2523,7 +2521,7 @@ } createCachedExecuteMethods(specialization); - clazz.add(createGetKind(specialization.getNode(), specialization, Kind.SPECIALIZED)); + clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.NONE)); } private ExecutableElement createUpdateType(ActualParameter parameter) { @@ -2563,34 +2561,34 @@ } CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false); - Kind kind; + NodeCost cost; if (specialization.isGeneric()) { - kind = Kind.GENERIC; + cost = NodeCost.MEGAMORPHIC; } else if (specialization.isUninitialized()) { - kind = Kind.UNINITIALIZED; + cost = NodeCost.UNINITIALIZED; } else if (specialization.isPolymorphic()) { - kind = Kind.POLYMORPHIC; + cost = NodeCost.NONE; } else if (specialization.isSpecialized()) { - kind = Kind.SPECIALIZED; + cost = NodeCost.MONOMORPHIC; } else { throw new AssertionError(); } - clazz.getAnnotationMirrors().add(createNodeInfo(node, kind)); + clazz.getAnnotationMirrors().add(createNodeInfo(node, cost)); return clazz; } - protected CodeAnnotationMirror createNodeInfo(NodeData node, Kind kind) { + protected CodeAnnotationMirror createNodeInfo(NodeData node, NodeCost cost) { String shortName = node.getShortName(); CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation()); if (shortName != null) { nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName)); } - DeclaredType nodeinfoKind = getContext().getTruffleTypes().getNodeInfoKind(); - VariableElement varKind = Utils.findVariableElement(nodeinfoKind, kind.name()); - - nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("kind"), new CodeAnnotationValue(varKind)); + DeclaredType nodeinfoCost = getContext().getTruffleTypes().getNodeCost(); + VariableElement varKind = Utils.findVariableElement(nodeinfoCost, cost.name()); + + nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("cost"), new CodeAnnotationValue(varKind)); return nodeInfoMirror; } @@ -2609,9 +2607,9 @@ } if (specialization.isGeneric()) { - clazz.add(createGetKind(specialization.getNode(), specialization, Kind.GENERIC)); + clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.MEGAMORPHIC)); } else if (specialization.isUninitialized()) { - clazz.add(createGetKind(specialization.getNode(), specialization, Kind.UNINITIALIZED)); + clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.UNINITIALIZED)); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/findbugsExcludeFilter.xml Mon Mar 17 12:40:35 2014 -0700 @@ -0,0 +1,41 @@ +<FindBugsFilter> + + <Match> + <Class name="com.oracle.graal.hotspot.CompilationTask" /> + <Method name="run" /> + <Bug pattern="NN_NAKED_NOTIFY" /> + </Match> + + <!-- justification = "concurrent abstraction calls are in synchronized block" --> + <Match> + <Class name="com.oracle.graal.hotspot.debug.BenchmarkCounters" /> + <Method name="getIndex" /> + <Bug pattern="AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION" /> + </Match> + + <!-- justification = "counters are only used for statistics" --> + <Match> + <Class name="com.oracle.graal.hotspot.meta.HotSpotGraphCache" /> + <Or> + <Method name="get" /> + <Method name="put" /> + <Method name="removeGraphs" /> + </Or> + <Bug pattern="VO_VOLATILE_INCREMENT" /> + </Match> + + <!-- justification = "reference equality on the receiver is what we want" --> + <Match> + <Class name="com.oracle.graal.replacements.StringSubstitutions" /> + <Method name="equals" /> + <Bug pattern="ES_COMPARING_PARAMETER_STRING_WITH_EQ" /> + </Match> + + <!-- justification = "reference equality to test whether string is interned" --> + <Match> + <Class name="com.oracle.graal.hotspot.phases.AheadOfTimeVerificationPhase" /> + <Method name="isInternedString" /> + <Bug pattern="ES_COMPARING_STRINGS_WITH_EQ" /> + </Match> + +</FindBugsFilter>
--- a/mx/mx_graal.py Mon Mar 17 12:39:25 2014 -0700 +++ b/mx/mx_graal.py Mon Mar 17 12:40:35 2014 -0700 @@ -1638,6 +1638,38 @@ valueMap = parser.parse(output.getvalue()) return valueMap +def findbugs(args): + '''run FindBugs against non-test Java projects''' + findBugsHome = mx.get_env('FINDBUGS_HOME', None) + if findBugsHome: + findbugsJar = join(findBugsHome, 'lib', 'findbugs.jar') + else: + findbugsLib = join(_graal_home, 'lib', 'findbugs-3.0.0') + if not exists(findbugsLib): + tmp = tempfile.mkdtemp(prefix='findbugs-download-tmp', dir=_graal_home) + try: + findbugsDist = join(tmp, 'findbugs.zip') + mx.download(findbugsDist, ['http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0-dev-20131204-e3cbbd5.zip']) + with zipfile.ZipFile(findbugsDist) as zf: + candidates = [e for e in zf.namelist() if e.endswith('/lib/findbugs.jar')] + assert len(candidates) == 1, candidates + libDirInZip = os.path.dirname(candidates[0]) + zf.extractall(tmp) + shutil.copytree(join(tmp, libDirInZip), findbugsLib) + finally: + shutil.rmtree(tmp) + findbugsJar = join(findbugsLib, 'findbugs.jar') + assert exists(findbugsJar) + nonTestProjects = [p for p in mx.projects() if not p.name.endswith('.test') and not p.name.endswith('.jtt')] + outputDirs = [p.output_dir() for p in nonTestProjects] + findbugsResults = join(_graal_home, 'findbugs.results') + exitcode = mx.run_java(['-jar', findbugsJar, '-textui', '-low', '-maxRank', '15', '-exclude', join(_graal_home, 'graal', 'findbugsExcludeFilter.xml'), + '-auxclasspath', mx.classpath([p.name for p in nonTestProjects]), '-output', findbugsResults, '-progress', '-exitcode'] + args + outputDirs, nonZeroIsFatal=False) + if exitcode != 0: + with open(findbugsResults) as fp: + mx.log(fp.read()) + os.unlink(findbugsResults) + return exitcode def mx_init(suite): commands = { @@ -1646,6 +1678,7 @@ 'buildvms': [buildvms, '[-options]'], 'c1visualizer' : [c1visualizer, ''], 'clean': [clean, ''], + 'findbugs': [findbugs, ''], 'generateZshCompletion' : [generateZshCompletion, ''], 'hsdis': [hsdis, '[att]'], 'hcfdis': [hcfdis, ''],
--- a/mx/projects Mon Mar 17 12:39:25 2014 -0700 +++ b/mx/projects Mon Mar 17 12:40:35 2014 -0700 @@ -13,9 +13,6 @@ library@CHECKSTYLE@path=lib/checkstyle-5.5-all.jar library@CHECKSTYLE@urls=jar:http://sourceforge.net/projects/checkstyle/files/checkstyle/5.5/checkstyle-5.5-bin.zip/download!/checkstyle-5.5/checkstyle-5.5-all.jar -library@FINDBUGS@path=lib/findbugs-3.0.0-dev-20131204-e3cbbd5.jar -library@FINDBUGS@urls=jar:http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0-dev-20131204-e3cbbd5.zip/download!/findbugs-3.0.0-dev-20131204-e3cbbd5/lib/findbugs.jar - library@DACAPO@path=lib/dacapo-9.12-bach.jar library@DACAPO@urls=http://softlayer.dl.sourceforge.net/project/dacapobench/9.12-bach/dacapo-9.12-bach.jar @@ -498,7 +495,7 @@ # graal.java.decompiler.test project@com.oracle.graal.java.decompiler.test@subDir=graal project@com.oracle.graal.java.decompiler.test@sourceDirs=src -project@com.oracle.graal.java.decompiler.test@dependencies=com.oracle.graal.printer,com.oracle.graal.runtime +project@com.oracle.graal.java.decompiler.test@dependencies=JUNIT,com.oracle.graal.printer,com.oracle.graal.runtime project@com.oracle.graal.java.decompiler.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.java.decompiler.test@javaCompliance=1.7 project@com.oracle.graal.java.decompiler.test@workingSets=Graal,Test
--- a/mxtool/mx.py Mon Mar 17 12:39:25 2014 -0700 +++ b/mxtool/mx.py Mon Mar 17 12:40:35 2014 -0700 @@ -1894,10 +1894,13 @@ abort('Could not find Eclipse executable. Use -e option or ensure ECLIPSE_EXE environment variable is set.') # Maybe an Eclipse installation dir was specified - look for the executable in it - if join(args.eclipse_exe, exe_suffix('eclipse')): + if isdir(args.eclipse_exe): args.eclipse_exe = join(args.eclipse_exe, exe_suffix('eclipse')) - - if not os.path.isfile(args.eclipse_exe) or not os.access(args.eclipse_exe, os.X_OK): + warn("The eclipse-exe was a directory, now using " + args.eclipse_exe) + + if not os.path.isfile(args.eclipse_exe): + abort('File does not exist: ' + args.eclipse_exe) + if not os.access(args.eclipse_exe, os.X_OK): abort('Not an executable file: ' + args.eclipse_exe) eclipseinit([], buildProcessorJars=False)
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -41,55 +41,32 @@ } } -inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { - oop inlineData = CompilationResult_DataPatch::inlineData(site); - address pc = _instructions->start() + pc_offset; +inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { + if (OopData::compressed(obj)) { + fatal("unimplemented: narrow oop relocation"); + } else { + address pc = _instructions->start() + pc_offset; + Handle obj = OopData::object(data); + jobject value = JNIHandles::make_local(obj()); - if (inlineData != NULL) { - oop kind = Constant::kind(inlineData); - char typeChar = Kind::typeChar(kind); + NativeMovConstReg* move = nativeMovConstReg_at(pc); + move->set_data((intptr_t) value); - switch (typeChar) { - case 'z': - case 'b': - case 's': - case 'c': - case 'i': - fatal("int-sized values not expected in DataPatch"); - break; - case 'f': - case 'j': - case 'd': { - NativeMovConstReg* move = nativeMovConstReg_at(pc); - uint64_t value = Constant::primitive(inlineData); - move->set_data(value); - break; - } - case 'a': { - NativeMovConstReg* move = nativeMovConstReg_at(pc); - Handle obj = Constant::object(inlineData); - jobject value = JNIHandles::make_local(obj()); - move->set_data((intptr_t) value); + // We need two relocations: one on the sethi and one on the add. + int oop_index = _oop_recorder->find_index(value); + RelocationHolder rspec = oop_Relocation::spec(oop_index); + _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); + _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); + } +} - // We need two relocations: one on the sethi and one on the add. - int oop_index = _oop_recorder->find_index(value); - RelocationHolder rspec = oop_Relocation::spec(oop_index); - _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec); - _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec); - break; - } - default: - fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); - break; - } - } else { - oop dataRef = CompilationResult_DataPatch::externalData(site); - jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef); +inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + jint offset = DataSectionReference::offset(data); - NativeMovRegMem* load = nativeMovRegMem_at(pc); - int disp = _constants_size + pc_offset - offset - BytesPerInstWord; - load->set_offset(-disp); - } + NativeMovRegMem* load = nativeMovRegMem_at(pc); + int disp = _constants_size + pc_offset - offset - BytesPerInstWord; + load->set_offset(-disp); } inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -59,68 +59,49 @@ } } -inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) { - oop inlineData = CompilationResult_DataPatch::inlineData(site); +inline bool check_metaspace_data(address pc, oop data) { + jlong value = MetaspaceData::value(data); + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); + if (MetaspaceData::compressed(data)) { + assert(*((jint*) operand) == value, err_msg("wrong compressed metaspace pointer: %p != %p", *((jint*) operand), value)); + } else { + assert(*((jlong*) operand) == value, err_msg("wrong metaspace pointer: %p != %p", *((jlong*) operand), value)); + } + return true; +} + +inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) { address pc = _instructions->start() + pc_offset; - if (inlineData != NULL) { - oop kind = Constant::kind(inlineData); - char typeChar = Kind::typeChar(kind); - - switch (typeChar) { - case 'z': - case 'b': - case 's': - case 'c': - case 'i': - fatal("int-sized values not expected in DataPatch"); - break; - case 'n': { - address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); - Handle obj = Constant::object(inlineData); + Handle obj = OopData::object(data); + jobject value = JNIHandles::make_local(obj()); + if (OopData::compressed(data)) { + address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand); + int oop_index = _oop_recorder->find_index(value); + _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); + TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand); + } else { + address operand = Assembler::locate_operand(pc, Assembler::imm_operand); + *((jobject*) operand) = value; + _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); + TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand); + } +} - jobject value = JNIHandles::make_local(obj()); - int oop_index = _oop_recorder->find_index(value); - _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand); - TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand); - break; - } - case 'f': - case 'j': - case 'd': - case '*': { - address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - *((jlong*) operand) = Constant::primitive(inlineData); - break; - } - case 'a': { - address operand = Assembler::locate_operand(pc, Assembler::imm_operand); - Handle obj = Constant::object(inlineData); +inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) { + address pc = _instructions->start() + pc_offset; + jint offset = DataSectionReference::offset(data); - jobject value = JNIHandles::make_local(obj()); - *((jobject*) operand) = value; - _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand); - break; - } - default: - fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar)); - break; - } - } else { - oop dataRef = CompilationResult_DataPatch::externalData(site); - jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef); - address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); - address next_instruction = Assembler::locate_next_instruction(pc); - address dest = _constants->start() + offset; + address operand = Assembler::locate_operand(pc, Assembler::disp32_operand); + address next_instruction = Assembler::locate_next_instruction(pc); + address dest = _constants->start() + offset; - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*) operand) = (jint) disp; + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*) operand) = (jint) disp; - _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); - TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset); - } + _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand); + TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset); } inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/share/vm/classfile/systemDictionary.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -187,12 +187,15 @@ do_klass(BitSet_klass, java_util_BitSet, Opt) \ /* graal.hotspot */ \ do_klass(HotSpotCompiledCode_klass, com_oracle_graal_hotspot_HotSpotCompiledCode, Opt) \ - do_klass(HotSpotCompiledCode_HotSpotData_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData, Opt) \ - do_klass(HotSpotCompiledCode_DataSection_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection, Opt) \ do_klass(HotSpotCompiledCode_Comment_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, Opt) \ do_klass(HotSpotCompiledNmethod_klass, com_oracle_graal_hotspot_HotSpotCompiledNmethod, Opt) \ do_klass(HotSpotCompiledRuntimeStub_klass, com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, Opt) \ do_klass(HotSpotForeignCallLinkage_klass, com_oracle_graal_hotspot_HotSpotForeignCallLinkage, Opt) \ + do_klass(HotSpotReferenceMap_klass, com_oracle_graal_hotspot_HotSpotReferenceMap, Opt) \ + do_klass(DataSection_klass, com_oracle_graal_hotspot_data_DataSection, Opt) \ + do_klass(DataSectionReference_klass, com_oracle_graal_hotspot_data_DataSectionReference, Opt) \ + do_klass(MetaspaceData_klass, com_oracle_graal_hotspot_data_MetaspaceData, Opt) \ + do_klass(OopData_klass, com_oracle_graal_hotspot_data_OopData, Opt) \ do_klass(HotSpotCodeInfo_klass, com_oracle_graal_hotspot_meta_HotSpotCodeInfo, Opt) \ do_klass(HotSpotInstalledCode_klass, com_oracle_graal_hotspot_meta_HotSpotInstalledCode, Opt) \ do_klass(HotSpotNmethod_klass, com_oracle_graal_hotspot_meta_HotSpotNmethod, Opt) \ @@ -210,7 +213,6 @@ do_klass(Assumptions_CallSiteTargetValue_klass, com_oracle_graal_api_code_Assumptions_CallSiteTargetValue, Opt) \ do_klass(BytecodePosition_klass, com_oracle_graal_api_code_BytecodePosition, Opt) \ do_klass(DebugInfo_klass, com_oracle_graal_api_code_DebugInfo, Opt) \ - do_klass(ReferenceMap_klass, com_oracle_graal_api_code_ReferenceMap, Opt) \ do_klass(RegisterSaveLayout_klass, com_oracle_graal_api_code_RegisterSaveLayout, Opt) \ do_klass(BytecodeFrame_klass, com_oracle_graal_api_code_BytecodeFrame, Opt) \ do_klass(CompilationResult_klass, com_oracle_graal_api_code_CompilationResult, Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -296,14 +296,17 @@ template(com_oracle_graal_hotspot_HotSpotKlassOop, "com/oracle/graal/hotspot/HotSpotKlassOop") \ template(com_oracle_graal_hotspot_HotSpotOptions, "com/oracle/graal/hotspot/HotSpotOptions") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode, "com/oracle/graal/hotspot/HotSpotCompiledCode") \ - template(com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData, "com/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData") \ - template(com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection, "com/oracle/graal/hotspot/HotSpotCompiledCode$DataSection") \ template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment, "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment") \ template(com_oracle_graal_hotspot_HotSpotCompiledNmethod, "com/oracle/graal/hotspot/HotSpotCompiledNmethod") \ template(com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub, "com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub") \ template(com_oracle_graal_hotspot_HotSpotForeignCallLinkage, "com/oracle/graal/hotspot/HotSpotForeignCallLinkage") \ + template(com_oracle_graal_hotspot_HotSpotReferenceMap, "com/oracle/graal/hotspot/HotSpotReferenceMap") \ template(com_oracle_graal_hotspot_bridge_VMToCompiler, "com/oracle/graal/hotspot/bridge/VMToCompiler") \ template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl, "com/oracle/graal/hotspot/bridge/CompilerToVMImpl") \ + template(com_oracle_graal_hotspot_data_DataSection, "com/oracle/graal/hotspot/data/DataSection") \ + template(com_oracle_graal_hotspot_data_DataSectionReference, "com/oracle/graal/hotspot/data/DataSectionReference") \ + template(com_oracle_graal_hotspot_data_MetaspaceData, "com/oracle/graal/hotspot/data/MetaspaceData") \ + template(com_oracle_graal_hotspot_data_OopData, "com/oracle/graal/hotspot/data/OopData") \ template(com_oracle_graal_hotspot_meta_HotSpotCodeInfo, "com/oracle/graal/hotspot/meta/HotSpotCodeInfo") \ template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode, "com/oracle/graal/hotspot/meta/HotSpotInstalledCode") \ template(com_oracle_graal_hotspot_meta_HotSpotNmethod, "com/oracle/graal/hotspot/meta/HotSpotNmethod") \ @@ -340,7 +343,6 @@ template(com_oracle_graal_api_code_BytecodeFrame, "com/oracle/graal/api/code/BytecodeFrame") \ template(com_oracle_graal_api_code_BytecodePosition, "com/oracle/graal/api/code/BytecodePosition") \ template(com_oracle_graal_api_code_DebugInfo, "com/oracle/graal/api/code/DebugInfo") \ - template(com_oracle_graal_api_code_ReferenceMap, "com/oracle/graal/api/code/ReferenceMap") \ template(com_oracle_graal_api_code_Register, "com/oracle/graal/api/code/Register") \ template(com_oracle_graal_api_code_RegisterValue, "com/oracle/graal/api/code/RegisterValue") \ template(com_oracle_graal_api_code_StackSlot, "com/oracle/graal/api/code/StackSlot") \
--- a/src/share/vm/code/nmethod.cpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/code/nmethod.cpp Mon Mar 17 12:40:35 2014 -0700 @@ -1025,6 +1025,7 @@ void nmethod::print_on(outputStream* st, const char* msg) const { if (st != NULL) { ttyLocker ttyl; + if (CIPrintCompilerName) st->print("%s:", compiler()->name()); if (WizardMode) { CompileTask::print_compilation(st, this, msg, /*short_form:*/ true); st->print_cr(" (" INTPTR_FORMAT ")", this);
--- a/src/share/vm/graal/graalCodeInstaller.cpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Mon Mar 17 12:40:35 2014 -0700 @@ -91,8 +91,8 @@ static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) { OopMap* map = new OopMap(total_frame_size, parameter_count); oop reference_map = DebugInfo::referenceMap(debug_info); - oop register_map = ReferenceMap::registerRefMap(reference_map); - oop frame_map = ReferenceMap::frameRefMap(reference_map); + oop register_map = HotSpotReferenceMap::registerRefMap(reference_map); + oop frame_map = HotSpotReferenceMap::frameRefMap(reference_map); oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info); if (register_map != NULL) { @@ -157,6 +157,27 @@ return map; } +static void record_metadata_reference(oop obj, jlong prim, bool compressed, OopRecorder* oop_recorder) { + if (obj->is_a(HotSpotResolvedObjectType::klass())) { + Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj)); + if (compressed) { + assert(Klass::decode_klass((narrowKlass) prim) == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim)); + } else { + assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim)); + } + int index = oop_recorder->find_index(klass); + TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string()); + } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) { + Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj); + assert(!compressed, err_msg("unexpected compressed method pointer %s @ %p = %p", method->name()->as_C_string(), method, prim)); + int index = oop_recorder->find_index(method); + TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string()); + } else { + assert(java_lang_String::is_instance(obj), + err_msg("unexpected metadata reference (%s) for constant %ld (%p)", obj->klass()->name()->as_C_string(), prim, prim)); + } +} + // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()). static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) { char kind = Kind::typeChar(Constant::kind(constant)); @@ -165,23 +186,15 @@ oop obj = Constant::object(constant); jlong prim = Constant::primitive(constant); if (obj != NULL) { - if (obj->is_a(HotSpotResolvedObjectType::klass())) { - Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj)); - assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim)); - int index = oop_recorder->find_index(klass); - TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string()); - } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) { - Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj); - int index = oop_recorder->find_index(method); - TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string()); - } else { - assert(java_lang_String::is_instance(obj), - err_msg("unexpected annotation type (%s) for constant %ld (%p) of kind %c", obj->klass()->name()->as_C_string(), prim, prim, kind)); - } + record_metadata_reference(obj, prim, false, oop_recorder); } } } +static void record_metadata_in_patch(oop data, OopRecorder* oop_recorder) { + record_metadata_reference(MetaspaceData::annotation(data), MetaspaceData::value(data), MetaspaceData::compressed(data), oop_recorder); +} + ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) { second = NULL; if (value == Value::ILLEGAL()) { @@ -445,8 +458,8 @@ // Pre-calculate the constants section size. This is required for PC-relative addressing. _dataSection = HotSpotCompiledCode::dataSection(compiled_code); - guarantee(HotSpotCompiledCode_DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); - arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection); + guarantee(DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); + arrayOop data = (arrayOop) DataSection::data(_dataSection); _constants_size = data->length(); if (_constants_size > 0) { _constants_size = align_size_up(_constants_size, _constants->alignment()); @@ -482,30 +495,24 @@ // copy the constant data into the newly created CodeBuffer address end_data = _constants->start() + _constants_size; - arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection); + arrayOop data = (arrayOop) DataSection::data(_dataSection); memcpy(_constants->start(), data->base(T_BYTE), data->length()); _constants->set_end(end_data); - objArrayOop patches = (objArrayOop) HotSpotCompiledCode_DataSection::patches(_dataSection); + objArrayOop patches = (objArrayOop) DataSection::patches(_dataSection); for (int i = 0; i < patches->length(); i++) { oop patch = patches->obj_at(i); - oop constant = HotSpotCompiledCode_HotSpotData::constant(patch); - oop kind = Constant::kind(constant); - char typeChar = Kind::typeChar(kind); - switch (typeChar) { - case 'f': - case 'j': - case 'd': - record_metadata_in_constant(constant, _oop_recorder); - break; - case 'a': - Handle obj = Constant::object(constant); - jobject value = JNIHandles::make_local(obj()); - int oop_index = _oop_recorder->find_index(value); + oop data = CompilationResult_DataPatch::data(patch); + if (data->is_a(MetaspaceData::klass())) { + record_metadata_in_patch(data, _oop_recorder); + } else if (data->is_a(OopData::klass())) { + Handle obj = OopData::object(data); + jobject value = JNIHandles::make_local(obj()); + int oop_index = _oop_recorder->find_index(value); - address dest = _constants->start() + HotSpotCompiledCode_HotSpotData::offset(patch); - _constants->relocate(dest, oop_Relocation::spec(oop_index)); - break; + address dest = _constants->start() + CompilationResult_Site::pcOffset(patch); + assert(!OopData::compressed(data), err_msg("unexpected compressed oop in data section")); + _constants->relocate(dest, oop_Relocation::spec(oop_index)); } } @@ -777,19 +784,16 @@ } void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) { - oop inlineData = CompilationResult_DataPatch::inlineData(site); - if (inlineData != NULL) { - oop kind = Constant::kind(inlineData); - char typeChar = Kind::typeChar(kind); - switch (typeChar) { - case 'f': - case 'j': - case 'd': - record_metadata_in_constant(inlineData, _oop_recorder); - break; - } + oop data = CompilationResult_DataPatch::data(site); + if (data->is_a(MetaspaceData::klass())) { + record_metadata_in_patch(data, _oop_recorder); + } else if (data->is_a(OopData::klass())) { + pd_patch_OopData(pc_offset, data); + } else if (data->is_a(DataSectionReference::klass())) { + pd_patch_DataSectionReference(pc_offset, data); + } else { + fatal("unknown data patch type"); } - CodeInstaller::pd_site_DataPatch(pc_offset, site); } void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
--- a/src/share/vm/graal/graalCodeInstaller.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -77,7 +77,8 @@ ExceptionHandlerTable _exception_handler_table; jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method); - void pd_site_DataPatch(int pc_offset, oop site); + void pd_patch_OopData(int pc_offset, oop data); + void pd_patch_DataSectionReference(int pc_offset, oop data); void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst); void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination); void pd_relocate_JavaMethod(oop method, jint pc_offset);
--- a/src/share/vm/graal/graalCompilerToVM.cpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Mar 17 12:40:35 2014 -0700 @@ -348,11 +348,6 @@ return CompilerOracle::should_inline(method) || method->force_inline(); C2V_END -C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method)) - nmethod* code = (asMethod(metaspace_method))->code(); - return code == NULL ? 0 : code->insts_size(); -C2V_END - C2V_VMENTRY(jlong, lookupType, (JNIEnv *env, jobject, jstring jname, jclass accessing_class, jboolean resolve)) ResourceMark rm; Handle name = JNIHandles::resolve(jname); @@ -814,7 +809,6 @@ {CC"doNotInlineOrCompile", CC"("METASPACE_METHOD")V", FN_PTR(doNotInlineOrCompile)}, {CC"canInlineMethod", CC"("METASPACE_METHOD")Z", FN_PTR(canInlineMethod)}, {CC"shouldInlineMethod", CC"("METASPACE_METHOD")Z", FN_PTR(shouldInlineMethod)}, - {CC"getCompiledCodeSize", CC"("METASPACE_METHOD")I", FN_PTR(getCompiledCodeSize)}, {CC"lookupType", CC"("STRING CLASS"Z)"METASPACE_KLASS, FN_PTR(lookupType)}, {CC"resolveConstantInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(resolveConstantInPool)}, {CC"resolvePossiblyCachedConstantInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(resolvePossiblyCachedConstantInPool)},
--- a/src/share/vm/graal/graalJavaAccess.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/graal/graalJavaAccess.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -79,16 +79,7 @@ oop_field(HotSpotCompiledCode, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;") \ oop_field(HotSpotCompiledCode, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;") \ oop_field(HotSpotCompiledCode, comments, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$Comment;") \ - oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/HotSpotCompiledCode$DataSection;") \ - end_class \ - start_class(HotSpotCompiledCode_HotSpotData) \ - int_field(HotSpotCompiledCode_HotSpotData, offset) \ - oop_field(HotSpotCompiledCode_HotSpotData, constant, "Lcom/oracle/graal/api/meta/Constant;") \ - end_class \ - start_class(HotSpotCompiledCode_DataSection) \ - int_field(HotSpotCompiledCode_DataSection, sectionAlignment) \ - oop_field(HotSpotCompiledCode_DataSection, data, "[B") \ - oop_field(HotSpotCompiledCode_DataSection, patches, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData;") \ + oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/data/DataSection;") \ end_class \ start_class(HotSpotCompiledCode_Comment) \ oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \ @@ -97,7 +88,7 @@ start_class(HotSpotCompiledNmethod) \ oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \ int_field(HotSpotCompiledNmethod, entryBCI) \ - int_field(HotSpotCompiledNmethod, id) \ + int_field(HotSpotCompiledNmethod, id) \ end_class \ start_class(HotSpotCompiledRuntimeStub) \ oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;") \ @@ -105,6 +96,23 @@ start_class(HotSpotForeignCallLinkage) \ long_field(HotSpotForeignCallLinkage, address) \ end_class \ + start_class(DataSection) \ + int_field(DataSection, sectionAlignment) \ + oop_field(DataSection, data, "[B") \ + oop_field(DataSection, patches, "[Lcom/oracle/graal/api/code/CompilationResult$DataPatch;") \ + end_class \ + start_class(DataSectionReference) \ + int_field(DataSectionReference, offset) \ + end_class \ + start_class(MetaspaceData) \ + long_field(MetaspaceData, value) \ + oop_field(MetaspaceData, annotation, "Ljava/lang/Object;") \ + boolean_field(MetaspaceData, compressed) \ + end_class \ + start_class(OopData) \ + oop_field(OopData, object, "Ljava/lang/Object;") \ + boolean_field(OopData, compressed) \ + end_class \ start_class(ExternalCompilationResult) \ long_field(ExternalCompilationResult, entryPoint) \ end_class \ @@ -145,8 +153,7 @@ oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;") \ end_class \ start_class(CompilationResult_DataPatch) \ - oop_field(CompilationResult_DataPatch, externalData, "Lcom/oracle/graal/api/code/CompilationResult$Data;") \ - oop_field(CompilationResult_DataPatch, inlineData, "Lcom/oracle/graal/api/meta/Constant;") \ + oop_field(CompilationResult_DataPatch, data, "Lcom/oracle/graal/api/code/CompilationResult$Data;") \ end_class \ start_class(InfopointReason) \ static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;") \ @@ -172,9 +179,9 @@ oop_field(DebugInfo, referenceMap, "Lcom/oracle/graal/api/code/ReferenceMap;") \ oop_field(DebugInfo, calleeSaveInfo, "Lcom/oracle/graal/api/code/RegisterSaveLayout;") \ end_class \ - start_class(ReferenceMap) \ - oop_field(ReferenceMap, registerRefMap, "Ljava/util/BitSet;") \ - oop_field(ReferenceMap, frameRefMap, "Ljava/util/BitSet;") \ + start_class(HotSpotReferenceMap) \ + oop_field(HotSpotReferenceMap, registerRefMap, "Ljava/util/BitSet;") \ + oop_field(HotSpotReferenceMap, frameRefMap, "Ljava/util/BitSet;") \ end_class \ start_class(RegisterSaveLayout) \ oop_field(RegisterSaveLayout, registers, "[Lcom/oracle/graal/api/code/Register;") \
--- a/src/share/vm/graal/vmStructs_graal.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/graal/vmStructs_graal.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -32,6 +32,7 @@ #define VM_STRUCTS_GRAAL(nonstatic_field, static_field) \ nonstatic_field(ThreadShadow, _pending_deoptimization, int) \ nonstatic_field(ThreadShadow, _pending_failed_speculation, oop) \ + nonstatic_field(MethodData, _graal_node_count, int) \ #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type) \
--- a/src/share/vm/oops/methodData.cpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/oops/methodData.cpp Mon Mar 17 12:40:35 2014 -0700 @@ -1216,6 +1216,9 @@ _highest_comp_level = 0; _highest_osr_comp_level = 0; _would_profile = true; +#ifdef GRAAL + _graal_node_count = 0; +#endif // Initialize flags and trap history. _nof_decompiles = 0;
--- a/src/share/vm/oops/methodData.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/oops/methodData.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -2203,6 +2203,11 @@ // Does this method contain anything worth profiling? bool _would_profile; +#ifdef GRAAL + // Support for HotSpotMethodData.setCompiledGraphSize(int) + int _graal_node_count; +#endif + // Size of _data array in bytes. (Excludes header and extra_data fields.) int _data_size;
--- a/src/share/vm/utilities/globalDefinitions.hpp Mon Mar 17 12:39:25 2014 -0700 +++ b/src/share/vm/utilities/globalDefinitions.hpp Mon Mar 17 12:40:35 2014 -0700 @@ -834,7 +834,7 @@ CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo CompLevel_full_optimization = 4, // C2, Shark or Graal -#if defined(COMPILER2) || defined(SHARK) || defined(GRAAL) +#if defined(COMPILER2) || defined(SHARK) || defined(COMPILERGRAAL) CompLevel_highest_tier = CompLevel_full_optimization, // pure C2 and tiered or Graal and tiered #elif defined(COMPILER1) CompLevel_highest_tier = CompLevel_simple, // pure C1 or Graal @@ -844,7 +844,7 @@ #if defined(TIERED) CompLevel_initial_compile = CompLevel_full_profile // tiered -#elif defined(COMPILER1) || defined(GRAAL) +#elif defined(COMPILER1) || defined(COMPILERGRAAL) CompLevel_initial_compile = CompLevel_simple // pure C1 or Graal #elif defined(COMPILER2) || defined(SHARK) CompLevel_initial_compile = CompLevel_full_optimization // pure C2