Mercurial > hg > graal-compiler
view graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/InstrumentationPartialEvaluationTest.java @ 22940:36a46bae0a59
update truffle import.
author | Andreas Woess <andreas.woess@oracle.com> |
---|---|
date | Tue, 03 Nov 2015 23:38:32 +0100 |
parents | 1fc7ee8c9443 |
children |
line wrap: on
line source
/* * 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.graal.truffle.test; import java.io.IOException; import java.lang.reflect.Field; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.oracle.graal.truffle.test.InstrumentationPETestLanguage.TestRootNode; import com.oracle.truffle.api.instrument.ASTProber; import com.oracle.truffle.api.instrument.Instrument; import com.oracle.truffle.api.instrument.Instrumenter; import com.oracle.truffle.api.instrument.Probe; import com.oracle.truffle.api.instrument.impl.DefaultSimpleInstrumentListener; import com.oracle.truffle.api.instrument.impl.DefaultStandardInstrumentListener; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.vm.PolyglotEngine; // TODO add some tests for the replacement for AdvancedInstrumentRootFactory /** * Partial evaluation tests on a constant valued RootNode with various instrumentation operations * applied to it. None of the instrumentation ultimately does anything, so should compile away. * <p> * A specialized test language produces a root with a single constant-valued child, no matter what * source is eval'd. * <p> * Taking care to avoid creating sources that appear equal so there won't be any sharing in the * engine. */ public class InstrumentationPartialEvaluationTest extends PartialEvaluationTest { PolyglotEngine vm; Instrumenter instrumenter; public static Object constant42() { return 42; } @Before public void before() { // TODO (mlvdv) eventually abstract this try { vm = PolyglotEngine.newBuilder().build(); final Field field = PolyglotEngine.class.getDeclaredField("instrumenter"); field.setAccessible(true); instrumenter = (Instrumenter) field.get(vm); final java.lang.reflect.Field testVMField = Instrumenter.class.getDeclaredField("testVM"); testVMField.setAccessible(true); testVMField.set(instrumenter, vm); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { fail("Reflective access to Instrumenter for testing"); } } @Override @After public void after() { vm.dispose(); vm = null; instrumenter = null; super.after(); } // TODO (mlvdv) fix other PE tests; move down the before/after setup @Test public void uninstrumented() throws IOException { final Source source = Source.fromText("uninstrumented", "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); root[0] = rootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedNoListeners() throws IOException { final String testName = "probedNoListeners"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node, but attach no listeners instrumenter.probe(testRootNode.getBody()); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithNullSimpleListener() throws IOException { final String testName = "probedWithNullSimpleListener"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach a "simple" empty listener instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithNullStandardListener() throws IOException { final String testName = "probedWithNullStandardListener"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach a "standard" empty listener instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithNullSimpleListenerDisposed() throws IOException { final String testName = "probedWithNullSimpleListenerDisposed"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach a "simple" empty listener final Instrument instrument = instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); // Detach the listener instrument.dispose(); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithNullStandardListenerDisposed() throws IOException { final String testName = "probedWithNullStandardListenerDisposed"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach a "standard" empty listener final Instrument instrument = instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); // Detach the listener instrument.dispose(); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithTwoSimpleListeners() throws IOException { final String testName = "probedWithTwoSimpleListeners"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach two "simple" empty listeners instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithTwoStandardListeners() throws IOException { final String testName = "probedWithTwoStandardListeners"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRotoNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRotoNode.getBody()); // Attach two "standard" empty listeners instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); root[0] = testRotoNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithThreeSimpleListeners() throws IOException { final String testName = "probedWithThreeSimpleListeners"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach three "simple" empty listeners instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithThreeStandardListeners() throws IOException { final String testName = "probedWithThreeStandardListeners"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach three "standard" empty listeners instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithThreeSimpleListenersOneDisposed() throws IOException { final String testName = "probedWithThreeSimpleListenersOneDisposed"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; // Abuse instrumentation to get a copy of the root node before execution instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach three "simple" empty listeners instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); final Instrument disposeMe = instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); instrumenter.attach(probe, new DefaultSimpleInstrumentListener(), testName); disposeMe.dispose(); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } @Test public void probedWithThreeStandardListenersOneDisposed() throws IOException { final String testName = "probedWithThreeStandardListenersOneDisposed"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; instrumenter.registerASTProber(new ASTProber() { public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node final Probe probe = instrumenter.probe(testRootNode.getBody()); // Attach three "standard" empty listeners instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); final Instrument disposeMe = instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); instrumenter.attach(probe, new DefaultStandardInstrumentListener(), testName); disposeMe.dispose(); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); assertPartialEvalEquals("constant42", root[0]); } /** * Sketch of how a test for deopt might work. */ @Test public void instrumentDeopt() throws IOException { final String testName = "instrumentDeopt"; final Source source = Source.fromText(testName, "any text").withMimeType("text/x-instPETest"); final RootNode[] root = new RootNode[1]; final Probe[] probe = new Probe[1]; final int[] count = {0}; // Register a "prober" that will get applied when CallTarget gets created. instrumenter.registerASTProber(new ASTProber() { @Override public void probeAST(Instrumenter inst, RootNode rootNode) { instrumenter.unregisterASTProber(this); final TestRootNode testRootNode = (TestRootNode) rootNode; // Probe the value node probe[0] = instrumenter.probe(testRootNode.getBody()); root[0] = testRootNode; } }); Assert.assertEquals(vm.eval(source).get(), 42); Assert.assertEquals(0, count[0]); // Didn't count anything // Add a counting instrument; this changes the "Probe state" and should cause a deopt final Instrument countingInstrument = instrumenter.attach(probe[0], new DefaultSimpleInstrumentListener() { @Override public void onEnter(Probe p) { count[0] = count[0] + 1; } }, testName); Assert.assertEquals(vm.eval(source).get(), 42); Assert.assertEquals(1, count[0]); // Counted the first call // Remove the counting instrument; this changes the "Probe state" and should cause a // deopt countingInstrument.dispose(); Assert.assertEquals(vm.eval(source).get(), 42); Assert.assertEquals(1, count[0]); // Didn't count this time } }