# HG changeset patch # User Christian Humer # Date 1450280293 -3600 # Node ID a63bda98cfdb007bed595e776dff9081b3c0162a # Parent fbe1eb7b4172d4ac7fb1f315b78e34ffab458da1 Extract profiles into separate package. Add isProfilingEnabled in TruffleRuntime to disable profiling in the default runtime; Add low overhead profiles for primitives; Add LoopConditionProfile; Profile footprint/threadsafety improvements; Make toString implementations more consistent; Greatly enhanced javadoc documentation for profiles; Deprecate old profiles diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Cached.java --- a/truffle/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Cached.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Cached.java Wed Dec 16 16:38:13 2015 +0100 @@ -26,7 +26,8 @@ import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.utilities.BranchProfile; +import com.oracle.truffle.api.profiles.BranchProfile; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/BinaryConditionProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/BinaryConditionProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.profiles; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class BinaryConditionProfileTest { + + @DataPoints public static boolean[] data = new boolean[]{true, false}; + + private ConditionProfile.Binary profile; + + @Before + public void create() { + profile = (ConditionProfile.Binary) ConditionProfile.Binary.create(); + } + + @Test + public void testInitial() { + assertThat(profile.wasTrue(), is(false)); + assertThat(profile.wasFalse(), is(false)); + profile.toString(); + } + + @Theory + public void testProfileOne(boolean value) { + boolean result = profile.profile(value); + + assertThat(result, is(value)); + assertThat(profile.wasTrue(), is(value)); + assertThat(profile.wasFalse(), is(!value)); + profile.toString(); + } + + @Theory + public void testProfileTwo(boolean value0, boolean value1) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(profile.wasTrue(), is(value0 || value1)); + assertThat(profile.wasFalse(), is(!value0 || !value1)); + profile.toString(); + } + + @Theory + public void testProfileThree(boolean value0, boolean value1, boolean value2) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + boolean result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + assertThat(profile.wasTrue(), is(value0 || value1 || value2)); + assertThat(profile.wasFalse(), is(!value0 || !value1 || !value2)); + profile.toString(); + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/BranchProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/BranchProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.profiles; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class BranchProfileTest { + + @Test + public void testEnter() { + BranchProfile profile = BranchProfile.Enabled.create0(); + profile.enter(); + profile.enter(); + } + + @Test + public void testToString() { + BranchProfile profile = BranchProfile.Enabled.create0(); + assertTrue(profile.toString().contains(BranchProfile.class.getSimpleName())); + assertTrue(profile.toString().contains("UNINITIALIZED")); + assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); + profile.enter(); + assertTrue(profile.toString().contains(BranchProfile.class.getSimpleName())); + assertTrue(profile.toString().contains("VISITED")); + assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/ByteValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/ByteValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,116 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class ByteValueProfileTest { + + @DataPoint public static final byte VALUE0 = Byte.MIN_VALUE; + @DataPoint public static final byte VALUE1 = 0; + @DataPoint public static final byte VALUE2 = 14; + @DataPoint public static final byte VALUE3 = Byte.MAX_VALUE; + + private ByteValueProfile.Enabled profile; + + @Before + public void create() { + profile = (ByteValueProfile.Enabled) ByteValueProfile.Enabled.create(); + } + + @Test + public void testInitial() { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneObject(byte value) { + byte result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoObject(byte value0, byte value1) { + byte result0 = profile.profile(value0); + byte result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + if (value0 == value1) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeObject(byte value0, byte value1, byte value2) { + byte result0 = profile.profile(value0); + byte result1 = profile.profile(value1); + byte result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + if (value0 == value1 && value1 == value2) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Test + public void testDisabled() { + ByteValueProfile.Disabled p = (ByteValueProfile.Disabled) ByteValueProfile.Disabled.INSTANCE; + assertThat(p.profile(VALUE0), is(VALUE0)); + assertThat(p.profile(VALUE1), is(VALUE1)); + assertThat(p.profile(VALUE2), is(VALUE2)); + assertThat(p.profile(VALUE3), is(VALUE3)); + p.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/CountingConditionProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/CountingConditionProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.profiles; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class CountingConditionProfileTest { + + @DataPoints public static boolean[] data = new boolean[]{true, false}; + + private ConditionProfile.Counting profile; + + @Before + public void create() { + profile = (ConditionProfile.Counting) ConditionProfile.Counting.create(); + } + + @Test + public void testInitial() { + assertThat(profile.getTrueCount(), is(0)); + assertThat(profile.getFalseCount(), is(0)); + profile.toString(); + } + + @Theory + public void testProfileOne(boolean value) { + boolean result = profile.profile(value); + + assertThat(result, is(value)); + assertThat(profile.getTrueCount(), is(value ? 1 : 0)); + assertThat(profile.getFalseCount(), is(!value ? 1 : 0)); + profile.toString(); + } + + @Theory + public void testProfileTwo(boolean value0, boolean value1) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0))); + assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0))); + profile.toString(); + } + + @Theory + public void testProfileThree(boolean value0, boolean value1, boolean value2) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + boolean result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0) + (value2 ? 1 : 0))); + assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0) + (!value2 ? 1 : 0))); + profile.toString(); + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/DoubleValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/DoubleValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,122 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class DoubleValueProfileTest { + + @DataPoint public static final double VALUE0 = Double.MIN_VALUE; + @DataPoint public static final double VALUE1 = -0.0f; + @DataPoint public static final double VALUE2 = +0.0f; + @DataPoint public static final double VALUE3 = 14.5f; + @DataPoint public static final double VALUE4 = Double.MAX_VALUE; + + private static final double FLOAT_DELTA = 0.00001f; + + private DoubleValueProfile.Enabled profile; + + @Before + public void create() { + profile = (DoubleValueProfile.Enabled) DoubleValueProfile.Enabled.create(); + } + + @Test + public void testInitial() { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneFloat(double value) { + double result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value, FLOAT_DELTA); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @SuppressWarnings("deprecation") + @Theory + public void testProfileTwoFloat(double value0, double value1) { + double result0 = profile.profile(value0); + double result1 = profile.profile(value1); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1)) { + assertEquals(profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @SuppressWarnings("deprecation") + @Theory + public void testProfileThreeFloat(double value0, double value1, double value2) { + double result0 = profile.profile(value0); + double result1 = profile.profile(value1); + double result2 = profile.profile(value2); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + assertEquals(result2, value2, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { + assertEquals(profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Test + public void testDisabled() { + DoubleValueProfile.Disabled p = (DoubleValueProfile.Disabled) DoubleValueProfile.Disabled.INSTANCE; + assertThat(p.profile(VALUE0), is(VALUE0)); + assertThat(p.profile(VALUE1), is(VALUE1)); + assertThat(p.profile(VALUE2), is(VALUE2)); + assertThat(p.profile(VALUE3), is(VALUE3)); + assertThat(p.profile(VALUE4), is(VALUE4)); + p.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/EqualityValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/EqualityValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,114 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class EqualityValueProfileTest { + + @DataPoint public static final String O1 = new String(); + @DataPoint public static final String O2 = O1; + @DataPoint public static final Object O3 = new Object(); + @DataPoint public static final Integer O4 = new Integer(1); + @DataPoint public static final Integer O5 = new Integer(1); + @DataPoint public static final Integer O6 = null; + + private ValueProfile.Equality profile; + + @Before + public void create() { + profile = (ValueProfile.Equality) ValueProfile.Equality.create(); + } + + @Test + public void testInitial() throws Exception { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOne(Object value) throws Exception { + Object result = profile.profile(value); + assertThat(result, is(equalTo(value))); + if (value == null) { + assertThat(profile.isUninitialized(), is(false)); + assertThat(profile.isGeneric(), is(true)); + } else { + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + assertThat(profile.isGeneric(), is(false)); + } + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwo(Object value0, Object value1) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertThat(result0, is(equalTo(value0))); + assertThat(result1, is(equalTo(value1))); + + if (value0 != null && value0.equals(value1)) { + assertThat(profile.getCachedValue(), is(equalTo(value0))); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + Object result2 = profile.profile(value2); + + assertThat(result0, is(equalTo(value0))); + assertThat(result1, is(equalTo(value1))); + assertThat(result2, is(equalTo(value2))); + + if (value0 != null && value0.equals(value1) && value1 != null && value1.equals(value2)) { + assertThat(profile.getCachedValue(), is(equalTo(value0))); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/ExactClassValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/ExactClassValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.profiles; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class ExactClassValueProfileTest { + + @DataPoint public static final String O1 = new String(); + @DataPoint public static final String O2 = new String(); + @DataPoint public static final Object O3 = new Object(); + @DataPoint public static final Integer O4 = new Integer(1); + @DataPoint public static final Integer O5 = null; + @DataPoint public static final TestBaseClass O6 = new TestBaseClass(); + @DataPoint public static final TestSubClass O7 = new TestSubClass(); + + private ValueProfile.ExactClass profile; + + private static class TestBaseClass { + } + + private static class TestSubClass extends TestBaseClass { + } + + @Before + public void create() { + profile = (ValueProfile.ExactClass) ValueProfile.ExactClass.create(); + } + + @Test + public void testInitial() throws Exception { + assertThat(isGeneric(profile), is(false)); + assertThat(isUninitialized(profile), is(true)); + assertNull(getCachedClass(profile)); + assertNotNull(profile.toString()); + } + + @Theory + public void testProfileOne(Object value) throws Exception { + Object result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(expectedClass(value), getCachedClass(profile)); + assertThat(isUninitialized(profile), is(false)); + assertNotNull(profile.toString()); + } + + @Theory + public void testProfileTwo(Object value0, Object value1) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + Object expectedClass = expectedClass(value0) == expectedClass(value1) ? expectedClass(value0) : Object.class; + + assertEquals(expectedClass, getCachedClass(profile)); + assertThat(isUninitialized(profile), is(false)); + assertThat(isGeneric(profile), is(expectedClass == Object.class)); + assertNotNull(profile.toString()); + } + + @Theory + public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + Object result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + Object expectedClass = expectedClass(value0) == expectedClass(value1) && expectedClass(value1) == expectedClass(value2) ? expectedClass(value0) : Object.class; + + assertEquals(expectedClass, getCachedClass(profile)); + assertThat(isUninitialized(profile), is(false)); + assertThat(isGeneric(profile), is(expectedClass == Object.class)); + assertNotNull(profile.toString()); + } + + private static Class expectedClass(Object value) { + return value == null ? Object.class : value.getClass(); + } + + private static Object getCachedClass(ValueProfile.ExactClass profile) throws Exception { + return profile.getCachedClass(); + } + + private static boolean isUninitialized(ValueProfile.ExactClass profile) throws Exception { + return profile.isUninitialized(); + } + + private static boolean isGeneric(ValueProfile.ExactClass profile) throws Exception { + return profile.isGeneric(); + } +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/FloatValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/FloatValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,122 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class FloatValueProfileTest { + + @DataPoint public static final float VALUE0 = Float.MIN_VALUE; + @DataPoint public static final float VALUE1 = -0.0f; + @DataPoint public static final float VALUE2 = +0.0f; + @DataPoint public static final float VALUE3 = 14.5f; + @DataPoint public static final float VALUE4 = Float.MAX_VALUE; + + private static final float FLOAT_DELTA = 0.00001f; + + private FloatValueProfile.Enabled profile; + + @Before + public void create() { + profile = (FloatValueProfile.Enabled) FloatValueProfile.Enabled.create(); + } + + @Test + public void testInitial() { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneFloat(float value) { + float result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value, FLOAT_DELTA); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @SuppressWarnings("deprecation") + @Theory + public void testProfileTwoFloat(float value0, float value1) { + float result0 = profile.profile(value0); + float result1 = profile.profile(value1); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1)) { + assertEquals(profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @SuppressWarnings("deprecation") + @Theory + public void testProfileThreeFloat(float value0, float value1, float value2) { + float result0 = profile.profile(value0); + float result1 = profile.profile(value1); + float result2 = profile.profile(value2); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + assertEquals(result2, value2, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { + assertEquals(profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Test + public void testDisabled() { + FloatValueProfile.Disabled p = (FloatValueProfile.Disabled) FloatValueProfile.Disabled.INSTANCE; + assertThat(p.profile(VALUE0), is(VALUE0)); + assertThat(p.profile(VALUE1), is(VALUE1)); + assertThat(p.profile(VALUE2), is(VALUE2)); + assertThat(p.profile(VALUE3), is(VALUE3)); + assertThat(p.profile(VALUE4), is(VALUE4)); + p.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/IdentityValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/IdentityValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.profiles; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class IdentityValueProfileTest { + + @DataPoint public static final String O1 = new String(); + @DataPoint public static final String O2 = O1; + @DataPoint public static final Object O3 = new Object(); + @DataPoint public static final Integer O4 = new Integer(1); + @DataPoint public static final Integer O5 = null; + + private ValueProfile.Identity profile; + + @Before + public void create() { + profile = (ValueProfile.Identity) ValueProfile.Identity.create(); + } + + @Test + public void testInitial() throws Exception { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testDisabled(Object value) { + ValueProfile.Disabled p = (ValueProfile.Disabled) ValueProfile.Disabled.INSTANCE; + assertThat(p.profile(value), is(value)); + p.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOne(Object value) throws Exception { + Object result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwo(Object value0, Object value1) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + if (value0 == value1) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + Object result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + if (value0 == value1 && value1 == value2) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/IntValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/IntValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,116 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class IntValueProfileTest { + + @DataPoint public static final int VALUE0 = Integer.MIN_VALUE; + @DataPoint public static final int VALUE1 = 0; + @DataPoint public static final int VALUE2 = 14; + @DataPoint public static final int VALUE3 = Integer.MAX_VALUE; + + private IntValueProfile.Enabled profile; + + @Before + public void create() { + profile = (IntValueProfile.Enabled) IntValueProfile.Enabled.create(); + } + + @Test + public void testInitial() { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneObject(int value) { + int result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoObject(int value0, int value1) { + int result0 = profile.profile(value0); + int result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + if (value0 == value1) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeObject(int value0, int value1, int value2) { + int result0 = profile.profile(value0); + int result1 = profile.profile(value1); + int result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + if (value0 == value1 && value1 == value2) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Test + public void testDisabled() { + IntValueProfile.Disabled p = (IntValueProfile.Disabled) IntValueProfile.Disabled.INSTANCE; + assertThat(p.profile(VALUE0), is(VALUE0)); + assertThat(p.profile(VALUE1), is(VALUE1)); + assertThat(p.profile(VALUE2), is(VALUE2)); + assertThat(p.profile(VALUE3), is(VALUE3)); + p.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/LazyProfileLoadingTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/LazyProfileLoadingTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,138 @@ +/* + * 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. + * + * 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.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URLClassLoader; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.InitializationError; + +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.profiles.LazyProfileLoadingTest.SeparateClassloaderTestRunner; + +@RunWith(SeparateClassloaderTestRunner.class) +public class LazyProfileLoadingTest { + + @Test + public void testLazyLoading() { + IntValueProfile.createIdentityProfile(); + assertDefaultProfile(IntValueProfile.class); + + DoubleValueProfile.createRawIdentityProfile(); + assertDefaultProfile(DoubleValueProfile.class); + + LongValueProfile.createIdentityProfile(); + assertDefaultProfile(LongValueProfile.class); + + FloatValueProfile.createRawIdentityProfile(); + assertDefaultProfile(FloatValueProfile.class); + + ByteValueProfile.createIdentityProfile(); + assertDefaultProfile(ByteValueProfile.class); + + LoopConditionProfile.createCountingProfile(); + assertDefaultProfile(LoopConditionProfile.class); + + BranchProfile.create(); + assertDefaultProfile(BranchProfile.class); + + PrimitiveValueProfile.createEqualityProfile(); + assertDefaultProfile(PrimitiveValueProfile.class); + + ConditionProfile.createBinaryProfile(); + assertLoaded(ConditionProfile.class.getName(), "Binary", "Disabled"); + + ConditionProfile.createCountingProfile(); + assertLoaded(ConditionProfile.class.getName(), "Counting", "Disabled"); + + ValueProfile.createClassProfile(); + assertLoaded(ValueProfile.class.getName(), "ExactClass", "Disabled"); + + ValueProfile.createIdentityProfile(); + assertLoaded(ValueProfile.class.getName(), "Identity", "Disabled"); + } + + private void assertDefaultProfile(Class clazz) { + assertLoaded(clazz.getName(), "Enabled", "Disabled"); + } + + private void assertLoaded(String className, String posInnerClass, String negInnerClass) { + String enabledClass = className + "$" + posInnerClass; + String disabledClass = className + "$" + negInnerClass; + if (Truffle.getRuntime().isProfilingEnabled()) { + Assert.assertFalse(isLoaded(disabledClass)); + Assert.assertTrue(isLoaded(enabledClass)); + } else { + Assert.assertFalse(isLoaded(enabledClass)); + Assert.assertTrue(isLoaded(disabledClass)); + } + } + + private boolean isLoaded(String className) { + ClassLoader classLoader = getClass().getClassLoader(); + Method m; + try { + m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class); + m.setAccessible(true); + return m.invoke(classLoader, className) != null; + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + public static class SeparateClassloaderTestRunner extends BlockJUnit4ClassRunner { + + public SeparateClassloaderTestRunner(Class clazz) throws InitializationError { + super(getFromTestClassloader(clazz)); + } + + private static Class getFromTestClassloader(Class clazz) throws InitializationError { + try { + ClassLoader testClassLoader = new TestClassLoader(); + return Class.forName(clazz.getName(), true, testClassLoader); + } catch (ClassNotFoundException e) { + throw new InitializationError(e); + } + } + + public static class TestClassLoader extends URLClassLoader { + public TestClassLoader() { + super(((URLClassLoader) getSystemClassLoader()).getURLs()); + } + + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (name.startsWith(Profile.class.getPackage().getName())) { + return super.findClass(name); + } + return super.loadClass(name); + } + } + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/LongValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/LongValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,116 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class LongValueProfileTest { + + @DataPoint public static final long VALUE0 = Long.MIN_VALUE; + @DataPoint public static final long VALUE1 = 0L; + @DataPoint public static final long VALUE2 = 14L; + @DataPoint public static final long VALUE3 = Long.MAX_VALUE; + + private LongValueProfile.Enabled profile; + + @Before + public void create() { + profile = (LongValueProfile.Enabled) LongValueProfile.Enabled.create(); + } + + @Test + public void testInitial() { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneObject(long value) { + long result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoObject(long value0, long value1) { + long result0 = profile.profile(value0); + long result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + if (value0 == value1) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeObject(long value0, long value1, long value2) { + long result0 = profile.profile(value0); + long result1 = profile.profile(value1); + long result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + if (value0 == value1 && value1 == value2) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Test + public void testDisabled() { + LongValueProfile.Disabled p = (LongValueProfile.Disabled) LongValueProfile.Disabled.INSTANCE; + assertThat(p.profile(VALUE0), is(VALUE0)); + assertThat(p.profile(VALUE1), is(VALUE1)); + assertThat(p.profile(VALUE2), is(VALUE2)); + assertThat(p.profile(VALUE3), is(VALUE3)); + p.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/LoopConditionProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/LoopConditionProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,155 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class LoopConditionProfileTest { + + @DataPoints public static boolean[] data = new boolean[]{true, false}; + @DataPoints public static long[] lengthes = new long[]{Long.MAX_VALUE, 0L, Long.MAX_VALUE / 2L, Long.MAX_VALUE / 2 + 1L, 1L}; + + private LoopConditionProfile.Enabled profile; + + @Before + public void create() { + profile = (LoopConditionProfile.Enabled) LoopConditionProfile.Enabled.create(); + } + + @Test + public void testInitial() { + assertThat(profile.getTrueCount(), is(0L)); + assertThat(profile.getFalseCount(), is(0)); + profile.toString(); // not crashing + } + + @Theory + public void testDisabled(boolean value, long length) { + LoopConditionProfile.Disabled p = (LoopConditionProfile.Disabled) LoopConditionProfile.Disabled.INSTANCE; + p.profileCounted(length); // not crashing + assertThat(p.profile(value), is(value)); + assertThat(p.inject(value), is(value)); + p.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOne(boolean value) { + boolean result = profile.profile(value); + + assertThat(result, is(value)); + assertThat(profile.getTrueCount(), is(value ? 1L : 0L)); + assertThat(profile.getFalseCount(), is(!value ? 1 : 0)); + profile.toString(); // not crashing + } + + @Theory + public void testProfileTwo(boolean value0, boolean value1) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(profile.getTrueCount(), is((value0 ? 1L : 0L) + (value1 ? 1L : 0L))); + assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0))); + profile.toString(); // not crashing + } + + @Theory + public void testProfileThree(boolean value0, boolean value1, boolean value2) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + boolean result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + assertThat(profile.getTrueCount(), is((value0 ? 1L : 0L) + (value1 ? 1L : 0L) + (value2 ? 1L : 0L))); + assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0) + (!value2 ? 1 : 0))); + profile.toString(); // not crashing + } + + @Theory + public void testLengthProfiling(long length1, long length2, long length3) { + assertThat(profile.inject(false), is(false)); + + profile.toString(); // not crashing + profile.profileCounted(length1); + profile.toString(); // not crashing + long expectedLength = length1; + assertThat(profile.getTrueCount(), is(expectedLength)); + assertThat(profile.getFalseCount(), is(1)); + assertThat(profile.inject(false), is(false)); + + profile.profileCounted(length2); + profile.toString(); // not crashing + expectedLength += length2; + if (expectedLength < 0) { + assertThat(profile.getTrueCount(), is(length1)); + assertThat(profile.getFalseCount(), is(1)); + assertThat(profile.inject(false), is(false)); + + profile.profileCounted(length3); + expectedLength = length1 + length3; + + if (expectedLength < 0) { + assertThat(profile.getTrueCount(), is(length1)); + assertThat(profile.getFalseCount(), is(1)); + assertThat(profile.inject(false), is(false)); + } else { + assertThat(profile.getTrueCount(), is(expectedLength)); + assertThat(profile.getFalseCount(), is(2)); + assertThat(profile.inject(false), is(false)); + } + return; + } else { + assertThat(profile.getTrueCount(), is(expectedLength)); + assertThat(profile.getFalseCount(), is(2)); + assertThat(profile.inject(false), is(false)); + } + + profile.profileCounted(length3); + profile.toString(); // not crashing + expectedLength += length3; + + if (expectedLength < 0) { + assertThat(profile.getTrueCount(), is(length1 + length2)); + assertThat(profile.getFalseCount(), is(2)); + assertThat(profile.inject(false), is(false)); + } else { + assertThat(profile.getTrueCount(), is(expectedLength)); + assertThat(profile.getFalseCount(), is(3)); + assertThat(profile.inject(false), is(false)); + } + profile.toString(); // not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/PrimitiveValueProfileTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/profiles/PrimitiveValueProfileTest.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,966 @@ +/* + * 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. + * + * 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 static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoint; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@SuppressWarnings("deprecation") +@RunWith(Theories.class) +public class PrimitiveValueProfileTest { + + @DataPoint public static final String O1 = new String(); + @DataPoint public static final String O2 = O1; + @DataPoint public static final Object O3 = new Object(); + @DataPoint public static final Object O4 = null; + + @DataPoint public static final byte B1 = Byte.MIN_VALUE; + @DataPoint public static final byte B2 = 0; + @DataPoint public static final byte B3 = 14; + @DataPoint public static final byte B4 = Byte.MAX_VALUE; + + @DataPoint public static final short S1 = Short.MIN_VALUE; + @DataPoint public static final short S2 = 0; + @DataPoint public static final short S3 = 14; + @DataPoint public static final short S4 = Short.MAX_VALUE; + + @DataPoint public static final int I1 = Integer.MIN_VALUE; + @DataPoint public static final int I2 = 0; + @DataPoint public static final int I3 = 14; + @DataPoint public static final int I4 = Integer.MAX_VALUE; + + @DataPoint public static final long L1 = Long.MIN_VALUE; + @DataPoint public static final long L2 = 0; + @DataPoint public static final long L3 = 14; + @DataPoint public static final long L4 = Long.MAX_VALUE; + + @DataPoint public static final float F1 = Float.MIN_VALUE; + @DataPoint public static final float F2 = -0.0f; + @DataPoint public static final float F3 = +0.0f; + @DataPoint public static final float F4 = 14.5f; + @DataPoint public static final float F5 = Float.MAX_VALUE; + + @DataPoint public static final double D1 = Double.MIN_VALUE; + @DataPoint public static final double D2 = -0.0; + @DataPoint public static final double D3 = +0.0; + @DataPoint public static final double D4 = 14.5; + @DataPoint public static final double D5 = Double.MAX_VALUE; + + @DataPoint public static final boolean T1 = false; + @DataPoint public static final boolean T2 = true; + + @DataPoint public static final char C1 = Character.MIN_VALUE; + @DataPoint public static final char C2 = 0; + @DataPoint public static final char C3 = 14; + @DataPoint public static final char C4 = Character.MAX_VALUE; + + private static final float FLOAT_DELTA = 0.00001f; + private static final double DOUBLE_DELTA = 0.00001; + + private PrimitiveValueProfile.Enabled profile; + + @Before + public void create() { + profile = (PrimitiveValueProfile.Enabled) PrimitiveValueProfile.Enabled.create(); + } + + @Test + public void testInitial() { + assertThat(profile.isGeneric(), is(false)); + assertThat(profile.isUninitialized(), is(true)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneObject(Object value) { + Object result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoObject(Object value0, Object value1) { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + + if (value0 == value1) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeObject(Object value0, Object value1, Object value2) { + Object result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + Object result2 = profile.profile(value2); + + assertThat(result0, is(value0)); + assertThat(result1, is(value1)); + assertThat(result2, is(value2)); + + if (value0 == value1 && value1 == value2) { + assertThat(profile.getCachedValue(), is(value0)); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneByte(byte value) { + byte result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoByte(byte value0, byte value1) { + byte result0 = profile.profile(value0); + byte result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Byte); + assertEquals((byte) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeByte(byte value0, byte value1, byte value2) { + byte result0 = profile.profile(value0); + byte result1 = profile.profile(value1); + byte result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Byte); + assertEquals((byte) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneShort(short value) { + short result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoShort(short value0, short value1) { + short result0 = profile.profile(value0); + short result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Short); + assertEquals((short) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeShort(short value0, short value1, short value2) { + short result0 = profile.profile(value0); + short result1 = profile.profile(value1); + short result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Short); + assertEquals((short) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneInteger(int value) { + int result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoInteger(int value0, int value1) { + int result0 = profile.profile(value0); + int result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Integer); + assertEquals((int) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeInteger(int value0, int value1, int value2) { + int result0 = profile.profile(value0); + int result1 = profile.profile(value1); + int result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Integer); + assertEquals((int) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneLong(long value) { + long result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoLong(long value0, long value1) { + long result0 = profile.profile(value0); + long result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Long); + assertEquals((long) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeLong(long value0, long value1, long value2) { + long result0 = profile.profile(value0); + long result1 = profile.profile(value1); + long result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Long); + assertEquals((long) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneFloat(float value) { + float result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoFloat(float value0, float value1) { + float result0 = profile.profile(value0); + float result1 = profile.profile(value1); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1)) { + assertTrue(profile.getCachedValue() instanceof Float); + assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeFloat(float value0, float value1, float value2) { + float result0 = profile.profile(value0); + float result1 = profile.profile(value1); + float result2 = profile.profile(value2); + + assertEquals(result0, value0, FLOAT_DELTA); + assertEquals(result1, value1, FLOAT_DELTA); + assertEquals(result2, value2, FLOAT_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { + assertTrue(profile.getCachedValue() instanceof Float); + assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneDouble(double value) { + double result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoDouble(double value0, double value1) { + double result0 = profile.profile(value0); + double result1 = profile.profile(value1); + + assertEquals(result0, value0, DOUBLE_DELTA); + assertEquals(result1, value1, DOUBLE_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1)) { + assertTrue(profile.getCachedValue() instanceof Double); + assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeDouble(double value0, double value1, double value2) { + double result0 = profile.profile(value0); + double result1 = profile.profile(value1); + double result2 = profile.profile(value2); + + assertEquals(result0, value0, DOUBLE_DELTA); + assertEquals(result1, value1, DOUBLE_DELTA); + assertEquals(result2, value2, DOUBLE_DELTA); + + if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { + assertTrue(profile.getCachedValue() instanceof Double); + assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneBoolean(boolean value) { + boolean result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoBoolean(boolean value0, boolean value1) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Boolean); + assertEquals((boolean) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeBoolean(boolean value0, boolean value1, boolean value2) { + boolean result0 = profile.profile(value0); + boolean result1 = profile.profile(value1); + boolean result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Boolean); + assertEquals((boolean) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileOneChar(char value) { + char result = profile.profile(value); + + assertThat(result, is(value)); + assertEquals(profile.getCachedValue(), value); + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileTwoChar(char value0, char value1) { + char result0 = profile.profile(value0); + char result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertEquals(result1, value1); + + if (value0 == value1) { + assertTrue(profile.getCachedValue() instanceof Character); + assertEquals((char) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testProfileThreeChar(char value0, char value1, char value2) { + char result0 = profile.profile(value0); + char result1 = profile.profile(value1); + char result2 = profile.profile(value2); + + assertEquals(result0, value0); + assertEquals(result1, value1); + assertEquals(result2, value2); + + if (value0 == value1 && value1 == value2) { + assertTrue(profile.getCachedValue() instanceof Character); + assertEquals((char) profile.getCachedValue(), value0); + assertThat(profile.isGeneric(), is(false)); + } else { + assertThat(profile.isGeneric(), is(true)); + } + assertThat(profile.isUninitialized(), is(false)); + profile.toString(); // test that it is not crashing + } + + @Theory + public void testWithBoxedBoxedByte(byte value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Byte); + assertEquals((byte) result0, value); + assertTrue(result1 instanceof Byte); + assertEquals((byte) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedByte(byte value) { + byte result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Byte); + assertEquals((byte) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedByte(byte value) { + Object result0 = profile.profile((Object) value); + byte result1 = profile.profile(value); + + assertTrue(result0 instanceof Byte); + assertEquals((byte) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedShort(short value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Short); + assertEquals((short) result0, value); + assertTrue(result1 instanceof Short); + assertEquals((short) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedShort(short value) { + short result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Short); + assertEquals((short) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedShort(short value) { + Object result0 = profile.profile((Object) value); + short result1 = profile.profile(value); + + assertTrue(result0 instanceof Short); + assertEquals((short) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedInt(int value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Integer); + assertEquals((int) result0, value); + assertTrue(result1 instanceof Integer); + assertEquals((int) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedInt(int value) { + int result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Integer); + assertEquals((int) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedInt(int value) { + Object result0 = profile.profile((Object) value); + int result1 = profile.profile(value); + + assertTrue(result0 instanceof Integer); + assertEquals((int) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedLong(long value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Long); + assertEquals((long) result0, value); + assertTrue(result1 instanceof Long); + assertEquals((long) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedLong(long value) { + long result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Long); + assertEquals((long) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedLong(long value) { + Object result0 = profile.profile((Object) value); + long result1 = profile.profile(value); + + assertTrue(result0 instanceof Long); + assertEquals((long) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedFloat(float value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); + assertTrue(result1 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedFloat(float value) { + float result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); + assertTrue(result1 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedFloat(float value) { + Object result0 = profile.profile((Object) value); + float result1 = profile.profile(value); + + assertTrue(result0 instanceof Float); + assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); + assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedDouble(double value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); + assertTrue(result1 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedDouble(double value) { + double result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); + assertTrue(result1 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedDouble(double value) { + Object result0 = profile.profile((Object) value); + double result1 = profile.profile(value); + + assertTrue(result0 instanceof Double); + assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); + assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedBoolean(boolean value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Boolean); + assertEquals((boolean) result0, value); + assertTrue(result1 instanceof Boolean); + assertEquals((boolean) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedBoolean(boolean value) { + boolean result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Boolean); + assertEquals((boolean) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedBoolean(boolean value) { + Object result0 = profile.profile((Object) value); + boolean result1 = profile.profile(value); + + assertTrue(result0 instanceof Boolean); + assertEquals((boolean) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedBoxedChar(char value) { + Object result0 = profile.profile((Object) value); + Object result1 = profile.profile((Object) value); + + assertTrue(result0 instanceof Character); + assertEquals((char) result0, value); + assertTrue(result1 instanceof Character); + assertEquals((char) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithUnboxedBoxedChar(char value) { + char result0 = profile.profile(value); + Object result1 = profile.profile((Object) value); + + assertEquals(result0, value); + assertTrue(result1 instanceof Character); + assertEquals((char) result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithBoxedUnboxedCharacter(char value) { + Object result0 = profile.profile((Object) value); + char result1 = profile.profile(value); + + assertTrue(result0 instanceof Character); + assertEquals((char) result0, value); + assertEquals(result1, value); + assertFalse(profile.isUninitialized()); + assertFalse(profile.isGeneric()); + } + + @Theory + public void testWithByteThenObject(byte value0, Object value1) { + byte result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithShortThenObject(short value0, Object value1) { + short result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithIntThenObject(int value0, Object value1) { + int result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithLongThenObject(long value0, Object value1) { + long result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithFloatThenObject(float value0, Object value1) { + float result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithDoubleThenObject(double value0, Object value1) { + double result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithBooleanThenObject(boolean value0, Object value1) { + boolean result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Theory + public void testWithCharThenObject(char value0, Object value1) { + char result0 = profile.profile(value0); + Object result1 = profile.profile(value1); + + assertEquals(result0, value0); + assertSame(result1, value1); + assertFalse(profile.isUninitialized()); + assertTrue(profile.isGeneric()); + } + + @Test + public void testNegativeZeroFloat() { + profile.profile(-0.0f); + profile.profile(+0.0f); + assertThat(profile.isGeneric(), is(true)); + } + + @Test + public void testNegativeZeroDouble() { + profile.profile(-0.0); + profile.profile(+0.0); + assertThat(profile.isGeneric(), is(true)); + } + + @Test + public void testDisabled() { + PrimitiveValueProfile.Disabled p = (PrimitiveValueProfile.Disabled) PrimitiveValueProfile.Disabled.INSTANCE; + assertThat(p.profile(O1), is(O1)); + assertThat(p.profile(B1), is(B1)); + assertThat(p.profile(S1), is(S1)); + assertThat(p.profile(I1), is(I1)); + assertThat(p.profile(L1), is(L1)); + assertThat(p.profile(F1), is(F1)); + assertThat(p.profile(D1), is(D1)); + assertThat(p.profile(T1), is(T1)); + assertThat(p.profile(C1), is(C1)); + p.toString(); // test that it is not crashing + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BinaryConditionProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BinaryConditionProfileTest.java Wed Dec 16 12:31:17 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.utilities; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoints; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class BinaryConditionProfileTest { - - @DataPoints public static boolean[] data = new boolean[]{true, false}; - - private BinaryConditionProfile profile; - - @Before - public void create() { - profile = (BinaryConditionProfile) ConditionProfile.createBinaryProfile(); - } - - @Test - public void testInitial() { - assertThat(profile.wasTrue(), is(false)); - assertThat(profile.wasFalse(), is(false)); - } - - @Theory - public void testProfileOne(boolean value) { - boolean result = profile.profile(value); - - assertThat(result, is(value)); - assertThat(profile.wasTrue(), is(value)); - assertThat(profile.wasFalse(), is(!value)); - } - - @Theory - public void testProfileTwo(boolean value0, boolean value1) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(profile.wasTrue(), is(value0 || value1)); - assertThat(profile.wasFalse(), is(!value0 || !value1)); - } - - @Theory - public void testProfileThree(boolean value0, boolean value1, boolean value2) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - boolean result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - assertThat(profile.wasTrue(), is(value0 || value1 || value2)); - assertThat(profile.wasFalse(), is(!value0 || !value1 || !value2)); - } - -} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BranchProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/BranchProfileTest.java Wed Dec 16 12:31:17 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.utilities; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class BranchProfileTest { - - @Test - public void testEnter() { - BranchProfile profile = BranchProfile.create(); - profile.enter(); - profile.enter(); - } - - @Test - public void testToString() { - BranchProfile profile = BranchProfile.create(); - assertTrue(profile.toString().contains(profile.getClass().getSimpleName())); - assertTrue(profile.toString().contains("not-visited")); - assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); - profile.enter(); - assertTrue(profile.toString().contains(profile.getClass().getSimpleName())); - assertTrue(profile.toString().contains("visited")); - assertTrue(profile.toString().contains(Integer.toHexString(profile.hashCode()))); - } - -} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/CountingConditionProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/CountingConditionProfileTest.java Wed Dec 16 12:31:17 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.utilities; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoints; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class CountingConditionProfileTest { - - @DataPoints public static boolean[] data = new boolean[]{true, false}; - - private CountingConditionProfile profile; - - @Before - public void create() { - profile = (CountingConditionProfile) ConditionProfile.createCountingProfile(); - } - - @Test - public void testInitial() { - assertThat(profile.getTrueCount(), is(0)); - assertThat(profile.getFalseCount(), is(0)); - } - - @Theory - public void testProfileOne(boolean value) { - boolean result = profile.profile(value); - - assertThat(result, is(value)); - assertThat(profile.getTrueCount(), is(value ? 1 : 0)); - assertThat(profile.getFalseCount(), is(!value ? 1 : 0)); - } - - @Theory - public void testProfileTwo(boolean value0, boolean value1) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0))); - assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0))); - } - - @Theory - public void testProfileThree(boolean value0, boolean value1, boolean value2) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - boolean result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - assertThat(profile.getTrueCount(), is((value0 ? 1 : 0) + (value1 ? 1 : 0) + (value2 ? 1 : 0))); - assertThat(profile.getFalseCount(), is((!value0 ? 1 : 0) + (!value1 ? 1 : 0) + (!value2 ? 1 : 0))); - } - -} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/ExactClassValueProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/ExactClassValueProfileTest.java Wed Dec 16 12:31:17 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.utilities; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; - -import java.lang.reflect.Method; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class ExactClassValueProfileTest { - - @DataPoint public static final String O1 = new String(); - @DataPoint public static final String O2 = new String(); - @DataPoint public static final Object O3 = new Object(); - @DataPoint public static final Integer O4 = new Integer(1); - @DataPoint public static final Integer O5 = null; - @DataPoint public static final TestBaseClass O6 = new TestBaseClass(); - @DataPoint public static final TestSubClass O7 = new TestSubClass(); - - private ValueProfile profile; - - private static class TestBaseClass { - } - - private static class TestSubClass extends TestBaseClass { - } - - @Before - public void create() { - profile = ValueProfile.createClassProfile(); - } - - @Test - public void testInitial() throws Exception { - assertThat(isGeneric(profile), is(false)); - assertThat(isUninitialized(profile), is(true)); - assertNull(getCachedClass(profile)); - assertNotNull(profile.toString()); - } - - @Theory - public void testProfileOne(Object value) throws Exception { - Object result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(expectedClass(value), getCachedClass(profile)); - assertThat(isUninitialized(profile), is(false)); - assertNotNull(profile.toString()); - } - - @Theory - public void testProfileTwo(Object value0, Object value1) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - - Object expectedClass = expectedClass(value0) == expectedClass(value1) ? expectedClass(value0) : Object.class; - - assertEquals(expectedClass, getCachedClass(profile)); - assertThat(isUninitialized(profile), is(false)); - assertThat(isGeneric(profile), is(expectedClass == Object.class)); - assertNotNull(profile.toString()); - } - - @Theory - public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - Object result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - - Object expectedClass = expectedClass(value0) == expectedClass(value1) && expectedClass(value1) == expectedClass(value2) ? expectedClass(value0) : Object.class; - - assertEquals(expectedClass, getCachedClass(profile)); - assertThat(isUninitialized(profile), is(false)); - assertThat(isGeneric(profile), is(expectedClass == Object.class)); - assertNotNull(profile.toString()); - } - - private static Class expectedClass(Object value) { - return value == null ? Object.class : value.getClass(); - } - - private static Object get(String name, ValueProfile profile) throws Exception { - final Method m = profile.getClass().getDeclaredMethod(name); - m.setAccessible(true); - return m.invoke(profile); - } - - private static Object getCachedClass(ValueProfile profile) throws Exception { - return get("getCachedClass", profile); - } - - private static boolean isUninitialized(ValueProfile profile) throws Exception { - return (Boolean) get("isUninitialized", profile); - } - - private static boolean isGeneric(ValueProfile profile) throws Exception { - return (Boolean) get("isGeneric", profile); - } -} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/IdentityValueProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/IdentityValueProfileTest.java Wed Dec 16 12:31:17 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.utilities; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - -import java.lang.reflect.Method; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class IdentityValueProfileTest { - - @DataPoint public static final String O1 = new String(); - @DataPoint public static final String O2 = O1; - @DataPoint public static final Object O3 = new Object(); - @DataPoint public static final Integer O4 = new Integer(1); - @DataPoint public static final Integer O5 = null; - - private ValueProfile profile; - - @Before - public void create() { - profile = ValueProfile.createIdentityProfile(); - } - - @Test - public void testInitial() throws Exception { - assertThat(isGeneric(profile), is(false)); - assertThat(isUninitialized(profile), is(true)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOne(Object value) throws Exception { - Object result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(getCachedValue(profile), value); - assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwo(Object value0, Object value1) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - - if (value0 == value1) { - assertThat(getCachedValue(profile), is(value0)); - assertThat(isGeneric(profile), is(false)); - } else { - assertThat(isGeneric(profile), is(true)); - } - assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThree(Object value0, Object value1, Object value2) throws Exception { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - Object result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - - if (value0 == value1 && value1 == value2) { - assertThat(getCachedValue(profile), is(value0)); - assertThat(isGeneric(profile), is(false)); - } else { - assertThat(isGeneric(profile), is(true)); - } - assertThat(isUninitialized(profile), is(false)); - profile.toString(); // test that it is not crashing - } - - private static Object get(String name, ValueProfile profile) throws Exception { - final Method m = profile.getClass().getDeclaredMethod(name); - m.setAccessible(true); - return m.invoke(profile); - } - - private static Object getCachedValue(ValueProfile profile) throws Exception { - return get("getCachedValue", profile); - } - - private static boolean isUninitialized(ValueProfile profile) throws Exception { - return (Boolean) get("isUninitialized", profile); - } - - private static boolean isGeneric(ValueProfile profile) throws Exception { - return (Boolean) get("isGeneric", profile); - } -} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/PrimitiveValueProfileTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/utilities/PrimitiveValueProfileTest.java Wed Dec 16 12:31:17 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,950 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.api.utilities; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.theories.DataPoint; -import org.junit.experimental.theories.Theories; -import org.junit.experimental.theories.Theory; -import org.junit.runner.RunWith; - -@RunWith(Theories.class) -public class PrimitiveValueProfileTest { - - @DataPoint public static final String O1 = new String(); - @DataPoint public static final String O2 = O1; - @DataPoint public static final Object O3 = new Object(); - @DataPoint public static final Object O4 = null; - - @DataPoint public static final byte B1 = Byte.MIN_VALUE; - @DataPoint public static final byte B2 = 0; - @DataPoint public static final byte B3 = 14; - @DataPoint public static final byte B4 = Byte.MAX_VALUE; - - @DataPoint public static final short S1 = Short.MIN_VALUE; - @DataPoint public static final short S2 = 0; - @DataPoint public static final short S3 = 14; - @DataPoint public static final short S4 = Short.MAX_VALUE; - - @DataPoint public static final int I1 = Integer.MIN_VALUE; - @DataPoint public static final int I2 = 0; - @DataPoint public static final int I3 = 14; - @DataPoint public static final int I4 = Integer.MAX_VALUE; - - @DataPoint public static final long L1 = Long.MIN_VALUE; - @DataPoint public static final long L2 = 0; - @DataPoint public static final long L3 = 14; - @DataPoint public static final long L4 = Long.MAX_VALUE; - - @DataPoint public static final float F1 = Float.MIN_VALUE; - @DataPoint public static final float F2 = -0.0f; - @DataPoint public static final float F3 = +0.0f; - @DataPoint public static final float F4 = 14.5f; - @DataPoint public static final float F5 = Float.MAX_VALUE; - - @DataPoint public static final double D1 = Double.MIN_VALUE; - @DataPoint public static final double D2 = -0.0; - @DataPoint public static final double D3 = +0.0; - @DataPoint public static final double D4 = 14.5; - @DataPoint public static final double D5 = Double.MAX_VALUE; - - @DataPoint public static final boolean T1 = false; - @DataPoint public static final boolean T2 = true; - - @DataPoint public static final char C1 = Character.MIN_VALUE; - @DataPoint public static final char C2 = 0; - @DataPoint public static final char C3 = 14; - @DataPoint public static final char C4 = Character.MAX_VALUE; - - private static final float FLOAT_DELTA = 0.00001f; - private static final double DOUBLE_DELTA = 0.00001; - - private PrimitiveValueProfile profile; - - @Before - public void create() { - profile = ValueProfile.createPrimitiveProfile(); - } - - @Test - public void testInitial() { - assertThat(profile.isGeneric(), is(false)); - assertThat(profile.isUninitialized(), is(true)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneObject(Object value) { - Object result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoObject(Object value0, Object value1) { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - - if (value0 == value1) { - assertThat(profile.getCachedValue(), is(value0)); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeObject(Object value0, Object value1, Object value2) { - Object result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - Object result2 = profile.profile(value2); - - assertThat(result0, is(value0)); - assertThat(result1, is(value1)); - assertThat(result2, is(value2)); - - if (value0 == value1 && value1 == value2) { - assertThat(profile.getCachedValue(), is(value0)); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneByte(byte value) { - byte result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoByte(byte value0, byte value1) { - byte result0 = profile.profile(value0); - byte result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Byte); - assertEquals((byte) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeByte(byte value0, byte value1, byte value2) { - byte result0 = profile.profile(value0); - byte result1 = profile.profile(value1); - byte result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Byte); - assertEquals((byte) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneShort(short value) { - short result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoShort(short value0, short value1) { - short result0 = profile.profile(value0); - short result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Short); - assertEquals((short) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeShort(short value0, short value1, short value2) { - short result0 = profile.profile(value0); - short result1 = profile.profile(value1); - short result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Short); - assertEquals((short) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneInteger(int value) { - int result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoInteger(int value0, int value1) { - int result0 = profile.profile(value0); - int result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Integer); - assertEquals((int) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeInteger(int value0, int value1, int value2) { - int result0 = profile.profile(value0); - int result1 = profile.profile(value1); - int result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Integer); - assertEquals((int) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneLong(long value) { - long result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoLong(long value0, long value1) { - long result0 = profile.profile(value0); - long result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Long); - assertEquals((long) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeLong(long value0, long value1, long value2) { - long result0 = profile.profile(value0); - long result1 = profile.profile(value1); - long result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Long); - assertEquals((long) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneFloat(float value) { - float result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoFloat(float value0, float value1) { - float result0 = profile.profile(value0); - float result1 = profile.profile(value1); - - assertEquals(result0, value0, FLOAT_DELTA); - assertEquals(result1, value1, FLOAT_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1)) { - assertTrue(profile.getCachedValue() instanceof Float); - assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeFloat(float value0, float value1, float value2) { - float result0 = profile.profile(value0); - float result1 = profile.profile(value1); - float result2 = profile.profile(value2); - - assertEquals(result0, value0, FLOAT_DELTA); - assertEquals(result1, value1, FLOAT_DELTA); - assertEquals(result2, value2, FLOAT_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { - assertTrue(profile.getCachedValue() instanceof Float); - assertEquals((float) profile.getCachedValue(), value0, FLOAT_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneDouble(double value) { - double result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoDouble(double value0, double value1) { - double result0 = profile.profile(value0); - double result1 = profile.profile(value1); - - assertEquals(result0, value0, DOUBLE_DELTA); - assertEquals(result1, value1, DOUBLE_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1)) { - assertTrue(profile.getCachedValue() instanceof Double); - assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeDouble(double value0, double value1, double value2) { - double result0 = profile.profile(value0); - double result1 = profile.profile(value1); - double result2 = profile.profile(value2); - - assertEquals(result0, value0, DOUBLE_DELTA); - assertEquals(result1, value1, DOUBLE_DELTA); - assertEquals(result2, value2, DOUBLE_DELTA); - - if (PrimitiveValueProfile.exactCompare(value0, value1) && PrimitiveValueProfile.exactCompare(value1, value2)) { - assertTrue(profile.getCachedValue() instanceof Double); - assertEquals((double) profile.getCachedValue(), value0, DOUBLE_DELTA); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneBoolean(boolean value) { - boolean result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoBoolean(boolean value0, boolean value1) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Boolean); - assertEquals((boolean) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeBoolean(boolean value0, boolean value1, boolean value2) { - boolean result0 = profile.profile(value0); - boolean result1 = profile.profile(value1); - boolean result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Boolean); - assertEquals((boolean) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileOneChar(char value) { - char result = profile.profile(value); - - assertThat(result, is(value)); - assertEquals(profile.getCachedValue(), value); - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileTwoChar(char value0, char value1) { - char result0 = profile.profile(value0); - char result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertEquals(result1, value1); - - if (value0 == value1) { - assertTrue(profile.getCachedValue() instanceof Character); - assertEquals((char) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testProfileThreeChar(char value0, char value1, char value2) { - char result0 = profile.profile(value0); - char result1 = profile.profile(value1); - char result2 = profile.profile(value2); - - assertEquals(result0, value0); - assertEquals(result1, value1); - assertEquals(result2, value2); - - if (value0 == value1 && value1 == value2) { - assertTrue(profile.getCachedValue() instanceof Character); - assertEquals((char) profile.getCachedValue(), value0); - assertThat(profile.isGeneric(), is(false)); - } else { - assertThat(profile.isGeneric(), is(true)); - } - assertThat(profile.isUninitialized(), is(false)); - profile.toString(); // test that it is not crashing - } - - @Theory - public void testWithBoxedBoxedByte(byte value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Byte); - assertEquals((byte) result0, value); - assertTrue(result1 instanceof Byte); - assertEquals((byte) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedByte(byte value) { - byte result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Byte); - assertEquals((byte) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedByte(byte value) { - Object result0 = profile.profile((Object) value); - byte result1 = profile.profile(value); - - assertTrue(result0 instanceof Byte); - assertEquals((byte) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedShort(short value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Short); - assertEquals((short) result0, value); - assertTrue(result1 instanceof Short); - assertEquals((short) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedShort(short value) { - short result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Short); - assertEquals((short) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedShort(short value) { - Object result0 = profile.profile((Object) value); - short result1 = profile.profile(value); - - assertTrue(result0 instanceof Short); - assertEquals((short) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedInt(int value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Integer); - assertEquals((int) result0, value); - assertTrue(result1 instanceof Integer); - assertEquals((int) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedInt(int value) { - int result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Integer); - assertEquals((int) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedInt(int value) { - Object result0 = profile.profile((Object) value); - int result1 = profile.profile(value); - - assertTrue(result0 instanceof Integer); - assertEquals((int) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedLong(long value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Long); - assertEquals((long) result0, value); - assertTrue(result1 instanceof Long); - assertEquals((long) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedLong(long value) { - long result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Long); - assertEquals((long) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedLong(long value) { - Object result0 = profile.profile((Object) value); - long result1 = profile.profile(value); - - assertTrue(result0 instanceof Long); - assertEquals((long) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedFloat(float value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); - assertTrue(result1 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedFloat(float value) { - float result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); - assertTrue(result1 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedFloat(float value) { - Object result0 = profile.profile((Object) value); - float result1 = profile.profile(value); - - assertTrue(result0 instanceof Float); - assertTrue(PrimitiveValueProfile.exactCompare((float) result0, value)); - assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedDouble(double value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); - assertTrue(result1 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedDouble(double value) { - double result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value)); - assertTrue(result1 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedDouble(double value) { - Object result0 = profile.profile((Object) value); - double result1 = profile.profile(value); - - assertTrue(result0 instanceof Double); - assertTrue(PrimitiveValueProfile.exactCompare((double) result0, value)); - assertTrue(PrimitiveValueProfile.exactCompare(result1, value)); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedBoolean(boolean value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Boolean); - assertEquals((boolean) result0, value); - assertTrue(result1 instanceof Boolean); - assertEquals((boolean) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedBoolean(boolean value) { - boolean result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Boolean); - assertEquals((boolean) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedBoolean(boolean value) { - Object result0 = profile.profile((Object) value); - boolean result1 = profile.profile(value); - - assertTrue(result0 instanceof Boolean); - assertEquals((boolean) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedBoxedChar(char value) { - Object result0 = profile.profile((Object) value); - Object result1 = profile.profile((Object) value); - - assertTrue(result0 instanceof Character); - assertEquals((char) result0, value); - assertTrue(result1 instanceof Character); - assertEquals((char) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithUnboxedBoxedChar(char value) { - char result0 = profile.profile(value); - Object result1 = profile.profile((Object) value); - - assertEquals(result0, value); - assertTrue(result1 instanceof Character); - assertEquals((char) result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithBoxedUnboxedCharacter(char value) { - Object result0 = profile.profile((Object) value); - char result1 = profile.profile(value); - - assertTrue(result0 instanceof Character); - assertEquals((char) result0, value); - assertEquals(result1, value); - assertFalse(profile.isUninitialized()); - assertFalse(profile.isGeneric()); - } - - @Theory - public void testWithByteThenObject(byte value0, Object value1) { - byte result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithShortThenObject(short value0, Object value1) { - short result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithIntThenObject(int value0, Object value1) { - int result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithLongThenObject(long value0, Object value1) { - long result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithFloatThenObject(float value0, Object value1) { - float result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithDoubleThenObject(double value0, Object value1) { - double result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertTrue(PrimitiveValueProfile.exactCompare(result0, value0)); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithBooleanThenObject(boolean value0, Object value1) { - boolean result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Theory - public void testWithCharThenObject(char value0, Object value1) { - char result0 = profile.profile(value0); - Object result1 = profile.profile(value1); - - assertEquals(result0, value0); - assertSame(result1, value1); - assertFalse(profile.isUninitialized()); - assertTrue(profile.isGeneric()); - } - - @Test - public void testNegativeZeroFloat() { - profile.profile(-0.0f); - profile.profile(+0.0f); - assertThat(profile.isGeneric(), is(true)); - } - - @Test - public void testNegativeZeroDouble() { - profile.profile(-0.0); - profile.profile(+0.0); - assertThat(profile.isGeneric(), is(true)); - } - -} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/snapshot.sigtest --- a/truffle/com.oracle.truffle.api/snapshot.sigtest Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/snapshot.sigtest Wed Dec 16 16:38:13 2015 +0100 @@ -172,6 +172,8 @@ meth public abstract java.lang.String getName() meth public abstract java.util.Collection getCallTargets() meth public abstract void notifyTransferToInterpreter() +meth public abstract boolean isProfilingEnabled() + CLSS public abstract interface com.oracle.truffle.api.TruffleRuntimeAccess meth public abstract com.oracle.truffle.api.TruffleRuntime getRuntime() diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java Wed Dec 16 16:38:13 2015 +0100 @@ -173,4 +173,13 @@ */ void notifyTransferToInterpreter(); + /** + * Whether or not the {@link TruffleRuntime} implementation can or wants to use gathered + * profiling information Truffle compilation. If this method returns false then all + * profiles in the {@link com.oracle.truffle.api.utilities} package are returning void + * implementations. If it returns true then all implementations gather profilinig + * information. + */ + boolean isProfilingEnabled(); + } diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java Wed Dec 16 16:38:13 2015 +0100 @@ -177,4 +177,8 @@ } return new DefaultLoopNode(repeating); } + + public boolean isProfilingEnabled() { + return false; + } } diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/BranchProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/BranchProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * 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: + * + *

