private List<DebuggerNode> collectDebuggerNodes(DebuggerNode source, SuspendAnchor suspendAnchor) { EventContext context = source.getContext(); List<DebuggerNode> nodes = new ArrayList<>(); nodes.add(source); DebuggerNode node = (DebuggerNode) nodesIterator.next(); if (after) { if (node.isActiveAt(suspendAnchor)) { nodes.add(node); break; if (node.isActiveAt(suspendAnchor)) { nodes.add(node);
boolean consumeIsDuplicate() { if (cachedThread == Thread.currentThread()) { // optimized version for single thread only if (cachedThreadDuplicate) { cachedThreadDuplicate = false; return true; } return false; } else if (cachedThread == null) { // node was never consumed so its not a duplicate return false; } else { // version for multiple threads return isDuplicateSlowPath(); } }
void markAsDuplicate(DebuggerSession session) { CompilerAsserts.neverPartOfCompilation(); noDuplicateAssumption.invalidate(); if (singleThreadSession) { Thread thread = Thread.currentThread(); if (cachedThreadId == thread.getId() && cachedSessionDuplicate == null) { cachedSessionDuplicate = session; return; } else if (cachedThreadId == 0) { Boolean marked = atomic(new Callable<Boolean>() { @Override public Boolean call() { if (cachedThreadId == 0) { cachedThreadId = thread.getId(); cachedSessionDuplicate = session; return true; } return false; } }); if (marked) { return; } // fall through to slowpath } } singleThreadSession = false; markAsDuplicateSlowPath(session); }
void markAsDuplicate() { Thread thread = Thread.currentThread(); if (cachedThread == thread) { cachedThreadDuplicate = true; } else if (cachedThread == null) { synchronized (getRootNode()) { if (cachedThread == null) { cachedThread = thread; cachedThreadDuplicate = true; return; } } // fall through to slowpath } getDuplicateThreadLocal().set(Boolean.FALSE); }
if (source.isStepNode()) { if (ignoreLanguageContextInitialization.get() && !source.getContext().isLanguageContextInitialized()) { return returnValue; if (event != null) { if (Debugger.TRACE) { trace("ignored suspended reason: recursive from source:%s context:%s location:%s", source, source.getContext(), source.getSuspendAnchors()); if (source.consumeIsDuplicate(this)) { if (Debugger.TRACE) { trace("ignored suspended reason: duplicate from source:%s context:%s location:%s", source, source.getContext(), source.getSuspendAnchors()); node.markAsDuplicate(this);
private Object notifyCallerReturn(SteppingStrategy s, DebuggerNode source, SuspendAnchor suspendAnchor, Object returnValue) { if (source.isStepNode()) { if (ignoreLanguageContextInitialization.get() && !source.getContext().isLanguageContextInitialized()) { return returnValue; Breakpoint breakpoint = node.getBreakpoint(); if (breakpoint == null || isBreakpointsActive(breakpoint.getKind()) && breakpoint.getCondition() == null) { node.markAsDuplicate(this);
List<Breakpoint> breaks = null; for (DebuggerNode node : nodes) { Breakpoint breakpoint = node.getBreakpoint(); if (breakpoint == null || !isBreakpointsActive(breakpoint.getKind())) { continue; // not a breakpoint node boolean hitStepping = s.step(this, source.getContext(), suspendAnchor); boolean hitBreakpoint = breaks != null && !breaks.isEmpty(); Object newReturnValue = returnValue; } else { if (Debugger.TRACE) { trace("ignored suspended reason: strategy(%s) from source:%s context:%s location:%s", s, source, source.getContext(), source.getSuspendAnchors()); throw new KillException(source.getContext().getInstrumentedNode());
private List<DebuggerNode> collectDebuggerNodes(Node iNode, SuspendAnchor suspendAnchor) { List<DebuggerNode> nodes = new ArrayList<>(); for (EventBinding<?> binding : allBindings) { DebuggerNode node = (DebuggerNode) debugger.getInstrumenter().lookupExecutionEventNode(iNode, binding); if (node != null && node.isActiveAt(suspendAnchor)) { nodes.add(node); } } return nodes; }
/** * Returns <code>true</code> if it should appear in the breakpoints list. * * @throws BreakpointConditionFailure */ boolean notifyIndirectHit(DebuggerNode source, DebuggerNode node, MaterializedFrame frame) throws BreakpointConditionFailure { if (!isEnabled()) { return false; } assert node.getBreakpoint() == this; if (source != node) { // TODO: We're testing the breakpoint condition for a second time (GR-7398). if (!((AbstractBreakpointNode) node).shouldBreak(frame)) { return false; } } else { // don't do the assert here, the breakpoint condition might have side effects. // assert ((BreakpointNode) node).shouldBreak(frame); } if (this.hitCount.incrementAndGet() <= ignoreCount) { // breakpoint hit was ignored return false; } if (isOneShot()) { setEnabled(false); } return true; }
@Override public SuspendedContext get() { return SuspendedContext.create(source.getContext(), debugger.getEnv()); } });
@SuppressWarnings("unchecked") private void markAsDuplicateSlowPath(DebuggerSession session) { atomic(new Runnable() { @Override public void run() { if (duplicateInThreads == null) { duplicateInThreads = EconomicMap.create(); } Thread thread = Thread.currentThread(); Object sessions = duplicateInThreads.get(thread); if (sessions == null) { duplicateInThreads.put(thread, session); } else if (sessions instanceof DebuggerSession) { EconomicSet<DebuggerSession> set = EconomicSet.create(); set.add((DebuggerSession) sessions); set.add(session); duplicateInThreads.put(thread, set); } else { ((EconomicSet<DebuggerSession>) sessions).add(session); } } }); }
private boolean isDuplicateSlowPath() { ThreadLocal<Boolean> suspend = getDuplicateThreadLocal(); Boolean b = suspend.get(); if (b == null) { return true; } else { boolean value = b.booleanValue(); if (!value) { duplicateThreadLocal.set(Boolean.TRUE); } return value; } }
if (source.isStepNode()) { if (ignoreLanguageContextInitialization.get() && !source.getContext().isLanguageContextInitialized()) { return; if (event != null) { if (Debugger.TRACE) { trace("ignored suspended reason: recursive from source:%s context:%s location:%s", source, source.getContext(), source.getSuspendAnchors()); if (source.consumeIsDuplicate()) { if (Debugger.TRACE) { trace("ignored suspended reason: duplicate from source:%s context:%s location:%s", source, source.getContext(), source.getSuspendAnchors()); List<DebuggerNode> nodes = collectDebuggerNodes(source.getContext(), suspendAnchor); for (DebuggerNode node : nodes) { if (node == source) { node.markAsDuplicate(); Breakpoint breakpoint = node.getBreakpoint(); if (breakpoint == null || !isBreakpointsActive()) { continue; // not a breakpoint node boolean hitStepping = s.step(this, source.getContext(), suspendAnchor); boolean hitBreakpoint = breaks != null && !breaks.isEmpty(); if (hitStepping || hitBreakpoint) { s.consume(); doSuspend(SuspendedContext.create(source.getContext()), suspendAnchor, frame, inputValuesProvider, returnValue, breaks, breakpointFailures); } else { if (Debugger.TRACE) {
if (localSyntaxElementBinding != null) { DebuggerNode node = (DebuggerNode) context.lookupExecutionEventNode(localSyntaxElementBinding); if (node != null && node.isActiveAt(suspendAnchor)) { nodes.add(node);
return false; assert node.getBreakpoint() == this;
@TruffleBoundary @SuppressWarnings("unchecked") private boolean isDuplicateSlowPath(DebuggerSession session) { return atomic(new Callable<Boolean>() { @Override public Boolean call() {
boolean consumeIsDuplicate(DebuggerSession session) { if (noDuplicateAssumption.isValid()) { return false; } if (cachedThreadId == Thread.currentThread().getId()) { // optimized version for single thread only if (cachedSessionDuplicate == session) { cachedSessionDuplicate = null; if (singleThreadSession) { noDuplicateAssumption = Truffle.getRuntime().createAssumption("No duplicate node assumption"); } return true; } } if (singleThreadSession) { return false; } // version for multiple threads and sessions return isDuplicateSlowPath(session); }