Search in sources :

Example 1 with ExplodeLoop

use of com.oracle.truffle.api.nodes.ExplodeLoop in project graal by oracle.

the class OptimizedCompilationProfile method profileDirectCall.

@ExplodeLoop
void profileDirectCall(Object[] args) {
    Assumption typesAssumption = profiledArgumentTypesAssumption;
    if (typesAssumption == null) {
        if (CompilerDirectives.inInterpreter()) {
            initializeProfiledArgumentTypes(args);
        }
    } else {
        Class<?>[] types = profiledArgumentTypes;
        if (types != null) {
            if (types.length != args.length) {
                CompilerDirectives.transferToInterpreterAndInvalidate();
                typesAssumption.invalidate();
                profiledArgumentTypes = null;
            } else if (typesAssumption.isValid()) {
                for (int i = 0; i < types.length; i++) {
                    Class<?> type = types[i];
                    Object value = args[i];
                    if (type != null && (value == null || value.getClass() != type)) {
                        CompilerDirectives.transferToInterpreterAndInvalidate();
                        updateProfiledArgumentTypes(args, types);
                        break;
                    }
                }
            }
        }
    }
}
Also used : Assumption(com.oracle.truffle.api.Assumption) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop)

Example 2 with ExplodeLoop

use of com.oracle.truffle.api.nodes.ExplodeLoop in project graal by oracle.

the class FlatNodeGenFactory method createExplodeLoop.

private CodeAnnotationMirror createExplodeLoop() {
    DeclaredType explodeLoopType = context.getDeclaredType(ExplodeLoop.class);
    CodeAnnotationMirror explodeLoop = new CodeAnnotationMirror(explodeLoopType);
    DeclaredType loopExplosionKind = context.getDeclaredType(ExplodeLoop.LoopExplosionKind.class);
    if (loopExplosionKind != null) {
        VariableElement kindValue = ElementUtils.findVariableElement(loopExplosionKind, "FULL_EXPLODE_UNTIL_RETURN");
        if (kindValue != null) {
            explodeLoop.setElementValue(ElementUtils.findExecutableElement(explodeLoopType, "kind"), new CodeAnnotationValue(kindValue));
        }
    }
    return explodeLoop;
}
Also used : CodeAnnotationMirror(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) DeclaredType(javax.lang.model.type.DeclaredType) CodeAnnotationValue(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationValue)

Example 3 with ExplodeLoop

use of com.oracle.truffle.api.nodes.ExplodeLoop in project graal by oracle.

the class ExecuteMethodNode method checkArgTypes.

@ExplodeLoop
static boolean checkArgTypes(Object[] args, Type[] argTypes, ToJavaNode toJavaNode, @SuppressWarnings("unused") boolean dummy) {
    if (args.length != argTypes.length) {
        return false;
    }
    for (int i = 0; i < argTypes.length; i++) {
        Type argType = argTypes[i];
        Object arg = args[i];
        if (argType == null) {
            if (arg != null) {
                return false;
            }
        } else {
            if (arg == null) {
                return false;
            }
            if (argType instanceof Class<?>) {
                if (arg.getClass() != argType) {
                    return false;
                }
            } else if (argType instanceof JavaObjectType) {
                if (!(arg instanceof JavaObject && ((JavaObject) arg).getObjectClass() == ((JavaObjectType) argType).clazz)) {
                    return false;
                }
            } else if (argType instanceof PrimitiveType) {
                if (!((PrimitiveType) argType).test(arg, toJavaNode)) {
                    return false;
                }
            } else {
                CompilerDirectives.transferToInterpreter();
                throw new IllegalArgumentException(String.valueOf(argType));
            }
        }
    }
    return true;
}
Also used : GenericArrayType(java.lang.reflect.GenericArrayType) Type(java.lang.reflect.Type) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop)

Example 4 with ExplodeLoop

use of com.oracle.truffle.api.nodes.ExplodeLoop in project sulong by graalvm.

the class LLVMGlobalRootNode method execute.

