# HG changeset patch
# User Jaroslav Tulach
+ * BranchProfiles are profiles to speculate on branches that are unlikely to be visited. If the
+ * {@link #enter()} method is invoked first the optimized code is invalidated and the branch where
+ * {@link #enter()} is invoked is enabled for compilation. Otherwise if the {@link #enter()} method
+ * was never invoked the branch will not get compiled.
+ *
+ * Usage example:
+ *
+ *
+ * Specialized value profile to capture certain properties of
+ * Usage example:
+ *
+ *
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see #createIdentityProfile()
+ * @see ValueProfile
+ */
+public abstract class ByteValueProfile extends Profile {
+
+ ByteValueProfile() {
+ }
+
+ public abstract byte profile(byte value);
+
+ /**
+ * Returns a value profile that profiles the exact value of a
+ * ConditionProfiles are useful to profile the outcome of conditions.
+ *
+ * Usage example:
+ *
+ *
+ * Specialized value profile to capture certain properties of
+ * Usage example:
+ *
+ *
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see #createRawIdentityProfile()
+ * @see ValueProfile
+ */
+public abstract class DoubleValueProfile extends Profile {
+
+ DoubleValueProfile() {
+ }
+
+ public abstract double profile(double value);
+
+ /**
+ * Returns a value profile that profiles the exact value of a
+ * Specialized value profile to capture certain properties of
+ * Usage example:
+ *
+ *
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see #createRawIdentityProfile()
+ * @see ValueProfile
+ */
+public abstract class FloatValueProfile extends Profile {
+
+ FloatValueProfile() {
+ }
+
+ public abstract float profile(float value);
+
+ /**
+ * Returns a value profile that profiles the exact value of a
+ * Specialized value profile to capture certain properties of
+ * Usage example:
+ *
+ *
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see #createIdentityProfile()
+ * @see ValueProfile
+ */
+public abstract class IntValueProfile extends Profile {
+
+ IntValueProfile() {
+ }
+
+ public abstract int profile(int value);
+
+ /**
+ * Returns a value profile that profiles the exact value of an
+ * Specialized value profile to capture certain properties of
+ * Usage example:
+ *
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see #createIdentityProfile()
+ * @see ValueProfile
+ */
+public abstract class LongValueProfile extends Profile {
+
+ LongValueProfile() {
+ }
+
+ public abstract long profile(long value);
+
+ /**
+ * Returns a value profile that profiles the exact value of an
+ * LoopConditionProfiles are designed to profile the outcome of loop conditions. Loop profiles can
+ * be used to profile unpredictable loops as well as predictable loops.
+ *
+ * Arbitrary loop usage example:
+ *
+ *
* @Specialization
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/BranchProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/BranchProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ *
+ * class SampleNode extends Node {
+ *
+ * final BranchProfile errorProfile = BranchProfile.create();
+ *
+ * void execute(int value) {
+ * if (value == Integer.MAX_VALUE) {
+ * errorProfile.enter();
+ * throw new Error("Invalid input value")
+ * }
+ * return value;
+ * }
+ * }
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see BranchProfile#enter()
+ */
+public abstract class BranchProfile extends Profile {
+
+ BranchProfile() {
+ }
+
+ /**
+ * Call when an unlikely branch is entered.
+ */
+ public abstract void enter();
+
+ /**
+ * @deprecated it is not reliable when profiling is turned off.
+ */
+ @Deprecated
+ public abstract boolean isVisited();
+
+ /**
+ * Call to create a new instance of a branch profile.
+ */
+ public static BranchProfile create() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Enabled.create0();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Enabled extends BranchProfile {
+
+ @CompilationFinal private boolean visited;
+
+ @Override
+ public void enter() {
+ if (!visited) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ visited = true;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public boolean isVisited() {
+ return visited;
+ }
+
+ @Override
+ public String toString() {
+ return toString(BranchProfile.class, !visited, false, "VISITED");
+ }
+
+ /* Needed for lazy class loading. */
+ static BranchProfile create0() {
+ return new Enabled();
+ }
+ }
+
+ static final class Disabled extends BranchProfile {
+
+ static final BranchProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public void enter() {
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public boolean isVisited() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(BranchProfile.class);
+ }
+
+ }
+
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/ByteValueProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/ByteValueProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ * byte
runtime values.
+ * Value profiles require a runtime check in their initialized state to verify their profiled
+ * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
+ * two or more values are profiled within a single profile then the profile has no effect. If the
+ * value assumption is invalidated in compiled code then it is invalidated.
+ *
+ * class SampleNode extends Node {
+ *
+ * final ByteValueProfile profile = ByteValueProfile.createIdentityProfile();
+ *
+ * byte execute(byte input) {
+ * byte profiledValue = profile.profile(input);
+ * // compiler may know now more about profiledValue
+ * return profiledValue;
+ * }
+ * }
+ *
+ * byte
.
+ *
+ * @see ByteValueProfile
+ */
+ public static ByteValueProfile createIdentityProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Enabled.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Enabled extends ByteValueProfile {
+
+ private static final byte UNINITIALIZED = 0;
+ private static final byte SPECIALIZED = 1;
+ private static final byte GENERIC = 2;
+
+ @CompilationFinal private byte cachedValue;
+ @CompilationFinal private byte state = 0;
+
+ @Override
+ public byte profile(byte value) {
+ byte localState = this.state;
+ if (localState != GENERIC) {
+ if (localState == SPECIALIZED) {
+ byte v = cachedValue;
+ if (v == value) {
+ return v;
+ }
+ }
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ if (localState == UNINITIALIZED) {
+ this.cachedValue = value;
+ this.state = SPECIALIZED;
+ } else {
+ this.state = GENERIC;
+ }
+ }
+ return value;
+ }
+
+ boolean isGeneric() {
+ return state == GENERIC;
+ }
+
+ boolean isUninitialized() {
+ return state == UNINITIALIZED;
+ }
+
+ byte getCachedValue() {
+ return cachedValue;
+ }
+
+ @Override
+ public String toString() {
+ return toString(ByteValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
+ String.format("value == (byte)%s", cachedValue));
+ }
+
+ /* Needed for lazy class loading. */
+ static ByteValueProfile create() {
+ return new Enabled();
+ }
+ }
+
+ static final class Disabled extends ByteValueProfile {
+
+ static final ByteValueProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public byte profile(byte value) {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(ByteValueProfile.class);
+ }
+
+ }
+
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/ConditionProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/ConditionProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ *
+ * class AbsoluteNode extends Node {
+ *
+ * final ConditionProfile greaterZeroProfile = ConditionProfile.create{Binary,Counting}Profile();
+ *
+ * void execute(int value) {
+ * if (greaterZeroProfile.profile(value >= 0)) {
+ * return value;
+ * } else {
+ * return -value;
+ * }
+ * }
+ * }
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see #createBinaryProfile()
+ * @see #createCountingProfile()
+ * @see LoopConditionProfile
+ */
+public abstract class ConditionProfile extends Profile {
+
+ ConditionProfile() {
+ }
+
+ public abstract boolean profile(boolean value);
+
+ /**
+ * Returns a {@link ConditionProfile} that speculates on conditions to be never
+ * true
or to be never false
. Additionally to a binary profile this
+ * method returns a condition profile that also counts the number of times the condition was
+ * true and false. This information is reported to the underlying optimization system using
+ * {@link CompilerDirectives#injectBranchProbability(double, boolean)}. Condition profiles are
+ * intended to be used as part of if conditions.
+ *
+ * @see ConditionProfile
+ * @see #createBinaryProfile()
+ */
+ public static ConditionProfile createCountingProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Counting.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ /**
+ * Returns a {@link ConditionProfile} that speculates on conditions to be never
+ * true
or to be never false
. Condition profiles are intended to be
+ * used as part of if conditions.
+ *
+ * @see ConditionProfile
+ * @see ConditionProfile#createCountingProfile()
+ */
+ public static ConditionProfile createBinaryProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Binary.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Disabled extends ConditionProfile {
+
+ static final ConditionProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public boolean profile(boolean value) {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(ConditionProfile.class);
+ }
+
+ }
+
+ static final class Counting extends ConditionProfile {
+
+ @CompilationFinal private int trueCount;
+ @CompilationFinal private int falseCount;
+
+ Counting() {
+ /* package protected constructor */
+ }
+
+ @Override
+ public boolean profile(boolean value) {
+ if (CompilerDirectives.inInterpreter()) {
+ if (value) {
+ // local required to guarantee no overflow in multi-threaded environments
+ int t = trueCount;
+ if (t < Integer.MAX_VALUE) {
+ trueCount = t + 1;
+ }
+ } else {
+ // local required to guarantee no overflow in multi-threaded environments
+ int f = falseCount;
+ if (f < Integer.MAX_VALUE) {
+ falseCount = f + 1;
+ }
+ }
+ // no branch probability calculation in the interpreter
+ return value;
+ } else {
+ // use trueCount and falseCount as locals for compilation speed
+ int t = trueCount;
+ int f = falseCount;
+ if (value) {
+ if (t == 0) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ t = 1;
+ }
+ } else {
+ if (f == 0) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ f = 1;
+ }
+ }
+ return CompilerDirectives.injectBranchProbability((double) t / (double) (t + f), value);
+ }
+ }
+
+ int getTrueCount() {
+ return trueCount;
+ }
+
+ int getFalseCount() {
+ return falseCount;
+ }
+
+ @Override
+ public String toString() {
+ int t = trueCount;
+ int f = falseCount;
+ return toString(ConditionProfile.class, trueCount == 0 && falseCount == 0, false, //
+ String.format("trueProbability=%s (trueCount=%s, falseCount=%s)", (double) t / (double) (t + f), t, f));
+ }
+
+ /* Needed for lazy class loading. */
+ static ConditionProfile create() {
+ return new Counting();
+ }
+ }
+
+ /**
+ * Utility class to speculate on conditions to be never true or to be never false. Condition
+ * profiles are intended to be used as part of if conditions.
+ *
+ * @see ConditionProfile#createBinaryProfile()
+ */
+ static final class Binary extends ConditionProfile {
+
+ @CompilationFinal private boolean wasTrue;
+ @CompilationFinal private boolean wasFalse;
+
+ Binary() {
+ /* package protected constructor */
+ }
+
+ @Override
+ public boolean profile(boolean value) {
+ if (value) {
+ if (!wasTrue) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ wasTrue = true;
+ }
+ return true;
+ } else {
+ if (!wasFalse) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ wasFalse = true;
+ }
+ return false;
+ }
+ }
+
+ boolean wasTrue() {
+ return wasTrue;
+ }
+
+ boolean wasFalse() {
+ return wasFalse;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s(wasTrue=%s, wasFalse=%s)@%x", getClass().getSimpleName(), wasTrue, wasFalse, hashCode());
+ }
+
+ /* Needed for lazy class loading. */
+ static ConditionProfile create() {
+ return new Binary();
+ }
+ }
+
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/DoubleValueProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/DoubleValueProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ * double
runtime values.
+ * Value profiles require a runtime check in their initialized state to verify their profiled
+ * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
+ * two or more values are profiled within a single profile then the profile has no effect. If the
+ * value assumption is invalidated in compiled code then it is invalidated.
+ *
+ * class SampleNode extends Node {
+ *
+ * final DoubleValueProfile profile = DoubleValueProfile.createRawIdentityProfile();
+ *
+ * double execute(double input) {
+ * double profiledValue = profile.profile(input);
+ * // compiler may know now more about profiledValue
+ * return profiledValue;
+ * }
+ * }
+ *
+ * double
using
+ * {@link Double#doubleToRawLongBits(double)}.
+ *
+ * @see IntValueProfile
+ */
+ public static DoubleValueProfile createRawIdentityProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Enabled.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Enabled extends DoubleValueProfile {
+
+ private static final byte UNINITIALIZED = 0;
+ private static final byte SPECIALIZED = 1;
+ private static final byte GENERIC = 2;
+
+ @CompilationFinal private double cachedValue;
+ @CompilationFinal private long cachedRawValue;
+ @CompilationFinal private byte state = 0;
+
+ @Override
+ public double profile(double value) {
+ byte localState = this.state;
+ if (localState != GENERIC) {
+ if (localState == SPECIALIZED) {
+ if (cachedRawValue == Double.doubleToRawLongBits(value)) {
+ return cachedValue;
+ }
+ }
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ if (localState == UNINITIALIZED) {
+ this.cachedValue = value;
+ this.cachedRawValue = Double.doubleToRawLongBits(value);
+ this.state = SPECIALIZED;
+ } else {
+ this.state = GENERIC;
+ }
+ }
+ return value;
+ }
+
+ boolean isGeneric() {
+ return state == GENERIC;
+ }
+
+ boolean isUninitialized() {
+ return state == UNINITIALIZED;
+ }
+
+ double getCachedValue() {
+ return cachedValue;
+ }
+
+ @Override
+ public String toString() {
+ return toString(DoubleValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
+ String.format("value == (double)%s (raw %h)", cachedValue, cachedRawValue));
+ }
+
+ /* Needed for lazy class loading. */
+ static DoubleValueProfile create() {
+ return new Enabled();
+ }
+ }
+
+ static final class Disabled extends DoubleValueProfile {
+
+ static final DoubleValueProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public double profile(double value) {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(DoubleValueProfile.class);
+ }
+
+ }
+
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/FloatValueProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/FloatValueProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ * float
runtime values.
+ * Value profiles require a runtime check in their initialized state to verify their profiled
+ * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
+ * two or more values are profiled within a single profile then the profile has no effect. If the
+ * value assumption is invalidated in compiled code then it is invalidated.
+ *
+ * class SampleNode extends Node {
+ *
+ * final FloatValueProfile profile = FloatValueProfile.createRawIdentityProfile();
+ *
+ * float execute(float input) {
+ * float profiledValue = profile.profile(input);
+ * // compiler may know now more about profiledValue
+ * return profiledValue;
+ * }
+ * }
+ *
+ * float
using
+ * {@link Float#floatToRawIntBits(float)}.
+ *
+ * @see IntValueProfile
+ */
+ public static FloatValueProfile createRawIdentityProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Enabled.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Enabled extends FloatValueProfile {
+
+ private static final byte UNINITIALIZED = 0;
+ private static final byte SPECIALIZED = 1;
+ private static final byte GENERIC = 2;
+
+ @CompilationFinal private float cachedValue;
+ @CompilationFinal private int cachedRawValue;
+ @CompilationFinal private byte state = 0;
+
+ @Override
+ public float profile(float value) {
+ byte localState = this.state;
+ if (localState != GENERIC) {
+ if (localState == SPECIALIZED) {
+ if (cachedRawValue == Float.floatToRawIntBits(value)) {
+ return cachedValue;
+ }
+ }
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ if (localState == UNINITIALIZED) {
+ this.cachedValue = value;
+ this.cachedRawValue = Float.floatToRawIntBits(value);
+ this.state = SPECIALIZED;
+ } else {
+ this.state = GENERIC;
+ }
+ }
+ return value;
+ }
+
+ boolean isGeneric() {
+ return state == GENERIC;
+ }
+
+ boolean isUninitialized() {
+ return state == UNINITIALIZED;
+ }
+
+ float getCachedValue() {
+ return cachedValue;
+ }
+
+ @Override
+ public String toString() {
+ return toString(FloatValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
+ String.format("value == (float)%s (raw %h)", cachedValue, cachedRawValue));
+ }
+
+ /* Needed for lazy class loading. */
+ static FloatValueProfile create() {
+ return new Enabled();
+ }
+ }
+
+ static final class Disabled extends FloatValueProfile {
+
+ static final FloatValueProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public float profile(float value) {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(FloatValueProfile.class);
+ }
+
+ }
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/IntValueProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/IntValueProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ * int
runtime values. Value
+ * profiles require a runtime check in their initialized state to verify their profiled assumption.
+ * Value profiles are limited to capture monomorphic profiles only. This means that if two or more
+ * values are profiled within a single profile then the profile has no effect. If the value
+ * assumption is invalidated in compiled code then it is invalidated.
+ *
+ * class SampleNode extends Node {
+ *
+ * final IntValueProfile profile = IntValueProfile.createIdentityProfile();
+ *
+ * int execute(int input) {
+ * int profiledValue = profile.profile(input);
+ * // compiler may know now more about profiledValue
+ * return profiledValue;
+ * }
+ * }
+ *
+ * int
.
+ *
+ * @see IntValueProfile
+ */
+ public static IntValueProfile createIdentityProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Enabled.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Enabled extends IntValueProfile {
+
+ private static final byte UNINITIALIZED = 0;
+ private static final byte SPECIALIZED = 1;
+ private static final byte GENERIC = 2;
+
+ @CompilationFinal private int cachedValue;
+ @CompilationFinal private byte state = 0;
+
+ @Override
+ public int profile(int value) {
+ byte localState = this.state;
+ if (localState != GENERIC) {
+ if (localState == SPECIALIZED) {
+ int v = cachedValue;
+ if (v == value) {
+ return v;
+ }
+ }
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ if (localState == UNINITIALIZED) {
+ this.cachedValue = value;
+ this.state = SPECIALIZED;
+ } else {
+ this.state = GENERIC;
+ }
+ }
+ return value;
+ }
+
+ boolean isGeneric() {
+ return state == GENERIC;
+ }
+
+ boolean isUninitialized() {
+ return state == UNINITIALIZED;
+ }
+
+ int getCachedValue() {
+ return cachedValue;
+ }
+
+ @Override
+ public String toString() {
+ return toString(IntValueProfile.class, isUninitialized(), isGeneric(), //
+ String.format("value == (int)%s", cachedValue));
+ }
+
+ /* Needed for lazy class loading. */
+ static IntValueProfile create() {
+ return new Enabled();
+ }
+ }
+
+ static final class Disabled extends IntValueProfile {
+
+ static final IntValueProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public int profile(int value) {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(IntValueProfile.class);
+ }
+
+ }
+
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/LongValueProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/LongValueProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ * long
runtime values.
+ * Value profiles require a runtime check in their initialized state to verify their profiled
+ * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
+ * two or more values are profiled within a single profile then the profile has no effect. If the
+ * value assumption is invalidated in compiled code then it is invalidated.
+ *
+ * class SampleNode extends Node {
+ *
+ * final LongValueProfile profile = LongValueProfile.createIdentityProfile();
+ *
+ * long execute(long input) {
+ * long profiledValue = profile.profile(input);
+ * // compiler may know now more about profiledValue
+ * return profiledValue;
+ * }
+ * }
+ *
+ * long
.
+ *
+ * @see LongValueProfile
+ */
+ public static LongValueProfile createIdentityProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Enabled.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Enabled extends LongValueProfile {
+
+ private static final byte UNINITIALIZED = 0;
+ private static final byte SPECIALIZED = 1;
+ private static final byte GENERIC = 2;
+
+ @CompilationFinal private long cachedValue;
+ @CompilationFinal private byte state = 0;
+
+ @Override
+ public long profile(long value) {
+ byte localState = this.state;
+ if (localState != GENERIC) {
+ if (localState == SPECIALIZED) {
+ long v = cachedValue;
+ if (v == value) {
+ return v;
+ }
+ }
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ if (localState == UNINITIALIZED) {
+ this.cachedValue = value;
+ this.state = SPECIALIZED;
+ } else {
+ this.state = GENERIC;
+ }
+ }
+ return value;
+ }
+
+ boolean isGeneric() {
+ return state == GENERIC;
+ }
+
+ boolean isUninitialized() {
+ return state == UNINITIALIZED;
+ }
+
+ long getCachedValue() {
+ return cachedValue;
+ }
+
+ @Override
+ public String toString() {
+ return toString(LongValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
+ String.format("value == (long)%s", cachedValue));
+ }
+
+ /* Needed for lazy class loading. */
+ static LongValueProfile create() {
+ return new Enabled();
+ }
+ }
+
+ static final class Disabled extends LongValueProfile {
+
+ static final LongValueProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public long profile(long value) {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(LongValueProfile.class);
+ }
+
+ }
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/LoopConditionProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/LoopConditionProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ *
+ * class LoopNode extends Node {
+ *
+ * final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile();
+ *
+ * void execute() {
+ * // loop count cannot be predicted
+ * while (loopProfile.profile(Math.random() >= 0.9)) {
+ * // work
+ * }
+ * }
+ * }
+ *
+ *
+ *
+ * Counted loop usage example: + * + *
+ * class CountedLoopNode extends Node { + * + * final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile(); + * + * void execute(int length) { + * // loop count can be predicted + * loopProfile.profileCounted(length); + * for (int i = 0; loopProfile.inject(i < length); i++) { + * // work + * } + * } + * } + *+ * + * + *
+ * The advantage of using {@link #profileCounted(long)} to using {@link #profile(boolean)} is that + * it incurs less overhead in the interpreter. Using {@link LoopConditionProfile#inject(boolean)} is + * a no-op in the interpreter while {@link #profile(boolean)} needs to use a counter for each + * iteration. + *
+ * + * + * {@inheritDoc} + * + * @see #createBinaryProfile() + * @see #createCountingProfile() + * @see LoopConditionProfile + */ +public abstract class LoopConditionProfile extends ConditionProfile { + + LoopConditionProfile() { + } + + @Override + public abstract boolean profile(boolean value); + + /** + * Provides an alternative way to profile counted loops with less interpreter footprint. Please + * see {@link LoopConditionProfile} for an usage example. + * + * @see #inject(boolean) + */ + public abstract void profileCounted(long length); + + /** + * Provides an alternative way to profile counted loops with less interpreter footprint. Please + * see {@link LoopConditionProfile} for an usage example. + * + * @see #inject(boolean) + */ + public abstract boolean inject(boolean condition); + + /** + * Returns a {@link LoopConditionProfile} that speculates on loop conditions to be never + *true
. It also captures loop probabilities for the compiler. Loop condition
+ * profiles are intended to be used for loop conditions.
+ *
+ * @see LoopConditionProfile
+ */
+ public static LoopConditionProfile createCountingProfile() {
+ if (Truffle.getRuntime().isProfilingEnabled()) {
+ return Enabled.create();
+ } else {
+ return Disabled.INSTANCE;
+ }
+ }
+
+ static final class Enabled extends LoopConditionProfile {
+
+ @CompilationFinal private long trueCount; // long for long running loops.
+ @CompilationFinal private int falseCount;
+
+ @Override
+ public boolean profile(boolean condition) {
+ if (CompilerDirectives.inInterpreter()) {
+ if (condition) {
+ // local required to guarantee no overflow in multi-threaded environments
+ long localTrueCount = trueCount;
+ if (localTrueCount < Long.MAX_VALUE) {
+ trueCount = localTrueCount + 1;
+ }
+ } else {
+ // local required to guarantee no overflow in multi-threaded environments
+ int localFalseCount = falseCount;
+ if (localFalseCount < Integer.MAX_VALUE) {
+ falseCount = localFalseCount + 1;
+ }
+ }
+ // no branch probability calculation in the interpreter
+ return condition;
+ } else {
+ long trueCountLocal = trueCount;
+ int falseCountLocal = falseCount;
+ if (trueCountLocal == 0) {
+ /* Deopt for never entering the loop. */
+ if (condition) {
+ CompilerDirectives.transferToInterpreterAndInvalidate();
+ trueCount = trueCountLocal = 1;
+ }
+ }
+ /* No deopt for not entering the loop. */
+ return CompilerDirectives.injectBranchProbability(calculateProbability(trueCountLocal, falseCountLocal), condition);
+ }
+ }
+
+ @Override
+ public void profileCounted(long length) {
+ if (CompilerDirectives.inInterpreter()) {
+ long trueCountLocal = trueCount + length;
+ if (trueCountLocal >= 0) { // don't write overflow values
+ trueCount = trueCountLocal;
+ int falseCountLocal = falseCount;
+ if (falseCountLocal < Integer.MAX_VALUE) {
+ falseCount = falseCountLocal + 1;
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean inject(boolean condition) {
+ if (CompilerDirectives.inCompiledCode()) {
+ return CompilerDirectives.injectBranchProbability(calculateProbability(trueCount, falseCount), condition);
+ } else {
+ return condition;
+ }
+ }
+
+ private static double calculateProbability(long trueCountLocal, int falseCountLocal) {
+ if (falseCountLocal == 0 && trueCountLocal == 0) {
+ /* Avoid division by zero if profile was never used. */
+ return 0.0;
+ } else {
+ return (double) trueCountLocal / (double) (trueCountLocal + falseCountLocal);
+ }
+ }
+
+ /* for testing */
+ long getTrueCount() {
+ return trueCount;
+ }
+
+ /* for testing */
+ int getFalseCount() {
+ return falseCount;
+ }
+
+ @Override
+ public String toString() {
+ return toString(LoopConditionProfile.class, falseCount == 0, false, //
+ String.format("trueProbability=%s (trueCount=%s, falseCount=%s)", calculateProbability(trueCount, falseCount), falseCount, trueCount));
+ }
+
+ /* Needed for lazy class loading. */
+ static LoopConditionProfile create() {
+ return new Enabled();
+ }
+
+ }
+
+ static final class Disabled extends LoopConditionProfile {
+
+ static final LoopConditionProfile INSTANCE = new Disabled();
+
+ @Override
+ protected Object clone() {
+ return INSTANCE;
+ }
+
+ @Override
+ public boolean profile(boolean condition) {
+ return condition;
+ }
+
+ @Override
+ public void profileCounted(long length) {
+ }
+
+ @Override
+ public boolean inject(boolean condition) {
+ return condition;
+ }
+
+ @Override
+ public String toString() {
+ return toStringDisabled(LoopConditionProfile.class);
+ }
+
+ }
+
+}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/PrimitiveValueProfile.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.profiles/src/com/oracle/truffle/api/profiles/PrimitiveValueProfile.java Thu Dec 17 10:01:38 2015 +0100
@@ -0,0 +1,427 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api.profiles;
+
+import java.util.Objects;
+
+import com.oracle.truffle.api.CompilerDirectives;
+import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
+import com.oracle.truffle.api.Truffle;
+
+/**
+ * + * Represents a {@link ValueProfile} that speculates on the primitive equality or object identity of + * values. Note that for {@code float} and {@code double} values we compare primitive equality via + * {@link Float#floatToRawIntBits} and {@link Double#doubleToRawLongBits}, so that for example + * {@code -0.0} is not considered the same as {@code 0.0}, even though primitive equality would + * normally say that it was. + *
+ * + * {@inheritDoc} + */ +public abstract class PrimitiveValueProfile extends ValueProfile { + + PrimitiveValueProfile() { + } + + @Override + public abstract+ * A profile is a Truffle utility class that uses the {@link CompilerDirectives Truffle compiler + * directives} to guard for and/or forward runtime information to the compiler. + *
+ * + *
+ * Usage: Profiles should be stored in final
or {@link CompilationFinal
+ * compilation final} fields of node classes to ensure that they can get optimized properly.
+ * Profiles must not be shared between ASTs. Using the same profile multiple times in a single
+ * {@link Node node} or in multiple {@link Node nodes} which {@link Node#getRootNode() link} to the
+ * same {@link RootNode root} is allowed. Never store profiles inside runtime values that
+ * leave the scope of the originating AST. This limitation exists because the used mechanism to
+ * invalidate compiled code performs local invalidations only. For global speculations use
+ * {@link Assumption assumptions} instead.
+ *
+ * Compilation: Some profiles like {@link BranchProfile branch} profiles do not induce + * additional overhead in compiled code. Others like {@link ValueProfile value} profiles might + * require a runtime check to verify their assumptions which are forwarded to the compiler. Even if + * profiles do not induce direct overhead in compiled code it still might get invalidated as a + * result of using profiles. Invalidating profiles will result in the invalidation of compiled code. + * It is therefore essential to place these profiles in way that is neither too aggressive nor too + * conservative. + *
+ * + *
+ * Footprint: Whether profiling information can be forwarded to the compiler depends on the
+ * capabilities of the {@link TruffleRuntime runtime system}. If the runtime returns
+ * true
in {@link TruffleRuntime#isProfilingEnabled()} then runtime information will
+ * get collected. This comes at at the cost of additional overhead and footprint in interpreted
+ * mode. Thats why the factory methods of profiles can return implementations where profiling is
+ * disabled. Using disabled profiles makes sense for runtimes that are unable to use the collected
+ * profiling information. Even runtime implementations that are able to use this information might
+ * decide to turn off profiling for benchmarking purposes.
+ *
+ * Profile subclasses: + *
byte
values.int
values.long
values.float
values.double
values.
+ * Specialized value profile to capture certain properties of Object
runtime values.
+ * Value profiles require a runtime check in their initialized state to verify their profiled
+ * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
+ * two or more identities or classes are profiles within a single profile then the profile has no
+ * effect and no overhead after compilation. There are specialized versions of this profile with
+ * less interpreter footprint for {@link ConditionProfile boolean}, {@link ByteValueProfile byte},
+ * {@link IntValueProfile int}, {@link LongValueProfile long}, {@link FloatValueProfile float} and
+ * {@link DoubleValueProfile double} values.
+ *
+ * Usage example: + * + *
+ * class SampleNode extends Node { + * + * final ValueProfile profile = ValueProfile.create{Identity,Class}Profile(); + * + * Object execute(Object input) { + * Object profiledValue = profile.profile(input); + * // compiler may know now more about profiledValue + * return profieldValue; + * } + * } + *+ *
+ *
+ *
+ * {@inheritDoc}
+ *
+ * @see #createIdentityProfile()
+ * @see #createClassProfile()
+ */
+public abstract class ValueProfile extends Profile {
+
+ ValueProfile() {
+ }
+
+ public abstract
+ * Returns a value profile that profiles the exact class of a value. It will check the class of
+ * the profiled value and provide additional information to the compiler if only non-null values
+ * of exactly one concrete Java class are passed as a parameter to the
+ * {@link ValueProfile#profile} method. This can be beneficial if subsequent code can take
+ * advantage of knowing the concrete class of the value. The profile will degrade to the generic
+ * case if a null value or if at least two instances of two different Java classes are
+ * registered.
+ *
+ * Compilation notes: Value profiles require a runtime check in their initialized state
+ * to verify their profiled class. If two classes have been seen on a single profile instance
+ * then this profile will transition to a generic state with no overhead.
+ *
+ * Returns a value profile that profiles the object identity of a value. A single instance can
+ * only profile one particular instance.
+ *
+ * Compilation notes: Identity profiles require a runtime check to verify their profiled
+ * object identity. If two identities have been seen on a single profile instance then this
+ * profile will transition to a generic state with no overhead.
+ *
+ * Returns a value profile that profiles the object equality of a value. A single instance can
+ * only profile one set of equal values.
+ *
+ * Compilation notes: Equality profiles inline the body of the equal method of the first
+ * profiled value in order to verify its assumption. Please take care that you do this only for
+ * equals implementations that your guest language actually has control over otherwise your
+ * compiled code might contain recursions or too much code. If two non equal objects have been
+ * seen on a single profile instance then this profile will transition to a generic state with
+ * no overhead.
+ *
- * BranchProfiles are profiles to speculate on branches that are unlikely to be visited. If the
- * {@link #enter()} method is invoked first the optimized code is invalidated and the branch where
- * {@link #enter()} is invoked is enabled for compilation. Otherwise if the {@link #enter()} method
- * was never invoked the branch will not get compiled.
- *
- * Usage example:
- *
- *
- * Specialized value profile to capture certain properties of
- * Usage example:
- *
- *
- *
- *
- * {@inheritDoc}
- *
- * @see #createIdentityProfile()
- * @see ValueProfile
- */
-public abstract class ByteValueProfile extends Profile {
-
- ByteValueProfile() {
- }
-
- public abstract byte profile(byte value);
-
- /**
- * Returns a value profile that profiles the exact value of a
- * ConditionProfiles are useful to profile the outcome of conditions.
- *
- * Usage example:
- *
- *
- * Specialized value profile to capture certain properties of
- * Usage example:
- *
- *
- *
- *
- * {@inheritDoc}
- *
- * @see #createRawIdentityProfile()
- * @see ValueProfile
- */
-public abstract class DoubleValueProfile extends Profile {
-
- DoubleValueProfile() {
- }
-
- public abstract double profile(double value);
-
- /**
- * Returns a value profile that profiles the exact value of a
- * Specialized value profile to capture certain properties of
- * Usage example:
- *
- *
- *
- *
- * {@inheritDoc}
- *
- * @see #createRawIdentityProfile()
- * @see ValueProfile
- */
-public abstract class FloatValueProfile extends Profile {
-
- FloatValueProfile() {
- }
-
- public abstract float profile(float value);
-
- /**
- * Returns a value profile that profiles the exact value of a
- * Specialized value profile to capture certain properties of
- * Usage example:
- *
- *
- *
- *
- * {@inheritDoc}
- *
- * @see #createIdentityProfile()
- * @see ValueProfile
- */
-public abstract class IntValueProfile extends Profile {
-
- IntValueProfile() {
- }
-
- public abstract int profile(int value);
-
- /**
- * Returns a value profile that profiles the exact value of an
- * Specialized value profile to capture certain properties of
- * Usage example:
- *
- *
- *
- * {@inheritDoc}
- *
- * @see #createIdentityProfile()
- * @see ValueProfile
- */
-public abstract class LongValueProfile extends Profile {
-
- LongValueProfile() {
- }
-
- public abstract long profile(long value);
-
- /**
- * Returns a value profile that profiles the exact value of an
- * LoopConditionProfiles are designed to profile the outcome of loop conditions. Loop profiles can
- * be used to profile unpredictable loops as well as predictable loops.
- *
- * Arbitrary loop usage example:
- *
- *
- * class SampleNode extends Node {
- *
- * final BranchProfile errorProfile = BranchProfile.create();
- *
- * void execute(int value) {
- * if (value == Integer.MAX_VALUE) {
- * errorProfile.enter();
- * throw new Error("Invalid input value")
- * }
- * return value;
- * }
- * }
- *
- *
- * {@inheritDoc}
- *
- * @see BranchProfile#enter()
- */
-public abstract class BranchProfile extends Profile {
-
- BranchProfile() {
- }
-
- /**
- * Call when an unlikely branch is entered.
- */
- public abstract void enter();
-
- /**
- * @deprecated it is not reliable when profiling is turned off.
- */
- @Deprecated
- public abstract boolean isVisited();
-
- /**
- * Call to create a new instance of a branch profile.
- */
- public static BranchProfile create() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Enabled.create0();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Enabled extends BranchProfile {
-
- @CompilationFinal private boolean visited;
-
- @Override
- public void enter() {
- if (!visited) {
- CompilerDirectives.transferToInterpreterAndInvalidate();
- visited = true;
- }
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public boolean isVisited() {
- return visited;
- }
-
- @Override
- public String toString() {
- return toString(BranchProfile.class, !visited, false, "VISITED");
- }
-
- /* Needed for lazy class loading. */
- static BranchProfile create0() {
- return new Enabled();
- }
- }
-
- static final class Disabled extends BranchProfile {
-
- static final BranchProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public void enter() {
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public boolean isVisited() {
- return true;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(BranchProfile.class);
- }
-
- }
-
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ByteValueProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ByteValueProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- * byte
runtime values.
- * Value profiles require a runtime check in their initialized state to verify their profiled
- * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
- * two or more values are profiled within a single profile then the profile has no effect. If the
- * value assumption is invalidated in compiled code then it is invalidated.
- *
- * class SampleNode extends Node {
- *
- * final ByteValueProfile profile = ByteValueProfile.createIdentityProfile();
- *
- * byte execute(byte input) {
- * byte profiledValue = profile.profile(input);
- * // compiler may know now more about profiledValue
- * return profiledValue;
- * }
- * }
- *
- * byte
.
- *
- * @see ByteValueProfile
- */
- public static ByteValueProfile createIdentityProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Enabled.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Enabled extends ByteValueProfile {
-
- private static final byte UNINITIALIZED = 0;
- private static final byte SPECIALIZED = 1;
- private static final byte GENERIC = 2;
-
- @CompilationFinal private byte cachedValue;
- @CompilationFinal private byte state = 0;
-
- @Override
- public byte profile(byte value) {
- byte localState = this.state;
- if (localState != GENERIC) {
- if (localState == SPECIALIZED) {
- byte v = cachedValue;
- if (v == value) {
- return v;
- }
- }
- CompilerDirectives.transferToInterpreterAndInvalidate();
- if (localState == UNINITIALIZED) {
- this.cachedValue = value;
- this.state = SPECIALIZED;
- } else {
- this.state = GENERIC;
- }
- }
- return value;
- }
-
- boolean isGeneric() {
- return state == GENERIC;
- }
-
- boolean isUninitialized() {
- return state == UNINITIALIZED;
- }
-
- byte getCachedValue() {
- return cachedValue;
- }
-
- @Override
- public String toString() {
- return toString(ByteValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
- String.format("value == (byte)%s", cachedValue));
- }
-
- /* Needed for lazy class loading. */
- static ByteValueProfile create() {
- return new Enabled();
- }
- }
-
- static final class Disabled extends ByteValueProfile {
-
- static final ByteValueProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public byte profile(byte value) {
- return value;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(ByteValueProfile.class);
- }
-
- }
-
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ConditionProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ConditionProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- *
- * class AbsoluteNode extends Node {
- *
- * final ConditionProfile greaterZeroProfile = ConditionProfile.create{Binary,Counting}Profile();
- *
- * void execute(int value) {
- * if (greaterZeroProfile.profile(value >= 0)) {
- * return value;
- * } else {
- * return -value;
- * }
- * }
- * }
- *
- *
- * {@inheritDoc}
- *
- * @see #createBinaryProfile()
- * @see #createCountingProfile()
- * @see LoopConditionProfile
- */
-public abstract class ConditionProfile extends Profile {
-
- ConditionProfile() {
- }
-
- public abstract boolean profile(boolean value);
-
- /**
- * Returns a {@link ConditionProfile} that speculates on conditions to be never
- * true
or to be never false
. Additionally to a binary profile this
- * method returns a condition profile that also counts the number of times the condition was
- * true and false. This information is reported to the underlying optimization system using
- * {@link CompilerDirectives#injectBranchProbability(double, boolean)}. Condition profiles are
- * intended to be used as part of if conditions.
- *
- * @see ConditionProfile
- * @see #createBinaryProfile()
- */
- public static ConditionProfile createCountingProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Counting.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- /**
- * Returns a {@link ConditionProfile} that speculates on conditions to be never
- * true
or to be never false
. Condition profiles are intended to be
- * used as part of if conditions.
- *
- * @see ConditionProfile
- * @see ConditionProfile#createCountingProfile()
- */
- public static ConditionProfile createBinaryProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Binary.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Disabled extends ConditionProfile {
-
- static final ConditionProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public boolean profile(boolean value) {
- return value;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(ConditionProfile.class);
- }
-
- }
-
- static final class Counting extends ConditionProfile {
-
- @CompilationFinal private int trueCount;
- @CompilationFinal private int falseCount;
-
- Counting() {
- /* package protected constructor */
- }
-
- @Override
- public boolean profile(boolean value) {
- if (CompilerDirectives.inInterpreter()) {
- if (value) {
- // local required to guarantee no overflow in multi-threaded environments
- int t = trueCount;
- if (t < Integer.MAX_VALUE) {
- trueCount = t + 1;
- }
- } else {
- // local required to guarantee no overflow in multi-threaded environments
- int f = falseCount;
- if (f < Integer.MAX_VALUE) {
- falseCount = f + 1;
- }
- }
- // no branch probability calculation in the interpreter
- return value;
- } else {
- // use trueCount and falseCount as locals for compilation speed
- int t = trueCount;
- int f = falseCount;
- if (value) {
- if (t == 0) {
- CompilerDirectives.transferToInterpreterAndInvalidate();
- t = 1;
- }
- } else {
- if (f == 0) {
- CompilerDirectives.transferToInterpreterAndInvalidate();
- f = 1;
- }
- }
- return CompilerDirectives.injectBranchProbability((double) t / (double) (t + f), value);
- }
- }
-
- int getTrueCount() {
- return trueCount;
- }
-
- int getFalseCount() {
- return falseCount;
- }
-
- @Override
- public String toString() {
- int t = trueCount;
- int f = falseCount;
- return toString(ConditionProfile.class, trueCount == 0 && falseCount == 0, false, //
- String.format("trueProbability=%s (trueCount=%s, falseCount=%s)", (double) t / (double) (t + f), t, f));
- }
-
- /* Needed for lazy class loading. */
- static ConditionProfile create() {
- return new Counting();
- }
- }
-
- /**
- * Utility class to speculate on conditions to be never true or to be never false. Condition
- * profiles are intended to be used as part of if conditions.
- *
- * @see ConditionProfile#createBinaryProfile()
- */
- static final class Binary extends ConditionProfile {
-
- @CompilationFinal private boolean wasTrue;
- @CompilationFinal private boolean wasFalse;
-
- Binary() {
- /* package protected constructor */
- }
-
- @Override
- public boolean profile(boolean value) {
- if (value) {
- if (!wasTrue) {
- CompilerDirectives.transferToInterpreterAndInvalidate();
- wasTrue = true;
- }
- return true;
- } else {
- if (!wasFalse) {
- CompilerDirectives.transferToInterpreterAndInvalidate();
- wasFalse = true;
- }
- return false;
- }
- }
-
- boolean wasTrue() {
- return wasTrue;
- }
-
- boolean wasFalse() {
- return wasFalse;
- }
-
- @Override
- public String toString() {
- return String.format("%s(wasTrue=%s, wasFalse=%s)@%x", getClass().getSimpleName(), wasTrue, wasFalse, hashCode());
- }
-
- /* Needed for lazy class loading. */
- static ConditionProfile create() {
- return new Binary();
- }
- }
-
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/DoubleValueProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/DoubleValueProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- * double
runtime values.
- * Value profiles require a runtime check in their initialized state to verify their profiled
- * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
- * two or more values are profiled within a single profile then the profile has no effect. If the
- * value assumption is invalidated in compiled code then it is invalidated.
- *
- * class SampleNode extends Node {
- *
- * final DoubleValueProfile profile = DoubleValueProfile.createRawIdentityProfile();
- *
- * double execute(double input) {
- * double profiledValue = profile.profile(input);
- * // compiler may know now more about profiledValue
- * return profiledValue;
- * }
- * }
- *
- * double
using
- * {@link Double#doubleToRawLongBits(double)}.
- *
- * @see IntValueProfile
- */
- public static DoubleValueProfile createRawIdentityProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Enabled.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Enabled extends DoubleValueProfile {
-
- private static final byte UNINITIALIZED = 0;
- private static final byte SPECIALIZED = 1;
- private static final byte GENERIC = 2;
-
- @CompilationFinal private double cachedValue;
- @CompilationFinal private long cachedRawValue;
- @CompilationFinal private byte state = 0;
-
- @Override
- public double profile(double value) {
- byte localState = this.state;
- if (localState != GENERIC) {
- if (localState == SPECIALIZED) {
- if (cachedRawValue == Double.doubleToRawLongBits(value)) {
- return cachedValue;
- }
- }
- CompilerDirectives.transferToInterpreterAndInvalidate();
- if (localState == UNINITIALIZED) {
- this.cachedValue = value;
- this.cachedRawValue = Double.doubleToRawLongBits(value);
- this.state = SPECIALIZED;
- } else {
- this.state = GENERIC;
- }
- }
- return value;
- }
-
- boolean isGeneric() {
- return state == GENERIC;
- }
-
- boolean isUninitialized() {
- return state == UNINITIALIZED;
- }
-
- double getCachedValue() {
- return cachedValue;
- }
-
- @Override
- public String toString() {
- return toString(DoubleValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
- String.format("value == (double)%s (raw %h)", cachedValue, cachedRawValue));
- }
-
- /* Needed for lazy class loading. */
- static DoubleValueProfile create() {
- return new Enabled();
- }
- }
-
- static final class Disabled extends DoubleValueProfile {
-
- static final DoubleValueProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public double profile(double value) {
- return value;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(DoubleValueProfile.class);
- }
-
- }
-
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/FloatValueProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/FloatValueProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- * float
runtime values.
- * Value profiles require a runtime check in their initialized state to verify their profiled
- * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
- * two or more values are profiled within a single profile then the profile has no effect. If the
- * value assumption is invalidated in compiled code then it is invalidated.
- *
- * class SampleNode extends Node {
- *
- * final FloatValueProfile profile = FloatValueProfile.createRawIdentityProfile();
- *
- * float execute(float input) {
- * float profiledValue = profile.profile(input);
- * // compiler may know now more about profiledValue
- * return profiledValue;
- * }
- * }
- *
- * float
using
- * {@link Float#floatToRawIntBits(float)}.
- *
- * @see IntValueProfile
- */
- public static FloatValueProfile createRawIdentityProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Enabled.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Enabled extends FloatValueProfile {
-
- private static final byte UNINITIALIZED = 0;
- private static final byte SPECIALIZED = 1;
- private static final byte GENERIC = 2;
-
- @CompilationFinal private float cachedValue;
- @CompilationFinal private int cachedRawValue;
- @CompilationFinal private byte state = 0;
-
- @Override
- public float profile(float value) {
- byte localState = this.state;
- if (localState != GENERIC) {
- if (localState == SPECIALIZED) {
- if (cachedRawValue == Float.floatToRawIntBits(value)) {
- return cachedValue;
- }
- }
- CompilerDirectives.transferToInterpreterAndInvalidate();
- if (localState == UNINITIALIZED) {
- this.cachedValue = value;
- this.cachedRawValue = Float.floatToRawIntBits(value);
- this.state = SPECIALIZED;
- } else {
- this.state = GENERIC;
- }
- }
- return value;
- }
-
- boolean isGeneric() {
- return state == GENERIC;
- }
-
- boolean isUninitialized() {
- return state == UNINITIALIZED;
- }
-
- float getCachedValue() {
- return cachedValue;
- }
-
- @Override
- public String toString() {
- return toString(FloatValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
- String.format("value == (float)%s (raw %h)", cachedValue, cachedRawValue));
- }
-
- /* Needed for lazy class loading. */
- static FloatValueProfile create() {
- return new Enabled();
- }
- }
-
- static final class Disabled extends FloatValueProfile {
-
- static final FloatValueProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public float profile(float value) {
- return value;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(FloatValueProfile.class);
- }
-
- }
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/IntValueProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/IntValueProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- * int
runtime values. Value
- * profiles require a runtime check in their initialized state to verify their profiled assumption.
- * Value profiles are limited to capture monomorphic profiles only. This means that if two or more
- * values are profiled within a single profile then the profile has no effect. If the value
- * assumption is invalidated in compiled code then it is invalidated.
- *
- * class SampleNode extends Node {
- *
- * final IntValueProfile profile = IntValueProfile.createIdentityProfile();
- *
- * int execute(int input) {
- * int profiledValue = profile.profile(input);
- * // compiler may know now more about profiledValue
- * return profiledValue;
- * }
- * }
- *
- * int
.
- *
- * @see IntValueProfile
- */
- public static IntValueProfile createIdentityProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Enabled.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Enabled extends IntValueProfile {
-
- private static final byte UNINITIALIZED = 0;
- private static final byte SPECIALIZED = 1;
- private static final byte GENERIC = 2;
-
- @CompilationFinal private int cachedValue;
- @CompilationFinal private byte state = 0;
-
- @Override
- public int profile(int value) {
- byte localState = this.state;
- if (localState != GENERIC) {
- if (localState == SPECIALIZED) {
- int v = cachedValue;
- if (v == value) {
- return v;
- }
- }
- CompilerDirectives.transferToInterpreterAndInvalidate();
- if (localState == UNINITIALIZED) {
- this.cachedValue = value;
- this.state = SPECIALIZED;
- } else {
- this.state = GENERIC;
- }
- }
- return value;
- }
-
- boolean isGeneric() {
- return state == GENERIC;
- }
-
- boolean isUninitialized() {
- return state == UNINITIALIZED;
- }
-
- int getCachedValue() {
- return cachedValue;
- }
-
- @Override
- public String toString() {
- return toString(IntValueProfile.class, isUninitialized(), isGeneric(), //
- String.format("value == (int)%s", cachedValue));
- }
-
- /* Needed for lazy class loading. */
- static IntValueProfile create() {
- return new Enabled();
- }
- }
-
- static final class Disabled extends IntValueProfile {
-
- static final IntValueProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public int profile(int value) {
- return value;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(IntValueProfile.class);
- }
-
- }
-
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LongValueProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LongValueProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- * long
runtime values.
- * Value profiles require a runtime check in their initialized state to verify their profiled
- * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
- * two or more values are profiled within a single profile then the profile has no effect. If the
- * value assumption is invalidated in compiled code then it is invalidated.
- *
- * class SampleNode extends Node {
- *
- * final LongValueProfile profile = LongValueProfile.createIdentityProfile();
- *
- * long execute(long input) {
- * long profiledValue = profile.profile(input);
- * // compiler may know now more about profiledValue
- * return profiledValue;
- * }
- * }
- *
- * long
.
- *
- * @see LongValueProfile
- */
- public static LongValueProfile createIdentityProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Enabled.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Enabled extends LongValueProfile {
-
- private static final byte UNINITIALIZED = 0;
- private static final byte SPECIALIZED = 1;
- private static final byte GENERIC = 2;
-
- @CompilationFinal private long cachedValue;
- @CompilationFinal private byte state = 0;
-
- @Override
- public long profile(long value) {
- byte localState = this.state;
- if (localState != GENERIC) {
- if (localState == SPECIALIZED) {
- long v = cachedValue;
- if (v == value) {
- return v;
- }
- }
- CompilerDirectives.transferToInterpreterAndInvalidate();
- if (localState == UNINITIALIZED) {
- this.cachedValue = value;
- this.state = SPECIALIZED;
- } else {
- this.state = GENERIC;
- }
- }
- return value;
- }
-
- boolean isGeneric() {
- return state == GENERIC;
- }
-
- boolean isUninitialized() {
- return state == UNINITIALIZED;
- }
-
- long getCachedValue() {
- return cachedValue;
- }
-
- @Override
- public String toString() {
- return toString(LongValueProfile.class, state == UNINITIALIZED, state == GENERIC, //
- String.format("value == (long)%s", cachedValue));
- }
-
- /* Needed for lazy class loading. */
- static LongValueProfile create() {
- return new Enabled();
- }
- }
-
- static final class Disabled extends LongValueProfile {
-
- static final LongValueProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public long profile(long value) {
- return value;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(LongValueProfile.class);
- }
-
- }
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LoopConditionProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LoopConditionProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- *
- * class LoopNode extends Node {
- *
- * final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile();
- *
- * void execute() {
- * // loop count cannot be predicted
- * while (loopProfile.profile(Math.random() >= 0.9)) {
- * // work
- * }
- * }
- * }
- *
- *
- *
- * Counted loop usage example: - * - *
- * class CountedLoopNode extends Node { - * - * final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile(); - * - * void execute(int length) { - * // loop count can be predicted - * loopProfile.profileCounted(length); - * for (int i = 0; loopProfile.inject(i < length); i++) { - * // work - * } - * } - * } - *- * - * - *
- * The advantage of using {@link #profileCounted(long)} to using {@link #profile(boolean)} is that - * it incurs less overhead in the interpreter. Using {@link LoopConditionProfile#inject(boolean)} is - * a no-op in the interpreter while {@link #profile(boolean)} needs to use a counter for each - * iteration. - *
- * - * - * {@inheritDoc} - * - * @see #createBinaryProfile() - * @see #createCountingProfile() - * @see LoopConditionProfile - */ -public abstract class LoopConditionProfile extends ConditionProfile { - - LoopConditionProfile() { - } - - @Override - public abstract boolean profile(boolean value); - - /** - * Provides an alternative way to profile counted loops with less interpreter footprint. Please - * see {@link LoopConditionProfile} for an usage example. - * - * @see #inject(boolean) - */ - public abstract void profileCounted(long length); - - /** - * Provides an alternative way to profile counted loops with less interpreter footprint. Please - * see {@link LoopConditionProfile} for an usage example. - * - * @see #inject(boolean) - */ - public abstract boolean inject(boolean condition); - - /** - * Returns a {@link LoopConditionProfile} that speculates on loop conditions to be never - *true
. It also captures loop probabilities for the compiler. Loop condition
- * profiles are intended to be used for loop conditions.
- *
- * @see LoopConditionProfile
- */
- public static LoopConditionProfile createCountingProfile() {
- if (Truffle.getRuntime().isProfilingEnabled()) {
- return Enabled.create();
- } else {
- return Disabled.INSTANCE;
- }
- }
-
- static final class Enabled extends LoopConditionProfile {
-
- @CompilationFinal private long trueCount; // long for long running loops.
- @CompilationFinal private int falseCount;
-
- @Override
- public boolean profile(boolean condition) {
- if (CompilerDirectives.inInterpreter()) {
- if (condition) {
- // local required to guarantee no overflow in multi-threaded environments
- long localTrueCount = trueCount;
- if (localTrueCount < Long.MAX_VALUE) {
- trueCount = localTrueCount + 1;
- }
- } else {
- // local required to guarantee no overflow in multi-threaded environments
- int localFalseCount = falseCount;
- if (localFalseCount < Integer.MAX_VALUE) {
- falseCount = localFalseCount + 1;
- }
- }
- // no branch probability calculation in the interpreter
- return condition;
- } else {
- long trueCountLocal = trueCount;
- int falseCountLocal = falseCount;
- if (trueCountLocal == 0) {
- /* Deopt for never entering the loop. */
- if (condition) {
- CompilerDirectives.transferToInterpreterAndInvalidate();
- trueCount = trueCountLocal = 1;
- }
- }
- /* No deopt for not entering the loop. */
- return CompilerDirectives.injectBranchProbability(calculateProbability(trueCountLocal, falseCountLocal), condition);
- }
- }
-
- @Override
- public void profileCounted(long length) {
- if (CompilerDirectives.inInterpreter()) {
- long trueCountLocal = trueCount + length;
- if (trueCountLocal >= 0) { // don't write overflow values
- trueCount = trueCountLocal;
- int falseCountLocal = falseCount;
- if (falseCountLocal < Integer.MAX_VALUE) {
- falseCount = falseCountLocal + 1;
- }
- }
- }
- }
-
- @Override
- public boolean inject(boolean condition) {
- if (CompilerDirectives.inCompiledCode()) {
- return CompilerDirectives.injectBranchProbability(calculateProbability(trueCount, falseCount), condition);
- } else {
- return condition;
- }
- }
-
- private static double calculateProbability(long trueCountLocal, int falseCountLocal) {
- if (falseCountLocal == 0 && trueCountLocal == 0) {
- /* Avoid division by zero if profile was never used. */
- return 0.0;
- } else {
- return (double) trueCountLocal / (double) (trueCountLocal + falseCountLocal);
- }
- }
-
- /* for testing */
- long getTrueCount() {
- return trueCount;
- }
-
- /* for testing */
- int getFalseCount() {
- return falseCount;
- }
-
- @Override
- public String toString() {
- return toString(LoopConditionProfile.class, falseCount == 0, false, //
- String.format("trueProbability=%s (trueCount=%s, falseCount=%s)", calculateProbability(trueCount, falseCount), falseCount, trueCount));
- }
-
- /* Needed for lazy class loading. */
- static LoopConditionProfile create() {
- return new Enabled();
- }
-
- }
-
- static final class Disabled extends LoopConditionProfile {
-
- static final LoopConditionProfile INSTANCE = new Disabled();
-
- @Override
- protected Object clone() {
- return INSTANCE;
- }
-
- @Override
- public boolean profile(boolean condition) {
- return condition;
- }
-
- @Override
- public void profileCounted(long length) {
- }
-
- @Override
- public boolean inject(boolean condition) {
- return condition;
- }
-
- @Override
- public String toString() {
- return toStringDisabled(LoopConditionProfile.class);
- }
-
- }
-
-}
diff -r d2b4fe945c23 -r 828c67903db2 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/PrimitiveValueProfile.java
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/PrimitiveValueProfile.java Wed Dec 16 15:32:23 2015 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,427 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.truffle.api.profiles;
-
-import java.util.Objects;
-
-import com.oracle.truffle.api.CompilerDirectives;
-import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
-import com.oracle.truffle.api.Truffle;
-
-/**
- * - * Represents a {@link ValueProfile} that speculates on the primitive equality or object identity of - * values. Note that for {@code float} and {@code double} values we compare primitive equality via - * {@link Float#floatToRawIntBits} and {@link Double#doubleToRawLongBits}, so that for example - * {@code -0.0} is not considered the same as {@code 0.0}, even though primitive equality would - * normally say that it was. - *
- * - * {@inheritDoc} - */ -public abstract class PrimitiveValueProfile extends ValueProfile { - - PrimitiveValueProfile() { - } - - @Override - public abstract- * A profile is a Truffle utility class that uses the {@link CompilerDirectives Truffle compiler - * directives} to guard for and/or forward runtime information to the compiler. - *
- * - *
- * Usage: Profiles should be stored in final
or {@link CompilationFinal
- * compilation final} fields of node classes to ensure that they can get optimized properly.
- * Profiles must not be shared between ASTs. Using the same profile multiple times in a single
- * {@link Node node} or in multiple {@link Node nodes} which {@link Node#getRootNode() link} to the
- * same {@link RootNode root} is allowed. Never store profiles inside runtime values that
- * leave the scope of the originating AST. This limitation exists because the used mechanism to
- * invalidate compiled code performs local invalidations only. For global speculations use
- * {@link Assumption assumptions} instead.
- *
- * Compilation: Some profiles like {@link BranchProfile branch} profiles do not induce - * additional overhead in compiled code. Others like {@link ValueProfile value} profiles might - * require a runtime check to verify their assumptions which are forwarded to the compiler. Even if - * profiles do not induce direct overhead in compiled code it still might get invalidated as a - * result of using profiles. Invalidating profiles will result in the invalidation of compiled code. - * It is therefore essential to place these profiles in way that is neither too aggressive nor too - * conservative. - *
- * - *
- * Footprint: Whether profiling information can be forwarded to the compiler depends on the
- * capabilities of the {@link TruffleRuntime runtime system}. If the runtime returns
- * true
in {@link TruffleRuntime#isProfilingEnabled()} then runtime information will
- * get collected. This comes at at the cost of additional overhead and footprint in interpreted
- * mode. Thats why the factory methods of profiles can return implementations where profiling is
- * disabled. Using disabled profiles makes sense for runtimes that are unable to use the collected
- * profiling information. Even runtime implementations that are able to use this information might
- * decide to turn off profiling for benchmarking purposes.
- *
- * Profile subclasses: - *
byte
values.int
values.long
values.float
values.double
values.
- * Specialized value profile to capture certain properties of Object
runtime values.
- * Value profiles require a runtime check in their initialized state to verify their profiled
- * assumption. Value profiles are limited to capture monomorphic profiles only. This means that if
- * two or more identities or classes are profiles within a single profile then the profile has no
- * effect and no overhead after compilation. There are specialized versions of this profile with
- * less interpreter footprint for {@link ConditionProfile boolean}, {@link ByteValueProfile byte},
- * {@link IntValueProfile int}, {@link LongValueProfile long}, {@link FloatValueProfile float} and
- * {@link DoubleValueProfile double} values.
- *
- * Usage example: - * - *
- * class SampleNode extends Node { - * - * final ValueProfile profile = ValueProfile.create{Identity,Class}Profile(); - * - * Object execute(Object input) { - * Object profiledValue = profile.profile(input); - * // compiler may know now more about profiledValue - * return profieldValue; - * } - * } - *- *
- *
- *
- * {@inheritDoc}
- *
- * @see #createIdentityProfile()
- * @see #createClassProfile()
- */
-public abstract class ValueProfile extends Profile {
-
- ValueProfile() {
- }
-
- public abstract
- * Returns a value profile that profiles the exact class of a value. It will check the class of
- * the profiled value and provide additional information to the compiler if only non-null values
- * of exactly one concrete Java class are passed as a parameter to the
- * {@link ValueProfile#profile} method. This can be beneficial if subsequent code can take
- * advantage of knowing the concrete class of the value. The profile will degrade to the generic
- * case if a null value or if at least two instances of two different Java classes are
- * registered.
- *
- * Compilation notes: Value profiles require a runtime check in their initialized state
- * to verify their profiled class. If two classes have been seen on a single profile instance
- * then this profile will transition to a generic state with no overhead.
- *
- * Returns a value profile that profiles the object identity of a value. A single instance can
- * only profile one particular instance.
- *
- * Compilation notes: Identity profiles require a runtime check to verify their profiled
- * object identity. If two identities have been seen on a single profile instance then this
- * profile will transition to a generic state with no overhead.
- *
- * Returns a value profile that profiles the object equality of a value. A single instance can
- * only profile one set of equal values.
- *
- * Compilation notes: Equality profiles inline the body of the equal method of the first
- * profiled value in order to verify its assumption. Please take care that you do this only for
- * equals implementations that your guest language actually has control over otherwise your
- * compiled code might contain recursions or too much code. If two non equal objects have been
- * seen on a single profile instance then this profile will transition to a generic state with
- * no overhead.
- *