| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_PROPERTY_H_ | 5 #ifndef V8_PROPERTY_H_ |
| 6 #define V8_PROPERTY_H_ | 6 #define V8_PROPERTY_H_ |
| 7 | 7 |
| 8 #include "isolate.h" | 8 #include "isolate.h" |
| 9 #include "factory.h" | 9 #include "factory.h" |
| 10 #include "types.h" | |
| 11 | 10 |
| 12 namespace v8 { | 11 namespace v8 { |
| 13 namespace internal { | 12 namespace internal { |
| 14 | 13 |
| 15 // Abstraction for elements in instance-descriptor arrays. | 14 // Abstraction for elements in instance-descriptor arrays. |
| 16 // | 15 // |
| 17 // Each descriptor has a key, property attributes, property type, | 16 // Each descriptor has a key, property attributes, property type, |
| 18 // property index (in the actual instance-descriptor array) and | 17 // property index (in the actual instance-descriptor array) and |
| 19 // optionally a piece of data. | 18 // optionally a piece of data. |
| 20 class Descriptor BASE_EMBEDDED { | 19 class Descriptor BASE_EMBEDDED { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 friend class DescriptorArray; | 67 friend class DescriptorArray; |
| 69 }; | 68 }; |
| 70 | 69 |
| 71 | 70 |
| 72 class FieldDescriptor V8_FINAL : public Descriptor { | 71 class FieldDescriptor V8_FINAL : public Descriptor { |
| 73 public: | 72 public: |
| 74 FieldDescriptor(Handle<Name> key, | 73 FieldDescriptor(Handle<Name> key, |
| 75 int field_index, | 74 int field_index, |
| 76 PropertyAttributes attributes, | 75 PropertyAttributes attributes, |
| 77 Representation representation) | 76 Representation representation) |
| 78 : Descriptor(key, HeapType::Any(key->GetIsolate()), attributes, | 77 : Descriptor(key, handle(Smi::FromInt(0), key->GetIsolate()), attributes, |
| 79 FIELD, representation, field_index) {} | 78 FIELD, representation, field_index) {} |
| 80 FieldDescriptor(Handle<Name> key, | |
| 81 int field_index, | |
| 82 Handle<HeapType> field_type, | |
| 83 PropertyAttributes attributes, | |
| 84 Representation representation) | |
| 85 : Descriptor(key, field_type, attributes, FIELD, | |
| 86 representation, field_index) { } | |
| 87 }; | 79 }; |
| 88 | 80 |
| 89 | 81 |
| 90 class ConstantDescriptor V8_FINAL : public Descriptor { | 82 class ConstantDescriptor V8_FINAL : public Descriptor { |
| 91 public: | 83 public: |
| 92 ConstantDescriptor(Handle<Name> key, | 84 ConstantDescriptor(Handle<Name> key, |
| 93 Handle<Object> value, | 85 Handle<Object> value, |
| 94 PropertyAttributes attributes) | 86 PropertyAttributes attributes) |
| 95 : Descriptor(key, value, attributes, CONSTANT, | 87 : Descriptor(key, value, attributes, CONSTANT, |
| 96 value->OptimalRepresentation()) {} | 88 value->OptimalRepresentation()) {} |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 Isolate* isolate() const { return isolate_; } | 170 Isolate* isolate() const { return isolate_; } |
| 179 | 171 |
| 180 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) { | 172 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) { |
| 181 lookup_type_ = DESCRIPTOR_TYPE; | 173 lookup_type_ = DESCRIPTOR_TYPE; |
| 182 holder_ = holder; | 174 holder_ = holder; |
| 183 transition_ = NULL; | 175 transition_ = NULL; |
| 184 details_ = details; | 176 details_ = details; |
| 185 number_ = number; | 177 number_ = number; |
| 186 } | 178 } |
| 187 | 179 |
| 188 bool CanHoldValue(Handle<Object> value) const { | 180 bool CanHoldValue(Handle<Object> value) { |
| 189 switch (type()) { | 181 if (IsNormal()) return true; |
| 190 case NORMAL: | 182 return value->FitsRepresentation(details_.representation()); |
| 191 return true; | |
| 192 case FIELD: | |
| 193 return value->FitsRepresentation(representation()) && | |
| 194 GetFieldType()->NowContains(value); | |
| 195 case CONSTANT: | |
| 196 ASSERT(GetConstant() != *value || | |
| 197 value->FitsRepresentation(representation())); | |
| 198 return GetConstant() == *value; | |
| 199 case CALLBACKS: | |
| 200 case HANDLER: | |
| 201 case INTERCEPTOR: | |
| 202 return true; | |
| 203 case NONEXISTENT: | |
| 204 UNREACHABLE(); | |
| 205 } | |
| 206 UNREACHABLE(); | |
| 207 return true; | |
| 208 } | 183 } |
| 209 | 184 |
| 210 void TransitionResult(JSObject* holder, Map* target) { | 185 void TransitionResult(JSObject* holder, Map* target) { |
| 211 lookup_type_ = TRANSITION_TYPE; | 186 lookup_type_ = TRANSITION_TYPE; |
| 212 number_ = target->LastAdded(); | 187 number_ = target->LastAdded(); |
| 213 details_ = target->instance_descriptors()->GetDetails(number_); | 188 details_ = target->instance_descriptors()->GetDetails(number_); |
| 214 holder_ = holder; | 189 holder_ = holder; |
| 215 transition_ = target; | 190 transition_ = target; |
| 216 } | 191 } |
| 217 | 192 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 return map->instance_descriptors()->GetValue(number_); | 451 return map->instance_descriptors()->GetValue(number_); |
| 477 } | 452 } |
| 478 | 453 |
| 479 int GetFieldIndexFromMap(Map* map) const { | 454 int GetFieldIndexFromMap(Map* map) const { |
| 480 ASSERT(lookup_type_ == DESCRIPTOR_TYPE || | 455 ASSERT(lookup_type_ == DESCRIPTOR_TYPE || |
| 481 lookup_type_ == TRANSITION_TYPE); | 456 lookup_type_ == TRANSITION_TYPE); |
| 482 ASSERT(number_ < map->NumberOfOwnDescriptors()); | 457 ASSERT(number_ < map->NumberOfOwnDescriptors()); |
| 483 return map->instance_descriptors()->GetFieldIndex(number_); | 458 return map->instance_descriptors()->GetFieldIndex(number_); |
| 484 } | 459 } |
| 485 | 460 |
| 486 HeapType* GetFieldType() const { | |
| 487 ASSERT(type() == FIELD); | |
| 488 if (lookup_type_ == DESCRIPTOR_TYPE) { | |
| 489 return GetFieldTypeFromMap(holder()->map()); | |
| 490 } | |
| 491 ASSERT(lookup_type_ == TRANSITION_TYPE); | |
| 492 return GetFieldTypeFromMap(transition_); | |
| 493 } | |
| 494 | |
| 495 HeapType* GetFieldTypeFromMap(Map* map) const { | |
| 496 ASSERT(lookup_type_ == DESCRIPTOR_TYPE || | |
| 497 lookup_type_ == TRANSITION_TYPE); | |
| 498 ASSERT(number_ < map->NumberOfOwnDescriptors()); | |
| 499 return map->instance_descriptors()->GetFieldType(number_); | |
| 500 } | |
| 501 | |
| 502 Map* GetFieldOwner() const { | |
| 503 return GetFieldOwnerFromMap(holder()->map()); | |
| 504 } | |
| 505 | |
| 506 Map* GetFieldOwnerFromMap(Map* map) const { | |
| 507 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | |
| 508 ASSERT(number_ < map->NumberOfOwnDescriptors()); | |
| 509 return map->FindFieldOwner(number_); | |
| 510 } | |
| 511 | |
| 512 void Iterate(ObjectVisitor* visitor); | 461 void Iterate(ObjectVisitor* visitor); |
| 513 | 462 |
| 514 private: | 463 private: |
| 515 Isolate* isolate_; | 464 Isolate* isolate_; |
| 516 LookupResult* next_; | 465 LookupResult* next_; |
| 517 | 466 |
| 518 // Where did we find the result; | 467 // Where did we find the result; |
| 519 enum { | 468 enum { |
| 520 NOT_FOUND, | 469 NOT_FOUND, |
| 521 DESCRIPTOR_TYPE, | 470 DESCRIPTOR_TYPE, |
| 522 TRANSITION_TYPE, | 471 TRANSITION_TYPE, |
| 523 DICTIONARY_TYPE, | 472 DICTIONARY_TYPE, |
| 524 HANDLER_TYPE, | 473 HANDLER_TYPE, |
| 525 INTERCEPTOR_TYPE | 474 INTERCEPTOR_TYPE |
| 526 } lookup_type_; | 475 } lookup_type_; |
| 527 | 476 |
| 528 JSReceiver* holder_; | 477 JSReceiver* holder_; |
| 529 Map* transition_; | 478 Map* transition_; |
| 530 int number_; | 479 int number_; |
| 531 bool cacheable_; | 480 bool cacheable_; |
| 532 PropertyDetails details_; | 481 PropertyDetails details_; |
| 533 }; | 482 }; |
| 534 | 483 |
| 535 } } // namespace v8::internal | 484 } } // namespace v8::internal |
| 536 | 485 |
| 537 #endif // V8_PROPERTY_H_ | 486 #endif // V8_PROPERTY_H_ |
| OLD | NEW |