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 2457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2468 // [1]: pointer to fixed array with enum cache | 2468 // [1]: pointer to fixed array with enum cache |
2469 // [3]: first key | 2469 // [3]: first key |
2470 // [length() - kDescriptorSize]: last key | 2470 // [length() - kDescriptorSize]: last key |
2471 // | 2471 // |
2472 class DescriptorArray: public FixedArray { | 2472 class DescriptorArray: public FixedArray { |
2473 public: | 2473 public: |
2474 // Returns true for both shared empty_descriptor_array and for smis, which the | 2474 // Returns true for both shared empty_descriptor_array and for smis, which the |
2475 // map uses to encode additional bit fields when the descriptor array is not | 2475 // map uses to encode additional bit fields when the descriptor array is not |
2476 // yet used. | 2476 // yet used. |
2477 inline bool IsEmpty(); | 2477 inline bool IsEmpty(); |
2478 inline bool MayContainTransitions(); | |
2479 inline bool HasTransitionArray(); | |
2480 | |
2481 DECL_ACCESSORS(transitions, TransitionArray) | |
2482 inline void ClearTransitions(); | |
2483 | 2478 |
2484 // Returns the number of descriptors in the array. | 2479 // Returns the number of descriptors in the array. |
2485 int number_of_descriptors() { | 2480 int number_of_descriptors() { |
2486 ASSERT(MayContainTransitions() || IsEmpty()); | 2481 ASSERT(length() >= kFirstIndex || IsEmpty()); |
2487 int len = length(); | 2482 int len = length(); |
2488 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; | 2483 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; |
2489 } | 2484 } |
2490 | 2485 |
2491 inline int number_of_entries() { return number_of_descriptors(); } | 2486 inline int number_of_entries() { return number_of_descriptors(); } |
2492 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } | 2487 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } |
2493 | 2488 |
2494 bool HasEnumCache() { | 2489 bool HasEnumCache() { |
2495 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); | 2490 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); |
2496 } | 2491 } |
2497 | 2492 |
2498 Object* GetEnumCache() { | 2493 Object* GetEnumCache() { |
2499 ASSERT(HasEnumCache()); | 2494 ASSERT(HasEnumCache()); |
2500 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); | 2495 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
2501 return bridge->get(kEnumCacheBridgeCacheIndex); | 2496 return bridge->get(kEnumCacheBridgeCacheIndex); |
2502 } | 2497 } |
2503 | 2498 |
2504 Object** GetEnumCacheSlot() { | 2499 Object** GetEnumCacheSlot() { |
2505 ASSERT(HasEnumCache()); | 2500 ASSERT(HasEnumCache()); |
2506 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | 2501 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
2507 kEnumCacheOffset); | 2502 kEnumCacheOffset); |
2508 } | 2503 } |
2509 | 2504 |
2510 Object** GetTransitionsSlot() { | |
2511 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | |
2512 kTransitionsOffset); | |
2513 } | |
2514 | |
2515 DECL_ACCESSORS(back_pointer_storage, Object) | |
2516 | |
2517 // Initialize or change the enum cache, | 2505 // Initialize or change the enum cache, |
2518 // using the supplied storage for the small "bridge". | 2506 // using the supplied storage for the small "bridge". |
2519 void SetEnumCache(FixedArray* bridge_storage, | 2507 void SetEnumCache(FixedArray* bridge_storage, |
2520 FixedArray* new_cache, | 2508 FixedArray* new_cache, |
2521 Object* new_index_cache); | 2509 Object* new_index_cache); |
2522 | 2510 |
2523 // Accessors for fetching instance descriptor at descriptor number. | 2511 // Accessors for fetching instance descriptor at descriptor number. |
2524 inline String* GetKey(int descriptor_number); | 2512 inline String* GetKey(int descriptor_number); |
2525 inline Object** GetKeySlot(int descriptor_number); | 2513 inline Object** GetKeySlot(int descriptor_number); |
2526 inline Object* GetValue(int descriptor_number); | 2514 inline Object* GetValue(int descriptor_number); |
(...skipping 17 matching lines...) Expand all Loading... | |
2544 const WhitenessWitness&, | 2532 const WhitenessWitness&, |
2545 int number_of_set_descriptors); | 2533 int number_of_set_descriptors); |
2546 | 2534 |
2547 // Transfer a complete descriptor from the src descriptor array to this | 2535 // Transfer a complete descriptor from the src descriptor array to this |
2548 // descriptor array. | 2536 // descriptor array. |
2549 void CopyFrom(int dst_index, | 2537 void CopyFrom(int dst_index, |
2550 DescriptorArray* src, | 2538 DescriptorArray* src, |
2551 int src_index, | 2539 int src_index, |
2552 const WhitenessWitness&); | 2540 const WhitenessWitness&); |
2553 | 2541 |
2554 // Indicates whether the search function should expect a sorted or an unsorted | |
2555 // descriptor array as input. | |
2556 enum SharedMode { | |
2557 MAY_BE_SHARED, | |
2558 CANNOT_BE_SHARED | |
2559 }; | |
2560 | |
2561 // Return a copy of the array with all transitions and null descriptors | |
2562 // removed. Return a Failure object in case of an allocation failure. | |
2563 MUST_USE_RESULT MaybeObject* Copy(SharedMode shared_mode); | |
2564 | |
2565 // Sort the instance descriptors by the hash codes of their keys. | 2542 // Sort the instance descriptors by the hash codes of their keys. |
2566 void Sort(const WhitenessWitness&); | 2543 void Sort(const WhitenessWitness&); |
2567 | 2544 |
2568 // Search the instance descriptors for given name. | 2545 // Search the instance descriptors for given name. |
2569 INLINE(int Search(String* name)); | 2546 INLINE(int Search(String* name)); |
2570 | 2547 |
2571 // As the above, but uses DescriptorLookupCache and updates it when | 2548 // As the above, but uses DescriptorLookupCache and updates it when |
2572 // necessary. | 2549 // necessary. |
2573 INLINE(int SearchWithCache(String* name)); | 2550 INLINE(int SearchWithCache(String* name)); |
2574 | 2551 |
2575 // Tells whether the name is present int the array. | 2552 // Tells whether the name is present int the array. |
2576 bool Contains(String* name) { return kNotFound != Search(name); } | 2553 bool Contains(String* name) { return kNotFound != Search(name); } |
2577 | 2554 |
2578 // Allocates a DescriptorArray, but returns the singleton | 2555 // Allocates a DescriptorArray, but returns the singleton |
2579 // empty descriptor array object if number_of_descriptors is 0. | 2556 // empty descriptor array object if number_of_descriptors is 0. |
2580 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, | 2557 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); |
2581 SharedMode shared_mode); | |
2582 | 2558 |
2583 // Casting. | 2559 // Casting. |
2584 static inline DescriptorArray* cast(Object* obj); | 2560 static inline DescriptorArray* cast(Object* obj); |
2585 | 2561 |
2586 // Constant for denoting key was not found. | 2562 // Constant for denoting key was not found. |
2587 static const int kNotFound = -1; | 2563 static const int kNotFound = -1; |
2588 | 2564 |
2589 static const int kBackPointerStorageIndex = 0; | 2565 static const int kEnumCacheIndex = 0; |
2590 static const int kEnumCacheIndex = 1; | 2566 static const int kFirstIndex = 1; |
2591 static const int kTransitionsIndex = 2; | |
2592 static const int kFirstIndex = 3; | |
2593 | 2567 |
2594 // The length of the "bridge" to the enum cache. | 2568 // The length of the "bridge" to the enum cache. |
2595 static const int kEnumCacheBridgeLength = 2; | 2569 static const int kEnumCacheBridgeLength = 2; |
2596 static const int kEnumCacheBridgeCacheIndex = 0; | 2570 static const int kEnumCacheBridgeCacheIndex = 0; |
2597 static const int kEnumCacheBridgeIndicesCacheIndex = 1; | 2571 static const int kEnumCacheBridgeIndicesCacheIndex = 1; |
2598 | 2572 |
2599 // Layout description. | 2573 // Layout description. |
2600 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; | 2574 static const int kEnumCacheOffset = FixedArray::kHeaderSize; |
2601 static const int kEnumCacheOffset = kBackPointerStorageOffset + | 2575 static const int kFirstOffset = kEnumCacheOffset + kPointerSize; |
2602 kPointerSize; | |
2603 static const int kTransitionsOffset = kEnumCacheOffset + kPointerSize; | |
2604 static const int kFirstOffset = kTransitionsOffset + kPointerSize; | |
2605 | 2576 |
2606 // Layout description for the bridge array. | 2577 // Layout description for the bridge array. |
2607 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize; | 2578 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize; |
2608 | 2579 |
2609 // Layout of descriptor. | 2580 // Layout of descriptor. |
2610 static const int kDescriptorKey = 0; | 2581 static const int kDescriptorKey = 0; |
2611 static const int kDescriptorDetails = 1; | 2582 static const int kDescriptorDetails = 1; |
2612 static const int kDescriptorValue = 2; | 2583 static const int kDescriptorValue = 2; |
2613 static const int kDescriptorSize = 3; | 2584 static const int kDescriptorSize = 3; |
2614 | 2585 |
(...skipping 2176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4791 } | 4762 } |
4792 | 4763 |
4793 static bool IsValidElementsTransition(ElementsKind from_kind, | 4764 static bool IsValidElementsTransition(ElementsKind from_kind, |
4794 ElementsKind to_kind); | 4765 ElementsKind to_kind); |
4795 | 4766 |
4796 inline bool HasTransitionArray(); | 4767 inline bool HasTransitionArray(); |
4797 inline bool HasElementsTransition(); | 4768 inline bool HasElementsTransition(); |
4798 inline Map* elements_transition_map(); | 4769 inline Map* elements_transition_map(); |
4799 MUST_USE_RESULT inline MaybeObject* set_elements_transition_map( | 4770 MUST_USE_RESULT inline MaybeObject* set_elements_transition_map( |
4800 Map* transitioned_map); | 4771 Map* transitioned_map); |
4801 inline TransitionArray* transitions(); | |
4802 inline void SetTransition(int index, Map* target); | 4772 inline void SetTransition(int index, Map* target); |
4803 MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target); | 4773 MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target); |
4804 MUST_USE_RESULT inline MaybeObject* set_transitions( | 4774 DECL_ACCESSORS(transitions, TransitionArray) |
4805 TransitionArray* transitions); | |
4806 inline void ClearTransitions(Heap* heap, | 4775 inline void ClearTransitions(Heap* heap, |
4807 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 4776 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
4808 | 4777 |
4809 // Tells whether the map is attached to SharedFunctionInfo | 4778 // Tells whether the map is attached to SharedFunctionInfo |
4810 // (for inobject slack tracking). | 4779 // (for inobject slack tracking). |
4811 inline void set_attached_to_shared_function_info(bool value); | 4780 inline void set_attached_to_shared_function_info(bool value); |
4812 | 4781 |
4813 inline bool attached_to_shared_function_info(); | 4782 inline bool attached_to_shared_function_info(); |
4814 | 4783 |
4815 // Tells whether the map is shared between objects that may have different | 4784 // Tells whether the map is shared between objects that may have different |
4816 // behavior. If true, the map should never be modified, instead a clone | 4785 // behavior. If true, the map should never be modified, instead a clone |
4817 // should be created and modified. | 4786 // should be created and modified. |
4818 inline void set_is_shared(bool value); | 4787 inline void set_is_shared(bool value); |
4819 inline bool is_shared(); | 4788 inline bool is_shared(); |
4820 | 4789 |
4821 // Tells whether the instance needs security checks when accessing its | 4790 // Tells whether the instance needs security checks when accessing its |
4822 // properties. | 4791 // properties. |
4823 inline void set_is_access_check_needed(bool access_check_needed); | 4792 inline void set_is_access_check_needed(bool access_check_needed); |
4824 inline bool is_access_check_needed(); | 4793 inline bool is_access_check_needed(); |
4825 | 4794 |
4826 // [prototype]: implicit prototype object. | 4795 // [prototype]: implicit prototype object. |
4827 DECL_ACCESSORS(prototype, Object) | 4796 DECL_ACCESSORS(prototype, Object) |
4828 | 4797 |
4829 // [constructor]: points back to the function responsible for this map. | 4798 // [constructor]: points back to the function responsible for this map. |
4830 DECL_ACCESSORS(constructor, Object) | 4799 DECL_ACCESSORS(constructor, Object) |
4831 | 4800 |
4832 inline JSFunction* unchecked_constructor(); | 4801 inline JSFunction* unchecked_constructor(); |
4833 | 4802 |
4834 // [instance descriptors]: describes the object. | 4803 // [instance descriptors]: describes the object. |
4835 DECL_ACCESSORS(instance_descriptors, DescriptorArray) | 4804 inline DescriptorArray* instance_descriptors(); |
4836 inline void InitializeDescriptors(DescriptorArray* descriptors); | 4805 MUST_USE_RESULT inline MaybeObject* SetDescriptors( |
4837 | 4806 DescriptorArray* descriptors, |
4838 // Should only be called to clear a descriptor array that was only used to | 4807 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
4839 // store transitions and does not contain any live transitions anymore. | 4808 static void SetDescriptors(Handle<Map> map, |
4840 inline void ClearDescriptorArray(Heap* heap, WriteBarrierMode mode); | 4809 Handle<DescriptorArray> descriptors); |
4810 MUST_USE_RESULT inline MaybeObject* InitializeDescriptors( | |
4811 DescriptorArray* descriptors); | |
4841 | 4812 |
4842 // [stub cache]: contains stubs compiled for this map. | 4813 // [stub cache]: contains stubs compiled for this map. |
4843 DECL_ACCESSORS(code_cache, Object) | 4814 DECL_ACCESSORS(code_cache, Object) |
4844 | 4815 |
4845 // [back pointer]: points back to the parent map from which a transition | 4816 // [back pointer]: points back to the parent map from which a transition |
4846 // leads to this map. The field overlaps with prototype transitions and the | 4817 // leads to this map. The field overlaps with prototype transitions and the |
4847 // back pointer will be moved into the prototype transitions array if | 4818 // back pointer will be moved into the prototype transitions array if |
4848 // required. | 4819 // required. |
4849 inline Object* GetBackPointer(); | 4820 inline Object* GetBackPointer(); |
4850 inline void SetBackPointer(Object* value, | 4821 inline void SetBackPointer(Object* value, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4936 TransitionFlag flag); | 4907 TransitionFlag flag); |
4937 | 4908 |
4938 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, | 4909 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, |
4939 NormalizedMapSharingMode sharing); | 4910 NormalizedMapSharingMode sharing); |
4940 | 4911 |
4941 inline void AppendDescriptor(Descriptor* desc, | 4912 inline void AppendDescriptor(Descriptor* desc, |
4942 const DescriptorArray::WhitenessWitness&); | 4913 const DescriptorArray::WhitenessWitness&); |
4943 | 4914 |
4944 // Returns a copy of the map, with all transitions dropped from the | 4915 // Returns a copy of the map, with all transitions dropped from the |
4945 // instance descriptors. | 4916 // instance descriptors. |
4946 MUST_USE_RESULT MaybeObject* Copy(DescriptorArray::SharedMode shared_mode); | 4917 MUST_USE_RESULT MaybeObject* Copy(); |
4947 | 4918 |
4948 // Returns the property index for name (only valid for FAST MODE). | 4919 // Returns the property index for name (only valid for FAST MODE). |
4949 int PropertyIndexFor(String* name); | 4920 int PropertyIndexFor(String* name); |
4950 | 4921 |
4951 // Returns the next free property index (only valid for FAST MODE). | 4922 // Returns the next free property index (only valid for FAST MODE). |
4952 int NextFreePropertyIndex(); | 4923 int NextFreePropertyIndex(); |
4953 | 4924 |
4954 // Returns the number of properties described in instance_descriptors | 4925 // Returns the number of properties described in instance_descriptors |
4955 // filtering out properties with the specified attributes. | 4926 // filtering out properties with the specified attributes. |
4956 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); | 4927 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5058 static const int kMaxPreAllocatedPropertyFields = 255; | 5029 static const int kMaxPreAllocatedPropertyFields = 255; |
5059 | 5030 |
5060 // Constant for denoting that the LastAdded field was not yet set. | 5031 // Constant for denoting that the LastAdded field was not yet set. |
5061 static const int kNoneAdded = LastAddedBits::kMax; | 5032 static const int kNoneAdded = LastAddedBits::kMax; |
5062 | 5033 |
5063 // Layout description. | 5034 // Layout description. |
5064 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 5035 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
5065 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 5036 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
5066 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; | 5037 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; |
5067 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; | 5038 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; |
5068 // Storage for instance descriptors is overloaded to also contain additional | 5039 // Storage for instance descriptors is overloaded to also contain additional |
Michael Starzinger
2012/08/07 13:55:05
These comments are completely outdated.
Toon Verwaest
2012/08/10 12:32:52
Done.
| |
5069 // map flags when unused (bit_field3). When the map has instance descriptors, | 5040 // map flags when unused (bit_field3). When the map has instance descriptors, |
5070 // the flags are transferred to the instance descriptor array and accessed | 5041 // the flags are transferred to the instance descriptor array and accessed |
5071 // through an extra indirection. | 5042 // through an extra indirection. |
5072 static const int kInstanceDescriptorsOrBackPointerOffset = | 5043 static const int kTransitionsOrBackPointerOffset = |
5073 kConstructorOffset + kPointerSize; | 5044 kConstructorOffset + kPointerSize; |
5074 static const int kCodeCacheOffset = | 5045 static const int kCodeCacheOffset = |
5075 kInstanceDescriptorsOrBackPointerOffset + kPointerSize; | 5046 kTransitionsOrBackPointerOffset + kPointerSize; |
5076 static const int kBitField3Offset = kCodeCacheOffset + kPointerSize; | 5047 static const int kBitField3Offset = kCodeCacheOffset + kPointerSize; |
5077 static const int kPadStart = kBitField3Offset + kPointerSize; | 5048 static const int kPadStart = kBitField3Offset + kPointerSize; |
5078 static const int kSize = MAP_POINTER_ALIGN(kPadStart); | 5049 static const int kSize = MAP_POINTER_ALIGN(kPadStart); |
5079 | 5050 |
5080 // Layout of pointer fields. Heap iteration code relies on them | 5051 // Layout of pointer fields. Heap iteration code relies on them |
5081 // being continuously allocated. | 5052 // being continuously allocated. |
5082 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; | 5053 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; |
5083 static const int kPointerFieldsEndOffset = kBitField3Offset + kPointerSize; | 5054 static const int kPointerFieldsEndOffset = kBitField3Offset + kPointerSize; |
5084 | 5055 |
5085 // Byte offsets within kInstanceSizesOffset. | 5056 // Byte offsets within kInstanceSizesOffset. |
(...skipping 3824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8910 } else { | 8881 } else { |
8911 value &= ~(1 << bit_position); | 8882 value &= ~(1 << bit_position); |
8912 } | 8883 } |
8913 return value; | 8884 return value; |
8914 } | 8885 } |
8915 }; | 8886 }; |
8916 | 8887 |
8917 } } // namespace v8::internal | 8888 } } // namespace v8::internal |
8918 | 8889 |
8919 #endif // V8_OBJECTS_H_ | 8890 #endif // V8_OBJECTS_H_ |
OLD | NEW |