@Override
@ExplodeLoop
public Object execute(VirtualFrame frame) {
    try (StackPointer basePointer = getContext().getThreadingStack().getStack().newFrame()) {
        try {
            TruffleObject appPath = (TruffleObject) ctxRef.get().getEnv().asGuestValue(applicationPath.getBytes());
            LLVMTruffleObject applicationPathObj = new LLVMTruffleObject(LLVMTypedForeignObject.createUnknown(appPath));
            Object[] realArgs = new Object[] { basePointer, mainFunctionType, applicationPathObj };
            Object result = startFunction.call(realArgs);
            getContext().awaitThreadTermination();
            return result;
        } catch (LLVMExitException e) {
            LLVMContext context = getContext();
            // if any variant of exit or abort was called, we know that all the necessary
            // cleanup was already done
            context.setCleanupNecessary(false);
            context.awaitThreadTermination();
            return e.getReturnCode();
        } catch (SulongRuntimeException e) {
            CompilerDirectives.transferToInterpreter();
            throw e;
        } catch (GuestLanguageRuntimeException e) {
            CompilerDirectives.transferToInterpreter();
            return e.handleExit();
        } finally {
            // if not done already, we want at least call a shutdown command
            getContext().shutdownThreads();
        }
    }
}
Also used : LLVMContext(com.oracle.truffle.llvm.runtime.LLVMContext) SulongRuntimeException(com.oracle.truffle.llvm.runtime.SulongRuntimeException) GuestLanguageRuntimeException(com.oracle.truffle.llvm.runtime.GuestLanguageRuntimeException) LLVMExitException(com.oracle.truffle.llvm.runtime.LLVMExitException) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) LLVMTruffleObject(com.oracle.truffle.llvm.runtime.LLVMTruffleObject) LLVMTypedForeignObject(com.oracle.truffle.llvm.runtime.interop.LLVMTypedForeignObject) StackPointer(com.oracle.truffle.llvm.runtime.memory.LLVMStack.StackPointer) TruffleObject(com.oracle.truffle.api.interop.TruffleObject) LLVMTruffleObject(com.oracle.truffle.llvm.runtime.LLVMTruffleObject) LLVMTruffleObject(com.oracle.truffle.llvm.runtime.LLVMTruffleObject) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop)

Example 5 with ExplodeLoop

use of com.oracle.truffle.api.nodes.ExplodeLoop in project sulong by graalvm.

the class LLVMDispatchBasicBlockNode method executeGeneric.

