OLD | NEW |
| (Empty) |
1 // Copyright 2009 the V8 project authors. All rights reserved. | |
2 // Redistribution and use in source and binary forms, with or without | |
3 // modification, are permitted provided that the following conditions are | |
4 // met: | |
5 // | |
6 // * Redistributions of source code must retain the above copyright | |
7 // notice, this list of conditions and the following disclaimer. | |
8 // * Redistributions in binary form must reproduce the above | |
9 // copyright notice, this list of conditions and the following | |
10 // disclaimer in the documentation and/or other materials provided | |
11 // with the distribution. | |
12 // * Neither the name of Google Inc. nor the names of its | |
13 // contributors may be used to endorse or promote products derived | |
14 // from this software without specific prior written permission. | |
15 // | |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | |
28 #ifndef V8_FRAME_ELEMENT_H_ | |
29 #define V8_FRAME_ELEMENT_H_ | |
30 | |
31 #include "allocation.h" | |
32 #include "type-info.h" | |
33 #include "macro-assembler.h" | |
34 #include "zone.h" | |
35 | |
36 namespace v8 { | |
37 namespace internal { | |
38 | |
39 // ------------------------------------------------------------------------- | |
40 // Virtual frame elements | |
41 // | |
42 // The internal elements of the virtual frames. There are several kinds of | |
43 // elements: | |
44 // * Invalid: elements that are uninitialized or not actually part | |
45 // of the virtual frame. They should not be read. | |
46 // * Memory: an element that resides in the actual frame. Its address is | |
47 // given by its position in the virtual frame. | |
48 // * Register: an element that resides in a register. | |
49 // * Constant: an element whose value is known at compile time. | |
50 | |
51 class FrameElement BASE_EMBEDDED { | |
52 public: | |
53 enum SyncFlag { | |
54 NOT_SYNCED, | |
55 SYNCED | |
56 }; | |
57 | |
58 inline TypeInfo type_info() { | |
59 // Copied elements do not have type info. Instead | |
60 // we have to inspect their backing element in the frame. | |
61 ASSERT(!is_copy()); | |
62 return TypeInfo::FromInt(TypeInfoField::decode(value_)); | |
63 } | |
64 | |
65 inline void set_type_info(TypeInfo info) { | |
66 // Copied elements do not have type info. Instead | |
67 // we have to inspect their backing element in the frame. | |
68 ASSERT(!is_copy()); | |
69 value_ = value_ & ~TypeInfoField::mask(); | |
70 value_ = value_ | TypeInfoField::encode(info.ToInt()); | |
71 } | |
72 | |
73 // The default constructor creates an invalid frame element. | |
74 FrameElement() { | |
75 value_ = TypeField::encode(INVALID) | |
76 | CopiedField::encode(false) | |
77 | SyncedField::encode(false) | |
78 | TypeInfoField::encode(TypeInfo::Uninitialized().ToInt()) | |
79 | DataField::encode(0); | |
80 } | |
81 | |
82 // Factory function to construct an invalid frame element. | |
83 static FrameElement InvalidElement() { | |
84 FrameElement result; | |
85 return result; | |
86 } | |
87 | |
88 // Factory function to construct an in-memory frame element. | |
89 static FrameElement MemoryElement(TypeInfo info) { | |
90 FrameElement result(MEMORY, no_reg, SYNCED, info); | |
91 return result; | |
92 } | |
93 | |
94 // Factory function to construct an in-register frame element. | |
95 static FrameElement RegisterElement(Register reg, | |
96 SyncFlag is_synced, | |
97 TypeInfo info) { | |
98 return FrameElement(REGISTER, reg, is_synced, info); | |
99 } | |
100 | |
101 // Factory function to construct a frame element whose value is known at | |
102 // compile time. | |
103 static FrameElement ConstantElement(Handle<Object> value, | |
104 SyncFlag is_synced) { | |
105 TypeInfo info = TypeInfo::TypeFromValue(value); | |
106 FrameElement result(value, is_synced, info); | |
107 return result; | |
108 } | |
109 | |
110 static bool ConstantPoolOverflowed() { | |
111 return !DataField::is_valid( | |
112 Isolate::Current()->frame_element_constant_list()->length()); | |
113 } | |
114 | |
115 bool is_synced() const { return SyncedField::decode(value_); } | |
116 | |
117 void set_sync() { | |
118 ASSERT(type() != MEMORY); | |
119 value_ = value_ | SyncedField::encode(true); | |
120 } | |
121 | |
122 void clear_sync() { | |
123 ASSERT(type() != MEMORY); | |
124 value_ = value_ & ~SyncedField::mask(); | |
125 } | |
126 | |
127 bool is_valid() const { return type() != INVALID; } | |
128 bool is_memory() const { return type() == MEMORY; } | |
129 bool is_register() const { return type() == REGISTER; } | |
130 bool is_constant() const { return type() == CONSTANT; } | |
131 bool is_copy() const { return type() == COPY; } | |
132 | |
133 bool is_copied() const { return CopiedField::decode(value_); } | |
134 void set_copied() { value_ = value_ | CopiedField::encode(true); } | |
135 void clear_copied() { value_ = value_ & ~CopiedField::mask(); } | |
136 | |
137 // An untagged int32 FrameElement represents a signed int32 | |
138 // on the stack. These are only allowed in a side-effect-free | |
139 // int32 calculation, and if a non-int32 input shows up or an overflow | |
140 // occurs, we bail out and drop all the int32 values. | |
141 void set_untagged_int32(bool value) { | |
142 value_ &= ~UntaggedInt32Field::mask(); | |
143 value_ |= UntaggedInt32Field::encode(value); | |
144 } | |
145 bool is_untagged_int32() const { return UntaggedInt32Field::decode(value_); } | |
146 | |
147 Register reg() const { | |
148 ASSERT(is_register()); | |
149 uint32_t reg = DataField::decode(value_); | |
150 Register result; | |
151 result.code_ = reg; | |
152 return result; | |
153 } | |
154 | |
155 Handle<Object> handle() const { | |
156 ASSERT(is_constant()); | |
157 return Isolate::Current()->frame_element_constant_list()-> | |
158 at(DataField::decode(value_)); | |
159 } | |
160 | |
161 int index() const { | |
162 ASSERT(is_copy()); | |
163 return DataField::decode(value_); | |
164 } | |
165 | |
166 bool Equals(FrameElement other) { | |
167 uint32_t masked_difference = (value_ ^ other.value_) & ~CopiedField::mask(); | |
168 if (!masked_difference) { | |
169 // The elements are equal if they agree exactly except on copied field. | |
170 return true; | |
171 } else { | |
172 // If two constants have the same value, and agree otherwise, return true. | |
173 return !(masked_difference & ~DataField::mask()) && | |
174 is_constant() && | |
175 handle().is_identical_to(other.handle()); | |
176 } | |
177 } | |
178 | |
179 // Test if two FrameElements refer to the same memory or register location. | |
180 bool SameLocation(FrameElement* other) { | |
181 if (type() == other->type()) { | |
182 if (value_ == other->value_) return true; | |
183 if (is_constant() && handle().is_identical_to(other->handle())) { | |
184 return true; | |
185 } | |
186 } | |
187 return false; | |
188 } | |
189 | |
190 // Given a pair of non-null frame element pointers, return one of them | |
191 // as an entry frame candidate or null if they are incompatible. | |
192 FrameElement* Combine(FrameElement* other) { | |
193 // If either is invalid, the result is. | |
194 if (!is_valid()) return this; | |
195 if (!other->is_valid()) return other; | |
196 | |
197 if (!SameLocation(other)) return NULL; | |
198 // If either is unsynced, the result is. | |
199 FrameElement* result = is_synced() ? other : this; | |
200 return result; | |
201 } | |
202 | |
203 private: | |
204 enum Type { | |
205 INVALID, | |
206 MEMORY, | |
207 REGISTER, | |
208 CONSTANT, | |
209 COPY | |
210 }; | |
211 | |
212 // Used to construct memory and register elements. | |
213 FrameElement(Type type, | |
214 Register reg, | |
215 SyncFlag is_synced, | |
216 TypeInfo info) { | |
217 value_ = TypeField::encode(type) | |
218 | CopiedField::encode(false) | |
219 | SyncedField::encode(is_synced != NOT_SYNCED) | |
220 | TypeInfoField::encode(info.ToInt()) | |
221 | DataField::encode(reg.code_ > 0 ? reg.code_ : 0); | |
222 } | |
223 | |
224 // Used to construct constant elements. | |
225 FrameElement(Handle<Object> value, SyncFlag is_synced, TypeInfo info) { | |
226 ZoneObjectList* constant_list = | |
227 Isolate::Current()->frame_element_constant_list(); | |
228 value_ = TypeField::encode(CONSTANT) | |
229 | CopiedField::encode(false) | |
230 | SyncedField::encode(is_synced != NOT_SYNCED) | |
231 | TypeInfoField::encode(info.ToInt()) | |
232 | DataField::encode(constant_list->length()); | |
233 constant_list->Add(value); | |
234 } | |
235 | |
236 Type type() const { return TypeField::decode(value_); } | |
237 void set_type(Type type) { | |
238 value_ = value_ & ~TypeField::mask(); | |
239 value_ = value_ | TypeField::encode(type); | |
240 } | |
241 | |
242 void set_index(int new_index) { | |
243 ASSERT(is_copy()); | |
244 value_ = value_ & ~DataField::mask(); | |
245 value_ = value_ | DataField::encode(new_index); | |
246 } | |
247 | |
248 void set_reg(Register new_reg) { | |
249 ASSERT(is_register()); | |
250 value_ = value_ & ~DataField::mask(); | |
251 value_ = value_ | DataField::encode(new_reg.code_); | |
252 } | |
253 | |
254 // Encode type, copied, synced and data in one 32 bit integer. | |
255 uint32_t value_; | |
256 | |
257 // Declare BitFields with template parameters <type, start, size>. | |
258 class TypeField: public BitField<Type, 0, 3> {}; | |
259 class CopiedField: public BitField<bool, 3, 1> {}; | |
260 class SyncedField: public BitField<bool, 4, 1> {}; | |
261 class UntaggedInt32Field: public BitField<bool, 5, 1> {}; | |
262 class TypeInfoField: public BitField<int, 6, 7> {}; | |
263 class DataField: public BitField<uint32_t, 13, 32 - 13> {}; | |
264 | |
265 friend class VirtualFrame; | |
266 }; | |
267 | |
268 } } // namespace v8::internal | |
269 | |
270 #endif // V8_FRAME_ELEMENT_H_ | |
OLD | NEW |