return; ProbeNode probe = new ProbeNode(InstrumentationHandler.this, sourceSection); com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode wrapper; try { assert probe.getContext().validEventContext();
} else { assert element instanceof ExecutionEventNodeFactory; ExecutionEventNode eventNode = createEventNode(binding, element); if (eventNode == null) { EventChainNode parent = findParentChain(frame, binding); EventProviderWithInputChainNode parentChain = ((EventProviderWithInputChainNode) parent); baseInput = 0; } else { EventContext parentContext = parentChain.findProbe().getContext(); int childIndex = indexOfChild(binding, rootNode, providedTags, parentContext.getInstrumentedNode(), parentContext.getInstrumentedSourceSection(), instrumentedNode); int inputBaseIndex = parentChain.inputBaseIndex; if (childIndex < 0) { int inputCount = countChildren(binding, rootNode, providedTags, instrumentedNode, instrumentedNodeSourceSection); next = new EventProviderWithInputChainNode(binding, eventNode, baseInput, inputCount); } else {
private static boolean checkInteropType(Object value, EventBinding.Source<?> binding) { if (value != null && value != UNWIND_ACTION_REENTER && value != UNWIND_ACTION_IGNORED && !InstrumentationHandler.ACCESSOR.isTruffleObject(value)) { Class<?> clazz = value.getClass(); if (!(clazz == Byte.class || clazz == Short.class || clazz == Integer.class || clazz == Long.class || clazz == Float.class || clazz == Double.class || clazz == Character.class || clazz == Boolean.class || clazz == String.class)) { CompilerDirectives.transferToInterpreter(); ClassCastException ccex = new ClassCastException(clazz.getName() + " isn't allowed Truffle interop type!"); if (binding.isLanguageBinding()) { throw ccex; } else { exceptionEventForClientInstrument(binding, "onUnwind", ccex); return false; } } } return true; }
@SuppressWarnings("deprecation") private static void invalidateWrapperImpl(com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode parent, Node node) { ProbeNode probeNode = parent.getProbeNode(); if (TRACE) { SourceSection section = probeNode.getContext().getInstrumentedSourceSection(); trace("Invalidate wrapper for %s, section %s %n", node, section); } if (probeNode != null) { probeNode.invalidate(); } }
@SuppressWarnings("deprecation") static void removeWrapper(ProbeNode node) { if (TRACE) { trace("Remove wrapper for %s%n", node.getContext().getInstrumentedSourceSection()); } com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode wrapperNode = node.findWrapper(); ((Node) wrapperNode).replace(wrapperNode.getDelegateNode()); }
EventChainNode createParentEventChainCallback(VirtualFrame frame, EventBinding.Source<?> binding, RootNode rootNode, Set<Class<?>> providedTags) { EventChainNode parent = findParentChain(frame, binding); if (!(parent instanceof EventProviderWithInputChainNode)) { // this event is unreachable because nobody is listening to it. return null; } EventContext parentContext = parent.findProbe().getContext(); EventProviderWithInputChainNode parentChain = (EventProviderWithInputChainNode) parent; int index = indexOfChild(binding, rootNode, providedTags, parentContext.getInstrumentedNode(), parentContext.getInstrumentedSourceSection(), context.getInstrumentedNode()); if (index < 0 || index >= parentChain.inputCount) { // not found. a child got replaced? // probe should have been notified about this with notifyInserted assert throwIllegalASTAssertion(parentChain, parentContext, binding, rootNode, providedTags, index); return null; } ProbeNode probe = parent.findProbe(); return new InputValueChainNode(binding, probe, context, index); }
EventChainNode createBindings(VirtualFrame frame, ProbeNode probeNodeImpl) { EventContext context = probeNodeImpl.getContext(); SourceSection sourceSection = context.getInstrumentedSourceSection(); if (TRACE) { Node parentNode = probeNodeImpl.getParent(); while (parentNode != null && parentNode.getParent() != null) { if (parentInstrumentable == null) { Node instrumentedNode = probeNodeImpl.getContext().getInstrumentedNode(); Set<Class<?>> providedTags = getProvidedTags(rootNode); EventChainNode root = null; EventChainNode next = probeNodeImpl.createParentEventChainCallback(frame, binding, rootNode, providedTags); if (next == null) { trace(" Found binding %s, %s%n", binding.getFilter(), binding.getElement()); EventChainNode next = probeNodeImpl.createEventChainCallback(frame, binding, rootNode, providedTags, instrumentedNode, sourceSection); if (next == null) { continue;
EventChainNode createParentEventChainCallback(VirtualFrame frame, EventBinding.Source<?> binding, RootNode rootNode, Set<Class<?>> providedTags) { EventChainNode parent = findParentChain(frame, binding); if (!(parent instanceof EventProviderWithInputChainNode)) { // this event is unreachable because nobody is listening to it. return null; } EventContext parentContext = parent.findProbe().getContext(); EventProviderWithInputChainNode parentChain = (EventProviderWithInputChainNode) parent; int index = indexOfChild(binding, rootNode, providedTags, parentContext.getInstrumentedNode(), parentContext.getInstrumentedSourceSection(), context.getInstrumentedNode()); if (index < 0 || index >= parentChain.inputCount) { // not found. a child got replaced? // TODO what to do if child was not found? // we should not continue with an out of bounds child index. assert false; return null; } ProbeNode probe = parent.findProbe(); return new InputValueChainNode(binding, probe, context, index); }
EventContext[] contexts = findChildContexts(binding, rootNode, providedTags, parentContext.getInstrumentedNode(), parentContext.getInstrumentedSourceSection(), Math.max(parentChain.inputCount, index + lookupChildrenCount));
/** * Accessor to the instrumented node at which the event occurred. The returned AST must not be * mutated by the user. * <p> * <b>Performance note:</b> this is method may be invoked in compiled code and is guaranteed to * always return a compilation constant . * </p> * * @since 0.12 */ @SuppressWarnings("deprecation") public Node getInstrumentedNode() { com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode wrapper = probeNode.findWrapper(); return wrapper != null ? wrapper.getDelegateNode() : null; }
EventChainNode createBindings(VirtualFrame frame, ProbeNode probeNodeImpl) { EventContext context = probeNodeImpl.getContext(); SourceSection sourceSection = context.getInstrumentedSourceSection(); if (TRACE) { Node parentNode = probeNodeImpl.getParent(); while (parentNode != null && parentNode.getParent() != null) { if (parentInstrumentable == null) { Node instrumentedNode = probeNodeImpl.getContext().getInstrumentedNode(); Set<Class<?>> providedTags = getProvidedTags(rootNode); EventChainNode root = null; EventChainNode next = probeNodeImpl.createParentEventChainCallback(frame, binding, rootNode, providedTags); if (next == null) { trace(" Found binding %s, %s%n", binding.getFilter(), binding.getElement()); EventChainNode next = probeNodeImpl.createEventChainCallback(frame, binding, rootNode, providedTags, instrumentedNode, sourceSection); if (next == null) { continue;
@SuppressWarnings("deprecation") static void removeWrapper(ProbeNode node) { if (TRACE) { trace("Remove wrapper for %s%n", node.getContext().getInstrumentedSourceSection()); } com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode wrapperNode = node.findWrapper(); ((Node) wrapperNode).replace(wrapperNode.getDelegateNode()); }
@SuppressWarnings("deprecation") private static void invalidateWrapperImpl(com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode parent, Node node) { ProbeNode probeNode = parent.getProbeNode(); if (TRACE) { SourceSection section = probeNode.getContext().getInstrumentedSourceSection(); trace("Invalidate wrapper for %s, section %s %n", node, section); } if (probeNode != null) { probeNode.invalidate(); } }
final EventContext getInputContext(int index) { EventContext[] contexts = inputContexts; if (contexts == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); ProbeNode probe = findProbe(); EventContext thisContext = probe.context; RootNode rootNode = getRootNode(); Set<Class<?>> providedTags = probe.handler.getProvidedTags(rootNode); inputContexts = contexts = findChildContexts(getBinding(), rootNode, providedTags, thisContext.getInstrumentedNode(), thisContext.getInstrumentedSourceSection(), inputCount); } if (contexts == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); throw new IllegalStateException("Input event context not yet available. They are only available during event notifications."); } return contexts[index]; }
/** * Accessor to the instrumented node at which the event occurred. The returned AST must not be * mutated by the user. * <p> * <b>Performance note:</b> this is method may be invoked in compiled code and is guaranteed to * always return a compilation constant . * </p> * * @since 0.12 */ @SuppressWarnings("deprecation") public Node getInstrumentedNode() { com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode wrapper = probeNode.findWrapper(); return wrapper != null ? wrapper.getDelegateNode() : null; }
} else { assert element instanceof ExecutionEventNodeFactory; ExecutionEventNode eventNode = createEventNode(binding, element); if (eventNode == null) { EventChainNode parent = findParentChain(frame, binding); EventProviderWithInputChainNode parentChain = ((EventProviderWithInputChainNode) parent); baseInput = 0; } else { EventContext parentContext = parentChain.findProbe().getContext(); int childIndex = indexOfChild(binding, rootNode, providedTags, parentContext.getInstrumentedNode(), parentContext.getInstrumentedSourceSection(), instrumentedNode); int inputBaseIndex = parentChain.inputBaseIndex; if (childIndex < 0) { int inputCount = countChildren(binding, rootNode, providedTags, instrumentedNode, instrumentedNodeSourceSection); next = new EventProviderWithInputChainNode(binding, eventNode, baseInput, inputCount); } else {
private static boolean checkInteropType(Object value, EventBinding.Source<?> binding) { if (value != null && value != UNWIND_ACTION_REENTER && !InstrumentationHandler.ACCESSOR.isTruffleObject(value)) { Class<?> clazz = value.getClass(); if (!(clazz == Byte.class || clazz == Short.class || clazz == Integer.class || clazz == Long.class || clazz == Float.class || clazz == Double.class || clazz == Character.class || clazz == Boolean.class || clazz == String.class)) { CompilerDirectives.transferToInterpreter(); ClassCastException ccex = new ClassCastException(clazz.getName() + " isn't allowed Truffle interop type!"); if (binding.isLanguageBinding()) { throw ccex; } else { exceptionEventForClientInstrument(binding, "onUnwind", ccex); return false; } } } return true; }
return; ProbeNode probe = new ProbeNode(InstrumentationHandler.this, sourceSection); com.oracle.truffle.api.instrumentation.InstrumentableFactory.WrapperNode wrapper; try { assert probe.getContext().validEventContext();
final EventContext getInputContext(int index) { EventContext[] contexts = inputContexts; if (contexts == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); ProbeNode probe = findProbe(); EventContext thisContext = probe.context; RootNode rootNode = getRootNode(); Set<Class<?>> providedTags = probe.handler.getProvidedTags(rootNode); inputContexts = contexts = findChildContexts(getBinding(), rootNode, providedTags, thisContext.getInstrumentedNode(), thisContext.getInstrumentedSourceSection(), inputCount); } if (contexts == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); throw new IllegalStateException("Input event context not yet available. They are only available during event notifications."); } return contexts[index]; }
private ExecutionEventNode createEventNode(EventBinding.Source<?> binding, Object element) { ExecutionEventNode eventNode; try { eventNode = ((ExecutionEventNodeFactory) element).create(context); if (eventNode.getParent() != null) { throw new IllegalStateException(String.format("Returned EventNode %s was already adopted by another AST.", eventNode)); } } catch (Throwable t) { if (binding.isLanguageBinding()) { /* Language bindings can just throw exceptions directly into the AST. */ throw t; } else { /* * Client Instruments are not allowed to disrupt program execution by throwing * exceptions into the AST. */ exceptionEventForClientInstrument(binding, "ProbeNodeFactory.create", t); return null; } } return eventNode; }