# HG changeset patch # User Stefan Anzinger # Date 1418412575 -3600 # Node ID 7cc21427d54ba8263347032125d8b713ac82591d # Parent 6ace9e5bc384058799dc70c1d2cd2e45b804754d# Parent b026b6d86ab61db4f982403e2a95e76a7e9fe030 Merge diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java --- a/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.asm.sparc/src/com/oracle/graal/asm/sparc/SPARCAssembler.java Fri Dec 12 20:29:35 2014 +0100 @@ -1273,18 +1273,6 @@ } } -// public static class Fmt4a { -// -// public Fmt4a(SPARCAssembler masm, int op, int op3, int cc, int rs1, int regOrImmediate, int rd) { -// assert op == 2; -// assert rs1 >= 0 && rs1 < 0x20; -// assert rd >= 0 && rd < 0x10; -// -// masm.emitInt(op << 30 | rd << 25 | op3 << 19 | rs1 << 14 | ((cc << 11) & 0x000001800) | -// regOrImmediate); -// } -// } - // @formatter:off /** * Instruction format for Movcc. diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/CollectionsFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/CollectionsFactory.java Fri Dec 12 20:29:35 2014 +0100 @@ -0,0 +1,107 @@ +/* + * 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.compiler.common; + +import static com.oracle.graal.compiler.common.CollectionsFactory.Mode.*; + +import java.util.*; + +/** + * Factory for creating collection objects used during compilation. + */ +public class CollectionsFactory { + + private static final ThreadLocal tl = new ThreadLocal<>(); + + public static class ModeScope implements AutoCloseable { + private final Mode previousMode; + + public ModeScope(Mode previousMode) { + this.previousMode = previousMode; + } + + public void close() { + tl.set(previousMode); + } + } + + /** + * Constants denoting what type of collections are {@link CollectionsFactory#getMode() + * currently} returned by the factory. + */ + public enum Mode { + /** + * Denotes standard collections such as {@link HashSet} and {@link HashMap}. + */ + STANDARD, + + /** + * Denotes collections that have a deterministic iteration order over their keys/entries. + */ + DETERMINISTIC_ITERATION_ORDER; + } + + /** + * Gets the current mode determining the type of collection objects created by this factory. + */ + public static Mode getMode() { + Mode mode = tl.get(); + return mode == null ? Mode.STANDARD : mode; + } + + /** + * Updates the mode for the current thread. + * + * @return an object which when {@linkplain ModeScope#close() closed} will revert the mode of + * the current thread to the stae before calling this method + */ + public static ModeScope changeMode(Mode mode) { + Mode previousMode = tl.get(); + tl.set(mode); + return new ModeScope(previousMode); + } + + public static HashMap newMap() { + return getMode() == STANDARD ? new HashMap<>() : new LinkedHashMap<>(); + } + + public static HashMap newMap(Map m) { + return getMode() == STANDARD ? new HashMap<>(m) : new LinkedHashMap<>(m); + } + + public static HashMap newMap(int initialCapacity) { + return getMode() == STANDARD ? new HashMap<>(initialCapacity) : new LinkedHashMap<>(initialCapacity); + } + + public static Map newIdentityMap() { + return getMode() == STANDARD ? new IdentityHashMap<>() : new LinkedIdentityHashMap<>(); + } + + public static Map newIdentityMap(int expectedMaxSize) { + return getMode() == STANDARD ? new IdentityHashMap<>(expectedMaxSize) : new LinkedIdentityHashMap<>(); + } + + public static Map newIdentityMap(Map m) { + return getMode() == STANDARD ? new IdentityHashMap<>(m) : new LinkedIdentityHashMap<>(m); + } +} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Fri Dec 12 20:29:35 2014 +0100 @@ -30,58 +30,67 @@ // @formatter:off public final class GraalOptions { - @Option(help = "Use baseline compiler configuration") + @Option(help = "Use experimental baseline compiler configuration.") public static final OptionValue UseBaselineCompiler = new OptionValue<>(false); - @Option(help = "Enable use of compiler intrinsics") + + @Option(help = "Use compiler intrinsifications.") public static final OptionValue Intrinsify = new OptionValue<>(true); - @Option(help = "Enable inlining of monomorphic calls") + + @Option(help = "Inline calls with monomorphic type profile.") public static final OptionValue InlineMonomorphicCalls = new OptionValue<>(true); - @Option(help = "Enable inlining of polymorphic calls") + + @Option(help = "Inline calls with polymorphic type profile.") public static final OptionValue InlinePolymorphicCalls = new OptionValue<>(true); - @Option(help = "Enable inlining of megamorphic calls") + + @Option(help = "Inline calls with megamorphic type profile (i.e., not all types could be recorded).") public static final OptionValue InlineMegamorphicCalls = new OptionValue<>(true); - @Option(help = "") + + @Option(help = "Maximum desired size of the compiler graph in nodes.") + public static final OptionValue MaximumDesiredSize = new OptionValue<>(20000); + + @Option(help = "Minimum probability for methods to be inlined for megamorphic type profiles.") public static final OptionValue MegamorphicInliningMinMethodProbability = new OptionValue<>(0.33D); - @Option(help = "") - public static final OptionValue MaximumDesiredSize = new OptionValue<>(20000); - @Option(help = "") + + @Option(help = "Maximum level of recursive inlining.") public static final OptionValue MaximumRecursiveInlining = new OptionValue<>(5); - // inlining settings - @Option(help = "") - public static final OptionValue BoostInliningForEscapeAnalysis = new OptionValue<>(2f); - @Option(help = "") - public static final OptionValue RelevanceCapForInlining = new OptionValue<>(1f); - @Option(help = "") - public static final OptionValue CapInheritedRelevance = new OptionValue<>(1f); @Option(help = "") public static final OptionValue IterativeInlining = new OptionValue<>(false); - @Option(help = "") + @Option(help = "Graphs with less than this number of nodes are trivial and therefore always inlined.") public static final OptionValue TrivialInliningSize = new OptionValue<>(10); - @Option(help = "") + + @Option(help = "Inlining is explored up to this number of nodes in the graph for each call site.") public static final OptionValue MaximumInliningSize = new OptionValue<>(300); - @Option(help = "") + + @Option(help = "If the previous low-level graph size of the method exceeds the threshold, it is not inlined.") public static final OptionValue SmallCompiledLowLevelGraphSize = new OptionValue<>(300); + @Option(help = "") public static final OptionValue LimitInlinedInvokes = new OptionValue<>(5.0); + @Option(help = "") public static final OptionValue InlineEverything = new OptionValue<>(false); // escape analysis settings @Option(help = "") public static final OptionValue PartialEscapeAnalysis = new OptionValue<>(true); + @Option(help = "") public static final OptionValue EscapeAnalysisIterations = new OptionValue<>(2); + @Option(help = "") public static final OptionValue EscapeAnalyzeOnly = new OptionValue<>(null); + @Option(help = "") public static final OptionValue MaximumEscapeAnalysisArrayLength = new OptionValue<>(32); + @Option(help = "") public static final OptionValue PEAInliningHints = new OptionValue<>(false); @Option(help = "") public static final OptionValue TailDuplicationProbability = new OptionValue<>(0.5); + @Option(help = "") public static final OptionValue TailDuplicationTrivialSize = new OptionValue<>(1); @@ -96,32 +105,44 @@ //loop transform settings TODO (gd) tune @Option(help = "") public static final OptionValue LoopPeeling = new OptionValue<>(true); + @Option(help = "") public static final OptionValue ReassociateInvariants = new OptionValue<>(true); + @Option(help = "") public static final OptionValue FullUnroll = new OptionValue<>(true); + @Option(help = "") public static final OptionValue LoopUnswitch = new OptionValue<>(true); + @Option(help = "") public static final OptionValue FullUnrollMaxNodes = new OptionValue<>(300); + @Option(help = "") public static final OptionValue ExactFullUnrollMaxNodes = new OptionValue<>(1200); + @Option(help = "") public static final OptionValue MinimumPeelProbability = new OptionValue<>(0.35f); + @Option(help = "") public static final OptionValue LoopMaxUnswitch = new OptionValue<>(3); + @Option(help = "") public static final OptionValue LoopUnswitchMaxIncrease = new OptionValue<>(50); + @Option(help = "") public static final OptionValue LoopUnswitchUncertaintyBoost = new OptionValue<>(5); + @Option(help = "") public static final OptionValue UseLoopLimitChecks = new OptionValue<>(true); // debugging settings @Option(help = "") public static final OptionValue ZapStackOnMethodEntry = new OptionValue<>(false); + @Option(help = "") public static final OptionValue DeoptALot = new OptionValue<>(false); + @Option(help = "") public static final OptionValue VerifyPhases = new OptionValue<>(false); @@ -131,47 +152,66 @@ // Debug settings: @Option(help = "") public static final OptionValue BootstrapReplacements = new OptionValue<>(false); + @Option(help = "") public static final OptionValue GCDebugStartCycle = new OptionValue<>(-1); + // Ideal graph visualizer output settings @Option(help = "Dump IdealGraphVisualizer output in binary format") public static final OptionValue PrintBinaryGraphs = new OptionValue<>(true); + @Option(help = "Output probabilities for fixed nodes during binary graph dumping") public static final OptionValue PrintGraphProbabilities = new OptionValue<>(false); + @Option(help = "Enable dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.") public static final OptionValue PrintCFG = new OptionValue<>(false); + @Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.") public static final OptionValue PrintBackendCFG = new OptionValue<>(true); + @Option(help = "") public static final OptionValue PrintIdealGraphFile = new OptionValue<>(false); + @Option(help = "") public static final OptionValue PrintIdealGraphAddress = new OptionValue<>("127.0.0.1"); + @Option(help = "") public static final OptionValue PrintIdealGraphPort = new OptionValue<>(4444); + @Option(help = "") public static final OptionValue PrintBinaryGraphPort = new OptionValue<>(4445); + @Option(help = "") public static final OptionValue PrintIdealGraphSchedule = new OptionValue<>(false); // Other printing settings @Option(help = "") public static final OptionValue PrintCompilation = new OptionValue<>(false); + @Option(help = "") public static final OptionValue PrintAfterCompilation = new OptionValue<>(false); + @Option(help = "Print profiling information when parsing a method's bytecode") public static final OptionValue PrintProfilingInformation = new OptionValue<>(false); + @Option(help = "") public static final OptionValue PrintCodeBytes = new OptionValue<>(false); + @Option(help = "") public static final OptionValue PrintBailout = new OptionValue<>(false); + @Option(help = "") public static final OptionValue TraceEscapeAnalysis = new OptionValue<>(false); + @Option(help = "") public static final OptionValue ExitVMOnBailout = new OptionValue<>(false); + @Option(help = "") public static final OptionValue ExitVMOnException = new OptionValue<>(true); + @Option(help = "") public static final OptionValue PrintStackTraceOnException = new OptionValue<>(false); + @Option(help = "Set a phase after which the decompiler dumps the graph, -G:Dump= required") public static final OptionValue DecompileAfterPhase = new OptionValue<>(null); @@ -180,55 +220,59 @@ public static final OptionValue HotSpotPrintInlining = new OptionValue<>(false); // Register allocator debugging - @Option(help = "") + @Option(help = "Comma separated list of register that the allocation is limited to.") public static final OptionValue RegisterPressure = new OptionValue<>(null); // Code generator settings @Option(help = "") public static final OptionValue FlowSensitiveReduction = new OptionValue<>(false); + @Option(help = "") public static final OptionValue ConditionalElimination = new OptionValue<>(true); + @Option(help = "") public static final OptionValue UseProfilingInformation = new OptionValue<>(true); + @Option(help = "") public static final OptionValue RemoveNeverExecutedCode = new OptionValue<>(true); + @Option(help = "") public static final OptionValue UseExceptionProbability = new OptionValue<>(true); + @Option(help = "") public static final OptionValue UseExceptionProbabilityForOperations = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OmitHotExceptionStacktrace = new OptionValue<>(false); + @Option(help = "") public static final OptionValue GenSafepoints = new OptionValue<>(true); + @Option(help = "") public static final OptionValue GenLoopSafepoints = new OptionValue<>(true); + @Option(help = "") public static final OptionValue UseTypeCheckHints = new OptionValue<>(true); + @Option(help = "") public static final OptionValue InlineVTableStubs = new OptionValue<>(true); + @Option(help = "") public static final OptionValue AlwaysInlineVTableStubs = new OptionValue<>(false); - @Option(help = "") - public static final OptionValue GenAssertionCode = new OptionValue<>(false); - @Option(help = "") - public static final OptionValue AlignCallsForPatching = new OptionValue<>(true); + @Option(help = "") public static final OptionValue ResolveClassBeforeStaticInvoke = new OptionValue<>(false); + @Option(help = "") public static final OptionValue CanOmitFrame = new OptionValue<>(true); - // Translating tableswitch instructions - @Option(help = "") - public static final OptionValue MinimumJumpTableSize = new OptionValue<>(5); - @Option(help = "") - public static final OptionValue RangeTestsSwitchDensity = new OptionValue<>(5); - @Option(help = "") - public static final OptionValue MinTableSwitchDensity = new OptionValue<>(0.5); - // Ahead of time compilation @Option(help = "Try to avoid emitting code where patching is required") public static final OptionValue ImmutableCode = new OptionValue<>(false); + @Option(help = "Generate position independent code") + public static final OptionValue GeneratePIC = new OptionValue<>(false); + @Option(help = "") public static final OptionValue CallArrayCopy = new OptionValue<>(true); @@ -238,42 +282,58 @@ @Option(help = "") public static final OptionValue OptAssumptions = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptConvertDeoptsToGuards = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptReadElimination = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptCanonicalizer = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptDeoptimizationGrouping = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptEliminateGuards = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptImplicitNullChecks = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptLivenessAnalysis = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptLoopTransform = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptFloatingReads = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptTailDuplication = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptEliminatePartiallyRedundantGuards = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptFilterProfiledTypes = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptDevirtualizeInvokesOptimistically = new OptionValue<>(true); + @Option(help = "") public static final OptionValue OptPushThroughPi = new OptionValue<>(true); - @Option(help = "Allow backend to emit arithmetic and compares directly against memory.") - public static final OptionValue OptFoldMemory = new OptionValue<>(false); + @Option(help = "Allow backend to match complex expressions.") public static final OptionValue MatchExpressions = new OptionValue<>(true); + @Option(help = "Constant fold final fields with default values.") public static final OptionValue TrustFinalDefaultFields = new OptionValue<>(true); + @Option(help = "Mark well-known stable fields as such.") public static final OptionValue ImplicitStableValues = new OptionValue<>(true); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/LinkedIdentityHashMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/LinkedIdentityHashMap.java Fri Dec 12 20:29:35 2014 +0100 @@ -0,0 +1,252 @@ +/* + * 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.compiler.common; + +import java.util.*; +import java.util.function.*; + +/** + * A map that combines {@link IdentityHashMap} with {@link LinkedHashMap} for the purpose of + * ensuring a deterministic execution order during a capturing compilation. + */ +final class LinkedIdentityHashMap implements Map { + + private final LinkedHashMap, V> map; + + public LinkedIdentityHashMap() { + map = new LinkedHashMap<>(); + } + + public LinkedIdentityHashMap(Map m) { + map = new LinkedHashMap<>(m.size()); + putAll(m); + } + + public LinkedIdentityHashMap(int expectedMaxSize) { + map = new LinkedHashMap<>(expectedMaxSize); + } + + /** + * Wrapper for an object that gives uses the object's identity for the purpose of equality + * comparisons and computing a hash code. + */ + static final class Id { + final T object; + + public Id(T object) { + assert object != null; + this.object = object; + } + + @SuppressWarnings("unchecked") + @Override + public boolean equals(Object obj) { + return obj instanceof Id && ((Id) obj).object == object; + } + + @Override + public int hashCode() { + return System.identityHashCode(object); + } + } + + public int size() { + return map.size(); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public boolean containsKey(Object key) { + return map.containsKey(id(key)); + } + + @SuppressWarnings("unchecked") + private Id id(Object key) { + if (key == null) { + return null; + } + return new Id<>((K) key); + } + + public boolean containsValue(Object value) { + return map.containsValue(value); + } + + public V get(Object key) { + return map.get(id(key)); + } + + public V put(K key, V value) { + return map.put(id(key), value); + } + + public V remove(Object key) { + return map.remove(id(key)); + } + + @SuppressWarnings("unchecked") + public void putAll(Map m) { + if (m == null) { + throw new NullPointerException(); + } + if (m.getClass() == getClass()) { + LinkedIdentityHashMap that = (LinkedIdentityHashMap) m; + map.putAll(that.map); + + } else { + for (K key : m.keySet()) { + map.put(id(key), m.get(key)); + } + } + } + + public void clear() { + map.clear(); + } + + final class KeySet extends AbstractSet { + @Override + public int size() { + return map.size(); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public Iterator iterator() { + return new Iterator() { + final Iterator> i = map.keySet().iterator(); + + public boolean hasNext() { + return i.hasNext(); + } + + public K next() { + return i.next().object; + } + + public void remove() { + i.remove(); + } + }; + } + + @Override + public boolean contains(Object o) { + return containsKey(o); + } + + @Override + public boolean remove(Object o) { + return LinkedIdentityHashMap.this.remove(o) != null; + } + + public Spliterator spliterator() { + return Spliterators.spliterator(this, Spliterator.SIZED | Spliterator.ORDERED | Spliterator.DISTINCT); + } + + public void forEach(Consumer action) { + throw new UnsupportedOperationException(); + } + } + + public Set keySet() { + return new KeySet(); + } + + public Collection values() { + return map.values(); + } + + final class EntrySet extends AbstractSet> { + @Override + public int size() { + return map.size(); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public Iterator> iterator() { + return new Iterator>() { + final Iterator, V>> i = map.entrySet().iterator(); + + public boolean hasNext() { + return i.hasNext(); + } + + public Map.Entry next() { + Map.Entry, V> e = i.next(); + return new Map.Entry() { + + public K getKey() { + return e.getKey().object; + } + + public V getValue() { + return e.getValue(); + } + + public V setValue(V value) { + return e.setValue(value); + } + }; + } + + public void remove() { + i.remove(); + } + }; + } + + @Override + public boolean contains(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean remove(Object o) { + throw new UnsupportedOperationException(); + } + + public Spliterator> spliterator() { + throw new UnsupportedOperationException(); + } + + public void forEach(Consumer> action) { + throw new UnsupportedOperationException(); + } + } + + public Set> entrySet() { + return new EntrySet(); + } +} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Context.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Context.java Fri Dec 12 20:02:09 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,533 +0,0 @@ -/* - * 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.compiler.common.remote; - -import static java.lang.reflect.Modifier.*; - -import java.lang.reflect.*; -import java.nio.*; -import java.util.*; - -import sun.awt.util.*; - -import com.oracle.graal.api.code.Register.RegisterCategory; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.type.*; - -/** - * Manages a context for replay or remote compilation. - * - * With respect to replay or remote compilation, certain objects only exist on the VM side of the - * VM-compiler boundary. These are objects that encapsulate compiler references to user heap objects - * or other VM data such as native VM objects representing Java classes and methods. - */ -public class Context implements AutoCloseable { - - private static final ThreadLocal currentContext = new ThreadLocal<>(); - - private final Map, Fields> fieldsMap = new HashMap<>(); - - public enum Mode { - Capturing, - Replaying - } - - private Mode mode = Mode.Capturing; - - public Mode getMode() { - return mode; - } - - public void setMode(Mode mode) { - this.mode = mode; - } - - public static HashMap newMap() { - return Context.getCurrent() == null ? new HashMap<>() : new LinkedHashMap<>(); - } - - public static HashMap newMap(Map m) { - return Context.getCurrent() == null ? new HashMap<>(m) : new LinkedHashMap<>(m); - } - - public static HashMap newMap(int initialCapacity) { - return Context.getCurrent() == null ? new HashMap<>(initialCapacity) : new LinkedHashMap<>(initialCapacity); - } - - public static Map newIdentityMap() { - return Context.getCurrent() == null ? new IdentityHashMap<>() : new LinkedIdentityHashMap<>(); - } - - public static Map newIdentityMap(int expectedMaxSize) { - return Context.getCurrent() == null ? new IdentityHashMap<>(expectedMaxSize) : new LinkedIdentityHashMap<>(); - } - - public static Map newIdentityMap(Map m) { - return Context.getCurrent() == null ? new IdentityHashMap<>(m) : new LinkedIdentityHashMap<>(m); - } - - /** - * Gets a descriptor for the fields in a class that can be used for serialization. - */ - private Fields fieldsFor(Class c) { - Fields fields = fieldsMap.get(c); - if (fields == null) { - fields = Fields.forClass(c, Object.class, true, null); - fieldsMap.put(c, fields); - } - return fields; - } - - /** - * Classes whose values are subject to special serialization handling. - */ - // @formatter:off - private static final Set> DontCopyClasses = new HashSet<>(Arrays.asList( - Enum.class, - Integer.class, - Boolean.class, - Short.class, - Byte.class, - Character.class, - Float.class, - Long.class, - Double.class, - String.class, - Method.class, - Class.class, - Field.class, - Constructor.class, - RegisterCategory.class, - NamedLocationIdentity.class - )); - // @formatter:on - - private static void registerSharedGlobal(Class declaringClass, String staticFieldName) { - try { - SharedGlobal global = new SharedGlobal(declaringClass.getDeclaredField(staticFieldName)); - SharedGlobals.put(global.get(), global); - } catch (NoSuchFieldException e) { - // ignore non-existing fields - } catch (Exception e) { - throw new GraalInternalError(e); - } - } - - private static void registerSharedGlobals(Class declaringClass, Class staticFieldType) { - assert !staticFieldType.isPrimitive(); - try { - for (Field f : declaringClass.getDeclaredFields()) { - if (isStatic(f.getModifiers()) && isFinal(f.getModifiers()) && !f.getType().isPrimitive()) { - SharedGlobal global = new SharedGlobal(f); - if (staticFieldType.isAssignableFrom(f.getType())) { - SharedGlobals.put(global.get(), global); - } else { - Class componentType = f.getType().getComponentType(); - if (componentType != null && staticFieldType.isAssignableFrom(componentType)) { - Object[] vals = global.get(); - for (int i = 0; i < vals.length; i++) { - SharedGlobal g = new SharedGlobal(f, i); - Object obj = g.get(); - SharedGlobals.put(obj, g); - } - } - } - } - } - } catch (Exception e) { - throw new GraalInternalError(e); - } - } - - /** - * A shared global is a non-primitive value in a static final variable whose identity is - * important to the compiler. That is, equality tests against these values are performed with - * {@code ==} or these values are keys in identity hash maps. - */ - static class SharedGlobal { - final Field staticField; - final Integer index; - - public SharedGlobal(Field staticField) { - this(staticField, null); - } - - public SharedGlobal(Field staticField, Integer index) { - int mods = staticField.getModifiers(); - assert isStatic(mods) && isFinal(mods) && !staticField.getType().isPrimitive() : staticField; - staticField.setAccessible(true); - this.staticField = staticField; - this.index = index; - } - - @SuppressWarnings("unchecked") - public T get() { - try { - Object value = staticField.get(null); - if (index != null) { - value = ((Object[]) value)[index.intValue()]; - } - return (T) value; - } catch (Exception e) { - throw new GraalInternalError(e); - } - } - - @Override - public String toString() { - String res = staticField.getDeclaringClass().getName() + "." + staticField.getName(); - if (index != null) { - res += "[" + index + "]"; - } - return res; - } - } - - /** - * Objects that should not be copied but retrieved from final static fields. - */ - private static final Map SharedGlobals = new IdentityHashMap<>(); - static { - registerSharedGlobal(ByteOrder.class, "BIG_ENDIAN"); - registerSharedGlobal(ByteOrder.class, "LITTLE_ENDIAN"); - registerSharedGlobal(ArrayList.class, "EMPTY_ELEMENTDATA"); - registerSharedGlobal(ArrayList.class, "DEFAULTCAPACITY_EMPTY_ELEMENTDATA"); - registerSharedGlobals(StampFactory.class, Stamp.class); - } - - /** - * Determines if a given class is a subclass of any class in a given collection of classes. - */ - private static boolean isAssignableTo(Class from, Collection> to) { - return to.stream().anyMatch(c -> c.isAssignableFrom(from)); - } - - /** - * Gets a string representing the identity of an object. - */ - private static String id(Object o) { - if (o == null) { - return "null"; - } - return String.format("%s@%x", MetaUtil.getSimpleName(o.getClass(), true), System.identityHashCode(o)); - } - - /** - * Process an object graph copy operation iteratively using a worklist. - */ - private void copy0(Deque worklist, Map copies) { - // 1. Traverse object graph, making uninitialized copies of - // objects that need to be copied (other object values are transferred 'as is') - while (!worklist.isEmpty()) { - Object obj = worklist.pollFirst(); - // System.out.printf("worklist-: %s%n", s(obj)); - assert copies.get(obj) == copies : id(obj) + " -> " + id(copies.get(obj)); - assert pool.get(obj) == null; - Class clazz = obj.getClass(); - Class componentType = clazz.getComponentType(); - if (componentType != null) { - if (componentType.isPrimitive()) { - if (obj instanceof int[]) { - copies.put(obj, ((int[]) obj).clone()); - } else if (obj instanceof byte[]) { - copies.put(obj, ((byte[]) obj).clone()); - } else if (obj instanceof char[]) { - copies.put(obj, ((char[]) obj).clone()); - } else if (obj instanceof short[]) { - copies.put(obj, ((short[]) obj).clone()); - } else if (obj instanceof float[]) { - copies.put(obj, ((float[]) obj).clone()); - } else if (obj instanceof long[]) { - copies.put(obj, ((long[]) obj).clone()); - } else if (obj instanceof double[]) { - copies.put(obj, ((double[]) obj).clone()); - } else { - copies.put(obj, ((boolean[]) obj).clone()); - } - } else { - Object[] o = (Object[]) obj; - Object[] c = o.clone(); - copies.put(obj, c); - // System.out.printf("m+: %s%n", s(obj)); - for (int i = 0; i < c.length; i++) { - c[i] = copyFieldOrElement(worklist, copies, o[i]); - } - } - } else { - assert !isAssignableTo(clazz, DontCopyClasses); - Object c; - try { - c = UnsafeAccess.unsafe.allocateInstance(clazz); - copies.put(obj, c); - // System.out.printf("m+: %s%n", s(obj)); - - Fields fields = fieldsFor(clazz); - fields.copy(obj, c, (i, o) -> copyFieldOrElement(worklist, copies, o)); - } catch (InstantiationException e) { - throw new GraalInternalError(e); - } - } - } - - // 2. Initialize fields of copied objects - for (Map.Entry e : copies.entrySet()) { - Object src = e.getKey(); - Object dst = e.getValue(); - assert dst != copies : id(src); - pool.put(src, dst); - if (src instanceof Object[]) { - Object[] srcArr = (Object[]) src; - Object[] dstArr = (Object[]) dst; - for (int i = 0; i < srcArr.length; i++) { - Object dstElement = copies.get(srcArr[i]); - if (dstElement != null) { - dstArr[i] = dstElement; - } - } - } else { - Fields fields = fieldsFor(src.getClass()); - assert !Proxy.isProxyClass(dst.getClass()); - for (int index = 0; index < fields.getCount(); index++) { - if (!fields.getType(index).isPrimitive()) { - Object value = copies.get(fields.getObject(src, index)); - if (value != null) { - fields.set(dst, index, value); - } - } - } - } - } - } - - /** - * Given the value of an object field or object array element, returns the value that should be - * written into the copy of the object or array. - */ - private Object copyFieldOrElement(Deque worklist, Map copies, Object srcValue) { - Object dstValue = srcValue; - if (srcValue != null && !Proxy.isProxyClass(srcValue.getClass())) { - if (isAssignableTo(srcValue.getClass(), DontCopyClasses) || SharedGlobals.containsKey(srcValue)) { - pool.put(srcValue, srcValue); - return srcValue; - } - dstValue = pool.get(srcValue); - if (dstValue == null) { - if (srcValue instanceof Remote) { - dstValue = get(srcValue); - } else { - dstValue = copies.get(srcValue); - if (dstValue == null) { - // System.out.printf("worklist+: %s%n", s(srcValue)); - worklist.add(srcValue); - copies.put(srcValue, copies); - } else if (dstValue == copies) { - dstValue = null; - } - } - } - } - return dstValue; - } - - /** - * Copies an object graph. This operation does not copy: - *
    - *
  • objects whose type is assignable to one of {@link #DontCopyClasses}
  • - *
  • proxy objects
  • - *
- * In addition, copies in {@link #pool} are re-used. - */ - private Object copy(Object root) { - long start = System.currentTimeMillis(); - assert !(isAssignableTo(root.getClass(), DontCopyClasses) || SharedGlobals.containsKey(root)); - // System.out.printf("----- %s ------%n", s(obj)); - assert pool.get(root) == null; - Deque worklist = new IdentityLinkedList<>(); - worklist.add(root); - IdentityHashMap copies = new IdentityHashMap<>(); - copies.put(root, copies); - copy0(worklist, copies); - if (DEBUG) { - long duration = System.currentTimeMillis() - start; - if (duration > 10) { - System.out.printf("After copying %s (proxies: %d, pool: %d) %d ms%n", root.getClass().getSimpleName(), proxies.size(), pool.size(), duration); - } - } - return pool.get(root); - } - - /** - * Creates an opens a context for a remote compilation request or a replay compilation - * capturing. This should be used in conjunction with the try-finally statement: - * - *
-     * try (Context c = new Context()) {
-     *     ...
-     * }
-     * 
- * - * Open one context can be active at any time for a thread. - */ - public Context() { - assert currentContext.get() == null : currentContext.get(); - currentContext.set(this); - pool = new IdentityHashMap<>(); - } - - private final Map proxies = new IdentityHashMap<>(); - private final Map pool; - - int invocationCacheHits; - int invocationCacheMisses; - - /** - * Gets the value of a given object within this context. - */ - @SuppressWarnings("unchecked") - public T get(Object obj) { - if (obj == null || Proxy.isProxyClass(obj.getClass())) { - return (T) obj; - } - if (obj instanceof Remote) { - Object proxy = proxies.get(obj); - if (proxy == null) { - Class[] interfaces = ProxyUtil.getAllInterfaces(obj.getClass()); - proxy = Proxy.newProxyInstance(obj.getClass().getClassLoader(), interfaces, new Handler<>(obj)); - proxies.put(obj, proxy); - } - return (T) proxy; - } else { - Object value; - if (isAssignableTo(obj.getClass(), DontCopyClasses) || SharedGlobals.containsKey(obj)) { - value = obj; - } else { - value = pool.get(obj); - if (value == null) { - if (mode == Mode.Capturing) { - value = copy(obj); - } else { - throw new GraalInternalError("No captured state for %s [class=%s]", obj, obj.getClass()); - } - } - } - return (T) value; - } - } - - private static final boolean DEBUG = Boolean.getBoolean("graal.replayContext.debug"); - - public void close() { - assert currentContext.get() == this : currentContext.get(); - if (DEBUG) { - System.out.printf("proxies: %d, pool: %d, invocation cache hits: %d, invocation cache misses: %d%n", proxies.size(), pool.size(), invocationCacheHits, invocationCacheMisses); - } - currentContext.set(null); - } - - /** - * Checks that a given value is valid within the {@linkplain #getCurrent() current context} (if - * any). - */ - public static boolean check(Object o) { - if (o != null) { - Context c = currentContext.get(); - if (c != null) { - if (o instanceof Remote) { - if (!Proxy.isProxyClass(o.getClass())) { - throw new GraalInternalError("Expecting proxy, found instance of %s", o.getClass()); - } - } else { - if (Proxy.isProxyClass(o.getClass())) { - throw new GraalInternalError("Expecting instance of %s, found proxy", o.getClass()); - } - } - } - } - return true; - } - - /** - * Asserts that the current caller is in code that is on the VM side. - * - * @param errorMessage the error message used for the {@link GraalInternalError} thrown if the - * check fails - * @return true if the check succeeds - * @throw AssertionError if the check fails - */ - public static boolean assertInLocal(String errorMessage) { - Context c = Context.getCurrent(); - if (c != null) { - if (!c.inProxyInvocation()) { - throw new AssertionError(errorMessage); - } - } - return true; - } - - private NoContext leave; - int activeInvocations; - - /** - * Enters a scope that disables the {@linkplain Context#getCurrent() current} context. The - * disabled scope is exited when {@link NoContext#close()} is called on the returned object. - */ - public NoContext leave() { - return new NoContext(); - } - - public class NoContext implements AutoCloseable { - NoContext() { - assert currentContext.get() == Context.this; - assert Context.this.leave == null; - Context.this.leave = this; - currentContext.set(null); - } - - public void close() { - assert leave == this; - assert currentContext.get() == null; - currentContext.set(Context.this); - leave = null; - } - } - - /** - * Gets the currently active context for the calling thread. - * - * @return {@code null} if there is no context active on the calling thread - */ - public static Context getCurrent() { - return currentContext.get(); - } - - public boolean inProxyInvocation() { - return activeInvocations != 0; - } - - public static void breakpoint() { - if (getCurrent() != null) { - System.console(); - } - } -} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Handler.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Handler.java Fri Dec 12 20:02:09 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * 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.compiler.common.remote; - -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; - -public class Handler implements InvocationHandler { - - private final T delegate; - - /** - * Proxies objects may be visible to multiple threads. - */ - Map cachedInvocations = new ConcurrentHashMap<>(); - - public Handler(T delegate) { - this.delegate = delegate; - } - - static Object[] unproxify(Object[] args) { - if (args == null) { - return args; - } - Object[] res = args; - for (int i = 0; i < args.length; i++) { - Object arg = args[i]; - if (arg != null) { - if (Proxy.isProxyClass(arg.getClass())) { - Handler h = (Handler) Proxy.getInvocationHandler(arg); - if (res == args) { - res = args.clone(); - } - res[i] = h.delegate; - } else if (arg instanceof Object[]) { - Object[] arrayArg = (Object[]) arg; - arrayArg = unproxify(arrayArg); - if (arrayArg != arg) { - if (res == args) { - res = args.clone(); - } - res[i] = arrayArg; - } - } - } - } - return res; - } - - private static boolean isCacheable(Method method) { - // TODO: use annotations for finer control of what should be cached - return method.getReturnType() != Void.TYPE; - } - - private static final Object NULL_RESULT = new Object(); - - @Override - public Object invoke(Object proxy, Method method, Object[] a) throws Throwable { - Object[] args = unproxify(a); - boolean isCacheable = isCacheable(method); - Invocation invocation = new Invocation(method, delegate, args); - if (isCacheable) { - Object result = cachedInvocations.get(invocation); - if (result != null) { - if (result == NULL_RESULT) { - result = null; - } - // System.out.println(invocation + ": " + result); - return result; - } - } else { - // System.out.println("not cacheable: " + method); - } - - Context context = Context.getCurrent(); - assert context != null; - try { - assert context.activeInvocations >= 0; - context.activeInvocations++; - Object result = invocation.invoke(); - result = context.get(result); - if (isCacheable) { - context.invocationCacheHits++; - cachedInvocations.put(invocation, result == null ? NULL_RESULT : result); - } - return result; - } finally { - assert context.activeInvocations > 0; - context.activeInvocations--; - } - } -} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Invocation.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Invocation.java Fri Dec 12 20:02:09 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * 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.compiler.common.remote; - -import java.lang.reflect.*; -import java.util.*; -import java.util.stream.*; - -class Invocation { - final Method method; - final Object receiver; - final Object[] args; - - public Invocation(Method method, Object receiver, Object[] args) { - this.method = method; - this.receiver = receiver; - this.args = args; - } - - @Override - public String toString() { - String res = receiver.getClass().getSimpleName() + "@" + System.identityHashCode(receiver) + "." + method.getName(); - if (args == null) { - return res + "()"; - } - return res + "(" + Arrays.asList(args).stream().map(o -> String.valueOf(o)).collect(Collectors.joining(", ")) + ")"; - } - - public Object invoke() { - try { - if (args == null) { - return method.invoke(receiver); - } else { - return method.invoke(receiver, args); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Invocation) { - Invocation that = (Invocation) obj; - assert that.receiver == receiver; - return that.method.equals(this.method) && Arrays.equals(that.args, this.args); - - } - return false; - } - - @Override - public int hashCode() { - if (args == null) { - return method.hashCode(); - } - return method.hashCode() ^ args.length; - } -} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/LinkedIdentityHashMap.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/LinkedIdentityHashMap.java Fri Dec 12 20:02:09 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,254 +0,0 @@ -/* - * 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.compiler.common.remote; - -import java.util.*; -import java.util.function.*; - -import com.oracle.graal.compiler.common.remote.Context.Mode; - -/** - * A map that combines {@link IdentityHashMap} with {@link LinkedHashMap} for the purpose of - * ensuring a deterministic execution order during {@link Mode#Capturing}. - */ -final class LinkedIdentityHashMap implements Map { - - private final LinkedHashMap, V> map; - - public LinkedIdentityHashMap() { - map = new LinkedHashMap<>(); - } - - public LinkedIdentityHashMap(Map m) { - map = new LinkedHashMap<>(m.size()); - putAll(m); - } - - public LinkedIdentityHashMap(int expectedMaxSize) { - map = new LinkedHashMap<>(expectedMaxSize); - } - - /** - * Wrapper for an object that gives uses the object's identity for the purpose of equality - * comparisons and computing a hash code. - */ - static final class Id { - final T object; - - public Id(T object) { - assert object != null; - this.object = object; - } - - @SuppressWarnings("unchecked") - @Override - public boolean equals(Object obj) { - return obj instanceof Id && ((Id) obj).object == object; - } - - @Override - public int hashCode() { - return System.identityHashCode(object); - } - } - - public int size() { - return map.size(); - } - - public boolean isEmpty() { - return map.isEmpty(); - } - - public boolean containsKey(Object key) { - return map.containsKey(id(key)); - } - - @SuppressWarnings("unchecked") - private Id id(Object key) { - if (key == null) { - return null; - } - return new Id<>((K) key); - } - - public boolean containsValue(Object value) { - return map.containsValue(value); - } - - public V get(Object key) { - return map.get(id(key)); - } - - public V put(K key, V value) { - return map.put(id(key), value); - } - - public V remove(Object key) { - return map.remove(id(key)); - } - - @SuppressWarnings("unchecked") - public void putAll(Map m) { - if (m == null) { - throw new NullPointerException(); - } - if (m.getClass() == getClass()) { - LinkedIdentityHashMap that = (LinkedIdentityHashMap) m; - map.putAll(that.map); - - } else { - for (K key : m.keySet()) { - map.put(id(key), m.get(key)); - } - } - } - - public void clear() { - map.clear(); - } - - final class KeySet extends AbstractSet { - @Override - public int size() { - return map.size(); - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public Iterator iterator() { - return new Iterator() { - final Iterator> i = map.keySet().iterator(); - - public boolean hasNext() { - return i.hasNext(); - } - - public K next() { - return i.next().object; - } - - public void remove() { - i.remove(); - } - }; - } - - @Override - public boolean contains(Object o) { - return containsKey(o); - } - - @Override - public boolean remove(Object o) { - return LinkedIdentityHashMap.this.remove(o) != null; - } - - public Spliterator spliterator() { - return Spliterators.spliterator(this, Spliterator.SIZED | Spliterator.ORDERED | Spliterator.DISTINCT); - } - - public void forEach(Consumer action) { - throw new UnsupportedOperationException(); - } - } - - public Set keySet() { - return new KeySet(); - } - - public Collection values() { - return map.values(); - } - - final class EntrySet extends AbstractSet> { - @Override - public int size() { - return map.size(); - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public Iterator> iterator() { - return new Iterator>() { - final Iterator, V>> i = map.entrySet().iterator(); - - public boolean hasNext() { - return i.hasNext(); - } - - public Map.Entry next() { - Map.Entry, V> e = i.next(); - return new Map.Entry() { - - public K getKey() { - return e.getKey().object; - } - - public V getValue() { - return e.getValue(); - } - - public V setValue(V value) { - return e.setValue(value); - } - }; - } - - public void remove() { - i.remove(); - } - }; - } - - @Override - public boolean contains(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean remove(Object o) { - throw new UnsupportedOperationException(); - } - - public Spliterator> spliterator() { - throw new UnsupportedOperationException(); - } - - public void forEach(Consumer> action) { - throw new UnsupportedOperationException(); - } - } - - public Set> entrySet() { - return new EntrySet(); - } -} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/ProxyUtil.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/ProxyUtil.java Fri Dec 12 20:02:09 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.common.remote; - -import java.util.*; - -public final class ProxyUtil { - - public static Class[] getAllInterfaces(Class clazz) { - HashSet> interfaces = new HashSet<>(); - getAllInterfaces(clazz, interfaces); - return interfaces.toArray(new Class[interfaces.size()]); - } - - private static void getAllInterfaces(Class clazz, HashSet> interfaces) { - for (Class iface : clazz.getInterfaces()) { - if (!interfaces.contains(iface)) { - interfaces.add(iface); - getAllInterfaces(iface, interfaces); - } - } - if (clazz.getSuperclass() != null) { - getAllInterfaces(clazz.getSuperclass(), interfaces); - } - } -} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri Dec 12 20:29:35 2014 +0100 @@ -27,7 +27,6 @@ import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.nodes.ConstantNode.*; -import java.io.*; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.atomic.*; @@ -44,8 +43,6 @@ import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.GraalCompiler.Request; import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.remote.*; -import com.oracle.graal.compiler.common.remote.Context.Mode; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; @@ -676,96 +673,6 @@ } /** - * Determines if {@linkplain #compile(ResolvedJavaMethod, StructuredGraph) compilation} should - * also be attempted in a replay {@link Context} where possible. - */ - private static final boolean TEST_REPLAY = Boolean.getBoolean("graal.testReplay"); - - /** - * Determines if a {@link #checkCompilationResultsEqual mismatching} replay compilation result - * results in a diagnostic message or a test error. - */ - private static final boolean TEST_REPLAY_MISMATCH_IS_FAILURE = Boolean.parseBoolean(System.getProperty("graal.testReplay.strict", "true")); - - /** - * Directory into which tests can dump content useful in debugging test failures. - */ - private static final File OUTPUT_DIR = new File(System.getProperty("graal.test.output"), "testOutput"); - - protected static File getOutputDir() { - if (!OUTPUT_DIR.exists()) { - OUTPUT_DIR.mkdirs(); - } - if (!OUTPUT_DIR.exists()) { - throw new GraalInternalError("Could not create test output directory: %s", OUTPUT_DIR.getAbsolutePath()); - } - return OUTPUT_DIR; - } - - protected String dissasembleToFile(CompilationResult result, ResolvedJavaMethod installedCodeOwner, String fileSuffix) { - String dis = getCodeCache().disassemble(result, null); - File disFile = new File(getOutputDir(), installedCodeOwner.format("%H.%n_%p").replace(", ", "__") + "." + fileSuffix); - try (PrintStream ps = new PrintStream(new FileOutputStream(disFile))) { - ps.println(dis); - return disFile.getAbsolutePath(); - } catch (IOException e) { - return null; - } - } - - protected void checkCompilationResultsEqual(CompilationResult expected, CompilationResult actual, ResolvedJavaMethod installedCodeOwner) { - if (!actual.equals(expected)) { - // Reset to capturing mode as dumping/printing/disassembling - // may need to execute proxy methods that have not yet been executed - String expectedDisFile = dissasembleToFile(expected, installedCodeOwner, "expected"); - String actualDisFile = dissasembleToFile(actual, installedCodeOwner, "actual"); - String message = "Reply compilation result differs from capturing compilation result"; - if (expectedDisFile != null && actualDisFile != null) { - message += String.format(" [diff %s %s]", expectedDisFile, actualDisFile); - } - if (TEST_REPLAY_MISMATCH_IS_FAILURE) { - Assert.fail(message); - } else { - System.out.println(message); - } - } - } - - protected CompilationResult recompile(Context c, Mode mode, ResolvedJavaMethod installedCodeOwner) { - try (Debug.Scope s = Debug.scope(mode.name(), new DebugDumpScope(mode.name(), true))) { - - StructuredGraph graphToCompile; - CallingConvention cc; - - try (Context.NoContext l = c.leave()) { - graphToCompile = parseForCompile(installedCodeOwner); - lastCompiledGraph = graphToCompile; - cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false); - } - graphToCompile = c.get(graphToCompile); - Request request = c.get(new GraalCompiler.Request<>(graphToCompile, null, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null, - getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), new CompilationResult(), - CompilationResultBuilderFactory.Default)); - return GraalCompiler.compile(request); - } catch (Throwable e) { - throw Debug.handle(e); - } - } - - protected void testReplayCompile(ResolvedJavaMethod installedCodeOwner) { - try (Context c = new Context()) { - - // Capturing compilation - CompilationResult expected = recompile(c, Mode.Capturing, installedCodeOwner); - - // Replay compilation - CompilationResult actual = recompile(c, Mode.Replaying, installedCodeOwner); - - checkCompilationResultsEqual(expected, actual, installedCodeOwner); - } - } - - /** * Compiles a given method. * * @param installedCodeOwner the method the compiled code will be associated with when installed @@ -777,13 +684,9 @@ StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner) : graph; lastCompiledGraph = graphToCompile; CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false); - CompilationResult res = GraalCompiler.compileGraph(graphToCompile, null, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), + Request request = new Request<>(graphToCompile, null, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null, getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default); - - if (TEST_REPLAY && graph == null) { - testReplayCompile(installedCodeOwner); - } - return res; + return GraalCompiler.compile(request); } protected StructuredGraph lastCompiledGraph; diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LocationMarker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LocationMarker.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LocationMarker.java Fri Dec 12 20:29:35 2014 +0100 @@ -41,7 +41,7 @@ public static class Options { // @formatter:off @Option(help = "Use decoupled pass for location marking (instead of using LSRA marking)") - public static final OptionValue UseLocationMarker = new OptionValue<>(true); + public static final OptionValue UseLocationMarker = new OptionValue<>(false); // @formatter:on } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/PhiResolver.java Fri Dec 12 20:29:35 2014 +0100 @@ -29,6 +29,7 @@ import java.util.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.gen.*; import com.oracle.graal.nodes.*; @@ -119,7 +120,7 @@ /** * Maps operands to nodes. */ - private final HashMap operandToNodeMap = new HashMap<>(); + private final HashMap operandToNodeMap = CollectionsFactory.newMap(); public PhiResolver(LIRGeneratorTool gen) { this.gen = gen; diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpHandler.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpHandler.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugDumpHandler.java Fri Dec 12 20:29:35 2014 +0100 @@ -28,6 +28,11 @@ void dump(Object object, String message); + /** + * Flushes and releases resources managed by this dump handler. A subsequent call to + * {@link #dump(Object, String)} will create and open new resources. That is, this method can be + * used to reset the handler. + */ @Override void close(); } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Fri Dec 12 20:29:35 2014 +0100 @@ -68,8 +68,9 @@ // these two arrays contain one entry for each NodeClass, indexed by NodeClass.iterableId. // they contain the first and last pointer to a linked list of all nodes with this type. - private final ArrayList nodeCacheFirst; - private final ArrayList nodeCacheLast; + private final ArrayList iterableNodesFirst; + private final ArrayList iterableNodesLast; + private int nodesDeletedSinceLastCompression; private int nodesDeletedBeforeLastCompression; @@ -153,8 +154,8 @@ */ public Graph(String name) { nodes = new Node[INITIAL_NODES_SIZE]; - nodeCacheFirst = new ArrayList<>(NodeClass.cacheSize()); - nodeCacheLast = new ArrayList<>(NodeClass.cacheSize()); + iterableNodesFirst = new ArrayList<>(NodeClass.allocatedNodeIterabledIds()); + iterableNodesLast = new ArrayList<>(NodeClass.allocatedNodeIterabledIds()); this.name = name; if (MODIFICATION_COUNTS_ENABLED) { nodeModCounts = new int[INITIAL_NODES_SIZE]; @@ -708,7 +709,7 @@ } Node getStartNode(int iterableId) { - Node start = nodeCacheFirst.size() <= iterableId ? null : nodeCacheFirst.get(iterableId); + Node start = iterableNodesFirst.size() <= iterableId ? null : iterableNodesFirst.get(iterableId); return start; } @@ -742,20 +743,7 @@ nodes[id] = node; nodesSize++; - int nodeClassId = node.getNodeClass().iterableId(); - if (nodeClassId != Node.NOT_ITERABLE) { - while (nodeCacheFirst.size() <= nodeClassId) { - nodeCacheFirst.add(null); - nodeCacheLast.add(null); - } - Node prev = nodeCacheLast.get(nodeClassId); - if (prev != null) { - prev.typeCacheNext = node; - } else { - nodeCacheFirst.set(nodeClassId, node); - } - nodeCacheLast.set(nodeClassId, node); - } + updateNodeCaches(node); node.id = id; if (nodeEventListener != null) { @@ -763,6 +751,42 @@ } } + @SuppressWarnings("unused") + private void postDeserialization() { + recomputeIterableNodeLists(); + } + + /** + * Rebuilds the lists used to support {@link #getNodes(Class)}. This is useful for serialization + * where the underlying {@linkplain NodeClass#iterableId() iterable ids} may have changed. + */ + private void recomputeIterableNodeLists() { + iterableNodesFirst.clear(); + iterableNodesLast.clear(); + for (Node node : nodes) { + if (node != null && node.isAlive()) { + updateNodeCaches(node); + } + } + } + + private void updateNodeCaches(Node node) { + int nodeClassId = node.getNodeClass().iterableId(); + if (nodeClassId != Node.NOT_ITERABLE) { + while (iterableNodesFirst.size() <= nodeClassId) { + iterableNodesFirst.add(null); + iterableNodesLast.add(null); + } + Node prev = iterableNodesLast.get(nodeClassId); + if (prev != null) { + prev.typeCacheNext = node; + } else { + iterableNodesFirst.set(nodeClassId, node); + } + iterableNodesLast.set(nodeClassId, node); + } + } + void unregister(Node node) { assert !isFrozen(); assert !node.isDeleted() : "cannot delete a node twice! node=" + node; diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java Fri Dec 12 20:29:35 2014 +0100 @@ -31,7 +31,7 @@ import sun.misc.*; import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.remote.*; +import com.oracle.graal.compiler.common.CollectionsFactory.Mode; import com.oracle.graal.graph.Graph.NodeEventListener; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.graph.spi.*; @@ -209,20 +209,20 @@ } /** - * Creates a {@link Node} set. If the current thread has a non-null - * {@linkplain Context#getCurrent() compilation replay scope}, the returned set will have a - * deterministic iteration order determined by the order in which elements are inserted in the - * map. + * Creates a {@link Node} set. If the current thread is + * {@linkplain CollectionsFactory#getMode() using} {@link Mode#DETERMINISTIC_ITERATION_ORDER} + * collections, the returned set will have an iteration order determined by the order in which + * elements are inserted in the set. */ public static Set newSet() { - return Context.getCurrent() == null ? new HashSet<>() : new LinkedHashSet<>(); + return CollectionsFactory.getMode() == Mode.STANDARD ? new HashSet<>() : new LinkedHashSet<>(); } /** * @see #newSet() */ public static Set newSet(Collection c) { - return Context.getCurrent() == null ? new HashSet<>(c) : new LinkedHashSet<>(c); + return CollectionsFactory.getMode() == Mode.STANDARD ? new HashSet<>(c) : new LinkedHashSet<>(c); } public static Map newMap() { @@ -250,15 +250,15 @@ } public static Map newIdentityMap() { - return Context.newIdentityMap(); + return CollectionsFactory.newIdentityMap(); } public static Map newIdentityMap(Map m) { - return Context.newIdentityMap(m); + return CollectionsFactory.newIdentityMap(m); } public static Map newIdentityMap(int expectedMaxSize) { - return Context.newIdentityMap(expectedMaxSize); + return CollectionsFactory.newIdentityMap(expectedMaxSize); } /** diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java Fri Dec 12 20:29:35 2014 +0100 @@ -255,7 +255,7 @@ return isSimplifiable; } - public static int cacheSize() { + static int allocatedNodeIterabledIds() { return nextIterableId; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableAddressOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableAddressOp.java Fri Dec 12 20:29:35 2014 +0100 @@ -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.amd64; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.hotspot.HotSpotGraalRuntime; + +public class AMD64HotSpotCardTableAddressOp extends AMD64LIRInstruction { + + @Def({OperandFlag.REG}) private AllocatableValue result; + + public AMD64HotSpotCardTableAddressOp(AllocatableValue result) { + this.result = result; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) { + Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); + int alignment = hostWordKind.getBitCount() / Byte.SIZE; + JavaConstant address = JavaConstant.forIntegerKind(hostWordKind, 0); + // recordDataReferenceInCode forces the mov to be rip-relative + asm.movq(ValueUtil.asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(address, alignment)); + MarkId.recordMark(crb, MarkId.CARD_TABLE_ADDRESS); + } + +} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableShiftOp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCardTableShiftOp.java Fri Dec 12 20:29:35 2014 +0100 @@ -0,0 +1,50 @@ +/* + * 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.amd64; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.amd64.*; +import com.oracle.graal.hotspot.meta.HotSpotCodeCacheProvider.*; +import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.hotspot.HotSpotGraalRuntime; + +public class AMD64HotSpotCardTableShiftOp extends AMD64LIRInstruction { + + @Def({OperandFlag.REG, OperandFlag.ILLEGAL}) private AllocatableValue result; + + public AMD64HotSpotCardTableShiftOp(AllocatableValue result) { + this.result = result; + } + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler asm) { + Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); + int alignment = Kind.Int.getBitCount() / Byte.SIZE; + JavaConstant shift = JavaConstant.forIntegerKind(hostWordKind, 0); + // recordDataReferenceInCode forces the mov to be rip-relative + asm.movq(ValueUtil.asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(shift, alignment)); + MarkId.recordMark(crb, MarkId.CARD_TABLE_SHIFT); + } +} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java Fri Dec 12 20:29:35 2014 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; +import com.oracle.graal.hotspot.HotSpotGraalRuntime; import com.oracle.graal.api.meta.*; import com.oracle.graal.asm.*; import com.oracle.graal.asm.amd64.*; @@ -66,14 +67,31 @@ masm.cmpq(asRegister(x), patch); } } else if (y instanceof HotSpotMetaspaceConstant) { + boolean isImmutable = GraalOptions.ImmutableCode.getValue(); + boolean generatePIC = GraalOptions.GeneratePIC.getValue(); if (y.getKind() == Kind.Int) { // compressed metaspace pointer crb.recordInlineDataInCode(y); - masm.cmpl(asRegister(x), y.asInt()); + if (isImmutable && generatePIC) { + Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); + int alignment = hostWordKind.getBitCount() / Byte.SIZE; + // recordDataReferenceInCode forces the mov to be rip-relative + masm.cmpl(asRegister(x), (AMD64Address) crb.recordDataReferenceInCode(JavaConstant.INT_0, alignment)); + } else { + masm.cmpl(asRegister(x), y.asInt()); + } } else { // uncompressed metaspace pointer - AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(y, 8); - masm.cmpq(asRegister(x), patch); + if (isImmutable && generatePIC) { + crb.recordInlineDataInCode(y); + Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); + int alignment = hostWordKind.getBitCount() / Byte.SIZE; + // recordDataReferenceInCode forces the mov to be rip-relative + masm.cmpq(asRegister(x), (AMD64Address) crb.recordDataReferenceInCode(JavaConstant.INT_0, alignment)); + } else { + AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(y, 8); + masm.cmpq(asRegister(x), patch); + } } } else { throw GraalInternalError.shouldNotReachHere(); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerationResult.java Fri Dec 12 20:29:35 2014 +0100 @@ -25,6 +25,7 @@ import java.util.*; import com.oracle.graal.api.code.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.hotspot.stubs.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.StandardOp.SaveRegistersOp; @@ -45,7 +46,7 @@ * Map from debug infos that need to be updated with callee save information to the operations * that provide the information. */ - private Map calleeSaveInfo = new HashMap<>(); + private Map calleeSaveInfo = CollectionsFactory.newMap(); public AMD64HotSpotLIRGenerationResult(LIR lir, FrameMapBuilder frameMapBuilder, Object stub) { super(lir, frameMapBuilder); diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri Dec 12 20:29:35 2014 +0100 @@ -211,6 +211,20 @@ append(new AMD64HotSpotLeaveUnpackFramesStackFrameOp(threadRegister, config.threadLastJavaSpOffset(), config.threadLastJavaPcOffset(), config.threadLastJavaFpOffset(), saveRegisterOp)); } + @Override + public Value emitCardTableShift() { + Variable result = newVariable(LIRKind.value(Kind.Long)); + append(new AMD64HotSpotCardTableShiftOp(result)); + return result; + } + + @Override + public Value emitCardTableAddress() { + Variable result = newVariable(LIRKind.value(Kind.Long)); + append(new AMD64HotSpotCardTableAddressOp(result)); + return result; + } + /** * @param savedRegisters the registers saved by this operation which may be subject to pruning * @param savedRegisterLocations the slots to which the registers are saved diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java Fri Dec 12 20:29:35 2014 +0100 @@ -32,6 +32,7 @@ import com.oracle.graal.asm.amd64.*; import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; @@ -94,17 +95,37 @@ } else if (input instanceof HotSpotMetaspaceConstant) { assert input.getKind() == Kind.Int || input.getKind() == Kind.Long; boolean compressed = input.getKind() == Kind.Int; + boolean isImmutable = GraalOptions.ImmutableCode.getValue(); + boolean generatePIC = GraalOptions.GeneratePIC.getValue(); crb.recordInlineDataInCode(input); if (isRegister(result)) { if (compressed) { - masm.movl(asRegister(result), input.asInt()); + if (isImmutable && generatePIC) { + Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); + int alignment = hostWordKind.getBitCount() / Byte.SIZE; + // recordDataReferenceInCode forces the mov to be rip-relative + masm.movl(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(JavaConstant.INT_0, alignment)); + } else { + masm.movl(asRegister(result), input.asInt()); + } } else { - masm.movq(asRegister(result), input.asLong()); + if (isImmutable && generatePIC) { + Kind hostWordKind = HotSpotGraalRuntime.getHostWordKind(); + int alignment = hostWordKind.getBitCount() / Byte.SIZE; + // recordDataReferenceInCode forces the mov to be rip-relative + masm.movq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(JavaConstant.INT_0, alignment)); + } else { + masm.movq(asRegister(result), input.asLong()); + } } } else { assert isStackSlot(result); if (compressed) { - masm.movl((AMD64Address) crb.asAddress(result), input.asInt()); + if (isImmutable && generatePIC) { + throw GraalInternalError.shouldNotReachHere("Unsupported operation offset(%rip) -> mem (mem -> mem)"); + } else { + masm.movl((AMD64Address) crb.asAddress(result), input.asInt()); + } } else { throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory"); } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Fri Dec 12 20:29:35 2014 +0100 @@ -1228,10 +1228,10 @@ int intSize = providers.getCodeCache().getTarget().arch.getSizeInBytes(Kind.Int); if (regNumber >= HSAIL.s0.number && regNumber <= HSAIL.s31.number) { long offset = config.hsailFrameHeaderSize + intSize * (regNumber - HSAIL.s0.number); - location = ConstantLocationNode.create(FINAL_LOCATION, valueKind, offset, hostGraph); + location = ConstantLocationNode.create(FINAL_LOCATION, offset, hostGraph); } else if (regNumber >= HSAIL.d0.number && regNumber <= HSAIL.d15.number) { long offset = config.hsailFrameHeaderSize + intSize * numSRegs + longSize * (regNumber - HSAIL.d0.number); - location = ConstantLocationNode.create(FINAL_LOCATION, valueKind, offset, hostGraph); + location = ConstantLocationNode.create(FINAL_LOCATION, offset, hostGraph); } else { throw GraalInternalError.shouldNotReachHere("unknown hsail register: " + regNumber); } @@ -1246,7 +1246,7 @@ int longSize = providers.getCodeCache().getTarget().arch.getSizeInBytes(Kind.Long); int intSize = providers.getCodeCache().getTarget().arch.getSizeInBytes(Kind.Int); long offset = config.hsailFrameHeaderSize + (intSize * numSRegs) + (longSize * numDRegs) + HSAIL.getStackOffsetStart(slot, slotSizeInBits); - LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, valueKind, offset, hostGraph); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, offset, hostGraph); ValueNode valueNode = hostGraph.unique(FloatingReadNode.create(hsailFrame, location, null, StampFactory.forKind(valueKind))); return valueNode; } else { diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotLoweringProvider.java Fri Dec 12 20:29:35 2014 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.hotspot.ptx; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -51,7 +52,7 @@ } } - public ValueNode reconstructArrayIndex(LocationNode location) { + public ValueNode reconstructArrayIndex(Kind elementKind, LocationNode location) { throw GraalInternalError.unimplemented(); } } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java --- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java Fri Dec 12 20:29:35 2014 +0100 @@ -210,7 +210,7 @@ int index = 0; for (int slot : objectSlots) { int offset = slot * wordSize; - LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, index * intSize, getGraph()); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, index * intSize, getGraph()); append(WriteNode.create(objectParametersOffsets, ConstantNode.forInt(offset, getGraph()), location, BarrierType.NONE, false)); index++; } @@ -233,12 +233,12 @@ for (javaParametersIndex = 0; javaParametersIndex < javaParameters.length; javaParametersIndex++) { ParameterNode javaParameter = javaParameters[javaParametersIndex]; int javaParameterOffset = javaParameterOffsetsInKernelParametersBuffer[javaParametersIndex]; - LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, javaParameter.getKind(), javaParameterOffset, getGraph()); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, javaParameterOffset, getGraph()); append(WriteNode.create(buf, javaParameter, location, BarrierType.NONE, false)); updateDimArg(method, sig, sigIndex++, args, javaParameter); } if (returnKind != Kind.Void) { - LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, bufSize - wordSize, getGraph()); + LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, bufSize - wordSize, getGraph()); append(WriteNode.create(buf, nullWord, location, BarrierType.NONE, false)); } diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Fri Dec 12 20:29:35 2014 +0100 @@ -31,6 +31,7 @@ import java.lang.reflect.*; import java.util.*; +import java.util.function.*; import sun.misc.*; @@ -41,7 +42,6 @@ import com.oracle.graal.api.replacements.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.*; -import com.oracle.graal.compiler.common.remote.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; @@ -80,13 +80,17 @@ } } + private static Predicate runtimeAccessCheck; + /** - * Checks that all accesses to a {@link HotSpotGraalRuntimeProvider} within a replay context are - * through references to a captured {@link HotSpotGraalRuntimeProvider}, not through the static - * {@link HotSpotGraalRuntimeProvider} instance of the runtime hosting the replay. + * Sets a predicate which will be used to assert a valid calling context for a call to + * {@link #runtime()}. This is useful for verifying execution scopes that should not make a + * static access to {@link HotSpotGraalRuntime}. Such scopes are responsible for resetting the + * predicate to null. */ - public static boolean checkRuntimeAccess() { - return Context.assertInLocal("Cannot access HotSpotGraalRuntime statically in replay/remote context"); + public static void setRuntimeAccessCheck(Predicate predicate) { + assert runtimeAccessCheck == null || predicate == null : "at most once runtime access check can be active"; + runtimeAccessCheck = predicate; } /** @@ -94,7 +98,7 @@ */ public static HotSpotGraalRuntime runtime() { assert instance != null; - assert checkRuntimeAccess(); + assert runtimeAccessCheck == null || runtimeAccessCheck.test(null); return instance; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Fri Dec 12 20:29:35 2014 +0100 @@ -127,6 +127,14 @@ throw GraalInternalError.unimplemented(); } + default Value emitCardTableShift() { + throw GraalInternalError.unimplemented(); + } + + default Value emitCardTableAddress() { + throw GraalInternalError.unimplemented(); + } + /** * Gets a stack slot for a lock at a given lock nesting depth. */ diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Fri Dec 12 20:29:35 2014 +0100 @@ -34,7 +34,7 @@ private static final long serialVersionUID = -1052183095979496819L; - private static final int BITS_PER_WORD = 3; + public static final int BITS_PER_WORD = 3; /** * Contains 3 bits per scalar register, and n*3 bits per n-word vector register (e.g., on a @@ -167,6 +167,14 @@ } } + public BitSet getFrameMap() { + return (BitSet) frameRefMap.clone(); + } + + public BitSet getRegisterMap() { + return (BitSet) registerRefMap.clone(); + } + // clear private static void clearOop(BitSet map, int startIdx, LIRKind kind) { diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri Dec 12 20:29:35 2014 +0100 @@ -74,7 +74,29 @@ oopEncoding = new CompressEncoding(narrowOopBase, narrowOopShift, logMinObjAlignment()); klassEncoding = new CompressEncoding(narrowKlassBase, narrowKlassShift, logKlassAlignment); + codeCacheLowBoundary = unsafe.getAddress(codeCacheHeap + codeHeapMemoryOffset + virtualSpaceLowBoundaryOffset); + codeCacheHighBoundary = unsafe.getAddress(codeCacheHeap + codeHeapMemoryOffset + virtualSpaceHighBoundaryOffset); + + final long barrierSetAddress = unsafe.getAddress(universeCollectedHeap + collectedHeapBarrierSetOffset); + final int kind = unsafe.getInt(barrierSetAddress + barrierSetKindOffset); + if ((kind == barrierSetCardTableModRef) || (kind == barrierSetCardTableExtension) || (kind == barrierSetG1SATBCT) || (kind == barrierSetG1SATBCTLogging)) { + final long base = unsafe.getAddress(barrierSetAddress + cardTableModRefBSByteMapBaseOffset); + assert base != 0 : "unexpected byte_map_base: " + base; + cardtableStartAddress = base; + cardtableShift = cardTableModRefBSCardShift; + } else if ((kind == barrierSetModRef) || (kind == barrierSetOther)) { + // No post barriers + cardtableStartAddress = 0; + cardtableShift = 0; + } else { + cardtableStartAddress = -1; + cardtableShift = -1; + } + + inlineCacheMissStub = inlineCacheMissBlob + unsafe.getInt(inlineCacheMissBlob + codeBlobCodeOffsetOffset); + assert check(); + assert HotSpotVMConfigVerifier.check(); } /** @@ -1205,32 +1227,21 @@ @HotSpotVMValue(expression = "(jbyte)CardTableModRefBS::dirty_card_val()") @Stable public byte dirtyCardValue; @HotSpotVMValue(expression = "(jbyte)G1SATBCardTableModRefBS::g1_young_card_val()") @Stable public byte g1YoungCardValue; + private final long cardtableStartAddress; + private final int cardtableShift; + public long cardtableStartAddress() { - final long barrierSetAddress = unsafe.getAddress(universeCollectedHeap + collectedHeapBarrierSetOffset); - final int kind = unsafe.getInt(barrierSetAddress + barrierSetKindOffset); - if ((kind == barrierSetCardTableModRef) || (kind == barrierSetCardTableExtension) || (kind == barrierSetG1SATBCT) || (kind == barrierSetG1SATBCTLogging)) { - final long base = unsafe.getAddress(barrierSetAddress + cardTableModRefBSByteMapBaseOffset); - assert base != 0 : "unexpected byte_map_base: " + base; - return base; + if (cardtableStartAddress == -1) { + throw GraalInternalError.shouldNotReachHere(); } - if ((kind == barrierSetModRef) || (kind == barrierSetOther)) { - // No post barriers - return 0; - } - throw GraalInternalError.shouldNotReachHere("kind: " + kind); + return cardtableStartAddress; } public int cardtableShift() { - final long barrierSetAddress = unsafe.getAddress(universeCollectedHeap + collectedHeapBarrierSetOffset); - final int kind = unsafe.getInt(barrierSetAddress + barrierSetKindOffset); - if ((kind == barrierSetCardTableModRef) || (kind == barrierSetCardTableExtension) || (kind == barrierSetG1SATBCT) || (kind == barrierSetG1SATBCTLogging)) { - return cardTableModRefBSCardShift; + if (cardtableShift == -1) { + throw GraalInternalError.shouldNotReachHere(); } - if ((kind == barrierSetModRef) || (kind == barrierSetOther)) { - // No post barriers - return 0; - } - throw GraalInternalError.shouldNotReachHere("kind: " + kind); + return cardtableShift; } @HotSpotVMField(name = "os::_polling_page", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long safepointPollingAddress; @@ -1367,8 +1378,10 @@ @HotSpotVMField(name = "CodeBlob::_code_offset", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable private int codeBlobCodeOffsetOffset; @HotSpotVMField(name = "SharedRuntime::_ic_miss_blob", type = "RuntimeStub*", get = HotSpotVMField.Type.VALUE) @Stable private long inlineCacheMissBlob; + private final long inlineCacheMissStub; + public long inlineCacheMissStub() { - return inlineCacheMissBlob + unsafe.getInt(inlineCacheMissBlob + codeBlobCodeOffsetOffset); + return inlineCacheMissStub; } @HotSpotVMField(name = "CodeCache::_heap", type = "CodeHeap*", get = HotSpotVMField.Type.VALUE) @Stable private long codeCacheHeap; @@ -1376,18 +1389,21 @@ @HotSpotVMField(name = "VirtualSpace::_low_boundary", type = "char*", get = HotSpotVMField.Type.OFFSET) @Stable private int virtualSpaceLowBoundaryOffset; @HotSpotVMField(name = "VirtualSpace::_high_boundary", type = "char*", get = HotSpotVMField.Type.OFFSET) @Stable private int virtualSpaceHighBoundaryOffset; + private final long codeCacheLowBoundary; + private final long codeCacheHighBoundary; + /** * @return CodeCache::_heap->_memory._low_boundary */ public long codeCacheLowBoundary() { - return unsafe.getAddress(codeCacheHeap + codeHeapMemoryOffset + virtualSpaceLowBoundaryOffset); + return codeCacheLowBoundary; } /** * @return CodeCache::_heap->_memory._high_boundary */ public long codeCacheHighBoundary() { - return unsafe.getAddress(codeCacheHeap + codeHeapMemoryOffset + virtualSpaceHighBoundaryOffset); + return codeCacheHighBoundary; } @HotSpotVMField(name = "StubRoutines::_aescrypt_encryptBlock", type = "address", get = HotSpotVMField.Type.VALUE) @Stable public long aescryptEncryptBlockStub; @@ -1538,6 +1554,8 @@ @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::CARD_TABLE_SHIFT") @Stable public int codeInstallerMarkIdCardTableShift; + @HotSpotVMConstant(name = "CodeInstaller::CARD_TABLE_ADDRESS") @Stable public int codeInstallerMarkIdCardTableAddress; @HotSpotVMConstant(name = "CodeInstaller::INVOKE_INVALID") @Stable public int codeInstallerMarkIdInvokeInvalid; public boolean check() { diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfigVerifier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfigVerifier.java Fri Dec 12 20:29:35 2014 +0100 @@ -0,0 +1,156 @@ +/* + * 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 static java.lang.String.*; + +import java.io.*; +import java.lang.reflect.*; +import java.util.*; + +import com.oracle.graal.compiler.common.*; + +import jdk.internal.org.objectweb.asm.*; +import jdk.internal.org.objectweb.asm.Type; +import sun.misc.*; + +/** + * A {@link ClassVisitor} that verifies {@link HotSpotVMConfig} does not access {@link Unsafe} from + * any of its non-static, non-constructor methods. This ensures that a deserialized + * {@link HotSpotVMConfig} object does not perform any unsafe reads on addresses that are only valid + * in the context in which the object was serialized. Note that this does not catch cases where a + * client uses an address stored in a {@link HotSpotVMConfig} field. + */ +final class HotSpotVMConfigVerifier extends ClassVisitor { + + public static boolean check() { + Class cls = HotSpotVMConfig.class; + String classFilePath = "/" + cls.getName().replace('.', '/') + ".class"; + try { + InputStream classfile = cls.getResourceAsStream(classFilePath); + ClassReader cr = new ClassReader(Objects.requireNonNull(classfile, "Could not find class file for " + cls.getName())); + ClassVisitor cv = new HotSpotVMConfigVerifier(); + cr.accept(cv, 0); + return true; + } catch (IOException e) { + throw new GraalInternalError(e); + } + } + + /** + * Source file context for error reporting. + */ + String sourceFile = null; + + /** + * Line number for error reporting. + */ + int lineNo = -1; + + private static Class resolve(String name) { + try { + return Class.forName(name.replace('/', '.')); + } catch (ClassNotFoundException e) { + throw new InternalError(e); + } + } + + HotSpotVMConfigVerifier() { + super(Opcodes.ASM5); + } + + @Override + public void visitSource(String source, String debug) { + this.sourceFile = source; + } + + void verify(boolean condition, String message) { + if (!condition) { + error(message); + } + } + + void error(String message) { + String errorMessage = format("%s:%d: %s is not allowed in the context of compilation replay. The unsafe access should be moved into the %s constructor and the result cached in a field", + sourceFile, lineNo, message, HotSpotVMConfig.class.getSimpleName()); + throw new InternalError(errorMessage); + + } + + @Override + public MethodVisitor visitMethod(int access, String name, String d, String signature, String[] exceptions) { + if (!Modifier.isStatic(access) && Modifier.isPublic(access) && !name.equals("")) { + return new MethodVisitor(Opcodes.ASM5) { + + @Override + public void visitLineNumber(int line, Label start) { + lineNo = line; + } + + private Executable resolveMethod(String owner, String methodName, String methodDesc) { + Class declaringClass = resolve(owner); + while (declaringClass != null) { + if (methodName.equals("")) { + for (Constructor c : declaringClass.getDeclaredConstructors()) { + if (methodDesc.equals(Type.getConstructorDescriptor(c))) { + return c; + } + } + } else { + Type[] argumentTypes = Type.getArgumentTypes(methodDesc); + for (Method m : declaringClass.getDeclaredMethods()) { + if (m.getName().equals(methodName)) { + if (Arrays.equals(argumentTypes, Type.getArgumentTypes(m))) { + if (Type.getReturnType(methodDesc).equals(Type.getReturnType(m))) { + return m; + } + } + } + } + } + declaringClass = declaringClass.getSuperclass(); + } + throw new NoSuchMethodError(owner + "." + methodName + methodDesc); + } + + /** + * Checks whether a given method is allowed to be called. + */ + private boolean checkInvokeTarget(Executable method) { + if (method.getDeclaringClass().equals(Unsafe.class)) { + return false; + } + return true; + } + + @Override + public void visitMethodInsn(int opcode, String owner, String methodName, String methodDesc, boolean itf) { + Executable callee = resolveMethod(owner, methodName, methodDesc); + verify(checkInvokeTarget(callee), "invocation of " + callee); + } + }; + } else { + return null; + } + } +} diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Fri Dec 12 20:29:35 2014 +0100 @@ -383,9 +383,9 @@ if (index >= 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, wordKind, config.graalCountersThreadOffset, graph); + ConstantLocationNode arrayLocation = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, config.graalCountersThreadOffset, graph); ReadNode readArray = graph.add(ReadNode.create(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE)); - ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph); + ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph); ReadNode read = graph.add(ReadNode.create(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE)); AddNode add = graph.unique(AddNode.create(read, counter.getIncrement())); WriteNode write = graph.add(WriteNode.create(readArray, add, location, BarrierType.NONE)); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Fri Dec 12 20:29:35 2014 +0100 @@ -198,11 +198,11 @@ Kind wordKind = runtime.getTarget().wordKind; ValueNode hub = createReadHub(graph, receiver, receiverNullCheck); - ReadNode metaspaceMethod = createReadVirtualMethod(graph, wordKind, hub, hsMethod, receiverType); + ReadNode metaspaceMethod = createReadVirtualMethod(graph, hub, hsMethod, receiverType); // We use LocationNode.ANY_LOCATION for the reads that access the // compiled code entry as HotSpot does not guarantee they are final // values. - ReadNode compiledEntry = graph.add(ReadNode.create(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, runtime.getConfig().methodCompiledEntryOffset, graph), + ReadNode compiledEntry = graph.add(ReadNode.create(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, runtime.getConfig().methodCompiledEntryOffset, graph), StampFactory.forKind(wordKind), BarrierType.NONE)); loweredCallTarget = graph.add(HotSpotIndirectCallTargetNode.create(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), @@ -254,8 +254,7 @@ @Override protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) { - Kind wordKind = runtime.getTarget().wordKind; - LocationNode location = ConstantLocationNode.create(OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, wordKind, runtime.getConfig().arrayClassElementOffset, graph); + LocationNode location = ConstantLocationNode.create(OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, runtime.getConfig().arrayClassElementOffset, graph); /* * Anchor the read of the element klass to the cfg, because it is only valid when arrayClass * is an object class, which might not be the case in other parts of the compiled method. @@ -273,15 +272,15 @@ } } - private void lowerLoadMethodNode(LoadMethodNode loadMethodNode) { + private static void lowerLoadMethodNode(LoadMethodNode loadMethodNode) { StructuredGraph graph = loadMethodNode.graph(); HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) loadMethodNode.getMethod(); - ReadNode metaspaceMethod = createReadVirtualMethod(graph, runtime.getTarget().wordKind, loadMethodNode.getHub(), method, loadMethodNode.getReceiverType()); + ReadNode metaspaceMethod = createReadVirtualMethod(graph, loadMethodNode.getHub(), method, loadMethodNode.getReceiverType()); graph.replaceFixed(loadMethodNode, metaspaceMethod); } private void lowerStoreHubNode(StoreHubNode storeHub, StructuredGraph graph) { - WriteNode hub = createWriteHub(graph, runtime.getTarget().wordKind, storeHub.getObject(), storeHub.getValue()); + WriteNode hub = createWriteHub(graph, storeHub.getObject(), storeHub.getValue()); graph.replaceFixed(storeHub, hub); } @@ -314,7 +313,7 @@ for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.class)) { int size = HIRFrameStateBuilder.stackSlots(osrLocal.getKind()); int offset = localsOffset - (osrLocal.index() + size - 1) * 8; - IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.getKind(), offset, ConstantNode.forLong(0, graph), graph, 1); + IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, offset, ConstantNode.forLong(0, graph), graph, 1); ReadNode load = graph.add(ReadNode.create(buffer, location, osrLocal.stamp(), BarrierType.NONE)); osrLocal.replaceAndDelete(load); graph.addBeforeFixed(migrationEnd, load); @@ -390,24 +389,23 @@ return false; } - private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, HotSpotResolvedJavaMethod method, ResolvedJavaType receiverType) { - return createReadVirtualMethod(graph, wordKind, hub, method.vtableEntryOffset(receiverType)); + private static ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, HotSpotResolvedJavaMethod method, ResolvedJavaType receiverType) { + return createReadVirtualMethod(graph, hub, method.vtableEntryOffset(receiverType)); } - private static ReadNode createReadVirtualMethod(StructuredGraph graph, Kind wordKind, ValueNode hub, int vtableEntryOffset) { + private static ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, int vtableEntryOffset) { assert vtableEntryOffset > 0; // We use LocationNode.ANY_LOCATION for the reads that access the vtable // entry as HotSpot does not guarantee that this is a final value. Stamp methodStamp = MethodPointerStamp.method(); - ReadNode metaspaceMethod = graph.add(ReadNode.create(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), methodStamp, BarrierType.NONE)); + ReadNode metaspaceMethod = graph.add(ReadNode.create(hub, ConstantLocationNode.create(ANY_LOCATION, vtableEntryOffset, graph), methodStamp, BarrierType.NONE)); return metaspaceMethod; } @Override protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, GuardingNode guard) { - Kind wordKind = target.wordKind; HotSpotVMConfig config = runtime.getConfig(); - LocationNode location = ConstantLocationNode.create(HUB_LOCATION, wordKind, config.hubOffset, graph); + LocationNode location = ConstantLocationNode.create(HUB_LOCATION, config.hubOffset, graph); assert !object.isConstant() || object.isNullConstant(); KlassPointerStamp hubStamp = KlassPointerStamp.klassNonNull(); @@ -423,9 +421,9 @@ } } - private WriteNode createWriteHub(StructuredGraph graph, Kind wordKind, ValueNode object, ValueNode value) { + private WriteNode createWriteHub(StructuredGraph graph, ValueNode object, ValueNode value) { HotSpotVMConfig config = runtime.getConfig(); - LocationNode location = ConstantLocationNode.create(HUB_WRITE_LOCATION, wordKind, config.hubOffset, graph); + LocationNode location = ConstantLocationNode.create(HUB_WRITE_LOCATION, config.hubOffset, graph); assert !object.isConstant() || object.isNullConstant(); ValueNode writeValue = value; diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Fri Dec 12 20:29:35 2014 +0100 @@ -80,7 +80,9 @@ POLL_NEAR(config().codeInstallerMarkIdPollNear), POLL_RETURN_NEAR(config().codeInstallerMarkIdPollReturnNear), POLL_FAR(config().codeInstallerMarkIdPollFar), - POLL_RETURN_FAR(config().codeInstallerMarkIdPollReturnFar); + POLL_RETURN_FAR(config().codeInstallerMarkIdPollReturnFar), + CARD_TABLE_SHIFT(config().codeInstallerMarkIdCardTableShift), + CARD_TABLE_ADDRESS(config().codeInstallerMarkIdCardTableAddress); private final int value; diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java Fri Dec 12 20:29:35 2014 +0100 @@ -25,7 +25,6 @@ import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.remote.*; import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding; public final class HotSpotMetaspaceConstantImpl extends PrimitiveConstant implements HotSpotMetaspaceConstant, VMConstant, Remote { @@ -47,7 +46,6 @@ super(kind, primitive); this.metaspaceObject = metaspaceObject; this.compressed = compressed; - assert Context.assertInLocal("Should not create metaspace constants here"); } @Override diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstantImpl.java Fri Dec 12 20:29:35 2014 +0100 @@ -28,7 +28,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.remote.*; import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; @@ -96,7 +95,6 @@ assert stableDimension == 0 || (object != null && object.getClass().isArray()); assert stableDimension >= 0 && stableDimension <= 255; assert !isDefaultStable || stableDimension > 0; - assert Context.assertInLocal("Should not create object constants here"); } private HotSpotObjectConstantImpl(Object object, boolean compressed) { diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nfi/NativeCallStubGraphBuilder.java Fri Dec 12 20:29:35 2014 +0100 @@ -120,7 +120,7 @@ int displacement = runtime().getArrayBaseOffset(arrayElementKind); ConstantNode index = ConstantNode.forInt(0, g); int indexScaling = runtime().getArrayIndexScale(arrayElementKind); - IndexedLocationNode locationNode = IndexedLocationNode.create(locationIdentity, arrayElementKind, displacement, index, g, indexScaling); + IndexedLocationNode locationNode = IndexedLocationNode.create(locationIdentity, displacement, index, g, indexScaling); Stamp wordStamp = StampFactory.forKind(providers.getCodeCache().getTarget().wordKind); ComputeAddressNode arrayAddress = g.unique(ComputeAddressNode.create(boxedElement, locationNode, wordStamp)); args.add(arrayAddress); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Fri Dec 12 20:29:35 2014 +0100 @@ -70,7 +70,7 @@ Constant klass; LocationNode location; if (type instanceof HotSpotResolvedObjectType) { - location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, Kind.Object, classMirrorOffset, graph); + location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, classMirrorOffset, graph); klass = ((HotSpotResolvedObjectType) type).klass(); } else { /* @@ -91,7 +91,7 @@ if (typeField == null) { throw new GraalInternalError("Can't find TYPE field in class"); } - location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Object, typeField.offset(), graph); + location = ConstantLocationNode.create(FINAL_LOCATION, typeField.offset(), graph); } ConstantNode klassNode = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), klass, metaAccess, graph); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableAddressNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableAddressNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -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.replacements; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +@NodeInfo +public class CardTableAddressNode extends FloatingNode implements LIRLowerable { + + public static CardTableAddressNode create() { + return new CardTableAddressNode(); + } + + protected CardTableAddressNode() { + super(StampFactory.forKind(Kind.Long)); + } + + @Override + public void generate(NodeLIRBuilderTool generator) { + Value res = ((HotSpotLIRGenerator) generator.getLIRGeneratorTool()).emitCardTableAddress(); + generator.setResult(this, res); + } + + @NodeIntrinsic + public static native long cardTableAddress(); +} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableShiftNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CardTableShiftNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -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.replacements; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; + +@NodeInfo +public class CardTableShiftNode extends FloatingNode implements LIRLowerable { + + public static CardTableShiftNode create() { + return new CardTableShiftNode(); + } + + protected CardTableShiftNode() { + super(StampFactory.intValue()); + } + + @Override + public void generate(NodeLIRBuilderTool generator) { + Value res = ((HotSpotLIRGenerator) generator.getLIRGeneratorTool()).emitCardTableShift(); + generator.setResult(this, res); + } + + @NodeIntrinsic + public static native int cardTableShift(); +} diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -98,7 +98,7 @@ return; } - LocationNode location = ConstantLocationNode.create(CLASS_KLASS_LOCATION, runtime.getTarget().wordKind, runtime.getConfig().klassOffset, graph()); + LocationNode location = ConstantLocationNode.create(CLASS_KLASS_LOCATION, runtime.getConfig().klassOffset, graph()); assert !clazz.isConstant(); FloatingReadNode read = graph().unique(FloatingReadNode.create(clazz, location, null, stamp(), getGuard(), BarrierType.NONE)); graph().replaceFloating(this, read); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri Dec 12 20:29:35 2014 +0100 @@ -810,6 +810,16 @@ public static native int identityHashCode(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); @Fold + public static boolean isImmutableCode() { + return GraalOptions.ImmutableCode.getValue(); + } + + @Fold + public static boolean generatePIC() { + return GraalOptions.GeneratePIC.getValue(); + } + + @Fold public static int verifiedEntryPointOffset() { return config().nmethodEntryOffset; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -81,7 +81,7 @@ return; } - LocationNode location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, Kind.Object, config.classMirrorOffset, graph()); + LocationNode location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, config.classMirrorOffset, graph()); assert !hub.isConstant(); FloatingReadNode read = graph().unique(FloatingReadNode.create(hub, location, null, stamp(), getGuard(), BarrierType.NONE)); graph().replaceFloating(this, read); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -117,7 +117,7 @@ if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) { return; } - LocationNode location = ConstantLocationNode.create(KLASS_LAYOUT_HELPER_LOCATION, Kind.Int, config.klassLayoutHelperOffset, graph()); + LocationNode location = ConstantLocationNode.create(KLASS_LAYOUT_HELPER_LOCATION, config.klassLayoutHelperOffset, graph()); assert !klass.isConstant(); graph().replaceFloating(this, graph().unique(FloatingReadNode.create(klass, location, null, stamp(), getGuard(), BarrierType.NONE))); } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Fri Dec 12 20:29:35 2014 +0100 @@ -77,13 +77,15 @@ oop = Word.fromObject(fixedObject); } serialWriteBarrierCounter.inc(); - Word base = (Word) oop.unsignedShiftRight(cardTableShift()); - long startAddress = cardTableStart(); + int cardTableShift = (isImmutableCode() && generatePIC()) ? CardTableShiftNode.cardTableShift() : cardTableShift(); + long cardTableAddress = (isImmutableCode() && generatePIC()) ? CardTableAddressNode.cardTableAddress() : cardTableStart(); + Word base = (Word) oop.unsignedShiftRight(cardTableShift); + long startAddress = cardTableAddress; int displacement = 0; if (((int) startAddress) == startAddress) { displacement = (int) startAddress; } else { - base = base.add(Word.unsigned(cardTableStart())); + base = base.add(Word.unsigned(cardTableAddress)); } base.writeByte(displacement, (byte) 0, GC_CARD_LOCATION); } @@ -481,7 +483,7 @@ public static void validateObject(Object parent, Object child) { if (verifyOops() && child != null && !validateOop(VALIDATE_OBJECT, parent, child)) { log(true, "Verification ERROR, Parent: %p Child: %p\n", Word.fromObject(parent).rawValue(), Word.fromObject(child).rawValue()); - DirectObjectStoreNode.storeObject(null, 0, 0, null, LocationIdentity.ANY_LOCATION); + DirectObjectStoreNode.storeObject(null, 0, 0, null, LocationIdentity.ANY_LOCATION, Kind.Object); } } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -111,7 +111,7 @@ private ValueNode computeBase(ValueNode base, ValueNode pos) { FixedWithNextNode basePtr = graph().add(GetObjectAddressNode.create(base)); graph().addBeforeFixed(this, basePtr); - ValueNode loc = IndexedLocationNode.create(getLocationIdentity(), elementKind, runtime.getArrayBaseOffset(elementKind), pos, graph(), runtime.getArrayIndexScale(elementKind)); + ValueNode loc = IndexedLocationNode.create(getLocationIdentity(), runtime.getArrayBaseOffset(elementKind), pos, graph(), runtime.getArrayIndexScale(elementKind)); return graph().unique(ComputeAddressNode.create(basePtr, loc, StampFactory.forKind(Kind.Long))); } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -98,7 +98,7 @@ private ValueNode computeBase(ValueNode base, ValueNode pos) { FixedWithNextNode basePtr = graph().add(GetObjectAddressNode.create(base)); graph().addBeforeFixed(this, basePtr); - ValueNode loc = IndexedLocationNode.create(getLocationIdentity(), Kind.Object, runtime.getArrayBaseOffset(Kind.Object), pos, graph(), runtime.getArrayIndexScale(Kind.Object)); + ValueNode loc = IndexedLocationNode.create(getLocationIdentity(), runtime.getArrayBaseOffset(Kind.Object), pos, graph(), runtime.getArrayIndexScale(Kind.Object)); return graph().unique(ComputeAddressNode.create(basePtr, loc, StampFactory.forKind(Kind.Long))); } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/UnsafeArrayCopySnippets.java Fri Dec 12 20:29:35 2014 +0100 @@ -207,13 +207,13 @@ long start = (long) (length - 1) * scale; for (long i = start; i >= 0; i -= scale) { Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation); - DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a, getArrayLocation(kind)); + DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a, getArrayLocation(kind), kind); } } else { long end = (long) length * scale; for (long i = 0; i < end; i += scale) { Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, kind, arrayLocation); - DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a, getArrayLocation(kind)); + DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a, getArrayLocation(kind), kind); } } } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java Fri Dec 12 20:29:35 2014 +0100 @@ -135,7 +135,7 @@ * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for * total size of the interpreter frames plus shadow page size. Bang one page at a time * because large sizes can bang beyond yellow and red zones. - * + * * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository. */ final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset()); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java Fri Dec 12 20:29:35 2014 +0100 @@ -147,7 +147,7 @@ * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for * total size of the interpreter frames plus shadow page size. Bang one page at a time * because large sizes can bang beyond yellow and red zones. - * + * * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository. */ final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset()); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypeRewriterPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypeRewriterPhase.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/HotSpotWordTypeRewriterPhase.java Fri Dec 12 20:29:35 2014 +0100 @@ -130,13 +130,12 @@ case READ_KLASS_POINTER: assert arguments.size() == 2 || arguments.size() == 3; - Kind readKind = asKind(callTargetNode.returnType()); Stamp readStamp = KlassPointerStamp.klass(); LocationNode location; if (arguments.size() == 2) { - location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); + location = makeLocation(graph, arguments.get(1), ANY_LOCATION); } else { - location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); + location = makeLocation(graph, arguments.get(1), arguments.get(2)); } replace(invoke, readKlassOp(graph, arguments.get(0), invoke, location, readStamp, operation.opcode())); break; @@ -150,9 +149,8 @@ protected ValueNode readKlassOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Stamp readStamp, HotspotOpcode op) { assert op == READ_KLASS_POINTER; final BarrierType barrier = BarrierType.NONE; - final boolean compressible = false; - JavaReadNode read = graph.add(JavaReadNode.create(base, location, readStamp, barrier, compressible)); + ReadNode read = graph.add(ReadNode.create(base, location, readStamp, barrier)); graph.addBeforeFixed(invoke.asNode(), read); /* * The read must not float outside its block otherwise it may float above an explicit zero diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/loop/LoopParseLong.java Fri Dec 12 20:29:35 2014 +0100 @@ -102,8 +102,20 @@ @Test public void run0() throws Throwable { runTest("testShortened", "7", 10); + } + + @Test + public void run1() throws Throwable { runTest("testShortened", "-100", 10); + } + + @Test + public void run2() throws Throwable { runTest("test", "7", 10); + } + + @Test + public void run3() throws Throwable { runTest("test", "-100", 10); } } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java --- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCBreakpointOp.java Fri Dec 12 20:29:35 2014 +0100 @@ -25,8 +25,8 @@ import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.asm.sparc.SPARCAssembler.Ta; import com.oracle.graal.asm.sparc.*; -import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Trap; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; @@ -51,8 +51,7 @@ } @Override - @SuppressWarnings("unused") public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) { - new Trap(masm, ST_RESERVED_FOR_USER_0); + new Ta(ST_RESERVED_FOR_USER_0).emit(masm); } } diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java Fri Dec 12 20:29:35 2014 +0100 @@ -332,7 +332,7 @@ * VirtualState nodes contained in the old exit's state may be shared by other * dominated VirtualStates. Those dominated virtual states need to see the * proxy->phi update that are applied below. - * + * * We now update the original fragment's nodes accordingly: */ originalExitState.applyToVirtual(node -> original.nodes.clearAndGrow(node)); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java Fri Dec 12 20:29:35 2014 +0100 @@ -24,8 +24,8 @@ import java.util.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.cfg.*; -import com.oracle.graal.compiler.common.remote.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.graph.*; @@ -34,7 +34,7 @@ public class LoopsData { - private Map, LoopEx> loopToEx = Context.newIdentityMap(); + private Map, LoopEx> loopToEx = CollectionsFactory.newIdentityMap(); private Map loopBeginToEx = Node.newIdentityMap(); private ControlFlowGraph cfg; diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AbsNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AddNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/BinaryArithmeticNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -22,12 +22,13 @@ */ package com.oracle.graal.nodes.calc; +import java.io.*; import java.util.function.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.BinaryOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.graph.spi.*; @@ -38,9 +39,12 @@ @NodeInfo public abstract class BinaryArithmeticNode extends BinaryNode implements ArithmeticLIRLowerable { - protected final Function> getOp; + protected interface SerializableBinaryFunction extends Function>, Serializable { + } - public BinaryArithmeticNode(Function> getOp, ValueNode x, ValueNode y) { + protected final SerializableBinaryFunction getOp; + + public BinaryArithmeticNode(SerializableBinaryFunction getOp, ValueNode x, ValueNode y) { super(getOp.apply(ArithmeticOpTable.forStamp(x.stamp())).foldStamp(x.stamp(), y.stamp()), x, y); this.getOp = getOp; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/DivNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatConvertNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerConvertNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -22,11 +22,12 @@ */ package com.oracle.graal.nodes.calc; +import java.io.*; import java.util.function.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.compiler.common.type.ArithmeticOpTable.IntegerConvertOp; +import com.oracle.graal.compiler.common.type.ArithmeticOpTable.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; @@ -38,14 +39,16 @@ @NodeInfo public abstract class IntegerConvertNode extends UnaryNode implements ConvertNode, ArithmeticLIRLowerable { - protected final Function> getOp; - protected final Function> getReverseOp; + protected final SerializableIntegerConvertFunction getOp; + protected final SerializableIntegerConvertFunction getReverseOp; protected final int inputBits; protected final int resultBits; - protected IntegerConvertNode(Function> getOp, Function> getReverseOp, int inputBits, int resultBits, - ValueNode input) { + protected interface SerializableIntegerConvertFunction extends Function>, Serializable { + } + + protected IntegerConvertNode(SerializableIntegerConvertFunction getOp, SerializableIntegerConvertFunction getReverseOp, int inputBits, int resultBits, ValueNode input) { super(getOp.apply(ArithmeticOpTable.forStamp(input.stamp())).foldStamp(inputBits, resultBits, input.stamp()), input); this.getOp = getOp; this.getReverseOp = getReverseOp; diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/MulNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NarrowNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -84,7 +84,7 @@ /* * One of the two objects has identity, the other doesn't. In code, this looks like * "Integer.valueOf(a) == new Integer(b)", which is always false. - * + * * In other words: an object created via valueOf can never be equal to one created * by new in the same compilation unit. */ diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RemNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SignExtendNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SqrtNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/SubNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnaryArithmeticNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.calc; +import java.io.*; import java.util.function.*; import com.oracle.graal.compiler.common.type.*; @@ -34,9 +35,12 @@ @NodeInfo public abstract class UnaryArithmeticNode extends UnaryNode implements ArithmeticLIRLowerable { - protected final Function> getOp; + protected interface SerializableUnaryFunction extends Function>, Serializable { + } - protected UnaryArithmeticNode(Function> getOp, ValueNode value) { + protected final SerializableUnaryFunction getOp; + + protected UnaryArithmeticNode(SerializableUnaryFunction getOp, ValueNode value) { super(getOp.apply(ArithmeticOpTable.forStamp(value.stamp())).foldStamp(value.stamp()), value); this.getOp = getOp; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ZeroExtendNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -51,7 +51,7 @@ } public static AddLocationNode create(LocationNode x, LocationNode y, Graph graph) { - assert x.getValueKind().equals(y.getValueKind()) && x.getLocationIdentity().equals(y.getLocationIdentity()); + assert x.getLocationIdentity().equals(y.getLocationIdentity()); return graph.unique(AddLocationNode.create(x, y)); } @@ -66,11 +66,6 @@ } @Override - public Kind getValueKind() { - return getX().getValueKind(); - } - - @Override public LocationIdentity getLocationIdentity() { return getX().getLocationIdentity(); } @@ -88,7 +83,7 @@ if (xIdx.getIndexScaling() == yIdx.getIndexScaling()) { long displacement = xIdx.getDisplacement() + yIdx.getDisplacement(); ValueNode index = BinaryArithmeticNode.add(xIdx.getIndex(), yIdx.getIndex()); - return IndexedLocationNode.create(getLocationIdentity(), getValueKind(), displacement, index, xIdx.getIndexScaling()); + return IndexedLocationNode.create(getLocationIdentity(), displacement, index, xIdx.getIndexScaling()); } } return this; @@ -97,10 +92,10 @@ private LocationNode canonical(ConstantLocationNode constant, LocationNode other) { if (other instanceof ConstantLocationNode) { ConstantLocationNode otherConst = (ConstantLocationNode) other; - return ConstantLocationNode.create(getLocationIdentity(), getValueKind(), otherConst.getDisplacement() + constant.getDisplacement()); + return ConstantLocationNode.create(getLocationIdentity(), otherConst.getDisplacement() + constant.getDisplacement()); } else if (other instanceof IndexedLocationNode) { IndexedLocationNode otherIdx = (IndexedLocationNode) other; - return IndexedLocationNode.create(getLocationIdentity(), getValueKind(), otherIdx.getDisplacement() + constant.getDisplacement(), otherIdx.getIndex(), otherIdx.getIndexScaling()); + return IndexedLocationNode.create(getLocationIdentity(), otherIdx.getDisplacement() + constant.getDisplacement(), otherIdx.getIndex(), otherIdx.getIndexScaling()); } else if (other instanceof AddLocationNode) { AddLocationNode otherAdd = (AddLocationNode) other; LocationNode newInner = otherAdd.canonical(constant, otherAdd.getX()); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -36,32 +36,24 @@ @NodeInfo(nameTemplate = "Loc {p#locationIdentity/s}") public class ConstantLocationNode extends LocationNode { - protected final Kind valueKind; protected final LocationIdentity locationIdentity; protected final long displacement; - public static ConstantLocationNode create(LocationIdentity identity, Kind kind, long displacement, Graph graph) { - return graph.unique(ConstantLocationNode.create(identity, kind, displacement)); - } - - public static ConstantLocationNode create(LocationIdentity identity, Kind kind, long displacement) { - return new ConstantLocationNode(identity, kind, displacement); + public static ConstantLocationNode create(LocationIdentity identity, long displacement, Graph graph) { + return graph.unique(ConstantLocationNode.create(identity, displacement)); } - protected ConstantLocationNode(LocationIdentity identity, Kind kind, long displacement) { + public static ConstantLocationNode create(LocationIdentity identity, long displacement) { + return new ConstantLocationNode(identity, displacement); + } + + protected ConstantLocationNode(LocationIdentity identity, long displacement) { super(StampFactory.forVoid()); - assert kind != Kind.Illegal && kind != Kind.Void; - this.valueKind = kind; this.locationIdentity = identity; this.displacement = displacement; } @Override - public Kind getValueKind() { - return valueKind; - } - - @Override public LocationIdentity getLocationIdentity() { return locationIdentity; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -41,7 +41,6 @@ @NodeInfo(nameTemplate = "IdxLoc {p#locationIdentity/s}") public class IndexedLocationNode extends LocationNode implements Canonicalizable { - protected final Kind valueKind; protected final LocationIdentity locationIdentity; protected final long displacement; @Input ValueNode index; @@ -65,20 +64,18 @@ return indexScaling; } - public static IndexedLocationNode create(LocationIdentity identity, Kind kind, long displacement, ValueNode index, Graph graph, int indexScaling) { - return graph.unique(IndexedLocationNode.create(identity, kind, displacement, index, indexScaling)); + public static IndexedLocationNode create(LocationIdentity identity, long displacement, ValueNode index, Graph graph, int indexScaling) { + return graph.unique(IndexedLocationNode.create(identity, displacement, index, indexScaling)); } - public static IndexedLocationNode create(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) { - return new IndexedLocationNode(identity, kind, displacement, index, indexScaling); + public static IndexedLocationNode create(LocationIdentity identity, long displacement, ValueNode index, int indexScaling) { + return new IndexedLocationNode(identity, displacement, index, indexScaling); } - protected IndexedLocationNode(LocationIdentity identity, Kind kind, long displacement, ValueNode index, int indexScaling) { + protected IndexedLocationNode(LocationIdentity identity, long displacement, ValueNode index, int indexScaling) { super(StampFactory.forVoid()); assert index != null; assert indexScaling != 0; - assert kind != Kind.Illegal && kind != Kind.Void; - this.valueKind = kind; this.locationIdentity = identity; this.index = index; this.displacement = displacement; @@ -86,11 +83,6 @@ } @Override - public Kind getValueKind() { - return valueKind; - } - - @Override public LocationIdentity getLocationIdentity() { return locationIdentity; } @@ -98,7 +90,7 @@ @Override public Node canonical(CanonicalizerTool tool) { if (index.isConstant()) { - return ConstantLocationNode.create(getLocationIdentity(), getValueKind(), index.asJavaConstant().asLong() * indexScaling + displacement); + return ConstantLocationNode.create(getLocationIdentity(), index.asJavaConstant().asLong() * indexScaling + displacement); } return this; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -36,23 +37,16 @@ @NodeInfo public class JavaReadNode extends FixedAccessNode implements Lowerable, GuardingNode, Canonicalizable { + protected final Kind readKind; protected final boolean compressible; - public static JavaReadNode create(ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { - return new JavaReadNode(object, location, barrierType, compressible); + public static JavaReadNode create(Kind readKind, ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { + return new JavaReadNode(readKind, object, location, barrierType, compressible); } - public static JavaReadNode create(ValueNode object, LocationNode location, Stamp readStamp, BarrierType barrierType, boolean compressible) { - return new JavaReadNode(object, location, readStamp, barrierType, compressible); - } - - protected JavaReadNode(ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { - super(object, location, StampFactory.forKind(location.getValueKind()), barrierType); - this.compressible = compressible; - } - - protected JavaReadNode(ValueNode object, LocationNode location, Stamp readStamp, BarrierType barrierType, boolean compressible) { - super(object, location, readStamp, barrierType); + protected JavaReadNode(Kind readKind, ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { + super(object, location, StampFactory.forKind(readKind), barrierType); + this.readKind = readKind; this.compressible = compressible; } @@ -64,6 +58,10 @@ return true; } + public Kind getReadKind() { + return readKind; + } + public boolean isCompressible() { return compressible; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.extended; +import com.oracle.graal.api.meta.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; @@ -33,14 +34,16 @@ @NodeInfo public class JavaWriteNode extends AbstractWriteNode implements Lowerable, StateSplit, MemoryAccess, MemoryCheckpoint.Single { + protected final Kind writeKind; protected final boolean compressible; - public static JavaWriteNode create(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { - return new JavaWriteNode(object, value, location, barrierType, compressible, initialization); + public static JavaWriteNode create(Kind writeKind, ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { + return new JavaWriteNode(writeKind, object, value, location, barrierType, compressible, initialization); } - protected JavaWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { + protected JavaWriteNode(Kind writeKind, ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { super(object, value, location, barrierType, initialization); + this.writeKind = writeKind; this.compressible = compressible; } @@ -52,6 +55,10 @@ return true; } + public Kind getWriteKind() { + return writeKind; + } + public boolean isCompressible() { return compressible; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -49,11 +49,6 @@ } /** - * Returns the kind of the accessed memory value. - */ - public abstract Kind getValueKind(); - - /** * Returns the identity of the accessed memory location. */ public abstract LocationIdentity getLocationIdentity(); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -23,6 +23,7 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -31,7 +32,6 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; -import com.oracle.graal.nodes.virtual.*; /** * Reads an {@linkplain FixedAccessNode accessed} value. @@ -171,17 +171,7 @@ @Override public void virtualize(VirtualizerTool tool) { - if (location() instanceof ConstantLocationNode) { - ConstantLocationNode constantLocation = (ConstantLocationNode) location(); - State state = tool.getObjectState(object()); - if (state != null && state.getState() == EscapeState.Virtual) { - VirtualObjectNode virtual = state.getVirtualObject(); - int entryIndex = virtual.entryIndexForOffset(constantLocation.getDisplacement()); - if (entryIndex != -1 && virtual.entryKind(entryIndex) == constantLocation.getValueKind()) { - tool.replaceWith(state.getEntry(entryIndex)); - } - } - } + throw GraalInternalError.shouldNotReachHere("unexpected ReadNode before PEA"); } public boolean canNullCheck() { diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -23,12 +23,12 @@ package com.oracle.graal.nodes.extended; import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.LocationNode.Location; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.virtual.*; /** * Writes a given {@linkplain #value() value} a {@linkplain FixedAccessNode memory location}. @@ -79,18 +79,7 @@ @Override public void virtualize(VirtualizerTool tool) { - if (location() instanceof ConstantLocationNode) { - ConstantLocationNode constantLocation = (ConstantLocationNode) location(); - State state = tool.getObjectState(object()); - if (state != null && state.getState() == EscapeState.Virtual) { - VirtualObjectNode virtual = state.getVirtualObject(); - int entryIndex = virtual.entryIndexForOffset(constantLocation.getDisplacement()); - if (entryIndex != -1 && virtual.entryKind(entryIndex) == constantLocation.getValueKind()) { - tool.setVirtualEntry(state, entryIndex, value(), false); - tool.delete(); - } - } - } + throw GraalInternalError.shouldNotReachHere("unexpected WriteNode before PEA"); } public boolean canNullCheck() { diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -73,7 +73,7 @@ } public void generate(NodeLIRBuilderTool gen) { - LocationNode location = IndexedLocationNode.create(getLocationIdentity(), delta.getKind(), 0, offset, graph(), 1); + LocationNode location = IndexedLocationNode.create(getLocationIdentity(), 0, offset, graph(), 1); Value address = location.generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object())); Value result = gen.getLIRGeneratorTool().emitAtomicReadAndAdd(address, gen.operand(delta)); gen.setResult(this, result); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java Fri Dec 12 20:29:35 2014 +0100 @@ -22,6 +22,7 @@ */ package com.oracle.graal.nodes.spi; +import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -36,9 +37,10 @@ /** * Reconstructs the array index from a location node that was created as a lowering of an * indexed access to an array. - * + * + * @param elementKind the {@link Kind} of the array elements * @param location a location pointing to an element in an array * @return a node that gives the index of the element */ - ValueNode reconstructArrayIndex(LocationNode location); + ValueNode reconstructArrayIndex(Kind elementKind, LocationNode location); } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Fri Dec 12 20:29:35 2014 +0100 @@ -24,10 +24,11 @@ import static com.oracle.graal.api.meta.LocationIdentity.*; import static com.oracle.graal.graph.Graph.NodeEvent.*; + import java.util.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.remote.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Graph.NodeEventScope; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -162,7 +163,7 @@ if (updateExistingPhis) { for (MemoryPhiNode phi : merge.phis().filter(MemoryPhiNode.class)) { if (existingPhis == null) { - existingPhis = Context.newMap(); + existingPhis = CollectionsFactory.newMap(); } phi.values().clear(); existingPhis.put(phi.getLocationIdentity(), phi); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/policy/AbstractInliningPolicy.java Fri Dec 12 20:29:35 2014 +0100 @@ -33,11 +33,11 @@ import java.util.Map; -import static com.oracle.graal.compiler.common.GraalOptions.RelevanceCapForInlining; import static com.oracle.graal.phases.common.inlining.InliningPhase.Options.AlwaysInlineIntrinsics; public abstract class AbstractInliningPolicy implements InliningPolicy { - + public static final float RelevanceCapForInlining = 1.0f; + public static final float CapInheritedRelevance = 1.0f; protected final Map hints; public AbstractInliningPolicy(Map hints) { @@ -45,7 +45,7 @@ } protected double computeMaximumSize(double relevance, int configuredMaximum) { - double inlineRatio = Math.min(RelevanceCapForInlining.getValue(), relevance); + double inlineRatio = Math.min(RelevanceCapForInlining, relevance); return configuredMaximum * inlineRatio; } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java Fri Dec 12 20:29:35 2014 +0100 @@ -25,13 +25,12 @@ import com.oracle.graal.api.meta.ResolvedJavaMethod; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.phases.common.inlining.policy.*; import com.oracle.graal.phases.graph.FixedNodeProbabilityCache; import java.util.*; import java.util.function.ToDoubleFunction; -import static com.oracle.graal.compiler.common.GraalOptions.CapInheritedRelevance; - /** *

* A {@link CallsiteHolder} whose graph has been copied already and thus can be modified without @@ -204,7 +203,7 @@ } public double invokeRelevance(Invoke invoke) { - return Math.min(CapInheritedRelevance.getValue(), relevance) * computeInliningRelevance.getRelevance(invoke); + return Math.min(AbstractInliningPolicy.CapInheritedRelevance, relevance) * computeInliningRelevance.getRelevance(invoke); } @Override diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Fri Dec 12 20:29:35 2014 +0100 @@ -98,9 +98,9 @@ if (!method.equals(curMethod) || !curDecorators.equals(decorators)) { cfgPrinter.printCompilation(method); TTY.println("CFGPrinter: Dumping method %s to %s", method, cfgFile); - curMethod = method; - curDecorators = decorators; } + curMethod = method; + curDecorators = decorators; return true; } @@ -206,6 +206,9 @@ public void close() { if (cfgPrinter != null) { cfgPrinter.close(); + cfgPrinter = null; + curDecorators = Collections.emptyList(); + curMethod = null; } } } diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java Fri Dec 12 20:29:35 2014 +0100 @@ -108,6 +108,8 @@ try { printStream.close(); fos.close(); + printStream = null; + fos = null; } catch (IOException e) { throw new IllegalStateException(e); } diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Fri Dec 12 20:29:35 2014 +0100 @@ -160,7 +160,7 @@ final Graph graph = (Graph) object; if (printer != null) { - // Get all current RiResolvedMethod instances in the context. + // Get all current JavaMethod instances in the context. List inlineContext = getInlineContext(); // Reverse list such that inner method comes after outer method. @@ -272,6 +272,7 @@ } if (printer != null) { printer.close(); + printer = null; } } } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/HexCodeFile.java Fri Dec 12 20:29:35 2014 +0100 @@ -39,23 +39,23 @@ * *

  *     HexCodeFile ::= Platform Delim HexCode Delim (OptionalSection Delim)*
- *
+ * 
  *     OptionalSection ::= Comment | OperandComment | JumpTable | LookupTable
- *
+ * 
  *     Platform ::= "Platform" ISA WordWidth
- *
+ * 
  *     HexCode ::= "HexCode" StartAddress HexDigits
- *
+ * 
  *     Comment ::= "Comment" Position String
- *
+ * 
  *     OperandComment ::= "OperandComment" Position String
- *
+ * 
  *     JumpTable ::= "JumpTable" Position EntrySize Low High
- *
+ * 
  *     LookupTable ::= "LookupTable" Position NPairs KeySize OffsetSize
- *
+ * 
  *     Position, EntrySize, Low, High, NPairs KeySize OffsetSize ::= int
- *
+ * 
  *     Delim := "<||@"
  * 
* diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64FloatConvertNode.java diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Fri Dec 12 20:29:35 2014 +0100 @@ -79,21 +79,21 @@ @Test public void testWrite1() { for (Kind kind : KINDS) { - assertWrite(parseEager("write" + kind.name() + "1"), kind, true, ID); + assertWrite(parseEager("write" + kind.name() + "1"), true, ID); } } @Test public void testWrite2() { for (Kind kind : KINDS) { - assertWrite(parseEager("write" + kind.name() + "2"), kind, true, ID); + assertWrite(parseEager("write" + kind.name() + "2"), true, ID); } } @Test public void testWrite3() { for (Kind kind : KINDS) { - assertWrite(parseEager("write" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); + assertWrite(parseEager("write" + kind.name() + "3"), true, LocationIdentity.ANY_LOCATION); } } @@ -103,7 +103,6 @@ Assert.assertEquals(graph.getParameter(0), read.object()); IndexedLocationNode location = (IndexedLocationNode) read.location(); - Assert.assertEquals(kind, location.getValueKind()); Assert.assertEquals(locationIdentity, location.getLocationIdentity()); Assert.assertEquals(1, location.getIndexScaling()); @@ -120,14 +119,13 @@ Assert.assertEquals(read, ret.result()); } - private static void assertWrite(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) { + private static void assertWrite(StructuredGraph graph, boolean indexConvert, LocationIdentity locationIdentity) { JavaWriteNode write = (JavaWriteNode) graph.start().next(); Assert.assertEquals(graph.getParameter(2), write.value()); Assert.assertEquals(graph.getParameter(0), write.object()); Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci); IndexedLocationNode location = (IndexedLocationNode) write.location(); - Assert.assertEquals(kind, location.getValueKind()); Assert.assertEquals(locationIdentity, location.getLocationIdentity()); Assert.assertEquals(1, location.getIndexScaling()); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Fri Dec 12 20:29:35 2014 +0100 @@ -85,21 +85,21 @@ @Test public void testWrite1() { for (Kind kind : KINDS) { - assertWrite(parseEager("write" + kind.name() + "1"), kind, true, ID); + assertWrite(parseEager("write" + kind.name() + "1"), true, ID); } } @Test public void testWrite2() { for (Kind kind : KINDS) { - assertWrite(parseEager("write" + kind.name() + "2"), kind, true, ID); + assertWrite(parseEager("write" + kind.name() + "2"), true, ID); } } @Test public void testWrite3() { for (Kind kind : KINDS) { - assertWrite(parseEager("write" + kind.name() + "3"), kind, true, LocationIdentity.ANY_LOCATION); + assertWrite(parseEager("write" + kind.name() + "3"), true, LocationIdentity.ANY_LOCATION); } } @@ -114,7 +114,6 @@ Assert.assertEquals(target.wordKind, cast.stamp().getStackKind()); IndexedLocationNode location = (IndexedLocationNode) read.location(); - Assert.assertEquals(kind, location.getValueKind()); Assert.assertEquals(locationIdentity, location.getLocationIdentity()); Assert.assertEquals(1, location.getIndexScaling()); @@ -131,7 +130,7 @@ Assert.assertEquals(read, ret.result()); } - private void assertWrite(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) { + private void assertWrite(StructuredGraph graph, boolean indexConvert, LocationIdentity locationIdentity) { WordCastNode cast = (WordCastNode) graph.start().next(); JavaWriteNode write = (JavaWriteNode) cast.next(); @@ -143,7 +142,6 @@ Assert.assertEquals(target.wordKind, cast.stamp().getStackKind()); IndexedLocationNode location = (IndexedLocationNode) write.location(); - Assert.assertEquals(kind, location.getValueKind()); Assert.assertEquals(locationIdentity, location.getLocationIdentity()); Assert.assertEquals(1, location.getIndexScaling()); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Fri Dec 12 20:29:35 2014 +0100 @@ -211,7 +211,7 @@ protected void lowerArrayLengthNode(ArrayLengthNode arrayLengthNode, LoweringTool tool) { StructuredGraph graph = arrayLengthNode.graph(); ValueNode array = arrayLengthNode.array(); - ConstantLocationNode location = ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, Kind.Int, arrayLengthOffset(), graph); + ConstantLocationNode location = ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, arrayLengthOffset(), graph); ReadNode arrayLengthRead = graph.add(ReadNode.create(array, location, StampFactory.positiveInt(), BarrierType.NONE)); arrayLengthRead.setGuard(createNullCheck(array, arrayLengthNode, tool)); @@ -243,7 +243,7 @@ protected void lowerAtomicReadAndWriteNode(AtomicReadAndWriteNode n) { StructuredGraph graph = n.graph(); Kind valueKind = n.getValueKind(); - LocationNode location = IndexedLocationNode.create(n.getLocationIdentity(), valueKind, 0, n.offset(), graph, 1); + LocationNode location = IndexedLocationNode.create(n.getLocationIdentity(), 0, n.offset(), graph, 1); ValueNode newValue = implicitStoreConvert(graph, valueKind, n.newValue()); @@ -312,7 +312,7 @@ protected void lowerJavaReadNode(JavaReadNode read) { StructuredGraph graph = read.graph(); - Kind valueKind = read.location().getValueKind(); + Kind valueKind = read.getReadKind(); Stamp loadStamp = loadStamp(read.stamp(), valueKind, read.isCompressible()); ReadNode memoryRead = graph.add(ReadNode.create(read.object(), read.location(), loadStamp, read.getBarrierType())); @@ -324,7 +324,7 @@ protected void lowerJavaWriteNode(JavaWriteNode write) { StructuredGraph graph = write.graph(); - Kind valueKind = write.location().getValueKind(); + Kind valueKind = write.getWriteKind(); ValueNode value = implicitStoreConvert(graph, valueKind, write.value(), write.isCompressible()); WriteNode memoryWrite = graph.add(WriteNode.create(write.object(), value, write.location(), write.getBarrierType(), write.isInitialization())); @@ -366,7 +366,6 @@ Kind entryKind = virtual.entryKind(i); // Truffle requires some leniency in terms of what can be put where: - Kind accessKind = valueKind.getStackKind() == entryKind.getStackKind() ? entryKind : valueKind; assert valueKind.getStackKind() == entryKind.getStackKind() || (valueKind == Kind.Long || valueKind == Kind.Double || (valueKind == Kind.Int && virtual instanceof VirtualArrayNode)); ConstantLocationNode location = null; @@ -375,11 +374,11 @@ ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i); long offset = fieldOffset(field); if (offset >= 0) { - location = ConstantLocationNode.create(initLocationIdentity(), accessKind, offset, graph); + location = ConstantLocationNode.create(initLocationIdentity(), offset, graph); barrierType = fieldInitializationBarrier(entryKind); } } else { - location = ConstantLocationNode.create(initLocationIdentity(), accessKind, arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind), graph); + location = ConstantLocationNode.create(initLocationIdentity(), arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind), graph); barrierType = arrayInitializationBarrier(entryKind); } if (location != null) { @@ -583,7 +582,7 @@ int offset = fieldOffset(field); if (offset >= 0) { LocationIdentity loc = initialization ? initLocationIdentity() : field; - return ConstantLocationNode.create(loc, field.getKind(), offset, graph); + return ConstantLocationNode.create(loc, offset, graph); } else { return null; } @@ -612,7 +611,7 @@ ValueNode offset = offsetNode; if (offset.isConstant()) { long offsetValue = offset.asJavaConstant().asLong(); - return ConstantLocationNode.create(locationIdentity, accessKind, offsetValue, offset.graph()); + return ConstantLocationNode.create(locationIdentity, offsetValue, offset.graph()); } long displacement = 0; @@ -673,12 +672,12 @@ // If we were using sign extended values before restore the sign extension. offset = offset.graph().addOrUnique(SignExtendNode.create(offset, 64)); } - return IndexedLocationNode.create(locationIdentity, accessKind, displacement, offset, offset.graph(), indexScaling); + return IndexedLocationNode.create(locationIdentity, displacement, offset, offset.graph(), indexScaling); } public IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) { LocationIdentity loc = initialization ? initLocationIdentity() : NamedLocationIdentity.getArrayLocation(elementKind); - return IndexedLocationNode.create(loc, elementKind, arrayBaseOffset(elementKind), index, graph, arrayScalingFactor(elementKind)); + return IndexedLocationNode.create(loc, arrayBaseOffset(elementKind), index, graph, arrayScalingFactor(elementKind)); } protected GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { @@ -687,7 +686,7 @@ ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); if (arrayLength == null) { Stamp stamp = StampFactory.positiveInt(); - ReadNode readArrayLength = graph.add(ReadNode.create(array, ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, Kind.Int, arrayLengthOffset(), graph), stamp, BarrierType.NONE)); + ReadNode readArrayLength = graph.add(ReadNode.create(array, ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, arrayLengthOffset(), graph), stamp, BarrierType.NONE)); graph.addBeforeFixed(n, readArrayLength); readArrayLength.setGuard(createNullCheck(array, readArrayLength, tool)); arrayLength = readArrayLength; @@ -715,8 +714,7 @@ } @Override - public ValueNode reconstructArrayIndex(LocationNode location) { - Kind elementKind = location.getValueKind(); + public ValueNode reconstructArrayIndex(Kind elementKind, LocationNode location) { assert location.getLocationIdentity().equals(NamedLocationIdentity.getArrayLocation(elementKind)); long base; diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Fri Dec 12 20:29:35 2014 +0100 @@ -315,10 +315,10 @@ try { Object[] args = new Object[constructor.getParameterCount()]; for (int i = 0; i < args.length; i++) { - Object arg = snippetReflection.getSubstitutionGuardParameter(paramTypes[0]); + Object arg = snippetReflection.getSubstitutionGuardParameter(paramTypes[i]); if (arg != null) { args[i] = arg; - } else if (paramTypes[0].isInstance(target.arch)) { + } else if (paramTypes[i].isInstance(target.arch)) { args[i] = target.arch; } else { throw new GraalInternalError("Unsupported type %s in substitution guard constructor: %s", paramTypes[i].getName(), constructor); diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java Fri Dec 12 20:29:35 2014 +0100 @@ -534,8 +534,9 @@ } } - private static final Object UNUSED_PARAMETER = "DEAD PARAMETER"; - private static final Object CONSTANT_PARAMETER = "CONSTANT"; + // These values must be compared with equals() not '==' to support replay compilation. + private static final Object UNUSED_PARAMETER = "UNUSED_PARAMETER"; + private static final Object CONSTANT_PARAMETER = "CONSTANT_PARAMETER"; /** * Determines if any parameter of a given method is annotated with {@link ConstantParameter}. @@ -905,7 +906,7 @@ } } } else { - assert parameter == CONSTANT_PARAMETER || parameter == UNUSED_PARAMETER : "unexpected entry for parameter: " + args.info.getParameterName(i) + " -> " + parameter; + assert parameter.equals(CONSTANT_PARAMETER) || parameter.equals(UNUSED_PARAMETER) : "unexpected entry for parameter: " + args.info.getParameterName(i) + " -> " + parameter; } } return replacements; @@ -1298,9 +1299,9 @@ sep = ", "; if (value == null) { buf.append(" ").append(name); - } else if (value == UNUSED_PARAMETER) { + } else if (value.equals(UNUSED_PARAMETER)) { buf.append(" ").append(name); - } else if (value == CONSTANT_PARAMETER) { + } else if (value.equals(CONSTANT_PARAMETER)) { buf.append(" ").append(name); } else if (value instanceof ParameterNode) { ParameterNode param = (ParameterNode) value; diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -42,30 +42,34 @@ @Input ValueNode offset; protected final int displacement; protected final LocationIdentity locationIdentity; + protected final Kind storeKind; - public static DirectObjectStoreNode create(ValueNode object, int displacement, ValueNode offset, ValueNode value, LocationIdentity locationIdentity) { - return new DirectObjectStoreNode(object, displacement, offset, value, locationIdentity); + public static DirectObjectStoreNode create(ValueNode object, int displacement, ValueNode offset, ValueNode value, LocationIdentity locationIdentity, Kind storeKind) { + return new DirectObjectStoreNode(object, displacement, offset, value, locationIdentity, storeKind); } - protected DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, LocationIdentity locationIdentity) { + protected DirectObjectStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, LocationIdentity locationIdentity, Kind storeKind) { super(StampFactory.forVoid()); this.object = object; this.value = value; this.offset = offset; this.displacement = displacement; this.locationIdentity = locationIdentity; + this.storeKind = storeKind; } @NodeIntrinsic - public static native void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter LocationIdentity locationIdentity); + public static native void storeObject(Object obj, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter LocationIdentity locationIdentity, + @ConstantNodeParameter Kind storeKind); @NodeIntrinsic - public static native void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter LocationIdentity locationIdenity); + public static native void storeLong(Object obj, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter LocationIdentity locationIdenity, + @ConstantNodeParameter Kind storeKind); @Override public void lower(LoweringTool tool) { - IndexedLocationNode location = IndexedLocationNode.create(locationIdentity, value.getKind(), displacement, offset, graph(), 1); - JavaWriteNode write = graph().add(JavaWriteNode.create(object, value, location, BarrierType.NONE, value.getKind() == Kind.Object, false)); + IndexedLocationNode location = IndexedLocationNode.create(locationIdentity, displacement, offset, graph(), 1); + JavaWriteNode write = graph().add(JavaWriteNode.create(storeKind, object, value, location, BarrierType.NONE, storeKind == Kind.Object, false)); graph().replaceFixedWithFixed(this, write); tool.getLowerer().lower(write, tool); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java Fri Dec 12 20:29:35 2014 +0100 @@ -23,11 +23,11 @@ package com.oracle.graal.virtual.phases.ea; import static com.oracle.graal.compiler.common.GraalOptions.*; + import java.util.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.cfg.*; -import com.oracle.graal.compiler.common.remote.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -45,7 +45,7 @@ protected final NodeMap aliases; protected final BlockMap blockEffects; - private final Map, GraphEffectList> loopMergeEffects = Context.newIdentityMap(); + private final Map, GraphEffectList> loopMergeEffects = CollectionsFactory.newIdentityMap(); private final Map loopEntryStates = Node.newIdentityMap(); protected boolean changed; diff -r 6ace9e5bc384 -r 7cc21427d54b 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 Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java Fri Dec 12 20:29:35 2014 +0100 @@ -26,7 +26,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.common.remote.*; +import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; @@ -271,7 +271,7 @@ protected class MergeProcessor extends EffectsClosure.MergeProcessor { - private final HashMap materializedPhis = Context.newMap(); + private final HashMap materializedPhis = CollectionsFactory.newMap(); private final Map valuePhis = Node.newIdentityMap(); private final Map valueObjectVirtuals = Node.newIdentityMap(); diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Fri Dec 12 20:29:35 2014 +0100 @@ -48,34 +48,32 @@ protected final SnippetReflectionProvider snippetReflection; - @Input ValueNode valueKind; @Input(InputType.Association) ValueNode locationIdentity; @Input ValueNode displacement; @Input ValueNode index; @Input ValueNode indexScaling; - public static SnippetLocationNode create(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode identity, ValueNode kind, ValueNode displacement, ValueNode index, - ValueNode indexScaling, Graph graph) { - return graph.unique(SnippetLocationNode.create(snippetReflection, identity, kind, displacement, index, indexScaling)); + public static SnippetLocationNode create(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode identity, ValueNode displacement, ValueNode index, ValueNode indexScaling, + Graph graph) { + return graph.unique(SnippetLocationNode.create(snippetReflection, identity, displacement, index, indexScaling)); } - public static SnippetLocationNode create(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement) { - return new SnippetLocationNode(snippetReflection, locationIdentity, kind, displacement); + public static SnippetLocationNode create(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode displacement) { + return new SnippetLocationNode(snippetReflection, locationIdentity, displacement); } - protected SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement) { - this(snippetReflection, locationIdentity, kind, displacement, null, null); + protected SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode displacement) { + this(snippetReflection, locationIdentity, displacement, null, null); } - public static SnippetLocationNode create(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, + public static SnippetLocationNode create(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode displacement, ValueNode index, ValueNode indexScaling) { - return new SnippetLocationNode(snippetReflection, locationIdentity, kind, displacement, index, indexScaling); + return new SnippetLocationNode(snippetReflection, locationIdentity, displacement, index, indexScaling); } - protected SnippetLocationNode(SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode kind, ValueNode displacement, ValueNode index, ValueNode indexScaling) { + protected SnippetLocationNode(SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode displacement, ValueNode index, ValueNode indexScaling) { super(StampFactory.object()); this.snippetReflection = snippetReflection; - this.valueKind = kind; this.locationIdentity = locationIdentity; this.displacement = displacement; this.index = index; @@ -83,14 +81,6 @@ } @Override - public Kind getValueKind() { - if (valueKind.isConstant()) { - return snippetReflection.asObject(Kind.class, valueKind.asJavaConstant()); - } - throw new GraalInternalError("Cannot access kind yet because it is not constant: " + valueKind); - } - - @Override public LocationIdentity getLocationIdentity() { if (locationIdentity.isConstant()) { LocationIdentity identity = snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant()); @@ -102,18 +92,17 @@ @Override public Node canonical(CanonicalizerTool tool) { - if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { - Kind constKind = snippetReflection.asObject(Kind.class, valueKind.asJavaConstant()); + if (locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { LocationIdentity constLocation = snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant()); long constDisplacement = displacement.asJavaConstant().asLong(); int constIndexScaling = indexScaling == null ? 0 : indexScaling.asJavaConstant().asInt(); if (index == null || constIndexScaling == 0) { - return ConstantLocationNode.create(constLocation, constKind, constDisplacement, graph()); + return ConstantLocationNode.create(constLocation, constDisplacement, graph()); } else if (index.isConstant()) { - return ConstantLocationNode.create(constLocation, constKind, index.asJavaConstant().asLong() * constIndexScaling + constDisplacement, graph()); + return ConstantLocationNode.create(constLocation, index.asJavaConstant().asLong() * constIndexScaling + constDisplacement, graph()); } else { - return IndexedLocationNode.create(constLocation, constKind, constDisplacement, index, graph(), constIndexScaling); + return IndexedLocationNode.create(constLocation, constDisplacement, index, graph(), constIndexScaling); } } return this; @@ -130,8 +119,8 @@ } @NodeIntrinsic - public static native Location constantLocation(LocationIdentity identity, Kind kind, long displacement); + public static native Location constantLocation(LocationIdentity identity, long displacement); @NodeIntrinsic - public static native Location indexedLocation(LocationIdentity identity, Kind kind, long displacement, int index, int indexScaling); + public static native Location indexedLocation(LocationIdentity identity, long displacement, int index, int indexScaling); } diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Dec 12 20:29:35 2014 +0100 @@ -230,19 +230,19 @@ Kind readKind = asKind(callTargetNode.returnType()); LocationNode location; if (arguments.size() == 2) { - location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); + location = makeLocation(graph, arguments.get(1), ANY_LOCATION); } else { - location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); + location = makeLocation(graph, arguments.get(1), arguments.get(2)); } - replace(invoke, readOp(graph, arguments.get(0), invoke, location, operation.opcode())); + replace(invoke, readOp(graph, readKind, arguments.get(0), invoke, location, operation.opcode())); break; } case READ_HEAP: { assert arguments.size() == 3; Kind readKind = asKind(callTargetNode.returnType()); - LocationNode location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); + LocationNode location = makeLocation(graph, arguments.get(1), ANY_LOCATION); BarrierType barrierType = snippetReflection.asObject(BarrierType.class, arguments.get(2).asJavaConstant()); - replace(invoke, readOp(graph, arguments.get(0), invoke, location, barrierType, true)); + replace(invoke, readOp(graph, readKind, arguments.get(0), invoke, location, barrierType, true)); break; } case WRITE_POINTER: @@ -253,11 +253,11 @@ Kind writeKind = asKind(targetMethod.getSignature().getParameterType(targetMethod.isStatic() ? 2 : 1, targetMethod.getDeclaringClass())); LocationNode location; if (arguments.size() == 3) { - location = makeLocation(graph, arguments.get(1), writeKind, LocationIdentity.ANY_LOCATION); + location = makeLocation(graph, arguments.get(1), LocationIdentity.ANY_LOCATION); } else { - location = makeLocation(graph, arguments.get(1), writeKind, arguments.get(3)); + location = makeLocation(graph, arguments.get(1), arguments.get(3)); } - replace(invoke, writeOp(graph, arguments.get(0), arguments.get(2), invoke, location, operation.opcode())); + replace(invoke, writeOp(graph, writeKind, arguments.get(0), arguments.get(2), invoke, location, operation.opcode())); break; } case ZERO: @@ -379,28 +379,27 @@ return materialize; } - protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, ValueNode locationIdentity) { + protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, ValueNode locationIdentity) { if (locationIdentity.isConstant()) { - return makeLocation(graph, offset, readKind, snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant())); + return makeLocation(graph, offset, snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant())); } - return SnippetLocationNode.create(snippetReflection, locationIdentity, ConstantNode.forConstant(snippetReflection.forObject(readKind), metaAccess, graph), ConstantNode.forLong(0, graph), - fromSigned(graph, offset), ConstantNode.forInt(1, graph), graph); + return SnippetLocationNode.create(snippetReflection, locationIdentity, ConstantNode.forLong(0, graph), fromSigned(graph, offset), ConstantNode.forInt(1, graph), graph); } - protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, Kind readKind, LocationIdentity locationIdentity) { - return IndexedLocationNode.create(locationIdentity, readKind, 0, fromSigned(graph, offset), graph, 1); + protected LocationNode makeLocation(StructuredGraph graph, ValueNode offset, LocationIdentity locationIdentity) { + return IndexedLocationNode.create(locationIdentity, 0, fromSigned(graph, offset), graph, 1); } - protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, Opcode op) { + protected ValueNode readOp(StructuredGraph graph, Kind readKind, ValueNode base, Invoke invoke, LocationNode location, Opcode op) { assert op == Opcode.READ_POINTER || op == Opcode.READ_OBJECT || op == Opcode.READ_BARRIERED; final BarrierType barrier = (op == Opcode.READ_BARRIERED ? BarrierType.PRECISE : BarrierType.NONE); final boolean compressible = (op == Opcode.READ_OBJECT || op == Opcode.READ_BARRIERED); - return readOp(graph, base, invoke, location, barrier, compressible); + return readOp(graph, readKind, base, invoke, location, barrier, compressible); } - protected ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, BarrierType barrierType, boolean compressible) { - JavaReadNode read = graph.add(JavaReadNode.create(base, location, barrierType, compressible)); + protected ValueNode readOp(StructuredGraph graph, Kind readKind, ValueNode base, Invoke invoke, LocationNode location, BarrierType barrierType, boolean compressible) { + JavaReadNode read = graph.add(JavaReadNode.create(readKind, base, location, barrierType, compressible)); graph.addBeforeFixed(invoke.asNode(), read); /* * The read must not float outside its block otherwise it may float above an explicit zero @@ -410,12 +409,12 @@ return read; } - protected ValueNode writeOp(StructuredGraph graph, ValueNode base, ValueNode value, Invoke invoke, LocationNode location, Opcode op) { + protected ValueNode writeOp(StructuredGraph graph, Kind writeKind, ValueNode base, ValueNode value, Invoke invoke, LocationNode location, Opcode op) { assert op == Opcode.WRITE_POINTER || op == Opcode.WRITE_OBJECT || op == Opcode.WRITE_BARRIERED || op == Opcode.INITIALIZE; final BarrierType barrier = (op == Opcode.WRITE_BARRIERED ? BarrierType.PRECISE : BarrierType.NONE); final boolean compressible = (op == Opcode.WRITE_OBJECT || op == Opcode.WRITE_BARRIERED); final boolean initialize = (op == Opcode.INITIALIZE); - JavaWriteNode write = graph.add(JavaWriteNode.create(base, value, location, barrier, compressible, initialize)); + JavaWriteNode write = graph.add(JavaWriteNode.create(writeKind, base, value, location, barrier, compressible, initialize)); write.setStateAfter(invoke.stateAfter()); graph.addBeforeFixed(invoke.asNode(), write); return write; diff -r 6ace9e5bc384 -r 7cc21427d54b graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java Fri Dec 12 20:02:09 2014 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java Fri Dec 12 20:29:35 2014 +0100 @@ -49,13 +49,14 @@ CompilerDirectives.transferToInterpreterAndInvalidate(); wasTrue = true; } + return true; } else { if (!wasFalse) { CompilerDirectives.transferToInterpreterAndInvalidate(); wasFalse = true; } + return false; } - return value; } public boolean wasTrue() { diff -r 6ace9e5bc384 -r 7cc21427d54b mx/mx_graal.py --- a/mx/mx_graal.py Fri Dec 12 20:02:09 2014 +0100 +++ b/mx/mx_graal.py Fri Dec 12 20:29:35 2014 +0100 @@ -755,7 +755,7 @@ if not exists(opts2.export_dir): os.makedirs(opts2.export_dir) else: - assert os.path.isdir(opts2.export_dir), '{} is not a directory'.format(opts2.export_dir) + assert os.path.isdir(opts2.export_dir), '{0} is not a directory'.format(opts2.export_dir) defsPath = join(_graal_home, 'make', 'defs.make') with open(defsPath) as fp: @@ -1835,7 +1835,7 @@ deps = d['deps'] makejmhdep(artifactId, groupId, deps) except ValueError as e: - mx.abort('Error parsing {}:\n{}'.format(f, e)) + mx.abort('Error parsing {0}:\n{1}'.format(f, e)) def buildjmh(args): """build the JMH benchmarks""" @@ -1916,7 +1916,7 @@ else: jmhArgs[n] = v except ValueError as e: - mx.abort('error parsing JSON input: {}\n{}'.format(j, e)) + mx.abort('error parsing JSON input: {0}\n{1}'.format(j, e)) jmhPath = _get_jmh_path() mx.log('Using benchmarks in ' + jmhPath) @@ -2310,7 +2310,7 @@ if not matcher.match(content): failures[f] = csConfig for n, v in failures.iteritems(): - mx.log('{}: header does not match RegexpHeader defined in {}'.format(n, v)) + mx.log('{0}: header does not match RegexpHeader defined in {1}'.format(n, v)) return len(failures) def mx_init(suite): diff -r 6ace9e5bc384 -r 7cc21427d54b mxtool/mx.py --- a/mxtool/mx.py Fri Dec 12 20:02:09 2014 +0100 +++ b/mxtool/mx.py Fri Dec 12 20:29:35 2014 +0100 @@ -109,7 +109,7 @@ try: excl = [dependency(d) for d in self.excludedDependencies] except SystemExit as e: - abort('invalid excluded dependency for {} distribution: {}'.format(self.name, e)) + abort('invalid excluded dependency for {0} distribution: {1}'.format(self.name, e)) return deps + [d for d in sorted_deps(self.deps, includeLibs=includeLibs) if d not in excl] def __str__(self): @@ -698,14 +698,14 @@ abspath = _make_absolute(path, self.suite.dir) if not optional and not exists(abspath): if not len(urls): - abort('Non-optional library {} must either exist at {} or specify one or more URLs from which it can be retrieved'.format(name, abspath)) + abort('Non-optional library {0} must either exist at {1} or specify one or more URLs from which it can be retrieved'.format(name, abspath)) def _checkSha1PropertyCondition(propName, cond, inputPath): if not cond: absInputPath = _make_absolute(inputPath, self.suite.dir) if exists(absInputPath): - abort('Missing "{}" property for library {}. Add the following line to projects file:\nlibrary@{}@{}={}'.format(propName, name, name, propName, sha1OfFile(absInputPath))) - abort('Missing "{}" property for library {}'.format(propName, name)) + abort('Missing "{0}" property for library {1}. Add the following line to projects file:\nlibrary@{2}@{3}={4}'.format(propName, name, name, propName, sha1OfFile(absInputPath))) + abort('Missing "{0}" property for library {1}'.format(propName, name)) _checkSha1PropertyCondition('sha1', sha1, path) _checkSha1PropertyCondition('sourceSha1', not sourcePath or sourceSha1, sourcePath) @@ -1181,12 +1181,12 @@ finally: d.optional = True if not path: - logv('[omitting optional library {} as {} does not exist]'.format(d, d.path)) + logv('[omitting optional library {0} as {1} does not exist]'.format(d, d.path)) del _libs[d.name] self.libs.remove(d) elif d.isProject(): if java(d.javaCompliance) is None: - logv('[omitting project {} as Java compliance {} cannot be satisfied by configured JDKs]'.format(d, d.javaCompliance)) + logv('[omitting project {0} as Java compliance {1} cannot be satisfied by configured JDKs]'.format(d, d.javaCompliance)) del _projects[d.name] self.projects.remove(d) else: @@ -1195,19 +1195,19 @@ if jreLib: if not jreLib.is_present_in_jdk(java(d.javaCompliance)): if jreLib.optional: - logv('[omitting project {} as dependency {} is missing]'.format(d, name)) + logv('[omitting project {0} as dependency {1} is missing]'.format(d, name)) del _projects[d.name] self.projects.remove(d) else: - abort('JRE library {} required by {} not found'.format(jreLib, d)) + abort('JRE library {0} required by {1} not found'.format(jreLib, d)) elif not dependency(name, fatalIfMissing=False): - logv('[omitting project {} as dependency {} is missing]'.format(d, name)) + logv('[omitting project {0} as dependency {1} is missing]'.format(d, name)) del _projects[d.name] self.projects.remove(d) for dist in _dists.itervalues(): for name in list(dist.deps): if not dependency(name, fatalIfMissing=False): - logv('[omitting {} from distribution {}]'.format(name, dist)) + logv('[omitting {0} from distribution {1}]'.format(name, dist)) dist.deps.remove(name) if hasattr(self, 'mx_post_parse_cmd_line'): @@ -1673,6 +1673,9 @@ opts = self.parse_args() + global _opts + _opts = opts + # Give the timeout options a default value to avoid the need for hasattr() tests opts.__dict__.setdefault('timeout', 0) opts.__dict__.setdefault('ptimeout', 0) @@ -2209,7 +2212,7 @@ the object's value is printed and the exit status is one. """ - if _opts.killwithsigquit: + if _opts and _opts.killwithsigquit: _send_sigquit() def is_alive(p): @@ -2227,7 +2230,7 @@ _kill_process_group(p.pid, signal.SIGKILL) except BaseException as e: if is_alive(p): - log('error while killing subprocess {} "{}": {}'.format(p.pid, ' '.join(args), e)) + log('error while killing subprocess {0} "{1}": {2}'.format(p.pid, ' '.join(args), e)) if _opts and _opts.verbose: import traceback @@ -2304,7 +2307,7 @@ return self.proj.name def logCompilation(self, compiler): - log('Compiling Java sources for {} with {}... [{}]'.format(self.proj.name, compiler, self.reason)) + log('Compiling Java sources for {0} with {1}... [{2}]'.format(self.proj.name, compiler, self.reason)) def execute(self): argfileName = join(self.proj.dir, 'javafilelist.txt') @@ -2469,22 +2472,6 @@ if args.java: ideinit([], refreshOnly=True, buildProcessorJars=False) - def prepareOutputDirs(p, clean): - outputDir = p.output_dir() - if exists(outputDir): - if clean: - log('Cleaning {0}...'.format(outputDir)) - shutil.rmtree(outputDir) - os.mkdir(outputDir) - else: - os.mkdir(outputDir) - genDir = p.source_gen_dir() - if genDir != '' and exists(genDir) and clean: - log('Cleaning {0}...'.format(genDir)) - for f in os.listdir(genDir): - shutil.rmtree(join(genDir, f)) - return outputDir - tasks = {} updatedAnnotationProcessorDists = set() for p in sortedProjects: @@ -2508,10 +2495,15 @@ jdk = java(requiredCompliance) assert jdk - outputDir = prepareOutputDirs(p, args.clean) + outputDir = p.output_dir() sourceDirs = p.source_dirs() - buildReason = 'forced build' if args.force else None + buildReason = None + if args.force: + buildReason = 'forced build' + elif args.clean: + buildReason = 'clean' + taskDeps = [] for dep in p.all_deps([], includeLibs=False, includeAnnotationProcessors=True): taskDep = tasks.get(dep.name) @@ -2520,52 +2512,14 @@ buildReason = dep.name + ' rebuilt' taskDeps.append(taskDep) - jasminAvailable = None javafilelist = [] + nonjavafiletuples = [] for sourceDir in sourceDirs: for root, _, files in os.walk(sourceDir): javafiles = [join(root, name) for name in files if name.endswith('.java') and name != 'package-info.java'] javafilelist += javafiles - # Copy all non Java resources or assemble Jasmin files - nonjavafilelist = [join(root, name) for name in files if not name.endswith('.java')] - for src in nonjavafilelist: - if src.endswith('.jasm'): - className = None - with open(src) as f: - for line in f: - if line.startswith('.class '): - className = line.split()[-1] - break - - if className is not None: - jasminOutputDir = p.jasmin_output_dir() - classFile = join(jasminOutputDir, className.replace('/', os.sep) + '.class') - if exists(dirname(classFile)) and (not exists(classFile) or os.path.getmtime(classFile) < os.path.getmtime(src)): - if jasminAvailable is None: - try: - with open(os.devnull) as devnull: - subprocess.call('jasmin', stdout=devnull, stderr=subprocess.STDOUT) - jasminAvailable = True - except OSError: - jasminAvailable = False - - if jasminAvailable: - log('Assembling Jasmin file ' + src) - run(['jasmin', '-d', jasminOutputDir, src]) - else: - log('The jasmin executable could not be found - skipping ' + src) - with file(classFile, 'a'): - os.utime(classFile, None) - - else: - log('could not file .class directive in Jasmin source: ' + src) - else: - dst = join(outputDir, src[len(sourceDir) + 1:]) - if not exists(dirname(dst)): - os.makedirs(dirname(dst)) - if exists(dirname(dst)) and (not exists(dst) or os.path.getmtime(dst) < os.path.getmtime(src)): - shutil.copyfile(src, dst) + nonjavafiletuples += [(sourceDir, [join(root, name) for name in files if not name.endswith('.java')])] if not buildReason: for javafile in javafiles: @@ -2580,8 +2534,11 @@ if not buildReason: logv('[all class files for {0} are up to date - skipping]'.format(p.name)) + _handleNonJavaFiles(outputDir, p, False, nonjavafiletuples) continue + _handleNonJavaFiles(outputDir, p, True, nonjavafiletuples) + if len(javafilelist) == 0: logv('[no Java sources for {0} - skipping]'.format(p.name)) continue @@ -2688,8 +2645,8 @@ failed += joinTasks(active) if len(failed): for t in failed: - log('Compiling {} failed'.format(t.proj.name)) - abort('{} Java compilation tasks failed'.format(len(failed))) + log('Compiling {0} failed'.format(t.proj.name)) + abort('{0} Java compilation tasks failed'.format(len(failed))) if args.java: for dist in sorted_dists(): @@ -2700,6 +2657,64 @@ return args return None +def _handleNonJavaFiles(outputDir, p, clean, nonjavafiletuples): + if exists(outputDir): + if clean: + log('Cleaning {0}...'.format(outputDir)) + shutil.rmtree(outputDir) + os.mkdir(outputDir) + else: + os.mkdir(outputDir) + genDir = p.source_gen_dir() + if genDir != '' and exists(genDir) and clean: + log('Cleaning {0}...'.format(genDir)) + for f in os.listdir(genDir): + shutil.rmtree(join(genDir, f)) + + # Copy all non Java resources or assemble Jasmin files + jasminAvailable = None + for nonjavafiletuple in nonjavafiletuples: + sourceDir = nonjavafiletuple[0] + nonjavafilelist = nonjavafiletuple[1] + + for src in nonjavafilelist: + if src.endswith('.jasm'): + className = None + with open(src) as f: + for line in f: + if line.startswith('.class '): + className = line.split()[-1] + break + + if className is not None: + jasminOutputDir = p.jasmin_output_dir() + classFile = join(jasminOutputDir, className.replace('/', os.sep) + '.class') + if exists(dirname(classFile)) and (not exists(classFile) or os.path.getmtime(classFile) < os.path.getmtime(src)): + if jasminAvailable is None: + try: + with open(os.devnull) as devnull: + subprocess.call('jasmin', stdout=devnull, stderr=subprocess.STDOUT) + jasminAvailable = True + except OSError: + jasminAvailable = False + + if jasminAvailable: + log('Assembling Jasmin file ' + src) + run(['jasmin', '-d', jasminOutputDir, src]) + else: + log('The jasmin executable could not be found - skipping ' + src) + with file(classFile, 'a'): + os.utime(classFile, None) + + else: + log('could not file .class directive in Jasmin source: ' + src) + else: + dst = join(outputDir, src[len(sourceDir) + 1:]) + if not exists(dirname(dst)): + os.makedirs(dirname(dst)) + if exists(dirname(dst)) and (not exists(dst) or os.path.getmtime(dst) < os.path.getmtime(src)): + shutil.copyfile(src, dst) + def _chunk_files_for_command_line(files, limit=None, pathFunction=None): """ Returns a generator for splitting up a list of files into chunks such that the @@ -3039,7 +3054,7 @@ candidates.difference_update(c.all_deps([], False, False)) candidates = [d.name for d in candidates] - abort('{} does not use any packages defined in these projects: {}\nComputed project dependencies: {}'.format( + abort('{0} does not use any packages defined in these projects: {1}\nComputed project dependencies: {2}'.format( p, ', '.join(ignoredDeps), ','.join(candidates))) excess = frozenset(p.deps) - set(p.canonical_deps()) @@ -3166,7 +3181,7 @@ if name == 'file': source[0] = attrs['name'] elif name == 'error': - errors.append('{}:{}: {}'.format(source[0], attrs['line'], attrs['message'])) + errors.append('{0}:{1}: {2}'.format(source[0], attrs['line'], attrs['message'])) xp = xml.parsers.expat.ParserCreate() xp.StartElementHandler = start_element @@ -4782,9 +4797,9 @@ if not 'version' in subprocess.check_output(['dot', '-V'], stderr=subprocess.STDOUT): dotErr = 'dot -V does not print a string containing "version"' except subprocess.CalledProcessError as e: - dotErr = 'error calling "dot -V": {}'.format(e) + dotErr = 'error calling "dot -V": {0}'.format(e) except OSError as e: - dotErr = 'error calling "dot -V": {}'.format(e) + dotErr = 'error calling "dot -V": {0}'.format(e) if dotErr != None: abort('cannot generate dependency graph: ' + dotErr) @@ -4824,7 +4839,7 @@ # Create HTML that embeds the svg file in an frame with open(html, 'w') as fp: - print >> fp, ''.format(args.dot_output_base) + print >> fp, ''.format(args.dot_output_base) if exists(args.base): shutil.rmtree(args.base) @@ -5177,9 +5192,9 @@ abort('no primary suite found') opts, commandAndArgs = _argParser._parse_cmd_line() - - global _opts, _java_homes - _opts = opts + assert _opts == opts + + global _java_homes defaultJdk = JavaConfig(opts.java_home, opts.java_dbg_port) _java_homes = [defaultJdk] if opts.extra_java_homes: diff -r 6ace9e5bc384 -r 7cc21427d54b src/cpu/x86/vm/nativeInst_x86.hpp --- a/src/cpu/x86/vm/nativeInst_x86.hpp Fri Dec 12 20:02:09 2014 +0100 +++ b/src/cpu/x86/vm/nativeInst_x86.hpp Fri Dec 12 20:29:35 2014 +0100 @@ -562,26 +562,24 @@ (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ } inline bool NativeInstruction::is_safepoint_poll() { #ifdef AMD64 - if (Assembler::is_polling_page_far()) { - // two cases, depending on the choice of the base register in the address. - if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix && - ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl && - (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) || - ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && - (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) { - return true; - } else { - return false; - } - } else { - if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && - ubyte_at(1) == 0x05) { // 00 rax 101 - address fault = addr_at(6) + int_at(2); - return os::is_poll_address(fault); - } else { - return false; - } + // Try decoding a near safepoint first: + if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && + ubyte_at(1) == 0x05) { // 00 rax 101 + address fault = addr_at(6) + int_at(2); + NOT_GRAAL(assert(!Assembler::is_polling_page_far(), "unexpected poll encoding");) + return os::is_poll_address(fault); } + // Now try decoding a far safepoint: + // two cases, depending on the choice of the base register in the address. + if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix && + ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl && + (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) || + ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && + (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) { + NOT_GRAAL(assert(Assembler::is_polling_page_far(), "unexpected poll encoding");) + return true; + } + return false; #else return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg || ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) && diff -r 6ace9e5bc384 -r 7cc21427d54b src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Fri Dec 12 20:02:09 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri Dec 12 20:29:35 2014 +0100 @@ -962,6 +962,9 @@ case POLL_RETURN_FAR: pd_relocate_poll(pc, id); break; + case CARD_TABLE_SHIFT: + case CARD_TABLE_ADDRESS: + break; default: ShouldNotReachHere(); break; diff -r 6ace9e5bc384 -r 7cc21427d54b src/share/vm/graal/graalCodeInstaller.hpp --- a/src/share/vm/graal/graalCodeInstaller.hpp Fri Dec 12 20:02:09 2014 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.hpp Fri Dec 12 20:29:35 2014 +0100 @@ -47,6 +47,8 @@ POLL_RETURN_NEAR = 12, POLL_FAR = 13, POLL_RETURN_FAR = 14, + CARD_TABLE_ADDRESS = 15, + CARD_TABLE_SHIFT = 16, INVOKE_INVALID = -1 }; diff -r 6ace9e5bc384 -r 7cc21427d54b src/share/vm/graal/graalRuntime.cpp --- a/src/share/vm/graal/graalRuntime.cpp Fri Dec 12 20:02:09 2014 +0100 +++ b/src/share/vm/graal/graalRuntime.cpp Fri Dec 12 20:29:35 2014 +0100 @@ -627,7 +627,7 @@ case 's': tty->print("%d", (jshort) value); break; case 'i': tty->print("%d", (jint) value); break; case 'f': tty->print("%f", uu.f); break; - case 'j': tty->print(INT64_FORMAT, value); break; + case 'j': tty->print(JLONG_FORMAT, value); break; case 'd': tty->print("%lf", uu.d); break; default: assert(false, "unknown typeChar"); break; } @@ -679,6 +679,7 @@ // private static TruffleRuntime Truffle.createRuntime() JVM_ENTRY(jobject, JVM_CreateTruffleRuntime(JNIEnv *env, jclass c)) + GraalRuntime::ensure_graal_class_loader_is_initialized(); TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", CHECK_NULL); KlassHandle klass = GraalRuntime::resolve_or_fail(name, CHECK_NULL); @@ -906,7 +907,7 @@ if (num_read == -1) { warning("Error reading file %s due to %s", path, strerror(errno)); } else if (num_read != st.st_size) { - warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, st.st_size, path); + warning("Only read %d of " SIZE_FORMAT " bytes from %s", num_read, (size_t) st.st_size, path); } os::close(file_handle); if (num_read == st.st_size) { diff -r 6ace9e5bc384 -r 7cc21427d54b src/share/vm/graal/vmStructs_graal.hpp --- a/src/share/vm/graal/vmStructs_graal.hpp Fri Dec 12 20:02:09 2014 +0100 +++ b/src/share/vm/graal/vmStructs_graal.hpp Fri Dec 12 20:29:35 2014 +0100 @@ -73,6 +73,8 @@ declare_constant(CodeInstaller::POLL_RETURN_NEAR) \ declare_constant(CodeInstaller::POLL_FAR) \ declare_constant(CodeInstaller::POLL_RETURN_FAR) \ + declare_constant(CodeInstaller::CARD_TABLE_SHIFT) \ + declare_constant(CodeInstaller::CARD_TABLE_ADDRESS) \ declare_constant(CodeInstaller::INVOKE_INVALID) \ \ declare_constant(Method::invalid_vtable_index) \