# HG changeset patch # User Thomas Wuerthinger # Date 1326736152 -3600 # Node ID 5a84f5548fc49379941de6a42b31e7daab594654 # Parent 279a43776f421e163c2808f046b7ed716b70816e More work on new debug infrastructure. diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalCompiler.java Mon Jan 16 18:49:12 2012 +0100 @@ -22,8 +22,6 @@ */ package com.oracle.max.graal.compiler; -import static com.oracle.max.graal.debug.Debug.*; - import java.util.*; import com.oracle.max.asm.*; @@ -107,8 +105,8 @@ context.timers.startScope("HIR"); if (graph.start().next() == null) { - plan.runPhases(PhasePosition.AFTER_PARSING, graph, context); - new DeadCodeEliminationPhase().apply(graph, context); + plan.runPhases(PhasePosition.AFTER_PARSING, graph); + new DeadCodeEliminationPhase().apply(graph); } else { if (context.isObserved()) { context.observable.fireCompilationEvent("initial state", graph); @@ -118,71 +116,71 @@ new PhiStampPhase().apply(graph); if (GraalOptions.ProbabilityAnalysis && graph.start().probability() == 0) { - new ComputeProbabilityPhase().apply(graph, context); + new ComputeProbabilityPhase().apply(graph); } if (GraalOptions.Intrinsify) { - new IntrinsificationPhase(runtime).apply(graph, context); + new IntrinsificationPhase(runtime).apply(graph); } if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) { - new InliningPhase(target, runtime, null, assumptions, plan).apply(graph, context); - new DeadCodeEliminationPhase().apply(graph, context); + new InliningPhase(target, runtime, null, assumptions, plan).apply(graph); + new DeadCodeEliminationPhase().apply(graph); new PhiStampPhase().apply(graph); } if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, assumptions).apply(graph, context); + new CanonicalizerPhase(target, runtime, assumptions).apply(graph); } - plan.runPhases(PhasePosition.HIGH_LEVEL, graph, context); + plan.runPhases(PhasePosition.HIGH_LEVEL, graph); if (GraalOptions.OptLoops) { graph.mark(); - new FindInductionVariablesPhase().apply(graph, context); + new FindInductionVariablesPhase().apply(graph); if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context); + new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph); } - new SafepointPollingEliminationPhase().apply(graph, context); + new SafepointPollingEliminationPhase().apply(graph); } if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) { - new EscapeAnalysisPhase(target, runtime, assumptions, plan).apply(graph, context); + new EscapeAnalysisPhase(target, runtime, assumptions, plan).apply(graph); new PhiStampPhase().apply(graph); - new CanonicalizerPhase(target, runtime, assumptions).apply(graph, context); + new CanonicalizerPhase(target, runtime, assumptions).apply(graph); } if (GraalOptions.OptGVN) { - new GlobalValueNumberingPhase().apply(graph, context); + new GlobalValueNumberingPhase().apply(graph); } graph.mark(); - new LoweringPhase(runtime).apply(graph, context); - new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context); + new LoweringPhase(runtime).apply(graph); + new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph); if (GraalOptions.OptLoops) { graph.mark(); - new RemoveInductionVariablesPhase().apply(graph, context); + new RemoveInductionVariablesPhase().apply(graph); if (GraalOptions.OptCanonicalizer) { - new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph, context); + new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph); } } if (GraalOptions.Lower) { - new FloatingReadPhase().apply(graph, context); + new FloatingReadPhase().apply(graph); if (GraalOptions.OptReadElimination) { - new ReadEliminationPhase().apply(graph, context); + new ReadEliminationPhase().apply(graph); } } - new RemovePlaceholderPhase().apply(graph, context); - new DeadCodeEliminationPhase().apply(graph, context); + new RemovePlaceholderPhase().apply(graph); + new DeadCodeEliminationPhase().apply(graph); - plan.runPhases(PhasePosition.MID_LEVEL, graph, context); + plan.runPhases(PhasePosition.MID_LEVEL, graph); - plan.runPhases(PhasePosition.LOW_LEVEL, graph, context); + plan.runPhases(PhasePosition.LOW_LEVEL, graph); IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY); - schedule.apply(graph, context); + schedule.apply(graph); if (context.isObserved()) { context.observable.fireCompilationEvent("After IdentifyBlocksPhase", graph, schedule); @@ -288,7 +286,7 @@ private TargetMethodAssembler createAssembler(FrameMap frameMap, LIR lir) { AbstractAssembler masm = backend.newAssembler(frameMap.registerConfig); - TargetMethodAssembler tasm = new TargetMethodAssembler(context, target, runtime, frameMap, lir.slowPaths, masm); + TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime, frameMap, lir.slowPaths, masm); tasm.setFrameSize(frameMap.frameSize()); tasm.targetMethod.setCustomStackAreaOffset(frameMap.offsetToCustomArea()); return tasm; diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/ControlFlowOptimizer.java Mon Jan 16 18:49:12 2012 +0100 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.compiler.util.*; @@ -39,8 +38,8 @@ * Performs control flow optimizations on the given LIR graph. * @param ir the LIR graph that should be optimized */ - public static void optimize(LIR ir, GraalContext context) { - ControlFlowOptimizer optimizer = new ControlFlowOptimizer(ir, context); + public static void optimize(LIR ir) { + ControlFlowOptimizer optimizer = new ControlFlowOptimizer(ir); List code = ir.codeEmittingOrder(); //optimizer.reorderShortLoops(code); optimizer.deleteEmptyBlocks(code); @@ -49,11 +48,9 @@ } private final LIR ir; - private final GraalContext context; - private ControlFlowOptimizer(LIR ir, GraalContext context) { + private ControlFlowOptimizer(LIR ir) { this.ir = ir; - this.context = context; } /* private void reorderShortLoop(List code, LIRBlock headerBlock, int headerIdx) { diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/Interval.java Mon Jan 16 18:49:12 2012 +0100 @@ -31,7 +31,6 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.compiler.util.*; -import com.oracle.max.graal.debug.*; /** * Represents an interval in the {@linkplain LinearScan linear scan register allocator}. @@ -658,12 +657,9 @@ /** * Sentinel interval to denote the end of an interval list. */ - static final Interval EndMarker = new Interval(null, CiValue.IllegalValue, -1); + static final Interval EndMarker = new Interval(CiValue.IllegalValue, -1); - private static final Debug.Metric instanceMetric = Debug.metric("LSRAIntervalsCreated"); - - Interval(GraalContext context, CiValue operand, int operandNumber) { - //instanceMetric.increment(); + Interval(CiValue operand, int operandNumber) { assert operand != null; this.operand = operand; this.operandNumber = operandNumber; diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/alloc/LinearScan.java Mon Jan 16 18:49:12 2012 +0100 @@ -237,7 +237,7 @@ assert isProcessed(operand); assert isLegal(operand); int operandNumber = operandNumber(operand); - Interval interval = new Interval(context, operand, operandNumber); + Interval interval = new Interval(operand, operandNumber); assert operandNumber < intervalsSize; assert intervals[operandNumber] == null; intervals[operandNumber] = interval; @@ -1619,7 +1619,7 @@ // intervals that have no oops inside need not to be processed. // to ensure a walking until the last instruction id, add a dummy interval // with a high operation id - nonOopIntervals = new Interval(context, CiValue.IllegalValue, -1); + nonOopIntervals = new Interval(CiValue.IllegalValue, -1); nonOopIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); return new IntervalWalker(this, oopIntervals, nonOopIntervals); @@ -1846,7 +1846,7 @@ try { printLir("After register number assignment", true); EdgeMoveOptimizer.optimize(ir.linearScanOrder()); - ControlFlowOptimizer.optimize(ir, context); + ControlFlowOptimizer.optimize(ir); printLir("After control flow optimization", false); } finally { context.timers.endScope(); @@ -2027,7 +2027,7 @@ fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first; // to ensure a walking until the last instruction id, add a dummy interval // with a high operation id - otherIntervals = new Interval(context, CiValue.IllegalValue, -1); + otherIntervals = new Interval(CiValue.IllegalValue, -1); otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals); diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/asm/TargetMethodAssembler.java Mon Jan 16 18:49:12 2012 +0100 @@ -47,10 +47,7 @@ private List exceptionInfoList; private int lastSafepointPos; - private final GraalContext context; - - public TargetMethodAssembler(GraalContext context, CiTarget target, RiRuntime runtime, FrameMap frameMap, List slowPaths, AbstractAssembler asm) { - this.context = context; + public TargetMethodAssembler(CiTarget target, RiRuntime runtime, FrameMap frameMap, List slowPaths, AbstractAssembler asm) { this.target = target; this.runtime = runtime; this.frameMap = frameMap; diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/ComputeProbabilityPhase.java Mon Jan 16 18:49:12 2012 +0100 @@ -27,6 +27,7 @@ import com.oracle.max.criutils.*; import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.graph.*; +import com.oracle.max.graal.debug.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; @@ -50,13 +51,9 @@ @Override protected void run(StructuredGraph graph) { new PropagateProbability(graph.start()).apply(); - if (currentContext.isObserved() && GraalOptions.TraceProbability) { - currentContext.observable.fireCompilationEvent("After PropagateProbability", graph); - } + Debug.dump(graph, "After PropagateProbability"); computeLoopFactors(); - if (currentContext.isObserved() && GraalOptions.TraceProbability) { - currentContext.observable.fireCompilationEvent("After computeLoopFactors", graph); - } + Debug.dump(graph, "After computeLoopFactors"); new PropagateLoopFrequency(graph.start()).apply(); } diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/EscapeAnalysisPhase.java Mon Jan 16 18:49:12 2012 +0100 @@ -29,6 +29,7 @@ import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.cri.*; +import com.oracle.max.graal.debug.*; import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; import com.oracle.max.graal.nodes.PhiNode.PhiType; @@ -428,21 +429,10 @@ } if (invokes.size() == 0) { - if (currentContext.isObserved()) { - currentContext.observable.fireCompilationEvent("Before escape " + node, graph); - } - if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { - TTY.println("%n!!!!!!!! non-escaping object: %s (%s)", node, node.exactType()); - } - try { - currentContext.timers.startScope("Escape Analysis Fixup"); - removeAllocation(node, op); - } finally { - currentContext.timers.endScope(); - } - if (currentContext.isObserved()) { - currentContext.observable.fireCompilationEvent("After escape", graph); - } + Debug.dump(graph, "Before escape %s", node); + Debug.log("!!!!!!!! non-escaping object: %s (%s)", node, node.exactType()); + removeAllocation(node, op); + Debug.dump(graph, "After escape", graph); break; } if (weight < minimumWeight) { @@ -457,8 +447,8 @@ if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { TTY.println("Trying inlining to get a non-escaping object for %s", node); } - new InliningPhase(target, runtime, invokes, assumptions, plan).apply(graph, currentContext); - new DeadCodeEliminationPhase().apply(graph, currentContext); + new InliningPhase(target, runtime, invokes, assumptions, plan).apply(graph); + new DeadCodeEliminationPhase().apply(graph); if (node.isDeleted()) { if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { TTY.println("%n!!!!!!!! object died while performing escape analysis: %s (%s)", node, node.exactType()); diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/FloatingReadPhase.java Mon Jan 16 18:49:12 2012 +0100 @@ -249,7 +249,7 @@ // Identify blocks. final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false); - s.apply(graph, currentContext); + s.apply(graph); List blocks = s.getBlocks(); // Process blocks (predecessors first). diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/InliningPhase.java Mon Jan 16 18:49:12 2012 +0100 @@ -99,16 +99,14 @@ if (GraalOptions.TraceInlining) { TTY.println("inlining %f: %s", info.weight, info); } - if (GraalOptions.TraceInlining) { - currentContext.observable.fireCompilationEvent("after inlining " + info, graph); - } + Debug.dump(graph, "after inlining %s", info); // get the new nodes here, the canonicalizer phase will reset the mark newNodes = graph.getNewNodes(); if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase(target, runtime, true, assumptions).apply(graph); } if (GraalOptions.Intrinsify) { - new IntrinsificationPhase(runtime).apply(graph, currentContext); + new IntrinsificationPhase(runtime).apply(graph); } metricInliningPerformed.increment(); } catch (CiBailout bailout) { @@ -161,14 +159,14 @@ StructuredGraph newGraph = new StructuredGraph(method); if (plan != null) { - plan.runPhases(PhasePosition.AFTER_PARSING, newGraph, currentContext); + plan.runPhases(PhasePosition.AFTER_PARSING, newGraph); } if (GraalOptions.ProbabilityAnalysis) { - new DeadCodeEliminationPhase().apply(newGraph, currentContext, false); - new ComputeProbabilityPhase().apply(newGraph, currentContext, false); + new DeadCodeEliminationPhase().apply(newGraph); + new ComputeProbabilityPhase().apply(newGraph); } - new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph, currentContext, false); + new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph); return newGraph; } @@ -213,9 +211,9 @@ if (!parsedMethods.containsKey(method)) { StructuredGraph newGraph = new StructuredGraph(method); if (plan != null) { - plan.runPhases(PhasePosition.AFTER_PARSING, newGraph, currentContext); + plan.runPhases(PhasePosition.AFTER_PARSING, newGraph); } - new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph, currentContext, false); + new CanonicalizerPhase(target, runtime, assumptions).apply(newGraph); count = graphComplexity(newGraph); parsedMethods.put(method, count); } else { diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Mon Jan 16 18:49:12 2012 +0100 @@ -40,7 +40,7 @@ @Override protected void run(final StructuredGraph graph) { final IdentifyBlocksPhase s = new IdentifyBlocksPhase(false); - s.apply(graph, currentContext); + s.apply(graph); s.calculateAlwaysReachedBlock(); NodeBitMap processed = graph.createNodeBitMap(); diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/Phase.java Mon Jan 16 18:49:12 2012 +0100 @@ -22,106 +22,27 @@ */ package com.oracle.max.graal.compiler.phases; -import static com.oracle.max.graal.debug.Debug.*; - -import com.oracle.max.cri.ci.*; -import com.oracle.max.graal.compiler.*; -import com.oracle.max.graal.compiler.schedule.*; import com.oracle.max.graal.debug.*; -import com.oracle.max.graal.graph.*; import com.oracle.max.graal.nodes.*; public abstract class Phase { private final String name; - private final boolean shouldVerify; - protected GraalContext currentContext; protected Phase() { this.name = this.getClass().getSimpleName(); - this.shouldVerify = GraalOptions.VerifyPhases; } protected Phase(String name) { - this(name, GraalOptions.VerifyPhases); - } - - protected Phase(String name, boolean shouldVerify) { this.name = name; - this.shouldVerify = shouldVerify; } protected String getDetailedName() { return getName(); } - public final void apply(StructuredGraph graph) { - apply(graph, GraalContext.EMPTY_CONTEXT); - } - - public final void apply(StructuredGraph graph, GraalContext context) { - apply(graph, context, true); - } - - public final void apply(StructuredGraph graph, boolean plot) { - apply(graph, GraalContext.EMPTY_CONTEXT, plot); - } - - public final void apply(final StructuredGraph graph, GraalContext context, boolean plot) { - - this.currentContext = context; - + public final void apply(final StructuredGraph graph) { Debug.scope(name, new Runnable() { public void run() { Phase.this.run(graph); }}); - -// try { -// assert graph != null && (!shouldVerify || graph.verify()); -// } catch (GraalInternalError e) { -// throw e.addContext("start of phase", getDetailedName()); -// } -// -// int startDeletedNodeCount = graph.getDeletedNodeCount(); -// int startNodeCount = graph.getNodeCount(); -// if (context != null) { -// context.timers.startScope(getName()); -// } -// try { -// try { -// run(graph); -// } catch (CiBailout bailout) { -// throw bailout; -// } catch (AssertionError e) { -// throw new GraalInternalError(e); -// } catch (RuntimeException e) { -// throw new GraalInternalError(e); -// } finally { -// if (context != null) { -// context.timers.endScope(); -// } -// } -// } catch (GraalInternalError e) { -// throw e.addContext(graph).addContext("phase", getDetailedName()); -// } -// -// if (context != null) { -// if (GraalOptions.Meter) { -// int deletedNodeCount = graph.getDeletedNodeCount() - startDeletedNodeCount; -// int createdNodeCount = graph.getNodeCount() - startNodeCount + deletedNodeCount; -// context.metrics.get(getName().concat(".executed")).increment(); -// context.metrics.get(getName().concat(".deletedNodes")).increment(deletedNodeCount); -// context.metrics.get(getName().concat(".createdNodes")).increment(createdNodeCount); -// } -// -// boolean shouldFireCompilationEvents = context.isObserved() && this.getClass() != IdentifyBlocksPhase.class && (plot || GraalOptions.PlotVerbose); -// if (shouldFireCompilationEvents && context.timers.currentLevel() < GraalOptions.PlotLevel) { -// context.observable.fireCompilationEvent("After " + getName(), graph); -// } -// } -// -// try { -// assert !shouldVerify || graph.verify(); -// } catch (GraalInternalError e) { -// throw e.addContext("end of phase", getDetailedName()); -// } } public final String getName() { diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/PhasePlan.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/PhasePlan.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/PhasePlan.java Mon Jan 16 18:49:12 2012 +0100 @@ -24,7 +24,6 @@ import java.util.*; -import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.nodes.*; /** @@ -68,10 +67,10 @@ phases[pos.ordinal()].add(phase); } - public void runPhases(PhasePosition pos, StructuredGraph graph, GraalContext context) { + public void runPhases(PhasePosition pos, StructuredGraph graph) { if (phases[pos.ordinal()] != null) { for (Phase p : phases[pos.ordinal()]) { - p.apply(graph, context); + p.apply(graph); } } } diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/IdentifyBlocksPhase.java Mon Jan 16 18:49:12 2012 +0100 @@ -57,7 +57,7 @@ } public IdentifyBlocksPhase(boolean scheduleAllNodes, BlockFactory blockFactory) { - super(scheduleAllNodes ? "FullSchedule" : "PartSchedule", false); + super(scheduleAllNodes ? "FullSchedule" : "PartSchedule"); this.blockFactory = blockFactory; this.scheduleAllNodes = scheduleAllNodes; } diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java --- a/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/Debug.java Mon Jan 16 18:49:12 2012 +0100 @@ -22,6 +22,11 @@ */ package com.oracle.max.graal.debug; +import com.oracle.max.graal.debug.internal.DebugScope; +import com.oracle.max.graal.debug.internal.MetricImpl; +import com.oracle.max.graal.debug.internal.TimerImpl; +import java.util.Collections; + public class Debug { public static boolean SCOPE = false; @@ -31,7 +36,15 @@ public static void scope(String name, Runnable runnable, Object... context) { if (SCOPE) { - DebugContext.getInstance().scope(name, runnable, context); + DebugScope.getInstance().scope(name, runnable, false, context); + } else { + runnable.run(); + } + } + + public static void sandbox(String name, Runnable runnable, Object... context) { + if (SCOPE) { + DebugScope.getInstance().scope(name, runnable, true, context); } else { runnable.run(); } @@ -39,7 +52,21 @@ public static void log(String msg, Object... args) { if (LOG) { - DebugContext.getInstance().log(msg, args); + DebugScope.getInstance().log(msg, args); + } + } + + public static void dump(Object object, String msg, Object... args) { + if (LOG) { + DebugScope.getInstance().log(msg, args); + } + } + + public static Iterable context() { + if (SCOPE) { + return DebugScope.getInstance().getCurrentContext(); + } else { + return Collections.emptyList(); } } @@ -57,7 +84,9 @@ } private static final Metric VOID_METRIC = new Metric() { + @Override public void increment() { } + @Override public void add(int value) { } }; @@ -75,38 +104,9 @@ } private static final Timer VOID_TIMER = new Timer() { - public void start() { }; - public void stop() { }; + @Override + public void start() { } + @Override + public void stop() { } }; - - private static final class MetricImpl extends ScopeChild implements Metric { - private MetricImpl(String name) { - super(name); - } - - public void increment() { - } - - public void add(int value) { - } - - } - - public static final class TimerImpl extends ScopeChild implements Timer { - private TimerImpl(String name) { - super(name); - } - - @Override - public void start() { - // TODO Auto-generated method stub - - } - - @Override - public void stop() { - // TODO Auto-generated method stub - - } - } } diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugContext.java --- a/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/DebugContext.java Fri Jan 13 18:48:46 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2012, 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.max.graal.debug; - - -class DebugContext { - - private static ThreadLocal instance = new ThreadLocal<>(); - - static DebugContext getInstance() { - if (instance.get() == null) { - instance.set(new DebugContext()); - } - return instance.get(); - } - - void log(String msg, Object... args) { - } - - void scope(String name, Runnable runnable, Object... context) { - runnable.run(); - } -} diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/ScopeChild.java --- a/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/ScopeChild.java Fri Jan 13 18:48:46 2012 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -package com.oracle.max.graal.debug; - -class ScopeChild { - private String name; - - protected ScopeChild(String name) { - this.name = name; - } -} \ No newline at end of file diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugScope.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugScope.java Mon Jan 16 18:49:12 2012 +0100 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2012, 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.max.graal.debug.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +public final class DebugScope { + + private static ThreadLocal instance = new ThreadLocal<>(); + private final List children = new ArrayList<>(4); + private final String name; + private final DebugScope parent; + private final Object[] context; + private final DebugValueMap valueMap = new DebugValueMap(); + + public static final DebugScope DEFAULT_CONTEXT = new DebugScope("DEFAULT", null); + + public static DebugScope getInstance() { + DebugScope result = instance.get(); + if (result == null) { + return DEFAULT_CONTEXT; + } else { + return result; + } + } + + private DebugScope(String name, DebugScope parent, Object... context) { + this.name = name; + this.parent = parent; + this.context = context; + } + + public void log(String msg, Object... args) { + } + + public void scope(String newName, Runnable runnable, boolean sandbox, Object... newContext) { + DebugScope oldContext = getInstance(); + DebugScope newChild = null; + if (sandbox) { + newChild = new DebugScope(name, null, newContext); + } else { + oldContext.createChild(newName, newContext); + } + instance.set(newChild); + try { + runnable.run(); + } catch (Throwable t) { + interceptException(t); + throw t; + } finally { + instance.set(oldContext); + } + } + + public DebugValueMap getValueMap() { + return valueMap; + } + + private void interceptException(Throwable t) { + } + + long getCurrentValue(int index) { + return valueMap.getCurrentValue(index); + } + + void setCurrentValue(int index, long l) { + valueMap.setCurrentValue(index, l); + } + + private DebugScope createChild(String newName, Object[] newContext) { + DebugScope result = new DebugScope(newName, this, newContext); + children.add(result); + return result; + } + + public Iterable getCurrentContext() { + return new Iterable() { + + @Override + public Iterator iterator() { + return new Iterator() { + + DebugScope currentScope = DebugScope.this; + int objectIndex; + + @Override + public boolean hasNext() { + selectScope(); + return currentScope != null; + } + + private void selectScope() { + while (currentScope != null && currentScope.context.length <= objectIndex) { + currentScope = currentScope.parent; + objectIndex = 0; + } + } + + @Override + public Object next() { + selectScope(); + if (currentScope != null) { + return currentScope.context[objectIndex++]; + } + throw new IllegalStateException("May only be called if there is a next element."); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("This iterator is read only."); + } + }; + } + }; + } +} + diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValue.java Mon Jan 16 18:49:12 2012 +0100 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2012, 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.max.graal.debug.internal; + +public class DebugValue { + + private String name; + private int index; + + protected DebugValue(String name) { + this.name = name; + this.index = -1; + } + + protected long getCurrentValue() { + ensureInitialized(); + return DebugScope.getInstance().getCurrentValue(index); + } + + protected void setCurrentValue(long l) { + ensureInitialized(); + DebugScope.getInstance().setCurrentValue(index, l); + } + + private void ensureInitialized() { + if (index == -1) { + index = KeyRegistry.register(name); + } + } + + protected void addToCurrentValue(long timeSpan) { + setCurrentValue(getCurrentValue() + timeSpan); + } +} diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValueMap.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/DebugValueMap.java Mon Jan 16 18:49:12 2012 +0100 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2012, 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.max.graal.debug.internal; + +import java.util.Arrays; + +public class DebugValueMap { + + private long[] values; + + public void setCurrentValue(int index, long l) { + ensureSize(index); + values[index] = l; + } + + public long getCurrentValue(int index) { + ensureSize(index); + return values[index]; + } + + private void ensureSize(int index) { + if (values == null || values.length <= index) { + values = Arrays.copyOf(values, index + 1); + } + } +} diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/KeyRegistry.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/KeyRegistry.java Mon Jan 16 18:49:12 2012 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012, 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.max.graal.debug.internal; + +import java.util.HashMap; +import java.util.Map; + +public class KeyRegistry { + + private static int keyCount; + private static Map keyMap = new HashMap<>(); + + public static synchronized int register(String name) { + if (!keyMap.containsKey(name)) { + keyMap.put(name, keyCount++); + } + return keyMap.get(name); + } + +} diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/MetricImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/MetricImpl.java Mon Jan 16 18:49:12 2012 +0100 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012, 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.max.graal.debug.internal; + +import com.oracle.max.graal.debug.Debug.Metric; + +public final class MetricImpl extends DebugValue implements Metric { + + public MetricImpl(String name) { + super(name); + } + + public void increment() { + add(1); + } + + public void add(int value) { + super.addToCurrentValue(value); + } +} diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/TimerImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.debug/src/com/oracle/max/graal/debug/internal/TimerImpl.java Mon Jan 16 18:49:12 2012 +0100 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, 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.max.graal.debug.internal; + +import com.oracle.max.graal.debug.Debug; + +public final class TimerImpl extends DebugValue implements Debug.Timer { + + private long startTime = -1; + + public TimerImpl(String name) { + super(name); + } + + @Override + public void start() { + startTime = System.currentTimeMillis(); + } + + @Override + public void stop() { + long timeSpan = System.currentTimeMillis() - startTime; + super.addToCurrentValue(timeSpan); + } +} diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java Mon Jan 16 18:49:12 2012 +0100 @@ -139,10 +139,11 @@ BlockMap map = new BlockMap(method, config.useBranchPrediction()); map.build(); - if (currentContext.isObserved()) { - String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method); - currentContext.observable.fireCompilationEvent(label, map); - } +// if (currentContext.isObserved()) { +// String label = CiUtil.format("BlockListBuilder %f %R %H.%n(%P)", method); +// currentContext.observable.fireCompilationEvent(label, map); +// } + // TODO(tw): Reinstall this logging code when debug framework is finished. return map; } diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/CFGPrinterObserver.java Mon Jan 16 18:49:12 2012 +0100 @@ -105,7 +105,7 @@ if (schedule == null) { try { schedule = new IdentifyBlocksPhase(true, LIRBlock.FACTORY); - schedule.apply((StructuredGraph) graph, false); + schedule.apply((StructuredGraph) graph); blocks = schedule.getBlocks(); ComputeLinearScanOrder clso = new ComputeLinearScanOrder(schedule.getBlocks().size(), schedule.loopCount(), (LIRBlock) schedule.getStartBlock()); diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java --- a/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.printer/src/com/oracle/max/graal/printer/IdealGraphPrinter.java Mon Jan 16 18:49:12 2012 +0100 @@ -137,7 +137,7 @@ if (schedule == null) { try { schedule = new IdentifyBlocksPhase(true); - schedule.apply((StructuredGraph) graph, false); + schedule.apply((StructuredGraph) graph); } catch (Throwable t) { // nothing to do here... } diff -r 279a43776f42 -r 5a84f5548fc4 graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java --- a/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java Fri Jan 13 18:48:46 2012 +0100 +++ b/graal/com.oracle.max.graal.snippets/src/com/oracle/max/graal/snippets/Snippets.java Mon Jan 16 18:49:12 2012 +0100 @@ -131,13 +131,13 @@ GraphBuilderConfiguration config = GraphBuilderConfiguration.getDeoptFreeDefault(); GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config); StructuredGraph graph = new StructuredGraph(snippetRiMethod); - graphBuilder.apply(graph, context); + graphBuilder.apply(graph); if (observer != null) { observer.printGraph(snippetRiMethod.name() + ":" + GraphBuilderPhase.class.getSimpleName(), graph); } - new SnippetIntrinsificationPhase(runtime, pool).apply(graph, context); + new SnippetIntrinsificationPhase(runtime, pool).apply(graph); for (Invoke invoke : graph.getInvokes()) { MethodCallTargetNode callTarget = invoke.callTarget(); @@ -153,13 +153,13 @@ } } - new SnippetIntrinsificationPhase(runtime, pool).apply(graph, context); + new SnippetIntrinsificationPhase(runtime, pool).apply(graph); if (observer != null) { observer.printGraph(snippetRiMethod.name() + ":" + SnippetIntrinsificationPhase.class.getSimpleName(), graph); } - new DeadCodeEliminationPhase().apply(graph, context); - new CanonicalizerPhase(target, runtime, null).apply(graph, context); + new DeadCodeEliminationPhase().apply(graph); + new CanonicalizerPhase(target, runtime, null).apply(graph); // TODO (gd) remove when we have safepoint polling elimination for (LoopEndNode end : graph.getNodes(LoopEndNode.class)) {