This task is automatically imported from the old Task Issue Board and it was originally created by jaroslavtulach.
Original issue is here.
Description
While working on #182412796 I noticed IdExecutionInstrument is calling iteratesFrames often - however that's not fast operation and must slow us down by magnitude.
The method
private boolean isTopFrame(CallTarget entryCallTarget) {
Object result =
Truffle.getRuntime()
.iterateFrames(
cannot run at full speed as iterateFrames needs to deopt to interpreter. The method seems to be called on every change in the IDE.
Alternatives
IdExecutionInstrument shall install a wrapper node around each StandardTags.Root. Marcin suggests: we can probably wrap the body nodes in every instrumented root node with some "depth tracking" node - i.e. when a root becomes instrumented we start keeping track of enters/leaves. This way we can do it without a @TruffleBoundary, the additional cost is one memory read/write per instrumented function call (compiled libs remain unaffected) and the cost of "hey is this recursive" is just a memory read.
Consider
Shouldn't we run some benchmarks with the IdExcecutionInstrument enabled? If we want the execution in the IDE be fast, we should measure it a bit and make sure it is not order of magnitudes slower than engine's standalone performance.
How many nodes are being instrumented by the IdExecutionInstrument? There is a method bind in the instrument class that currently does:
var builder = SourceSectionFilter.newBuilder()
.tagIs(StandardTags.ExpressionTag.class, StandardTags.CallTag.class)
.tagIs(IdentifiedTag.class)
.tagIsNot(AvoidIdInstrumentationTag.class)
.sourceIs(module::isModuleSource);
if (entryCallTarget instanceof RootCallTarget r && r.getRootNode() instanceof ClosureRootNode c && c.getSourceSection() != null) {
final int firstFunctionLine = c.getSourceSection().getStartLine();
final int afterFunctionLine = c.getSourceSection().getEndLine() + 1;
builder.lineIn(SourceSectionFilter.IndexRange.between(firstFunctionLine, afterFunctionLine));
}
SourceSectionFilter filter = builder.build();
E.g. it selects all nodes from the .enso file between firstFunctionLine and afterFunctionLine - e.g. very likely only small set of nodes is instrumented. (jaroslavtulach - Jul 25, 2022)
This task is automatically imported from the old Task Issue Board and it was originally created by jaroslavtulach. Original issue is here.
Description
While working on #182412796 I noticed
IdExecutionInstrument
is callingiteratesFrames
often - however that's not fast operation and must slow us down by magnitude. The methodcannot run at full speed as
iterateFrames
needs to deopt to interpreter. The method seems to be called on every change in the IDE.Alternatives
IdExecutionInstrument
shall install a wrapper node around each StandardTags.Root. Marcin suggests: we can probably wrap the body nodes in every instrumented root node with some "depth tracking" node - i.e. when a root becomes instrumented we start keeping track of enters/leaves. This way we can do it without a@TruffleBoundary
, the additional cost is one memory read/write per instrumented function call (compiled libs remain unaffected) and the cost of "hey is this recursive" is just a memory read.Consider
Shouldn't we run some benchmarks with the
IdExcecutionInstrument
enabled? If we want the execution in the IDE be fast, we should measure it a bit and make sure it is not order of magnitudes slower than engine's standalone performance.The counter shall be per thread. Take a look at ContextThreadLocal.
Comments:
How many nodes are being instrumented by the
IdExecutionInstrument
? There is a methodbind
in the instrument class that currently does:E.g. it selects all nodes from the
.enso
file betweenfirstFunctionLine
andafterFunctionLine
- e.g. very likely only small set of nodes is instrumented. (jaroslavtulach - Jul 25, 2022)