|
Java example source code file (CompilationPhase.java)
The CompilationPhase.java Java example source codepackage jdk.nashorn.internal.codegen; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.ATTR; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.CONSTANT_FOLDED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.FINALIZED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.INITIALIZED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.LOWERED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.PARSED; import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Deque; import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; import jdk.nashorn.internal.codegen.types.Range; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.LexicalContext; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.Symbol; import jdk.nashorn.internal.ir.TemporarySymbols; import jdk.nashorn.internal.ir.debug.ASTWriter; import jdk.nashorn.internal.ir.debug.PrintVisitor; import jdk.nashorn.internal.ir.visitor.NodeVisitor; import jdk.nashorn.internal.runtime.ECMAErrors; import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.Timing; /** * A compilation phase is a step in the processes of turning a JavaScript * FunctionNode into bytecode. It has an optional return value. */ enum CompilationPhase { /* * Lazy initialization - tag all function nodes not the script as lazy as * default policy. The will get trampolines and only be generated when * called */ LAZY_INITIALIZATION_PHASE(EnumSet.of(INITIALIZED, PARSED)) { @Override FunctionNode transform(final Compiler compiler, final FunctionNode fn) { /* * For lazy compilation, we might be given a node previously marked * as lazy to compile as the outermost function node in the * compiler. Unmark it so it can be compiled and not cause * recursion. Make sure the return type is unknown so it can be * correctly deduced. Return types are always Objects in Lazy nodes * as we haven't got a change to generate code for them and decude * its parameter specialization * * TODO: in the future specializations from a callsite will be * passed here so we can generate a better non-lazy version of a * function from a trampoline */ final FunctionNode outermostFunctionNode = fn; final Set<FunctionNode> neverLazy = new HashSet<>(); final Set<FunctionNode> lazy = new HashSet<>(); FunctionNode newFunctionNode = outermostFunctionNode; newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { // self references are done with invokestatic and thus cannot // have trampolines - never lazy @Override public boolean enterCallNode(final CallNode node) { final Node callee = node.getFunction(); if (callee instanceof FunctionNode) { neverLazy.add(((FunctionNode)callee)); return false; } return true; } //any function that isn't the outermost one must be marked as lazy @Override public boolean enterFunctionNode(final FunctionNode node) { assert compiler.isLazy(); lazy.add(node); return true; } }); //at least one method is non lazy - the outermost one neverLazy.add(newFunctionNode); for (final FunctionNode node : neverLazy) { Compiler.LOG.fine( "Marking ", node.getName(), " as non lazy, as it's a self reference"); lazy.remove(node); } newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { @Override public Node leaveFunctionNode(final FunctionNode functionNode) { if (lazy.contains(functionNode)) { Compiler.LOG.fine( "Marking ", functionNode.getName(), " as lazy"); final FunctionNode parent = lc.getParentFunction(functionNode); assert parent != null; lc.setFlag(parent, FunctionNode.HAS_LAZY_CHILDREN); lc.setBlockNeedsScope(parent.getBody()); lc.setFlag(functionNode, FunctionNode.IS_LAZY); return functionNode; } return functionNode. clearFlag(lc, FunctionNode.IS_LAZY). setReturnType(lc, Type.UNKNOWN); } }); return newFunctionNode; } @Override public String toString() { return "[Lazy JIT Initialization]"; } }, /* * Constant folding pass Simple constant folding that will make elementary * constructs go away */ CONSTANT_FOLDING_PHASE(EnumSet.of(INITIALIZED, PARSED)) { @Override FunctionNode transform(final Compiler compiler, final FunctionNode fn) { return (FunctionNode)fn.accept(new FoldConstants()); } @Override public String toString() { return "[Constant Folding]"; } }, /* * Lower (Control flow pass) Finalizes the control flow. Clones blocks for * finally constructs and similar things. Establishes termination criteria * for nodes Guarantee return instructions to method making sure control * flow cannot fall off the end. Replacing high level nodes with lower such * as runtime nodes where applicable. */ LOWERING_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED)) { @Override FunctionNode transform(final Compiler compiler, final FunctionNode fn) { return (FunctionNode)fn.accept(new Lower(compiler.getCodeInstaller())); } @Override public String toString() { return "[Control Flow Lowering]"; } }, /* * Attribution Assign symbols and types to all nodes. */ ATTRIBUTION_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED)) { @Override FunctionNode transform(final Compiler compiler, final FunctionNode fn) { final TemporarySymbols ts = compiler.getTemporarySymbols(); final FunctionNode newFunctionNode = (FunctionNode)enterAttr(fn, ts).accept(new Attr(ts)); if (compiler.getEnv()._print_mem_usage) { Compiler.LOG.info("Attr temporary symbol count: " + ts.getTotalSymbolCount()); } return newFunctionNode; } /** * Pessimistically set all lazy functions' return types to Object * and the function symbols to object * @param functionNode node where to start iterating */ private FunctionNode enterAttr(final FunctionNode functionNode, final TemporarySymbols ts) { return (FunctionNode)functionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { @Override public Node leaveFunctionNode(final FunctionNode node) { if (node.isLazy()) { FunctionNode newNode = node.setReturnType(lc, Type.OBJECT); return ts.ensureSymbol(lc, Type.OBJECT, newNode); } //node may have a reference here that needs to be nulled if it was referred to by //its outer context, if it is lazy and not attributed return node.setReturnType(lc, Type.UNKNOWN).setSymbol(lc, null); } }); } @Override public String toString() { return "[Type Attribution]"; } }, /* * Range analysis * Conservatively prove that certain variables can be narrower than * the most generic number type */ RANGE_ANALYSIS_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) { @Override FunctionNode transform(final Compiler compiler, final FunctionNode fn) { if (!compiler.getEnv()._range_analysis) { return fn; } FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer()); final List<ReturnNode> returns = new ArrayList<>(); newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { private final Deque<ArrayList Other Java examples (source code examples)Here is a short list of links related to this Java CompilationPhase.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.