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 2382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2393 // [1]: pointer to fixed array with enum cache | 2393 // [1]: pointer to fixed array with enum cache |
2394 // [3]: first key | 2394 // [3]: first key |
2395 // [length() - 1]: last key | 2395 // [length() - 1]: last key |
2396 // | 2396 // |
2397 class DescriptorArray: public FixedArray { | 2397 class DescriptorArray: public FixedArray { |
2398 public: | 2398 public: |
2399 // Returns true for both shared empty_descriptor_array and for smis, which the | 2399 // Returns true for both shared empty_descriptor_array and for smis, which the |
2400 // map uses to encode additional bit fields when the descriptor array is not | 2400 // map uses to encode additional bit fields when the descriptor array is not |
2401 // yet used. | 2401 // yet used. |
2402 inline bool IsEmpty(); | 2402 inline bool IsEmpty(); |
2403 inline bool MayContainTransitions(); | |
2404 | |
2405 DECL_ACCESSORS(elements_transition, Map) | |
danno
2012/06/01 13:49:55
probably should call this elements_transition_map
Toon Verwaest
2012/06/04 09:17:48
Done.
| |
2403 | 2406 |
2404 // Returns the number of descriptors in the array. | 2407 // Returns the number of descriptors in the array. |
2405 int number_of_descriptors() { | 2408 int number_of_descriptors() { |
2406 ASSERT(length() > kFirstIndex || IsEmpty()); | 2409 ASSERT(length() >= kFirstIndex || IsEmpty()); |
danno
2012/06/01 13:49:55
ASSERT(length() > kFirstIndex || length() == kTran
Toon Verwaest
2012/06/04 09:17:48
Done.
| |
2407 int len = length(); | 2410 int len = length(); |
2408 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; | 2411 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; |
2409 } | 2412 } |
2410 | 2413 |
2411 int NextEnumerationIndex() { | 2414 int NextEnumerationIndex() { |
2412 if (IsEmpty()) return PropertyDetails::kInitialIndex; | 2415 if (IsEmpty()) return PropertyDetails::kInitialIndex; |
2413 Object* obj = get(kEnumerationIndexIndex); | 2416 Object* obj = get(kEnumerationIndexIndex); |
2414 if (obj->IsSmi()) { | 2417 if (obj->IsSmi()) { |
2415 return Smi::cast(obj)->value(); | 2418 return Smi::cast(obj)->value(); |
2416 } else { | 2419 } else { |
(...skipping 17 matching lines...) Expand all Loading... | |
2434 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); | 2437 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); |
2435 return bridge->get(kEnumCacheBridgeCacheIndex); | 2438 return bridge->get(kEnumCacheBridgeCacheIndex); |
2436 } | 2439 } |
2437 | 2440 |
2438 Object** GetEnumCacheSlot() { | 2441 Object** GetEnumCacheSlot() { |
2439 ASSERT(HasEnumCache()); | 2442 ASSERT(HasEnumCache()); |
2440 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | 2443 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
2441 kEnumerationIndexOffset); | 2444 kEnumerationIndexOffset); |
2442 } | 2445 } |
2443 | 2446 |
2447 Object** GetTransitionsSlot() { | |
2448 ASSERT(elements_transition() != NULL); | |
2449 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | |
2450 kTransitionsOffset); | |
2451 } | |
2452 | |
2444 // TODO(1399): It should be possible to make room for bit_field3 in the map | 2453 // TODO(1399): It should be possible to make room for bit_field3 in the map |
2445 // without overloading the instance descriptors field in the map | 2454 // without overloading the instance descriptors field in the map |
2446 // (and storing it in the DescriptorArray when the map has one). | 2455 // (and storing it in the DescriptorArray when the map has one). |
2447 inline int bit_field3_storage(); | 2456 inline int bit_field3_storage(); |
2448 inline void set_bit_field3_storage(int value); | 2457 inline void set_bit_field3_storage(int value); |
2449 | 2458 |
2450 // Initialize or change the enum cache, | 2459 // Initialize or change the enum cache, |
2451 // using the supplied storage for the small "bridge". | 2460 // using the supplied storage for the small "bridge". |
2452 void SetEnumCache(FixedArray* bridge_storage, | 2461 void SetEnumCache(FixedArray* bridge_storage, |
2453 FixedArray* new_cache, | 2462 FixedArray* new_cache, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2512 // remove map transitions. If the descriptor is already present, it is | 2521 // remove map transitions. If the descriptor is already present, it is |
2513 // replaced. If a replaced descriptor is a real property (not a transition | 2522 // replaced. If a replaced descriptor is a real property (not a transition |
2514 // or null), its enumeration index is kept as is. | 2523 // or null), its enumeration index is kept as is. |
2515 // If adding a real property, map transitions must be removed. If adding | 2524 // If adding a real property, map transitions must be removed. If adding |
2516 // a transition, they must not be removed. All null descriptors are removed. | 2525 // a transition, they must not be removed. All null descriptors are removed. |
2517 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, | 2526 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, |
2518 TransitionFlag transition_flag); | 2527 TransitionFlag transition_flag); |
2519 | 2528 |
2520 // Return a copy of the array with all transitions and null descriptors | 2529 // Return a copy of the array with all transitions and null descriptors |
2521 // removed. Return a Failure object in case of an allocation failure. | 2530 // removed. Return a Failure object in case of an allocation failure. |
2522 MUST_USE_RESULT MaybeObject* RemoveTransitions(); | 2531 MUST_USE_RESULT MaybeObject* RemoveTransitions(bool mutable_transitions); |
2523 | 2532 |
2524 // Sort the instance descriptors by the hash codes of their keys. | 2533 // Sort the instance descriptors by the hash codes of their keys. |
2525 // Does not check for duplicates. | 2534 // Does not check for duplicates. |
2526 void SortUnchecked(const WhitenessWitness&); | 2535 void SortUnchecked(const WhitenessWitness&); |
2527 | 2536 |
2528 // Sort the instance descriptors by the hash codes of their keys. | 2537 // Sort the instance descriptors by the hash codes of their keys. |
2529 // Checks the result for duplicates. | 2538 // Checks the result for duplicates. |
2530 void Sort(const WhitenessWitness&); | 2539 void Sort(const WhitenessWitness&); |
2531 | 2540 |
2532 // Search the instance descriptors for given name. | 2541 // Search the instance descriptors for given name. |
(...skipping 12 matching lines...) Expand all Loading... | |
2545 // with low=0 and high=2. | 2554 // with low=0 and high=2. |
2546 int BinarySearch(String* name, int low, int high); | 2555 int BinarySearch(String* name, int low, int high); |
2547 | 2556 |
2548 // Perform a linear search in the instance descriptors represented | 2557 // Perform a linear search in the instance descriptors represented |
2549 // by this fixed array. len is the number of descriptor indices that are | 2558 // by this fixed array. len is the number of descriptor indices that are |
2550 // valid. Does not require the descriptors to be sorted. | 2559 // valid. Does not require the descriptors to be sorted. |
2551 int LinearSearch(String* name, int len); | 2560 int LinearSearch(String* name, int len); |
2552 | 2561 |
2553 // Allocates a DescriptorArray, but returns the singleton | 2562 // Allocates a DescriptorArray, but returns the singleton |
2554 // empty descriptor array object if number_of_descriptors is 0. | 2563 // empty descriptor array object if number_of_descriptors is 0. |
2555 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); | 2564 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, |
2565 bool mutable_transitions); | |
danno
2012/06/01 13:49:55
Turn this into an enum.
Toon Verwaest
2012/06/04 09:17:48
Done.
| |
2556 | 2566 |
2557 // Casting. | 2567 // Casting. |
2558 static inline DescriptorArray* cast(Object* obj); | 2568 static inline DescriptorArray* cast(Object* obj); |
2559 | 2569 |
2560 // Constant for denoting key was not found. | 2570 // Constant for denoting key was not found. |
2561 static const int kNotFound = -1; | 2571 static const int kNotFound = -1; |
2562 | 2572 |
2563 static const int kBitField3StorageIndex = 0; | 2573 static const int kBitField3StorageIndex = 0; |
2564 static const int kEnumerationIndexIndex = 1; | 2574 static const int kTransitionsIndex = 1; |
2565 static const int kFirstIndex = 2; | 2575 static const int kEnumerationIndexIndex = 2; |
2576 static const int kFirstIndex = 3; | |
2566 | 2577 |
2567 // The length of the "bridge" to the enum cache. | 2578 // The length of the "bridge" to the enum cache. |
2568 static const int kEnumCacheBridgeLength = 3; | 2579 static const int kEnumCacheBridgeLength = 3; |
2569 static const int kEnumCacheBridgeEnumIndex = 0; | 2580 static const int kEnumCacheBridgeEnumIndex = 0; |
2570 static const int kEnumCacheBridgeCacheIndex = 1; | 2581 static const int kEnumCacheBridgeCacheIndex = 1; |
2571 static const int kEnumCacheBridgeIndicesCacheIndex = 2; | 2582 static const int kEnumCacheBridgeIndicesCacheIndex = 2; |
2572 | 2583 |
2573 // Layout description. | 2584 // Layout description. |
2574 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; | 2585 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; |
2575 static const int kEnumerationIndexOffset = kBitField3StorageOffset + | 2586 static const int kTransitionsOffset = kBitField3StorageOffset + kPointerSize; |
2576 kPointerSize; | 2587 static const int kEnumerationIndexOffset = kTransitionsOffset + kPointerSize; |
2577 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; | 2588 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; |
2578 | 2589 |
2579 // Layout description for the bridge array. | 2590 // Layout description for the bridge array. |
2580 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; | 2591 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; |
2581 static const int kEnumCacheBridgeCacheOffset = | 2592 static const int kEnumCacheBridgeCacheOffset = |
2582 kEnumCacheBridgeEnumOffset + kPointerSize; | 2593 kEnumCacheBridgeEnumOffset + kPointerSize; |
2583 | 2594 |
2584 // Layout of descriptor. | 2595 // Layout of descriptor. |
2585 static const int kDescriptorKey = 0; | 2596 static const int kDescriptorKey = 0; |
2586 static const int kDescriptorDetails = 1; | 2597 static const int kDescriptorDetails = 1; |
(...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4672 } | 4683 } |
4673 | 4684 |
4674 inline bool has_slow_elements_kind() { | 4685 inline bool has_slow_elements_kind() { |
4675 return elements_kind() == DICTIONARY_ELEMENTS | 4686 return elements_kind() == DICTIONARY_ELEMENTS |
4676 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; | 4687 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; |
4677 } | 4688 } |
4678 | 4689 |
4679 static bool IsValidElementsTransition(ElementsKind from_kind, | 4690 static bool IsValidElementsTransition(ElementsKind from_kind, |
4680 ElementsKind to_kind); | 4691 ElementsKind to_kind); |
4681 | 4692 |
4693 inline Map* elements_transition(); | |
4694 inline void set_elements_transition(Map* transitioned_map); | |
4695 | |
4682 // Tells whether the map is attached to SharedFunctionInfo | 4696 // Tells whether the map is attached to SharedFunctionInfo |
4683 // (for inobject slack tracking). | 4697 // (for inobject slack tracking). |
4684 inline void set_attached_to_shared_function_info(bool value); | 4698 inline void set_attached_to_shared_function_info(bool value); |
4685 | 4699 |
4686 inline bool attached_to_shared_function_info(); | 4700 inline bool attached_to_shared_function_info(); |
4687 | 4701 |
4688 // Tells whether the map is shared between objects that may have different | 4702 // Tells whether the map is shared between objects that may have different |
4689 // behavior. If true, the map should never be modified, instead a clone | 4703 // behavior. If true, the map should never be modified, instead a clone |
4690 // should be created and modified. | 4704 // should be created and modified. |
4691 inline void set_is_shared(bool value); | 4705 inline void set_is_shared(bool value); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4768 String* name, | 4782 String* name, |
4769 LookupResult* result); | 4783 LookupResult* result); |
4770 | 4784 |
4771 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); | 4785 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); |
4772 | 4786 |
4773 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, | 4787 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, |
4774 NormalizedMapSharingMode sharing); | 4788 NormalizedMapSharingMode sharing); |
4775 | 4789 |
4776 // Returns a copy of the map, with all transitions dropped from the | 4790 // Returns a copy of the map, with all transitions dropped from the |
4777 // instance descriptors. | 4791 // instance descriptors. |
4778 MUST_USE_RESULT MaybeObject* CopyDropTransitions(); | 4792 MUST_USE_RESULT MaybeObject* CopyDropTransitions(bool mutable_transitions); |
danno
2012/06/01 13:49:55
Enum instead of bool
Toon Verwaest
2012/06/04 09:17:48
Done.
| |
4779 | 4793 |
4780 // Returns the property index for name (only valid for FAST MODE). | 4794 // Returns the property index for name (only valid for FAST MODE). |
4781 int PropertyIndexFor(String* name); | 4795 int PropertyIndexFor(String* name); |
4782 | 4796 |
4783 // Returns the next free property index (only valid for FAST MODE). | 4797 // Returns the next free property index (only valid for FAST MODE). |
4784 int NextFreePropertyIndex(); | 4798 int NextFreePropertyIndex(); |
4785 | 4799 |
4786 // Returns the number of properties described in instance_descriptors | 4800 // Returns the number of properties described in instance_descriptors |
4787 // filtering out properties with the specified attributes. | 4801 // filtering out properties with the specified attributes. |
4788 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); | 4802 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4821 | 4835 |
4822 // Computes a hash value for this map, to be used in HashTables and such. | 4836 // Computes a hash value for this map, to be used in HashTables and such. |
4823 int Hash(); | 4837 int Hash(); |
4824 | 4838 |
4825 // Compares this map to another to see if they describe equivalent objects. | 4839 // Compares this map to another to see if they describe equivalent objects. |
4826 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if | 4840 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if |
4827 // it had exactly zero inobject properties. | 4841 // it had exactly zero inobject properties. |
4828 // The "shared" flags of both this map and |other| are ignored. | 4842 // The "shared" flags of both this map and |other| are ignored. |
4829 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); | 4843 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); |
4830 | 4844 |
4831 // Returns the contents of this map's descriptor array for the given string. | |
4832 // May return NULL. |safe_to_add_transition| is set to false and NULL | |
4833 // is returned if adding transitions is not allowed. | |
4834 Object* GetDescriptorContents(String* sentinel_name, | |
4835 bool* safe_to_add_transitions); | |
4836 | |
4837 // Returns the map that this map transitions to if its elements_kind | 4845 // Returns the map that this map transitions to if its elements_kind |
4838 // is changed to |elements_kind|, or NULL if no such map is cached yet. | 4846 // is changed to |elements_kind|, or NULL if no such map is cached yet. |
4839 // |safe_to_add_transitions| is set to false if adding transitions is not | 4847 // |safe_to_add_transitions| is set to false if adding transitions is not |
4840 // allowed. | 4848 // allowed. |
4841 Map* LookupElementsTransitionMap(ElementsKind elements_kind, | 4849 Map* LookupElementsTransitionMap(ElementsKind elements_kind); |
4842 bool* safe_to_add_transition); | |
4843 | 4850 |
4844 // Adds an entry to this map's descriptor array for a transition to | 4851 // Adds a new transitions for changing the elements kind to |elements_kind|. |
4845 // |transitioned_map| when its elements_kind is changed to |elements_kind|. | 4852 MUST_USE_RESULT MaybeObject* CreateNextElementsTransition( |
4846 MUST_USE_RESULT MaybeObject* AddElementsTransition( | 4853 ElementsKind elements_kind); |
4847 ElementsKind elements_kind, Map* transitioned_map); | |
4848 | 4854 |
4849 // Returns the transitioned map for this map with the most generic | 4855 // Returns the transitioned map for this map with the most generic |
4850 // elements_kind that's found in |candidates|, or null handle if no match is | 4856 // elements_kind that's found in |candidates|, or null handle if no match is |
4851 // found at all. | 4857 // found at all. |
4852 Handle<Map> FindTransitionedMap(MapHandleList* candidates); | 4858 Handle<Map> FindTransitionedMap(MapHandleList* candidates); |
4853 Map* FindTransitionedMap(MapList* candidates); | 4859 Map* FindTransitionedMap(MapList* candidates); |
4854 | 4860 |
4855 // Zaps the contents of backing data structures in debug mode. Note that the | 4861 // Zaps the contents of backing data structures in debug mode. Note that the |
4856 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects | 4862 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects |
4857 // holding weak references when incremental marking is used, because it also | 4863 // holding weak references when incremental marking is used, because it also |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4979 // Layout of the default cache. It holds alternating name and code objects. | 4985 // Layout of the default cache. It holds alternating name and code objects. |
4980 static const int kCodeCacheEntrySize = 2; | 4986 static const int kCodeCacheEntrySize = 2; |
4981 static const int kCodeCacheEntryNameOffset = 0; | 4987 static const int kCodeCacheEntryNameOffset = 0; |
4982 static const int kCodeCacheEntryCodeOffset = 1; | 4988 static const int kCodeCacheEntryCodeOffset = 1; |
4983 | 4989 |
4984 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset, | 4990 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset, |
4985 kPointerFieldsEndOffset, | 4991 kPointerFieldsEndOffset, |
4986 kSize> BodyDescriptor; | 4992 kSize> BodyDescriptor; |
4987 | 4993 |
4988 private: | 4994 private: |
4989 String* elements_transition_sentinel_name(); | |
4990 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); | 4995 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); |
4991 }; | 4996 }; |
4992 | 4997 |
4993 | 4998 |
4994 // An abstract superclass, a marker class really, for simple structure classes. | 4999 // An abstract superclass, a marker class really, for simple structure classes. |
4995 // It doesn't carry much functionality but allows struct classes to be | 5000 // It doesn't carry much functionality but allows struct classes to be |
4996 // identified in the type system. | 5001 // identified in the type system. |
4997 class Struct: public HeapObject { | 5002 class Struct: public HeapObject { |
4998 public: | 5003 public: |
4999 inline void InitializeBody(int object_size); | 5004 inline void InitializeBody(int object_size); |
(...skipping 3675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8675 } else { | 8680 } else { |
8676 value &= ~(1 << bit_position); | 8681 value &= ~(1 << bit_position); |
8677 } | 8682 } |
8678 return value; | 8683 return value; |
8679 } | 8684 } |
8680 }; | 8685 }; |
8681 | 8686 |
8682 } } // namespace v8::internal | 8687 } } // namespace v8::internal |
8683 | 8688 |
8684 #endif // V8_OBJECTS_H_ | 8689 #endif // V8_OBJECTS_H_ |
OLD | NEW |