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;
}
}
}
}
}
}
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;
}
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;
}
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();
}
}
}
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;
}
Aggregations