From a8585cf5ada0777b74c2a910ecc84b61c868134d Mon Sep 17 00:00:00 2001 From: Lukas Stadler <lukas.stadler@oracle.com> Date: Thu, 29 Jun 2017 19:01:41 +0200 Subject: [PATCH] rework switching of allocation tracing, cleanups --- .../oracle/truffle/r/library/utils/Rprof.java | 39 ++++---- .../truffle/r/library/utils/Rprofmem.java | 66 ++++++------- .../r/nodes/builtin/base/AsVector.java | 2 +- .../nodes/builtin/base/TrigExpFunctions.java | 3 - .../r/nodes/builtin/fastr/FastRInterop.java | 3 +- .../r/nodes/builtin/fastr/FastRStats.java | 57 +++++------ .../fastr/memprof/FastRprofmemShow.java | 2 +- .../fastr/memprof/FastRprofmemSnapshot.java | 2 +- .../fastr/memprof/FastRprofmemSource.java | 5 +- .../castsTests/ResultTypesAnalyserTest.java | 7 +- .../vector/CachedReplaceVectorNode.java | 1 - .../truffle/r/nodes/unary/CastListNode.java | 3 - .../truffle/r/runtime/context/RContext.java | 6 +- .../truffle/r/runtime/data/RDataFactory.java | 96 +++++++++++-------- .../memprof/MemAllocProfilerPaths.java | 16 ++-- .../r/runtime/interop/ForeignArray2R.java | 6 +- 16 files changed, 160 insertions(+), 154 deletions(-) diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java index f6b5274db4..49efa1fd13 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprof.java @@ -81,7 +81,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; * the function name. * */ -public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFactory.Listener, MemoryCopyTracer.Listener { +public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements MemoryCopyTracer.Listener { static { Casts casts = new Casts(Rprof.class); @@ -114,8 +114,7 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa warning(RError.Message.GENERIC, "Rprof: gc profiling not supported"); } if (memProfiling) { - RDataFactory.addListener(this); - RDataFactory.setTracingState(true); + RDataFactory.addListener(LISTENER); MemoryCopyTracer.addListener(this); MemoryCopyTracer.setTracingState(true); } @@ -133,24 +132,26 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa return RNull.instance; } - @Override - @TruffleBoundary - public void reportAllocation(RTypedValue data) { - RprofState profState = RprofState.get(); - if (profState.memoryQuad == null) { - return; - } - long size = RObjectSize.getObjectSize(data, Rprofmem.myIgnoreObjectHandler); - if (data instanceof RAbstractVector) { - if (size >= Rprofmem.LARGE_VECTOR) { - profState.memoryQuad.largeV += size; + private static final RDataFactory.Listener LISTENER = new RDataFactory.Listener() { + @Override + @TruffleBoundary + public void reportAllocation(RTypedValue data) { + RprofState profState = RprofState.get(); + if (profState.memoryQuad == null) { + return; + } + long size = RObjectSize.getObjectSize(data, Rprofmem.myIgnoreObjectHandler); + if (data instanceof RAbstractVector) { + if (size >= Rprofmem.LARGE_VECTOR) { + profState.memoryQuad.largeV += size; + } else { + profState.memoryQuad.smallV += size; + } } else { - profState.memoryQuad.smallV += size; + profState.memoryQuad.nodes += size; } - } else { - profState.memoryQuad.nodes += size; } - } + }; @Override @TruffleBoundary @@ -362,7 +363,7 @@ public abstract class Rprof extends RExternalBuiltinNode.Arg8 implements RDataFa out.close(); this.setOut(null); if (this.memoryProfiling) { - RDataFactory.setTracingState(false); + RDataFactory.removeListener(LISTENER); MemoryCopyTracer.setTracingState(false); } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java index 34a5b00b39..197dc7b9bd 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Rprofmem.java @@ -49,7 +49,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.instrument.InstrumentationState.RprofState; -public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDataFactory.Listener { +public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 { static { Casts casts = new Casts(Rprofmem.class); @@ -75,8 +75,7 @@ public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDat try { PrintStream out = new PrintStream(new FileOutputStream(filename, append)); profmemState.initialize(out, thresholdVec.getDataAt(0)); - RDataFactory.addListener(this); - RDataFactory.setTracingState(true); + RDataFactory.addListener(LISTENER); } catch (IOException ex) { throw error(RError.Message.GENERIC, String.format("Rprofmem: cannot open profile file '%s'", filename)); } @@ -116,39 +115,40 @@ public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDat static final RObjectSize.IgnoreObjectHandler myIgnoreObjectHandler = new MyIgnoreObjectHandler(); - @Override - @TruffleBoundary - public void reportAllocation(RTypedValue data) { - // We could do some in memory buffering - // TODO write out full stack - RprofmemState profmemState = RprofmemState.get(); - Frame frame = Utils.getActualCurrentFrame(); - if (frame == null) { - // not an R evaluation, some internal use - return; - } - RFunction func = RArguments.getFunction(frame); - if (func == null) { - return; - } - String name = func.getRootNode().getName(); - - long size = RObjectSize.getObjectSize(data, myIgnoreObjectHandler); - if (data instanceof RAbstractVector && size >= LARGE_VECTOR) { - if (size > profmemState.threshold) { - profmemState.out().printf("%d: %s\n", size, name); + private static final RDataFactory.Listener LISTENER = new RDataFactory.Listener() { + @Override + public void reportAllocation(RTypedValue data) { + // We could do some in memory buffering + // TODO write out full stack + RprofmemState profmemState = RprofmemState.get(); + Frame frame = Utils.getActualCurrentFrame(); + if (frame == null) { + // not an R evaluation, some internal use + return; } - } else { - int pageCount = profmemState.pageCount; - long pcs = pageCount + size; - if (pcs > PAGE_SIZE) { - profmemState.out().printf("new page: %s\n", name); - profmemState.pageCount = (int) (pcs - PAGE_SIZE); + RFunction func = RArguments.getFunction(frame); + if (func == null) { + return; + } + String name = func.getRootNode().getName(); + + long size = RObjectSize.getObjectSize(data, myIgnoreObjectHandler); + if (data instanceof RAbstractVector && size >= LARGE_VECTOR) { + if (size > profmemState.threshold) { + profmemState.out().printf("%d: %s\n", size, name); + } } else { - profmemState.pageCount = (int) pcs; + int pageCount = profmemState.pageCount; + long pcs = pageCount + size; + if (pcs > PAGE_SIZE) { + profmemState.out().printf("new page: %s\n", name); + profmemState.pageCount = (int) (pcs - PAGE_SIZE); + } else { + profmemState.pageCount = (int) pcs; + } } } - } + }; private static final class RprofmemState extends RprofState { private double threshold; @@ -170,7 +170,7 @@ public abstract class Rprofmem extends RExternalBuiltinNode.Arg3 implements RDat @Override public void cleanup(int status) { - RDataFactory.setTracingState(false); + RDataFactory.removeListener(LISTENER); closeAndResetOut(); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java index 7cbc81998e..233e19751c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java @@ -267,7 +267,7 @@ public abstract class AsVector extends RBuiltinNode.Arg2 { } @Fallback - protected Object castPairlist(@SuppressWarnings("unused") Object x) { + protected Object castPairlist(Object x) { throw RInternalError.unimplemented("non-list casts to pairlist for " + x.getClass().getSimpleName()); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java index 37c52d9142..cfa92609f7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/TrigExpFunctions.java @@ -31,12 +31,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.LoopConditionProfile; -import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java index d87fd82091..5678a43e44 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRInterop.java @@ -133,10 +133,9 @@ public class FastRInterop { return parse(mimeType, source).call(); } - @SuppressWarnings("unused") @Specialization() @TruffleBoundary - protected Object eval(RMissing mimeType, String source, RMissing path) { + protected Object eval(@SuppressWarnings("unused") RMissing mimeType, @SuppressWarnings("unused") String source, @SuppressWarnings("unused") RMissing path) { throw RError.error(this, RError.Message.INVALID_ARG, "mimeType"); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java index 458fa6ebef..e09fae33d3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRStats.java @@ -158,7 +158,7 @@ public class FastRStats { } @RBuiltin(name = ".fastr.stats.typecounts", visibility = OFF, kind = PRIMITIVE, parameterNames = {"filename", "append"}, behavior = COMPLEX) - public abstract static class FastRProfTypecounts extends RBuiltinNode.Arg2 implements RDataFactory.Listener { + public abstract static class FastRProfTypecounts extends RBuiltinNode.Arg2 { @Override public Object[] getDefaultParameterValues() { return new Object[]{"Rproftypecounts.out", RRuntime.LOGICAL_FALSE}; @@ -190,8 +190,7 @@ public class FastRStats { try { PrintStream out = new PrintStream(new FileOutputStream(filenameVec.getDataAt(0), append)); state.setOut(out); - RDataFactory.addListener(this); - RDataFactory.setTracingState(true); + RDataFactory.addListener(LISTENER); } catch (IOException ex) { throw error(RError.Message.GENERIC, String.format("Rprofmem: cannot open profile file '%s'", filenameVec.getDataAt(0))); } @@ -202,36 +201,38 @@ public class FastRStats { protected void endProfiling() { State state = State.get(); if (state.out() != null) { - RDataFactory.setTracingState(false); + RDataFactory.removeListener(LISTENER); state.cleanup(0); } } - @Override - public void reportAllocation(RTypedValue data) { - Class<? extends RTypedValue> klass = data.getClass(); - boolean isVector = (data instanceof RAbstractVector); - State state = State.get(); - Map<Class<? extends RTypedValue>, SortedMap<Integer, State.Counter>> typecountsMap = state.getTypecountsMap(); - SortedMap<Integer, State.Counter> countsMap = typecountsMap.get(klass); - if (countsMap == null) { - countsMap = new TreeMap<>(); - typecountsMap.put(klass, countsMap); - } - int length; - if (isVector) { - RAbstractVector vector = (RAbstractVector) data; - length = vector.getLength(); - } else { - length = 1; - } - State.Counter count = countsMap.get(length); - if (count == null) { - count = new State.Counter(); - countsMap.put(length, count); + private static final RDataFactory.Listener LISTENER = new RDataFactory.Listener() { + @Override + public void reportAllocation(RTypedValue data) { + Class<? extends RTypedValue> klass = data.getClass(); + boolean isVector = (data instanceof RAbstractVector); + State state = State.get(); + Map<Class<? extends RTypedValue>, SortedMap<Integer, State.Counter>> typecountsMap = state.getTypecountsMap(); + SortedMap<Integer, State.Counter> countsMap = typecountsMap.get(klass); + if (countsMap == null) { + countsMap = new TreeMap<>(); + typecountsMap.put(klass, countsMap); + } + int length; + if (isVector) { + RAbstractVector vector = (RAbstractVector) data; + length = vector.getLength(); + } else { + length = 1; + } + State.Counter count = countsMap.get(length); + if (count == null) { + count = new State.Counter(); + countsMap.put(length, count); + } + count.incCount(); } - count.incCount(); - } + }; private static class State extends RprofState { public static class Counter { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java index b91d1b1de2..b85dfe90a7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemShow.java @@ -77,7 +77,7 @@ public abstract class FastRprofmemShow extends RBuiltinNode.Arg6 { private static Object show(int levels, boolean desc, Integer entryId, boolean printParents, String view, MemAllocProfilerPaths snapshot) { MemAllocProfilerPaths usedSnapshot = snapshot; if (FastRprofmem.HOTSPOTS_VIEW.equals(view)) { - usedSnapshot = usedSnapshot.toHotSpots(); + usedSnapshot = usedSnapshot.toHS(); } FastRprofmem.getProfilerPrinter().show(usedSnapshot, entryId, levels, desc, printParents); return RNull.instance; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java index 9c04dc658b..4c86181456 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSnapshot.java @@ -57,7 +57,7 @@ public abstract class FastRprofmemSnapshot extends RBuiltinNode.Arg2 { MemAllocProfilerPaths snapshot = MemAllocProfilerStacks.getInstance().getStackPaths().getOrMakeSnapshot(name); if (FastRprofmem.HOTSPOTS_VIEW.equals(view)) { - snapshot = snapshot.toHotSpots(); + snapshot = snapshot.toHS(); } return snapshot.toTruffleObject(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java index 5339bbaac4..3c008c7eec 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/memprof/FastRprofmemSource.java @@ -22,7 +22,6 @@ */ package com.oracle.truffle.r.nodes.builtin.fastr.memprof; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.singleElement; import static com.oracle.truffle.r.nodes.builtin.fastr.memprof.FastRprofmem.castSnapshotArg; import static com.oracle.truffle.r.nodes.builtin.fastr.memprof.FastRprofmem.castViewArg; @@ -59,18 +58,16 @@ public abstract class FastRprofmemSource extends RBuiltinNode.Arg3 { public Object showSource(int entryId, String view, TruffleObject snapshotTO) { MemAllocProfilerPaths paths = MemAllocProfilerPaths.fromTruffleObject(snapshotTO); return showSource(entryId, view, paths); - } private static Object showSource(int entryId, String view, MemAllocProfilerPaths snap) { MemAllocProfilerPaths snapshot = snap; if (FastRprofmem.HOTSPOTS_VIEW.equals(view)) { - snapshot = snapshot.toHotSpots(); + snapshot = snapshot.toHS(); } FastRprofmem.getProfilerPrinter().source(snapshot, entryId); return RNull.instance; } - } diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java index 19dea4141a..85f11a3b1d 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java @@ -22,8 +22,6 @@ */ package com.oracle.truffle.r.nodes.castsTests; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.emptyIntegerVector; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullConstant; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.atomicIntegerValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.atomicLogicalValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.chain; @@ -32,6 +30,7 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.constant; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.dimEq; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.doubleToInt; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.elementAt; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.emptyIntegerVector; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.eq; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.intNA; @@ -43,14 +42,15 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.mapIf; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.matrix; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.missingValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.not; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullConstant; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.squareMatrix; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; -import static com.oracle.truffle.r.nodes.casts.TypeExpr.atom; import static com.oracle.truffle.r.nodes.casts.MarkLookup.mark; +import static com.oracle.truffle.r.nodes.casts.TypeExpr.atom; import java.lang.reflect.Type; import java.util.Map; @@ -71,7 +71,6 @@ import com.oracle.truffle.r.nodes.casts.TypeExpr; import com.oracle.truffle.r.nodes.castsTests.CastBuilderTest.DummyBuiltin; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java index cea19e14d2..11d21398ee 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java @@ -32,7 +32,6 @@ import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import com.oracle.truffle.api.object.DynamicObject; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java index 2275f18416..d08d2bbf5c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java @@ -33,7 +33,6 @@ import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; -import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.context.RContext; @@ -49,8 +48,6 @@ import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.interop.Foreign2R; -import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen; import com.oracle.truffle.r.runtime.interop.ForeignArray2R; import com.oracle.truffle.r.runtime.interop.ForeignArray2RNodeGen; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java index d12bdff737..a35713f109 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java @@ -66,10 +66,10 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltinKind; import com.oracle.truffle.r.runtime.builtins.RBuiltinLookup; import com.oracle.truffle.r.runtime.conn.ConnectionSupport; import com.oracle.truffle.r.runtime.conn.StdConnections; +import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTruffleObject; -import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; @@ -77,7 +77,6 @@ import com.oracle.truffle.r.runtime.instrument.InstrumentationState; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; import com.oracle.truffle.r.runtime.rng.RRNG; -import com.oracle.truffle.r.runtime.data.RDataFactory; /** * Encapsulates the runtime state ("context") of an R session. All access to that state from the @@ -398,6 +397,7 @@ public final class RContext implements RTruffleObject { this.allocationReporter = env.lookup(AllocationReporter.class); this.allocationReporter.addPropertyChangeListener(ALLOCATION_ACTIVATION_LISTENER); + RDataFactory.setAllocationTracingEnabled(allocationReporter.isActive()); } /** @@ -812,7 +812,7 @@ public final class RContext implements RTruffleObject { private static final PropertyChangeListener ALLOCATION_ACTIVATION_LISTENER = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { - RDataFactory.setTracingState(event.getNewValue() == Boolean.TRUE); + RDataFactory.setAllocationTracingEnabled(event.getNewValue() == Boolean.TRUE); } }; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index c3c0ff363a..56ac7016f2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java @@ -31,10 +31,10 @@ import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.instrumentation.AllocationReporter; -import com.oracle.truffle.api.utilities.CyclicAssumption; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RInternalError; @@ -160,7 +160,6 @@ public final class RDataFactory { } public static RComplexVector createComplexVector(double[] data, boolean complete, int[] dims, RStringVector names) { - return traceDataCreated(new RComplexVector(data, complete, dims, names)); } @@ -223,7 +222,6 @@ public final class RDataFactory { } public static RLogicalVector createLogicalVector(byte[] data, boolean complete, int[] dims, RStringVector names) { - return traceDataCreated(new RLogicalVector(data, complete, dims, names)); } @@ -233,30 +231,25 @@ public final class RDataFactory { public static RIntSequence createAscendingRange(int start, int end) { assert start <= end; - return traceDataCreated(new RIntSequence(start, 1, end - start + 1)); } public static RIntSequence createDescendingRange(int start, int end) { assert start > end; - return traceDataCreated(new RIntSequence(start, -1, start - end + 1)); } public static RIntSequence createIntSequence(int start, int stride, int length) { - return traceDataCreated(new RIntSequence(start, stride, length)); } public static RDoubleSequence createAscendingRange(double start, double end) { assert start <= end; - return traceDataCreated(new RDoubleSequence(start, 1, (int) ((end - start) + 1))); } public static RDoubleSequence createDescendingRange(double start, double end) { assert start > end; - return traceDataCreated(new RDoubleSequence(start, -1, (int) ((start - end) + 1))); } @@ -398,7 +391,6 @@ public final class RDataFactory { } public static RList createList(Object[] data, int[] newDimensions, RStringVector names) { - return traceDataCreated(new RList(data, newDimensions, names)); } @@ -565,53 +557,71 @@ public final class RDataFactory { * allocated. Owing to the use of the Assumption, there should be no overhead when disabled. */ - private static Deque<Listener> listeners = new ConcurrentLinkedDeque<>(); + private static final Deque<Listener> listeners = new ConcurrentLinkedDeque<>(); + private static boolean allocationTracingEnabled = false; - @CompilationFinal private static byte enabled = RRuntime.LOGICAL_NA; + @CompilationFinal private static StateAssumption stateAssumption = new StateAssumption(); - private static final CyclicAssumption noAllocationTracingAssumption = new CyclicAssumption("data allocation"); + /** + * As long as "off" is valid, the feature is off. It is on as long as "on" is valid. + */ + public static final class StateAssumption { + private final Assumption off = Truffle.getRuntime().createAssumption("off"); + private final Assumption on = Truffle.getRuntime().createAssumption("on"); - public static void setTracingState(boolean newState) { - byte newStateLogical = RRuntime.asLogical(newState); - if (enabled != newStateLogical) { - noAllocationTracingAssumption.invalidate(); - enabled = newStateLogical; + public boolean isEnabled() { + return !off.isValid() && on.isValid(); } - } - private static <T> T traceDataCreated(T data) { - if (RRuntime.isNA(enabled)) { - RContext ctx = RContext.getThreadLocalInstance(); - if (ctx != null) { - setTracingState(ctx.getAllocationReporter().isActive()); + public StateAssumption setState(boolean enabled) { + if (enabled && !stateAssumption.isEnabled()) { + assert !isEnabled(); + off.invalidate(); + return this; + } else if (!enabled && stateAssumption.isEnabled()) { + assert isEnabled(); + on.invalidate(); + return new StateAssumption(); + } else { + // no change needed + return this; } } + } - if (enabled == RRuntime.LOGICAL_TRUE) { + public static synchronized void setAllocationTracingEnabled(boolean enabled) { + allocationTracingEnabled = enabled; + updateTracingState(); + } - if (noAllocationTracingAssumption.getAssumption().isValid()) { - reportAllocation(data); - } + private static synchronized void updateTracingState() { + boolean enabled = !listeners.isEmpty() || allocationTracingEnabled; + stateAssumption = stateAssumption.setState(enabled); + } - for (Listener listener : listeners) { - listener.reportAllocation((RTypedValue) data); - } + private static <T> T traceDataCreated(T data) { + if (stateAssumption.isEnabled()) { + reportDataCreated(data); } - return data; } @TruffleBoundary - private static void reportAllocation(Object data) { - RContext ctx = RContext.getThreadLocalInstance(); - assert ctx != null; - AllocationReporter allocationReporter = ctx.getAllocationReporter(); - - allocationReporter.onEnter(null, 0, AllocationReporter.SIZE_UNKNOWN); + private static void reportDataCreated(Object data) { + System.out.println("reportDataCreated " + listeners.size() + " " + allocationTracingEnabled); + if (allocationTracingEnabled) { + RContext ctx = RContext.getThreadLocalInstance(); + assert ctx != null; + AllocationReporter allocationReporter = ctx.getAllocationReporter(); - long size = data instanceof RTypedValue ? getSize((RTypedValue) data) : AllocationReporter.SIZE_UNKNOWN; - allocationReporter.onReturnValue(data, 0, size); + allocationReporter.onEnter(null, 0, AllocationReporter.SIZE_UNKNOWN); + long size = data instanceof RTypedValue ? getSize((RTypedValue) data) : AllocationReporter.SIZE_UNKNOWN; + allocationReporter.onReturnValue(data, 0, size); + } + for (Listener listener : listeners) { + listener.reportAllocation((RTypedValue) data); + } } public interface Listener { @@ -630,8 +640,14 @@ public final class RDataFactory { * Sets the listener of memory tracing events. For the time being there can only be one * listener. This can be extended to an array should we need more listeners. */ - public static void addListener(Listener listener) { + public static synchronized void addListener(Listener listener) { listeners.addLast(listener); + updateTracingState(); + } + + public static synchronized void removeListener(Listener listener) { + listeners.remove(listener); + updateTracingState(); } private static Object[] createRNullArray(int size) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java index 75ca4b5c90..14aa7cb15f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/instrument/memprof/MemAllocProfilerPaths.java @@ -47,8 +47,8 @@ public final class MemAllocProfilerPaths { private final Map<Integer, Entry> entryMap = new ConcurrentHashMap<>(); private volatile Entry root = new Entry(this, null, "", null); - private MemAllocProfilerPaths hotSpotsView; - private long hotSpotsViewVersion; + private MemAllocProfilerPaths hsView; + private long hsViewVersion; /** * Clear the model. @@ -93,14 +93,14 @@ public final class MemAllocProfilerPaths { return clonePaths(); } - public synchronized MemAllocProfilerPaths toHotSpots() { + public synchronized MemAllocProfilerPaths toHS() { long curVer = version.get(); - if (curVer == hotSpotsViewVersion && hotSpotsView != null) { - return hotSpotsView; + if (curVer == hsViewVersion && hsView != null) { + return hsView; } - hotSpotsViewVersion = curVer; - hotSpotsView = invert().groupBySrcSection(); - return hotSpotsView; + hsViewVersion = curVer; + hsView = invert().groupBySrcSection(); + return hsView; } @SuppressWarnings("unused") diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java index 895d6114c9..03ef1cf845 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/ForeignArray2R.java @@ -22,10 +22,12 @@ */ package com.oracle.truffle.r.runtime.interop; +import java.util.ArrayList; +import java.util.List; + import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.ArityException; @@ -43,8 +45,6 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; -import java.util.ArrayList; -import java.util.List; @ImportStatic({Message.class, RRuntime.class}) public abstract class ForeignArray2R extends RBaseNode { -- GitLab