# HG changeset patch # User Tom Rodriguez # Date 1395168697 25200 # Node ID ff2095ec7bdb64324b74833eda9070d7eae290b9 # Parent 3eda945af90a5c0a6b397ae3d4e1624eccce7707# Parent 90b43a808eb0dd0f82284a1ff6bfbb46f6cc6990 Merge diff -r 3eda945af90a -r ff2095ec7bdb CHANGELOG.md --- a/CHANGELOG.md Tue Mar 18 11:07:47 2014 -0700 +++ b/CHANGELOG.md Tue Mar 18 11:51:37 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) diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java --- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java Tue Mar 18 11:51:37 2014 -0700 @@ -146,7 +146,6 @@ case Short: case Int: case Long: - case NarrowOop: case Object: return true; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java Tue Mar 18 11:51:37 2014 -0700 @@ -198,8 +198,6 @@ return 8; case Object: return wordSize; - case NarrowOop: - return wordSize / 2; default: return 0; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java Tue Mar 18 11:51:37 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); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java Tue Mar 18 11:51:37 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(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java Tue Mar 18 11:51:37 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()) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java Tue Mar 18 11:51:37 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[]", pcOffset, getDataString()); + return String.format("%d[]", 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(']'); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java Tue Mar 18 11:51:37 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. - *
    - *
  • bit0 = 0: contains no references
  • - *
  • bit0 = 1, bit1 = 0: contains a wide oop
  • - *
  • bit0 = 1, bit1 = 1: contains a narrow oop
  • - *