@Override
@ExplodeLoop(kind = LoopExplosionKind.MERGE_EXPLODE)
public Object executeGeneric(VirtualFrame frame) {
    copyArgumentsToFrame(frame);
    Object returnValue = null;
    CompilerAsserts.compilationConstant(bodyNodes.length);
    int basicBlockIndex = 0;
    int backEdgeCounter = 0;
    outer: while (basicBlockIndex != LLVMBasicBlockNode.RETURN_FROM_FUNCTION) {
        CompilerAsserts.partialEvaluationConstant(basicBlockIndex);
        LLVMBasicBlockNode bb = bodyNodes[basicBlockIndex];
        // execute all statements
        bb.executeStatements(frame);
        // execute control flow node, write phis, null stack frame slots, and dispatch to
        // the correct successor block
        LLVMControlFlowNode controlFlowNode = bb.termInstruction;
        if (controlFlowNode instanceof LLVMConditionalBranchNode) {
            LLVMConditionalBranchNode conditionalBranchNode = (LLVMConditionalBranchNode) controlFlowNode;
            boolean condition = conditionalBranchNode.executeCondition(frame);
            if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(LLVMConditionalBranchNode.TRUE_SUCCESSOR), condition)) {
                if (CompilerDirectives.inInterpreter()) {
                    bb.increaseBranchProbability(LLVMConditionalBranchNode.TRUE_SUCCESSOR);
                    if (conditionalBranchNode.getTrueSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, conditionalBranchNode, LLVMConditionalBranchNode.TRUE_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = conditionalBranchNode.getTrueSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            } else {
                if (CompilerDirectives.inInterpreter()) {
                    bb.increaseBranchProbability(LLVMConditionalBranchNode.FALSE_SUCCESSOR);
                    if (conditionalBranchNode.getFalseSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, conditionalBranchNode, LLVMConditionalBranchNode.FALSE_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = conditionalBranchNode.getFalseSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            }
        } else if (controlFlowNode instanceof LLVMSwitchNode) {
            LLVMSwitchNode switchNode = (LLVMSwitchNode) controlFlowNode;
            Object condition = switchNode.executeCondition(frame);
            int[] successors = switchNode.getSuccessors();
            for (int i = 0; i < successors.length - 1; i++) {
                Object caseValue = switchNode.getCase(i).executeGeneric(frame);
                assert caseValue.getClass() == condition.getClass() : "must be the same type - otherwise equals might wrongly return false";
                if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(i), condition.equals(caseValue))) {
                    if (CompilerDirectives.inInterpreter()) {
                        bb.increaseBranchProbability(i);
                        if (successors[i] <= basicBlockIndex) {
                            backEdgeCounter++;
                        }
                    }
                    executePhis(frame, switchNode, i);
                    nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                    basicBlockIndex = successors[i];
                    nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                    continue outer;
                }
            }
            int i = successors.length - 1;
            if (CompilerDirectives.inInterpreter()) {
                bb.increaseBranchProbability(i);
                if (successors[i] <= basicBlockIndex) {
                    backEdgeCounter++;
                }
            }
            executePhis(frame, switchNode, i);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = successors[i];
            nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
            continue outer;
        } else if (controlFlowNode instanceof LLVMIndirectBranchNode) {
            // TODO (chaeubl): we need a different approach here - this is awfully
            // inefficient (see GR-3664)
            LLVMIndirectBranchNode indirectBranchNode = (LLVMIndirectBranchNode) controlFlowNode;
            int[] successors = indirectBranchNode.getSuccessors();
            int successorBasicBlockIndex = indirectBranchNode.executeCondition(frame);
            for (int i = 0; i < successors.length - 1; i++) {
                if (CompilerDirectives.injectBranchProbability(bb.getBranchProbability(i), successors[i] == successorBasicBlockIndex)) {
                    if (CompilerDirectives.inInterpreter()) {
                        bb.increaseBranchProbability(i);
                        if (successors[i] <= basicBlockIndex) {
                            backEdgeCounter++;
                        }
                    }
                    executePhis(frame, indirectBranchNode, i);
                    nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                    basicBlockIndex = successors[i];
                    nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                    continue outer;
                }
            }
            int i = successors.length - 1;
            assert successorBasicBlockIndex == successors[i];
            if (CompilerDirectives.inInterpreter()) {
                bb.increaseBranchProbability(i);
                if (successors[i] <= basicBlockIndex) {
                    backEdgeCounter++;
                }
            }
            executePhis(frame, indirectBranchNode, i);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = successors[i];
            nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
            continue outer;
        } else if (controlFlowNode instanceof LLVMBrUnconditionalNode) {
            LLVMBrUnconditionalNode unconditionalNode = (LLVMBrUnconditionalNode) controlFlowNode;
            if (CompilerDirectives.inInterpreter()) {
                if (unconditionalNode.getSuccessor() <= basicBlockIndex) {
                    backEdgeCounter++;
                }
            }
            // required for instrumentation
            unconditionalNode.execute(frame);
            executePhis(frame, unconditionalNode, 0);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = unconditionalNode.getSuccessor();
            nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
            continue outer;
        } else if (controlFlowNode instanceof LLVMInvokeNode) {
            LLVMInvokeNode invokeNode = (LLVMInvokeNode) controlFlowNode;
            try {
                invokeNode.execute(frame);
                if (CompilerDirectives.inInterpreter()) {
                    if (invokeNode.getNormalSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, invokeNode, LLVMInvokeNode.NORMAL_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = invokeNode.getNormalSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            } catch (LLVMException e) {
                frame.setObject(exceptionValueSlot, e);
                if (CompilerDirectives.inInterpreter()) {
                    if (invokeNode.getUnwindSuccessor() <= basicBlockIndex) {
                        backEdgeCounter++;
                    }
                }
                executePhis(frame, invokeNode, LLVMInvokeNode.UNWIND_SUCCESSOR);
                nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
                basicBlockIndex = invokeNode.getUnwindSuccessor();
                nullDeadSlots(frame, basicBlockIndex, beforeBlockNuller);
                continue outer;
            }
        } else if (controlFlowNode instanceof LLVMRetNode) {
            LLVMRetNode retNode = (LLVMRetNode) controlFlowNode;
            returnValue = retNode.execute(frame);
            assert noPhisNecessary(retNode);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            basicBlockIndex = retNode.getSuccessor();
            continue outer;
        } else if (controlFlowNode instanceof LLVMResumeNode) {
            LLVMResumeNode resumeNode = (LLVMResumeNode) controlFlowNode;
            assert noPhisNecessary(resumeNode);
            nullDeadSlots(frame, basicBlockIndex, afterBlockNuller);
            resumeNode.execute(frame);
            CompilerAsserts.neverPartOfCompilation();
            throw new IllegalStateException("must not reach here");
        } else if (controlFlowNode instanceof LLVMUnreachableNode) {
            LLVMUnreachableNode unreachableNode = (LLVMUnreachableNode) controlFlowNode;
            assert noPhisNecessary(unreachableNode);
            unreachableNode.execute();
            CompilerAsserts.neverPartOfCompilation();
            throw new IllegalStateException("must not reach here");
        } else {
            CompilerAsserts.neverPartOfCompilation();
            throw new UnsupportedOperationException("unexpected controlFlowNode type: " + controlFlowNode);
        }
    }
    assert backEdgeCounter >= 0;
    LoopNode.reportLoopCount(this, backEdgeCounter);
    return returnValue;
}
Also used : LLVMControlFlowNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode) LLVMUnreachableNode(com.oracle.truffle.llvm.nodes.others.LLVMUnreachableNode) LLVMInvokeNode(com.oracle.truffle.llvm.nodes.func.LLVMInvokeNode) LLVMException(com.oracle.truffle.llvm.runtime.LLVMException) LLVMResumeNode(com.oracle.truffle.llvm.nodes.func.LLVMResumeNode) LLVMBasicBlockNode(com.oracle.truffle.llvm.nodes.base.LLVMBasicBlockNode) ExplodeLoop(com.oracle.truffle.api.nodes.ExplodeLoop)

Aggregations

ExplodeLoop (com.oracle.truffle.api.nodes.ExplodeLoop)34 Specialization (com.oracle.truffle.api.dsl.Specialization)27 LLVMTruffleObject (com.oracle.truffle.llvm.runtime.LLVMTruffleObject)25 UnexpectedResultException (com.oracle.truffle.api.nodes.UnexpectedResultException)5 TruffleObject (com.oracle.truffle.api.interop.TruffleObject)3 LLVMAddress (com.oracle.truffle.llvm.runtime.LLVMAddress)3 StackPointer (com.oracle.truffle.llvm.runtime.memory.LLVMStack.StackPointer)3 ArityException (com.oracle.truffle.api.interop.ArityException)2 UnsupportedMessageException (com.oracle.truffle.api.interop.UnsupportedMessageException)2 UnsupportedTypeException (com.oracle.truffle.api.interop.UnsupportedTypeException)2 LLVMContext (com.oracle.truffle.llvm.runtime.LLVMContext)2 LLVMFunctionDescriptor (com.oracle.truffle.llvm.runtime.LLVMFunctionDescriptor)2 LLVM80BitFloat (com.oracle.truffle.llvm.runtime.floating.LLVM80BitFloat)2 LLVMStack (com.oracle.truffle.llvm.runtime.memory.LLVMStack)2 GenericArrayType (java.lang.reflect.GenericArrayType)2 Type (java.lang.reflect.Type)2 Assumption (com.oracle.truffle.api.Assumption)1 UnknownIdentifierException (com.oracle.truffle.api.interop.UnknownIdentifierException)1 CodeAnnotationMirror (com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror)1 CodeAnnotationValue (com.oracle.truffle.dsl.processor.java.model.CodeAnnotationValue)1