Chromium Code Reviews| 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 |