- */ - private final BitSet registerRefMap; - - /** - * Contains 3 bits per stack slot. - *
    - *
  • bit0 = 0: contains no references
  • - *
  • bit0 = 1, bit1+2 = 0: contains a wide oop
  • - *
  • bit0 = 1, bit1 = 1: contains a narrow oop in the lower half
  • - *
  • bit0 = 1, bit2 = 1: contains a narrow oop in the upper half
  • - *
- */ - 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java Tue Mar 18 11:51:37 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Tue Mar 18 11:51:37 2014 -0700 @@ -77,22 +77,6 @@ } } - /** - * @see ResolvedJavaMethod#getCompiledCodeSize() - */ - @Test - public void getCompiledCodeSizeTest() { - for (Map.Entry e : methods.entrySet()) { - ResolvedJavaMethod m = e.getValue(); - int size = m.getCompiledCodeSize(); - if (isAbstract(m.getModifiers())) { - assertTrue(size == 0); - } else { - assertTrue(size >= 0); - } - } - } - @Test public void getModifiersTest() { for (Map.Entry e : methods.entrySet()) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java Tue Mar 18 11:51:37 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()); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java Tue Mar 18 11:51:37 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; + } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Tue Mar 18 11:51:37 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; } /** diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java Tue Mar 18 11:51:37 2014 -0700 @@ -25,7 +25,7 @@ import java.util.*; /** - * A {@link LocationIdentity} warpping an object. + * A {@link LocationIdentity} wrapping an object. */ public final class ObjectLocationIdentity implements LocationIdentity { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java Tue Mar 18 11:51:37 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(); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java Tue Mar 18 11:51:37 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 getCompilerStorage(); - - /** * Returns the constant pool of this method. */ ConstantPool getConstantPool(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java --- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java --- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java Tue Mar 18 11:51:37 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)); } /** diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java --- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Tue Mar 18 11:51:37 2014 -0700 @@ -264,9 +264,6 @@ case Byte: prefix = "s8"; break; - case NarrowOop: - prefix = "u32"; - break; default: throw GraalInternalError.shouldNotReachHere(); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java Tue Mar 18 11:51:37 2014 -0700 @@ -360,9 +360,9 @@ } @Override - public void emitNullCheck(ValueNode v, DeoptimizingNode deoping) { - assert v.stamp() instanceof ObjectStamp; - append(new AMD64Move.NullCheckOp(load(operand(v)), state(deoping))); + public void emitNullCheck(ValueNode v, DeoptimizingNode deopt) { + assert v.kind() == Kind.Object : v + " - " + v.stamp() + " @ " + deopt; + append(new AMD64Move.NullCheckOp(load(operand(v)), state(deopt))); } @Override diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Tue Mar 18 11:51:37 2014 -0700 @@ -120,6 +120,9 @@ errors.add(e.getMessage()); } catch (LinkageError e) { // suppress linkages errors resulting from eager resolution + } catch (BailoutException e) { + // Graal bail outs on certain patterns in Java bytecode (e.g., + // unbalanced monitors introduced by jacoco). } catch (Throwable e) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Mar 18 11:51:37 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 HIR 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(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java Tue Mar 18 11:51:37 2014 -0700 @@ -45,8 +45,8 @@ this.nodeOperands = nodeOperands; } - protected HashMap virtualObjects = new HashMap<>(); - protected IdentityHashMap objectStates = new IdentityHashMap<>(); + protected final HashMap virtualObjects = new HashMap<>(); + protected final IdentityHashMap objectStates = new IdentityHashMap<>(); public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) { assert virtualObjects.size() == 0; diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Mar 18 11:51:37 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 { @@ -41,8 +38,6 @@ public static class Options { // @formatter:off - @Option(help = "") - public static final OptionValue VerifyUsageWithEquals = new OptionValue<>(true); @Option(help = "Enable inlining") public static final OptionValue 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Tue Mar 18 11:51:37 2014 -0700 @@ -167,7 +167,7 @@ * @return the scope entered by this method which will be exited when its {@link Scope#close()} * method is called */ - public static Scope scope(String name, Object... context) { + public static Scope scope(CharSequence name, Object... context) { if (ENABLED) { return DebugScope.getInstance().scope(name, null, context); } else { @@ -195,7 +195,7 @@ * @return the scope entered by this method which will be exited when its {@link Scope#close()} * method is called */ - public static Scope sandbox(String name, DebugConfig config, Object... context) { + public static Scope sandbox(CharSequence name, DebugConfig config, Object... context) { if (ENABLED) { DebugConfig sandboxConfig = config == null ? silentConfig() : config; return DebugScope.getInstance().scope(name, sandboxConfig, context); @@ -379,11 +379,11 @@ *

* A disabled metric has virtually no overhead. */ - public static DebugMetric metric(String name) { - if (Boolean.getBoolean(ENABLE_METRIC_PROPERTY_NAME_PREFIX + name)) { - return new MetricImpl(name, false); + public static DebugMetric metric(CharSequence name) { + if (enabledMetrics != null && enabledMetrics.contains(name.toString())) { + return new MetricImpl(name.toString(), false); } else if (ENABLED) { - return new MetricImpl(name, true); + return new MetricImpl(name.toString(), true); } else { return VOID_METRIC; } @@ -495,15 +495,33 @@ }; /** - * @see #timer(String) + * @see #timer(CharSequence) */ public static final String ENABLE_TIMER_PROPERTY_NAME_PREFIX = "graal.debug.timer."; /** - * @see #metric(String) + * @see #metric(CharSequence) */ public static final String ENABLE_METRIC_PROPERTY_NAME_PREFIX = "graal.debug.metric."; + private static final Set enabledMetrics; + private static final Set enabledTimers; + static { + Set metrics = new HashSet<>(); + Set timers = new HashSet<>(); + for (Map.Entry e : System.getProperties().entrySet()) { + String name = e.getKey().toString(); + if (name.startsWith(ENABLE_METRIC_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) { + metrics.add(name.substring(ENABLE_METRIC_PROPERTY_NAME_PREFIX.length())); + } + if (name.startsWith(ENABLE_TIMER_PROPERTY_NAME_PREFIX) && Boolean.parseBoolean(e.getValue().toString())) { + timers.add(name.substring(ENABLE_TIMER_PROPERTY_NAME_PREFIX.length())); + } + } + enabledMetrics = metrics.isEmpty() ? null : metrics; + enabledTimers = timers.isEmpty() ? null : timers; + } + /** * Creates a {@linkplain DebugTimer timer} that is enabled iff debugging is * {@linkplain #isEnabled() enabled} or the system property whose name is formed by adding to @@ -514,11 +532,11 @@ *

* A disabled timer has virtually no overhead. */ - public static DebugTimer timer(String name) { - if (Boolean.getBoolean(ENABLE_TIMER_PROPERTY_NAME_PREFIX + name)) { - return new TimerImpl(name, false); + public static DebugTimer timer(CharSequence name) { + if (enabledTimers != null && enabledTimers.contains(name.toString())) { + return new TimerImpl(name.toString(), false); } else if (ENABLED) { - return new TimerImpl(name, true); + return new TimerImpl(name.toString(), true); } else { return VOID_TIMER; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Tue Mar 18 11:51:37 2014 -0700 @@ -45,7 +45,7 @@ * Determines if metering is enabled in the {@linkplain Debug#currentScope() current debug * scope}. * - * @see Debug#metric(String) + * @see Debug#metric(CharSequence) */ boolean isMeterEnabled(); @@ -76,7 +76,7 @@ void removeFromContext(Object o); /** - * @see Debug#timer(String) + * @see Debug#timer(CharSequence) */ boolean isTimeEnabled(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java Tue Mar 18 11:51:37 2014 -0700 @@ -72,6 +72,10 @@ count++; } + public void add(int n) { + count += n; + } + public int getCount() { return count; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramAsciiPrinter.java diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Tue Mar 18 11:51:37 2014 -0700 @@ -231,13 +231,13 @@ * @param newContextObjects objects to be appended to the debug context * @return the new scope which will be exited when its {@link #close()} method is called */ - public DebugScope scope(String name, DebugConfig sandboxConfig, Object... newContextObjects) { + public DebugScope scope(CharSequence name, DebugConfig sandboxConfig, Object... newContextObjects) { DebugScope newScope = null; if (sandboxConfig != null) { - newScope = new DebugScope(name, name, this, true, newContextObjects); + newScope = new DebugScope(name.toString(), name.toString(), this, true, newContextObjects); configTL.set(sandboxConfig); } else { - newScope = this.createChild(name, newContextObjects); + newScope = this.createChild(name.toString(), newContextObjects); } instanceTL.set(newScope); newScope.updateFlags(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Tue Mar 18 11:51:37 2014 -0700 @@ -458,6 +458,7 @@ * newInput: removes this node from oldInput's usages and adds this node to newInput's usages. */ protected void updateUsages(Node oldInput, Node newInput) { + assert isAlive() && (newInput == null || newInput.isAlive()) : "adding " + newInput + " to " + this + " instead of " + oldInput; if (oldInput != newInput) { if (oldInput != null) { if (oldInput.recordsUsages()) { @@ -482,6 +483,7 @@ * this node to newSuccessor's predecessors. */ protected void updatePredecessor(Node oldSuccessor, Node newSuccessor) { + assert isAlive() && (newSuccessor == null || newSuccessor.isAlive()) : "adding " + newSuccessor + " to " + this + " instead of " + oldSuccessor; assert graph == null || !graph.isFrozen(); if (oldSuccessor != newSuccessor) { if (oldSuccessor != null) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeList.java Tue Mar 18 11:51:37 2014 -0700 @@ -257,7 +257,7 @@ } @Override - public void snapshotTo(List to) { + public void snapshotTo(Collection to) { for (int i = 0; i < size; i++) { to.add(get(i)); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/AbstractNodeIterable.java Tue Mar 18 11:51:37 2014 -0700 @@ -74,7 +74,7 @@ } @Override - public void snapshotTo(List to) { + public void snapshotTo(Collection to) { for (T n : this) { to.add(n); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/NodeIterable.java Tue Mar 18 11:51:37 2014 -0700 @@ -44,7 +44,7 @@ List snapshot(); - void snapshotTo(List to); + void snapshotTo(Collection to); T first(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java Tue Mar 18 11:51:37 2014 -0700 @@ -41,8 +41,8 @@ import com.oracle.graal.compiler.gen.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.hotspot.nfi.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; @@ -249,7 +249,7 @@ public void emitCodePrefix(ResolvedJavaMethod installedCodeOwner, CompilationResultBuilder crb, AMD64MacroAssembler asm, RegisterConfig regConfig, HotSpotVMConfig config, Label verifiedEntry) { HotSpotProviders providers = getProviders(); if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) { - crb.recordMark(Marks.MARK_UNVERIFIED_ENTRY); + MarkId.recordMark(crb, MarkId.UNVERIFIED_ENTRY); CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{providers.getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false); Register inlineCacheKlass = rax; // see definition of IC_Klass in // c1_LIRAssembler_x86.cpp @@ -271,9 +271,9 @@ } asm.align(config.codeEntryAlignment); - crb.recordMark(Marks.MARK_OSR_ENTRY); + MarkId.recordMark(crb, MarkId.OSR_ENTRY); asm.bind(verifiedEntry); - crb.recordMark(Marks.MARK_VERIFIED_ENTRY); + MarkId.recordMark(crb, MarkId.VERIFIED_ENTRY); } /** @@ -293,9 +293,9 @@ HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext; if (!frameContext.isStub) { HotSpotForeignCallsProvider foreignCalls = providers.getForeignCalls(); - crb.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY); + MarkId.recordMark(crb, MarkId.EXCEPTION_HANDLER_ENTRY); AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null); - crb.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY); + MarkId.recordMark(crb, MarkId.DEOPT_HANDLER_ENTRY); AMD64Call.directCall(crb, asm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null); } else { // No need to emit the stubs for entries back into the method since diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java Tue Mar 18 11:51:37 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 diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Mar 18 11:51:37 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. diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Tue Mar 18 11:51:37 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"); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java Tue Mar 18 11:51:37 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 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); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotSafepointOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -24,13 +24,13 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.asm.NumUtil.*; -import static com.oracle.graal.hotspot.bridge.Marks.*; import static com.oracle.graal.phases.GraalOptions.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; @@ -82,21 +82,21 @@ // co-located with the immutable code. asm.movq(scratch, (AMD64Address) crb.recordDataReferenceInCode(pollingPageAddress, alignment)); final int pos = asm.position(); - crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR); + MarkId.recordMark(crb, atReturn ? MarkId.POLL_RETURN_FAR : MarkId.POLL_FAR); if (state != null) { crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); } asm.testl(rax, new AMD64Address(scratch)); } else if (isPollingPageFar(config)) { asm.movq(scratch, config.safepointPollingAddress); - crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR); + MarkId.recordMark(crb, atReturn ? MarkId.POLL_RETURN_FAR : MarkId.POLL_FAR); final int pos = asm.position(); if (state != null) { crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); } asm.testl(rax, new AMD64Address(scratch)); } else { - crb.recordMark(atReturn ? MARK_POLL_RETURN_NEAR : MARK_POLL_NEAR); + MarkId.recordMark(crb, atReturn ? MarkId.POLL_RETURN_NEAR : MarkId.POLL_NEAR); final int pos = asm.position(); if (state != null) { crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectStaticCallOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -26,7 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; @@ -55,7 +55,7 @@ // The mark for an invocation that uses an inline cache must be placed at the // instruction that loads the Klass from the inline cache. AMD64Move.move(crb, masm, AMD64.rbx.asValue(Kind.Long), metaspaceMethod); - crb.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL); + MarkId.recordMark(crb, invokeKind == InvokeKind.Static ? MarkId.INVOKESTATIC : MarkId.INVOKESPECIAL); // This must be emitted exactly like this to ensure it's patchable masm.movq(AMD64.rax, HotSpotGraalRuntime.runtime().getConfig().nonOopBits); super.emitCode(crb, masm); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotspotDirectVirtualCallOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -28,7 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.AMD64Call.DirectCallOp; import com.oracle.graal.lir.asm.*; @@ -53,7 +53,7 @@ public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { // The mark for an invocation that uses an inline cache must be placed at the // instruction that loads the Klass from the inline cache. - crb.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); + MarkId.recordMark(crb, invokeKind == Virtual ? MarkId.INVOKEVIRTUAL : MarkId.INVOKEINTERFACE); // This must be emitted exactly like this to ensure it's patchable masm.movq(AMD64.rax, HotSpotGraalRuntime.runtime().getConfig().nonOopBits); super.emitCode(crb, masm); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64IndirectCallOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -29,7 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.amd64.*; -import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.amd64.AMD64Call.IndirectCallOp; @@ -58,7 +58,7 @@ @Override public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { - crb.recordMark(Marks.MARK_INLINE_INVOKE); + MarkId.recordMark(crb, MarkId.INLINE_INVOKE); Register callReg = asRegister(targetAddress); assert !callReg.equals(METHOD); AMD64Call.indirectCall(crb, masm, callReg, callTarget, state); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java Tue Mar 18 11:51:37 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() { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java Tue Mar 18 11:51:37 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java Tue Mar 18 11:51:37 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() { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java Tue Mar 18 11:51:37 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); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Tue Mar 18 11:51:37 2014 -0700 @@ -34,8 +34,8 @@ import com.oracle.graal.compiler.gen.LIRGenerator; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.hotspot.stubs.Stub; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.*; @@ -189,7 +189,7 @@ // Emit the prefix if (unverifiedStub != null) { - crb.recordMark(Marks.MARK_UNVERIFIED_ENTRY); + MarkId.recordMark(crb, MarkId.UNVERIFIED_ENTRY); // We need to use JavaCall here because we haven't entered the frame yet. CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getProviders().getMetaAccess().lookupJavaType(Object.class)}, getTarget(), false); Register inlineCacheKlass = g5; // see MacroAssembler::ic_call @@ -204,8 +204,8 @@ } masm.align(config.codeEntryAlignment); - crb.recordMark(Marks.MARK_OSR_ENTRY); - crb.recordMark(Marks.MARK_VERIFIED_ENTRY); + MarkId.recordMark(crb, MarkId.OSR_ENTRY); + MarkId.recordMark(crb, MarkId.VERIFIED_ENTRY); // Emit code for the LIR crb.emit(lir); @@ -213,9 +213,9 @@ HotSpotFrameContext frameContext = (HotSpotFrameContext) crb.frameContext; HotSpotForeignCallsProvider foreignCalls = getProviders().getForeignCalls(); if (!frameContext.isStub) { - crb.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY); + MarkId.recordMark(crb, MarkId.EXCEPTION_HANDLER_ENTRY); SPARCCall.directCall(crb, masm, foreignCalls.lookupForeignCall(EXCEPTION_HANDLER), null, false, null); - crb.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY); + MarkId.recordMark(crb, MarkId.DEOPT_HANDLER_ENTRY); SPARCCall.directCall(crb, masm, foreignCalls.lookupForeignCall(DEOPT_HANDLER), null, false, null); } else { // No need to emit the stubs for entries back into the method since diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java Tue Mar 18 11:51:37 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) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java Tue Mar 18 11:51:37 2014 -0700 @@ -34,6 +34,6 @@ @Override protected RegisterConfig createRegisterConfig() { - return new SPARCHotSpotRegisterConfig(getTarget().arch, runtime.getConfig()); + return new SPARCHotSpotRegisterConfig(getTarget(), runtime.getConfig()); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java Tue Mar 18 11:51:37 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); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotSafepointOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -23,13 +23,13 @@ package com.oracle.graal.hotspot.sparc; import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; -import static com.oracle.graal.hotspot.bridge.Marks.*; import static com.oracle.graal.sparc.SPARC.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.asm.*; @@ -61,7 +61,7 @@ public static void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm, HotSpotVMConfig config, boolean atReturn, LIRFrameState state, Register scratch) { final int pos = masm.position(); new Setx(config.safepointPollingAddress, scratch).emit(masm); - crb.recordMark(atReturn ? MARK_POLL_RETURN_FAR : MARK_POLL_FAR); + MarkId.recordMark(crb, atReturn ? MarkId.POLL_RETURN_FAR : MarkId.POLL_FAR); if (state != null) { crb.recordInfopoint(pos, state, InfopointReason.SAFEPOINT); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectStaticCallOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -28,7 +28,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.sparc.SPARCCall.DirectCallOp; @@ -42,7 +42,6 @@ @Opcode("CALL_DIRECT") final class SPARCHotspotDirectStaticCallOp extends DirectCallOp { - private static final long nonOopBits = HotSpotGraalRuntime.runtime().getConfig().nonOopBits; private final Constant metaspaceMethod; private final InvokeKind invokeKind; @@ -58,9 +57,9 @@ // The mark for an invocation that uses an inline cache must be placed at the // instruction that loads the Klass from the inline cache. SPARCMove.move(crb, masm, g5.asValue(Kind.Long), metaspaceMethod); - crb.recordMark(invokeKind == InvokeKind.Static ? Marks.MARK_INVOKESTATIC : Marks.MARK_INVOKESPECIAL); + MarkId.recordMark(crb, invokeKind == InvokeKind.Static ? MarkId.INVOKESTATIC : MarkId.INVOKESPECIAL); // SPARCMove.move(crb, masm, g3.asValue(Kind.Long), Constant.LONG_0); - new Setx(nonOopBits, g3, true).emit(masm); + new Setx(HotSpotGraalRuntime.runtime().getConfig().nonOopBits, g3, true).emit(masm); super.emitCode(crb, masm); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotspotDirectVirtualCallOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -29,7 +29,7 @@ import com.oracle.graal.asm.sparc.*; import com.oracle.graal.asm.sparc.SPARCMacroAssembler.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.sparc.SPARCCall.DirectCallOp; import com.oracle.graal.lir.asm.*; @@ -54,7 +54,7 @@ public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { // The mark for an invocation that uses an inline cache must be placed at the // instruction that loads the Klass from the inline cache. - crb.recordMark(invokeKind == Virtual ? Marks.MARK_INVOKEVIRTUAL : Marks.MARK_INVOKEINTERFACE); + MarkId.recordMark(crb, invokeKind == Virtual ? MarkId.INVOKEVIRTUAL : MarkId.INVOKEINTERFACE); new Setx(HotSpotGraalRuntime.runtime().getConfig().nonOopBits, g3, true).emit(masm); super.emitCode(crb, masm); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCIndirectCallOp.java Tue Mar 18 11:51:37 2014 -0700 @@ -29,7 +29,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.hotspot.bridge.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.sparc.*; import com.oracle.graal.lir.sparc.SPARCCall.IndirectCallOp; @@ -58,7 +58,7 @@ @Override public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - crb.recordMark(Marks.MARK_INLINE_INVOKE); + MarkId.recordMark(crb, MarkId.INLINE_INVOKE); Register callReg = asRegister(targetAddress); assert !callReg.equals(METHOD); SPARCCall.indirectCall(crb, masm, callReg, callTarget, state); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Tue Mar 18 11:51:37 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()"); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Mar 18 11:51:37 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())); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Tue Mar 18 11:51:37 2014 -0700 @@ -27,7 +27,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.target.*; -import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; @@ -51,7 +50,8 @@ /** * Descriptor for {@link ExceptionHandlerStub}. This stub is called by the - * {@linkplain Marks#MARK_EXCEPTION_HANDLER_ENTRY exception handler} in a compiled method. + * {@linkplain HotSpotVMConfig#codeInstallerMarkIdExceptionHandlerEntry exception handler} in a + * compiled method. */ public static final ForeignCallDescriptor EXCEPTION_HANDLER = new ForeignCallDescriptor("exceptionHandler", void.class, Object.class, Word.class); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java Tue Mar 18 11:51:37 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 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 { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Tue Mar 18 11:51:37 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(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java Tue Mar 18 11:51:37 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; diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Tue Mar 18 11:51:37 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. + *

    + *
  • bit0 = 0: contains no references
  • + *
  • bit0 = 1, bit1 = 0: contains a wide oop
  • + *
  • bit0 = 1, bit1 = 1: contains a narrow oop
  • + *
+ */ + private final BitSet registerRefMap; + + /** + * Contains 3 bits per stack slot. + *
    + *
  • bit0 = 0: contains no references
  • + *
  • bit0 = 1, bit1+2 = 0: contains a wide oop
  • + *
  • bit0 = 1, bit1 = 1: contains a narrow oop in the lower half
  • + *
  • bit0 = 1, bit2 = 1: contains a narrow oop in the upper half
  • + *
+ */ + 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)); + } + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java Tue Mar 18 11:51:37 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); + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Mar 18 11:51:37 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; @@ -1419,6 +1422,22 @@ @HotSpotVMConstant(name = "CompilerToVM::KLASS_TAG") @Stable public int compilerToVMKlassTag; @HotSpotVMConstant(name = "CompilerToVM::SYMBOL_TAG") @Stable public int compilerToVMSymbolTag; + @HotSpotVMConstant(name = "CodeInstaller::VERIFIED_ENTRY") @Stable public int codeInstallerMarkIdVerifiedEntry; + @HotSpotVMConstant(name = "CodeInstaller::UNVERIFIED_ENTRY") @Stable public int codeInstallerMarkIdUnverifiedEntry; + @HotSpotVMConstant(name = "CodeInstaller::OSR_ENTRY") @Stable public int codeInstallerMarkIdOsrEntry; + @HotSpotVMConstant(name = "CodeInstaller::EXCEPTION_HANDLER_ENTRY") @Stable public int codeInstallerMarkIdExceptionHandlerEntry; + @HotSpotVMConstant(name = "CodeInstaller::DEOPT_HANDLER_ENTRY") @Stable public int codeInstallerMarkIdDeoptHandlerEntry; + @HotSpotVMConstant(name = "CodeInstaller::INVOKEINTERFACE") @Stable public int codeInstallerMarkIdInvokeinterface; + @HotSpotVMConstant(name = "CodeInstaller::INVOKEVIRTUAL") @Stable public int codeInstallerMarkIdInvokevirtual; + @HotSpotVMConstant(name = "CodeInstaller::INVOKESTATIC") @Stable public int codeInstallerMarkIdInvokestatic; + @HotSpotVMConstant(name = "CodeInstaller::INVOKESPECIAL") @Stable public int codeInstallerMarkIdInvokespecial; + @HotSpotVMConstant(name = "CodeInstaller::INLINE_INVOKE") @Stable public int codeInstallerMarkIdInlineInvoke; + @HotSpotVMConstant(name = "CodeInstaller::POLL_NEAR") @Stable public int codeInstallerMarkIdPollNear; + @HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_NEAR") @Stable public int codeInstallerMarkIdPollReturnNear; + @HotSpotVMConstant(name = "CodeInstaller::POLL_FAR") @Stable public int codeInstallerMarkIdPollFar; + @HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_FAR") @Stable public int codeInstallerMarkIdPollReturnFar; + @HotSpotVMConstant(name = "CodeInstaller::INVOKE_INVALID") @Stable public int codeInstallerMarkIdInvokeInvalid; + public boolean check() { for (Field f : getClass().getDeclaredFields()) { int modifiers = f.getModifiers(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java Tue Mar 18 11:51:37 2014 -0700 @@ -118,7 +118,9 @@ */ long lookupType(String name, Class accessingClass, boolean resolve); - Object lookupConstantInPool(long metaspaceConstantPool, int cpi); + Object resolveConstantInPool(long metaspaceConstantPool, int cpi); + + Object resolvePossiblyCachedConstantInPool(long metaspaceConstantPool, int cpi); int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi); @@ -128,6 +130,8 @@ int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi); + long constantPoolKlassAt(long metaspaceConstantPool, int cpi); + /** * Looks up a class entry in a constant pool. * @@ -163,7 +167,7 @@ */ long resolveField(long metaspaceConstantPool, int cpi, byte opcode, long[] info); - void loadReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode); + int constantPoolRemapInstructionOperandFromCache(long metaspaceConstantPool, int cpi); Object lookupAppendixInPool(long metaspaceConstantPool, int cpi); @@ -248,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. * diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java Tue Mar 18 11:51:37 2014 -0700 @@ -63,8 +63,9 @@ @Override public native long lookupType(String name, Class accessingClass, boolean eagerResolve); - @Override - public native Object lookupConstantInPool(long metaspaceConstantPool, int cpi); + public native Object resolveConstantInPool(long metaspaceConstantPool, int cpi); + + public native Object resolvePossiblyCachedConstantInPool(long metaspaceConstantPool, int cpi); @Override public native int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi); @@ -78,6 +79,8 @@ @Override public native int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi); + public native long constantPoolKlassAt(long metaspaceConstantPool, int cpi); + @Override public native long lookupKlassInPool(long metaspaceConstantPool, int cpi); @@ -87,8 +90,7 @@ @Override public native long resolveField(long metaspaceConstantPool, int cpi, byte opcode, long[] info); - @Override - public native void loadReferencedTypeInPool(long metaspaceConstantPool, int cpi, byte opcode); + public native int constantPoolRemapInstructionOperandFromCache(long metaspaceConstantPool, int cpi); @Override public native Object lookupAppendixInPool(long metaspaceConstantPool, int cpi); @@ -109,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 diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/Marks.java Tue Mar 18 11:07:47 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.hotspot.bridge; - -/** - * Constants used to mark special positions in code being installed into the code cache by Graal C++ - * code. These constants need to be kept in sync with those of the same name defined in - * graalCodeInstaller.hpp. - */ -public interface Marks { - - int MARK_VERIFIED_ENTRY = 1; - int MARK_UNVERIFIED_ENTRY = 2; - int MARK_OSR_ENTRY = 3; - int MARK_EXCEPTION_HANDLER_ENTRY = 4; - int MARK_DEOPT_HANDLER_ENTRY = 5; - int MARK_INVOKEINTERFACE = 6; - int MARK_INVOKEVIRTUAL = 7; - int MARK_INVOKESTATIC = 8; - int MARK_INVOKESPECIAL = 9; - int MARK_INLINE_INVOKE = 10; - int MARK_POLL_NEAR = 11; - int MARK_POLL_RETURN_NEAR = 12; - int MARK_POLL_FAR = 13; - int MARK_POLL_RETURN_FAR = 14; -} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java Tue Mar 18 11:51:37 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 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; + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java Tue Mar 18 11:51:37 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) { + } + +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java Tue Mar 18 11:51:37 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 + "}"; + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java Tue Mar 18 11:51:37 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) + "]"; + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java Tue Mar 18 11:51:37 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); + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Mar 18 11:51:37 2014 -0700 @@ -50,10 +50,10 @@ * infrastructure is enabled by specifying either the GenericDynamicCounters or * BenchmarkDynamicCounters option.
* - * The counters are kept in a special area in the native JavaThread object, and the number of - * counters is configured in {@code thread.hpp (GRAAL_COUNTERS_SIZE)}. This file also contains an - * option to exclude compiler threads ({@code GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS}, which - * defaults to true). + * The counters are kept in a special area allocated for each native JavaThread object, and the + * number of counters is configured using {@code -XX:GraalCounterSize=value}. + * {@code -XX:+/-GraalCountersExcludeCompiler} configures whether to exclude compiler threads + * (defaults to true). * * The subsystems that use the logging need to have their own options to turn on the counters, and * insert DynamicCounterNodes when they're enabled. @@ -64,12 +64,10 @@ *

Example

In order to create statistics about allocations within the DaCapo pmd benchmark * the following steps are necessary: *
    - *
  • Modify {@code thread.hpp}: increase GRAAL_COUNTER_SIZE. The actual required value depends on - * the granularity of the profiling, 10000 should be enough for most cases. This will increase the - * JavaThread structure by 80kb.
  • - *
  • Also in {@code thread.hpp}: GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS specifies whether the - * numbers generated by compiler threads should be excluded (default: true).
  • - *
  • Build the Graal VM.
  • + *
  • Set {@code -XX:GraalCounterSize=value}. The actual required value depends on the granularity + * of the profiling, 10000 should be enough for most cases.
  • + *
  • Also: {@code -XX:+/-GraalCountersExcludeCompiler} specifies whether the numbers generated by + * compiler threads should be excluded (default: true).
  • *
  • Start the DaCapo pmd benchmark with * {@code "-G:BenchmarkDynamicCounters=err, starting ====, PASSED in "} and * {@code -G:+ProfileAllocations}.
  • @@ -330,7 +328,7 @@ int index = BenchmarkCounters.getIndex(counter); if (index >= config.graalCountersSize) { - throw new GraalInternalError("too many counters, reduce number of counters or increase GRAAL_COUNTERS_SIZE (current value: " + config.graalCountersSize + ")"); + throw new GraalInternalError("too many counters, reduce number of counters or increase -XX:GraalCounterSize=... (current value: " + config.graalCountersSize + ")"); } ConstantLocationNode arrayLocation = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, config.graalCountersThreadOffset, graph); ReadNode readArray = graph.add(new ReadNode(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE, false)); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Tue Mar 18 11:51:37 2014 -0700 @@ -29,15 +29,20 @@ 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.graph.*; 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.lir.asm.*; import com.oracle.graal.printer.*; /** @@ -57,6 +62,54 @@ protected abstract RegisterConfig createRegisterConfig(); + /** + * Constants used to mark special positions in code being installed into the code cache by Graal + * C++ code. + */ + public enum MarkId { + VERIFIED_ENTRY(config().codeInstallerMarkIdVerifiedEntry), + UNVERIFIED_ENTRY(config().codeInstallerMarkIdUnverifiedEntry), + OSR_ENTRY(config().codeInstallerMarkIdOsrEntry), + EXCEPTION_HANDLER_ENTRY(config().codeInstallerMarkIdExceptionHandlerEntry), + DEOPT_HANDLER_ENTRY(config().codeInstallerMarkIdDeoptHandlerEntry), + INVOKEINTERFACE(config().codeInstallerMarkIdInvokeinterface), + INVOKEVIRTUAL(config().codeInstallerMarkIdInvokevirtual), + INVOKESTATIC(config().codeInstallerMarkIdInvokestatic), + INVOKESPECIAL(config().codeInstallerMarkIdInvokespecial), + INLINE_INVOKE(config().codeInstallerMarkIdInlineInvoke), + POLL_NEAR(config().codeInstallerMarkIdPollNear), + POLL_RETURN_NEAR(config().codeInstallerMarkIdPollReturnNear), + POLL_FAR(config().codeInstallerMarkIdPollFar), + POLL_RETURN_FAR(config().codeInstallerMarkIdPollReturnFar); + + private final int value; + + private MarkId(int value) { + this.value = value; + } + + private static HotSpotVMConfig config() { + return HotSpotGraalRuntime.runtime().getConfig(); + } + + public static MarkId getEnum(int value) { + for (MarkId e : values()) { + if (e.value == value) { + return e; + } + } + throw GraalInternalError.shouldNotReachHere("unknown enum value " + value); + } + + /** + * Helper method to {@link CompilationResultBuilder#recordMark(Object) record a mark} with a + * {@link CompilationResultBuilder}. + */ + public static void recordMark(CompilationResultBuilder crb, MarkId mark) { + crb.recordMark(mark.value); + } + } + @Override public String disassemble(CompilationResult compResult, InstalledCode installedCode) { byte[] code = installedCode == null ? Arrays.copyOf(compResult.getTargetCode(), compResult.getTargetCodeSize()) : installedCode.getCode(); @@ -82,10 +135,10 @@ } } 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)); + hcf.addComment(mark.pcOffset, MarkId.getEnum((int) mark.id).toString()); } } return hcf.toEmbeddedString(); @@ -111,25 +164,6 @@ return String.valueOf(call.target); } - /** - * Decodes a mark to a mnemonic if possible. - */ - private static String getMarkName(Mark mark) { - Field[] fields = Marks.class.getDeclaredFields(); - for (Field f : fields) { - if (Modifier.isStatic(f.getModifiers()) && f.getName().startsWith("MARK_")) { - f.setAccessible(true); - try { - if (f.get(null).equals(mark.id)) { - return f.getName(); - } - } catch (Exception e) { - } - } - } - return "MARK:" + mark.id; - } - private static void addExceptionHandlersComment(CompilationResult compResult, HexCodeFile hcf) { if (!compResult.getExceptionHandlers().isEmpty()) { String nl = HexCodeFile.NEW_LINE; @@ -173,7 +207,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 +218,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 +237,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 +250,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; diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java Tue Mar 18 11:51:37 2014 -0700 @@ -40,6 +40,51 @@ private static final long serialVersionUID = -5443206401485234850L; /** + * Enum of all {@code JVM_CONSTANT} constants used in the VM. This includes the public and + * internal ones. + */ + private enum JVM_CONSTANT { + // @formatter:off + Utf8(config().jvmConstantUtf8), + Integer(config().jvmConstantInteger), + Long(config().jvmConstantLong), + Float(config().jvmConstantFloat), + Double(config().jvmConstantDouble), + Class(config().jvmConstantClass), + UnresolvedClass(config().jvmConstantUnresolvedClass), + UnresolvedClassInError(config().jvmConstantUnresolvedClassInError), + String(config().jvmConstantString), + Fieldref(config().jvmConstantFieldref), + MethodRef(config().jvmConstantMethodref), + InterfaceMethodref(config().jvmConstantInterfaceMethodref), + NameAndType(config().jvmConstantNameAndType), + MethodHandle(config().jvmConstantMethodHandle), + MethodHandleInError(config().jvmConstantMethodHandleInError), + MethodType(config().jvmConstantMethodType), + MethodTypeInError(config().jvmConstantMethodTypeInError); + // @formatter:on + + private final int value; + + private JVM_CONSTANT(int value) { + this.value = value; + } + + private static HotSpotVMConfig config() { + return runtime().getConfig(); + } + + public static JVM_CONSTANT getEnum(int value) { + for (JVM_CONSTANT e : values()) { + if (e.value == value) { + return e; + } + } + throw GraalInternalError.shouldNotReachHere("unknown enum value " + value); + } + } + + /** * Reference to the C++ ConstantPool object. */ private final long metaspaceConstantPool; @@ -86,11 +131,12 @@ * @param index constant pool index * @return constant pool tag */ - private int getTagAt(int index) { + private JVM_CONSTANT getTagAt(int index) { assertBounds(index); HotSpotVMConfig config = runtime().getConfig(); - long tags = unsafe.getAddress(metaspaceConstantPool + config.constantPoolTagsOffset); - return unsafe.getByteVolatile(null, tags + config.arrayU1DataOffset + index); + final long metaspaceConstantPoolTags = unsafe.getAddress(metaspaceConstantPool + config.constantPoolTagsOffset); + final int tag = unsafe.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index); + return JVM_CONSTANT.getEnum(tag); } /** @@ -101,8 +147,7 @@ */ private long getEntryAt(int index) { assertBounds(index); - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getAddress(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize); + return unsafe.getAddress(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getTarget().wordSize); } /** @@ -112,9 +157,8 @@ * @return integer constant pool entry at index */ private int getIntAt(int index) { - HotSpotVMConfig config = runtime().getConfig(); - assertTag(index, config.jvmConstantInteger); - return unsafe.getInt(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize); + assertTag(index, JVM_CONSTANT.Integer); + return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getTarget().wordSize); } /** @@ -124,9 +168,8 @@ * @return long constant pool entry */ private long getLongAt(int index) { - HotSpotVMConfig config = runtime().getConfig(); - assertTag(index, config.jvmConstantLong); - return unsafe.getLong(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize); + assertTag(index, JVM_CONSTANT.Long); + return unsafe.getLong(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getTarget().wordSize); } /** @@ -136,9 +179,8 @@ * @return float constant pool entry */ private float getFloatAt(int index) { - HotSpotVMConfig config = runtime().getConfig(); - assertTag(index, config.jvmConstantFloat); - return unsafe.getFloat(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize); + assertTag(index, JVM_CONSTANT.Float); + return unsafe.getFloat(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getTarget().wordSize); } /** @@ -148,9 +190,8 @@ * @return float constant pool entry */ private double getDoubleAt(int index) { - HotSpotVMConfig config = runtime().getConfig(); - assertTag(index, config.jvmConstantDouble); - return unsafe.getDouble(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize); + assertTag(index, JVM_CONSTANT.Double); + return unsafe.getDouble(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getTarget().wordSize); } /** @@ -160,9 +201,8 @@ * @return {@code JVM_CONSTANT_NameAndType} constant pool entry */ private int getNameAndTypeAt(int index) { - HotSpotVMConfig config = runtime().getConfig(); - assertTag(index, config.jvmConstantNameAndType); - return unsafe.getInt(metaspaceConstantPool + config.constantPoolSize + index * runtime().getTarget().wordSize); + assertTag(index, JVM_CONSTANT.NameAndType); + return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getTarget().wordSize); } /** @@ -239,6 +279,20 @@ } /** + * Gets the uncached klass reference index constant pool entry at index {@code index}. See: + * {@code ConstantPool::uncached_klass_ref_index_at}. + * + * @param index constant pool index + * @return klass reference index + */ + private int getUncachedKlassRefIndexAt(int index) { + assert getTagAt(index) == JVM_CONSTANT.Fieldref || getTagAt(index) == JVM_CONSTANT.MethodRef || getTagAt(index) == JVM_CONSTANT.InterfaceMethodref; + final int refIndex = unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolSize + index * runtime().getTarget().wordSize); + // klass ref index is in the low 16-bits. + return refIndex & 0xFFFF; + } + + /** * Asserts that the constant pool index {@code index} is in the bounds of the constant pool. * * @param index constant pool index @@ -253,115 +307,52 @@ * @param index constant pool index * @param tag expected tag */ - private void assertTag(int index, int tag) { - assert getTagAt(index) == tag : "constant pool tag at index " + index + " is " + getNameForTag(getTagAt(index)) + " but expected " + getNameForTag(tag); - } - - private static String getNameForTag(int tag) { - HotSpotVMConfig config = runtime().getConfig(); - if (tag == config.jvmConstantUtf8) { - return "JVM_CONSTANT_Utf8"; - } - if (tag == config.jvmConstantInteger) { - return "JVM_CONSTANT_Integer"; - } - if (tag == config.jvmConstantLong) { - return "JVM_CONSTANT_Long"; - } - if (tag == config.jvmConstantFloat) { - return "JVM_CONSTANT_Float"; - } - if (tag == config.jvmConstantDouble) { - return "JVM_CONSTANT_Double"; - } - if (tag == config.jvmConstantClass) { - return "JVM_CONSTANT_Class"; - } - if (tag == config.jvmConstantUnresolvedClass) { - return "JVM_CONSTANT_UnresolvedClass"; - } - if (tag == config.jvmConstantUnresolvedClassInError) { - return "JVM_CONSTANT_UnresolvedClassInError"; - } - if (tag == config.jvmConstantString) { - return "JVM_CONSTANT_String"; - } - if (tag == config.jvmConstantFieldref) { - return "JVM_CONSTANT_Fieldref"; - } - if (tag == config.jvmConstantMethodref) { - return "JVM_CONSTANT_Methodref"; - } - if (tag == config.jvmConstantInterfaceMethodref) { - return "JVM_CONSTANT_InterfaceMethodref"; - } - if (tag == config.jvmConstantNameAndType) { - return "JVM_CONSTANT_NameAndType"; - } - if (tag == config.jvmConstantMethodHandle) { - return "JVM_CONSTANT_MethodHandle"; - } - if (tag == config.jvmConstantMethodHandleInError) { - return "JVM_CONSTANT_MethodHandleInError"; - } - if (tag == config.jvmConstantMethodType) { - return "JVM_CONSTANT_MethodType"; - } - if (tag == config.jvmConstantMethodTypeInError) { - return "JVM_CONSTANT_MethodTypeInError"; - } - return "unknown constant tag " + tag; + private void assertTag(int index, JVM_CONSTANT tag) { + assert getTagAt(index) == tag : "constant pool tag at index " + index + " is " + getTagAt(index) + " but expected " + tag; } @Override public int length() { - HotSpotVMConfig config = runtime().getConfig(); - return unsafe.getInt(metaspaceConstantPool + config.constantPoolLengthOffset); + return unsafe.getInt(metaspaceConstantPool + runtime().getConfig().constantPoolLengthOffset); } @Override public Object lookupConstant(int cpi) { assert cpi != 0; - - HotSpotVMConfig config = runtime().getConfig(); - final int tag = getTagAt(cpi); - - // Handle primitive constant pool entries directly. - if (tag == config.jvmConstantInteger) { - return Constant.forInt(getIntAt(cpi)); - } - if (tag == config.jvmConstantLong) { - return Constant.forLong(getLongAt(cpi)); - } - if (tag == config.jvmConstantFloat) { - return Constant.forFloat(getFloatAt(cpi)); - } - if (tag == config.jvmConstantDouble) { - return Constant.forDouble(getDoubleAt(cpi)); + final JVM_CONSTANT tag = getTagAt(cpi); + switch (tag) { + case Integer: + return Constant.forInt(getIntAt(cpi)); + case Long: + return Constant.forLong(getLongAt(cpi)); + case Float: + return Constant.forFloat(getFloatAt(cpi)); + case Double: + return Constant.forDouble(getDoubleAt(cpi)); + case Class: + case UnresolvedClass: + case UnresolvedClassInError: + final int opcode = -1; // opcode is not used + return lookupType(cpi, opcode); + case String: + Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(metaspaceConstantPool, cpi); + return Constant.forObject(string); + case MethodHandle: + case MethodHandleInError: + case MethodType: + case MethodTypeInError: + Object obj = runtime().getCompilerToVM().resolveConstantInPool(metaspaceConstantPool, cpi); + return Constant.forObject(obj); + default: + throw GraalInternalError.shouldNotReachHere("unknown constant pool tag " + tag); } - - // All the other constant pool entries need special attention so we call down into the VM. - if (tag == config.jvmConstantClass || tag == config.jvmConstantUnresolvedClass || tag == config.jvmConstantUnresolvedClassInError) { - final int opcode = -1; // opcode is not used - return lookupType(cpi, opcode); - } - if (tag == config.jvmConstantString) { - Object string = runtime().getCompilerToVM().lookupConstantInPool(metaspaceConstantPool, cpi); - return Constant.forObject(string); - } - if (tag == config.jvmConstantMethodHandle || tag == config.jvmConstantMethodHandleInError || tag == config.jvmConstantMethodType || tag == config.jvmConstantMethodTypeInError) { - Object obj = runtime().getCompilerToVM().lookupConstantInPool(metaspaceConstantPool, cpi); - return Constant.forObject(obj); - } - - throw GraalInternalError.shouldNotReachHere("unknown constant pool tag " + tag); } @Override public String lookupUtf8(int cpi) { - assertTag(cpi, runtime().getConfig().jvmConstantUtf8); - long signature = getEntryAt(cpi); - HotSpotSymbol symbol = new HotSpotSymbol(signature); + assertTag(cpi, JVM_CONSTANT.Utf8); + final long metaspaceSymbol = getEntryAt(cpi); + HotSpotSymbol symbol = new HotSpotSymbol(metaspaceSymbol); return symbol.asString(); } @@ -473,7 +464,37 @@ break; default: index = toConstantPoolIndex(cpi, opcode); + index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(metaspaceConstantPool, index); } - runtime().getCompilerToVM().loadReferencedTypeInPool(metaspaceConstantPool, index, (byte) opcode); + + JVM_CONSTANT tag = getTagAt(index); + switch (tag) { + case Fieldref: + case MethodRef: + case InterfaceMethodref: + index = getUncachedKlassRefIndexAt(index); + tag = getTagAt(index); + assert tag == JVM_CONSTANT.Class || tag == JVM_CONSTANT.UnresolvedClass || tag == JVM_CONSTANT.UnresolvedClassInError : tag; + break; + default: + // nothing + break; + } + + switch (tag) { + case Class: + case UnresolvedClass: + case UnresolvedClassInError: + final long metaspaceKlass = runtime().getCompilerToVM().constantPoolKlassAt(metaspaceConstantPool, index); + HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) HotSpotResolvedObjectType.fromMetaspaceKlass(metaspaceKlass); + Class klass = type.mirror(); + if (!klass.isPrimitive() && !klass.isArray()) { + unsafe.ensureClassInitialized(klass); + } + break; + default: + // nothing + break; + } } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Tue Mar 18 11:51:37 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); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java Tue Mar 18 11:51:37 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); + } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java Tue Mar 18 11:51:37 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; diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java Tue Mar 18 11:51:37 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; + } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java Tue Mar 18 11:51:37 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 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 getCompilerStorage() { - if (compilerStorage == null) { - compilerStorage = new ConcurrentHashMap<>(); - } - return compilerStorage; - } - - @Override public ConstantPool getConstantPool() { return constantPool; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java --- /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 Tue Mar 18 11:51:37 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); + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Tue Mar 18 11:51:37 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java Tue Mar 18 11:51:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -31,16 +31,16 @@ import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.*; import com.oracle.graal.word.*; /** - * Stub called by the {@linkplain Marks#MARK_EXCEPTION_HANDLER_ENTRY exception handler entry point} - * in a compiled method. This entry point is used when returning to a method to handle an exception + * Stub called by the {@linkplain MarkId#EXCEPTION_HANDLER_ENTRY exception handler entry point} in a + * compiled method. This entry point is used when returning to a method to handle an exception * thrown by a callee. It is not used for routing implicit exceptions. Therefore, it does not need * to save any registers as HotSpot uses a caller save convention. *

    diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java Tue Mar 18 11:51:37 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) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java --- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java Tue Mar 18 11:51:37 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) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java --- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java Tue Mar 18 11:51:37 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: diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/DecompilerTest.java --- /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 Tue Mar 18 11:51:37 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"); + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java --- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java Tue Mar 18 11:07:47 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); - } -} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java --- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java Tue Mar 18 11:51:37 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.*; diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerIfSimplify.java --- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerIfSimplify.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerIfSimplify.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/block/DecompilerIfBlock.java --- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/block/DecompilerIfBlock.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/block/DecompilerIfBlock.java Tue Mar 18 11:51:37 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 diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Tue Mar 18 11:51:37 2014 -0700 @@ -99,11 +99,6 @@ public Block retSuccessor; public boolean endsWithRet = false; - public BitSet localsLiveIn; - public BitSet localsLiveOut; - private BitSet localsLiveGen; - private BitSet localsLiveKill; - public Block exceptionDispatchBlock() { if (successors.size() > 0 && successors.get(successors.size() - 1) instanceof ExceptionDispatchBlock) { return successors.get(successors.size() - 1); @@ -167,6 +162,8 @@ private Block[] blockMap; public Block[] loopHeaders; + public LocalLiveness liveness; + /** * Creates a new BlockMap instance from bytecode of the given method . * @@ -212,7 +209,8 @@ } if (OptLivenessAnalysis.getValue()) { try (Scope s = Debug.scope("LivenessAnalysis")) { - computeLiveness(); + liveness = method.getMaxLocals() <= 64 ? new SmallLocalLiveness() : new LargeLocalLiveness(); + liveness.computeLiveness(); } catch (Throwable e) { throw Debug.handle(e); } @@ -729,153 +727,225 @@ return loops; } - private void computeLiveness() { - for (Block block : blocks) { - computeLocalLiveness(block); - } + /** + * Encapsulates the liveness calculation, so that subclasses for locals <= 64 and locals > 64 + * can be implemented. + */ + public abstract class LocalLiveness { + + private void computeLiveness() { + for (Block block : blocks) { + computeLocalLiveness(block); + } - boolean changed; - int iteration = 0; - do { - Debug.log("Iteration %d", iteration); - changed = false; - for (int i = blocks.size() - 1; i >= 0; i--) { - Block block = blocks.get(i); - Debug.log(" start B%d [%d, %d] in: %s out: %s gen: %s kill: %s", block.blockID, block.startBci, block.endBci, block.localsLiveIn, block.localsLiveOut, block.localsLiveGen, - block.localsLiveKill); + boolean changed; + int iteration = 0; + do { + Debug.log("Iteration %d", iteration); + changed = false; + for (int i = blocks.size() - 1; i >= 0; i--) { + Block block = blocks.get(i); + int blockID = block.blockID; + // log statements in IFs because debugLiveX creates a new String + if (Debug.isLogEnabled()) { + Debug.log(" start B%d [%d, %d] in: %s out: %s gen: %s kill: %s", block.blockID, block.startBci, block.endBci, debugLiveIn(blockID), debugLiveOut(blockID), + debugLiveGen(blockID), debugLiveKill(blockID)); + } - boolean blockChanged = (iteration == 0); - if (block.successors.size() > 0) { - int oldCardinality = block.localsLiveOut.cardinality(); - for (Block sux : block.successors) { - Debug.log(" Successor B%d: %s", sux.blockID, sux.localsLiveIn); - block.localsLiveOut.or(sux.localsLiveIn); + boolean blockChanged = (iteration == 0); + if (block.successors.size() > 0) { + int oldCardinality = liveOutCardinality(blockID); + for (Block sux : block.successors) { + if (Debug.isLogEnabled()) { + Debug.log(" Successor B%d: %s", sux.blockID, debugLiveIn(sux.blockID)); + } + propagateLiveness(blockID, sux.blockID); + } + blockChanged |= (oldCardinality != liveOutCardinality(blockID)); } - blockChanged |= (oldCardinality != block.localsLiveOut.cardinality()); + + if (blockChanged) { + updateLiveness(blockID); + if (Debug.isLogEnabled()) { + Debug.log(" end B%d [%d, %d] in: %s out: %s gen: %s kill: %s", block.blockID, block.startBci, block.endBci, debugLiveIn(blockID), debugLiveOut(blockID), + debugLiveGen(blockID), debugLiveKill(blockID)); + } + } + changed |= blockChanged; } - - if (blockChanged) { - block.localsLiveIn.clear(); - block.localsLiveIn.or(block.localsLiveOut); - block.localsLiveIn.andNot(block.localsLiveKill); - block.localsLiveIn.or(block.localsLiveGen); - Debug.log(" end B%d [%d, %d] in: %s out: %s gen: %s kill: %s", block.blockID, block.startBci, block.endBci, block.localsLiveIn, block.localsLiveOut, block.localsLiveGen, - block.localsLiveKill); - } - changed |= blockChanged; - } - iteration++; - } while (changed); - } - - private void computeLocalLiveness(Block block) { - block.localsLiveIn = new BitSet(method.getMaxLocals()); - block.localsLiveOut = new BitSet(method.getMaxLocals()); - block.localsLiveGen = new BitSet(method.getMaxLocals()); - block.localsLiveKill = new BitSet(method.getMaxLocals()); - - if (block.startBci < 0 || block.endBci < 0) { - return; + iteration++; + } while (changed); } - stream.setBCI(block.startBci); - while (stream.currentBCI() <= block.endBci) { - switch (stream.currentBC()) { - case LLOAD: - case DLOAD: - loadTwo(block, stream.readLocalIndex()); - break; - case LLOAD_0: - case DLOAD_0: - loadTwo(block, 0); - break; - case LLOAD_1: - case DLOAD_1: - loadTwo(block, 1); - break; - case LLOAD_2: - case DLOAD_2: - loadTwo(block, 2); - break; - case LLOAD_3: - case DLOAD_3: - loadTwo(block, 3); - break; - case ILOAD: - case IINC: - case FLOAD: - case ALOAD: - case RET: - loadOne(block, stream.readLocalIndex()); - break; - case ILOAD_0: - case FLOAD_0: - case ALOAD_0: - loadOne(block, 0); - break; - case ILOAD_1: - case FLOAD_1: - case ALOAD_1: - loadOne(block, 1); - break; - case ILOAD_2: - case FLOAD_2: - case ALOAD_2: - loadOne(block, 2); - break; - case ILOAD_3: - case FLOAD_3: - case ALOAD_3: - loadOne(block, 3); - break; + /** + * Returns whether the local is live at the beginning of the given block. + */ + public abstract boolean localIsLiveIn(Block block, int local); + + /** + * Returns whether the local is live at the end of the given block. + */ + public abstract boolean localIsLiveOut(Block block, int local); + + /** + * Returns a string representation of the liveIn values of the given block. + */ + protected abstract String debugLiveIn(int blockID); + + /** + * Returns a string representation of the liveOut values of the given block. + */ + protected abstract String debugLiveOut(int blockID); + + /** + * Returns a string representation of the liveGen values of the given block. + */ + protected abstract String debugLiveGen(int blockID); + + /** + * Returns a string representation of the liveKill values of the given block. + */ + protected abstract String debugLiveKill(int blockID); + + /** + * Returns the number of live locals at the end of the given block. + */ + protected abstract int liveOutCardinality(int blockID); + + /** + * Adds all locals the are in the liveIn of the successor to the liveOut of the block. + */ + protected abstract void propagateLiveness(int blockID, int successorID); + + /** + * Calculates a new liveIn for the given block from liveOut, liveKill and liveGen. + */ + protected abstract void updateLiveness(int blockID); + + /** + * Adds the local to liveGen if it wasn't already killed in this block. + */ + protected abstract void loadOne(int blockID, int local); + + /** + * Add this local to liveKill if it wasn't already generated in this block. + */ + protected abstract void storeOne(int blockID, int local); - case LSTORE: - case DSTORE: - storeTwo(block, stream.readLocalIndex()); - break; - case LSTORE_0: - case DSTORE_0: - storeTwo(block, 0); - break; - case LSTORE_1: - case DSTORE_1: - storeTwo(block, 1); - break; - case LSTORE_2: - case DSTORE_2: - storeTwo(block, 2); - break; - case LSTORE_3: - case DSTORE_3: - storeTwo(block, 3); - break; - case ISTORE: - case FSTORE: - case ASTORE: - storeOne(block, stream.readLocalIndex()); - break; - case ISTORE_0: - case FSTORE_0: - case ASTORE_0: - storeOne(block, 0); - break; - case ISTORE_1: - case FSTORE_1: - case ASTORE_1: - storeOne(block, 1); - break; - case ISTORE_2: - case FSTORE_2: - case ASTORE_2: - storeOne(block, 2); - break; - case ISTORE_3: - case FSTORE_3: - case ASTORE_3: - storeOne(block, 3); - break; + private void computeLocalLiveness(Block block) { + if (block.startBci < 0 || block.endBci < 0) { + return; } - stream.next(); + int blockID = block.blockID; + stream.setBCI(block.startBci); + while (stream.currentBCI() <= block.endBci) { + switch (stream.currentBC()) { + case LLOAD: + case DLOAD: + loadTwo(blockID, stream.readLocalIndex()); + break; + case LLOAD_0: + case DLOAD_0: + loadTwo(blockID, 0); + break; + case LLOAD_1: + case DLOAD_1: + loadTwo(blockID, 1); + break; + case LLOAD_2: + case DLOAD_2: + loadTwo(blockID, 2); + break; + case LLOAD_3: + case DLOAD_3: + loadTwo(blockID, 3); + break; + case ILOAD: + case IINC: + case FLOAD: + case ALOAD: + case RET: + loadOne(blockID, stream.readLocalIndex()); + break; + case ILOAD_0: + case FLOAD_0: + case ALOAD_0: + loadOne(blockID, 0); + break; + case ILOAD_1: + case FLOAD_1: + case ALOAD_1: + loadOne(blockID, 1); + break; + case ILOAD_2: + case FLOAD_2: + case ALOAD_2: + loadOne(blockID, 2); + break; + case ILOAD_3: + case FLOAD_3: + case ALOAD_3: + loadOne(blockID, 3); + break; + + case LSTORE: + case DSTORE: + storeTwo(blockID, stream.readLocalIndex()); + break; + case LSTORE_0: + case DSTORE_0: + storeTwo(blockID, 0); + break; + case LSTORE_1: + case DSTORE_1: + storeTwo(blockID, 1); + break; + case LSTORE_2: + case DSTORE_2: + storeTwo(blockID, 2); + break; + case LSTORE_3: + case DSTORE_3: + storeTwo(blockID, 3); + break; + case ISTORE: + case FSTORE: + case ASTORE: + storeOne(blockID, stream.readLocalIndex()); + break; + case ISTORE_0: + case FSTORE_0: + case ASTORE_0: + storeOne(blockID, 0); + break; + case ISTORE_1: + case FSTORE_1: + case ASTORE_1: + storeOne(blockID, 1); + break; + case ISTORE_2: + case FSTORE_2: + case ASTORE_2: + storeOne(blockID, 2); + break; + case ISTORE_3: + case FSTORE_3: + case ASTORE_3: + storeOne(blockID, 3); + break; + } + stream.next(); + } + } + + private void loadTwo(int blockID, int local) { + loadOne(blockID, local); + loadOne(blockID, local + 1); + } + + private void storeTwo(int blockID, int local) { + storeOne(blockID, local); + storeOne(blockID, local + 1); } } @@ -889,25 +959,182 @@ return map; } - private static void loadTwo(Block block, int local) { - loadOne(block, local); - loadOne(block, local + 1); - } + public final class SmallLocalLiveness extends LocalLiveness { + /* + * local n is represented by the bit accessible as (1 << n) + */ + + private final long[] localsLiveIn; + private final long[] localsLiveOut; + private final long[] localsLiveGen; + private final long[] localsLiveKill; + + public SmallLocalLiveness() { + localsLiveIn = new long[blocks.size()]; + localsLiveOut = new long[blocks.size()]; + localsLiveGen = new long[blocks.size()]; + localsLiveKill = new long[blocks.size()]; + } + + private String debugString(long value) { + StringBuilder str = new StringBuilder("{"); + long current = value; + for (int i = 0; i < method.getMaxLocals(); i++) { + if ((current & 1L) == 1L) { + if (str.length() > 1) { + str.append(", "); + } + str.append(i); + } + current >>= 1; + } + return str.append('}').toString(); + } + + @Override + protected String debugLiveIn(int blockID) { + return debugString(localsLiveIn[blockID]); + } + + @Override + protected String debugLiveOut(int blockID) { + return debugString(localsLiveOut[blockID]); + } + + @Override + protected String debugLiveGen(int blockID) { + return debugString(localsLiveGen[blockID]); + } - private static void loadOne(Block block, int local) { - if (!block.localsLiveKill.get(local)) { - block.localsLiveGen.set(local); + @Override + protected String debugLiveKill(int blockID) { + return debugString(localsLiveKill[blockID]); + } + + @Override + protected int liveOutCardinality(int blockID) { + return Long.bitCount(localsLiveOut[blockID]); + } + + @Override + protected void propagateLiveness(int blockID, int successorID) { + localsLiveOut[blockID] |= localsLiveIn[successorID]; + } + + @Override + protected void updateLiveness(int blockID) { + localsLiveIn[blockID] = (localsLiveOut[blockID] & ~localsLiveKill[blockID]) | localsLiveGen[blockID]; + } + + @Override + protected void loadOne(int blockID, int local) { + long bit = 1L << local; + if ((localsLiveKill[blockID] & bit) == 0L) { + localsLiveGen[blockID] |= bit; + } + } + + @Override + protected void storeOne(int blockID, int local) { + long bit = 1L << local; + if ((localsLiveGen[blockID] & bit) == 0L) { + localsLiveKill[blockID] |= bit; + } + } + + @Override + public boolean localIsLiveIn(Block block, int local) { + int blockID = block.blockID; + return blockID >= Integer.MAX_VALUE ? false : (localsLiveIn[blockID] & (1L << local)) != 0L; + } + + @Override + public boolean localIsLiveOut(Block block, int local) { + int blockID = block.blockID; + return blockID >= Integer.MAX_VALUE ? false : (localsLiveOut[blockID] & (1L << local)) != 0L; } } - private static void storeTwo(Block block, int local) { - storeOne(block, local); - storeOne(block, local + 1); - } + public final class LargeLocalLiveness extends LocalLiveness { + private BitSet[] localsLiveIn; + private BitSet[] localsLiveOut; + private BitSet[] localsLiveGen; + private BitSet[] localsLiveKill; + + public LargeLocalLiveness() { + localsLiveIn = new BitSet[blocks.size()]; + localsLiveOut = new BitSet[blocks.size()]; + localsLiveGen = new BitSet[blocks.size()]; + localsLiveKill = new BitSet[blocks.size()]; + for (int i = 0; i < blocks.size(); i++) { + localsLiveIn[i] = new BitSet(method.getMaxLocals()); + localsLiveOut[i] = new BitSet(method.getMaxLocals()); + localsLiveGen[i] = new BitSet(method.getMaxLocals()); + localsLiveKill[i] = new BitSet(method.getMaxLocals()); + } + } + + @Override + protected String debugLiveIn(int blockID) { + return localsLiveIn[blockID].toString(); + } + + @Override + protected String debugLiveOut(int blockID) { + return localsLiveOut[blockID].toString(); + } + + @Override + protected String debugLiveGen(int blockID) { + return localsLiveGen[blockID].toString(); + } + + @Override + protected String debugLiveKill(int blockID) { + return localsLiveKill[blockID].toString(); + } - private static void storeOne(Block block, int local) { - if (!block.localsLiveGen.get(local)) { - block.localsLiveKill.set(local); + @Override + protected int liveOutCardinality(int blockID) { + return localsLiveOut[blockID].cardinality(); + } + + @Override + protected void propagateLiveness(int blockID, int successorID) { + localsLiveOut[blockID].or(localsLiveIn[successorID]); + } + + @Override + protected void updateLiveness(int blockID) { + BitSet liveIn = localsLiveIn[blockID]; + liveIn.clear(); + liveIn.or(localsLiveOut[blockID]); + liveIn.andNot(localsLiveKill[blockID]); + liveIn.or(localsLiveGen[blockID]); + } + + @Override + protected void loadOne(int blockID, int local) { + if (!localsLiveKill[blockID].get(local)) { + localsLiveGen[blockID].set(local); + } + } + + @Override + protected void storeOne(int blockID, int local) { + if (!localsLiveGen[blockID].get(local)) { + localsLiveKill[blockID].set(local); + } + } + + @Override + public boolean localIsLiveIn(Block block, int local) { + return block.blockID >= Integer.MAX_VALUE ? true : localsLiveIn[block.blockID].get(local); + } + + @Override + public boolean localIsLiveOut(Block block, int local) { + return block.blockID >= Integer.MAX_VALUE ? true : localsLiveOut[block.blockID].get(local); } } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java Tue Mar 18 11:51:37 2014 -0700 @@ -32,6 +32,8 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.Node.Verbosity; +import com.oracle.graal.java.BciBlockMapping.Block; +import com.oracle.graal.java.BciBlockMapping.LocalLiveness; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; @@ -203,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); } @@ -301,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; } @@ -315,13 +317,21 @@ } } - public void clearNonLiveLocals(BitSet liveness) { + public void clearNonLiveLocals(Block block, LocalLiveness liveness, boolean liveIn) { if (liveness == null) { return; } - for (int i = 0; i < locals.length; i++) { - if (!liveness.get(i)) { - locals[i] = null; + if (liveIn) { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveIn(block, i)) { + locals[i] = null; + } + } + } else { + for (int i = 0; i < locals.length; i++) { + if (!liveness.localIsLiveOut(block, i)) { + locals[i] = null; + } } } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Tue Mar 18 11:51:37 2014 -0700 @@ -42,6 +42,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.java.BciBlockMapping.Block; import com.oracle.graal.java.BciBlockMapping.ExceptionDispatchBlock; +import com.oracle.graal.java.BciBlockMapping.LocalLiveness; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.calc.FloatConvertNode.FloatConvert; @@ -69,7 +70,7 @@ public static final class RuntimeCalls { public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", NullPointerException.class); - public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", IndexOutOfBoundsException.class, int.class); + public static final ForeignCallDescriptor CREATE_OUT_OF_BOUNDS_EXCEPTION = new ForeignCallDescriptor("createOutOfBoundsException", ArrayIndexOutOfBoundsException.class, int.class); } /** @@ -159,6 +160,7 @@ } private Block[] loopHeaders; + private LocalLiveness liveness; /** * Gets the current frame state being processed by this builder. @@ -225,6 +227,7 @@ // compute the block map, setup exception handlers and get the entrypoint(s) BciBlockMapping blockMap = BciBlockMapping.create(method); loopHeaders = blockMap.loopHeaders; + liveness = blockMap.liveness; lastInstr = currentGraph.start(); if (isSynchronized(method.getModifiers())) { @@ -233,7 +236,7 @@ methodSynchronizedObject = synchronizedObject(frameState, method); lastInstr = genMonitorEnter(methodSynchronizedObject); } - frameState.clearNonLiveLocals(blockMap.startBlock.localsLiveIn); + frameState.clearNonLiveLocals(blockMap.startBlock, liveness, true); ((StateSplit) lastInstr).setStateAfter(frameState.create(0)); if (graphBuilderConfig.eagerInfopointMode()) { @@ -1228,7 +1231,7 @@ createInvoke(callTarget, resultType); } else { assert bci() == currentBlock.endBci; - frameState.clearNonLiveLocals(currentBlock.localsLiveOut); + frameState.clearNonLiveLocals(currentBlock, liveness, false); InvokeWithExceptionNode invoke = createInvokeWithException(callTarget, resultType); @@ -1544,7 +1547,7 @@ Target target = checkLoopExit(block.firstInstruction, block, state); FixedNode result = target.fixed; block.entryState = target.state == state ? state.copy() : target.state; - block.entryState.clearNonLiveLocals(block.localsLiveIn); + block.entryState.clearNonLiveLocals(block, liveness, true); Debug.log("createTarget %s: first visit, result: %s", block, block.firstInstruction); return result; @@ -1823,7 +1826,7 @@ bci = stream.currentBCI(); if (bci > block.endBci) { - frameState.clearNonLiveLocals(currentBlock.localsLiveOut); + frameState.clearNonLiveLocals(currentBlock, liveness, false); } if (lastInstr instanceof StateSplit) { if (lastInstr.getClass() == AbstractBeginNode.class) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopParseLong.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopParseLong.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopParseLong.java Tue Mar 18 11:51:37 2014 -0700 @@ -27,6 +27,25 @@ public class LoopParseLong extends JTTTest { + @SuppressWarnings("unused") + public static long testShortened(String s, int radix) throws NumberFormatException { + long result = 0; + boolean negative = false; + int len = s.length(); + char firstChar = s.charAt(0); + if (firstChar < '0') { + if (firstChar == '-') { + negative = true; + } else if (firstChar != '+') { + throw new NumberFormatException(); + } + if (len == 1) { + throw new NumberFormatException(); + } + } + return result; + } + public static long test(String s, int radix) throws NumberFormatException { if (s == null) { throw new NumberFormatException("null"); @@ -81,6 +100,8 @@ @LongTest public void run0() throws Throwable { + runTest("testShortened", "7", 10); + runTest("testShortened", "-100", 10); runTest("test", "7", 10); runTest("test", "-100", 10); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Tue Mar 18 11:51:37 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(); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java Tue Mar 18 11:51:37 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); } } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java Tue Mar 18 11:51:37 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) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Tue Mar 18 11:51:37 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)); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java Tue Mar 18 11:51:37 2014 -0700 @@ -222,7 +222,8 @@ } } else if (b instanceof InstanceOfNode) { InstanceOfNode instanceOfB = (InstanceOfNode) b; - if (instanceOfA.object() == instanceOfB.object() && !instanceOfA.type().isAssignableFrom(instanceOfB.type()) && !instanceOfB.type().isAssignableFrom(instanceOfA.type())) { + if (instanceOfA.object() == instanceOfB.object() && !instanceOfA.type().isInterface() && !instanceOfB.type().isInterface() && + !instanceOfA.type().isAssignableFrom(instanceOfB.type()) && !instanceOfB.type().isAssignableFrom(instanceOfA.type())) { // Two instanceof on the same value with mutually exclusive types. JavaTypeProfile profileA = instanceOfA.profile(); JavaTypeProfile profileB = instanceOfB.profile(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java Tue Mar 18 11:51:37 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java Tue Mar 18 11:51:37 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 diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java Tue Mar 18 11:51:37 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())); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FrameStateAssignmentPhase.java Tue Mar 18 11:51:37 2014 -0700 @@ -59,8 +59,9 @@ if (node instanceof StateSplit) { StateSplit stateSplit = (StateSplit) node; - if (stateSplit.stateAfter() != null) { - FrameState newState = stateSplit.stateAfter(); + FrameState stateAfter = stateSplit.stateAfter(); + if (stateAfter != null) { + FrameState newState = stateAfter; stateSplit.setStateAfter(null); return newState; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Tue Mar 18 11:51:37 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 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()) : "") + remainingInvokes; } } - - private static class CompiledMethodInfo { - - private int lowLevelNodes; - - public CompiledMethodInfo() { - } - - public int lowLevelNodeCount() { - return lowLevelNodes; - } - - public void setLowLevelNodeCount(int lowLevelNodes) { - this.lowLevelNodes = lowLevelNodes; - } - - } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java Tue Mar 18 11:51:37 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()); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java Tue Mar 18 11:51:37 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)); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java Tue Mar 18 11:51:37 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Tue Mar 18 11:51:37 2014 -0700 @@ -36,7 +36,35 @@ */ public abstract class BasePhase { - private final String name; + /** + * Phase name lazily computed from the phase class. + */ + class Name extends LazyName { + + @Override + public String createString() { + String s = BasePhase.this.getClass().getSimpleName(); + return s.substring(0, s.length() - "Phase".length()); + } + } + + /** + * Lazily computed debug value name composed of a prefix and a phase's name. + */ + class DebugValueName extends LazyName { + final String prefix; + + public DebugValueName(String prefix) { + this.prefix = prefix; + } + + @Override + public String createString() { + return prefix + name; + } + } + + private final CharSequence name; private final DebugTimer phaseTimer; private final DebugMetric phaseMetric; @@ -49,25 +77,20 @@ } protected BasePhase() { - String nm = this.getClass().getSimpleName(); - if (nm.endsWith("Phase")) { - name = nm.substring(0, nm.length() - "Phase".length()); - } else { - name = nm; - } - assert checkName(name); - phaseTimer = Debug.timer("PhaseTime_" + name); - phaseMetric = Debug.metric("PhaseCount_" + name); + name = new Name(); + assert checkName(name.toString()); + phaseTimer = Debug.timer(new DebugValueName("PhaseTime_")); + phaseMetric = Debug.metric(new DebugValueName("PhaseCount_")); } protected BasePhase(String name) { assert checkName(name); this.name = name; - phaseTimer = Debug.timer("PhaseTime_" + name); - phaseMetric = Debug.metric("PhaseCount_" + name); + phaseTimer = Debug.timer(new DebugValueName("PhaseTime_")); + phaseMetric = Debug.metric(new DebugValueName("PhaseCount_")); } - protected String getDetailedName() { + protected CharSequence getDetailedName() { return getName(); } @@ -88,7 +111,7 @@ } } - public final String getName() { + public final CharSequence getName() { return name; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Tue Mar 18 11:51:37 2014 -0700 @@ -177,6 +177,8 @@ @Option(help = "") public static final OptionValue HotSpotPrintCompilation = new OptionValue<>(false); @Option(help = "") + public static final OptionValue HotSpotCIPrintCompilerName = new OptionValue<>(false); + @Option(help = "") public static final OptionValue HotSpotPrintInlining = new OptionValue<>(false); // Register allocator debugging diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/LazyName.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/LazyName.java Tue Mar 18 11:51:37 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.phases; + +import com.oracle.graal.debug.*; + +/** + * A name whose {@link String} value is computed only when it is needed. This is useful in + * combination with debugging facilities such as {@link Debug#scope(CharSequence, Object...)} where + * the {@link String} value of a name is only needed if debugging is enabled. + */ +public abstract class LazyName implements CharSequence { + + private String value; + + public int length() { + return toString().length(); + } + + public char charAt(int index) { + return toString().charAt(index); + } + + public CharSequence subSequence(int start, int end) { + return toString().subSequence(start, end); + } + + @Override + public final String toString() { + if (value == null) { + value = createString(); + } + return value; + } + + /** + * Creates the {@link String} value of this name. + */ + protected abstract String createString(); +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Tue Mar 18 11:51:37 2014 -0700 @@ -292,7 +292,7 @@ } private void printSchedule(String desc) { - if (Debug.isEnabled()) { + if (Debug.isLogEnabled()) { Debug.printf("=== %s / %s / %s (%s) ===\n", getCFG().getStartBlock().getBeginNode().graph(), selectedStrategy, memsched, desc); for (Block b : getCFG().getBlocks()) { Debug.printf("==== b: %s (loopDepth: %s). ", b, b.getLoopDepth()); @@ -388,8 +388,7 @@ private void assignBlockToNode(ScheduledNode node, SchedulingStrategy strategy) { assert !node.isDeleted(); - Block prevBlock = cfg.getNodeToBlock().get(node); - if (prevBlock != null) { + if (cfg.getNodeToBlock().containsKey(node)) { return; } // PhiNodes, ProxyNodes and FixedNodes should already have been placed in blocks by @@ -418,6 +417,7 @@ block = latestBlock(node, strategy); } if (block == null) { + // handle nodes without usages block = earliestBlock; } else if (strategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS && !(node instanceof VirtualObjectNode)) { // schedule at the latest position possible in the outermost loop possible @@ -752,10 +752,14 @@ if (!(usage instanceof FrameState)) { throw new SchedulingError(usage.toString()); } - // If a FrameState belongs to a BeginNode then it's inputs will be placed at the - // common dominator of all EndNodes. - for (Node pred : unscheduledUsage.cfgPredecessors()) { - closure.apply(cfg.getNodeToBlock().get(pred)); + if (unscheduledUsage instanceof StartNode) { + closure.apply(cfg.getNodeToBlock().get(unscheduledUsage)); + } else { + // If a FrameState belongs to a BeginNode then it's inputs will be placed at + // the common dominator of all EndNodes. + for (Node pred : unscheduledUsage.cfgPredecessors()) { + closure.apply(cfg.getNodeToBlock().get(pred)); + } } } else { // For the time being, FrameStates can only be connected to NodeWithState. diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java Tue Mar 18 11:51:37 2014 -0700 @@ -26,7 +26,12 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.VirtualState.NodeClosure; +import com.oracle.graal.nodes.cfg.*; import com.oracle.graal.phases.graph.*; +import com.oracle.graal.phases.graph.ReentrantBlockIterator.*; +import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.phases.schedule.SchedulePhase.*; public final class GraphOrder { @@ -34,9 +39,9 @@ } /** - * Asserts that there are no (invalid) cycles in the given graph. First, an ordered list of all - * nodes in the graph (a total ordering) is created. A second run over this list checks whether - * inputs are scheduled before their usages. + * Quick (and imprecise) assertion that there are no (invalid) cycles in the given graph. First, + * an ordered list of all nodes in the graph (a total ordering) is created. A second run over + * this list checks whether inputs are scheduled before their usages. * * @param graph the graph to be checked. * @throws AssertionError if a cycle was detected. @@ -62,7 +67,6 @@ } visited.mark(node); } - return true; } @@ -80,34 +84,161 @@ } private static void visitForward(ArrayList nodes, NodeBitMap visited, Node node, boolean floatingOnly) { - if (node != null && !visited.isMarked(node)) { - assert !floatingOnly || !(node instanceof FixedNode) : "unexpected reference to fixed node: " + node + " (this indicates an unexpected cycle)"; - visited.mark(node); - FrameState stateAfter = null; - if (node instanceof StateSplit) { - stateAfter = ((StateSplit) node).stateAfter(); - } - for (Node input : node.inputs()) { - if (input != stateAfter) { - visitForward(nodes, visited, input, true); + try { + 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); + } + visited.mark(node); + FrameState stateAfter = null; + if (node instanceof StateSplit) { + stateAfter = ((StateSplit) node).stateAfter(); + } + for (Node input : node.inputs()) { + if (input != stateAfter) { + visitForward(nodes, visited, input, true); + } + } + if (node instanceof EndNode) { + EndNode end = (EndNode) node; + for (PhiNode phi : end.merge().phis()) { + visitForward(nodes, visited, phi.valueAt(end), true); + } + } + nodes.add(node); + if (node instanceof MergeNode) { + for (PhiNode phi : ((MergeNode) node).phis()) { + visited.mark(phi); + nodes.add(phi); + } + } + if (stateAfter != null) { + visitForward(nodes, visited, stateAfter, true); } } - if (node instanceof EndNode) { - EndNode end = (EndNode) node; - for (PhiNode phi : end.merge().phis()) { - visitForward(nodes, visited, phi.valueAt(end), true); - } - } - nodes.add(node); - if (node instanceof MergeNode) { - for (PhiNode phi : ((MergeNode) node).phis()) { - visited.mark(phi); - nodes.add(phi); - } - } - if (stateAfter != null) { - visitForward(nodes, visited, stateAfter, true); - } + } catch (GraalInternalError e) { + e.addContext(node); + throw e; } } + + /** + * This method schedules the graph and makes sure that, for every node, all inputs are available + * at the position where it is scheduled. This is a very expensive assertion. + * + * Also, this phase assumes ProxyNodes to exist at LoopExitNodes, so that it cannot be run after + * phases that remove loop proxies or move proxies to BeginNodes. + */ + public static boolean assertSchedulableGraph(final StructuredGraph graph) { + try { + final SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, MemoryScheduling.NONE); + final IdentityHashMap loopEntryStates = new IdentityHashMap<>(); + schedule.apply(graph, false); + + BlockIteratorClosure closure = new BlockIteratorClosure() { + + @Override + protected List processLoop(Loop loop, NodeBitMap initialState) { + return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates; + } + + @Override + protected NodeBitMap processBlock(final Block block, final NodeBitMap currentState) { + final List list = schedule.getBlockToNodesMap().get(block); + + /* + * A stateAfter is not valid directly after its associated state split, but + * right before the next fixed node. Therefore a pending stateAfter is kept that + * will be checked at the correct position. + */ + FrameState pendingStateAfter = null; + for (final ScheduledNode node : list) { + FrameState stateAfter = node instanceof StateSplit ? ((StateSplit) node).stateAfter() : null; + + if (pendingStateAfter != null && node instanceof FixedNode) { + pendingStateAfter.applyToNonVirtual(new NodeClosure() { + public void apply(Node usage, Node nonVirtualNode) { + assert currentState.isMarked(nonVirtualNode) : nonVirtualNode + " not available at virtualstate " + usage + " before " + node + " in block " + block + " \n" + list; + } + }); + pendingStateAfter = null; + } + + if (node instanceof MergeNode) { + // phis aren't scheduled, so they need to be added explicitly + currentState.markAll(((MergeNode) node).phis()); + if (node instanceof LoopBeginNode) { + // remember the state at the loop entry, it's restored at exits + loopEntryStates.put((LoopBeginNode) node, currentState.copy()); + } + } else if (node instanceof ProxyNode) { + for (Node input : node.inputs()) { + if (input != ((ProxyNode) node).proxyPoint()) { + assert currentState.isMarked(input) : input + " not available at " + node + " in block " + block + "\n" + list; + } + } + } else if (node instanceof LoopExitNode) { + // the contents of the loop are only accessible via proxies at the exit + currentState.clearAll(); + currentState.markAll(loopEntryStates.get(((LoopExitNode) node).loopBegin())); + // Loop proxies aren't scheduled, so they need to be added explicitly + currentState.markAll(((LoopExitNode) node).proxies()); + } else { + for (Node input : node.inputs()) { + if (input != stateAfter) { + assert currentState.isMarked(input) : input + " not available at " + node + " in block " + block + "\n" + list; + } + } + } + if (node instanceof AbstractEndNode) { + MergeNode merge = ((AbstractEndNode) node).merge(); + for (PhiNode phi : merge.phis()) { + assert currentState.isMarked(phi.valueAt((AbstractEndNode) node)) : phi.valueAt((AbstractEndNode) node) + " not available at phi " + phi + " / end " + node + + " in block " + block; + } + } + if (stateAfter != null) { + assert pendingStateAfter == null; + pendingStateAfter = stateAfter; + } + currentState.mark(node); + } + if (pendingStateAfter != null) { + pendingStateAfter.applyToNonVirtual(new NodeClosure() { + public void apply(Node usage, Node nonVirtualNode) { + assert currentState.isMarked(nonVirtualNode) : nonVirtualNode + " not available at virtualstate " + usage + " at end of block " + block + " \n" + list; + } + }); + } + return currentState; + } + + @Override + protected NodeBitMap merge(Block merge, List states) { + NodeBitMap result = states.get(0); + for (int i = 1; i < states.size(); i++) { + result.intersect(states.get(i)); + } + return result; + } + + @Override + protected NodeBitMap getInitialState() { + return graph.createNodeBitMap(); + } + + @Override + protected NodeBitMap cloneState(NodeBitMap oldState) { + return oldState.copy(); + } + }; + + ReentrantBlockIterator.apply(closure, schedule.getCFG().getStartBlock()); + + } catch (Throwable t) { + throw new AssertionError("unschedulable graph", t); + } + return true; + } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/MethodDebugValueName.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/MethodDebugValueName.java Tue Mar 18 11:51:37 2014 -0700 @@ -0,0 +1,45 @@ +/* + * 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.phases.util; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.phases.*; + +/** + * Lazily computed debug value name composed of a prefix and a {@linkplain JavaMethod#getName() + * method name}. + */ +public class MethodDebugValueName extends LazyName { + final String prefix; + final JavaMethod method; + + public MethodDebugValueName(String prefix, JavaMethod method) { + this.prefix = prefix; + this.method = method; + } + + @Override + public String createString() { + return prefix + "[" + method.getName() + "]"; + } +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java Tue Mar 18 11:51:37 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"); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Tue Mar 18 11:51:37 2014 -0700 @@ -202,7 +202,7 @@ for (Object o : Debug.context()) { JavaMethod method = asJavaMethod(o); if (method != null) { - if (lastMethodOrGraph == null || !asJavaMethod(lastMethodOrGraph).equals(method)) { + if (lastMethodOrGraph == null || asJavaMethod(lastMethodOrGraph) == null || !asJavaMethod(lastMethodOrGraph).equals(method)) { result.add(MetaUtil.format("%H::%n(%p)", method)); } else { // This prevents multiple adjacent method context objects for the same method diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ArraysSubstitutionsTest.java Tue Mar 18 11:51:37 2014 -0700 @@ -329,4 +329,25 @@ return Arrays.equals(a, b); } + @Test + public void testEqualsNodeGVN() { + test("testEqualsNodeGVNSnippet", true); + } + + public static int[] intArrayCompare = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; + public static int[] intArray; + + public static boolean testEqualsNodeGVNSnippet(boolean b) { + int[] newIntArray = new int[]{0, 2, 3, 4, 5, 6, 7, 8, 9}; + intArray = newIntArray; + + if (b) { + newIntArray[0] = 1; + return Arrays.equals(newIntArray, intArrayCompare); + } else { + newIntArray[0] = 1; + return Arrays.equals(newIntArray, intArrayCompare); + } + } + } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Tue Mar 18 11:51:37 2014 -0700 @@ -99,7 +99,7 @@ FrameStateProcessing frameStateProcessing = method.getAnnotation(Snippet.class).removeAllFrameStates() ? FrameStateProcessing.Removal : FrameStateProcessing.CollapseFrameForSingleSideEffect; StructuredGraph newGraph = makeGraph(method, recursiveEntry, recursiveEntry, inliningPolicy(method), frameStateProcessing); - Debug.metric("SnippetNodeCount[" + method.getName() + "]").add(newGraph.getNodeCount()); + Debug.metric(new MethodDebugValueName("SnippetNodeCount", method)).add(newGraph.getNodeCount()); if (!UseSnippetGraphCache) { return newGraph; } @@ -201,8 +201,8 @@ } } } - // We don't have per method guards for macro substitutions but at least respect the - // defaultGuard if there is one. + // We don't have per method guards for macro substitutions but at + // least respect the defaultGuard if there is one. if (macroSubstitution != null && (defaultGuard == null || defaultGuard.execute())) { String originalName = originalName(substituteMethod, macroSubstitution.value()); JavaSignature originalSignature = originalSignature(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic()); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Tue Mar 18 11:51:37 2014 -0700 @@ -97,8 +97,8 @@ protected SnippetInfo(ResolvedJavaMethod method) { this.method = method; - instantiationCounter = Debug.metric("SnippetInstantiationCount[" + method.getName() + "]"); - instantiationTimer = Debug.timer("SnippetInstantiationTime[" + method.getName() + "]"); + instantiationCounter = Debug.metric(new MethodDebugValueName("SnippetInstantiationCount", method)); + instantiationTimer = Debug.timer(new MethodDebugValueName("SnippetInstantiationTime", method)); assert Modifier.isStatic(method.getModifiers()) : "snippet method must be static: " + MetaUtil.format("%H.%n", method); int count = method.getSignature().getParameterCount(false); constantParameters = new boolean[count]; @@ -876,10 +876,11 @@ @Override public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) { - if (mmap != null && newNode != null) { + if (mmap != null) { for (Node usage : oldNode.usages().snapshot()) { LocationIdentity identity = getLocationIdentity(usage); - if (identity != null && identity != LocationIdentity.FINAL_LOCATION) { + boolean usageReplaced = false; + if (identity != null && identity != FINAL_LOCATION) { // lastLocationAccess points into the snippet graph. find a proper // MemoryCheckPoint inside the snippet graph MemoryNode lastAccess = mmap.getLastLocationAccess(identity); @@ -888,17 +889,26 @@ if (usage instanceof MemoryAccess) { MemoryAccess access = (MemoryAccess) usage; if (access.getLastLocationAccess() == oldNode) { - assert newNode.graph().isAfterFloatingReadPhase(); + assert oldNode.graph().isAfterFloatingReadPhase(); access.setLastLocationAccess(lastAccess); + usageReplaced = true; } } else { assert usage instanceof MemoryProxy || usage instanceof MemoryPhiNode; usage.replaceFirstInput(oldNode, lastAccess.asNode()); + usageReplaced = true; } } + if (!usageReplaced) { + assert newNode != null : "this branch is only valid if we have a newNode for replacement"; + } } } - oldNode.replaceAtUsages(newNode); + if (newNode == null) { + assert oldNode.usages().isEmpty(); + } else { + oldNode.replaceAtUsages(newNode); + } } }; @@ -1002,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) { @@ -1036,12 +1040,18 @@ returnValue = returnDuplicate.result(); MemoryMapNode mmap = new DuplicateMapper(duplicates, replaceeGraph.start()); if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) { - replacer.replace(replacee, (ValueNode) returnDuplicate.predecessor(), mmap); + replacer.replace(replacee, null, mmap); } else { assert returnValue != null || replacee.usages().isEmpty(); 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ArrayEqualsNode.java Tue Mar 18 11:51:37 2014 -0700 @@ -31,13 +31,12 @@ import com.oracle.graal.graph.spi.*; import com.oracle.graal.lir.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.type.*; /** * Compares two arrays with the same length. */ -public class ArrayEqualsNode extends FloatingNode implements LIRGenLowerable, Canonicalizable { +public class ArrayEqualsNode extends FixedWithNextNode implements LIRGenLowerable, Canonicalizable { /** {@link Kind} of the arrays to compare. */ private final Kind kind; diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java --- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java Tue Mar 18 11:51:37 2014 -0700 @@ -162,7 +162,6 @@ case Int: case Long: case Object: - case NarrowOop: return true; } } else if (category == FPU) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/OptimizedCallTargetInstrumentation.java Tue Mar 18 11:51:37 2014 -0700 @@ -29,8 +29,8 @@ import com.oracle.graal.asm.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.bridge.*; import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.MarkId; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.truffle.*; @@ -51,10 +51,9 @@ @Override public Mark recordMark(Object id) { Mark mark = super.recordMark(id); - if (Integer.valueOf(Marks.MARK_VERIFIED_ENTRY).equals(id)) { - HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig(); + if (MarkId.getEnum((int) id) == MarkId.VERIFIED_ENTRY) { HotSpotRegistersProvider registers = HotSpotGraalRuntime.runtime().getHostProviders().getRegisters(); - injectTailCallCode(config, registers); + injectTailCallCode(HotSpotGraalRuntime.runtime().getConfig(), registers); } return mark; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java Tue Mar 18 11:51:37 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. @@ -60,7 +60,7 @@ } @SuppressWarnings("unused") - public void nodeReplaced(Node oldNode, Node newNode, String reason) { + public void nodeReplaced(Node oldNode, Node newNode, CharSequence reason) { } @Override @@ -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,16 +140,11 @@ if (isMaxSingleCall()) { return true; } - return countPolymorphic() >= 1 || countGeneric() > 0; + return countPolymorphic() >= 1; } @Override - public void nodeReplaced(Node oldNode, Node newNode, String reason) { - trySplit = true; - } - - @Override - protected void notifyCallNodeAdded() { + public void nodeReplaced(Node oldNode, Node newNode, CharSequence reason) { trySplit = true; } @@ -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 diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java Tue Mar 18 11:51:37 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. @@ -136,7 +136,7 @@ return call(caller, args); } - private void invalidate(Node oldNode, Node newNode, String reason) { + private void invalidate(Node oldNode, Node newNode, CharSequence reason) { InstalledCode m = this.installedCode; if (m != null) { CompilerAsserts.neverPartOfCompilation(); @@ -147,7 +147,7 @@ cancelInstalledTask(oldNode, newNode, reason); } - private void cancelInstalledTask(Node oldNode, Node newNode, String reason) { + private void cancelInstalledTask(Node oldNode, Node newNode, CharSequence reason) { Future task = this.installedCodeTask; if (task != null) { task.cancel(true); @@ -298,7 +298,7 @@ } @Override - public void nodeReplaced(Node oldNode, Node newNode, String reason) { + public void nodeReplaced(Node oldNode, Node newNode, CharSequence reason) { compilationProfile.reportNodeReplaced(); invalidate(oldNode, newNode, reason); @@ -382,7 +382,7 @@ } } - private static void logOptimizingUnqueued(OptimizedCallTarget target, Node oldNode, Node newNode, String reason) { + private static void logOptimizingUnqueued(OptimizedCallTarget target, Node oldNode, Node newNode, CharSequence reason) { if (TraceTruffleCompilationDetails.getValue()) { Map properties = new LinkedHashMap<>(); addReplaceProperties(properties, oldNode, newNode); @@ -405,7 +405,7 @@ } } - private static void logOptimizedInvalidated(OptimizedCallTarget target, Node oldNode, Node newNode, String reason) { + private static void logOptimizedInvalidated(OptimizedCallTarget target, Node oldNode, Node newNode, CharSequence reason) { if (TraceTruffleCompilation.getValue()) { Map properties = new LinkedHashMap<>(); addReplaceProperties(properties, oldNode, newNode); @@ -414,7 +414,7 @@ } } - private static void logOptimizingFailed(OptimizedCallTarget callSite, String reason) { + private static void logOptimizingFailed(OptimizedCallTarget callSite, CharSequence reason) { Map properties = new LinkedHashMap<>(); properties.put("Reason", reason); log(0, "opt fail", callSite.toString(), properties); @@ -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 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 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); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java Tue Mar 18 11:51:37 2014 -0700 @@ -78,7 +78,9 @@ graph.stopTrackingInputChange(); graph.stopTrackingUsagesDroppedZero(); - Debug.dump(graph, "after " + getName() + " iteration"); + if (Debug.isDumpEnabled()) { + Debug.dump(graph, "after " + getName() + " iteration"); + } new DeadCodeEliminationPhase().apply(graph); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java Tue Mar 18 11:51:37 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]); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Tue Mar 18 11:51:37 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 PhiNode getCachedPhi(T virtual, Kind kind) { + protected 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; @@ -334,6 +335,13 @@ ObjectState[] objStates = new ObjectState[states.size()]; boolean materialized; do { + Iterator> iter = newState.objectStates.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + if (!virtualObjTemp.contains(entry.getValue())) { + iter.remove(); + } + } mergeEffects.clear(); afterMergeEffects.clear(); materialized = false; @@ -363,7 +371,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 +466,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 +495,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); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Mar 18 11:51:37 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 PhiNode getCachedPhi(T virtual, Kind kind) { + protected 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]); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Tue Mar 18 11:51:37 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)); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java Tue Mar 18 11:51:37 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 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 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()); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java --- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java Tue Mar 18 11:51:37 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") diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ReplaceObserver.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ReplaceObserver.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ReplaceObserver.java Tue Mar 18 11:51:37 2014 -0700 @@ -31,5 +31,5 @@ */ public interface ReplaceObserver { - void nodeReplaced(Node oldNode, Node newNode, String reason); + void nodeReplaced(Node oldNode, Node newNode, CharSequence reason); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java Tue Mar 18 11:51:37 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. *

    * 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. *

    * 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); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/KillException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/KillException.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/KillException.java Tue Mar 18 11:51:37 2014 -0700 @@ -26,7 +26,6 @@ import com.oracle.truffle.api.nodes.*; -// TODO (mlvdv) does this need to extend ControlFlowException? It was originally part of the Ruby Shell. /** * Controls breaking out of an execution context, such as a shell or eval. */ diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/QuitException.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/QuitException.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/QuitException.java Tue Mar 18 11:51:37 2014 -0700 @@ -26,7 +26,6 @@ import com.oracle.truffle.api.nodes.*; -//TODO (mlvdv) does this need to extend ControlFlowException? It was originally part of the Ruby execution environment. /** * Controls breaking out of all executions and ending Truffle execution. */ diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java Tue Mar 18 11:51:37 2014 -0700 @@ -64,6 +64,11 @@ } @Override + public boolean isInlinable() { + return false; + } + + @Override public String toString() { return getParent() != null ? getParent().toString() : super.toString(); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java Tue Mar 18 11:51:37 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 true 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 true 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 true 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 true for {@link RootNode#isSplittable()}. + * + * @return true 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 true 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,8 +139,24 @@ } } + /** + * 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 null. + * + * @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) { + protected void onReplace(Node newNode, CharSequence 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 true 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); - } - } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java Tue Mar 18 11:51:37 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()); } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java Tue Mar 18 11:51:37 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; } /** @@ -179,7 +186,7 @@ * @param reason a description of the reason for the replacement * @return the new node */ - public final T replace(T newNode, String reason) { + public final T replace(T newNode, CharSequence reason) { CompilerDirectives.transferToInterpreterAndInvalidate(); if (this.getParent() == null) { throw new IllegalStateException("This node cannot be replaced, because it does not yet have a parent."); @@ -253,7 +260,7 @@ return false; } - private void reportReplace(Node oldNode, Node newNode, String reason) { + private void reportReplace(Node oldNode, Node newNode, CharSequence reason) { RootNode rootNode = getRootNode(); if (rootNode != null) { CallTarget target = rootNode.getCallTarget(); @@ -270,68 +277,61 @@ * @param newNode the replacement node * @param reason the reason the replace supplied */ - protected void onReplace(Node newNode, String reason) { + protected void onReplace(Node newNode, CharSequence reason) { if (TruffleOptions.TraceRewrites) { traceRewrite(newNode, reason); } } - private void traceRewrite(Node newNode, String reason) { - Class from = getClass(); - Class to = newNode.getClass(); + private void traceRewrite(Node newNode, CharSequence reason) { - 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 from = getClass(); + Class 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 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 from, String filter) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCost.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCost.java Tue Mar 18 11:51:37 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; + +} diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java Tue Mar 18 11:51:37 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; } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java Tue Mar 18 11:51:37 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 findOutermostCallTargets(Node node) { - RootNode root = node.getRootNode(); - if (root == null) { - return Collections.emptyList(); - } - List 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 findParent(Node start, Class 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) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java Tue Mar 18 11:51:37 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 true 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 true a proper implementation of {@link #split()} must also be provided. + * This method is intended to be overridden by a subclass. + * + * @return true if splittable else false. */ - @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(); - } } diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java Tue Mar 18 11:51:37 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) { diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java Tue Mar 18 11:51:37 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(); diff -r 3eda945af90a -r ff2095ec7bdb graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Mar 18 11:07:47 2014 -0700 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Mar 18 11:51:37 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)); } } diff -r 3eda945af90a -r ff2095ec7bdb graal/findbugsExcludeFilter.xml --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/findbugsExcludeFilter.xml Tue Mar 18 11:51:37 2014 -0700 @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 3eda945af90a -r ff2095ec7bdb make/Makefile --- a/make/Makefile Tue Mar 18 11:07:47 2014 -0700 +++ b/make/Makefile Tue Mar 18 11:51:37 2014 -0700 @@ -307,7 +307,7 @@ # Builds code that can be shared among different build flavors buildshared: -# python2.7 -u $(GAMMADIR)/mxtool/mx.py build --no-native --export-dir $(SHARED_DIR) + python2.7 -u $(GAMMADIR)/mxtool/mx.py build --no-native --export-dir $(SHARED_DIR) # Export file rule generic_export: $(EXPORT_LIST) @@ -315,11 +315,11 @@ export_product: $(MAKE) BUILD_FLAVOR=$(@:export_%=%) generic_export export_fastdebug: - $(MAKE) BUILD_FLAVOR=$(@:export_%=%) generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export export_debug: - $(MAKE) BUILD_FLAVOR=$(@:export_%=%) generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export export_optimized: - $(MAKE) BUILD_FLAVOR=$(@:export_%=%) generic_export + $(MAKE) BUILD_FLAVOR=$(@:export_%=%) EXPORT_SUBDIR=/$(@:export_%=%) generic_export export_product_jdk:: $(MAKE) BUILD_FLAVOR=$(@:export_%_jdk=%) ALT_EXPORT_PATH=$(JDK_IMAGE_DIR) generic_export diff -r 3eda945af90a -r ff2095ec7bdb mx/mx_graal.py --- a/mx/mx_graal.py Tue Mar 18 11:07:47 2014 -0700 +++ b/mx/mx_graal.py Tue Mar 18 11:51:37 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, ''], diff -r 3eda945af90a -r ff2095ec7bdb mx/projects --- a/mx/projects Tue Mar 18 11:07:47 2014 -0700 +++ b/mx/projects Tue Mar 18 11:51:37 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 diff -r 3eda945af90a -r ff2095ec7bdb mxtool/mx.py --- a/mxtool/mx.py Tue Mar 18 11:07:47 2014 -0700 +++ b/mxtool/mx.py Tue Mar 18 11:51:37 2014 -0700 @@ -1099,6 +1099,8 @@ return run(java().format_cmd(args, addDefaultArgs), nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd) def _kill_process_group(pid, sig): + if not sig: + sig = signal.SIGKILL pgid = os.getpgid(pid) try: os.killpg(pgid, sig) @@ -1892,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) diff -r 3eda945af90a -r ff2095ec7bdb src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp --- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp Tue Mar 18 11:51:37 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) { @@ -121,24 +98,24 @@ } #endif switch (_next_call_type) { - case MARK_INLINE_INVOKE: + case INLINE_INVOKE: break; - case MARK_INVOKEVIRTUAL: - case MARK_INVOKEINTERFACE: { + case INVOKEVIRTUAL: + case INVOKEINTERFACE: { assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_virtual_call_stub()); _instructions->relocate(call->instruction_address(), virtual_call_Relocation::spec(_invoke_mark_pc)); break; } - case MARK_INVOKESTATIC: { + case INVOKESTATIC: { assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_static_call_stub()); _instructions->relocate(call->instruction_address(), relocInfo::static_call_type); break; } - case MARK_INVOKESPECIAL: { + case INVOKESPECIAL: { assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); @@ -153,16 +130,16 @@ inline void CodeInstaller::pd_relocate_poll(address pc, jint mark) { switch (mark) { - case MARK_POLL_NEAR: { + case POLL_NEAR: { fatal("unimplemented"); } - case MARK_POLL_FAR: + case POLL_FAR: _instructions->relocate(pc, relocInfo::poll_type); break; - case MARK_POLL_RETURN_NEAR: { + case POLL_RETURN_NEAR: { fatal("unimplemented"); } - case MARK_POLL_RETURN_FAR: + case POLL_RETURN_FAR: _instructions->relocate(pc, relocInfo::poll_return_type); break; default: diff -r 3eda945af90a -r ff2095ec7bdb src/cpu/x86/vm/graalCodeInstaller_x86.hpp --- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp Tue Mar 18 11:51:37 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) { @@ -170,10 +151,10 @@ } #endif switch (_next_call_type) { - case MARK_INLINE_INVOKE: + case INLINE_INVOKE: break; - case MARK_INVOKEVIRTUAL: - case MARK_INVOKEINTERFACE: { + case INVOKEVIRTUAL: + case INVOKEINTERFACE: { assert(method == NULL || !method->is_static(), "cannot call static method with invokeinterface"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); @@ -183,7 +164,7 @@ Assembler::call32_operand); break; } - case MARK_INVOKESTATIC: { + case INVOKESTATIC: { assert(method == NULL || method->is_static(), "cannot call non-static method with invokestatic"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); @@ -192,7 +173,7 @@ relocInfo::static_call_type, Assembler::call32_operand); break; } - case MARK_INVOKESPECIAL: { + case INVOKESPECIAL: { assert(method == NULL || !method->is_static(), "cannot call static method with invokespecial"); NativeCall* call = nativeCall_at(_instructions->start() + pc_offset); call->set_destination(SharedRuntime::get_resolve_opt_virtual_call_stub()); @@ -216,24 +197,24 @@ inline void CodeInstaller::pd_relocate_poll(address pc, jint mark) { switch (mark) { - case MARK_POLL_NEAR: { + case POLL_NEAR: { relocate_poll_near(pc); _instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand); break; } - case MARK_POLL_FAR: + case POLL_FAR: // This is a load from a register so there is no relocatable operand. // We just have to ensure that the format is not disp32_operand // so that poll_Relocation::fix_relocation_after_move does the right // thing (i.e. ignores this relocation record) _instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand); break; - case MARK_POLL_RETURN_NEAR: { + case POLL_RETURN_NEAR: { relocate_poll_near(pc); _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::disp32_operand); break; } - case MARK_POLL_RETURN_FAR: + case POLL_RETURN_FAR: // see comment above for MARK_POLL_FAR _instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand); break; diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/classfile/systemDictionary.hpp Tue Mar 18 11:51:37 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) \ diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/classfile/vmSymbols.hpp Tue Mar 18 11:51:37 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") \ diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/code/nmethod.cpp Tue Mar 18 11:51:37 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); diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Mar 18 11:51:37 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) != 0, oop_recorder); +} + ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray* 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()); @@ -456,7 +469,7 @@ _comments = (arrayOop) HotSpotCompiledCode::comments(compiled_code); #endif - _next_call_type = MARK_INVOKE_INVALID; + _next_call_type = INVOKE_INVALID; } // perform data and call relocation on the CodeBuffer @@ -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)); } } @@ -769,7 +776,7 @@ CodeInstaller::pd_relocate_JavaMethod(hotspot_method, pc_offset); } - _next_call_type = MARK_INVOKE_INVALID; + _next_call_type = INVOKE_INVALID; if (debug_info != NULL) { _debug_recorder->end_safepoint(next_pc_offset); @@ -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) { @@ -802,33 +806,33 @@ address pc = _instructions->start() + pc_offset; switch (id) { - case MARK_UNVERIFIED_ENTRY: + case UNVERIFIED_ENTRY: _offsets.set_value(CodeOffsets::Entry, pc_offset); break; - case MARK_VERIFIED_ENTRY: + case VERIFIED_ENTRY: _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset); break; - case MARK_OSR_ENTRY: + case OSR_ENTRY: _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset); break; - case MARK_EXCEPTION_HANDLER_ENTRY: + case EXCEPTION_HANDLER_ENTRY: _offsets.set_value(CodeOffsets::Exceptions, pc_offset); break; - case MARK_DEOPT_HANDLER_ENTRY: + case DEOPT_HANDLER_ENTRY: _offsets.set_value(CodeOffsets::Deopt, pc_offset); break; - case MARK_INVOKEVIRTUAL: - case MARK_INVOKEINTERFACE: - case MARK_INLINE_INVOKE: - case MARK_INVOKESTATIC: - case MARK_INVOKESPECIAL: + case INVOKEVIRTUAL: + case INVOKEINTERFACE: + case INLINE_INVOKE: + case INVOKESTATIC: + case INVOKESPECIAL: _next_call_type = (MarkId) id; _invoke_mark_pc = pc; break; - case MARK_POLL_NEAR: - case MARK_POLL_FAR: - case MARK_POLL_RETURN_NEAR: - case MARK_POLL_RETURN_FAR: + case POLL_NEAR: + case POLL_FAR: + case POLL_RETURN_NEAR: + case POLL_RETURN_FAR: pd_relocate_poll(pc, id); break; default: diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Tue Mar 18 11:51:37 2014 -0700 @@ -24,28 +24,30 @@ #ifndef SHARE_VM_GRAAL_GRAAL_CODE_INSTALLER_HPP #define SHARE_VM_GRAAL_GRAAL_CODE_INSTALLER_HPP +#include "graal/graalEnv.hpp" + /* * This class handles the conversion from a InstalledCode to a CodeBlob or an nmethod. */ class CodeInstaller { + friend class VMStructs; private: - // these need to correspond to Marks.java enum MarkId { - MARK_VERIFIED_ENTRY = 1, - MARK_UNVERIFIED_ENTRY = 2, - MARK_OSR_ENTRY = 3, - MARK_EXCEPTION_HANDLER_ENTRY = 4, - MARK_DEOPT_HANDLER_ENTRY = 5, - MARK_INVOKEINTERFACE = 6, - MARK_INVOKEVIRTUAL = 7, - MARK_INVOKESTATIC = 8, - MARK_INVOKESPECIAL = 9, - MARK_INLINE_INVOKE = 10, - MARK_POLL_NEAR = 11, - MARK_POLL_RETURN_NEAR = 12, - MARK_POLL_FAR = 13, - MARK_POLL_RETURN_FAR = 14, - MARK_INVOKE_INVALID = -1 + VERIFIED_ENTRY = 1, + UNVERIFIED_ENTRY = 2, + OSR_ENTRY = 3, + EXCEPTION_HANDLER_ENTRY = 4, + DEOPT_HANDLER_ENTRY = 5, + INVOKEINTERFACE = 6, + INVOKEVIRTUAL = 7, + INVOKESTATIC = 8, + INVOKESPECIAL = 9, + INLINE_INVOKE = 10, + POLL_NEAR = 11, + POLL_RETURN_NEAR = 12, + POLL_FAR = 13, + POLL_RETURN_FAR = 14, + INVOKE_INVALID = -1 }; Arena _arena; @@ -77,7 +79,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); diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Mar 18 11:51:37 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); @@ -378,23 +373,15 @@ return (jlong) (address) resolved_klass; C2V_END -C2V_VMENTRY(jobject, lookupConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index)) +C2V_VMENTRY(jobject, resolveConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index)) ConstantPool* cp = (ConstantPool*) metaspace_constant_pool; - oop result = NULL; - constantTag tag = cp->tag_at(index); - switch (tag.value()) { - case JVM_CONSTANT_String: - result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL); - break; - case JVM_CONSTANT_MethodHandle: - case JVM_CONSTANT_MethodHandleInError: - case JVM_CONSTANT_MethodType: - case JVM_CONSTANT_MethodTypeInError: - result = cp->resolve_constant_at(index, CHECK_NULL); - break; - default: - fatal(err_msg_res("unknown constant pool tag %s at cpi %d in %s", tag.internal_name(), index, cp->pool_holder()->name()->as_C_string())); - } + oop result = cp->resolve_constant_at(index, CHECK_NULL); + return JNIHandles::make_local(THREAD, result); +C2V_END + +C2V_VMENTRY(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index)) + ConstantPool* cp = (ConstantPool*) metaspace_constant_pool; + oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL); return JNIHandles::make_local(THREAD, result); C2V_END @@ -418,6 +405,11 @@ return cp->klass_ref_index_at(index); C2V_END +C2V_VMENTRY(jlong, constantPoolKlassAt, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index)) + ConstantPool* cp = (ConstantPool*) metaspace_constant_pool; + return (jlong) (address) cp->klass_at(index, THREAD); +C2V_END + C2V_VMENTRY(jlong, lookupKlassInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode)) constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool; KlassHandle loading_klass(cp->pool_holder()); @@ -456,26 +448,9 @@ return (jlong) (address) method(); C2V_END -C2V_VMENTRY(void, loadReferencedTypeInPool, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte op)) +C2V_VMENTRY(jint, constantPoolRemapInstructionOperandFromCache, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index)) ConstantPool* cp = (ConstantPool*) metaspace_constant_pool; - Bytecodes::Code bc = (Bytecodes::Code) (((int) op) & 0xFF); - if (bc != Bytecodes::_checkcast && bc != Bytecodes::_instanceof && bc != Bytecodes::_new && bc != Bytecodes::_anewarray - && bc != Bytecodes::_multianewarray && bc != Bytecodes::_ldc && bc != Bytecodes::_ldc_w && bc != Bytecodes::_ldc2_w) - { - index = cp->remap_instruction_operand_from_cache(index); - } - constantTag tag = cp->tag_at(index); - if (tag.is_field_or_method()) { - index = cp->uncached_klass_ref_index_at(index); - tag = cp->tag_at(index); - } - - if (tag.is_unresolved_klass() || tag.is_klass()) { - Klass* klass = cp->klass_at(index, CHECK); - if (klass->oop_is_instance()) { - InstanceKlass::cast(klass)->initialize(CHECK); - } - } + return cp->remap_instruction_operand_from_cache(index); C2V_END C2V_VMENTRY(jlong, resolveField, (JNIEnv *env, jobject, jlong metaspace_constant_pool, jint index, jbyte opcode, jlongArray info_handle)) @@ -823,53 +798,54 @@ #define METASPACE_SYMBOL "J" JNINativeMethod CompilerToVM_methods[] = { - {CC"initializeBytecode", CC"("METASPACE_METHOD"[B)[B", FN_PTR(initializeBytecode)}, - {CC"exceptionTableStart", CC"("METASPACE_METHOD")J", FN_PTR(exceptionTableStart)}, - {CC"exceptionTableLength", CC"("METASPACE_METHOD")I", FN_PTR(exceptionTableLength)}, - {CC"hasBalancedMonitors", CC"("METASPACE_METHOD")Z", FN_PTR(hasBalancedMonitors)}, - {CC"findUniqueConcreteMethod", CC"("METASPACE_METHOD")"METASPACE_METHOD, FN_PTR(findUniqueConcreteMethod)}, - {CC"getKlassImplementor", CC"("METASPACE_KLASS")"METASPACE_KLASS, FN_PTR(getKlassImplementor)}, - {CC"getStackTraceElement", CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, - {CC"initializeMethod", CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V", FN_PTR(initializeMethod)}, - {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"lookupConstantInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(lookupConstantInPool)}, - {CC"lookupNameRefInPool", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_SYMBOL, FN_PTR(lookupNameRefInPool)}, - {CC"lookupNameAndTypeRefIndexInPool", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)}, - {CC"lookupSignatureRefInPool", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_SYMBOL, FN_PTR(lookupSignatureRefInPool)}, - {CC"lookupKlassRefIndexInPool", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(lookupKlassRefIndexInPool)}, - {CC"lookupKlassInPool", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS, FN_PTR(lookupKlassInPool)}, - {CC"lookupAppendixInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(lookupAppendixInPool)}, - {CC"lookupMethodInPool", CC"("METASPACE_CONSTANT_POOL"IB)"METASPACE_METHOD, FN_PTR(lookupMethodInPool)}, - {CC"loadReferencedTypeInPool", CC"("METASPACE_CONSTANT_POOL"IB)V", FN_PTR(loadReferencedTypeInPool)}, - {CC"resolveField", CC"("METASPACE_CONSTANT_POOL"IB[J)"METASPACE_KLASS, FN_PTR(resolveField)}, - {CC"resolveMethod", CC"("METASPACE_KLASS STRING STRING")"METASPACE_METHOD, FN_PTR(resolveMethod)}, - {CC"getClassInitializer", CC"("METASPACE_KLASS")"METASPACE_METHOD, FN_PTR(getClassInitializer)}, - {CC"hasFinalizableSubclass", CC"("METASPACE_KLASS")Z", FN_PTR(hasFinalizableSubclass)}, - {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, - {CC"getMetaspaceMethod", CC"("CLASS"I)"METASPACE_METHOD, FN_PTR(getMetaspaceMethod)}, - {CC"initializeConfiguration", CC"("HS_CONFIG")V", FN_PTR(initializeConfiguration)}, - {CC"installCode0", CC"("HS_COMPILED_CODE HS_INSTALLED_CODE SPECULATION_LOG")I", FN_PTR(installCode0)}, - {CC"notifyCompilationStatistics", CC"(I"HS_RESOLVED_METHOD"ZIJJ"HS_INSTALLED_CODE")V", FN_PTR(notifyCompilationStatistics)}, - {CC"printCompilationStatistics", CC"(ZZ)V", FN_PTR(printCompilationStatistics)}, - {CC"resetCompilationStatistics", CC"()V", FN_PTR(resetCompilationStatistics)}, - {CC"disassembleCodeBlob", CC"(J)"STRING, FN_PTR(disassembleCodeBlob)}, - {CC"executeCompiledMethodVarargs", CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, - {CC"getLineNumberTable", CC"("METASPACE_METHOD")[J", FN_PTR(getLineNumberTable)}, - {CC"getLocalVariableTableStart", CC"("METASPACE_METHOD")J", FN_PTR(getLocalVariableTableStart)}, - {CC"getLocalVariableTableLength", CC"("METASPACE_METHOD")I", FN_PTR(getLocalVariableTableLength)}, - {CC"reprofile", CC"("METASPACE_METHOD")V", FN_PTR(reprofile)}, - {CC"invalidateInstalledCode", CC"("HS_INSTALLED_CODE")V", FN_PTR(invalidateInstalledCode)}, - {CC"readUnsafeUncompressedPointer", CC"("OBJECT"J)"OBJECT, FN_PTR(readUnsafeUncompressedPointer)}, - {CC"readUnsafeKlassPointer", CC"("OBJECT")J", FN_PTR(readUnsafeKlassPointer)}, - {CC"collectCounters", CC"()[J", FN_PTR(collectCounters)}, - {CC"getGPUs", CC"()"STRING, FN_PTR(getGPUs)}, - {CC"allocateCompileId", CC"("METASPACE_METHOD"I)I", FN_PTR(allocateCompileId)}, - {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, - {CC"hasCompiledCodeForOSR", CC"("METASPACE_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, + {CC"initializeBytecode", CC"("METASPACE_METHOD"[B)[B", FN_PTR(initializeBytecode)}, + {CC"exceptionTableStart", CC"("METASPACE_METHOD")J", FN_PTR(exceptionTableStart)}, + {CC"exceptionTableLength", CC"("METASPACE_METHOD")I", FN_PTR(exceptionTableLength)}, + {CC"hasBalancedMonitors", CC"("METASPACE_METHOD")Z", FN_PTR(hasBalancedMonitors)}, + {CC"findUniqueConcreteMethod", CC"("METASPACE_METHOD")"METASPACE_METHOD, FN_PTR(findUniqueConcreteMethod)}, + {CC"getKlassImplementor", CC"("METASPACE_KLASS")"METASPACE_KLASS, FN_PTR(getKlassImplementor)}, + {CC"getStackTraceElement", CC"("METASPACE_METHOD"I)"STACK_TRACE_ELEMENT, FN_PTR(getStackTraceElement)}, + {CC"initializeMethod", CC"("METASPACE_METHOD HS_RESOLVED_METHOD")V", FN_PTR(initializeMethod)}, + {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"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)}, + {CC"lookupNameRefInPool", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_SYMBOL, FN_PTR(lookupNameRefInPool)}, + {CC"lookupNameAndTypeRefIndexInPool", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(lookupNameAndTypeRefIndexInPool)}, + {CC"lookupSignatureRefInPool", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_SYMBOL, FN_PTR(lookupSignatureRefInPool)}, + {CC"lookupKlassRefIndexInPool", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(lookupKlassRefIndexInPool)}, + {CC"constantPoolKlassAt", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS, FN_PTR(constantPoolKlassAt)}, + {CC"lookupKlassInPool", CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS, FN_PTR(lookupKlassInPool)}, + {CC"lookupAppendixInPool", CC"("METASPACE_CONSTANT_POOL"I)"OBJECT, FN_PTR(lookupAppendixInPool)}, + {CC"lookupMethodInPool", CC"("METASPACE_CONSTANT_POOL"IB)"METASPACE_METHOD, FN_PTR(lookupMethodInPool)}, + {CC"constantPoolRemapInstructionOperandFromCache", CC"("METASPACE_CONSTANT_POOL"I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)}, + {CC"resolveField", CC"("METASPACE_CONSTANT_POOL"IB[J)"METASPACE_KLASS, FN_PTR(resolveField)}, + {CC"resolveMethod", CC"("METASPACE_KLASS STRING STRING")"METASPACE_METHOD, FN_PTR(resolveMethod)}, + {CC"getClassInitializer", CC"("METASPACE_KLASS")"METASPACE_METHOD, FN_PTR(getClassInitializer)}, + {CC"hasFinalizableSubclass", CC"("METASPACE_KLASS")Z", FN_PTR(hasFinalizableSubclass)}, + {CC"getMaxCallTargetOffset", CC"(J)J", FN_PTR(getMaxCallTargetOffset)}, + {CC"getMetaspaceMethod", CC"("CLASS"I)"METASPACE_METHOD, FN_PTR(getMetaspaceMethod)}, + {CC"initializeConfiguration", CC"("HS_CONFIG")V", FN_PTR(initializeConfiguration)}, + {CC"installCode0", CC"("HS_COMPILED_CODE HS_INSTALLED_CODE SPECULATION_LOG")I", FN_PTR(installCode0)}, + {CC"notifyCompilationStatistics", CC"(I"HS_RESOLVED_METHOD"ZIJJ"HS_INSTALLED_CODE")V", FN_PTR(notifyCompilationStatistics)}, + {CC"printCompilationStatistics", CC"(ZZ)V", FN_PTR(printCompilationStatistics)}, + {CC"resetCompilationStatistics", CC"()V", FN_PTR(resetCompilationStatistics)}, + {CC"disassembleCodeBlob", CC"(J)"STRING, FN_PTR(disassembleCodeBlob)}, + {CC"executeCompiledMethodVarargs", CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeCompiledMethodVarargs)}, + {CC"getLineNumberTable", CC"("METASPACE_METHOD")[J", FN_PTR(getLineNumberTable)}, + {CC"getLocalVariableTableStart", CC"("METASPACE_METHOD")J", FN_PTR(getLocalVariableTableStart)}, + {CC"getLocalVariableTableLength", CC"("METASPACE_METHOD")I", FN_PTR(getLocalVariableTableLength)}, + {CC"reprofile", CC"("METASPACE_METHOD")V", FN_PTR(reprofile)}, + {CC"invalidateInstalledCode", CC"("HS_INSTALLED_CODE")V", FN_PTR(invalidateInstalledCode)}, + {CC"readUnsafeUncompressedPointer", CC"("OBJECT"J)"OBJECT, FN_PTR(readUnsafeUncompressedPointer)}, + {CC"readUnsafeKlassPointer", CC"("OBJECT")J", FN_PTR(readUnsafeKlassPointer)}, + {CC"collectCounters", CC"()[J", FN_PTR(collectCounters)}, + {CC"getGPUs", CC"()"STRING, FN_PTR(getGPUs)}, + {CC"allocateCompileId", CC"("METASPACE_METHOD"I)I", FN_PTR(allocateCompileId)}, + {CC"isMature", CC"("METASPACE_METHOD_DATA")Z", FN_PTR(isMature)}, + {CC"hasCompiledCodeForOSR", CC"("METASPACE_METHOD"II)Z", FN_PTR(hasCompiledCodeForOSR)}, }; int CompilerToVM_methods_count() { diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Mar 18 11:51:37 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;") \ diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/graal/vmStructs_graal.hpp --- a/src/share/vm/graal/vmStructs_graal.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/graal/vmStructs_graal.hpp Tue Mar 18 11:51:37 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -26,12 +26,14 @@ #define SHARE_VM_GRAAL_VMSTRUCTS_GRAAL_HPP #include "compiler/abstractCompiler.hpp" +#include "graal/graalCodeInstaller.hpp" #include "graal/graalCompilerToVM.hpp" #include "graal/graalEnv.hpp" #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) \ @@ -47,5 +49,21 @@ \ declare_constant(CompilerToVM::KLASS_TAG) \ declare_constant(CompilerToVM::SYMBOL_TAG) \ + \ + declare_constant(CodeInstaller::VERIFIED_ENTRY) \ + declare_constant(CodeInstaller::UNVERIFIED_ENTRY) \ + declare_constant(CodeInstaller::OSR_ENTRY) \ + declare_constant(CodeInstaller::EXCEPTION_HANDLER_ENTRY) \ + declare_constant(CodeInstaller::DEOPT_HANDLER_ENTRY) \ + declare_constant(CodeInstaller::INVOKEINTERFACE) \ + declare_constant(CodeInstaller::INVOKEVIRTUAL) \ + declare_constant(CodeInstaller::INVOKESTATIC) \ + declare_constant(CodeInstaller::INVOKESPECIAL) \ + declare_constant(CodeInstaller::INLINE_INVOKE) \ + declare_constant(CodeInstaller::POLL_NEAR) \ + declare_constant(CodeInstaller::POLL_RETURN_NEAR) \ + declare_constant(CodeInstaller::POLL_FAR) \ + declare_constant(CodeInstaller::POLL_RETURN_FAR) \ + declare_constant(CodeInstaller::INVOKE_INVALID) \ #endif // SHARE_VM_GRAAL_VMSTRUCTS_GRAAL_HPP diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/oops/methodData.cpp --- a/src/share/vm/oops/methodData.cpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/oops/methodData.cpp Tue Mar 18 11:51:37 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; diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/oops/methodData.hpp --- a/src/share/vm/oops/methodData.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/oops/methodData.hpp Tue Mar 18 11:51:37 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; diff -r 3eda945af90a -r ff2095ec7bdb src/share/vm/utilities/globalDefinitions.hpp --- a/src/share/vm/utilities/globalDefinitions.hpp Tue Mar 18 11:07:47 2014 -0700 +++ b/src/share/vm/utilities/globalDefinitions.hpp Tue Mar 18 11:51:37 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