src/jdk/nashorn/internal/ir/Node.java

Mon, 20 Oct 2014 12:06:36 +0200

author
attila
date
Mon, 20 Oct 2014 12:06:36 +0200
changeset 1064
03c06c337d9d
parent 1063
8c51767d534d
child 1205
4112748288bb
child 1361
55c1eef5c4fc
permissions
-rw-r--r--

8059844: Implement optimistic splitter
Reviewed-by: hannesw, lagergren

     1 /*
     2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package jdk.nashorn.internal.ir;
    28 import java.io.Serializable;
    29 import java.util.ArrayList;
    30 import java.util.List;
    31 import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    32 import jdk.nashorn.internal.parser.Token;
    33 import jdk.nashorn.internal.parser.TokenType;
    35 /**
    36  * Nodes are used to compose Abstract Syntax Trees.
    37  */
    38 public abstract class Node implements Cloneable, Serializable {
    39     private static final long serialVersionUID = 1L;
    41     /** Constant used for synthetic AST nodes that have no line number. */
    42     public static final int NO_LINE_NUMBER = -1;
    44     /** Constant used for synthetic AST nodes that have no token. */
    45     public static final long NO_TOKEN = 0L;
    47     /** Constant used for synthetic AST nodes that have no finish. */
    48     public static final int NO_FINISH = 0;
    50     /** Start of source range. */
    51     protected final int start;
    53     /** End of source range. */
    54     protected int finish;
    56     /** Token descriptor. */
    57     private final long token;
    59     /**
    60      * Constructor
    61      *
    62      * @param token  token
    63      * @param finish finish
    64      */
    65     public Node(final long token, final int finish) {
    66         this.token  = token;
    67         this.start  = Token.descPosition(token);
    68         this.finish = finish;
    69     }
    71     /**
    72      * Constructor
    73      *
    74      * @param token   token
    75      * @param start   start
    76      * @param finish  finish
    77      */
    78     protected Node(final long token, final int start, final int finish) {
    79         this.start = start;
    80         this.finish = finish;
    81         this.token = token;
    82     }
    84     /**
    85      * Copy constructor
    86      *
    87      * @param node source node
    88      */
    89     protected Node(final Node node) {
    90         this.token  = node.token;
    91         this.start  = node.start;
    92         this.finish = node.finish;
    93     }
    95     /**
    96      * Is this a loop node?
    97      *
    98      * @return true if atom
    99      */
   100     public boolean isLoop() {
   101         return false;
   102     }
   104     /**
   105      * Is this an assignment node - for example a var node with an init
   106      * or a binary node that writes to a destination
   107      *
   108      * @return true if assignment
   109      */
   110     public boolean isAssignment() {
   111         return false;
   112     }
   114     /**
   115      * For reference copies - ensure that labels in the copy node are unique
   116      * using an appropriate copy constructor
   117      * @param lc lexical context
   118      * @return new node or same of no labels
   119      */
   120     public Node ensureUniqueLabels(final LexicalContext lc) {
   121         return this;
   122     }
   124     /**
   125      * Provides a means to navigate the IR.
   126      * @param visitor Node visitor.
   127      * @return node the node or its replacement after visitation, null if no further visitations are required
   128      */
   129     public abstract Node accept(NodeVisitor<? extends LexicalContext> visitor);
   131     @Override
   132     public String toString() {
   133         final StringBuilder sb = new StringBuilder();
   134         toString(sb);
   135         return sb.toString();
   136     }
   138     /**
   139      * String conversion helper. Fills a {@link StringBuilder} with the
   140      * string version of this node
   141      *
   142      * @param sb a StringBuilder
   143      */
   144     public void toString(final StringBuilder sb) {
   145         toString(sb, true);
   146     }
   148     /**
   149      * Print logic that decides whether to show the optimistic type
   150      * or not - for example it should not be printed after just parse,
   151      * when it hasn't been computed, or has been set to a trivially provable
   152      * value
   153      * @param sb   string builder
   154      * @param printType print type?
   155      */
   156     public abstract void toString(final StringBuilder sb, final boolean printType);
   158     /**
   159      * Get the finish position for this node in the source string
   160      * @return finish
   161      */
   162     public int getFinish() {
   163         return finish;
   164     }
   166     /**
   167      * Set finish position for this node in the source string
   168      * @param finish finish
   169      */
   170     public void setFinish(final int finish) {
   171         this.finish = finish;
   172     }
   174     /**
   175      * Get start position for node
   176      * @return start position
   177      */
   178     public int getStart() {
   179         return start;
   180     }
   182     @Override
   183     protected Object clone() {
   184         try {
   185             return super.clone();
   186         } catch (final CloneNotSupportedException e) {
   187             throw new AssertionError(e);
   188         }
   189     }
   191     @Override
   192     public final boolean equals(final Object other) {
   193         return this == other;
   194     }
   196     @Override
   197     public final int hashCode() {
   198         // NOTE: we aren't delegating to Object.hashCode as it still requires trip to the VM for initializing,
   199         // it touches the object header and/or stores the identity hashcode somewhere, etc. There's several
   200         // places in the compiler pipeline that store nodes in maps, so this can get hot.
   201         return Long.hashCode(token);
   202     }
   204     /**
   205      * Return token position from a token descriptor.
   206      *
   207      * @return Start position of the token in the source.
   208      */
   209     public int position() {
   210         return Token.descPosition(token);
   211     }
   213     /**
   214      * Return token length from a token descriptor.
   215      *
   216      * @return Length of the token.
   217      */
   218     public int length() {
   219         return Token.descLength(token);
   220     }
   222     /**
   223      * Return token tokenType from a token descriptor.
   224      *
   225      * @return Type of token.
   226      */
   227     public TokenType tokenType() {
   228         return Token.descType(token);
   229     }
   231     /**
   232      * Test token tokenType.
   233      *
   234      * @param type a type to check this token against
   235      * @return true if token types match.
   236      */
   237     public boolean isTokenType(final TokenType type) {
   238         return Token.descType(token) == type;
   239     }
   241     /**
   242      * Get the token for this location
   243      * @return the token
   244      */
   245     public long getToken() {
   246         return token;
   247     }
   249     //on change, we have to replace the entire list, that's we can't simple do ListIterator.set
   250     static <T extends Node> List<T> accept(final NodeVisitor<? extends LexicalContext> visitor, final List<T> list) {
   251         final int size = list.size();
   252         if (size == 0) {
   253             return list;
   254         }
   256          List<T> newList = null;
   258         for (int i = 0; i < size; i++) {
   259             final T node = list.get(i);
   260             @SuppressWarnings("unchecked")
   261             final T newNode = node == null ? null : (T)node.accept(visitor);
   262             if (newNode != node) {
   263                 if (newList == null) {
   264                     newList = new ArrayList<>(size);
   265                     for (int j = 0; j < i; j++) {
   266                         newList.add(list.get(j));
   267                     }
   268                 }
   269                 newList.add(newNode);
   270             } else {
   271                 if (newList != null) {
   272                     newList.add(node);
   273                 }
   274             }
   275         }
   277         return newList == null ? list : newList;
   278     }
   280     static <T extends LexicalContextNode> T replaceInLexicalContext(final LexicalContext lc, final T oldNode, final T newNode) {
   281         if (lc != null) {
   282             lc.replace(oldNode, newNode);
   283         }
   284         return newNode;
   285     }
   286 }

mercurial