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 |