| 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 "src/isolate.h" | 8 #include "src/isolate.h" |
| 9 #include "src/factory.h" | 9 #include "src/factory.h" |
| 10 #include "src/field-index.h" |
| 11 #include "src/field-index-inl.h" |
| 10 #include "src/types.h" | 12 #include "src/types.h" |
| 11 | 13 |
| 12 namespace v8 { | 14 namespace v8 { |
| 13 namespace internal { | 15 namespace internal { |
| 14 | 16 |
| 15 // Abstraction for elements in instance-descriptor arrays. | 17 // Abstraction for elements in instance-descriptor arrays. |
| 16 // | 18 // |
| 17 // Each descriptor has a key, property attributes, property type, | 19 // Each descriptor has a key, property attributes, property type, |
| 18 // property index (in the actual instance-descriptor array) and | 20 // property index (in the actual instance-descriptor array) and |
| 19 // optionally a piece of data. | 21 // optionally a piece of data. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 class CallbacksDescriptor V8_FINAL : public Descriptor { | 103 class CallbacksDescriptor V8_FINAL : public Descriptor { |
| 102 public: | 104 public: |
| 103 CallbacksDescriptor(Handle<Name> key, | 105 CallbacksDescriptor(Handle<Name> key, |
| 104 Handle<Object> foreign, | 106 Handle<Object> foreign, |
| 105 PropertyAttributes attributes) | 107 PropertyAttributes attributes) |
| 106 : Descriptor(key, foreign, attributes, CALLBACKS, | 108 : Descriptor(key, foreign, attributes, CALLBACKS, |
| 107 Representation::Tagged()) {} | 109 Representation::Tagged()) {} |
| 108 }; | 110 }; |
| 109 | 111 |
| 110 | 112 |
| 111 // Holds a property index value distinguishing if it is a field index or an | |
| 112 // index inside the object header. | |
| 113 class PropertyIndex V8_FINAL { | |
| 114 public: | |
| 115 static PropertyIndex NewFieldIndex(int index) { | |
| 116 return PropertyIndex(index, false); | |
| 117 } | |
| 118 static PropertyIndex NewHeaderIndex(int index) { | |
| 119 return PropertyIndex(index, true); | |
| 120 } | |
| 121 | |
| 122 bool is_field_index() { return (index_ & kHeaderIndexBit) == 0; } | |
| 123 bool is_header_index() { return (index_ & kHeaderIndexBit) != 0; } | |
| 124 | |
| 125 int field_index() { | |
| 126 ASSERT(is_field_index()); | |
| 127 return value(); | |
| 128 } | |
| 129 int header_index() { | |
| 130 ASSERT(is_header_index()); | |
| 131 return value(); | |
| 132 } | |
| 133 | |
| 134 bool is_inobject(Handle<JSObject> holder) { | |
| 135 if (is_header_index()) return true; | |
| 136 return field_index() < holder->map()->inobject_properties(); | |
| 137 } | |
| 138 | |
| 139 int translate(Handle<JSObject> holder) { | |
| 140 if (is_header_index()) return header_index(); | |
| 141 int index = field_index() - holder->map()->inobject_properties(); | |
| 142 if (index >= 0) return index; | |
| 143 return index + holder->map()->instance_size() / kPointerSize; | |
| 144 } | |
| 145 | |
| 146 private: | |
| 147 static const int kHeaderIndexBit = 1 << 31; | |
| 148 static const int kIndexMask = ~kHeaderIndexBit; | |
| 149 | |
| 150 int value() { return index_ & kIndexMask; } | |
| 151 | |
| 152 PropertyIndex(int index, bool is_header_based) | |
| 153 : index_(index | (is_header_based ? kHeaderIndexBit : 0)) { | |
| 154 ASSERT(index <= kIndexMask); | |
| 155 } | |
| 156 | |
| 157 int index_; | |
| 158 }; | |
| 159 | |
| 160 | |
| 161 class LookupResult V8_FINAL BASE_EMBEDDED { | 113 class LookupResult V8_FINAL BASE_EMBEDDED { |
| 162 public: | 114 public: |
| 163 explicit LookupResult(Isolate* isolate) | 115 explicit LookupResult(Isolate* isolate) |
| 164 : isolate_(isolate), | 116 : isolate_(isolate), |
| 165 next_(isolate->top_lookup_result()), | 117 next_(isolate->top_lookup_result()), |
| 166 lookup_type_(NOT_FOUND), | 118 lookup_type_(NOT_FOUND), |
| 167 holder_(NULL), | 119 holder_(NULL), |
| 168 transition_(NULL), | 120 transition_(NULL), |
| 169 cacheable_(true), | 121 cacheable_(true), |
| 170 details_(NONE, NONEXISTENT, Representation::None()) { | 122 details_(NONE, NONEXISTENT, Representation::None()) { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 case NOT_FOUND: | 319 case NOT_FOUND: |
| 368 case TRANSITION_TYPE: | 320 case TRANSITION_TYPE: |
| 369 case HANDLER_TYPE: | 321 case HANDLER_TYPE: |
| 370 case INTERCEPTOR_TYPE: | 322 case INTERCEPTOR_TYPE: |
| 371 return isolate()->heap()->the_hole_value(); | 323 return isolate()->heap()->the_hole_value(); |
| 372 | 324 |
| 373 case DESCRIPTOR_TYPE: | 325 case DESCRIPTOR_TYPE: |
| 374 case DICTIONARY_TYPE: | 326 case DICTIONARY_TYPE: |
| 375 switch (type()) { | 327 switch (type()) { |
| 376 case FIELD: | 328 case FIELD: |
| 377 return holder()->RawFastPropertyAt(GetFieldIndex().field_index()); | 329 return holder()->RawFastPropertyAt(GetFieldIndex()); |
| 378 case NORMAL: { | 330 case NORMAL: { |
| 379 Object* value = holder()->property_dictionary()->ValueAt( | 331 Object* value = holder()->property_dictionary()->ValueAt( |
| 380 GetDictionaryEntry()); | 332 GetDictionaryEntry()); |
| 381 if (holder()->IsGlobalObject()) { | 333 if (holder()->IsGlobalObject()) { |
| 382 value = PropertyCell::cast(value)->value(); | 334 value = PropertyCell::cast(value)->value(); |
| 383 } | 335 } |
| 384 return value; | 336 return value; |
| 385 } | 337 } |
| 386 case CONSTANT: | 338 case CONSTANT: |
| 387 return GetConstant(); | 339 return GetConstant(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 409 | 361 |
| 410 bool IsTransitionToConstant() const { | 362 bool IsTransitionToConstant() const { |
| 411 return IsTransition() && details_.type() == CONSTANT; | 363 return IsTransition() && details_.type() == CONSTANT; |
| 412 } | 364 } |
| 413 | 365 |
| 414 int GetDescriptorIndex() const { | 366 int GetDescriptorIndex() const { |
| 415 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | 367 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
| 416 return number_; | 368 return number_; |
| 417 } | 369 } |
| 418 | 370 |
| 419 PropertyIndex GetFieldIndex() const { | 371 FieldIndex GetFieldIndex() const { |
| 420 ASSERT(lookup_type_ == DESCRIPTOR_TYPE || | 372 ASSERT(lookup_type_ == DESCRIPTOR_TYPE || |
| 421 lookup_type_ == TRANSITION_TYPE); | 373 lookup_type_ == TRANSITION_TYPE); |
| 422 return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map())); | 374 return FieldIndex::ForLookupResult(this); |
| 423 } | 375 } |
| 424 | 376 |
| 425 int GetLocalFieldIndexFromMap(Map* map) const { | 377 int GetLocalFieldIndexFromMap(Map* map) const { |
| 426 return GetFieldIndexFromMap(map) - map->inobject_properties(); | 378 return GetFieldIndexFromMap(map) - map->inobject_properties(); |
| 427 } | 379 } |
| 428 | 380 |
| 429 int GetDictionaryEntry() const { | 381 int GetDictionaryEntry() const { |
| 430 ASSERT(lookup_type_ == DICTIONARY_TYPE); | 382 ASSERT(lookup_type_ == DICTIONARY_TYPE); |
| 431 return number_; | 383 return number_; |
| 432 } | 384 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 JSReceiver* holder_; | 483 JSReceiver* holder_; |
| 532 Map* transition_; | 484 Map* transition_; |
| 533 int number_; | 485 int number_; |
| 534 bool cacheable_; | 486 bool cacheable_; |
| 535 PropertyDetails details_; | 487 PropertyDetails details_; |
| 536 }; | 488 }; |
| 537 | 489 |
| 538 } } // namespace v8::internal | 490 } } // namespace v8::internal |
| 539 | 491 |
| 540 #endif // V8_PROPERTY_H_ | 492 #endif // V8_PROPERTY_H_ |
| OLD | NEW |