+ * 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ByteValueProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ByteValueProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * Specialized value profile to capture certain properties of 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. + *

+ * + *

+ * Usage example: + * + *

+ * 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;
+ *     }
+ * }
+ * 
+ *

+ * + * + * {@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 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ConditionProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ConditionProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * ConditionProfiles are useful to profile the outcome of conditions. + *

+ * + *

+ * Usage example: + * + *

+ * 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/DoubleValueProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/DoubleValueProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * Specialized value profile to capture certain properties of 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. + *

+ * + *

+ * Usage example: + * + *

+ * 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;
+ *     }
+ * }
+ * 
+ *

+ * + * + * {@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 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/FloatValueProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/FloatValueProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * Specialized value profile to capture certain properties of 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. + *

+ * + *

+ * Usage example: + * + *

+ * 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;
+ *     }
+ * }
+ * 
+ *

+ * + * + * {@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 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/IntValueProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/IntValueProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * Specialized value profile to capture certain properties of 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. + *

+ * + *

+ * Usage example: + * + *

+ * 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;
+ *     }
+ * }
+ * 
+ *

+ * + * + * {@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 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LongValueProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LongValueProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * Specialized value profile to capture certain properties of 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. + *

+ * + *

+ * Usage example: + * + *

+ * 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;
+ *     }
+ * }
+ * 
+ *

