| 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 "type-info.h" | |
| 32 #include "macro-assembler.h" | |
| 33 #include "zone.h" | |
| 34 | |
| 35 namespace v8 { | |
| 36 namespace internal { | |
| 37 | |
| 38 // ------------------------------------------------------------------------- | |
| 39 // Virtual frame elements | |
| 40 // | |
| 41 // The internal elements of the virtual frames. There are several kinds of | |
| 42 // elements: | |
| 43 // * Invalid: elements that are uninitialized or not actually part | |
| 44 // of the virtual frame. They should not be read. | |
| 45 // * Memory: an element that resides in the actual frame. Its address is | |
| 46 // given by its position in the virtual frame. | |
| 47 // * Register: an element that resides in a register. | |
| 48 // * Constant: an element whose value is known at compile time. | |
| 49 | |
| 50 class FrameElement BASE_EMBEDDED { | |
| 51 public: | |
| 52 enum SyncFlag { | |
| 53 NOT_SYNCED, | |
| 54 SYNCED | |
| 55 }; | |
| 56 | |
| 57 inline TypeInfo type_info() { | |
| 58 // Copied elements do not have type info. Instead | |
| 59 // we have to inspect their backing element in the frame. | |
| 60 ASSERT(!is_copy()); | |
| 61 return TypeInfo::FromInt(TypeInfoField::decode(value_)); | |
| 62 } | |
| 63 | |
| 64 inline void set_type_info(TypeInfo info) { | |
| 65 // Copied elements do not have type info. Instead | |
| 66 // we have to inspect their backing element in the frame. | |
| 67 ASSERT(!is_copy()); | |
| 68 value_ = value_ & ~TypeInfoField::mask(); | |
| 69 value_ = value_ | TypeInfoField::encode(info.ToInt()); | |
| 70 } | |
| 71 | |
| 72 // The default constructor creates an invalid frame element. | |
| 73 FrameElement() { | |
| 74 value_ = TypeField::encode(INVALID) | |
| 75 | CopiedField::encode(false) | |
| 76 | SyncedField::encode(false) | |
| 77 | TypeInfoField::encode(TypeInfo::Uninitialized().ToInt()) | |
| 78 | DataField::encode(0); | |
| 79 } | |
| 80 | |
| 81 // Factory function to construct an invalid frame element. | |
| 82 static FrameElement InvalidElement() { | |
| 83 FrameElement result; | |
| 84 return result; | |
| 85 } | |
| 86 | |
| 87 // Factory function to construct an in-memory frame element. | |
| 88 static FrameElement MemoryElement(TypeInfo info) { | |
| 89 FrameElement result(MEMORY, no_reg, SYNCED, info); | |
| 90 return result; | |
| 91 } | |
| 92 | |
| 93 // Factory function to construct an in-register frame element. | |
| 94 static FrameElement RegisterElement(Register reg, | |
| 95 SyncFlag is_synced, | |
| 96 TypeInfo info) { | |
| 97 return FrameElement(REGISTER, reg, is_synced, info); | |
| 98 } | |
| 99 | |
| 100 // Factory function to construct a frame element whose value is known at | |
| 101 // compile time. | |
| 102 static FrameElement ConstantElement(Handle<Object> value, | |
| 103 SyncFlag is_synced) { | |
| 104 TypeInfo info = TypeInfo::TypeFromValue(value); | |
| 105 FrameElement result(value, is_synced, info); | |
| 106 return result; | |
| 107 } | |
| 108 | |
| 109 static bool ConstantPoolOverflowed() { | |
| 110 return !DataField::is_valid( | |
| 111 Isolate::Current()->frame_element_constant_list()->length()); | |
| 112 } | |
| 113 | |
| 114 bool is_synced() const { return SyncedField::decode(value_); } | |
| 115 | |
| 116 void set_sync() { | |
| 117 ASSERT(type() != MEMORY); | |
| 118 value_ = value_ | SyncedField::encode(true); | |
| 119 } | |
| 120 | |
| 121 void clear_sync() { | |
| 122 ASSERT(type() != MEMORY); | |
| 123 value_ = value_ & ~SyncedField::mask(); | |
| 124 } | |
| 125 | |
| 126 bool is_valid() const { return type() != INVALID; } | |
| 127 bool is_memory() const { return type() == MEMORY; } | |
| 128 bool is_register() const { return type() == REGISTER; } | |
| 129 bool is_constant() const { return type() == CONSTANT; } | |
| 130 bool is_copy() const { return type() == COPY; } | |
| 131 | |
| 132 bool is_copied() const { return CopiedField::decode(value_); } | |
| 133 void set_copied() { value_ = value_ | CopiedField::encode(true); } | |
| 134 void clear_copied() { value_ = value_ & ~CopiedField::mask(); } | |
| 135 | |
| 136 // An untagged int32 FrameElement represents a signed int32 | |
| 137 // on the stack. These are only allowed in a side-effect-free | |
| 138 // int32 calculation, and if a non-int32 input shows up or an overflow | |
| 139 // occurs, we bail out and drop all the int32 values. | |
| 140 void set_untagged_int32(bool value) { | |
| 141 value_ &= ~UntaggedInt32Field::mask(); | |
| 142 value_ |= UntaggedInt32Field::encode(value); | |
| 143 } | |
| 144 bool is_untagged_int32() const { return UntaggedInt32Field::decode(value_); } | |
| 145 | |
| 146 Register reg() const { | |
| 147 ASSERT(is_register()); | |
| 148 uint32_t reg = DataField::decode(value_); | |
| 149 Register result; | |
| 150 result.code_ = reg; | |
| 151 return result; | |
| 152 } | |
| 153 | |
| 154 Handle<Object> handle() const { | |
| 155 ASSERT(is_constant()); | |
| 156 return Isolate::Current()->frame_element_constant_list()-> | |
| 157 at(DataField::decode(value_)); | |
| 158 } | |
| 159 | |
| 160 int index() const { | |
| 161 ASSERT(is_copy()); | |
| 162 return DataField::decode(value_); | |
| 163 } | |
| 164 | |
| 165 bool Equals(FrameElement other) { | |
| 166 uint32_t masked_difference = (value_ ^ other.value_) & ~CopiedField::mask(); | |
| 167 if (!masked_difference) { | |
| 168 // The elements are equal if they agree exactly except on copied field. | |
| 169 return true; | |
| 170 } else { | |
| 171 // If two constants have the same value, and agree otherwise, return true. | |
| 172 return !(masked_difference & ~DataField::mask()) && | |
| 173 is_constant() && | |
| 174 handle().is_identical_to(other.handle()); | |
| 175 } | |
| 176 } | |
| 177 | |
| 178 // Test if two FrameElements refer to the same memory or register location. | |
| 179 bool SameLocation(FrameElement* other) { | |
| 180 if (type() == other->type()) { | |
| 181 if (value_ == other->value_) return true; | |
| 182 if (is_constant() && handle().is_identical_to(other->handle())) { | |
| 183 return true; | |
| 184 } | |
| 185 } | |
| 186 return false; | |
| 187 } | |
| 188 | |
| 189 // Given a pair of non-null frame element pointers, return one of them | |
| 190 // as an entry frame candidate or null if they are incompatible. | |
| 191 FrameElement* Combine(FrameElement* other) { | |
| 192 // If either is invalid, the result is. | |
| 193 if (!is_valid()) return this; | |
| 194 if (!other->is_valid()) return other; | |
| 195 | |
| 196 if (!SameLocation(other)) return NULL; | |
| 197 // If either is unsynced, the result is. | |
| 198 FrameElement* result = is_synced() ? other : this; | |
| 199 return result; | |
| 200 } | |
| 201 | |
| 202 private: | |
| 203 enum Type { | |
| 204 INVALID, | |
| 205 MEMORY, | |
| 206 REGISTER, | |
| 207 CONSTANT, | |
| 208 COPY | |
| 209 }; | |
| 210 | |
| 211 // Used to construct memory and register elements. | |
| 212 FrameElement(Type type, | |
| 213 Register reg, | |
| 214 SyncFlag is_synced, | |
| 215 TypeInfo info) { | |
| 216 value_ = TypeField::encode(type) | |
| 217 | CopiedField::encode(false) | |
| 218 | SyncedField::encode(is_synced != NOT_SYNCED) | |
| 219 | TypeInfoField::encode(info.ToInt()) | |
| 220 | DataField::encode(reg.code_ > 0 ? reg.code_ : 0); | |
| 221 } | |
| 222 | |
| 223 // Used to construct constant elements. | |
| 224 FrameElement(Handle<Object> value, SyncFlag is_synced, TypeInfo info) { | |
| 225 ZoneObjectList* constant_list = | |
| 226 Isolate::Current()->frame_element_constant_list(); | |
| 227 value_ = TypeField::encode(CONSTANT) | |
| 228 | CopiedField::encode(false) | |
| 229 | SyncedField::encode(is_synced != NOT_SYNCED) | |
| 230 | TypeInfoField::encode(info.ToInt()) | |
| 231 | DataField::encode(constant_list->length()); | |
| 232 constant_list->Add(value); | |
| 233 } | |
| 234 | |
| 235 Type type() const { return TypeField::decode(value_); } | |
| 236 void set_type(Type type) { | |
| 237 value_ = value_ & ~TypeField::mask(); | |
| 238 value_ = value_ | TypeField::encode(type); | |
| 239 } | |
| 240 | |
| 241 void set_index(int new_index) { | |
| 242 ASSERT(is_copy()); | |
| 243 value_ = value_ & ~DataField::mask(); | |
| 244 value_ = value_ | DataField::encode(new_index); | |
| 245 } | |
| 246 | |
| 247 void set_reg(Register new_reg) { | |
| 248 ASSERT(is_register()); | |
| 249 value_ = value_ & ~DataField::mask(); | |
| 250 value_ = value_ | DataField::encode(new_reg.code_); | |
| 251 } | |
| 252 | |
| 253 // Encode type, copied, synced and data in one 32 bit integer. | |
| 254 uint32_t value_; | |
| 255 | |
| 256 // Declare BitFields with template parameters <type, start, size>. | |
| 257 class TypeField: public BitField<Type, 0, 3> {}; | |
| 258 class CopiedField: public BitField<bool, 3, 1> {}; | |
| 259 class SyncedField: public BitField<bool, 4, 1> {}; | |
| 260 class UntaggedInt32Field: public BitField<bool, 5, 1> {}; | |
| 261 class TypeInfoField: public BitField<int, 6, 7> {}; | |
| 262 class DataField: public BitField<uint32_t, 13, 32 - 13> {}; | |
| 263 | |
| 264 friend class VirtualFrame; | |
| 265 }; | |
| 266 | |
| 267 } } // namespace v8::internal | |
| 268 | |
| 269 #endif // V8_FRAME_ELEMENT_H_ | |
| OLD | NEW |