Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(779)

Side by Side Diff: src/objects.h

Issue 10816005: Swapped transition array and descriptor array. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments, and updated additional code comments. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 // - DescriptorArray 77 // - DescriptorArray
78 // - HashTable 78 // - HashTable
79 // - Dictionary 79 // - Dictionary
80 // - SymbolTable 80 // - SymbolTable
81 // - CompilationCacheTable 81 // - CompilationCacheTable
82 // - CodeCacheHashTable 82 // - CodeCacheHashTable
83 // - MapCache 83 // - MapCache
84 // - Context 84 // - Context
85 // - JSFunctionResultCache 85 // - JSFunctionResultCache
86 // - ScopeInfo 86 // - ScopeInfo
87 // - TransitionArray
87 // - FixedDoubleArray 88 // - FixedDoubleArray
88 // - ExternalArray 89 // - ExternalArray
89 // - ExternalPixelArray 90 // - ExternalPixelArray
90 // - ExternalByteArray 91 // - ExternalByteArray
91 // - ExternalUnsignedByteArray 92 // - ExternalUnsignedByteArray
92 // - ExternalShortArray 93 // - ExternalShortArray
93 // - ExternalUnsignedShortArray 94 // - ExternalUnsignedShortArray
94 // - ExternalIntArray 95 // - ExternalIntArray
95 // - ExternalUnsignedIntArray 96 // - ExternalUnsignedIntArray
96 // - ExternalFloatArray 97 // - ExternalFloatArray
(...skipping 2354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 void FixedDoubleArrayVerify(); 2452 void FixedDoubleArrayVerify();
2452 #endif 2453 #endif
2453 2454
2454 private: 2455 private:
2455 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray); 2456 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
2456 }; 2457 };
2457 2458
2458 2459
2459 // DescriptorArrays are fixed arrays used to hold instance descriptors. 2460 // DescriptorArrays are fixed arrays used to hold instance descriptors.
2460 // The format of the these objects is: 2461 // The format of the these objects is:
2461 // TODO(1399): It should be possible to make room for bit_field3 in the map 2462 // [0]: Either Smi(0) if uninitialized, or a pointer to small fixed array:
2462 // without overloading the instance descriptors field in the map 2463 // [0]: pointer to fixed array with enum cache
2463 // (and storing it in the DescriptorArray when the map has one). 2464 // [1]: either Smi(0) or pointer to fixed array with indices
2464 // [0]: storage for bit_field3 for Map owning this object (Smi) 2465 // [1]: first key
2465 // [1]: point to a fixed array with (value, detail) pairs.
2466 // [2]: next enumeration index (Smi), or pointer to small fixed array:
2467 // [0]: next enumeration index (Smi)
2468 // [1]: pointer to fixed array with enum cache
2469 // [3]: first key
2470 // [length() - kDescriptorSize]: last key 2466 // [length() - kDescriptorSize]: last key
2471 //
2472 class DescriptorArray: public FixedArray { 2467 class DescriptorArray: public FixedArray {
2473 public: 2468 public:
2474 // Returns true for both shared empty_descriptor_array and for smis, which the 2469 // 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 2470 // map uses to encode additional bit fields when the descriptor array is not
2476 // yet used. 2471 // yet used.
2477 inline bool IsEmpty(); 2472 inline bool IsEmpty();
2478 inline bool MayContainTransitions();
2479 inline bool HasTransitionArray();
2480
2481 DECL_ACCESSORS(transitions, TransitionArray)
2482 inline void ClearTransitions();
2483 2473
2484 // Returns the number of descriptors in the array. 2474 // Returns the number of descriptors in the array.
2485 int number_of_descriptors() { 2475 int number_of_descriptors() {
2486 ASSERT(MayContainTransitions() || IsEmpty()); 2476 ASSERT(length() >= kFirstIndex || IsEmpty());
2487 int len = length(); 2477 int len = length();
2488 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; 2478 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize;
2489 } 2479 }
2490 2480
2491 inline int number_of_entries() { return number_of_descriptors(); } 2481 inline int number_of_entries() { return number_of_descriptors(); }
2492 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } 2482 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; }
2493 2483
2494 bool HasEnumCache() { 2484 bool HasEnumCache() {
2495 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); 2485 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi();
2496 } 2486 }
2497 2487
2498 Object* GetEnumCache() { 2488 Object* GetEnumCache() {
2499 ASSERT(HasEnumCache()); 2489 ASSERT(HasEnumCache());
2500 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); 2490 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex));
2501 return bridge->get(kEnumCacheBridgeCacheIndex); 2491 return bridge->get(kEnumCacheBridgeCacheIndex);
2502 } 2492 }
2503 2493
2504 Object** GetEnumCacheSlot() { 2494 Object** GetEnumCacheSlot() {
2505 ASSERT(HasEnumCache()); 2495 ASSERT(HasEnumCache());
2506 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), 2496 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2507 kEnumCacheOffset); 2497 kEnumCacheOffset);
2508 } 2498 }
2509 2499
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, 2500 // Initialize or change the enum cache,
2518 // using the supplied storage for the small "bridge". 2501 // using the supplied storage for the small "bridge".
2519 void SetEnumCache(FixedArray* bridge_storage, 2502 void SetEnumCache(FixedArray* bridge_storage,
2520 FixedArray* new_cache, 2503 FixedArray* new_cache,
2521 Object* new_index_cache); 2504 Object* new_index_cache);
2522 2505
2523 // Accessors for fetching instance descriptor at descriptor number. 2506 // Accessors for fetching instance descriptor at descriptor number.
2524 inline String* GetKey(int descriptor_number); 2507 inline String* GetKey(int descriptor_number);
2525 inline Object** GetKeySlot(int descriptor_number); 2508 inline Object** GetKeySlot(int descriptor_number);
2526 inline Object* GetValue(int descriptor_number); 2509 inline Object* GetValue(int descriptor_number);
(...skipping 17 matching lines...) Expand all
2544 const WhitenessWitness&, 2527 const WhitenessWitness&,
2545 int number_of_set_descriptors); 2528 int number_of_set_descriptors);
2546 2529
2547 // Transfer a complete descriptor from the src descriptor array to this 2530 // Transfer a complete descriptor from the src descriptor array to this
2548 // descriptor array. 2531 // descriptor array.
2549 void CopyFrom(int dst_index, 2532 void CopyFrom(int dst_index,
2550 DescriptorArray* src, 2533 DescriptorArray* src,
2551 int src_index, 2534 int src_index,
2552 const WhitenessWitness&); 2535 const WhitenessWitness&);
2553 2536
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. 2537 // Sort the instance descriptors by the hash codes of their keys.
2566 void Sort(const WhitenessWitness&); 2538 void Sort(const WhitenessWitness&);
2567 2539
2568 // Search the instance descriptors for given name. 2540 // Search the instance descriptors for given name.
2569 INLINE(int Search(String* name)); 2541 INLINE(int Search(String* name));
2570 2542
2571 // As the above, but uses DescriptorLookupCache and updates it when 2543 // As the above, but uses DescriptorLookupCache and updates it when
2572 // necessary. 2544 // necessary.
2573 INLINE(int SearchWithCache(String* name)); 2545 INLINE(int SearchWithCache(String* name));
2574 2546
2575 // Tells whether the name is present int the array. 2547 // Tells whether the name is present int the array.
2576 bool Contains(String* name) { return kNotFound != Search(name); } 2548 bool Contains(String* name) { return kNotFound != Search(name); }
2577 2549
2578 // Allocates a DescriptorArray, but returns the singleton 2550 // Allocates a DescriptorArray, but returns the singleton
2579 // empty descriptor array object if number_of_descriptors is 0. 2551 // empty descriptor array object if number_of_descriptors is 0.
2580 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, 2552 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors);
2581 SharedMode shared_mode);
2582 2553
2583 // Casting. 2554 // Casting.
2584 static inline DescriptorArray* cast(Object* obj); 2555 static inline DescriptorArray* cast(Object* obj);
2585 2556
2586 // Constant for denoting key was not found. 2557 // Constant for denoting key was not found.
2587 static const int kNotFound = -1; 2558 static const int kNotFound = -1;
2588 2559
2589 static const int kBackPointerStorageIndex = 0; 2560 static const int kEnumCacheIndex = 0;
2590 static const int kEnumCacheIndex = 1; 2561 static const int kFirstIndex = 1;
2591 static const int kTransitionsIndex = 2;
2592 static const int kFirstIndex = 3;
2593 2562
2594 // The length of the "bridge" to the enum cache. 2563 // The length of the "bridge" to the enum cache.
2595 static const int kEnumCacheBridgeLength = 2; 2564 static const int kEnumCacheBridgeLength = 2;
2596 static const int kEnumCacheBridgeCacheIndex = 0; 2565 static const int kEnumCacheBridgeCacheIndex = 0;
2597 static const int kEnumCacheBridgeIndicesCacheIndex = 1; 2566 static const int kEnumCacheBridgeIndicesCacheIndex = 1;
2598 2567
2599 // Layout description. 2568 // Layout description.
2600 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; 2569 static const int kEnumCacheOffset = FixedArray::kHeaderSize;
2601 static const int kEnumCacheOffset = kBackPointerStorageOffset + 2570 static const int kFirstOffset = kEnumCacheOffset + kPointerSize;
2602 kPointerSize;
2603 static const int kTransitionsOffset = kEnumCacheOffset + kPointerSize;
2604 static const int kFirstOffset = kTransitionsOffset + kPointerSize;
2605 2571
2606 // Layout description for the bridge array. 2572 // Layout description for the bridge array.
2607 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize; 2573 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize;
2608 2574
2609 // Layout of descriptor. 2575 // Layout of descriptor.
2610 static const int kDescriptorKey = 0; 2576 static const int kDescriptorKey = 0;
2611 static const int kDescriptorDetails = 1; 2577 static const int kDescriptorDetails = 1;
2612 static const int kDescriptorValue = 2; 2578 static const int kDescriptorValue = 2;
2613 static const int kDescriptorSize = 3; 2579 static const int kDescriptorSize = 3;
2614 2580
(...skipping 2176 matching lines...) Expand 10 before | Expand all | Expand 10 after
4791 } 4757 }
4792 4758
4793 static bool IsValidElementsTransition(ElementsKind from_kind, 4759 static bool IsValidElementsTransition(ElementsKind from_kind,
4794 ElementsKind to_kind); 4760 ElementsKind to_kind);
4795 4761
4796 inline bool HasTransitionArray(); 4762 inline bool HasTransitionArray();
4797 inline bool HasElementsTransition(); 4763 inline bool HasElementsTransition();
4798 inline Map* elements_transition_map(); 4764 inline Map* elements_transition_map();
4799 MUST_USE_RESULT inline MaybeObject* set_elements_transition_map( 4765 MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
4800 Map* transitioned_map); 4766 Map* transitioned_map);
4801 inline TransitionArray* transitions();
4802 inline void SetTransition(int index, Map* target); 4767 inline void SetTransition(int index, Map* target);
4803 MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target); 4768 MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target);
4804 MUST_USE_RESULT inline MaybeObject* set_transitions( 4769 DECL_ACCESSORS(transitions, TransitionArray)
4805 TransitionArray* transitions);
4806 inline void ClearTransitions(Heap* heap, 4770 inline void ClearTransitions(Heap* heap,
4807 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); 4771 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
4808 4772
4809 // Tells whether the map is attached to SharedFunctionInfo 4773 // Tells whether the map is attached to SharedFunctionInfo
4810 // (for inobject slack tracking). 4774 // (for inobject slack tracking).
4811 inline void set_attached_to_shared_function_info(bool value); 4775 inline void set_attached_to_shared_function_info(bool value);
4812 4776
4813 inline bool attached_to_shared_function_info(); 4777 inline bool attached_to_shared_function_info();
4814 4778
4815 // Tells whether the map is shared between objects that may have different 4779 // 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 4780 // behavior. If true, the map should never be modified, instead a clone
4817 // should be created and modified. 4781 // should be created and modified.
4818 inline void set_is_shared(bool value); 4782 inline void set_is_shared(bool value);
4819 inline bool is_shared(); 4783 inline bool is_shared();
4820 4784
4821 // Tells whether the instance needs security checks when accessing its 4785 // Tells whether the instance needs security checks when accessing its
4822 // properties. 4786 // properties.
4823 inline void set_is_access_check_needed(bool access_check_needed); 4787 inline void set_is_access_check_needed(bool access_check_needed);
4824 inline bool is_access_check_needed(); 4788 inline bool is_access_check_needed();
4825 4789
4826 // [prototype]: implicit prototype object. 4790 // [prototype]: implicit prototype object.
4827 DECL_ACCESSORS(prototype, Object) 4791 DECL_ACCESSORS(prototype, Object)
4828 4792
4829 // [constructor]: points back to the function responsible for this map. 4793 // [constructor]: points back to the function responsible for this map.
4830 DECL_ACCESSORS(constructor, Object) 4794 DECL_ACCESSORS(constructor, Object)
4831 4795
4832 inline JSFunction* unchecked_constructor(); 4796 inline JSFunction* unchecked_constructor();
4833 4797
4834 // [instance descriptors]: describes the object. 4798 // [instance descriptors]: describes the object.
4835 DECL_ACCESSORS(instance_descriptors, DescriptorArray) 4799 inline DescriptorArray* instance_descriptors();
4836 inline void InitializeDescriptors(DescriptorArray* descriptors); 4800 MUST_USE_RESULT inline MaybeObject* SetDescriptors(
4837 4801 DescriptorArray* descriptors,
4838 // Should only be called to clear a descriptor array that was only used to 4802 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
4839 // store transitions and does not contain any live transitions anymore. 4803 static void SetDescriptors(Handle<Map> map,
4840 inline void ClearDescriptorArray(Heap* heap, WriteBarrierMode mode); 4804 Handle<DescriptorArray> descriptors);
4805 MUST_USE_RESULT inline MaybeObject* InitializeDescriptors(
4806 DescriptorArray* descriptors);
4841 4807
4842 // [stub cache]: contains stubs compiled for this map. 4808 // [stub cache]: contains stubs compiled for this map.
4843 DECL_ACCESSORS(code_cache, Object) 4809 DECL_ACCESSORS(code_cache, Object)
4844 4810
4845 // [back pointer]: points back to the parent map from which a transition 4811 // [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 4812 // leads to this map. The field overlaps with prototype transitions and the
4847 // back pointer will be moved into the prototype transitions array if 4813 // back pointer will be moved into the prototype transitions array if
4848 // required. 4814 // required.
4849 inline Object* GetBackPointer(); 4815 inline Object* GetBackPointer();
4850 inline void SetBackPointer(Object* value, 4816 inline void SetBackPointer(Object* value,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
4936 TransitionFlag flag); 4902 TransitionFlag flag);
4937 4903
4938 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, 4904 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode,
4939 NormalizedMapSharingMode sharing); 4905 NormalizedMapSharingMode sharing);
4940 4906
4941 inline void AppendDescriptor(Descriptor* desc, 4907 inline void AppendDescriptor(Descriptor* desc,
4942 const DescriptorArray::WhitenessWitness&); 4908 const DescriptorArray::WhitenessWitness&);
4943 4909
4944 // Returns a copy of the map, with all transitions dropped from the 4910 // Returns a copy of the map, with all transitions dropped from the
4945 // instance descriptors. 4911 // instance descriptors.
4946 MUST_USE_RESULT MaybeObject* Copy(DescriptorArray::SharedMode shared_mode); 4912 MUST_USE_RESULT MaybeObject* Copy();
4947 4913
4948 // Returns the property index for name (only valid for FAST MODE). 4914 // Returns the property index for name (only valid for FAST MODE).
4949 int PropertyIndexFor(String* name); 4915 int PropertyIndexFor(String* name);
4950 4916
4951 // Returns the next free property index (only valid for FAST MODE). 4917 // Returns the next free property index (only valid for FAST MODE).
4952 int NextFreePropertyIndex(); 4918 int NextFreePropertyIndex();
4953 4919
4954 // Returns the number of properties described in instance_descriptors 4920 // Returns the number of properties described in instance_descriptors
4955 // filtering out properties with the specified attributes. 4921 // filtering out properties with the specified attributes.
4956 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); 4922 int NumberOfDescribedProperties(PropertyAttributes filter = NONE);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
5058 static const int kMaxPreAllocatedPropertyFields = 255; 5024 static const int kMaxPreAllocatedPropertyFields = 255;
5059 5025
5060 // Constant for denoting that the LastAdded field was not yet set. 5026 // Constant for denoting that the LastAdded field was not yet set.
5061 static const int kNoneAdded = LastAddedBits::kMax; 5027 static const int kNoneAdded = LastAddedBits::kMax;
5062 5028
5063 // Layout description. 5029 // Layout description.
5064 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; 5030 static const int kInstanceSizesOffset = HeapObject::kHeaderSize;
5065 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; 5031 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize;
5066 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; 5032 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize;
5067 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; 5033 static const int kConstructorOffset = kPrototypeOffset + kPointerSize;
5068 // Storage for instance descriptors is overloaded to also contain additional 5034 // Storage for the transition array is overloaded to directly contain a back
5069 // map flags when unused (bit_field3). When the map has instance descriptors, 5035 // pointer if unused. When the map has transitions, the back pointer is
5070 // the flags are transferred to the instance descriptor array and accessed 5036 // transferred to the transition array and accessed through an extra
5071 // through an extra indirection. 5037 // indirection.
5072 static const int kInstanceDescriptorsOrBackPointerOffset = 5038 static const int kTransitionsOrBackPointerOffset =
5073 kConstructorOffset + kPointerSize; 5039 kConstructorOffset + kPointerSize;
5074 static const int kCodeCacheOffset = 5040 static const int kCodeCacheOffset =
5075 kInstanceDescriptorsOrBackPointerOffset + kPointerSize; 5041 kTransitionsOrBackPointerOffset + kPointerSize;
5076 static const int kBitField3Offset = kCodeCacheOffset + kPointerSize; 5042 static const int kBitField3Offset = kCodeCacheOffset + kPointerSize;
5077 static const int kPadStart = kBitField3Offset + kPointerSize; 5043 static const int kPadStart = kBitField3Offset + kPointerSize;
5078 static const int kSize = MAP_POINTER_ALIGN(kPadStart); 5044 static const int kSize = MAP_POINTER_ALIGN(kPadStart);
5079 5045
5080 // Layout of pointer fields. Heap iteration code relies on them 5046 // Layout of pointer fields. Heap iteration code relies on them
5081 // being continuously allocated. 5047 // being continuously allocated.
5082 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; 5048 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset;
5083 static const int kPointerFieldsEndOffset = kBitField3Offset + kPointerSize; 5049 static const int kPointerFieldsEndOffset = kBitField3Offset + kPointerSize;
5084 5050
5085 // Byte offsets within kInstanceSizesOffset. 5051 // Byte offsets within kInstanceSizesOffset.
(...skipping 3824 matching lines...) Expand 10 before | Expand all | Expand 10 after
8910 } else { 8876 } else {
8911 value &= ~(1 << bit_position); 8877 value &= ~(1 << bit_position);
8912 } 8878 }
8913 return value; 8879 return value;
8914 } 8880 }
8915 }; 8881 };
8916 8882
8917 } } // namespace v8::internal 8883 } } // namespace v8::internal
8918 8884
8919 #endif // V8_OBJECTS_H_ 8885 #endif // V8_OBJECTS_H_
OLDNEW
« src/bootstrapper.cc ('K') | « src/mark-compact.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698