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

Side by Side Diff: src/objects.h

Issue 10444055: Promoting elements transitions to their own field. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: handling danno's comments Created 8 years, 6 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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 }; 162 };
163 163
164 164
165 // Indicates whether a get method should implicitly create the object looked up. 165 // Indicates whether a get method should implicitly create the object looked up.
166 enum CreationFlag { 166 enum CreationFlag {
167 ALLOW_CREATION, 167 ALLOW_CREATION,
168 OMIT_CREATION 168 OMIT_CREATION
169 }; 169 };
170 170
171 171
172 // Indicates whether the search function should expect a sorted or an unsorted
173 // descriptor array as input.
174 enum SearchMode {
danno 2012/06/04 13:52:13 Since this is specific to Descriptor Arrays, consi
Toon Verwaest 2012/06/04 15:03:20 Done.
175 EXPECT_SORTED,
176 EXPECT_UNSORTED
177 };
178
179
180 // Indicates whether the search function should expect a sorted or an unsorted
181 // descriptor array as input.
182 enum SharedMode {
183 MAYBE_SHARED,
danno 2012/06/04 13:52:13 MAY_BE_SHARED
Toon Verwaest 2012/06/04 15:03:20 Done.
184 FORCE_NEW
danno 2012/06/04 13:52:13 Either make this CANNOT_BE_SHARED, or, since this
Toon Verwaest 2012/06/04 15:03:20 Done.
185 };
186
187
172 // Instance size sentinel for objects of variable size. 188 // Instance size sentinel for objects of variable size.
173 const int kVariableSizeSentinel = 0; 189 const int kVariableSizeSentinel = 0;
174 190
175 191
176 // All Maps have a field instance_type containing a InstanceType. 192 // All Maps have a field instance_type containing a InstanceType.
177 // It describes the type of the instances. 193 // It describes the type of the instances.
178 // 194 //
179 // As an example, a JavaScript object is a heap object and its map 195 // As an example, a JavaScript object is a heap object and its map
180 // instance_type is JS_OBJECT_TYPE. 196 // instance_type is JS_OBJECT_TYPE.
181 // 197 //
(...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after
2391 // [1]: pointer to fixed array with enum cache 2407 // [1]: pointer to fixed array with enum cache
2392 // [3]: first key 2408 // [3]: first key
2393 // [length() - 1]: last key 2409 // [length() - 1]: last key
2394 // 2410 //
2395 class DescriptorArray: public FixedArray { 2411 class DescriptorArray: public FixedArray {
2396 public: 2412 public:
2397 // Returns true for both shared empty_descriptor_array and for smis, which the 2413 // Returns true for both shared empty_descriptor_array and for smis, which the
2398 // map uses to encode additional bit fields when the descriptor array is not 2414 // map uses to encode additional bit fields when the descriptor array is not
2399 // yet used. 2415 // yet used.
2400 inline bool IsEmpty(); 2416 inline bool IsEmpty();
2417 inline bool MayContainTransitions();
2418
2419 DECL_ACCESSORS(elements_transition_map, Map)
2401 2420
2402 // Returns the number of descriptors in the array. 2421 // Returns the number of descriptors in the array.
2403 int number_of_descriptors() { 2422 int number_of_descriptors() {
2404 ASSERT(length() > kFirstIndex || IsEmpty()); 2423 ASSERT(length() > kFirstIndex ||
2424 length() == kTransitionsIndex ||
2425 IsEmpty());
2405 int len = length(); 2426 int len = length();
2406 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; 2427 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize;
2407 } 2428 }
2408 2429
2409 int NextEnumerationIndex() { 2430 int NextEnumerationIndex() {
2410 if (IsEmpty()) return PropertyDetails::kInitialIndex; 2431 if (IsEmpty()) return PropertyDetails::kInitialIndex;
2411 Object* obj = get(kEnumerationIndexIndex); 2432 Object* obj = get(kEnumerationIndexIndex);
2412 if (obj->IsSmi()) { 2433 if (obj->IsSmi()) {
2413 return Smi::cast(obj)->value(); 2434 return Smi::cast(obj)->value();
2414 } else { 2435 } else {
(...skipping 17 matching lines...) Expand all
2432 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); 2453 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex));
2433 return bridge->get(kEnumCacheBridgeCacheIndex); 2454 return bridge->get(kEnumCacheBridgeCacheIndex);
2434 } 2455 }
2435 2456
2436 Object** GetEnumCacheSlot() { 2457 Object** GetEnumCacheSlot() {
2437 ASSERT(HasEnumCache()); 2458 ASSERT(HasEnumCache());
2438 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), 2459 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2439 kEnumerationIndexOffset); 2460 kEnumerationIndexOffset);
2440 } 2461 }
2441 2462
2463 Object** GetTransitionsSlot() {
2464 ASSERT(elements_transition_map() != NULL);
2465 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2466 kTransitionsOffset);
2467 }
2468
2442 // TODO(1399): It should be possible to make room for bit_field3 in the map 2469 // TODO(1399): It should be possible to make room for bit_field3 in the map
2443 // without overloading the instance descriptors field in the map 2470 // without overloading the instance descriptors field in the map
2444 // (and storing it in the DescriptorArray when the map has one). 2471 // (and storing it in the DescriptorArray when the map has one).
2445 inline int bit_field3_storage(); 2472 inline int bit_field3_storage();
2446 inline void set_bit_field3_storage(int value); 2473 inline void set_bit_field3_storage(int value);
2447 2474
2448 // Initialize or change the enum cache, 2475 // Initialize or change the enum cache,
2449 // using the supplied storage for the small "bridge". 2476 // using the supplied storage for the small "bridge".
2450 void SetEnumCache(FixedArray* bridge_storage, 2477 void SetEnumCache(FixedArray* bridge_storage,
2451 FixedArray* new_cache, 2478 FixedArray* new_cache,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2510 // remove map transitions. If the descriptor is already present, it is 2537 // remove map transitions. If the descriptor is already present, it is
2511 // replaced. If a replaced descriptor is a real property (not a transition 2538 // replaced. If a replaced descriptor is a real property (not a transition
2512 // or null), its enumeration index is kept as is. 2539 // or null), its enumeration index is kept as is.
2513 // If adding a real property, map transitions must be removed. If adding 2540 // If adding a real property, map transitions must be removed. If adding
2514 // a transition, they must not be removed. All null descriptors are removed. 2541 // a transition, they must not be removed. All null descriptors are removed.
2515 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, 2542 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor,
2516 TransitionFlag transition_flag); 2543 TransitionFlag transition_flag);
2517 2544
2518 // Return a copy of the array with all transitions and null descriptors 2545 // Return a copy of the array with all transitions and null descriptors
2519 // removed. Return a Failure object in case of an allocation failure. 2546 // removed. Return a Failure object in case of an allocation failure.
2520 MUST_USE_RESULT MaybeObject* RemoveTransitions(); 2547 MUST_USE_RESULT MaybeObject* RemoveTransitions(SharedMode shared_mode);
2521 2548
2522 // Sort the instance descriptors by the hash codes of their keys. 2549 // Sort the instance descriptors by the hash codes of their keys.
2523 // Does not check for duplicates. 2550 // Does not check for duplicates.
2524 void SortUnchecked(const WhitenessWitness&); 2551 void SortUnchecked(const WhitenessWitness&);
2525 2552
2526 // Sort the instance descriptors by the hash codes of their keys. 2553 // Sort the instance descriptors by the hash codes of their keys.
2527 // Checks the result for duplicates. 2554 // Checks the result for duplicates.
2528 void Sort(const WhitenessWitness&); 2555 void Sort(const WhitenessWitness&);
2529 2556
2530 // Search the instance descriptors for given name. 2557 // Search the instance descriptors for given name.
2531 inline int Search(String* name); 2558 inline int Search(String* name);
2532 2559
2533 // As the above, but uses DescriptorLookupCache and updates it when 2560 // As the above, but uses DescriptorLookupCache and updates it when
2534 // necessary. 2561 // necessary.
2535 inline int SearchWithCache(String* name); 2562 inline int SearchWithCache(String* name);
2536 2563
2537 // Tells whether the name is present int the array. 2564 // Tells whether the name is present int the array.
2538 bool Contains(String* name) { return kNotFound != Search(name); } 2565 bool Contains(String* name) { return kNotFound != Search(name); }
2539 2566
2540 // Perform a binary search in the instance descriptors represented 2567 // Perform a binary search in the instance descriptors represented
2541 // by this fixed array. low and high are descriptor indices. If there 2568 // by this fixed array. low and high are descriptor indices. If there
2542 // are three instance descriptors in this array it should be called 2569 // are three instance descriptors in this array it should be called
2543 // with low=0 and high=2. 2570 // with low=0 and high=2.
2544 int BinarySearch(String* name, int low, int high); 2571 int BinarySearch(String* name, int low, int high);
2545 2572
2546 // Perform a linear search in the instance descriptors represented 2573 // Perform a linear search in the instance descriptors represented
2547 // by this fixed array. len is the number of descriptor indices that are 2574 // by this fixed array. len is the number of descriptor indices that are
2548 // valid. Does not require the descriptors to be sorted. 2575 // valid.
2549 int LinearSearch(String* name, int len); 2576 int LinearSearch(SearchMode mode, String* name, int len);
2550 2577
2551 // Allocates a DescriptorArray, but returns the singleton 2578 // Allocates a DescriptorArray, but returns the singleton
2552 // empty descriptor array object if number_of_descriptors is 0. 2579 // empty descriptor array object if number_of_descriptors is 0.
2553 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); 2580 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors,
2581 SharedMode shared_mode);
2554 2582
2555 // Casting. 2583 // Casting.
2556 static inline DescriptorArray* cast(Object* obj); 2584 static inline DescriptorArray* cast(Object* obj);
2557 2585
2558 // Constant for denoting key was not found. 2586 // Constant for denoting key was not found.
2559 static const int kNotFound = -1; 2587 static const int kNotFound = -1;
2560 2588
2561 static const int kBitField3StorageIndex = 0; 2589 static const int kBitField3StorageIndex = 0;
2562 static const int kEnumerationIndexIndex = 1; 2590 static const int kTransitionsIndex = 1;
2563 static const int kFirstIndex = 2; 2591 static const int kEnumerationIndexIndex = 2;
2592 static const int kFirstIndex = 3;
2564 2593
2565 // The length of the "bridge" to the enum cache. 2594 // The length of the "bridge" to the enum cache.
2566 static const int kEnumCacheBridgeLength = 3; 2595 static const int kEnumCacheBridgeLength = 3;
2567 static const int kEnumCacheBridgeEnumIndex = 0; 2596 static const int kEnumCacheBridgeEnumIndex = 0;
2568 static const int kEnumCacheBridgeCacheIndex = 1; 2597 static const int kEnumCacheBridgeCacheIndex = 1;
2569 static const int kEnumCacheBridgeIndicesCacheIndex = 2; 2598 static const int kEnumCacheBridgeIndicesCacheIndex = 2;
2570 2599
2571 // Layout description. 2600 // Layout description.
2572 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; 2601 static const int kBitField3StorageOffset = FixedArray::kHeaderSize;
2573 static const int kEnumerationIndexOffset = kBitField3StorageOffset + 2602 static const int kTransitionsOffset = kBitField3StorageOffset + kPointerSize;
2574 kPointerSize; 2603 static const int kEnumerationIndexOffset = kTransitionsOffset + kPointerSize;
2575 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; 2604 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize;
2576 2605
2577 // Layout description for the bridge array. 2606 // Layout description for the bridge array.
2578 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; 2607 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize;
2579 static const int kEnumCacheBridgeCacheOffset = 2608 static const int kEnumCacheBridgeCacheOffset =
2580 kEnumCacheBridgeEnumOffset + kPointerSize; 2609 kEnumCacheBridgeEnumOffset + kPointerSize;
2581 2610
2582 // Layout of descriptor. 2611 // Layout of descriptor.
2583 static const int kDescriptorKey = 0; 2612 static const int kDescriptorKey = 0;
2584 static const int kDescriptorDetails = 1; 2613 static const int kDescriptorDetails = 1;
(...skipping 2085 matching lines...) Expand 10 before | Expand all | Expand 10 after
4670 } 4699 }
4671 4700
4672 inline bool has_slow_elements_kind() { 4701 inline bool has_slow_elements_kind() {
4673 return elements_kind() == DICTIONARY_ELEMENTS 4702 return elements_kind() == DICTIONARY_ELEMENTS
4674 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; 4703 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4675 } 4704 }
4676 4705
4677 static bool IsValidElementsTransition(ElementsKind from_kind, 4706 static bool IsValidElementsTransition(ElementsKind from_kind,
4678 ElementsKind to_kind); 4707 ElementsKind to_kind);
4679 4708
4709 inline Map* elements_transition_map();
4710 inline void set_elements_transition_map(Map* transitioned_map);
4711
4680 // Tells whether the map is attached to SharedFunctionInfo 4712 // Tells whether the map is attached to SharedFunctionInfo
4681 // (for inobject slack tracking). 4713 // (for inobject slack tracking).
4682 inline void set_attached_to_shared_function_info(bool value); 4714 inline void set_attached_to_shared_function_info(bool value);
4683 4715
4684 inline bool attached_to_shared_function_info(); 4716 inline bool attached_to_shared_function_info();
4685 4717
4686 // Tells whether the map is shared between objects that may have different 4718 // Tells whether the map is shared between objects that may have different
4687 // behavior. If true, the map should never be modified, instead a clone 4719 // behavior. If true, the map should never be modified, instead a clone
4688 // should be created and modified. 4720 // should be created and modified.
4689 inline void set_is_shared(bool value); 4721 inline void set_is_shared(bool value);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
4766 String* name, 4798 String* name,
4767 LookupResult* result); 4799 LookupResult* result);
4768 4800
4769 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); 4801 MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
4770 4802
4771 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, 4803 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode,
4772 NormalizedMapSharingMode sharing); 4804 NormalizedMapSharingMode sharing);
4773 4805
4774 // Returns a copy of the map, with all transitions dropped from the 4806 // Returns a copy of the map, with all transitions dropped from the
4775 // instance descriptors. 4807 // instance descriptors.
4776 MUST_USE_RESULT MaybeObject* CopyDropTransitions(); 4808 MUST_USE_RESULT MaybeObject* CopyDropTransitions(SharedMode shared_mode);
4777 4809
4778 // Returns the property index for name (only valid for FAST MODE). 4810 // Returns the property index for name (only valid for FAST MODE).
4779 int PropertyIndexFor(String* name); 4811 int PropertyIndexFor(String* name);
4780 4812
4781 // Returns the next free property index (only valid for FAST MODE). 4813 // Returns the next free property index (only valid for FAST MODE).
4782 int NextFreePropertyIndex(); 4814 int NextFreePropertyIndex();
4783 4815
4784 // Returns the number of properties described in instance_descriptors 4816 // Returns the number of properties described in instance_descriptors
4785 // filtering out properties with the specified attributes. 4817 // filtering out properties with the specified attributes.
4786 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); 4818 int NumberOfDescribedProperties(PropertyAttributes filter = NONE);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
4819 4851
4820 // Computes a hash value for this map, to be used in HashTables and such. 4852 // Computes a hash value for this map, to be used in HashTables and such.
4821 int Hash(); 4853 int Hash();
4822 4854
4823 // Compares this map to another to see if they describe equivalent objects. 4855 // Compares this map to another to see if they describe equivalent objects.
4824 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if 4856 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if
4825 // it had exactly zero inobject properties. 4857 // it had exactly zero inobject properties.
4826 // The "shared" flags of both this map and |other| are ignored. 4858 // The "shared" flags of both this map and |other| are ignored.
4827 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); 4859 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
4828 4860
4829 // Returns the contents of this map's descriptor array for the given string.
4830 // May return NULL. |safe_to_add_transition| is set to false and NULL
4831 // is returned if adding transitions is not allowed.
4832 Object* GetDescriptorContents(String* sentinel_name,
4833 bool* safe_to_add_transitions);
4834
4835 // Returns the map that this map transitions to if its elements_kind 4861 // Returns the map that this map transitions to if its elements_kind
4836 // is changed to |elements_kind|, or NULL if no such map is cached yet. 4862 // is changed to |elements_kind|, or NULL if no such map is cached yet.
4837 // |safe_to_add_transitions| is set to false if adding transitions is not 4863 // |safe_to_add_transitions| is set to false if adding transitions is not
4838 // allowed. 4864 // allowed.
4839 Map* LookupElementsTransitionMap(ElementsKind elements_kind, 4865 Map* LookupElementsTransitionMap(ElementsKind elements_kind);
4840 bool* safe_to_add_transition);
4841 4866
4842 // Adds an entry to this map's descriptor array for a transition to 4867 // Adds a new transitions for changing the elements kind to |elements_kind|.
4843 // |transitioned_map| when its elements_kind is changed to |elements_kind|. 4868 MUST_USE_RESULT MaybeObject* CreateNextElementsTransition(
4844 MUST_USE_RESULT MaybeObject* AddElementsTransition( 4869 ElementsKind elements_kind);
4845 ElementsKind elements_kind, Map* transitioned_map);
4846 4870
4847 // Returns the transitioned map for this map with the most generic 4871 // Returns the transitioned map for this map with the most generic
4848 // elements_kind that's found in |candidates|, or null handle if no match is 4872 // elements_kind that's found in |candidates|, or null handle if no match is
4849 // found at all. 4873 // found at all.
4850 Handle<Map> FindTransitionedMap(MapHandleList* candidates); 4874 Handle<Map> FindTransitionedMap(MapHandleList* candidates);
4851 Map* FindTransitionedMap(MapList* candidates); 4875 Map* FindTransitionedMap(MapList* candidates);
4852 4876
4853 // Zaps the contents of backing data structures in debug mode. Note that the 4877 // Zaps the contents of backing data structures in debug mode. Note that the
4854 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects 4878 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
4855 // holding weak references when incremental marking is used, because it also 4879 // holding weak references when incremental marking is used, because it also
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
4977 // Layout of the default cache. It holds alternating name and code objects. 5001 // Layout of the default cache. It holds alternating name and code objects.
4978 static const int kCodeCacheEntrySize = 2; 5002 static const int kCodeCacheEntrySize = 2;
4979 static const int kCodeCacheEntryNameOffset = 0; 5003 static const int kCodeCacheEntryNameOffset = 0;
4980 static const int kCodeCacheEntryCodeOffset = 1; 5004 static const int kCodeCacheEntryCodeOffset = 1;
4981 5005
4982 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset, 5006 typedef FixedBodyDescriptor<kPointerFieldsBeginOffset,
4983 kPointerFieldsEndOffset, 5007 kPointerFieldsEndOffset,
4984 kSize> BodyDescriptor; 5008 kSize> BodyDescriptor;
4985 5009
4986 private: 5010 private:
4987 String* elements_transition_sentinel_name();
4988 DISALLOW_IMPLICIT_CONSTRUCTORS(Map); 5011 DISALLOW_IMPLICIT_CONSTRUCTORS(Map);
4989 }; 5012 };
4990 5013
4991 5014
4992 // An abstract superclass, a marker class really, for simple structure classes. 5015 // An abstract superclass, a marker class really, for simple structure classes.
4993 // It doesn't carry much functionality but allows struct classes to be 5016 // It doesn't carry much functionality but allows struct classes to be
4994 // identified in the type system. 5017 // identified in the type system.
4995 class Struct: public HeapObject { 5018 class Struct: public HeapObject {
4996 public: 5019 public:
4997 inline void InitializeBody(int object_size); 5020 inline void InitializeBody(int object_size);
(...skipping 3680 matching lines...) Expand 10 before | Expand all | Expand 10 after
8678 } else { 8701 } else {
8679 value &= ~(1 << bit_position); 8702 value &= ~(1 << bit_position);
8680 } 8703 }
8681 return value; 8704 return value;
8682 } 8705 }
8683 }; 8706 };
8684 8707
8685 } } // namespace v8::internal 8708 } } // namespace v8::internal
8686 8709
8687 #endif // V8_OBJECTS_H_ 8710 #endif // V8_OBJECTS_H_
OLDNEW
« src/bootstrapper.cc ('K') | « src/mips/macro-assembler-mips.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698