public int depth() { int d = 0; NodeSourcePosition pos = this; while (pos != null) { d++; pos = pos.getCaller(); } return d; }
@Override public NodeSourcePosition next() { NodeSourcePosition current = currentPosition; currentPosition = currentPosition.getCaller(); return current; } };
/** * Remove marker frames. */ public NodeSourcePosition trim() { NodeSourcePosition lastMarker = null; for (NodeSourcePosition current = this; current != null; current = current.getCaller()) { if (current.marker != None) { lastMarker = current; } } if (lastMarker == null) { return this; } return lastMarker.getCaller(); }
@Override public NodeSourcePosition nodeSourcePositionCaller(NodeSourcePosition pos) { return pos.getCaller(); }
@Override public String toString() { StringBuilder sb = new StringBuilder(100); NodeSourcePosition pos = this; while (pos != null) { format(sb, pos); if (pos.sourceLanguagePosition != null) { sb.append(" source=" + pos.sourceLanguagePosition.toShortString()); } pos = pos.getCaller(); if (pos != null) { sb.append(CodeUtil.NEW_LINE); } } return sb.toString(); }
@Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj != null && getClass() == obj.getClass()) { NodeSourcePosition that = (NodeSourcePosition) obj; if (hashCode != that.hashCode) { return false; } if (this.getBCI() == that.getBCI() && Objects.equals(this.getMethod(), that.getMethod()) && Objects.equals(this.getCaller(), that.getCaller()) && Objects.equals(this.sourceLanguagePosition, that.sourceLanguagePosition)) { return true; } } return false; }
public InlineCacheGuardPosition(NodeSourcePosition callStack, ResolvedJavaType dispatchedType, ResolvedJavaMethod targetMethod) { super(callStack.getCaller(), callStack.getMethod(), callStack.getBCI()); this.concreteMethod = targetMethod; this.dispatchedType = dispatchedType; this.hashCode = super.hashCode() + 7 * ((dispatchedType == null) ? 0 : dispatchedType.hashCode()) + 31 * targetMethod.hashCode(); }
private void verifySourcePosition(NodeSourcePosition originalPosition, NodeSourcePosition decodedSourcePosition) { if (originalPosition == null) { assert decodedSourcePosition == null; return; } assert originalPosition.getBCI() == decodedSourcePosition.getBCI(); assert originalPosition.getMethod().equals(decodedSourcePosition.getMethod()); verifySourcePosition(originalPosition.getCaller(), decodedSourcePosition.getCaller()); } }
private boolean compareCallContext(NodeSourcePosition successorPosition) { NodeSourcePosition position = getNodeSourcePosition(); NodeSourcePosition successor = successorPosition; while (position != null) { assertTrue(Objects.equals(position.getMethod(), successor.getMethod()), "method mismatch"); position = position.getCaller(); successor = successor.getCaller(); } assertTrue(successor == null, "successor position has more methods"); return true; }
/** * This method returns a unique key for the given node. Unless the node comes from a * substitution, the unique key is the BCI of the node. Every * newinstance/newarray/newmultiarray/instanceof/checkcast node coming from a substitution * method cannot have a BCI. If one substitution has multiple nodes of the same type, then the * BCI would not be unique. In the later case the key is a unique object. */ protected static Object uniqueKey(Node node) { NodeSourcePosition position = node.getNodeSourcePosition(); // If the 'position' has a 'caller' then it is inlined, case in which the BCI is // probably not unique. if (position != null && position.getCaller() == null) { if (position.getBCI() >= 0) { return position.getBCI(); } } return new Object(); }
private static boolean verifyTrim(NodeSourcePosition sourcePosition) { for (NodeSourcePosition sp = sourcePosition; sp != null; sp = sp.getCaller()) { assert (sp.getMethod().getAnnotation(Snippet.class) == null && sp.getMethod().getAnnotation(MethodSubstitution.class) == null); } return true; } }
private long encodeSourcePositions(NodeSourcePosition sourcePosition, EconomicMap<NodeSourcePosition, Long> sourcePositionStartOffsets, UnsafeArrayTypeWriter encodingBuffer) { Long existingAbsoluteOffset = sourcePositionStartOffsets.get(sourcePosition); if (existingAbsoluteOffset != null) { return existingAbsoluteOffset; } long callerAbsoluteOffset = -1; if (sourcePosition.getCaller() != null) { callerAbsoluteOffset = encodeSourcePositions(sourcePosition.getCaller(), sourcePositionStartOffsets, encodingBuffer); } long startAbsoluteOffset = encodingBuffer.getBytesWritten(); long callerRelativeOffset = DeoptimizationSourcePositionDecoder.NO_CALLER; if (sourcePosition.getCaller() != null) { callerRelativeOffset = startAbsoluteOffset - callerAbsoluteOffset; assert callerRelativeOffset > DeoptimizationSourcePositionDecoder.NO_CALLER; } encodingBuffer.putUV(callerRelativeOffset); encodingBuffer.putSV(sourcePosition.getBCI()); encodingBuffer.putUV(objectConstants.getIndex(sourcePosition.getMethod())); sourcePositionStartOffsets.put(sourcePosition, startAbsoluteOffset); return startAbsoluteOffset; }
private static String filterAndEncode(MethodFilter[] methodFilter, Node node, InstrumentPhase phase) { NodeSourcePosition pos = node.getNodeSourcePosition(); if (pos != null) { if (!MethodFilter.matches(methodFilter, pos.getMethod())) { return null; } if (phase.instrumentPerInlineSite(node.getOptions())) { StringBuilder sb = new StringBuilder(); while (pos != null) { MetaUtil.appendLocation(sb.append("at "), pos.getMethod(), pos.getBCI()); pos = pos.getCaller(); if (pos != null) { sb.append(CodeUtil.NEW_LINE); } } return sb.toString(); } else { return MetaUtil.appendLocation(new StringBuilder(), pos.getMethod(), pos.getBCI()).toString(); } } else { // IfNode has no position information, and is probably synthetic, so we do not // instrument it. return null; } }
private void addObjectConstants(NodeSourcePosition sourcePosition, EconomicSet<NodeSourcePosition> processedPositions) { if (sourcePosition == null || processedPositions.contains(sourcePosition)) { return; } addObjectConstants(sourcePosition.getCaller(), processedPositions); objectConstants.addObject(sourcePosition.getMethod()); processedPositions.add(sourcePosition); }
public NodeSourcePosition addCaller(SourceLanguagePosition newSourceLanguagePosition, NodeSourcePosition link, boolean isSubstitution) { if (getCaller() == null) { if (isPlaceholder()) { return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), 0); } assert link == null || isSubstitution || verifyCaller(this, link) : link; assert !isSubstitution || marker == None; return new NodeSourcePosition(newSourceLanguagePosition, link, getMethod(), getBCI(), isSubstitution ? Substitution : None); } else { return new NodeSourcePosition(getCaller().addCaller(newSourceLanguagePosition, link, isSubstitution), getMethod(), getBCI(), marker); } }
protected void raiseInvalidFrameStateError(FrameState state) throws GraalGraphError { // This is a hard error since an incorrect state could crash hotspot NodeSourcePosition sourcePosition = state.getNodeSourcePosition(); List<String> context = new ArrayList<>(); ResolvedJavaMethod replacementMethodWithProblematicSideEffect = null; if (sourcePosition != null) { NodeSourcePosition pos = sourcePosition; while (pos != null) { StringBuilder sb = new StringBuilder("parsing "); ResolvedJavaMethod method = pos.getMethod(); MetaUtil.appendLocation(sb, method, pos.getBCI()); if (method.getAnnotation(MethodSubstitution.class) != null || method.getAnnotation(Snippet.class) != null) { replacementMethodWithProblematicSideEffect = method; } context.add(sb.toString()); pos = pos.getCaller(); } } String message = "Invalid frame state " + state; if (replacementMethodWithProblematicSideEffect != null) { message += " associated with a side effect in " + replacementMethodWithProblematicSideEffect.format("%H.%n(%p)") + " at a position that cannot be deoptimized to"; } GraalGraphError error = new GraalGraphError(message); for (String c : context) { error.addContext(c); } throw error; } }
@Override public NodeSourcePosition getCallerBytecodePosition(NodeSourcePosition position) { if (caller == null) { return position; } if (callerBytecodePosition == null) { NodeSourcePosition invokePosition = invokeData.invoke.asNode().getNodeSourcePosition(); if (invokePosition == null) { assert position == null : "should only happen when tracking is disabled"; return null; } callerBytecodePosition = invokePosition; } if (position != null) { return position.addCaller(caller.resolveSourceLanguagePosition(), callerBytecodePosition); } final SourceLanguagePosition pos = caller.resolveSourceLanguagePosition(); if (pos != null && callerBytecodePosition != null) { return new NodeSourcePosition(pos, callerBytecodePosition.getCaller(), callerBytecodePosition.getMethod(), callerBytecodePosition.getBCI()); } return callerBytecodePosition; }
protected void readProperties(MethodScope methodScope, Node node) { NodeSourcePosition position = (NodeSourcePosition) readObject(methodScope); Fields fields = node.getNodeClass().getData(); for (int pos = 0; pos < fields.getCount(); pos++) { if (fields.getType(pos).isPrimitive()) { long primitive = methodScope.reader.getSV(); fields.setRawPrimitive(node, pos, primitive); } else { Object value = readObject(methodScope); fields.putObject(node, pos, value); } } if (graph.trackNodeSourcePosition() && position != null) { NodeSourcePosition callerBytecodePosition = methodScope.getCallerBytecodePosition(position); node.setNodeSourcePosition(callerBytecodePosition); if (node instanceof DeoptimizingGuard) { ((DeoptimizingGuard) node).addCallerToNoDeoptSuccessorPosition(callerBytecodePosition.getCaller()); } } }