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