OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2465 // Returns the number of descriptors in the array. | 2465 // Returns the number of descriptors in the array. |
2466 int number_of_descriptors() { | 2466 int number_of_descriptors() { |
2467 ASSERT(MayContainTransitions() || IsEmpty()); | 2467 ASSERT(MayContainTransitions() || IsEmpty()); |
2468 int len = length(); | 2468 int len = length(); |
2469 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; | 2469 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; |
2470 } | 2470 } |
2471 | 2471 |
2472 inline int number_of_entries() { return number_of_descriptors(); } | 2472 inline int number_of_entries() { return number_of_descriptors(); } |
2473 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } | 2473 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } |
2474 | 2474 |
2475 int LastAdded() { | |
2476 ASSERT(!IsEmpty()); | |
2477 Object* obj = get(kLastAddedIndex); | |
2478 if (obj->IsSmi()) { | |
2479 return Smi::cast(obj)->value(); | |
2480 } else { | |
2481 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeLastAdded); | |
2482 return Smi::cast(index)->value(); | |
2483 } | |
2484 } | |
2485 | |
2486 // Set index of the last added descriptor and flush any enum cache. | |
2487 void SetLastAdded(int index) { | |
2488 ASSERT(!IsEmpty() || index > 0); | |
2489 set(kLastAddedIndex, Smi::FromInt(index)); | |
2490 } | |
2491 | |
2492 int NumberOfSetDescriptors() { | |
2493 ASSERT(!IsEmpty()); | |
2494 if (LastAdded() == kNoneAdded) return 0; | |
2495 return GetDetails(LastAdded()).index(); | |
2496 } | |
2497 | |
2498 bool HasEnumCache() { | 2475 bool HasEnumCache() { |
2499 return !IsEmpty() && !get(kLastAddedIndex)->IsSmi(); | 2476 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); |
2500 } | 2477 } |
2501 | 2478 |
2502 Object* GetEnumCache() { | 2479 Object* GetEnumCache() { |
2503 ASSERT(HasEnumCache()); | 2480 ASSERT(HasEnumCache()); |
2504 FixedArray* bridge = FixedArray::cast(get(kLastAddedIndex)); | 2481 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
2505 return bridge->get(kEnumCacheBridgeCacheIndex); | 2482 return bridge->get(kEnumCacheBridgeCacheIndex); |
2506 } | 2483 } |
2507 | 2484 |
2508 Object** GetEnumCacheSlot() { | 2485 Object** GetEnumCacheSlot() { |
2509 ASSERT(HasEnumCache()); | 2486 ASSERT(HasEnumCache()); |
2510 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | 2487 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
2511 kLastAddedOffset); | 2488 kEnumCacheOffset); |
2512 } | 2489 } |
2513 | 2490 |
2514 Object** GetTransitionsSlot() { | 2491 Object** GetTransitionsSlot() { |
2515 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | 2492 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
2516 kTransitionsOffset); | 2493 kTransitionsOffset); |
2517 } | 2494 } |
2518 | 2495 |
2519 DECL_ACCESSORS(back_pointer_storage, Object) | 2496 DECL_ACCESSORS(back_pointer_storage, Object) |
2520 | 2497 |
2521 // Initialize or change the enum cache, | 2498 // Initialize or change the enum cache, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2583 // empty descriptor array object if number_of_descriptors is 0. | 2560 // empty descriptor array object if number_of_descriptors is 0. |
2584 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, | 2561 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, |
2585 SharedMode shared_mode); | 2562 SharedMode shared_mode); |
2586 | 2563 |
2587 // Casting. | 2564 // Casting. |
2588 static inline DescriptorArray* cast(Object* obj); | 2565 static inline DescriptorArray* cast(Object* obj); |
2589 | 2566 |
2590 // Constant for denoting key was not found. | 2567 // Constant for denoting key was not found. |
2591 static const int kNotFound = -1; | 2568 static const int kNotFound = -1; |
2592 | 2569 |
2593 // Constant for denoting that the LastAdded field was not yet set. | |
2594 static const int kNoneAdded = -1; | |
2595 | |
2596 static const int kBackPointerStorageIndex = 0; | 2570 static const int kBackPointerStorageIndex = 0; |
2597 static const int kLastAddedIndex = 1; | 2571 static const int kEnumCacheIndex = 1; |
2598 static const int kTransitionsIndex = 2; | 2572 static const int kTransitionsIndex = 2; |
2599 static const int kFirstIndex = 3; | 2573 static const int kFirstIndex = 3; |
2600 | 2574 |
2601 // The length of the "bridge" to the enum cache. | 2575 // The length of the "bridge" to the enum cache. |
2602 static const int kEnumCacheBridgeLength = 3; | 2576 static const int kEnumCacheBridgeLength = 3; |
2603 static const int kEnumCacheBridgeLastAdded = 0; | 2577 static const int kEnumCacheBridgeLastAdded = 0; |
2604 static const int kEnumCacheBridgeCacheIndex = 1; | 2578 static const int kEnumCacheBridgeCacheIndex = 1; |
2605 static const int kEnumCacheBridgeIndicesCacheIndex = 2; | 2579 static const int kEnumCacheBridgeIndicesCacheIndex = 2; |
2606 | 2580 |
2607 // Layout description. | 2581 // Layout description. |
2608 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; | 2582 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; |
2609 static const int kLastAddedOffset = kBackPointerStorageOffset + | 2583 static const int kEnumCacheOffset = kBackPointerStorageOffset + |
2610 kPointerSize; | 2584 kPointerSize; |
2611 static const int kTransitionsOffset = kLastAddedOffset + kPointerSize; | 2585 static const int kTransitionsOffset = kEnumCacheOffset + kPointerSize; |
2612 static const int kFirstOffset = kTransitionsOffset + kPointerSize; | 2586 static const int kFirstOffset = kTransitionsOffset + kPointerSize; |
2613 | 2587 |
2614 // Layout description for the bridge array. | 2588 // Layout description for the bridge array. |
2615 static const int kEnumCacheBridgeLastAddedOffset = FixedArray::kHeaderSize; | 2589 static const int kEnumCacheBridgeLastAddedOffset = FixedArray::kHeaderSize; |
2616 static const int kEnumCacheBridgeCacheOffset = | 2590 static const int kEnumCacheBridgeCacheOffset = |
2617 kEnumCacheBridgeLastAddedOffset + kPointerSize; | 2591 kEnumCacheBridgeLastAddedOffset + kPointerSize; |
2618 | 2592 |
2619 // Layout of descriptor. | 2593 // Layout of descriptor. |
2620 static const int kDescriptorKey = 0; | 2594 static const int kDescriptorKey = 0; |
2621 static const int kDescriptorDetails = 1; | 2595 static const int kDescriptorDetails = 1; |
(...skipping 2045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4667 inline void set_bit_field(byte value); | 4641 inline void set_bit_field(byte value); |
4668 | 4642 |
4669 // Bit field 2. | 4643 // Bit field 2. |
4670 inline byte bit_field2(); | 4644 inline byte bit_field2(); |
4671 inline void set_bit_field2(byte value); | 4645 inline void set_bit_field2(byte value); |
4672 | 4646 |
4673 // Bit field 3. | 4647 // Bit field 3. |
4674 inline int bit_field3(); | 4648 inline int bit_field3(); |
4675 inline void set_bit_field3(int value); | 4649 inline void set_bit_field3(int value); |
4676 | 4650 |
| 4651 class IsShared: public BitField<bool, 0, 1> {}; |
| 4652 class FunctionWithPrototype: public BitField<bool, 1, 1> {}; |
| 4653 class LastAddedBits: public BitField<int, 2, 11> {}; |
| 4654 |
4677 // Tells whether the object in the prototype property will be used | 4655 // Tells whether the object in the prototype property will be used |
4678 // for instances created from this function. If the prototype | 4656 // for instances created from this function. If the prototype |
4679 // property is set to a value that is not a JSObject, the prototype | 4657 // property is set to a value that is not a JSObject, the prototype |
4680 // property will not be used to create instances of the function. | 4658 // property will not be used to create instances of the function. |
4681 // See ECMA-262, 13.2.2. | 4659 // See ECMA-262, 13.2.2. |
4682 inline void set_non_instance_prototype(bool value); | 4660 inline void set_non_instance_prototype(bool value); |
4683 inline bool has_non_instance_prototype(); | 4661 inline bool has_non_instance_prototype(); |
4684 | 4662 |
4685 // Tells whether function has special prototype property. If not, prototype | 4663 // Tells whether function has special prototype property. If not, prototype |
4686 // property will not be created when accessed (will return undefined), | 4664 // property will not be created when accessed (will return undefined), |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4891 // with the given holder if the name is found. The holder may be | 4869 // with the given holder if the name is found. The holder may be |
4892 // NULL when this function is used from the compiler. | 4870 // NULL when this function is used from the compiler. |
4893 void LookupDescriptor(JSObject* holder, | 4871 void LookupDescriptor(JSObject* holder, |
4894 String* name, | 4872 String* name, |
4895 LookupResult* result); | 4873 LookupResult* result); |
4896 | 4874 |
4897 void LookupTransition(JSObject* holder, | 4875 void LookupTransition(JSObject* holder, |
4898 String* name, | 4876 String* name, |
4899 LookupResult* result); | 4877 LookupResult* result); |
4900 | 4878 |
| 4879 void SetLastAdded(int index) { |
| 4880 set_bit_field3(LastAddedBits::update(bit_field3(), index)); |
| 4881 } |
| 4882 |
| 4883 int LastAdded() { |
| 4884 return LastAddedBits::decode(bit_field3()); |
| 4885 } |
| 4886 |
| 4887 int NumberOfSetDescriptors() { |
| 4888 ASSERT(!instance_descriptors()->IsEmpty()); |
| 4889 if (LastAdded() == kNoneAdded) return 0; |
| 4890 return instance_descriptors()->GetDetails(LastAdded()).index(); |
| 4891 } |
| 4892 |
4901 MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); | 4893 MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); |
4902 MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); | 4894 MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); |
4903 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); | 4895 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); |
4904 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( | 4896 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( |
4905 DescriptorArray* descriptors, | 4897 DescriptorArray* descriptors, |
4906 String* name, | 4898 String* name, |
4907 int last_added, | 4899 int last_added, |
4908 TransitionFlag flag); | 4900 TransitionFlag flag); |
4909 MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, | 4901 MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, |
4910 TransitionFlag flag); | 4902 TransitionFlag flag); |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5026 // and the values are the maps the are transitioned to. | 5018 // and the values are the maps the are transitioned to. |
5027 static const int kMaxCachedPrototypeTransitions = 256; | 5019 static const int kMaxCachedPrototypeTransitions = 256; |
5028 | 5020 |
5029 Map* GetPrototypeTransition(Object* prototype); | 5021 Map* GetPrototypeTransition(Object* prototype); |
5030 | 5022 |
5031 MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype, | 5023 MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype, |
5032 Map* map); | 5024 Map* map); |
5033 | 5025 |
5034 static const int kMaxPreAllocatedPropertyFields = 255; | 5026 static const int kMaxPreAllocatedPropertyFields = 255; |
5035 | 5027 |
| 5028 // Constant for denoting that the LastAdded field was not yet set. |
| 5029 static const int kNoneAdded = LastAddedBits::kMax; |
| 5030 |
5036 // Layout description. | 5031 // Layout description. |
5037 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 5032 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
5038 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 5033 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
5039 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; | 5034 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; |
5040 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; | 5035 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; |
5041 // Storage for instance descriptors is overloaded to also contain additional | 5036 // Storage for instance descriptors is overloaded to also contain additional |
5042 // map flags when unused (bit_field3). When the map has instance descriptors, | 5037 // map flags when unused (bit_field3). When the map has instance descriptors, |
5043 // the flags are transferred to the instance descriptor array and accessed | 5038 // the flags are transferred to the instance descriptor array and accessed |
5044 // through an extra indirection. | 5039 // through an extra indirection. |
5045 static const int kInstanceDescriptorsOrBackPointerOffset = | 5040 static const int kInstanceDescriptorsOrBackPointerOffset = |
(...skipping 3835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8881 } else { | 8876 } else { |
8882 value &= ~(1 << bit_position); | 8877 value &= ~(1 << bit_position); |
8883 } | 8878 } |
8884 return value; | 8879 return value; |
8885 } | 8880 } |
8886 }; | 8881 }; |
8887 | 8882 |
8888 } } // namespace v8::internal | 8883 } } // namespace v8::internal |
8889 | 8884 |
8890 #endif // V8_OBJECTS_H_ | 8885 #endif // V8_OBJECTS_H_ |
OLD | NEW |