comparison truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/FrameDescriptor.java@79d212bfee22
children 5023b913e2ba
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2012, 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 package com.oracle.truffle.api.frame;
26
27 import java.util.*;
28
29 import com.oracle.truffle.api.*;
30
31 /**
32 * Descriptor of the slots of frame objects. Multiple frame instances are associated with one such
33 * descriptor.
34 */
35 public final class FrameDescriptor implements Cloneable {
36
37 private final Object defaultValue;
38 private final ArrayList<FrameSlot> slots;
39 private final HashMap<Object, FrameSlot> identifierToSlotMap;
40 private Assumption version;
41 private HashMap<Object, Assumption> identifierToNotInFrameAssumptionMap;
42
43 public FrameDescriptor() {
44 this(null);
45 }
46
47 public FrameDescriptor(Object defaultValue) {
48 this.defaultValue = defaultValue;
49 slots = new ArrayList<>();
50 identifierToSlotMap = new HashMap<>();
51 version = createVersion();
52 }
53
54 public static FrameDescriptor create() {
55 return new FrameDescriptor();
56 }
57
58 public static FrameDescriptor create(Object defaultValue) {
59 return new FrameDescriptor(defaultValue);
60 }
61
62 public FrameSlot addFrameSlot(Object identifier) {
63 return addFrameSlot(identifier, null, FrameSlotKind.Illegal);
64 }
65
66 public FrameSlot addFrameSlot(Object identifier, FrameSlotKind kind) {
67 return addFrameSlot(identifier, null, kind);
68 }
69
70 public FrameSlot addFrameSlot(Object identifier, Object info, FrameSlotKind kind) {
71 CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations.");
72 assert !identifierToSlotMap.containsKey(identifier);
73 FrameSlot slot = new FrameSlot(this, identifier, info, slots.size(), kind);
74 slots.add(slot);
75 identifierToSlotMap.put(identifier, slot);
76 updateVersion();
77 invalidateNotInFrameAssumption(identifier);
78 return slot;
79 }
80
81 public FrameSlot findFrameSlot(Object identifier) {
82 return identifierToSlotMap.get(identifier);
83 }
84
85 public FrameSlot findOrAddFrameSlot(Object identifier) {
86 FrameSlot result = findFrameSlot(identifier);
87 if (result != null) {
88 return result;
89 }
90 return addFrameSlot(identifier);
91 }
92
93 public FrameSlot findOrAddFrameSlot(Object identifier, FrameSlotKind kind) {
94 FrameSlot result = findFrameSlot(identifier);
95 if (result != null) {
96 return result;
97 }
98 return addFrameSlot(identifier, kind);
99 }
100
101 public FrameSlot findOrAddFrameSlot(Object identifier, Object info, FrameSlotKind kind) {
102 FrameSlot result = findFrameSlot(identifier);
103 if (result != null) {
104 return result;
105 }
106 return addFrameSlot(identifier, info, kind);
107 }
108
109 public void removeFrameSlot(Object identifier) {
110 CompilerAsserts.neverPartOfCompilation("interpreter-only. includes hashmap operations.");
111 assert identifierToSlotMap.containsKey(identifier);
112 slots.remove(identifierToSlotMap.get(identifier));
113 identifierToSlotMap.remove(identifier);
114 updateVersion();
115 getNotInFrameAssumption(identifier);
116 }
117
118 public int getSize() {
119 return slots.size();
120 }
121
122 public List<? extends FrameSlot> getSlots() {
123 return Collections.unmodifiableList(slots);
124 }
125
126 /**
127 * Retrieve the list of all the identifiers associated with this frame descriptor.
128 *
129 * @return the list of all the identifiers in this frame descriptor
130 */
131 public Set<Object> getIdentifiers() {
132 return Collections.unmodifiableSet(identifierToSlotMap.keySet());
133 }
134
135 public FrameDescriptor copy() {
136 FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue);
137 for (int i = 0; i < this.getSlots().size(); i++) {
138 Object identifier = this.getSlots().get(i).getIdentifier();
139 clonedFrameDescriptor.addFrameSlot(identifier);
140 }
141 return clonedFrameDescriptor;
142 }
143
144 public FrameDescriptor shallowCopy() {
145 FrameDescriptor clonedFrameDescriptor = new FrameDescriptor(this.defaultValue);
146 clonedFrameDescriptor.slots.addAll(slots);
147 clonedFrameDescriptor.identifierToSlotMap.putAll(identifierToSlotMap);
148 return clonedFrameDescriptor;
149 }
150
151 void updateVersion() {
152 version.invalidate();
153 version = createVersion();
154 }
155
156 public Assumption getVersion() {
157 return version;
158 }
159
160 private static Assumption createVersion() {
161 return Truffle.getRuntime().createAssumption("frame version");
162 }
163
164 public Object getDefaultValue() {
165 return defaultValue;
166 }
167
168 public Assumption getNotInFrameAssumption(Object identifier) {
169 if (identifierToSlotMap.containsKey(identifier)) {
170 throw new IllegalArgumentException("Cannot get not-in-frame assumption for existing frame slot!");
171 }
172
173 if (identifierToNotInFrameAssumptionMap == null) {
174 identifierToNotInFrameAssumptionMap = new HashMap<>();
175 } else {
176 Assumption assumption = identifierToNotInFrameAssumptionMap.get(identifier);
177 if (assumption != null) {
178 return assumption;
179 }
180 }
181 Assumption assumption = Truffle.getRuntime().createAssumption("not in frame: " + identifier);
182 identifierToNotInFrameAssumptionMap.put(identifier, assumption);
183 return assumption;
184 }
185
186 private void invalidateNotInFrameAssumption(Object identifier) {
187 if (identifierToNotInFrameAssumptionMap != null) {
188 Assumption assumption = identifierToNotInFrameAssumptionMap.get(identifier);
189 if (assumption != null) {
190 assumption.invalidate();
191 identifierToNotInFrameAssumptionMap.remove(identifier);
192 }
193 }
194 }
195
196 @Override
197 public String toString() {
198 StringBuilder sb = new StringBuilder();
199 sb.append("FrameDescriptor@").append(Integer.toHexString(hashCode()));
200 sb.append("{");
201 boolean comma = false;
202 for (FrameSlot slot : slots) {
203 if (comma) {
204 sb.append(", ");
205 } else {
206 comma = true;
207 }
208 sb.append(slot.getIndex()).append(":").append(slot.getIdentifier());
209 }
210 sb.append("}");
211 return sb.toString();
212 }
213 }