| 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 |