OptimisticLexicalContext.java revision 1173:82ae555768c7
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 */
25package jdk.nashorn.internal.ir;
26
27import java.util.ArrayDeque;
28import java.util.ArrayList;
29import java.util.Collections;
30import java.util.Deque;
31import java.util.List;
32import jdk.nashorn.internal.codegen.types.Type;
33
34/**
35 * Lexical context that keeps track of optimistic assumptions (if any)
36 * made during code generation. Used from Attr and FinalizeTypes
37 */
38public class OptimisticLexicalContext extends LexicalContext {
39
40    private final boolean isEnabled;
41
42    class Assumption {
43        Symbol symbol;
44        Type   type;
45
46        Assumption(final Symbol symbol, final Type type) {
47            this.symbol = symbol;
48            this.type   = type;
49        }
50        @Override
51        public String toString() {
52            return symbol.getName() + "=" + type;
53        }
54    }
55
56    /** Optimistic assumptions that could be made per function */
57    private final Deque<List<Assumption>> optimisticAssumptions = new ArrayDeque<>();
58
59    /**
60     * Constructor
61     * @param isEnabled are optimistic types enabled?
62     */
63    public OptimisticLexicalContext(final boolean isEnabled) {
64        super();
65        this.isEnabled = isEnabled;
66    }
67
68    /**
69     * Are optimistic types enabled
70     * @return true if optimistic types
71     */
72    public boolean isEnabled() {
73        return isEnabled;
74    }
75
76    /**
77     * Log an optimistic assumption during codegen
78     * TODO : different parameters and more info about the assumption for future profiling
79     * needs
80     * @param symbol symbol
81     * @param type   type
82     */
83    public void logOptimisticAssumption(final Symbol symbol, final Type type) {
84        if (isEnabled) {
85            final List<Assumption> peek = optimisticAssumptions.peek();
86            peek.add(new Assumption(symbol, type));
87        }
88    }
89
90    /**
91     * Get the list of optimistic assumptions made
92     * @return optimistic assumptions
93     */
94    public List<Assumption> getOptimisticAssumptions() {
95        return Collections.unmodifiableList(optimisticAssumptions.peek());
96    }
97
98    /**
99     * Does this method have optimistic assumptions made during codegen?
100     * @return true if optimistic assumptions were made
101     */
102    public boolean hasOptimisticAssumptions() {
103        return !optimisticAssumptions.isEmpty() && !getOptimisticAssumptions().isEmpty();
104    }
105
106    @Override
107    public <T extends LexicalContextNode> T push(final T node) {
108        if (isEnabled) {
109            if(node instanceof FunctionNode) {
110                optimisticAssumptions.push(new ArrayList<Assumption>());
111            }
112        }
113
114        return super.push(node);
115    }
116
117    @Override
118    public <T extends Node> T pop(final T node) {
119        final T popped = super.pop(node);
120        if (isEnabled) {
121            if(node instanceof FunctionNode) {
122                optimisticAssumptions.pop();
123            }
124        }
125        return popped;
126    }
127
128}
129