+ * + * {@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 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LoopConditionProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/LoopConditionProfile.java Wed Dec 16 16:38:13 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; + +/** + *

+ * 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 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 fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/PrimitiveValueProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/PrimitiveValueProfile.java Wed Dec 16 16:38:13 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 T profile(T value); + + public abstract byte profile(byte value); + + public abstract short profile(short value); + + public abstract int profile(int value); + + public abstract long profile(long value); + + public abstract float profile(float value); + + public abstract double profile(double value); + + public abstract boolean profile(boolean value); + + public abstract char profile(char value); + + /** + * Returns a {@link PrimitiveValueProfile} that speculates on the primitive equality or object + * identity of a value. + */ + public static PrimitiveValueProfile createEqualityProfile() { + if (Truffle.getRuntime().isProfilingEnabled()) { + return Enabled.create(); + } else { + return Disabled.INSTANCE; + } + } + + /** + * @deprecated going to get removed without replacement + */ + @Deprecated + public static boolean exactCompare(float a, float b) { + /* + * -0.0 == 0.0, but you can tell the difference through other means, so we need to + * differentiate. + */ + return Float.floatToRawIntBits(a) == Float.floatToRawIntBits(b); + } + + /** + * @deprecated going to get removed without replacement + */ + @Deprecated + public static boolean exactCompare(double a, double b) { + /* + * -0.0 == 0.0, but you can tell the difference through other means, so we need to + * differentiate. + */ + return Double.doubleToRawLongBits(a) == Double.doubleToRawLongBits(b); + } + + static final class Enabled extends PrimitiveValueProfile { + + private static final byte STATE_UNINITIALIZED = 0; + private static final byte STATE_BYTE = 1; + private static final byte STATE_SHORT = 2; + private static final byte STATE_INTEGER = 3; + private static final byte STATE_LONG = 4; + private static final byte STATE_BOOLEAN = 5; + private static final byte STATE_CHARACTER = 6; + private static final byte STATE_FLOAT = 7; + private static final byte STATE_DOUBLE = 8; + private static final byte STATE_IDENTITY = 9; + private static final byte STATE_GENERIC = 10; + + @CompilationFinal private byte state = STATE_UNINITIALIZED; + @CompilationFinal private Object cachedValue; + + Enabled() { + } + + @SuppressWarnings("unchecked") + @Override + public T profile(T value) { + byte s = this.state; + Object snapshot; + switch (s) { + case STATE_BYTE: + case STATE_SHORT: + case STATE_INTEGER: + case STATE_LONG: + case STATE_BOOLEAN: + case STATE_CHARACTER: + snapshot = this.cachedValue; + if (snapshot.equals(value)) { + return (T) snapshot; + } + break; + case STATE_DOUBLE: + snapshot = this.cachedValue; + if (value instanceof Double && exactCompare((Double) snapshot, (Double) value)) { + return (T) snapshot; + } + break; + case STATE_FLOAT: + snapshot = this.cachedValue; + if (value instanceof Float && exactCompare((Float) snapshot, (Float) value)) { + return (T) snapshot; + } + break; + case STATE_IDENTITY: + snapshot = this.cachedValue; + if (snapshot == value) { + return (T) snapshot; + } + break; + case STATE_GENERIC: + return value; + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + return value; + } + + @Override + public byte profile(byte value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_BYTE) { + byte castCachedValue = (byte) this.cachedValue; + if (castCachedValue == value) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + } + + @Override + public short profile(short value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_SHORT) { + short castCachedValue = (short) this.cachedValue; + if (castCachedValue == value) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + } + + @Override + public int profile(int value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_INTEGER) { + int castCachedValue = (int) this.cachedValue; + if (castCachedValue == value) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + } + + @Override + public long profile(long value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_LONG) { + long castCachedValue = (long) this.cachedValue; + if (castCachedValue == value) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + } + + @Override + public float profile(float value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_FLOAT) { + float castCachedValue = (float) this.cachedValue; + if (exactCompare(castCachedValue, value)) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + } + + @Override + public double profile(double value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_DOUBLE) { + double castCachedValue = (double) this.cachedValue; + if (exactCompare(castCachedValue, value)) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + + } + + @Override + public boolean profile(boolean value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_BOOLEAN) { + boolean castCachedValue = (boolean) this.cachedValue; + if (castCachedValue == value) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + } + + @Override + public char profile(char value) { + byte s = this.state; + if (s != STATE_GENERIC) { + if (s == STATE_CHARACTER) { + char castCachedValue = (char) this.cachedValue; + if (castCachedValue == value) { + return castCachedValue; + } + } + CompilerDirectives.transferToInterpreterAndInvalidate(); + slowpath(s, value); + } + return value; + } + + private void slowpath(byte s, Object value) { + if (s == STATE_UNINITIALIZED) { + cachedValue = value; + state = specialize(value); + } else { + state = STATE_GENERIC; + cachedValue = null; + } + } + + private static byte specialize(Object value) { + if (value instanceof Byte) { + return STATE_BYTE; + } else if (value instanceof Short) { + return STATE_SHORT; + } else if (value instanceof Integer) { + return STATE_INTEGER; + } else if (value instanceof Long) { + return STATE_LONG; + } else if (value instanceof Boolean) { + return STATE_BOOLEAN; + } else if (value instanceof Character) { + return STATE_CHARACTER; + } else if (value instanceof Double) { + return STATE_DOUBLE; + } else if (value instanceof Float) { + return STATE_FLOAT; + } else { + return STATE_IDENTITY; + } + } + + boolean isGeneric() { + return state == STATE_GENERIC; + } + + boolean isUninitialized() { + return state == STATE_UNINITIALIZED; + } + + Object getCachedValue() { + return cachedValue; + } + + @Override + public String toString() { + return toString(PrimitiveValueProfile.class, state == STATE_UNINITIALIZED, state == STATE_GENERIC, formatSpecialization()); + } + + private String formatSpecialization() { + Object snapshot = this.cachedValue; + if (state != STATE_UNINITIALIZED && state != STATE_GENERIC) { + if (snapshot == null) { + return String.format("value == null"); + } else { + if (state == STATE_IDENTITY) { + String simpleName = snapshot.getClass().getSimpleName(); + return String.format("value == %s@%x", simpleName, Objects.hash(snapshot)); + } else { + return String.format("value == (%s)%s", snapshot.getClass().getSimpleName(), snapshot); + } + } + } + return null; + } + + /** + * Returns a {@link PrimitiveValueProfile} that speculates on the primitive equality or + * object identity of a value. + */ + static PrimitiveValueProfile create() { + return new Enabled(); + } + } + + static final class Disabled extends PrimitiveValueProfile { + + static final PrimitiveValueProfile INSTANCE = new Disabled(); + + @Override + public T profile(T value) { + return value; + } + + @Override + public byte profile(byte value) { + return value; + } + + @Override + public short profile(short value) { + return value; + } + + @Override + public int profile(int value) { + return value; + } + + @Override + public long profile(long value) { + return value; + } + + @Override + public float profile(float value) { + return value; + } + + @Override + public double profile(double value) { + return value; + } + + @Override + public boolean profile(boolean value) { + return value; + } + + @Override + public char profile(char value) { + return value; + } + + @Override + public String toString() { + return toStringDisabled(PrimitiveValueProfile.class); + } + + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/Profile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/Profile.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,114 @@ +/* + * 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.Assumption; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.TruffleRuntime; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeCloneable; +import com.oracle.truffle.api.nodes.RootNode; + +/** + *

+ * 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: + *

    + *
  • {@link BranchProfile} to profile on unlikely branches like errors.
  • + *
  • {@link ConditionProfile} to profile on conditionals or boolean values.
  • + *
  • {@link LoopConditionProfile} to profile on conditionals of loops with special support for + * counted loops.
  • + *
  • {@link ValueProfile} to profile on properties like type and identity of values.
  • + *
  • {@link ByteValueProfile} to profile on byte values.
  • + *
  • {@link IntValueProfile} to profile on int values.
  • + *
  • {@link LongValueProfile} to profile on long values.
  • + *
  • {@link FloatValueProfile} to profile on float values.
  • + *
  • {@link DoubleValueProfile} to profile on double values.
  • + *
  • {@link PrimitiveValueProfile} to profile on objects by identity and on primitives by value.
  • + *
+ *

+ * + * @see Assumption + */ +public abstract class Profile extends NodeCloneable { + + Profile() { + /* We don't to allow custom profiles. We want to evolve this API further first. Sorry. */ + } + + String toStringDisabled(Class profileClass) { + return String.format("%s(DISABLED)", profileClass.getSimpleName()); + } + + String toString(Class profileClass, boolean uninitialized, boolean generic, String specialization) { + String s; + if (uninitialized) { + s = "UNINITIALIZED"; + } else if (generic) { + s = "GENERIC"; + } else { + s = specialization == null ? "" : specialization; + } + return String.format("%s(%s)@%s", profileClass.getSimpleName(), s, Integer.toHexString(this.hashCode())); + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ValueProfile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/ValueProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,334 @@ +/* + * 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; + +/** + *

+ * 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 T profile(T value); + + /** + *

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

+ * + * @see ValueProfile usage example + */ + public static ValueProfile createClassProfile() { + if (Truffle.getRuntime().isProfilingEnabled()) { + return ExactClass.create(); + } else { + return Disabled.INSTANCE; + } + } + + /** + *

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

+ */ + public static ValueProfile createIdentityProfile() { + if (Truffle.getRuntime().isProfilingEnabled()) { + return Identity.create(); + } else { + return Disabled.INSTANCE; + } + } + + /** + *

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

+ */ + public static ValueProfile createEqualityProfile() { + if (Truffle.getRuntime().isProfilingEnabled()) { + return Equality.create(); + } else { + return Disabled.INSTANCE; + } + } + + static final class Disabled extends ValueProfile { + + static final ValueProfile INSTANCE = new Disabled(); + + @Override + protected Object clone() { + return INSTANCE; + } + + @Override + public T profile(T value) { + return value; + } + + @Override + public String toString() { + return toStringDisabled(ValueProfile.class); + } + + } + + static final class Equality extends ValueProfile { + + private static final Object GENERIC = new Object(); + + @CompilationFinal protected Object cachedValue = null; + + Equality() { + } + + @Override + @SuppressWarnings("unchecked") + public T profile(T newValue) { + // Field needs to be cached in local variable for thread safety and startup speed. + Object cached = this.cachedValue; + if (cached != GENERIC) { + if (cached != null && cached.equals(newValue)) { + return (T) cached; + } else { + CompilerDirectives.transferToInterpreterAndInvalidate(); + if (cached == null && newValue != null) { + cachedValue = newValue; + } else { + cachedValue = GENERIC; + } + } + } + return newValue; + } + + public boolean isGeneric() { + return getCachedValue() == GENERIC; + } + + public boolean isUninitialized() { + return getCachedValue() == null; + } + + public Object getCachedValue() { + return cachedValue; + } + + @Override + public String toString() { + return toString(ValueProfile.class, isUninitialized(), isGeneric(), // + String.format("value == %s@%x", cachedValue != null ? cachedValue.getClass().getSimpleName() : "null", Objects.hash(cachedValue))); + } + + /* Needed for lazy class loading. */ + static ValueProfile create() { + return new Equality(); + } + + } + + static final class Identity extends ValueProfile { + + private static final Object UNINITIALIZED = new Object(); + private static final Object GENERIC = new Object(); + + @CompilationFinal protected Object cachedValue = UNINITIALIZED; + + Identity() { + } + + @Override + @SuppressWarnings("unchecked") + public T profile(T newValue) { + // Field needs to be cached in local variable for thread safety and startup speed. + Object cached = this.cachedValue; + if (cached != GENERIC) { + if (cached == newValue) { + return (T) cached; + } else { + CompilerDirectives.transferToInterpreterAndInvalidate(); + if (cachedValue == UNINITIALIZED) { + cachedValue = newValue; + } else { + cachedValue = GENERIC; + } + } + } + return newValue; + } + + public boolean isGeneric() { + return getCachedValue() == GENERIC; + } + + public boolean isUninitialized() { + return getCachedValue() == UNINITIALIZED; + } + + public Object getCachedValue() { + return cachedValue; + } + + @Override + public String toString() { + return toString(ValueProfile.class, isUninitialized(), isGeneric(), // + String.format("value == %s@%x", cachedValue != null ? cachedValue.getClass().getSimpleName() : "null", Objects.hash(cachedValue))); + } + + /* Needed for lazy class loading. */ + static ValueProfile create() { + return new Identity(); + } + + } + + static final class ExactClass extends ValueProfile { + + @CompilationFinal protected Class cachedClass; + + ExactClass() { + } + + public static ValueProfile create() { + return new ExactClass(); + } + + @SuppressWarnings("unchecked") + @Override + public T profile(T value) { + // Field needs to be cached in local variable for thread safety and startup speed. + Class clazz = cachedClass; + if (clazz != Object.class) { + if (clazz != null && value != null && clazz == value.getClass()) { + /* + * The cast is really only for the compiler relevant. It does not perform any + * useful action in the interpreter and only takes time. + */ + if (CompilerDirectives.inInterpreter()) { + return value; + } else { + return (T) clazz.cast(value); + } + } else { + CompilerDirectives.transferToInterpreterAndInvalidate(); + if (clazz == null && value != null) { + cachedClass = value.getClass(); + } else { + cachedClass = Object.class; + } + } + } + return value; + } + + boolean isGeneric() { + return cachedClass == Object.class; + } + + boolean isUninitialized() { + return cachedClass == null; + } + + Class getCachedClass() { + return cachedClass; + } + + @Override + public String toString() { + return toString(ValueProfile.class, cachedClass == null, cachedClass == Object.class, // + String.format("value.getClass() == %s.class", cachedClass != null ? cachedClass.getSimpleName() : "null")); + } + + } + +} diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/package-info.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/profiles/package-info.java Wed Dec 16 16:38:13 2015 +0100 @@ -0,0 +1,39 @@ +/* + * 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. + */ + +/* + @ApiInfo( + group="Stable" + ) + */ +/** + * A profile is a Truffle utility class that uses the + * {@link com.oracle.truffle.api.CompilerDirectives Truffle compiler directives} to guard for and/or + * forward runtime information to the compiler. + * + * @see com.oracle.truffle.api.profiles.Profile + */ +package com.oracle.truffle.api.profiles; + diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BinaryConditionProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -28,11 +28,11 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; /** - * 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() + * @deprecated package name renamed to {@link com.oracle.truffle.api.profiles.ConditionProfile} + * instead */ +@SuppressWarnings("deprecation") +@Deprecated public final class BinaryConditionProfile extends ConditionProfile { @CompilationFinal private boolean wasTrue; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/BranchProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -29,14 +29,9 @@ import com.oracle.truffle.api.nodes.NodeCloneable; /** - * Utility class to speculate on branches to be never 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. - * - * All {@code BranchProfile} instances must be held in {@code final} fields for compiler - * optimizations to take effect. + * @deprecated use {@link com.oracle.truffle.api.profiles.BranchProfile} instead */ +@Deprecated public final class BranchProfile extends NodeCloneable { @CompilationFinal private boolean visited; @@ -55,6 +50,10 @@ return visited; } + /** + * @deprecated use {@link com.oracle.truffle.api.profiles.BranchProfile#create()} instead + */ + @Deprecated public static BranchProfile create() { return new BranchProfile(); } diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ConditionProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -24,33 +24,12 @@ */ package com.oracle.truffle.api.utilities; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.nodes.NodeCloneable; /** - * Abstract utility class to speculate on conditions. Condition profiles are intended to be used as - * part of if conditions. - * - * Example usage: - * - *
- * private final ConditionProfile zero = ConditionProfile.createBinaryProfile();
- *
- * int value = ...;
- * if (zero.profile(value == 0)) {
- *   return 0;
- * } else {
- *   return value;
- * }
- *
- * 
- * - * All instances of {@code ConditionProfile} (and subclasses) must be held in {@code final} fields - * for compiler optimizations to take effect. - * - * @see #createCountingProfile() - * @see #createBinaryProfile() + * @deprecated use {@link com.oracle.truffle.api.profiles.ConditionProfile} instead */ +@Deprecated public abstract class ConditionProfile extends NodeCloneable { ConditionProfile() { } @@ -58,27 +37,23 @@ 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() + * @deprecated use + * {@link com.oracle.truffle.api.profiles.ConditionProfile#createCountingProfile()} + * instead */ + @SuppressWarnings("deprecation") + @Deprecated public static ConditionProfile createCountingProfile() { return new CountingConditionProfile(); } /** - * 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() + * @deprecated use + * {@link com.oracle.truffle.api.profiles.ConditionProfile#createBinaryProfile()} + * instead */ + @Deprecated + @SuppressWarnings("deprecation") public static ConditionProfile createBinaryProfile() { return new BinaryConditionProfile(); } diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CountingConditionProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CountingConditionProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/CountingConditionProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -28,14 +28,11 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; /** - * Utility class to speculate on conditions to be never true or to be never false. Additionally to - * {@link BinaryConditionProfile} this implementation of {@link ConditionProfile} 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#createCountingProfile() + * @deprecated use {@link com.oracle.truffle.api.profiles.ConditionProfile#createCountingProfile()} + * instead */ +@Deprecated +@SuppressWarnings("deprecation") public final class CountingConditionProfile extends ConditionProfile { @CompilationFinal private int trueCount; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ExactClassValueProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -28,8 +28,10 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; /** - * Represents a {@link ValueProfile} that speculates on the exact class of a value. + * @deprecated use {@link com.oracle.truffle.api.profiles.ValueProfile#createClassProfile()} instead */ +@Deprecated +@SuppressWarnings("deprecation") final class ExactClassValueProfile extends ValueProfile { @CompilationFinal protected Class cachedClass; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/IdentityValueProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/IdentityValueProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/IdentityValueProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -26,11 +26,15 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; + import java.util.Objects; /** - * Represents a {@link ValueProfile} that speculates on the object identity of a value. + * @deprecated use {@link com.oracle.truffle.api.profiles.ValueProfile#createIdentityProfile()} + * instead */ +@Deprecated +@SuppressWarnings("deprecation") final class IdentityValueProfile extends ValueProfile { private static final Object UNINITIALIZED = new Object(); diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/PrimitiveValueProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -26,17 +26,14 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; + import java.util.Objects; /** - * 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. + * @deprecated use {@link com.oracle.truffle.api.profiles.PrimitiveValueProfile} instead */ +@Deprecated +@SuppressWarnings("deprecation") public class PrimitiveValueProfile extends ValueProfile { private static final Object UNINITIALIZED = new Object(); diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/ValueProfile.java Wed Dec 16 16:38:13 2015 +0100 @@ -27,51 +27,38 @@ import com.oracle.truffle.api.nodes.NodeCloneable; /** - * Utility class to speculate on certain properties of values. - * - * Example usage: - * - *

- * private final ValueProfile classProfile = ValueProfile.createClassProfile();
- *
- * return classProfile.profile(value);
- * 
- * - * All instances of {@code ValueProfile} (and subclasses) must be held in {@code final} fields for - * compiler optimizations to take effect. - * - * @see #createPrimitiveProfile() - * @see #createIdentityProfile() - * @see #createClassProfile() + * @deprecated use {@link com.oracle.truffle.api.profiles.ValueProfile} instead */ +@Deprecated +@SuppressWarnings("deprecation") public abstract class ValueProfile extends NodeCloneable { public abstract T profile(T value); /** - * Returns a {@link PrimitiveValueProfile} that speculates on the primitive equality or object - * identity of a value. + * @deprecated use + * {@link com.oracle.truffle.api.profiles.PrimitiveValueProfile#createEqualityProfile()} + * instead */ + @Deprecated public static PrimitiveValueProfile createPrimitiveProfile() { return new PrimitiveValueProfile(); } /** - * Returns a {@link ValueProfile} that speculates on 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. + * @deprecated use {@link com.oracle.truffle.api.profiles.ValueProfile#createClassProfile()} + * instead */ + @Deprecated public static ValueProfile createClassProfile() { return new ExactClassValueProfile(); } /** - * Returns a {@link ValueProfile} that speculates on the object identity of a value. + * @deprecated use {@link com.oracle.truffle.api.profiles.ValueProfile#createIdentityProfile()} + * instead */ + @Deprecated public static ValueProfile createIdentityProfile() { return new IdentityValueProfile(); } diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/package-info.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/package-info.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/utilities/package-info.java Wed Dec 16 16:38:13 2015 +0100 @@ -28,8 +28,24 @@ group="To Review" ) */ - -/** Various utility methods. +/** + * Various utility classes that aim to make the development of TruffleLanguage guest + * languages easier. + * + *

+ * We try to capture common language patterns in this package. Here is an overview of patterns that + * we have captured so far: + *

    + *
  • {@link com.oracle.truffle.api.utilities.AssumedValue} speculates on global values to remain + * unchanged.
  • + *
  • {@link com.oracle.truffle.api.utilities.CyclicAssumption} speculates on assumptions that + * might invalidate more often but are assumed to stabilize over time.
  • + *
  • {@link com.oracle.truffle.api.utilities.NeverValidAssumption} utility for assumptions that + * are always invalidated
  • + *
  • {@link com.oracle.truffle.api.utilities.UnionAssumption} utility for the union of two + * assumptions
  • + *
+ *

*/ package com.oracle.truffle.api.utilities; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java Wed Dec 16 16:38:13 2015 +0100 @@ -43,7 +43,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.utilities.BranchProfile; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.sl.nodes.SLExpressionNode; import com.oracle.truffle.sl.nodes.SLRootNode; import com.oracle.truffle.sl.nodes.SLStatementNode; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java Wed Dec 16 16:38:13 2015 +0100 @@ -46,9 +46,7 @@ import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.utilities.BinaryConditionProfile; -import com.oracle.truffle.api.utilities.ConditionProfile; -import com.oracle.truffle.api.utilities.CountingConditionProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.sl.nodes.SLExpressionNode; import com.oracle.truffle.sl.nodes.SLStatementNode; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLRepeatingNode.java Wed Dec 16 16:38:13 2015 +0100 @@ -46,7 +46,7 @@ import com.oracle.truffle.api.nodes.RepeatingNode; import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.utilities.BranchProfile; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.sl.nodes.SLExpressionNode; import com.oracle.truffle.sl.nodes.SLStatementNode; diff -r fbe1eb7b4172 -r a63bda98cfdb truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java --- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java Wed Dec 16 12:31:17 2015 +0100 +++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java Wed Dec 16 16:38:13 2015 +0100 @@ -41,8 +41,8 @@ package com.oracle.truffle.sl.nodes.local; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.utilities.BranchProfile; import com.oracle.truffle.sl.nodes.SLExpressionNode; import com.oracle.truffle.sl.parser.SLNodeFactory; import com.oracle.truffle.sl.runtime.SLNull;