| 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" | |
| 12 #include "src/types.h" | 10 #include "src/types.h" |
| 13 | 11 |
| 14 namespace v8 { | 12 namespace v8 { |
| 15 namespace internal { | 13 namespace internal { |
| 16 | 14 |
| 17 // Abstraction for elements in instance-descriptor arrays. | 15 // Abstraction for elements in instance-descriptor arrays. |
| 18 // | 16 // |
| 19 // Each descriptor has a key, property attributes, property type, | 17 // Each descriptor has a key, property attributes, property type, |
| 20 // property index (in the actual instance-descriptor array) and | 18 // property index (in the actual instance-descriptor array) and |
| 21 // optionally a piece of data. | 19 // optionally a piece of data. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 103 class CallbacksDescriptor V8_FINAL : public Descriptor { | 101 class CallbacksDescriptor V8_FINAL : public Descriptor { |
| 104 public: | 102 public: |
| 105 CallbacksDescriptor(Handle<Name> key, | 103 CallbacksDescriptor(Handle<Name> key, |
| 106 Handle<Object> foreign, | 104 Handle<Object> foreign, |
| 107 PropertyAttributes attributes) | 105 PropertyAttributes attributes) |
| 108 : Descriptor(key, foreign, attributes, CALLBACKS, | 106 : Descriptor(key, foreign, attributes, CALLBACKS, |
| 109 Representation::Tagged()) {} | 107 Representation::Tagged()) {} |
| 110 }; | 108 }; |
| 111 | 109 |
| 112 | 110 |
| 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 |
| 113 class LookupResult V8_FINAL BASE_EMBEDDED { | 161 class LookupResult V8_FINAL BASE_EMBEDDED { |
| 114 public: | 162 public: |
| 115 explicit LookupResult(Isolate* isolate) | 163 explicit LookupResult(Isolate* isolate) |
| 116 : isolate_(isolate), | 164 : isolate_(isolate), |
| 117 next_(isolate->top_lookup_result()), | 165 next_(isolate->top_lookup_result()), |
| 118 lookup_type_(NOT_FOUND), | 166 lookup_type_(NOT_FOUND), |
| 119 holder_(NULL), | 167 holder_(NULL), |
| 120 transition_(NULL), | 168 transition_(NULL), |
| 121 cacheable_(true), | 169 cacheable_(true), |
| 122 details_(NONE, NONEXISTENT, Representation::None()) { | 170 details_(NONE, NONEXISTENT, Representation::None()) { |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 case NOT_FOUND: | 367 case NOT_FOUND: |
| 320 case TRANSITION_TYPE: | 368 case TRANSITION_TYPE: |
| 321 case HANDLER_TYPE: | 369 case HANDLER_TYPE: |
| 322 case INTERCEPTOR_TYPE: | 370 case INTERCEPTOR_TYPE: |
| 323 return isolate()->heap()->the_hole_value(); | 371 return isolate()->heap()->the_hole_value(); |
| 324 | 372 |
| 325 case DESCRIPTOR_TYPE: | 373 case DESCRIPTOR_TYPE: |
| 326 case DICTIONARY_TYPE: | 374 case DICTIONARY_TYPE: |
| 327 switch (type()) { | 375 switch (type()) { |
| 328 case FIELD: | 376 case FIELD: |
| 329 return holder()->RawFastPropertyAt(GetFieldIndex()); | 377 return holder()->RawFastPropertyAt(GetFieldIndex().field_index()); |
| 330 case NORMAL: { | 378 case NORMAL: { |
| 331 Object* value = holder()->property_dictionary()->ValueAt( | 379 Object* value = holder()->property_dictionary()->ValueAt( |
| 332 GetDictionaryEntry()); | 380 GetDictionaryEntry()); |
| 333 if (holder()->IsGlobalObject()) { | 381 if (holder()->IsGlobalObject()) { |
| 334 value = PropertyCell::cast(value)->value(); | 382 value = PropertyCell::cast(value)->value(); |
| 335 } | 383 } |
| 336 return value; | 384 return value; |
| 337 } | 385 } |
| 338 case CONSTANT: | 386 case CONSTANT: |
| 339 return GetConstant(); | 387 return GetConstant(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 361 | 409 |
| 362 bool IsTransitionToConstant() const { | 410 bool IsTransitionToConstant() const { |
| 363 return IsTransition() && details_.type() == CONSTANT; | 411 return IsTransition() && details_.type() == CONSTANT; |
| 364 } | 412 } |
| 365 | 413 |
| 366 int GetDescriptorIndex() const { | 414 int GetDescriptorIndex() const { |
| 367 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); | 415 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); |
| 368 return number_; | 416 return number_; |
| 369 } | 417 } |
| 370 | 418 |
| 371 FieldIndex GetFieldIndex() const { | 419 PropertyIndex GetFieldIndex() const { |
| 372 ASSERT(lookup_type_ == DESCRIPTOR_TYPE || | 420 ASSERT(lookup_type_ == DESCRIPTOR_TYPE || |
| 373 lookup_type_ == TRANSITION_TYPE); | 421 lookup_type_ == TRANSITION_TYPE); |
| 374 return FieldIndex::ForLookupResult(this); | 422 return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map())); |
| 375 } | 423 } |
| 376 | 424 |
| 377 int GetLocalFieldIndexFromMap(Map* map) const { | 425 int GetLocalFieldIndexFromMap(Map* map) const { |
| 378 return GetFieldIndexFromMap(map) - map->inobject_properties(); | 426 return GetFieldIndexFromMap(map) - map->inobject_properties(); |
| 379 } | 427 } |
| 380 | 428 |
| 381 int GetDictionaryEntry() const { | 429 int GetDictionaryEntry() const { |
| 382 ASSERT(lookup_type_ == DICTIONARY_TYPE); | 430 ASSERT(lookup_type_ == DICTIONARY_TYPE); |
| 383 return number_; | 431 return number_; |
| 384 } | 432 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 483 JSReceiver* holder_; | 531 JSReceiver* holder_; |
| 484 Map* transition_; | 532 Map* transition_; |
| 485 int number_; | 533 int number_; |
| 486 bool cacheable_; | 534 bool cacheable_; |
| 487 PropertyDetails details_; | 535 PropertyDetails details_; |
| 488 }; | 536 }; |
| 489 | 537 |
| 490 } } // namespace v8::internal | 538 } } // namespace v8::internal |
| 491 | 539 |
| 492 #endif // V8_PROPERTY_H_ | 540 #endif // V8_PROPERTY_H_ |
| OLD | NEW |