@Override public CodeTree createBody(SpecializationData s, LocalContext values) { return builder.create().returnTrue().build(); } };
public CodeTree createLoad(FrameState frameState) { if (frameState.get(name) != null) { // already loaded return CodeTreeBuilder.singleString(""); } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); String fieldName = name + "_"; LocalVariable var = new LocalVariable(bitSetType, name, null); CodeTreeBuilder init = builder.create(); init.tree(CodeTreeBuilder.singleString(fieldName)); builder.tree(var.createDeclaration(init.build())); frameState.set(name, var); return builder.build(); }
private CodeTree createCallRemove(String reason, ExecutableTypeData forType, LocalContext currentValues) { if (singleSpecializable) { return createThrowUnsupported(currentValues); } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); builder.startCall("remove"); builder.doubleQuote(reason); currentValues.addReferencesTo(builder, FRAME_VALUE); builder.end(); CodeTree call = builder.build(); builder = builder.create(); builder.startReturn(); builder.tree(expectOrCast(genericType, forType, call)); builder.end(); return builder.build(); }
private CodeTree createCallNext(CodeTreeBuilder parent, ExecutableTypeData currentType, ExecutableTypeData callType, LocalContext currentValues) { if (singleSpecializable) { return createThrowUnsupported(currentValues); } CodeTreeBuilder callBuilder = parent.create(); callBuilder.tree(createCallDelegateExecute(callBuilder, CodeTreeBuilder.singleString("getNext()"), currentValues, currentType, callType)); nextUsed = true; return callBuilder.build(); }
private CodeTree createReturnUnexpectedResult(ExecutableTypeData forType, boolean needsCast) { TypeMirror returnType = context.getType(Object.class); CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); builder.startCall(needsCast ? "((UnexpectedResultException) ex)" : "ex", "getResult").end(); CodeTree call = builder.build(); builder = builder.create(); if (isVoid(forType.getReturnType())) { builder.statement(call); builder.returnStatement(); } else { builder.startReturn(); builder.tree(expectOrCast(returnType, forType, call)); builder.end(); } return builder.build(); }
private ChildExecutionResult createExecuteChild(CodeTreeBuilder parent, FrameState originalFrameState, FrameState frameState, NodeExecutionData execution, LocalVariable target) { ChildExecutionResult result; if (!typeSystem.hasImplicitSourceTypes(target.getTypeMirror())) { ExecutableTypeData targetExecutable = resolveTargetExecutable(execution, target.typeMirror); final CodeTreeBuilder builder = parent.create(); result = createCallSingleChildExecute(execution, target, frameState, targetExecutable); builder.string(target.getName()).string(" = "); builder.tree(result.code); result.code = builder.build(); } else { result = createExecuteChildImplicitCast(parent.create(), originalFrameState, frameState, execution, target); } return result; }
private static CodeTree createShortCircuit(LocalVariable targetValue, LocalVariable shortCircuitValue, CodeTree tryExecute) { if (shortCircuitValue == null) { return tryExecute; } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); builder.tree(shortCircuitValue.createDeclaration(shortCircuitValue.createReference())); builder.tree(targetValue.createDeclaration(builder.create().defaultValue(targetValue.getTypeMirror()).build())); builder.startIf().string(shortCircuitValue.getName()).end().startBlock(); builder.tree(tryExecute); builder.end(); return builder.build(); }
private CodeTree createSpecialize(CodeTreeBuilder parent, FrameState frameState, SpecializationGroup group, SpecializationData specialization) { CodeTreeBuilder builder = parent.create();
private CodeTree createCallExecuteAndSpecialize(ExecutableTypeData forType, FrameState frameState) { TypeMirror returnType = node.getPolymorphicSpecialization().getReturnType().getType(); String frame = null; if (needsFrameToExecute(reachableSpecializations)) { frame = FRAME_VALUE; } CodeTreeBuilder builder = CodeTreeBuilder.createBuilder(); builder.startCall("executeAndSpecialize"); frameState.addReferencesTo(builder, frame); builder.end(); CodeTree call = builder.build(); builder = builder.create(); if (isVoid(forType.getReturnType())) { builder.statement(call); builder.returnStatement(); } else { builder.startReturn(); builder.tree(expectOrCast(returnType, forType, call)); builder.end(); } return builder.build(); }
private CodeTree wrapInAMethod(CodeTreeBuilder parent, SpecializationGroup group, FrameState frameState, String suffix, CodeTree codeTree) { CodeExecutableElement parentMethod = (CodeExecutableElement) parent.findMethod(); CodeTypeElement parentClass = (CodeTypeElement) parentMethod.getEnclosingElement(); String name = parentMethod.getSimpleName().toString() + "_" + suffix + (boxingSplitIndex++); CodeExecutableElement method = parentClass.add( frameState.createMethod(modifiers(Modifier.PRIVATE), parentMethod.getReturnType(), name, FRAME_VALUE, STATE_VALUE)); CodeTreeBuilder builder = method.createBuilder(); builder.tree(codeTree); method.getThrownTypes().addAll(parentMethod.getThrownTypes()); addExplodeLoop(builder, group); CodeTreeBuilder parentBuilder = parent.create(); parentBuilder.startReturn(); parentBuilder.startCall(method.getSimpleName().toString()); frameState.addReferencesTo(parentBuilder, FRAME_VALUE, STATE_VALUE); parentBuilder.end(); parentBuilder.end(); return parentBuilder.build(); }
private CodeTree createThrowUnsupported(final CodeTreeBuilder parent, final FrameState frameState) { CodeTreeBuilder builder = parent.create(); builder.startThrow().startNew(context.getType(UnsupportedSpecializationException.class)); builder.string("this"); builder.startNewArray(new ArrayCodeTypeMirror(context.getType(Node.class)), null); List<CodeTree> values = new ArrayList<>(); for (NodeExecutionData execution : node.getChildExecutions()) { NodeChildData child = execution.getChild(); LocalVariable var = frameState.getValue(execution); if (child != null) { builder.string(accessNodeField(execution)); } else { builder.string("null"); } if (var != null) { values.add(var.createReference()); } } builder.end(); builder.trees(values.toArray(new CodeTree[0])); builder.end().end(); return builder.build(); }
private CodeTree createCatchRewriteException(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData forType, FrameState frameState, CodeTree execution, NodeExecutionMode mode) { if (specialization.getExceptions().isEmpty()) { return execution; } CodeTreeBuilder builder = parent.create(); builder.startTryBlock(); builder.tree(execution); boolean nonSlowPath = false; TypeMirror[] exceptionTypes = new TypeMirror[specialization.getExceptions().size()]; for (int i = 0; i < exceptionTypes.length; i++) { TypeMirror type = specialization.getExceptions().get(i).getJavaClass(); if (!ElementUtils.isAssignable(type, context.getType(SlowPathException.class)) && !ElementUtils.isAssignable(type, context.getType(ArithmeticException.class))) { nonSlowPath = true; } exceptionTypes[i] = type; } builder.end().startCatchBlock(exceptionTypes, "ex"); if (nonSlowPath) { builder.tree(createTransferToInterpreterAndInvalidate()); } else { builder.lineComment("implicit transferToInterpreterAndInvalidate()"); } builder.tree(createExcludeThis(builder, frameState, forType, specialization, mode)); builder.end(); return builder.build(); }
private CodeTree executeFastPathGroup(final CodeTreeBuilder parent, FrameState frameState, final ExecutableTypeData currentType, SpecializationGroup group, int sharedExecutes, List<SpecializationData> allowedSpecializations) { CodeTreeBuilder builder = parent.create(); FrameState originalFrameState = frameState.copy(); for (NodeExecutionData execution : node.getChildExecutions()) { if (execution.getIndex() < sharedExecutes) { // skip shared executes continue; } builder.tree(createFastPathExecuteChild(builder, originalFrameState, frameState, currentType, group, execution)); } builder.tree(visitSpecializationGroup(builder, group, currentType, frameState, allowedSpecializations, NodeExecutionMode.FAST_PATH)); if (group.hasFallthrough()) { builder.tree(createTransferToInterpreterAndInvalidate()); builder.tree(createCallExecuteAndSpecialize(currentType, originalFrameState)); } return builder.build(); }
private CodeTree createCallDelegateExecute(final CodeTreeBuilder parent, CodeTree receiver, LocalContext currentLocals, ExecutableTypeData source, ExecutableTypeData delegate) { CodeTreeBuilder callBuilder = parent.create(); CodeTree call = expectOrCast(delegate.getReturnType(), source, callBuilder.build()); CodeTreeBuilder returnBuilder = parent.create(); if (isVoid(source.getReturnType())) { returnBuilder.statement(call); CodeTreeBuilder builder = parent.create();
private CodeTree createFastPathAssumptionCheck(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData forType, FrameState frameState) throws AssertionError { CodeTreeBuilder builder = parent.create(); builder.startIf(); String sep = ""; for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) { builder.string(sep); builder.string("!"); builder.startCall("isValid_").tree(createAssumptionReference(frameState, specialization, assumption)).end(); isValidSignatures.put(ElementUtils.getQualifiedName(assumption.getExpression().getResolvedType()), assumption.getExpression().getResolvedType()); sep = " || "; } builder.end().startBlock(); builder.tree(createTransferToInterpreterAndInvalidate()); builder.tree(createRemoveThis(builder, frameState, forType, specialization)); builder.end(); return builder.build(); }
private CodeTree createUpdateImplicitCastState(CodeTreeBuilder parent, FrameState frameState, SpecializationData specialization) { CodeTreeBuilder builder = null; int signatureIndex = 0; for (Parameter p : specialization.getSignatureParameters()) { TypeMirror targetType = p.getType(); TypeMirror polymorphicType = node.getPolymorphicSpecialization().findParameterOrDie(p.getSpecification().getExecution()).getType(); if (typeSystem.hasImplicitSourceTypes(targetType) && needsCastTo(polymorphicType, targetType)) { String implicitFieldName = createImplicitTypeStateLocalName(p); if (builder == null) { builder = parent.create(); } builder.tree(state.createSetInteger(frameState, new TypeGuard(p.getType(), signatureIndex), CodeTreeBuilder.singleString(implicitFieldName))); } signatureIndex++; } return builder == null ? null : builder.build(); }
private CodeTree createFastPathExecute(CodeTreeBuilder parent, final ExecutableTypeData forType, SpecializationData specialization, FrameState frameState) { CodeTreeBuilder builder = parent.create(); int ifCount = 0; if (specialization.isFallback()) { builder.startIf().startCall(METHOD_FALLBACK_GUARD); if (fallbackNeedsFrame) { if (frameState.get(FRAME_VALUE) != null) { builder.string(FRAME_VALUE); } else { builder.nullLiteral(); } } if (fallbackNeedsState) { builder.string(STATE_VALUE); } frameState.addReferencesTo(builder); builder.end(); builder.end(); builder.startBlock(); ifCount++; } builder.tree(createExecute(builder, frameState, forType, specialization, NodeExecutionMode.FAST_PATH)); builder.end(ifCount); return builder.build(); }
private CodeTree createExecute(CodeTreeBuilder parent, FrameState frameState, final ExecutableTypeData forType, SpecializationData specialization, NodeExecutionMode mode) { CodeTreeBuilder builder = parent.create(); if (mode.isSlowPath()) { builder.statement("lock.unlock()"); builder.statement("hasLock = false"); } if (specialization.getMethod() == null) { builder.tree(createThrowUnsupported(builder, frameState)); } else { if (isVoid(specialization.getMethod().getReturnType())) { builder.statement(callTemplateMethod(null, specialization, frameState)); if (isVoid(forType.getReturnType())) { builder.returnStatement(); } else { builder.startReturn().defaultValue(forType.getReturnType()).end(); } } else { builder.startReturn(); builder.tree(expectOrCast(specialization.getReturnType().getType(), forType, callTemplateMethod(null, specialization, frameState))); builder.end(); } } return createCatchRewriteException(builder, specialization, forType, frameState, builder.build(), mode); }
private Element createCreate(CodeTypeElement clazz) { String methodName = "create"; CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), clazz.asType(), methodName); method.addParameter(new CodeVariableElement(context.getType(Object.class), "value")); CodeTreeBuilder builder = method.createBuilder(); builder.declaration(clazz.asType(), "newCast", builder.create().startNew(clazz.asType()).end()); for (TypeMirror sourceType : sourceTypes) { String seenField = seenFieldName(sourceType); builder.startStatement(); builder.string("newCast.").string(seenField).string(" = ").tree(TypeSystemCodeGenerator.check(typeSystem, sourceType, "value")); builder.end(); } builder.startReturn().string("newCast").end(); return method; }
private CodeTree createAssignExecuteChild(FrameState originalFrameState, FrameState frameState, CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData forType, LocalVariable targetValue) { CodeTreeBuilder builder = parent.create(); ChildExecutionResult executeChild = createExecuteChild(builder, originalFrameState, frameState, execution, targetValue); builder.tree(createTryExecuteChild(targetValue, executeChild.code, true, executeChild.throwsUnexpectedResult)); builder.end(); if (executeChild.throwsUnexpectedResult) { builder.startCatchBlock(getType(UnexpectedResultException.class), "ex"); FrameState slowPathFrameState = originalFrameState.copy(); slowPathFrameState.setValue(execution, targetValue.makeGeneric(context).accessWith(CodeTreeBuilder.singleString("ex.getResult()"))); ExecutableTypeData delegateType = node.getGenericExecutableType(forType); boolean found = false; for (NodeExecutionData otherExecution : node.getChildExecutions()) { if (found) { LocalVariable childEvaluatedValue = slowPathFrameState.createValue(otherExecution, genericType); builder.tree(createAssignExecuteChild(slowPathFrameState.copy(), slowPathFrameState, builder, otherExecution, delegateType, childEvaluatedValue)); slowPathFrameState.setValue(otherExecution, childEvaluatedValue); } else { // skip forward already evaluated found = execution == otherExecution; } } builder.tree(createCallExecuteAndSpecialize(forType, slowPathFrameState)); builder.end(); } return builder.build(); }