| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 // | 4 // |
| 5 // Review notes: | 5 // Review notes: |
| 6 // | 6 // |
| 7 // - The use of macros in these inline functions may seem superfluous | 7 // - The use of macros in these inline functions may seem superfluous |
| 8 // but it is absolutely needed to make sure gcc generates optimal | 8 // but it is absolutely needed to make sure gcc generates optimal |
| 9 // code. gcc is not happy when attempting to inline too deep. | 9 // code. gcc is not happy when attempting to inline too deep. |
| 10 // | 10 // |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 } | 47 } |
| 48 | 48 |
| 49 | 49 |
| 50 PropertyDetails PropertyDetails::AsDeleted() const { | 50 PropertyDetails PropertyDetails::AsDeleted() const { |
| 51 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1)); | 51 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1)); |
| 52 return PropertyDetails(smi); | 52 return PropertyDetails(smi); |
| 53 } | 53 } |
| 54 | 54 |
| 55 | 55 |
| 56 #define TYPE_CHECKER(type, instancetype) \ | 56 #define TYPE_CHECKER(type, instancetype) \ |
| 57 bool Object::Is##type() { \ | 57 bool Object::Is##type() const { \ |
| 58 return Object::IsHeapObject() && \ | 58 return Object::IsHeapObject() && \ |
| 59 HeapObject::cast(this)->map()->instance_type() == instancetype; \ | 59 HeapObject::cast(this)->map()->instance_type() == instancetype; \ |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 // TODO(svenpanne) We use const_cast here and at a few other places to break our | |
| 64 // dependency cycle between the cast methods and the predicates. This can be | |
| 65 // removed when the predicates are const-correct, too. | |
| 66 #define CAST_ACCESSOR(type) \ | 63 #define CAST_ACCESSOR(type) \ |
| 67 type* type::cast(Object* object) { \ | 64 type* type::cast(Object* object) { \ |
| 68 SLOW_ASSERT(object->Is##type()); \ | 65 SLOW_ASSERT(object->Is##type()); \ |
| 69 return reinterpret_cast<type*>(object); \ | 66 return reinterpret_cast<type*>(object); \ |
| 70 } \ | 67 } \ |
| 71 const type* type::cast(const Object* object) { \ | 68 const type* type::cast(const Object* object) { \ |
| 72 SLOW_ASSERT(const_cast<Object*>(object)->Is##type()); \ | 69 SLOW_ASSERT(object->Is##type()); \ |
| 73 return reinterpret_cast<const type*>(object); \ | 70 return reinterpret_cast<const type*>(object); \ |
| 74 } | 71 } |
| 75 | 72 |
| 76 | 73 |
| 77 #define INT_ACCESSORS(holder, name, offset) \ | 74 #define INT_ACCESSORS(holder, name, offset) \ |
| 78 int holder::name() const { return READ_INT_FIELD(this, offset); } \ | 75 int holder::name() const { return READ_INT_FIELD(this, offset); } \ |
| 79 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } | 76 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } |
| 80 | 77 |
| 81 | 78 |
| 82 #define ACCESSORS(holder, name, type, offset) \ | 79 #define ACCESSORS(holder, name, type, offset) \ |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 128 |
| 132 #define BOOL_ACCESSORS(holder, field, name, offset) \ | 129 #define BOOL_ACCESSORS(holder, field, name, offset) \ |
| 133 bool holder::name() const { \ | 130 bool holder::name() const { \ |
| 134 return BooleanBit::get(field(), offset); \ | 131 return BooleanBit::get(field(), offset); \ |
| 135 } \ | 132 } \ |
| 136 void holder::set_##name(bool value) { \ | 133 void holder::set_##name(bool value) { \ |
| 137 set_##field(BooleanBit::set(field(), offset, value)); \ | 134 set_##field(BooleanBit::set(field(), offset, value)); \ |
| 138 } | 135 } |
| 139 | 136 |
| 140 | 137 |
| 141 bool Object::IsFixedArrayBase() { | 138 bool Object::IsFixedArrayBase() const { |
| 142 return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray() || | 139 return IsFixedArray() || IsFixedDoubleArray() || IsConstantPoolArray() || |
| 143 IsFixedTypedArrayBase() || IsExternalArray(); | 140 IsFixedTypedArrayBase() || IsExternalArray(); |
| 144 } | 141 } |
| 145 | 142 |
| 146 | 143 |
| 147 // External objects are not extensible, so the map check is enough. | 144 // External objects are not extensible, so the map check is enough. |
| 148 bool Object::IsExternal() { | 145 bool Object::IsExternal() const { |
| 149 return Object::IsHeapObject() && | 146 return Object::IsHeapObject() && |
| 150 HeapObject::cast(this)->map() == | 147 HeapObject::cast(this)->map() == |
| 151 HeapObject::cast(this)->GetHeap()->external_map(); | 148 HeapObject::cast(this)->GetHeap()->external_map(); |
| 152 } | 149 } |
| 153 | 150 |
| 154 | 151 |
| 155 bool Object::IsAccessorInfo() { | 152 bool Object::IsAccessorInfo() const { |
| 156 return IsExecutableAccessorInfo() || IsDeclaredAccessorInfo(); | 153 return IsExecutableAccessorInfo() || IsDeclaredAccessorInfo(); |
| 157 } | 154 } |
| 158 | 155 |
| 159 | 156 |
| 160 bool Object::IsSmi() { | 157 bool Object::IsSmi() const { |
| 161 return HAS_SMI_TAG(this); | 158 return HAS_SMI_TAG(this); |
| 162 } | 159 } |
| 163 | 160 |
| 164 | 161 |
| 165 bool Object::IsHeapObject() { | 162 bool Object::IsHeapObject() const { |
| 166 return Internals::HasHeapObjectTag(this); | 163 return Internals::HasHeapObjectTag(this); |
| 167 } | 164 } |
| 168 | 165 |
| 169 | 166 |
| 170 TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE) | 167 TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE) |
| 171 TYPE_CHECKER(Symbol, SYMBOL_TYPE) | 168 TYPE_CHECKER(Symbol, SYMBOL_TYPE) |
| 172 | 169 |
| 173 | 170 |
| 174 bool Object::IsString() { | 171 bool Object::IsString() const { |
| 175 return Object::IsHeapObject() | 172 return Object::IsHeapObject() |
| 176 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE; | 173 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE; |
| 177 } | 174 } |
| 178 | 175 |
| 179 | 176 |
| 180 bool Object::IsName() { | 177 bool Object::IsName() const { |
| 181 return IsString() || IsSymbol(); | 178 return IsString() || IsSymbol(); |
| 182 } | 179 } |
| 183 | 180 |
| 184 | 181 |
| 185 bool Object::IsUniqueName() { | 182 bool Object::IsUniqueName() const { |
| 186 return IsInternalizedString() || IsSymbol(); | 183 return IsInternalizedString() || IsSymbol(); |
| 187 } | 184 } |
| 188 | 185 |
| 189 | 186 |
| 190 bool Object::IsSpecObject() { | 187 bool Object::IsSpecObject() const { |
| 191 return Object::IsHeapObject() | 188 return Object::IsHeapObject() |
| 192 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE; | 189 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE; |
| 193 } | 190 } |
| 194 | 191 |
| 195 | 192 |
| 196 bool Object::IsSpecFunction() { | 193 bool Object::IsSpecFunction() const { |
| 197 if (!Object::IsHeapObject()) return false; | 194 if (!Object::IsHeapObject()) return false; |
| 198 InstanceType type = HeapObject::cast(this)->map()->instance_type(); | 195 InstanceType type = HeapObject::cast(this)->map()->instance_type(); |
| 199 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE; | 196 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE; |
| 200 } | 197 } |
| 201 | 198 |
| 202 | 199 |
| 203 bool Object::IsTemplateInfo() { | 200 bool Object::IsTemplateInfo() const { |
| 204 return IsObjectTemplateInfo() || IsFunctionTemplateInfo(); | 201 return IsObjectTemplateInfo() || IsFunctionTemplateInfo(); |
| 205 } | 202 } |
| 206 | 203 |
| 207 | 204 |
| 208 bool Object::IsInternalizedString() { | 205 bool Object::IsInternalizedString() const { |
| 209 if (!this->IsHeapObject()) return false; | 206 if (!this->IsHeapObject()) return false; |
| 210 uint32_t type = HeapObject::cast(this)->map()->instance_type(); | 207 uint32_t type = HeapObject::cast(this)->map()->instance_type(); |
| 211 STATIC_ASSERT(kNotInternalizedTag != 0); | 208 STATIC_ASSERT(kNotInternalizedTag != 0); |
| 212 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) == | 209 return (type & (kIsNotStringMask | kIsNotInternalizedMask)) == |
| 213 (kStringTag | kInternalizedTag); | 210 (kStringTag | kInternalizedTag); |
| 214 } | 211 } |
| 215 | 212 |
| 216 | 213 |
| 217 bool Object::IsConsString() { | 214 bool Object::IsConsString() const { |
| 218 if (!IsString()) return false; | 215 if (!IsString()) return false; |
| 219 return StringShape(String::cast(this)).IsCons(); | 216 return StringShape(String::cast(this)).IsCons(); |
| 220 } | 217 } |
| 221 | 218 |
| 222 | 219 |
| 223 bool Object::IsSlicedString() { | 220 bool Object::IsSlicedString() const { |
| 224 if (!IsString()) return false; | 221 if (!IsString()) return false; |
| 225 return StringShape(String::cast(this)).IsSliced(); | 222 return StringShape(String::cast(this)).IsSliced(); |
| 226 } | 223 } |
| 227 | 224 |
| 228 | 225 |
| 229 bool Object::IsSeqString() { | 226 bool Object::IsSeqString() const { |
| 230 if (!IsString()) return false; | 227 if (!IsString()) return false; |
| 231 return StringShape(String::cast(this)).IsSequential(); | 228 return StringShape(String::cast(this)).IsSequential(); |
| 232 } | 229 } |
| 233 | 230 |
| 234 | 231 |
| 235 bool Object::IsSeqOneByteString() { | 232 bool Object::IsSeqOneByteString() const { |
| 236 if (!IsString()) return false; | 233 if (!IsString()) return false; |
| 237 return StringShape(String::cast(this)).IsSequential() && | 234 return StringShape(String::cast(this)).IsSequential() && |
| 238 String::cast(this)->IsOneByteRepresentation(); | 235 String::cast(this)->IsOneByteRepresentation(); |
| 239 } | 236 } |
| 240 | 237 |
| 241 | 238 |
| 242 bool Object::IsSeqTwoByteString() { | 239 bool Object::IsSeqTwoByteString() const { |
| 243 if (!IsString()) return false; | 240 if (!IsString()) return false; |
| 244 return StringShape(String::cast(this)).IsSequential() && | 241 return StringShape(String::cast(this)).IsSequential() && |
| 245 String::cast(this)->IsTwoByteRepresentation(); | 242 String::cast(this)->IsTwoByteRepresentation(); |
| 246 } | 243 } |
| 247 | 244 |
| 248 | 245 |
| 249 bool Object::IsExternalString() { | 246 bool Object::IsExternalString() const { |
| 250 if (!IsString()) return false; | 247 if (!IsString()) return false; |
| 251 return StringShape(String::cast(this)).IsExternal(); | 248 return StringShape(String::cast(this)).IsExternal(); |
| 252 } | 249 } |
| 253 | 250 |
| 254 | 251 |
| 255 bool Object::IsExternalAsciiString() { | 252 bool Object::IsExternalAsciiString() const { |
| 256 if (!IsString()) return false; | 253 if (!IsString()) return false; |
| 257 return StringShape(String::cast(this)).IsExternal() && | 254 return StringShape(String::cast(this)).IsExternal() && |
| 258 String::cast(this)->IsOneByteRepresentation(); | 255 String::cast(this)->IsOneByteRepresentation(); |
| 259 } | 256 } |
| 260 | 257 |
| 261 | 258 |
| 262 bool Object::IsExternalTwoByteString() { | 259 bool Object::IsExternalTwoByteString() const { |
| 263 if (!IsString()) return false; | 260 if (!IsString()) return false; |
| 264 return StringShape(String::cast(this)).IsExternal() && | 261 return StringShape(String::cast(this)).IsExternal() && |
| 265 String::cast(this)->IsTwoByteRepresentation(); | 262 String::cast(this)->IsTwoByteRepresentation(); |
| 266 } | 263 } |
| 267 | 264 |
| 268 | 265 |
| 269 bool Object::HasValidElements() { | 266 bool Object::HasValidElements() { |
| 270 // Dictionary is covered under FixedArray. | 267 // Dictionary is covered under FixedArray. |
| 271 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() || | 268 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray() || |
| 272 IsFixedTypedArrayBase(); | 269 IsFixedTypedArrayBase(); |
| 273 } | 270 } |
| 274 | 271 |
| 275 | 272 |
| 276 Handle<Object> Object::NewStorageFor(Isolate* isolate, | 273 Handle<Object> Object::NewStorageFor(Isolate* isolate, |
| 277 Handle<Object> object, | 274 Handle<Object> object, |
| 278 Representation representation) { | 275 Representation representation) { |
| 279 if (representation.IsSmi() && object->IsUninitialized()) { | 276 if (representation.IsSmi() && object->IsUninitialized()) { |
| 280 return handle(Smi::FromInt(0), isolate); | 277 return handle(Smi::FromInt(0), isolate); |
| 281 } | 278 } |
| 282 if (!representation.IsDouble()) return object; | 279 if (!representation.IsDouble()) return object; |
| 283 if (object->IsUninitialized()) { | 280 if (object->IsUninitialized()) { |
| 284 return isolate->factory()->NewHeapNumber(0); | 281 return isolate->factory()->NewHeapNumber(0); |
| 285 } | 282 } |
| 286 return isolate->factory()->NewHeapNumber(object->Number()); | 283 return isolate->factory()->NewHeapNumber(object->Number()); |
| 287 } | 284 } |
| 288 | 285 |
| 289 | 286 |
| 290 StringShape::StringShape(String* str) | 287 StringShape::StringShape(const String* str) |
| 291 : type_(str->map()->instance_type()) { | 288 : type_(str->map()->instance_type()) { |
| 292 set_valid(); | 289 set_valid(); |
| 293 ASSERT((type_ & kIsNotStringMask) == kStringTag); | 290 ASSERT((type_ & kIsNotStringMask) == kStringTag); |
| 294 } | 291 } |
| 295 | 292 |
| 296 | 293 |
| 297 StringShape::StringShape(Map* map) | 294 StringShape::StringShape(Map* map) |
| 298 : type_(map->instance_type()) { | 295 : type_(map->instance_type()) { |
| 299 set_valid(); | 296 set_valid(); |
| 300 ASSERT((type_ & kIsNotStringMask) == kStringTag); | 297 ASSERT((type_ & kIsNotStringMask) == kStringTag); |
| 301 } | 298 } |
| 302 | 299 |
| 303 | 300 |
| 304 StringShape::StringShape(InstanceType t) | 301 StringShape::StringShape(InstanceType t) |
| 305 : type_(static_cast<uint32_t>(t)) { | 302 : type_(static_cast<uint32_t>(t)) { |
| 306 set_valid(); | 303 set_valid(); |
| 307 ASSERT((type_ & kIsNotStringMask) == kStringTag); | 304 ASSERT((type_ & kIsNotStringMask) == kStringTag); |
| 308 } | 305 } |
| 309 | 306 |
| 310 | 307 |
| 311 bool StringShape::IsInternalized() { | 308 bool StringShape::IsInternalized() { |
| 312 ASSERT(valid()); | 309 ASSERT(valid()); |
| 313 STATIC_ASSERT(kNotInternalizedTag != 0); | 310 STATIC_ASSERT(kNotInternalizedTag != 0); |
| 314 return (type_ & (kIsNotStringMask | kIsNotInternalizedMask)) == | 311 return (type_ & (kIsNotStringMask | kIsNotInternalizedMask)) == |
| 315 (kStringTag | kInternalizedTag); | 312 (kStringTag | kInternalizedTag); |
| 316 } | 313 } |
| 317 | 314 |
| 318 | 315 |
| 319 bool String::IsOneByteRepresentation() { | 316 bool String::IsOneByteRepresentation() const { |
| 320 uint32_t type = map()->instance_type(); | 317 uint32_t type = map()->instance_type(); |
| 321 return (type & kStringEncodingMask) == kOneByteStringTag; | 318 return (type & kStringEncodingMask) == kOneByteStringTag; |
| 322 } | 319 } |
| 323 | 320 |
| 324 | 321 |
| 325 bool String::IsTwoByteRepresentation() { | 322 bool String::IsTwoByteRepresentation() const { |
| 326 uint32_t type = map()->instance_type(); | 323 uint32_t type = map()->instance_type(); |
| 327 return (type & kStringEncodingMask) == kTwoByteStringTag; | 324 return (type & kStringEncodingMask) == kTwoByteStringTag; |
| 328 } | 325 } |
| 329 | 326 |
| 330 | 327 |
| 331 bool String::IsOneByteRepresentationUnderneath() { | 328 bool String::IsOneByteRepresentationUnderneath() { |
| 332 uint32_t type = map()->instance_type(); | 329 uint32_t type = map()->instance_type(); |
| 333 STATIC_ASSERT(kIsIndirectStringTag != 0); | 330 STATIC_ASSERT(kIsIndirectStringTag != 0); |
| 334 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0); | 331 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0); |
| 335 ASSERT(IsFlat()); | 332 ASSERT(IsFlat()); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 string_, chars_, hash_field_); | 602 string_, chars_, hash_field_); |
| 606 } | 603 } |
| 607 | 604 |
| 608 Vector<const char> string_; | 605 Vector<const char> string_; |
| 609 uint32_t hash_field_; | 606 uint32_t hash_field_; |
| 610 int chars_; // Caches the number of characters when computing the hash code. | 607 int chars_; // Caches the number of characters when computing the hash code. |
| 611 uint32_t seed_; | 608 uint32_t seed_; |
| 612 }; | 609 }; |
| 613 | 610 |
| 614 | 611 |
| 615 bool Object::IsNumber() { | 612 bool Object::IsNumber() const { |
| 616 return IsSmi() || IsHeapNumber(); | 613 return IsSmi() || IsHeapNumber(); |
| 617 } | 614 } |
| 618 | 615 |
| 619 | 616 |
| 620 TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE) | 617 TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE) |
| 621 TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE) | 618 TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE) |
| 622 | 619 |
| 623 | 620 |
| 624 bool Object::IsFiller() { | 621 bool Object::IsFiller() const { |
| 625 if (!Object::IsHeapObject()) return false; | 622 if (!Object::IsHeapObject()) return false; |
| 626 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type(); | 623 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type(); |
| 627 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE; | 624 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE; |
| 628 } | 625 } |
| 629 | 626 |
| 630 | 627 |
| 631 bool Object::IsExternalArray() { | 628 bool Object::IsExternalArray() const { |
| 632 if (!Object::IsHeapObject()) | 629 if (!Object::IsHeapObject()) |
| 633 return false; | 630 return false; |
| 634 InstanceType instance_type = | 631 InstanceType instance_type = |
| 635 HeapObject::cast(this)->map()->instance_type(); | 632 HeapObject::cast(this)->map()->instance_type(); |
| 636 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE && | 633 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE && |
| 637 instance_type <= LAST_EXTERNAL_ARRAY_TYPE); | 634 instance_type <= LAST_EXTERNAL_ARRAY_TYPE); |
| 638 } | 635 } |
| 639 | 636 |
| 640 | 637 |
| 641 #define TYPED_ARRAY_TYPE_CHECKER(Type, type, TYPE, ctype, size) \ | 638 #define TYPED_ARRAY_TYPE_CHECKER(Type, type, TYPE, ctype, size) \ |
| 642 TYPE_CHECKER(External##Type##Array, EXTERNAL_##TYPE##_ARRAY_TYPE) \ | 639 TYPE_CHECKER(External##Type##Array, EXTERNAL_##TYPE##_ARRAY_TYPE) \ |
| 643 TYPE_CHECKER(Fixed##Type##Array, FIXED_##TYPE##_ARRAY_TYPE) | 640 TYPE_CHECKER(Fixed##Type##Array, FIXED_##TYPE##_ARRAY_TYPE) |
| 644 | 641 |
| 645 TYPED_ARRAYS(TYPED_ARRAY_TYPE_CHECKER) | 642 TYPED_ARRAYS(TYPED_ARRAY_TYPE_CHECKER) |
| 646 #undef TYPED_ARRAY_TYPE_CHECKER | 643 #undef TYPED_ARRAY_TYPE_CHECKER |
| 647 | 644 |
| 648 | 645 |
| 649 bool Object::IsFixedTypedArrayBase() { | 646 bool Object::IsFixedTypedArrayBase() const { |
| 650 if (!Object::IsHeapObject()) return false; | 647 if (!Object::IsHeapObject()) return false; |
| 651 | 648 |
| 652 InstanceType instance_type = | 649 InstanceType instance_type = |
| 653 HeapObject::cast(this)->map()->instance_type(); | 650 HeapObject::cast(this)->map()->instance_type(); |
| 654 return (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE && | 651 return (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE && |
| 655 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE); | 652 instance_type <= LAST_FIXED_TYPED_ARRAY_TYPE); |
| 656 } | 653 } |
| 657 | 654 |
| 658 | 655 |
| 659 bool Object::IsJSReceiver() { | 656 bool Object::IsJSReceiver() const { |
| 660 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); | 657 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 661 return IsHeapObject() && | 658 return IsHeapObject() && |
| 662 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE; | 659 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE; |
| 663 } | 660 } |
| 664 | 661 |
| 665 | 662 |
| 666 bool Object::IsJSObject() { | 663 bool Object::IsJSObject() const { |
| 667 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); | 664 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE); |
| 668 return IsHeapObject() && | 665 return IsHeapObject() && |
| 669 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE; | 666 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE; |
| 670 } | 667 } |
| 671 | 668 |
| 672 | 669 |
| 673 bool Object::IsJSProxy() { | 670 bool Object::IsJSProxy() const { |
| 674 if (!Object::IsHeapObject()) return false; | 671 if (!Object::IsHeapObject()) return false; |
| 675 return HeapObject::cast(this)->map()->IsJSProxyMap(); | 672 return HeapObject::cast(this)->map()->IsJSProxyMap(); |
| 676 } | 673 } |
| 677 | 674 |
| 678 | 675 |
| 679 TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE) | 676 TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE) |
| 680 TYPE_CHECKER(JSSet, JS_SET_TYPE) | 677 TYPE_CHECKER(JSSet, JS_SET_TYPE) |
| 681 TYPE_CHECKER(JSMap, JS_MAP_TYPE) | 678 TYPE_CHECKER(JSMap, JS_MAP_TYPE) |
| 682 TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE) | 679 TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE) |
| 683 TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE) | 680 TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE) |
| 684 TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE) | 681 TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE) |
| 685 TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE) | 682 TYPE_CHECKER(JSWeakSet, JS_WEAK_SET_TYPE) |
| 686 TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE) | 683 TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE) |
| 687 TYPE_CHECKER(Map, MAP_TYPE) | 684 TYPE_CHECKER(Map, MAP_TYPE) |
| 688 TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE) | 685 TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE) |
| 689 TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE) | 686 TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE) |
| 690 TYPE_CHECKER(ConstantPoolArray, CONSTANT_POOL_ARRAY_TYPE) | 687 TYPE_CHECKER(ConstantPoolArray, CONSTANT_POOL_ARRAY_TYPE) |
| 691 | 688 |
| 692 | 689 |
| 693 bool Object::IsJSWeakCollection() { | 690 bool Object::IsJSWeakCollection() const { |
| 694 return IsJSWeakMap() || IsJSWeakSet(); | 691 return IsJSWeakMap() || IsJSWeakSet(); |
| 695 } | 692 } |
| 696 | 693 |
| 697 | 694 |
| 698 bool Object::IsDescriptorArray() { | 695 bool Object::IsDescriptorArray() const { |
| 699 return IsFixedArray(); | 696 return IsFixedArray(); |
| 700 } | 697 } |
| 701 | 698 |
| 702 | 699 |
| 703 bool Object::IsTransitionArray() { | 700 bool Object::IsTransitionArray() const { |
| 704 return IsFixedArray(); | 701 return IsFixedArray(); |
| 705 } | 702 } |
| 706 | 703 |
| 707 | 704 |
| 708 bool Object::IsDeoptimizationInputData() { | 705 bool Object::IsDeoptimizationInputData() const { |
| 709 // Must be a fixed array. | 706 // Must be a fixed array. |
| 710 if (!IsFixedArray()) return false; | 707 if (!IsFixedArray()) return false; |
| 711 | 708 |
| 712 // There's no sure way to detect the difference between a fixed array and | 709 // There's no sure way to detect the difference between a fixed array and |
| 713 // a deoptimization data array. Since this is used for asserts we can | 710 // a deoptimization data array. Since this is used for asserts we can |
| 714 // check that the length is zero or else the fixed size plus a multiple of | 711 // check that the length is zero or else the fixed size plus a multiple of |
| 715 // the entry size. | 712 // the entry size. |
| 716 int length = FixedArray::cast(this)->length(); | 713 int length = FixedArray::cast(this)->length(); |
| 717 if (length == 0) return true; | 714 if (length == 0) return true; |
| 718 | 715 |
| 719 length -= DeoptimizationInputData::kFirstDeoptEntryIndex; | 716 length -= DeoptimizationInputData::kFirstDeoptEntryIndex; |
| 720 return length >= 0 && | 717 return length >= 0 && |
| 721 length % DeoptimizationInputData::kDeoptEntrySize == 0; | 718 length % DeoptimizationInputData::kDeoptEntrySize == 0; |
| 722 } | 719 } |
| 723 | 720 |
| 724 | 721 |
| 725 bool Object::IsDeoptimizationOutputData() { | 722 bool Object::IsDeoptimizationOutputData() const { |
| 726 if (!IsFixedArray()) return false; | 723 if (!IsFixedArray()) return false; |
| 727 // There's actually no way to see the difference between a fixed array and | 724 // There's actually no way to see the difference between a fixed array and |
| 728 // a deoptimization data array. Since this is used for asserts we can check | 725 // a deoptimization data array. Since this is used for asserts we can check |
| 729 // that the length is plausible though. | 726 // that the length is plausible though. |
| 730 if (FixedArray::cast(this)->length() % 2 != 0) return false; | 727 if (FixedArray::cast(this)->length() % 2 != 0) return false; |
| 731 return true; | 728 return true; |
| 732 } | 729 } |
| 733 | 730 |
| 734 | 731 |
| 735 bool Object::IsDependentCode() { | 732 bool Object::IsDependentCode() const { |
| 736 if (!IsFixedArray()) return false; | 733 if (!IsFixedArray()) return false; |
| 737 // There's actually no way to see the difference between a fixed array and | 734 // There's actually no way to see the difference between a fixed array and |
| 738 // a dependent codes array. | 735 // a dependent codes array. |
| 739 return true; | 736 return true; |
| 740 } | 737 } |
| 741 | 738 |
| 742 | 739 |
| 743 bool Object::IsContext() { | 740 bool Object::IsContext() const { |
| 744 if (!Object::IsHeapObject()) return false; | 741 if (!Object::IsHeapObject()) return false; |
| 745 Map* map = HeapObject::cast(this)->map(); | 742 Map* map = HeapObject::cast(this)->map(); |
| 746 Heap* heap = map->GetHeap(); | 743 Heap* heap = map->GetHeap(); |
| 747 return (map == heap->function_context_map() || | 744 return (map == heap->function_context_map() || |
| 748 map == heap->catch_context_map() || | 745 map == heap->catch_context_map() || |
| 749 map == heap->with_context_map() || | 746 map == heap->with_context_map() || |
| 750 map == heap->native_context_map() || | 747 map == heap->native_context_map() || |
| 751 map == heap->block_context_map() || | 748 map == heap->block_context_map() || |
| 752 map == heap->module_context_map() || | 749 map == heap->module_context_map() || |
| 753 map == heap->global_context_map()); | 750 map == heap->global_context_map()); |
| 754 } | 751 } |
| 755 | 752 |
| 756 | 753 |
| 757 bool Object::IsNativeContext() { | 754 bool Object::IsNativeContext() const { |
| 758 return Object::IsHeapObject() && | 755 return Object::IsHeapObject() && |
| 759 HeapObject::cast(this)->map() == | 756 HeapObject::cast(this)->map() == |
| 760 HeapObject::cast(this)->GetHeap()->native_context_map(); | 757 HeapObject::cast(this)->GetHeap()->native_context_map(); |
| 761 } | 758 } |
| 762 | 759 |
| 763 | 760 |
| 764 bool Object::IsScopeInfo() { | 761 bool Object::IsScopeInfo() const { |
| 765 return Object::IsHeapObject() && | 762 return Object::IsHeapObject() && |
| 766 HeapObject::cast(this)->map() == | 763 HeapObject::cast(this)->map() == |
| 767 HeapObject::cast(this)->GetHeap()->scope_info_map(); | 764 HeapObject::cast(this)->GetHeap()->scope_info_map(); |
| 768 } | 765 } |
| 769 | 766 |
| 770 | 767 |
| 771 TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE) | 768 TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE) |
| 772 | 769 |
| 773 | 770 |
| 774 template <> inline bool Is<JSFunction>(Object* obj) { | 771 template <> inline bool Is<JSFunction>(Object* obj) { |
| 775 return obj->IsJSFunction(); | 772 return obj->IsJSFunction(); |
| 776 } | 773 } |
| 777 | 774 |
| 778 | 775 |
| 779 TYPE_CHECKER(Code, CODE_TYPE) | 776 TYPE_CHECKER(Code, CODE_TYPE) |
| 780 TYPE_CHECKER(Oddball, ODDBALL_TYPE) | 777 TYPE_CHECKER(Oddball, ODDBALL_TYPE) |
| 781 TYPE_CHECKER(Cell, CELL_TYPE) | 778 TYPE_CHECKER(Cell, CELL_TYPE) |
| 782 TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE) | 779 TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE) |
| 783 TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE) | 780 TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE) |
| 784 TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE) | 781 TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE) |
| 785 TYPE_CHECKER(JSModule, JS_MODULE_TYPE) | 782 TYPE_CHECKER(JSModule, JS_MODULE_TYPE) |
| 786 TYPE_CHECKER(JSValue, JS_VALUE_TYPE) | 783 TYPE_CHECKER(JSValue, JS_VALUE_TYPE) |
| 787 TYPE_CHECKER(JSDate, JS_DATE_TYPE) | 784 TYPE_CHECKER(JSDate, JS_DATE_TYPE) |
| 788 TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE) | 785 TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE) |
| 789 | 786 |
| 790 | 787 |
| 791 bool Object::IsStringWrapper() { | 788 bool Object::IsStringWrapper() const { |
| 792 return IsJSValue() && JSValue::cast(this)->value()->IsString(); | 789 return IsJSValue() && JSValue::cast(this)->value()->IsString(); |
| 793 } | 790 } |
| 794 | 791 |
| 795 | 792 |
| 796 TYPE_CHECKER(Foreign, FOREIGN_TYPE) | 793 TYPE_CHECKER(Foreign, FOREIGN_TYPE) |
| 797 | 794 |
| 798 | 795 |
| 799 bool Object::IsBoolean() { | 796 bool Object::IsBoolean() const { |
| 800 return IsOddball() && | 797 return IsOddball() && |
| 801 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0); | 798 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0); |
| 802 } | 799 } |
| 803 | 800 |
| 804 | 801 |
| 805 TYPE_CHECKER(JSArray, JS_ARRAY_TYPE) | 802 TYPE_CHECKER(JSArray, JS_ARRAY_TYPE) |
| 806 TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE) | 803 TYPE_CHECKER(JSArrayBuffer, JS_ARRAY_BUFFER_TYPE) |
| 807 TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE) | 804 TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE) |
| 808 TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE) | 805 TYPE_CHECKER(JSDataView, JS_DATA_VIEW_TYPE) |
| 809 | 806 |
| 810 | 807 |
| 811 bool Object::IsJSArrayBufferView() { | 808 bool Object::IsJSArrayBufferView() const { |
| 812 return IsJSDataView() || IsJSTypedArray(); | 809 return IsJSDataView() || IsJSTypedArray(); |
| 813 } | 810 } |
| 814 | 811 |
| 815 | 812 |
| 816 TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE) | 813 TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE) |
| 817 | 814 |
| 818 | 815 |
| 819 template <> inline bool Is<JSArray>(Object* obj) { | 816 template <> inline bool Is<JSArray>(Object* obj) { |
| 820 return obj->IsJSArray(); | 817 return obj->IsJSArray(); |
| 821 } | 818 } |
| 822 | 819 |
| 823 | 820 |
| 824 bool Object::IsHashTable() { | 821 bool Object::IsHashTable() const { |
| 825 return Object::IsHeapObject() && | 822 return Object::IsHeapObject() && |
| 826 HeapObject::cast(this)->map() == | 823 HeapObject::cast(this)->map() == |
| 827 HeapObject::cast(this)->GetHeap()->hash_table_map(); | 824 HeapObject::cast(this)->GetHeap()->hash_table_map(); |
| 828 } | 825 } |
| 829 | 826 |
| 830 | 827 |
| 831 bool Object::IsWeakHashTable() { | 828 bool Object::IsWeakHashTable() const { |
| 832 return IsHashTable(); | 829 return IsHashTable(); |
| 833 } | 830 } |
| 834 | 831 |
| 835 | 832 |
| 836 bool Object::IsDictionary() { | 833 bool Object::IsDictionary() const { |
| 837 return IsHashTable() && | 834 return IsHashTable() && |
| 838 this != HeapObject::cast(this)->GetHeap()->string_table(); | 835 this != HeapObject::cast(this)->GetHeap()->string_table(); |
| 839 } | 836 } |
| 840 | 837 |
| 841 | 838 |
| 842 bool Object::IsNameDictionary() { | 839 bool Object::IsNameDictionary() const { |
| 843 return IsDictionary(); | 840 return IsDictionary(); |
| 844 } | 841 } |
| 845 | 842 |
| 846 | 843 |
| 847 bool Object::IsSeededNumberDictionary() { | 844 bool Object::IsSeededNumberDictionary() const { |
| 848 return IsDictionary(); | 845 return IsDictionary(); |
| 849 } | 846 } |
| 850 | 847 |
| 851 | 848 |
| 852 bool Object::IsUnseededNumberDictionary() { | 849 bool Object::IsUnseededNumberDictionary() const { |
| 853 return IsDictionary(); | 850 return IsDictionary(); |
| 854 } | 851 } |
| 855 | 852 |
| 856 | 853 |
| 857 bool Object::IsStringTable() { | 854 bool Object::IsStringTable() const { |
| 858 return IsHashTable(); | 855 return IsHashTable(); |
| 859 } | 856 } |
| 860 | 857 |
| 861 | 858 |
| 862 bool Object::IsJSFunctionResultCache() { | 859 bool Object::IsJSFunctionResultCache() const { |
| 863 if (!IsFixedArray()) return false; | 860 if (!IsFixedArray()) return false; |
| 864 FixedArray* self = FixedArray::cast(this); | 861 const FixedArray* self = FixedArray::cast(this); |
| 865 int length = self->length(); | 862 int length = self->length(); |
| 866 if (length < JSFunctionResultCache::kEntriesIndex) return false; | 863 if (length < JSFunctionResultCache::kEntriesIndex) return false; |
| 867 if ((length - JSFunctionResultCache::kEntriesIndex) | 864 if ((length - JSFunctionResultCache::kEntriesIndex) |
| 868 % JSFunctionResultCache::kEntrySize != 0) { | 865 % JSFunctionResultCache::kEntrySize != 0) { |
| 869 return false; | 866 return false; |
| 870 } | 867 } |
| 871 #ifdef VERIFY_HEAP | 868 #ifdef VERIFY_HEAP |
| 872 if (FLAG_verify_heap) { | 869 if (FLAG_verify_heap) { |
| 873 reinterpret_cast<JSFunctionResultCache*>(this)-> | 870 // TODO(svenpanne) We use const_cast here and below to break our dependency |
| 871 // cycle between the predicates and the verifiers. This can be removed when |
| 872 // the verifiers are const-correct, too. |
| 873 reinterpret_cast<JSFunctionResultCache*>(const_cast<Object*>(this))-> |
| 874 JSFunctionResultCacheVerify(); | 874 JSFunctionResultCacheVerify(); |
| 875 } | 875 } |
| 876 #endif | 876 #endif |
| 877 return true; | 877 return true; |
| 878 } | 878 } |
| 879 | 879 |
| 880 | 880 |
| 881 bool Object::IsNormalizedMapCache() { | 881 bool Object::IsNormalizedMapCache() const { |
| 882 return NormalizedMapCache::IsNormalizedMapCache(this); | 882 return NormalizedMapCache::IsNormalizedMapCache(this); |
| 883 } | 883 } |
| 884 | 884 |
| 885 | 885 |
| 886 int NormalizedMapCache::GetIndex(Handle<Map> map) { | 886 int NormalizedMapCache::GetIndex(Handle<Map> map) { |
| 887 return map->Hash() % NormalizedMapCache::kEntries; | 887 return map->Hash() % NormalizedMapCache::kEntries; |
| 888 } | 888 } |
| 889 | 889 |
| 890 | 890 |
| 891 bool NormalizedMapCache::IsNormalizedMapCache(Object* obj) { | 891 bool NormalizedMapCache::IsNormalizedMapCache(const Object* obj) { |
| 892 if (!obj->IsFixedArray()) return false; | 892 if (!obj->IsFixedArray()) return false; |
| 893 if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) { | 893 if (FixedArray::cast(obj)->length() != NormalizedMapCache::kEntries) { |
| 894 return false; | 894 return false; |
| 895 } | 895 } |
| 896 #ifdef VERIFY_HEAP | 896 #ifdef VERIFY_HEAP |
| 897 if (FLAG_verify_heap) { | 897 if (FLAG_verify_heap) { |
| 898 reinterpret_cast<NormalizedMapCache*>(obj)->NormalizedMapCacheVerify(); | 898 reinterpret_cast<NormalizedMapCache*>(const_cast<Object*>(obj))-> |
| 899 NormalizedMapCacheVerify(); |
| 899 } | 900 } |
| 900 #endif | 901 #endif |
| 901 return true; | 902 return true; |
| 902 } | 903 } |
| 903 | 904 |
| 904 | 905 |
| 905 bool Object::IsCompilationCacheTable() { | 906 bool Object::IsCompilationCacheTable() const { |
| 906 return IsHashTable(); | 907 return IsHashTable(); |
| 907 } | 908 } |
| 908 | 909 |
| 909 | 910 |
| 910 bool Object::IsCodeCacheHashTable() { | 911 bool Object::IsCodeCacheHashTable() const { |
| 911 return IsHashTable(); | 912 return IsHashTable(); |
| 912 } | 913 } |
| 913 | 914 |
| 914 | 915 |
| 915 bool Object::IsPolymorphicCodeCacheHashTable() { | 916 bool Object::IsPolymorphicCodeCacheHashTable() const { |
| 916 return IsHashTable(); | 917 return IsHashTable(); |
| 917 } | 918 } |
| 918 | 919 |
| 919 | 920 |
| 920 bool Object::IsMapCache() { | 921 bool Object::IsMapCache() const { |
| 921 return IsHashTable(); | 922 return IsHashTable(); |
| 922 } | 923 } |
| 923 | 924 |
| 924 | 925 |
| 925 bool Object::IsObjectHashTable() { | 926 bool Object::IsObjectHashTable() const { |
| 926 return IsHashTable(); | 927 return IsHashTable(); |
| 927 } | 928 } |
| 928 | 929 |
| 929 | 930 |
| 930 bool Object::IsOrderedHashTable() { | 931 bool Object::IsOrderedHashTable() const { |
| 931 return IsHeapObject() && | 932 return IsHeapObject() && |
| 932 HeapObject::cast(this)->map() == | 933 HeapObject::cast(this)->map() == |
| 933 HeapObject::cast(this)->GetHeap()->ordered_hash_table_map(); | 934 HeapObject::cast(this)->GetHeap()->ordered_hash_table_map(); |
| 934 } | 935 } |
| 935 | 936 |
| 936 | 937 |
| 937 bool Object::IsOrderedHashSet() { | 938 bool Object::IsOrderedHashSet() const { |
| 938 return IsOrderedHashTable(); | 939 return IsOrderedHashTable(); |
| 939 } | 940 } |
| 940 | 941 |
| 941 | 942 |
| 942 bool Object::IsOrderedHashMap() { | 943 bool Object::IsOrderedHashMap() const { |
| 943 return IsOrderedHashTable(); | 944 return IsOrderedHashTable(); |
| 944 } | 945 } |
| 945 | 946 |
| 946 | 947 |
| 947 bool Object::IsPrimitive() { | 948 bool Object::IsPrimitive() const { |
| 948 return IsOddball() || IsNumber() || IsString(); | 949 return IsOddball() || IsNumber() || IsString(); |
| 949 } | 950 } |
| 950 | 951 |
| 951 | 952 |
| 952 bool Object::IsJSGlobalProxy() { | 953 bool Object::IsJSGlobalProxy() const { |
| 953 bool result = IsHeapObject() && | 954 bool result = IsHeapObject() && |
| 954 (HeapObject::cast(this)->map()->instance_type() == | 955 (HeapObject::cast(this)->map()->instance_type() == |
| 955 JS_GLOBAL_PROXY_TYPE); | 956 JS_GLOBAL_PROXY_TYPE); |
| 956 ASSERT(!result || | 957 ASSERT(!result || |
| 957 HeapObject::cast(this)->map()->is_access_check_needed()); | 958 HeapObject::cast(this)->map()->is_access_check_needed()); |
| 958 return result; | 959 return result; |
| 959 } | 960 } |
| 960 | 961 |
| 961 | 962 |
| 962 bool Object::IsGlobalObject() { | 963 bool Object::IsGlobalObject() const { |
| 963 if (!IsHeapObject()) return false; | 964 if (!IsHeapObject()) return false; |
| 964 | 965 |
| 965 InstanceType type = HeapObject::cast(this)->map()->instance_type(); | 966 InstanceType type = HeapObject::cast(this)->map()->instance_type(); |
| 966 return type == JS_GLOBAL_OBJECT_TYPE || | 967 return type == JS_GLOBAL_OBJECT_TYPE || |
| 967 type == JS_BUILTINS_OBJECT_TYPE; | 968 type == JS_BUILTINS_OBJECT_TYPE; |
| 968 } | 969 } |
| 969 | 970 |
| 970 | 971 |
| 971 TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE) | 972 TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE) |
| 972 TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE) | 973 TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE) |
| 973 | 974 |
| 974 | 975 |
| 975 bool Object::IsUndetectableObject() { | 976 bool Object::IsUndetectableObject() const { |
| 976 return IsHeapObject() | 977 return IsHeapObject() |
| 977 && HeapObject::cast(this)->map()->is_undetectable(); | 978 && HeapObject::cast(this)->map()->is_undetectable(); |
| 978 } | 979 } |
| 979 | 980 |
| 980 | 981 |
| 981 bool Object::IsAccessCheckNeeded() { | 982 bool Object::IsAccessCheckNeeded() const { |
| 982 if (!IsHeapObject()) return false; | 983 if (!IsHeapObject()) return false; |
| 983 if (IsJSGlobalProxy()) { | 984 if (IsJSGlobalProxy()) { |
| 984 JSGlobalProxy* proxy = JSGlobalProxy::cast(this); | 985 const JSGlobalProxy* proxy = JSGlobalProxy::cast(this); |
| 985 GlobalObject* global = | 986 GlobalObject* global = proxy->GetIsolate()->context()->global_object(); |
| 986 proxy->GetIsolate()->context()->global_object(); | |
| 987 return proxy->IsDetachedFrom(global); | 987 return proxy->IsDetachedFrom(global); |
| 988 } | 988 } |
| 989 return HeapObject::cast(this)->map()->is_access_check_needed(); | 989 return HeapObject::cast(this)->map()->is_access_check_needed(); |
| 990 } | 990 } |
| 991 | 991 |
| 992 | 992 |
| 993 bool Object::IsStruct() { | 993 bool Object::IsStruct() const { |
| 994 if (!IsHeapObject()) return false; | 994 if (!IsHeapObject()) return false; |
| 995 switch (HeapObject::cast(this)->map()->instance_type()) { | 995 switch (HeapObject::cast(this)->map()->instance_type()) { |
| 996 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true; | 996 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true; |
| 997 STRUCT_LIST(MAKE_STRUCT_CASE) | 997 STRUCT_LIST(MAKE_STRUCT_CASE) |
| 998 #undef MAKE_STRUCT_CASE | 998 #undef MAKE_STRUCT_CASE |
| 999 default: return false; | 999 default: return false; |
| 1000 } | 1000 } |
| 1001 } | 1001 } |
| 1002 | 1002 |
| 1003 | 1003 |
| 1004 #define MAKE_STRUCT_PREDICATE(NAME, Name, name) \ | 1004 #define MAKE_STRUCT_PREDICATE(NAME, Name, name) \ |
| 1005 bool Object::Is##Name() { \ | 1005 bool Object::Is##Name() const { \ |
| 1006 return Object::IsHeapObject() \ | 1006 return Object::IsHeapObject() \ |
| 1007 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \ | 1007 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \ |
| 1008 } | 1008 } |
| 1009 STRUCT_LIST(MAKE_STRUCT_PREDICATE) | 1009 STRUCT_LIST(MAKE_STRUCT_PREDICATE) |
| 1010 #undef MAKE_STRUCT_PREDICATE | 1010 #undef MAKE_STRUCT_PREDICATE |
| 1011 | 1011 |
| 1012 | 1012 |
| 1013 bool Object::IsUndefined() { | 1013 bool Object::IsUndefined() const { |
| 1014 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined; | 1014 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined; |
| 1015 } | 1015 } |
| 1016 | 1016 |
| 1017 | 1017 |
| 1018 bool Object::IsNull() { | 1018 bool Object::IsNull() const { |
| 1019 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull; | 1019 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull; |
| 1020 } | 1020 } |
| 1021 | 1021 |
| 1022 | 1022 |
| 1023 bool Object::IsTheHole() { | 1023 bool Object::IsTheHole() const { |
| 1024 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole; | 1024 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole; |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 | 1027 |
| 1028 bool Object::IsException() { | 1028 bool Object::IsException() const { |
| 1029 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kException; | 1029 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kException; |
| 1030 } | 1030 } |
| 1031 | 1031 |
| 1032 | 1032 |
| 1033 bool Object::IsUninitialized() { | 1033 bool Object::IsUninitialized() const { |
| 1034 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized; | 1034 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUninitialized; |
| 1035 } | 1035 } |
| 1036 | 1036 |
| 1037 | 1037 |
| 1038 bool Object::IsTrue() { | 1038 bool Object::IsTrue() const { |
| 1039 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue; | 1039 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue; |
| 1040 } | 1040 } |
| 1041 | 1041 |
| 1042 | 1042 |
| 1043 bool Object::IsFalse() { | 1043 bool Object::IsFalse() const { |
| 1044 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse; | 1044 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse; |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 | 1047 |
| 1048 bool Object::IsArgumentsMarker() { | 1048 bool Object::IsArgumentsMarker() const { |
| 1049 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker; | 1049 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker; |
| 1050 } | 1050 } |
| 1051 | 1051 |
| 1052 | 1052 |
| 1053 double Object::Number() { | 1053 double Object::Number() { |
| 1054 ASSERT(IsNumber()); | 1054 ASSERT(IsNumber()); |
| 1055 return IsSmi() | 1055 return IsSmi() |
| 1056 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value()) | 1056 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value()) |
| 1057 : reinterpret_cast<HeapNumber*>(this)->value(); | 1057 : reinterpret_cast<HeapNumber*>(this)->value(); |
| 1058 } | 1058 } |
| 1059 | 1059 |
| 1060 | 1060 |
| 1061 bool Object::IsNaN() { | 1061 bool Object::IsNaN() const { |
| 1062 return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value()); | 1062 return this->IsHeapNumber() && std::isnan(HeapNumber::cast(this)->value()); |
| 1063 } | 1063 } |
| 1064 | 1064 |
| 1065 | 1065 |
| 1066 MaybeHandle<Smi> Object::ToSmi(Isolate* isolate, Handle<Object> object) { | 1066 MaybeHandle<Smi> Object::ToSmi(Isolate* isolate, Handle<Object> object) { |
| 1067 if (object->IsSmi()) return Handle<Smi>::cast(object); | 1067 if (object->IsSmi()) return Handle<Smi>::cast(object); |
| 1068 if (object->IsHeapNumber()) { | 1068 if (object->IsHeapNumber()) { |
| 1069 double value = Handle<HeapNumber>::cast(object)->value(); | 1069 double value = Handle<HeapNumber>::cast(object)->value(); |
| 1070 int int_value = FastD2I(value); | 1070 int int_value = FastD2I(value); |
| 1071 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { | 1071 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) { |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1362 | 1362 |
| 1363 | 1363 |
| 1364 Heap* HeapObject::GetHeap() const { | 1364 Heap* HeapObject::GetHeap() const { |
| 1365 Heap* heap = | 1365 Heap* heap = |
| 1366 MemoryChunk::FromAddress(reinterpret_cast<const byte*>(this))->heap(); | 1366 MemoryChunk::FromAddress(reinterpret_cast<const byte*>(this))->heap(); |
| 1367 SLOW_ASSERT(heap != NULL); | 1367 SLOW_ASSERT(heap != NULL); |
| 1368 return heap; | 1368 return heap; |
| 1369 } | 1369 } |
| 1370 | 1370 |
| 1371 | 1371 |
| 1372 Isolate* HeapObject::GetIsolate() { | 1372 Isolate* HeapObject::GetIsolate() const { |
| 1373 return GetHeap()->isolate(); | 1373 return GetHeap()->isolate(); |
| 1374 } | 1374 } |
| 1375 | 1375 |
| 1376 | 1376 |
| 1377 Map* HeapObject::map() const { | 1377 Map* HeapObject::map() const { |
| 1378 #ifdef DEBUG | 1378 #ifdef DEBUG |
| 1379 // Clear mark potentially added by PathTracer. | 1379 // Clear mark potentially added by PathTracer. |
| 1380 uintptr_t raw_value = | 1380 uintptr_t raw_value = |
| 1381 map_word().ToRawValue() & ~static_cast<uintptr_t>(PathTracer::kMarkTag); | 1381 map_word().ToRawValue() & ~static_cast<uintptr_t>(PathTracer::kMarkTag); |
| 1382 return MapWord::FromRawValue(raw_value).ToMap(); | 1382 return MapWord::FromRawValue(raw_value).ToMap(); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 void HeapObject::IteratePointer(ObjectVisitor* v, int offset) { | 1471 void HeapObject::IteratePointer(ObjectVisitor* v, int offset) { |
| 1472 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset))); | 1472 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset))); |
| 1473 } | 1473 } |
| 1474 | 1474 |
| 1475 | 1475 |
| 1476 void HeapObject::IterateNextCodeLink(ObjectVisitor* v, int offset) { | 1476 void HeapObject::IterateNextCodeLink(ObjectVisitor* v, int offset) { |
| 1477 v->VisitNextCodeLink(reinterpret_cast<Object**>(FIELD_ADDR(this, offset))); | 1477 v->VisitNextCodeLink(reinterpret_cast<Object**>(FIELD_ADDR(this, offset))); |
| 1478 } | 1478 } |
| 1479 | 1479 |
| 1480 | 1480 |
| 1481 double HeapNumber::value() { | 1481 double HeapNumber::value() const { |
| 1482 return READ_DOUBLE_FIELD(this, kValueOffset); | 1482 return READ_DOUBLE_FIELD(this, kValueOffset); |
| 1483 } | 1483 } |
| 1484 | 1484 |
| 1485 | 1485 |
| 1486 void HeapNumber::set_value(double value) { | 1486 void HeapNumber::set_value(double value) { |
| 1487 WRITE_DOUBLE_FIELD(this, kValueOffset, value); | 1487 WRITE_DOUBLE_FIELD(this, kValueOffset, value); |
| 1488 } | 1488 } |
| 1489 | 1489 |
| 1490 | 1490 |
| 1491 int HeapNumber::get_exponent() { | 1491 int HeapNumber::get_exponent() { |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1842 if (target_details.type() != FIELD) return Handle<Map>::null(); | 1842 if (target_details.type() != FIELD) return Handle<Map>::null(); |
| 1843 if (target_details.attributes() != NONE) return Handle<Map>::null(); | 1843 if (target_details.attributes() != NONE) return Handle<Map>::null(); |
| 1844 return Handle<Map>(transitions->GetTarget(transition)); | 1844 return Handle<Map>(transitions->GetTarget(transition)); |
| 1845 } | 1845 } |
| 1846 | 1846 |
| 1847 | 1847 |
| 1848 ACCESSORS(Oddball, to_string, String, kToStringOffset) | 1848 ACCESSORS(Oddball, to_string, String, kToStringOffset) |
| 1849 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) | 1849 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) |
| 1850 | 1850 |
| 1851 | 1851 |
| 1852 byte Oddball::kind() { | 1852 byte Oddball::kind() const { |
| 1853 return Smi::cast(READ_FIELD(this, kKindOffset))->value(); | 1853 return Smi::cast(READ_FIELD(this, kKindOffset))->value(); |
| 1854 } | 1854 } |
| 1855 | 1855 |
| 1856 | 1856 |
| 1857 void Oddball::set_kind(byte value) { | 1857 void Oddball::set_kind(byte value) { |
| 1858 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value)); | 1858 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value)); |
| 1859 } | 1859 } |
| 1860 | 1860 |
| 1861 | 1861 |
| 1862 Object* Cell::value() const { | 1862 Object* Cell::value() const { |
| (...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3140 SLOW_ASSERT(object->IsHeapObject() && | 3140 SLOW_ASSERT(object->IsHeapObject() && |
| 3141 HeapObject::cast(object)->map()->instance_type() == | 3141 HeapObject::cast(object)->map()->instance_type() == |
| 3142 Traits::kInstanceType); | 3142 Traits::kInstanceType); |
| 3143 return reinterpret_cast<FixedTypedArray<Traits>*>(object); | 3143 return reinterpret_cast<FixedTypedArray<Traits>*>(object); |
| 3144 } | 3144 } |
| 3145 | 3145 |
| 3146 | 3146 |
| 3147 template <class Traits> | 3147 template <class Traits> |
| 3148 const FixedTypedArray<Traits>* | 3148 const FixedTypedArray<Traits>* |
| 3149 FixedTypedArray<Traits>::cast(const Object* object) { | 3149 FixedTypedArray<Traits>::cast(const Object* object) { |
| 3150 SLOW_ASSERT(const_cast<Object*>(object)->IsHeapObject() && | 3150 SLOW_ASSERT(object->IsHeapObject() && |
| 3151 HeapObject::cast(object)->map()->instance_type() == | 3151 HeapObject::cast(object)->map()->instance_type() == |
| 3152 Traits::kInstanceType); | 3152 Traits::kInstanceType); |
| 3153 return reinterpret_cast<FixedTypedArray<Traits>*>(object); | 3153 return reinterpret_cast<FixedTypedArray<Traits>*>(object); |
| 3154 } | 3154 } |
| 3155 | 3155 |
| 3156 | 3156 |
| 3157 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) | 3157 #define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name) |
| 3158 STRUCT_LIST(MAKE_STRUCT_CAST) | 3158 STRUCT_LIST(MAKE_STRUCT_CAST) |
| 3159 #undef MAKE_STRUCT_CAST | 3159 #undef MAKE_STRUCT_CAST |
| 3160 | 3160 |
| 3161 | 3161 |
| 3162 template <typename Derived, typename Shape, typename Key> | 3162 template <typename Derived, typename Shape, typename Key> |
| 3163 HashTable<Derived, Shape, Key>* | 3163 HashTable<Derived, Shape, Key>* |
| 3164 HashTable<Derived, Shape, Key>::cast(Object* obj) { | 3164 HashTable<Derived, Shape, Key>::cast(Object* obj) { |
| 3165 SLOW_ASSERT(obj->IsHashTable()); | 3165 SLOW_ASSERT(obj->IsHashTable()); |
| 3166 return reinterpret_cast<HashTable*>(obj); | 3166 return reinterpret_cast<HashTable*>(obj); |
| 3167 } | 3167 } |
| 3168 | 3168 |
| 3169 | 3169 |
| 3170 template <typename Derived, typename Shape, typename Key> | 3170 template <typename Derived, typename Shape, typename Key> |
| 3171 const HashTable<Derived, Shape, Key>* | 3171 const HashTable<Derived, Shape, Key>* |
| 3172 HashTable<Derived, Shape, Key>::cast(const Object* obj) { | 3172 HashTable<Derived, Shape, Key>::cast(const Object* obj) { |
| 3173 SLOW_ASSERT(const_cast<Object*>(obj)->IsHashTable()); | 3173 SLOW_ASSERT(obj->IsHashTable()); |
| 3174 return reinterpret_cast<const HashTable*>(obj); | 3174 return reinterpret_cast<const HashTable*>(obj); |
| 3175 } | 3175 } |
| 3176 | 3176 |
| 3177 | 3177 |
| 3178 SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) | 3178 SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) |
| 3179 SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) | 3179 SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) |
| 3180 | 3180 |
| 3181 SMI_ACCESSORS(FreeSpace, size, kSizeOffset) | 3181 SMI_ACCESSORS(FreeSpace, size, kSizeOffset) |
| 3182 NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset) | 3182 NOBARRIER_SMI_ACCESSORS(FreeSpace, size, kSizeOffset) |
| 3183 | 3183 |
| (...skipping 3247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6431 | 6431 |
| 6432 bool String::AsArrayIndex(uint32_t* index) { | 6432 bool String::AsArrayIndex(uint32_t* index) { |
| 6433 uint32_t field = hash_field(); | 6433 uint32_t field = hash_field(); |
| 6434 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) { | 6434 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) { |
| 6435 return false; | 6435 return false; |
| 6436 } | 6436 } |
| 6437 return SlowAsArrayIndex(index); | 6437 return SlowAsArrayIndex(index); |
| 6438 } | 6438 } |
| 6439 | 6439 |
| 6440 | 6440 |
| 6441 Object* JSReceiver::GetPrototype() { | 6441 Object* JSReceiver::GetPrototype() const { |
| 6442 return map()->prototype(); | 6442 return map()->prototype(); |
| 6443 } | 6443 } |
| 6444 | 6444 |
| 6445 | 6445 |
| 6446 Object* JSReceiver::GetConstructor() { | 6446 Object* JSReceiver::GetConstructor() { |
| 6447 return map()->constructor(); | 6447 return map()->constructor(); |
| 6448 } | 6448 } |
| 6449 | 6449 |
| 6450 | 6450 |
| 6451 bool JSReceiver::HasProperty(Handle<JSReceiver> object, | 6451 bool JSReceiver::HasProperty(Handle<JSReceiver> object, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6487 return JSObject::GetElementAttributeWithReceiver( | 6487 return JSObject::GetElementAttributeWithReceiver( |
| 6488 Handle<JSObject>::cast(object), object, index, true); | 6488 Handle<JSObject>::cast(object), object, index, true); |
| 6489 } | 6489 } |
| 6490 | 6490 |
| 6491 | 6491 |
| 6492 bool JSGlobalObject::IsDetached() { | 6492 bool JSGlobalObject::IsDetached() { |
| 6493 return JSGlobalProxy::cast(global_receiver())->IsDetachedFrom(this); | 6493 return JSGlobalProxy::cast(global_receiver())->IsDetachedFrom(this); |
| 6494 } | 6494 } |
| 6495 | 6495 |
| 6496 | 6496 |
| 6497 bool JSGlobalProxy::IsDetachedFrom(GlobalObject* global) { | 6497 bool JSGlobalProxy::IsDetachedFrom(GlobalObject* global) const { |
| 6498 return GetPrototype() != global; | 6498 return GetPrototype() != global; |
| 6499 } | 6499 } |
| 6500 | 6500 |
| 6501 | 6501 |
| 6502 Handle<Smi> JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver> object) { | 6502 Handle<Smi> JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver> object) { |
| 6503 return object->IsJSProxy() | 6503 return object->IsJSProxy() |
| 6504 ? JSProxy::GetOrCreateIdentityHash(Handle<JSProxy>::cast(object)) | 6504 ? JSProxy::GetOrCreateIdentityHash(Handle<JSProxy>::cast(object)) |
| 6505 : JSObject::GetOrCreateIdentityHash(Handle<JSObject>::cast(object)); | 6505 : JSObject::GetOrCreateIdentityHash(Handle<JSObject>::cast(object)); |
| 6506 } | 6506 } |
| 6507 | 6507 |
| (...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7001 #undef READ_SHORT_FIELD | 7001 #undef READ_SHORT_FIELD |
| 7002 #undef WRITE_SHORT_FIELD | 7002 #undef WRITE_SHORT_FIELD |
| 7003 #undef READ_BYTE_FIELD | 7003 #undef READ_BYTE_FIELD |
| 7004 #undef WRITE_BYTE_FIELD | 7004 #undef WRITE_BYTE_FIELD |
| 7005 #undef NOBARRIER_READ_BYTE_FIELD | 7005 #undef NOBARRIER_READ_BYTE_FIELD |
| 7006 #undef NOBARRIER_WRITE_BYTE_FIELD | 7006 #undef NOBARRIER_WRITE_BYTE_FIELD |
| 7007 | 7007 |
| 7008 } } // namespace v8::internal | 7008 } } // namespace v8::internal |
| 7009 | 7009 |
| 7010 #endif // V8_OBJECTS_INL_H_ | 7010 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |