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 |