nashorn/src/jdk/nashorn/internal/codegen/Frame.java
changeset 17535 a1435ffd1926
parent 17533 93a2cadbbd33
parent 17289 4dec41b3c5e3
child 17536 b0e6d5596000
equal deleted inserted replaced
17533:93a2cadbbd33 17535:a1435ffd1926
     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  */
       
    25 
       
    26 package jdk.nashorn.internal.codegen;
       
    27 
       
    28 import java.util.ArrayList;
       
    29 import java.util.Collections;
       
    30 import java.util.List;
       
    31 import jdk.nashorn.internal.ir.Symbol;
       
    32 
       
    33 /**
       
    34  * Tracks the variable area state.
       
    35  *
       
    36  */
       
    37 public final class Frame {
       
    38     /** Previous frame. */
       
    39     private Frame previous;
       
    40 
       
    41     /** Current variables. */
       
    42     private final ArrayList<Symbol> symbols;
       
    43 
       
    44     /** Number of slots in previous frame. */
       
    45     private int baseCount;
       
    46 
       
    47     /** Number of slots in this frame. */
       
    48     private int count;
       
    49 
       
    50     /**
       
    51      * Constructor.
       
    52      *
       
    53      * @param previous frame, the parent variable frame
       
    54      */
       
    55     public Frame(final Frame previous) {
       
    56         this.previous  = previous;
       
    57         this.symbols   = new ArrayList<>();
       
    58         this.baseCount = getBaseCount();
       
    59         this.count     = 0;
       
    60     }
       
    61 
       
    62     /**
       
    63      * Copy constructor
       
    64      * @param frame
       
    65      * @param symbols
       
    66      */
       
    67     private Frame(final Frame frame, final List<Symbol> symbols) {
       
    68         this.previous  = frame.getPrevious() == null ? null : new Frame(frame.getPrevious(), frame.getPrevious().getSymbols());
       
    69         this.symbols   = new ArrayList<>(frame.getSymbols());
       
    70         this.baseCount = frame.getBaseCount();
       
    71         this.count     = frame.getCount();
       
    72     }
       
    73 
       
    74     /**
       
    75      * Copy the frame
       
    76      *
       
    77      * @return a new frame with the identical contents
       
    78      */
       
    79     public Frame copy() {
       
    80         return new Frame(this, getSymbols());
       
    81     }
       
    82 
       
    83     /**
       
    84      * Add a new variable to the frame.
       
    85      * @param symbol Symbol representing variable.
       
    86      */
       
    87     public void addSymbol(final Symbol symbol) {
       
    88         final int slot = symbol.getSlot();
       
    89         if (slot < 0) {
       
    90             symbols.add(symbol);
       
    91             count += symbol.slotCount();
       
    92         }
       
    93     }
       
    94 
       
    95     /**
       
    96      * Realign slot numbering prior to code generation.
       
    97      * @return Number of slots in frame.
       
    98      */
       
    99     public int realign() {
       
   100         baseCount = getBaseCount();
       
   101         count     = 0;
       
   102 
       
   103         for (final Symbol symbol : symbols) {
       
   104             if (symbol.hasSlot()) {
       
   105                 symbol.setSlot(baseCount + count);
       
   106                 count += symbol.slotCount();
       
   107             }
       
   108         }
       
   109 
       
   110         return count;
       
   111     }
       
   112 
       
   113     /**
       
   114      * Return the slot count of previous frames.
       
   115      * @return Number of slots in previous frames.
       
   116      */
       
   117     private int getBaseCount() {
       
   118         return previous != null ? previous.getSlotCount() : 0;
       
   119     }
       
   120 
       
   121     /**
       
   122      * Determine the number of slots to top of frame.
       
   123      * @return Number of slots in total.
       
   124      */
       
   125     public int getSlotCount() {
       
   126         return baseCount + count;
       
   127     }
       
   128 
       
   129     @Override
       
   130     public String toString() {
       
   131         final StringBuilder sb = new StringBuilder();
       
   132         Frame f = this;
       
   133         boolean hasPrev = false;
       
   134         int pos = 0;
       
   135 
       
   136         do {
       
   137             if (hasPrev) {
       
   138                 sb.append("\n");
       
   139             }
       
   140 
       
   141             sb.append("#").
       
   142                 append(pos++).
       
   143                 append(" {baseCount:").
       
   144                 append(baseCount).
       
   145                 append(", ").
       
   146                 append("count:").
       
   147                 append(count).
       
   148                 append("} ");
       
   149 
       
   150             for (final Symbol var : f.getSymbols()) {
       
   151                 sb.append('[').
       
   152                     append(var.toString()).
       
   153                     append(' ').
       
   154                     append(var.hashCode()).
       
   155                     append("] ");
       
   156             }
       
   157 
       
   158             f = f.getPrevious();
       
   159             hasPrev = true;
       
   160         } while (f != null);
       
   161 
       
   162         return sb.toString();
       
   163     }
       
   164 
       
   165     /**
       
   166      * Get variable count for this frame
       
   167      * @return variable count
       
   168      */
       
   169     public int getCount() {
       
   170         return count;
       
   171     }
       
   172 
       
   173     /**
       
   174      * Get previous frame
       
   175      * @return previous frame
       
   176      */
       
   177     public Frame getPrevious() {
       
   178         return previous;
       
   179     }
       
   180 
       
   181     /**
       
   182      * Set previous frame
       
   183      * @param previous previous frame
       
   184      */
       
   185     public void setPrevious(final Frame previous) {
       
   186         this.previous = previous;
       
   187     }
       
   188 
       
   189     /**
       
   190      * Get symbols in frame
       
   191      * @return a list of symbols in this frame
       
   192      */
       
   193     public List<Symbol> getSymbols() {
       
   194         return Collections.unmodifiableList(symbols);
       
   195     }
       
   196  }