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

Side by Side Diff: src/objects.h

Issue 10697015: Separating transitions from descriptors. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Using WhitenessWitness in TransitionArray code. Created 8 years, 5 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
« no previous file with comments | « src/mirror-debugger.js ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 762 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 V(ExternalDoubleArray) \ 773 V(ExternalDoubleArray) \
774 V(ExternalPixelArray) \ 774 V(ExternalPixelArray) \
775 V(ByteArray) \ 775 V(ByteArray) \
776 V(FreeSpace) \ 776 V(FreeSpace) \
777 V(JSReceiver) \ 777 V(JSReceiver) \
778 V(JSObject) \ 778 V(JSObject) \
779 V(JSContextExtensionObject) \ 779 V(JSContextExtensionObject) \
780 V(JSModule) \ 780 V(JSModule) \
781 V(Map) \ 781 V(Map) \
782 V(DescriptorArray) \ 782 V(DescriptorArray) \
783 V(TransitionArray) \
783 V(DeoptimizationInputData) \ 784 V(DeoptimizationInputData) \
784 V(DeoptimizationOutputData) \ 785 V(DeoptimizationOutputData) \
785 V(TypeFeedbackCells) \ 786 V(TypeFeedbackCells) \
786 V(FixedArray) \ 787 V(FixedArray) \
787 V(FixedDoubleArray) \ 788 V(FixedDoubleArray) \
788 V(Context) \ 789 V(Context) \
789 V(GlobalContext) \ 790 V(GlobalContext) \
790 V(ModuleContext) \ 791 V(ModuleContext) \
791 V(ScopeInfo) \ 792 V(ScopeInfo) \
792 V(JSFunction) \ 793 V(JSFunction) \
(...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 // (storage->length() == NumberOfEnumElements()). 1892 // (storage->length() == NumberOfEnumElements()).
1892 // If storage is NULL, will count the elements without adding 1893 // If storage is NULL, will count the elements without adding
1893 // them to any storage. 1894 // them to any storage.
1894 // Returns the number of enumerable elements. 1895 // Returns the number of enumerable elements.
1895 int GetEnumElementKeys(FixedArray* storage); 1896 int GetEnumElementKeys(FixedArray* storage);
1896 1897
1897 // Add a property to a fast-case object using a map transition to 1898 // Add a property to a fast-case object using a map transition to
1898 // new_map. 1899 // new_map.
1899 MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map, 1900 MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(Map* new_map,
1900 String* name, 1901 String* name,
1901 Object* value); 1902 Object* value,
1903 int field_index);
1902 1904
1903 // Add a constant function property to a fast-case object. 1905 // Add a constant function property to a fast-case object.
1904 // This leaves a CONSTANT_TRANSITION in the old map, and 1906 // This leaves a CONSTANT_TRANSITION in the old map, and
1905 // if it is called on a second object with this map, a 1907 // if it is called on a second object with this map, a
1906 // normal property is added instead, with a map transition. 1908 // normal property is added instead, with a map transition.
1907 // This avoids the creation of many maps with the same constant 1909 // This avoids the creation of many maps with the same constant
1908 // function, all orphaned. 1910 // function, all orphaned.
1909 MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty( 1911 MUST_USE_RESULT MaybeObject* AddConstantFunctionProperty(
1910 String* name, 1912 String* name,
1911 JSFunction* function, 1913 JSFunction* function,
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
2049 #ifdef OBJECT_PRINT 2051 #ifdef OBJECT_PRINT
2050 inline void PrintProperties() { 2052 inline void PrintProperties() {
2051 PrintProperties(stdout); 2053 PrintProperties(stdout);
2052 } 2054 }
2053 void PrintProperties(FILE* out); 2055 void PrintProperties(FILE* out);
2054 2056
2055 inline void PrintElements() { 2057 inline void PrintElements() {
2056 PrintElements(stdout); 2058 PrintElements(stdout);
2057 } 2059 }
2058 void PrintElements(FILE* out); 2060 void PrintElements(FILE* out);
2061 inline void PrintTransitions() {
2062 PrintTransitions(stdout);
2063 }
2064 void PrintTransitions(FILE* out);
2059 #endif 2065 #endif
2060 2066
2061 void PrintElementsTransition( 2067 void PrintElementsTransition(
2062 FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements, 2068 FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements,
2063 ElementsKind to_kind, FixedArrayBase* to_elements); 2069 ElementsKind to_kind, FixedArrayBase* to_elements);
2064 2070
2065 #ifdef DEBUG 2071 #ifdef DEBUG
2066 // Structure for collecting spill information about JSObjects. 2072 // Structure for collecting spill information about JSObjects.
2067 class SpillInformation { 2073 class SpillInformation {
2068 public: 2074 public:
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2202 uint32_t index, 2208 uint32_t index,
2203 Object* getter, 2209 Object* getter,
2204 Object* setter, 2210 Object* setter,
2205 PropertyAttributes attributes); 2211 PropertyAttributes attributes);
2206 MUST_USE_RESULT MaybeObject* CreateAccessorPairFor(String* name); 2212 MUST_USE_RESULT MaybeObject* CreateAccessorPairFor(String* name);
2207 MUST_USE_RESULT MaybeObject* DefinePropertyAccessor( 2213 MUST_USE_RESULT MaybeObject* DefinePropertyAccessor(
2208 String* name, 2214 String* name,
2209 Object* getter, 2215 Object* getter,
2210 Object* setter, 2216 Object* setter,
2211 PropertyAttributes attributes); 2217 PropertyAttributes attributes);
2212 void LookupInDescriptor(String* name, LookupResult* result);
2213 2218
2214 // Returns the hidden properties backing store object, currently 2219 // Returns the hidden properties backing store object, currently
2215 // a StringDictionary, stored on this object. 2220 // a StringDictionary, stored on this object.
2216 // If no hidden properties object has been put on this object, 2221 // If no hidden properties object has been put on this object,
2217 // return undefined, unless create_if_absent is true, in which case 2222 // return undefined, unless create_if_absent is true, in which case
2218 // a new dictionary is created, added to this object, and returned. 2223 // a new dictionary is created, added to this object, and returned.
2219 MUST_USE_RESULT MaybeObject* GetHiddenPropertiesDictionary( 2224 MUST_USE_RESULT MaybeObject* GetHiddenPropertiesDictionary(
2220 bool create_if_absent); 2225 bool create_if_absent);
2221 // Updates the existing hidden properties dictionary. 2226 // Updates the existing hidden properties dictionary.
2222 MUST_USE_RESULT MaybeObject* SetHiddenPropertiesDictionary( 2227 MUST_USE_RESULT MaybeObject* SetHiddenPropertiesDictionary(
(...skipping 14 matching lines...) Expand all
2237 inline static FixedArrayBase* cast(Object* object); 2242 inline static FixedArrayBase* cast(Object* object);
2238 2243
2239 // Layout description. 2244 // Layout description.
2240 // Length is smi tagged when it is stored. 2245 // Length is smi tagged when it is stored.
2241 static const int kLengthOffset = HeapObject::kHeaderSize; 2246 static const int kLengthOffset = HeapObject::kHeaderSize;
2242 static const int kHeaderSize = kLengthOffset + kPointerSize; 2247 static const int kHeaderSize = kLengthOffset + kPointerSize;
2243 }; 2248 };
2244 2249
2245 2250
2246 class FixedDoubleArray; 2251 class FixedDoubleArray;
2252 class IncrementalMarking;
2253
2247 2254
2248 // FixedArray describes fixed-sized arrays with element type Object*. 2255 // FixedArray describes fixed-sized arrays with element type Object*.
2249 class FixedArray: public FixedArrayBase { 2256 class FixedArray: public FixedArrayBase {
2250 public: 2257 public:
2251 // Setter and getter for elements. 2258 // Setter and getter for elements.
2252 inline Object* get(int index); 2259 inline Object* get(int index);
2253 // Setter that uses write barrier. 2260 // Setter that uses write barrier.
2254 inline void set(int index, Object* value); 2261 inline void set(int index, Object* value);
2255 inline bool is_the_hole(int index); 2262 inline bool is_the_hole(int index);
2256 2263
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2332 // object, the prefix of this array is sorted. 2339 // object, the prefix of this array is sorted.
2333 void SortPairs(FixedArray* numbers, uint32_t len); 2340 void SortPairs(FixedArray* numbers, uint32_t len);
2334 2341
2335 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { 2342 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> {
2336 public: 2343 public:
2337 static inline int SizeOf(Map* map, HeapObject* object) { 2344 static inline int SizeOf(Map* map, HeapObject* object) {
2338 return SizeFor(reinterpret_cast<FixedArray*>(object)->length()); 2345 return SizeFor(reinterpret_cast<FixedArray*>(object)->length());
2339 } 2346 }
2340 }; 2347 };
2341 2348
2349 // WhitenessWitness is used to prove that a descriptor array is white
2350 // (unmarked), so incremental write barriers can be skipped because the
2351 // marking invariant cannot be broken and slots pointing into evacuation
2352 // candidates will be discovered when the object is scanned. A witness is
2353 // always stack-allocated right after creating an array. By allocating a
2354 // witness, incremental marking is globally disabled. The witness is then
2355 // passed along wherever needed to statically prove that the array is known to
2356 // be white.
2357 class WhitenessWitness {
2358 public:
2359 inline explicit WhitenessWitness(FixedArray* array);
2360 inline ~WhitenessWitness();
2361
2362 private:
2363 IncrementalMarking* marking_;
2364 };
2365
2342 protected: 2366 protected:
2343 // Set operation on FixedArray without using write barriers. Can 2367 // Set operation on FixedArray without using write barriers. Can
2344 // only be used for storing old space objects or smis. 2368 // only be used for storing old space objects or smis.
2345 static inline void NoWriteBarrierSet(FixedArray* array, 2369 static inline void NoWriteBarrierSet(FixedArray* array,
2346 int index, 2370 int index,
2347 Object* value); 2371 Object* value);
2348 2372
2349 // Set operation on FixedArray without incremental write barrier. Can 2373 // Set operation on FixedArray without incremental write barrier. Can
2350 // only be used if the object is guaranteed to be white (whiteness witness 2374 // only be used if the object is guaranteed to be white (whiteness witness
2351 // is present). 2375 // is present).
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2406 2430
2407 #ifdef DEBUG 2431 #ifdef DEBUG
2408 void FixedDoubleArrayVerify(); 2432 void FixedDoubleArrayVerify();
2409 #endif 2433 #endif
2410 2434
2411 private: 2435 private:
2412 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray); 2436 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray);
2413 }; 2437 };
2414 2438
2415 2439
2416 class IncrementalMarking;
2417
2418
2419 // DescriptorArrays are fixed arrays used to hold instance descriptors. 2440 // DescriptorArrays are fixed arrays used to hold instance descriptors.
2420 // The format of the these objects is: 2441 // The format of the these objects is:
2421 // TODO(1399): It should be possible to make room for bit_field3 in the map 2442 // TODO(1399): It should be possible to make room for bit_field3 in the map
2422 // without overloading the instance descriptors field in the map 2443 // without overloading the instance descriptors field in the map
2423 // (and storing it in the DescriptorArray when the map has one). 2444 // (and storing it in the DescriptorArray when the map has one).
2424 // [0]: storage for bit_field3 for Map owning this object (Smi) 2445 // [0]: storage for bit_field3 for Map owning this object (Smi)
2425 // [1]: point to a fixed array with (value, detail) pairs. 2446 // [1]: point to a fixed array with (value, detail) pairs.
2426 // [2]: next enumeration index (Smi), or pointer to small fixed array: 2447 // [2]: next enumeration index (Smi), or pointer to small fixed array:
2427 // [0]: next enumeration index (Smi) 2448 // [0]: next enumeration index (Smi)
2428 // [1]: pointer to fixed array with enum cache 2449 // [1]: pointer to fixed array with enum cache
2429 // [3]: first key 2450 // [3]: first key
2430 // [length() - 1]: last key 2451 // [length() - 1]: last key
2431 // 2452 //
2432 class DescriptorArray: public FixedArray { 2453 class DescriptorArray: public FixedArray {
2433 public: 2454 public:
2434 // Returns true for both shared empty_descriptor_array and for smis, which the 2455 // Returns true for both shared empty_descriptor_array and for smis, which the
2435 // map uses to encode additional bit fields when the descriptor array is not 2456 // map uses to encode additional bit fields when the descriptor array is not
2436 // yet used. 2457 // yet used.
2437 inline bool IsEmpty(); 2458 inline bool IsEmpty();
2438 inline bool MayContainTransitions(); 2459 inline bool MayContainTransitions();
2460 inline bool HasTransitionArray();
2439 2461
2440 DECL_ACCESSORS(elements_transition_map, Map) 2462 DECL_ACCESSORS(transitions, TransitionArray)
2441 inline void ClearElementsTransition(); 2463 inline void ClearTransitions();
2442 2464
2443 // Returns the number of descriptors in the array. 2465 // Returns the number of descriptors in the array.
2444 int number_of_descriptors() { 2466 int number_of_descriptors() {
2445 ASSERT(length() >= kFirstIndex || IsEmpty()); 2467 ASSERT(MayContainTransitions() || IsEmpty());
2446 int len = length(); 2468 int len = length();
2447 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; 2469 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize;
2448 } 2470 }
2449 2471
2472 inline int number_of_entries() { return number_of_descriptors(); }
2473
2450 int NextEnumerationIndex() { 2474 int NextEnumerationIndex() {
2451 if (IsEmpty()) return PropertyDetails::kInitialIndex; 2475 if (IsEmpty()) return PropertyDetails::kInitialIndex;
2452 Object* obj = get(kEnumerationIndexIndex); 2476 Object* obj = get(kEnumerationIndexIndex);
2453 if (obj->IsSmi()) { 2477 if (obj->IsSmi()) {
2454 return Smi::cast(obj)->value(); 2478 return Smi::cast(obj)->value();
2455 } else { 2479 } else {
2456 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); 2480 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex);
2457 return Smi::cast(index)->value(); 2481 return Smi::cast(index)->value();
2458 } 2482 }
2459 } 2483 }
(...skipping 14 matching lines...) Expand all
2474 return bridge->get(kEnumCacheBridgeCacheIndex); 2498 return bridge->get(kEnumCacheBridgeCacheIndex);
2475 } 2499 }
2476 2500
2477 Object** GetEnumCacheSlot() { 2501 Object** GetEnumCacheSlot() {
2478 ASSERT(HasEnumCache()); 2502 ASSERT(HasEnumCache());
2479 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), 2503 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2480 kEnumerationIndexOffset); 2504 kEnumerationIndexOffset);
2481 } 2505 }
2482 2506
2483 Object** GetTransitionsSlot() { 2507 Object** GetTransitionsSlot() {
2484 ASSERT(elements_transition_map() != NULL);
2485 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), 2508 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
2486 kTransitionsOffset); 2509 kTransitionsOffset);
2487 } 2510 }
2488 2511
2489 // TODO(1399): It should be possible to make room for bit_field3 in the map 2512 // TODO(1399): It should be possible to make room for bit_field3 in the map
2490 // without overloading the instance descriptors field in the map 2513 // without overloading the instance descriptors field in the map
2491 // (and storing it in the DescriptorArray when the map has one). 2514 // (and storing it in the DescriptorArray when the map has one).
2492 inline int bit_field3_storage(); 2515 inline int bit_field3_storage();
2493 inline void set_bit_field3_storage(int value); 2516 inline void set_bit_field3_storage(int value);
2494 2517
2495 // Initialize or change the enum cache, 2518 // Initialize or change the enum cache,
2496 // using the supplied storage for the small "bridge". 2519 // using the supplied storage for the small "bridge".
2497 void SetEnumCache(FixedArray* bridge_storage, 2520 void SetEnumCache(FixedArray* bridge_storage,
2498 FixedArray* new_cache, 2521 FixedArray* new_cache,
2499 Object* new_index_cache); 2522 Object* new_index_cache);
2500 2523
2501 // Accessors for fetching instance descriptor at descriptor number. 2524 // Accessors for fetching instance descriptor at descriptor number.
2502 inline String* GetKey(int descriptor_number); 2525 inline String* GetKey(int descriptor_number);
2503 inline Object** GetKeySlot(int descriptor_number); 2526 inline Object** GetKeySlot(int descriptor_number);
2504 inline void SetKeyUnchecked(Heap* heap, int descriptor_number, String* value);
2505 inline Object* GetValue(int descriptor_number); 2527 inline Object* GetValue(int descriptor_number);
2506 inline Object** GetValueSlot(int descriptor_number); 2528 inline Object** GetValueSlot(int descriptor_number);
2507 inline void SetNullValueUnchecked(Heap* heap, int descriptor_number);
2508 inline void SetValueUnchecked(Heap* heap,
2509 int descriptor_number,
2510 Object* value);
2511 inline PropertyDetails GetDetails(int descriptor_number); 2529 inline PropertyDetails GetDetails(int descriptor_number);
2512 inline void SetDetailsUnchecked(int descriptor_number, Smi* value);
2513 inline PropertyType GetType(int descriptor_number); 2530 inline PropertyType GetType(int descriptor_number);
2514 inline int GetFieldIndex(int descriptor_number); 2531 inline int GetFieldIndex(int descriptor_number);
2515 inline JSFunction* GetConstantFunction(int descriptor_number); 2532 inline JSFunction* GetConstantFunction(int descriptor_number);
2516 inline Object* GetCallbacksObject(int descriptor_number); 2533 inline Object* GetCallbacksObject(int descriptor_number);
2517 inline AccessorDescriptor* GetCallbacks(int descriptor_number); 2534 inline AccessorDescriptor* GetCallbacks(int descriptor_number);
2518 inline bool IsProperty(int descriptor_number);
2519 inline bool IsTransitionOnly(int descriptor_number);
2520
2521 // WhitenessWitness is used to prove that a specific descriptor array is white
2522 // (unmarked), so incremental write barriers can be skipped because the
2523 // marking invariant cannot be broken and slots pointing into evacuation
2524 // candidates will be discovered when the object is scanned. A witness is
2525 // always stack-allocated right after creating a descriptor array. By
2526 // allocating a witness, incremental marking is globally disabled. The witness
2527 // is then passed along wherever needed to statically prove that the
2528 // descriptor array is known to be white.
2529 class WhitenessWitness {
2530 public:
2531 inline explicit WhitenessWitness(DescriptorArray* array);
2532 inline ~WhitenessWitness();
2533
2534 private:
2535 IncrementalMarking* marking_;
2536 };
2537 2535
2538 // Accessor for complete descriptor. 2536 // Accessor for complete descriptor.
2539 inline void Get(int descriptor_number, Descriptor* desc); 2537 inline void Get(int descriptor_number, Descriptor* desc);
2540 inline void Set(int descriptor_number, 2538 inline void Set(int descriptor_number,
2541 Descriptor* desc, 2539 Descriptor* desc,
2542 const WhitenessWitness&); 2540 const WhitenessWitness&);
2543 2541
2544 // Transfer a complete descriptor from the src descriptor array to the dst 2542 // Transfer a complete descriptor from the src descriptor array to the dst
2545 // one, dropping map transitions in CALLBACKS. 2543 // one, dropping map transitions in CALLBACKS.
2546 static void CopyFrom(Handle<DescriptorArray> dst, 2544 static void CopyFrom(Handle<DescriptorArray> dst,
2547 int dst_index, 2545 int dst_index,
2548 Handle<DescriptorArray> src, 2546 Handle<DescriptorArray> src,
2549 int src_index, 2547 int src_index,
2550 const WhitenessWitness& witness); 2548 const WhitenessWitness& witness);
2551 2549
2552 // Transfer a complete descriptor from the src descriptor array to this 2550 // Transfer a complete descriptor from the src descriptor array to this
2553 // descriptor array, dropping map transitions in CALLBACKS. 2551 // descriptor array, dropping map transitions in CALLBACKS.
2554 MUST_USE_RESULT MaybeObject* CopyFrom(int dst_index, 2552 MUST_USE_RESULT MaybeObject* CopyFrom(int dst_index,
2555 DescriptorArray* src, 2553 DescriptorArray* src,
2556 int src_index, 2554 int src_index,
2557 const WhitenessWitness&); 2555 const WhitenessWitness&);
2558 2556
2559 // Copy the descriptor array, insert a new descriptor and optionally 2557 // Copy the descriptor array, insert a new descriptor and optionally
2560 // remove map transitions. If the descriptor is already present, it is 2558 // remove map transitions. If the descriptor is already present, it is
2561 // replaced. If a replaced descriptor is a real property (not a transition 2559 // replaced. If a replaced descriptor is a real property (not a transition
2562 // or null), its enumeration index is kept as is. 2560 // or null), its enumeration index is kept as is.
2563 // If adding a real property, map transitions must be removed. If adding 2561 // If adding a real property, map transitions must be removed. If adding
2564 // a transition, they must not be removed. All null descriptors are removed. 2562 // a transition, they must not be removed. All null descriptors are removed.
2565 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, 2563 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor);
2566 TransitionFlag transition_flag);
2567 2564
2568 // Indicates whether the search function should expect a sorted or an unsorted 2565 // Indicates whether the search function should expect a sorted or an unsorted
2569 // descriptor array as input. 2566 // descriptor array as input.
2570 enum SharedMode { 2567 enum SharedMode {
2571 MAY_BE_SHARED, 2568 MAY_BE_SHARED,
2572 CANNOT_BE_SHARED 2569 CANNOT_BE_SHARED
2573 }; 2570 };
2574 2571
2575 // Return a copy of the array with all transitions and null descriptors 2572 // Return a copy of the array with all transitions and null descriptors
2576 // removed. Return a Failure object in case of an allocation failure. 2573 // removed. Return a Failure object in case of an allocation failure.
2577 MUST_USE_RESULT MaybeObject* RemoveTransitions(SharedMode shared_mode); 2574 MUST_USE_RESULT MaybeObject* Copy(SharedMode shared_mode);
2578 2575
2579 // Sort the instance descriptors by the hash codes of their keys. 2576 // Sort the instance descriptors by the hash codes of their keys.
2580 // Does not check for duplicates. 2577 // Does not check for duplicates.
2581 void SortUnchecked(const WhitenessWitness&); 2578 void SortUnchecked(const WhitenessWitness&);
2582 2579
2583 // Sort the instance descriptors by the hash codes of their keys. 2580 // Sort the instance descriptors by the hash codes of their keys.
2584 // Checks the result for duplicates. 2581 // Checks the result for duplicates.
2585 void Sort(const WhitenessWitness&); 2582 void Sort(const WhitenessWitness&);
2586 2583
2587 // Search the instance descriptors for given name. 2584 // Search the instance descriptors for given name.
2588 INLINE(int Search(String* name)); 2585 INLINE(int Search(String* name));
2589 2586
2590 // As the above, but uses DescriptorLookupCache and updates it when 2587 // As the above, but uses DescriptorLookupCache and updates it when
2591 // necessary. 2588 // necessary.
2592 INLINE(int SearchWithCache(String* name)); 2589 INLINE(int SearchWithCache(String* name));
2593 2590
2594 // Tells whether the name is present int the array. 2591 // Tells whether the name is present int the array.
2595 bool Contains(String* name) { return kNotFound != Search(name); } 2592 bool Contains(String* name) { return kNotFound != Search(name); }
2596 2593
2597 // Perform a binary search in the instance descriptors represented
2598 // by this fixed array. low and high are descriptor indices. If there
2599 // are three instance descriptors in this array it should be called
2600 // with low=0 and high=2.
2601 int BinarySearch(String* name, int low, int high);
2602
2603 // Perform a linear search in the instance descriptors represented
2604 // by this fixed array. len is the number of descriptor indices that are
2605 // valid.
2606 int LinearSearch(SearchMode mode, String* name, int len);
2607
2608 // Allocates a DescriptorArray, but returns the singleton 2594 // Allocates a DescriptorArray, but returns the singleton
2609 // empty descriptor array object if number_of_descriptors is 0. 2595 // empty descriptor array object if number_of_descriptors is 0.
2610 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, 2596 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors,
2611 SharedMode shared_mode); 2597 SharedMode shared_mode);
2612 2598
2613 // Casting. 2599 // Casting.
2614 static inline DescriptorArray* cast(Object* obj); 2600 static inline DescriptorArray* cast(Object* obj);
2615 2601
2616 // Constant for denoting key was not found. 2602 // Constant for denoting key was not found.
2617 static const int kNotFound = -1; 2603 static const int kNotFound = -1;
2618 2604
2619 static const int kBitField3StorageIndex = 0; 2605 static const int kBitField3StorageIndex = 0;
2620 static const int kEnumerationIndexIndex = 1; 2606 static const int kEnumerationIndexIndex = 1;
2621 static const int kTransitionsIndex = 2; 2607 static const int kTransitionsIndex = 2;
2622 static const int kFirstIndex = 3; 2608 static const int kFirstIndex = 3;
2623 2609
2624 // The length of the "bridge" to the enum cache. 2610 // The length of the "bridge" to the enum cache.
2625 static const int kEnumCacheBridgeLength = 3; 2611 static const int kEnumCacheBridgeLength = 3;
2626 static const int kEnumCacheBridgeEnumIndex = 0; 2612 static const int kEnumCacheBridgeEnumIndex = 0;
2627 static const int kEnumCacheBridgeCacheIndex = 1; 2613 static const int kEnumCacheBridgeCacheIndex = 1;
2628 static const int kEnumCacheBridgeIndicesCacheIndex = 2; 2614 static const int kEnumCacheBridgeIndicesCacheIndex = 2;
2629 2615
2630 // Layout description. 2616 // Layout description.
2631 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; 2617 static const int kBitField3StorageOffset = FixedArray::kHeaderSize;
2632 static const int kEnumerationIndexOffset = 2618 static const int kEnumerationIndexOffset = kBitField3StorageOffset +
2633 kBitField3StorageOffset + kPointerSize; 2619 kPointerSize;
2634 static const int kTransitionsOffset = kEnumerationIndexOffset + kPointerSize; 2620 static const int kTransitionsOffset = kEnumerationIndexOffset + kPointerSize;
2635 static const int kFirstOffset = kTransitionsOffset + kPointerSize; 2621 static const int kFirstOffset = kTransitionsOffset + kPointerSize;
2636 2622
2637 // Layout description for the bridge array. 2623 // Layout description for the bridge array.
2638 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; 2624 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize;
2639 static const int kEnumCacheBridgeCacheOffset = 2625 static const int kEnumCacheBridgeCacheOffset =
2640 kEnumCacheBridgeEnumOffset + kPointerSize; 2626 kEnumCacheBridgeEnumOffset + kPointerSize;
2641 2627
2642 // Layout of descriptor. 2628 // Layout of descriptor.
2643 static const int kDescriptorKey = 0; 2629 static const int kDescriptorKey = 0;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2699 static int ToValueIndex(int descriptor_number) { 2685 static int ToValueIndex(int descriptor_number) {
2700 return kFirstIndex + 2686 return kFirstIndex +
2701 (descriptor_number * kDescriptorSize) + 2687 (descriptor_number * kDescriptorSize) +
2702 kDescriptorValue; 2688 kDescriptorValue;
2703 } 2689 }
2704 2690
2705 // Swap operation on FixedArray without using write barriers. 2691 // Swap operation on FixedArray without using write barriers.
2706 static inline void NoIncrementalWriteBarrierSwap( 2692 static inline void NoIncrementalWriteBarrierSwap(
2707 FixedArray* array, int first, int second); 2693 FixedArray* array, int first, int second);
2708 2694
2709 // Swap descriptor first and second. 2695 // Swap first and second descriptor.
2710 inline void NoIncrementalWriteBarrierSwapDescriptors( 2696 inline void NoIncrementalWriteBarrierSwapDescriptors(
2711 int first, int second); 2697 int first, int second);
2712 2698
2713 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); 2699 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
2714 }; 2700 };
2715 2701
2716 2702
2703 template<typename T>
2704 inline int LinearSearch(T* array, SearchMode mode, String* name, int len);
2705
2706
2707 template<typename T>
2708 inline int Search(T* array, String* name);
2709
2710
2717 // HashTable is a subclass of FixedArray that implements a hash table 2711 // HashTable is a subclass of FixedArray that implements a hash table
2718 // that uses open addressing and quadratic probing. 2712 // that uses open addressing and quadratic probing.
2719 // 2713 //
2720 // In order for the quadratic probing to work, elements that have not 2714 // In order for the quadratic probing to work, elements that have not
2721 // yet been used and elements that have been deleted are 2715 // yet been used and elements that have been deleted are
2722 // distinguished. Probing continues when deleted elements are 2716 // distinguished. Probing continues when deleted elements are
2723 // encountered and stops when unused elements are encountered. 2717 // encountered and stops when unused elements are encountered.
2724 // 2718 //
2725 // - Elements with key == undefined have not been used yet. 2719 // - Elements with key == undefined have not been used yet.
2726 // - Elements with key == the_hole have been deleted. 2720 // - Elements with key == the_hole have been deleted.
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
3171 void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array); 3165 void CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array);
3172 3166
3173 // For transforming properties of a JSObject. 3167 // For transforming properties of a JSObject.
3174 MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor( 3168 MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
3175 JSObject* obj, 3169 JSObject* obj,
3176 int unused_property_fields); 3170 int unused_property_fields);
3177 3171
3178 // Find entry for key, otherwise return kNotFound. Optimized version of 3172 // Find entry for key, otherwise return kNotFound. Optimized version of
3179 // HashTable::FindEntry. 3173 // HashTable::FindEntry.
3180 int FindEntry(String* key); 3174 int FindEntry(String* key);
3181
3182 bool ContainsTransition(int entry);
3183 }; 3175 };
3184 3176
3185 3177
3186 class NumberDictionaryShape : public BaseShape<uint32_t> { 3178 class NumberDictionaryShape : public BaseShape<uint32_t> {
3187 public: 3179 public:
3188 static inline bool IsMatch(uint32_t key, Object* other); 3180 static inline bool IsMatch(uint32_t key, Object* other);
3189 MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key); 3181 MUST_USE_RESULT static inline MaybeObject* AsObject(uint32_t key);
3190 static const int kEntrySize = 3; 3182 static const int kEntrySize = 3;
3191 static const bool kIsEnumerable = false; 3183 static const bool kIsEnumerable = false;
3192 }; 3184 };
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after
4621 // Bit field 2. 4613 // Bit field 2.
4622 inline byte bit_field2(); 4614 inline byte bit_field2();
4623 inline void set_bit_field2(byte value); 4615 inline void set_bit_field2(byte value);
4624 4616
4625 // Bit field 3. 4617 // Bit field 3.
4626 // TODO(1399): It should be possible to make room for bit_field3 in the map 4618 // TODO(1399): It should be possible to make room for bit_field3 in the map
4627 // without overloading the instance descriptors field (and storing it in the 4619 // without overloading the instance descriptors field (and storing it in the
4628 // DescriptorArray when the map has one). 4620 // DescriptorArray when the map has one).
4629 inline int bit_field3(); 4621 inline int bit_field3();
4630 inline void set_bit_field3(int value); 4622 inline void set_bit_field3(int value);
4623 inline void SetOwnBitField3(int value);
4631 4624
4632 // Tells whether the object in the prototype property will be used 4625 // Tells whether the object in the prototype property will be used
4633 // for instances created from this function. If the prototype 4626 // for instances created from this function. If the prototype
4634 // property is set to a value that is not a JSObject, the prototype 4627 // property is set to a value that is not a JSObject, the prototype
4635 // property will not be used to create instances of the function. 4628 // property will not be used to create instances of the function.
4636 // See ECMA-262, 13.2.2. 4629 // See ECMA-262, 13.2.2.
4637 inline void set_non_instance_prototype(bool value); 4630 inline void set_non_instance_prototype(bool value);
4638 inline bool has_non_instance_prototype(); 4631 inline bool has_non_instance_prototype();
4639 4632
4640 // Tells whether function has special prototype property. If not, prototype 4633 // Tells whether function has special prototype property. If not, prototype
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
4741 } 4734 }
4742 4735
4743 inline bool has_slow_elements_kind() { 4736 inline bool has_slow_elements_kind() {
4744 return elements_kind() == DICTIONARY_ELEMENTS 4737 return elements_kind() == DICTIONARY_ELEMENTS
4745 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; 4738 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4746 } 4739 }
4747 4740
4748 static bool IsValidElementsTransition(ElementsKind from_kind, 4741 static bool IsValidElementsTransition(ElementsKind from_kind,
4749 ElementsKind to_kind); 4742 ElementsKind to_kind);
4750 4743
4744 inline bool HasTransitionArray();
4745 inline bool HasElementsTransition();
4751 inline Map* elements_transition_map(); 4746 inline Map* elements_transition_map();
4752 inline void set_elements_transition_map(Map* transitioned_map); 4747 MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
4748 Map* transitioned_map);
4749 inline TransitionArray* transitions();
4750 MUST_USE_RESULT inline MaybeObject* AddTransition(String* key,
4751 Object* value);
4752 MUST_USE_RESULT inline MaybeObject* set_transitions(
4753 TransitionArray* transitions);
4754 inline void ClearTransitions();
4753 4755
4754 // Tells whether the map is attached to SharedFunctionInfo 4756 // Tells whether the map is attached to SharedFunctionInfo
4755 // (for inobject slack tracking). 4757 // (for inobject slack tracking).
4756 inline void set_attached_to_shared_function_info(bool value); 4758 inline void set_attached_to_shared_function_info(bool value);
4757 4759
4758 inline bool attached_to_shared_function_info(); 4760 inline bool attached_to_shared_function_info();
4759 4761
4760 // Tells whether the map is shared between objects that may have different 4762 // Tells whether the map is shared between objects that may have different
4761 // behavior. If true, the map should never be modified, instead a clone 4763 // behavior. If true, the map should never be modified, instead a clone
4762 // should be created and modified. 4764 // should be created and modified.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
4832 inline void SetNumberOfProtoTransitions(int value) { 4834 inline void SetNumberOfProtoTransitions(int value) {
4833 FixedArray* cache = prototype_transitions(); 4835 FixedArray* cache = prototype_transitions();
4834 ASSERT(cache->length() != 0); 4836 ASSERT(cache->length() != 0);
4835 cache->set_unchecked(kProtoTransitionNumberOfEntriesOffset, 4837 cache->set_unchecked(kProtoTransitionNumberOfEntriesOffset,
4836 Smi::FromInt(value)); 4838 Smi::FromInt(value));
4837 } 4839 }
4838 4840
4839 // Lookup in the map's instance descriptors and fill out the result 4841 // Lookup in the map's instance descriptors and fill out the result
4840 // with the given holder if the name is found. The holder may be 4842 // with the given holder if the name is found. The holder may be
4841 // NULL when this function is used from the compiler. 4843 // NULL when this function is used from the compiler.
4842 void LookupInDescriptors(JSObject* holder, 4844 void LookupDescriptor(JSObject* holder,
4843 String* name, 4845 String* name,
4844 LookupResult* result); 4846 LookupResult* result);
4847
4848 void LookupTransition(JSObject* holder,
4849 String* name,
4850 LookupResult* result);
4851
4852 void LookupTransitionOrDescriptor(JSObject* holder,
4853 String* name,
4854 LookupResult* result);
4845 4855
4846 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); 4856 MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
4847 4857
4848 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, 4858 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode,
4849 NormalizedMapSharingMode sharing); 4859 NormalizedMapSharingMode sharing);
4850 4860
4851 // Returns a copy of the map, with all transitions dropped from the 4861 // Returns a copy of the map, with all transitions dropped from the
4852 // instance descriptors. 4862 // instance descriptors.
4853 MUST_USE_RESULT MaybeObject* CopyDropTransitions( 4863 MUST_USE_RESULT MaybeObject* CopyDropTransitions(
4854 DescriptorArray::SharedMode shared_mode); 4864 DescriptorArray::SharedMode shared_mode);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
4918 // elements_kind that's found in |candidates|, or null handle if no match is 4928 // elements_kind that's found in |candidates|, or null handle if no match is
4919 // found at all. 4929 // found at all.
4920 Handle<Map> FindTransitionedMap(MapHandleList* candidates); 4930 Handle<Map> FindTransitionedMap(MapHandleList* candidates);
4921 Map* FindTransitionedMap(MapList* candidates); 4931 Map* FindTransitionedMap(MapList* candidates);
4922 4932
4923 // Zaps the contents of backing data structures in debug mode. Note that the 4933 // Zaps the contents of backing data structures in debug mode. Note that the
4924 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects 4934 // heap verifier (i.e. VerifyMarkingVisitor) relies on zapping of objects
4925 // holding weak references when incremental marking is used, because it also 4935 // holding weak references when incremental marking is used, because it also
4926 // iterates over objects that are otherwise unreachable. 4936 // iterates over objects that are otherwise unreachable.
4927 #ifdef DEBUG 4937 #ifdef DEBUG
4928 void ZapInstanceDescriptors();
4929 void ZapPrototypeTransitions(); 4938 void ZapPrototypeTransitions();
4939 void ZapTransitions();
4930 #endif 4940 #endif
4931 4941
4932 // Dispatched behavior. 4942 // Dispatched behavior.
4933 #ifdef OBJECT_PRINT 4943 #ifdef OBJECT_PRINT
4934 inline void MapPrint() { 4944 inline void MapPrint() {
4935 MapPrint(stdout); 4945 MapPrint(stdout);
4936 } 4946 }
4937 void MapPrint(FILE* out); 4947 void MapPrint(FILE* out);
4938 #endif 4948 #endif
4939 #ifdef DEBUG 4949 #ifdef DEBUG
(...skipping 3871 matching lines...) Expand 10 before | Expand all | Expand 10 after
8811 } else { 8821 } else {
8812 value &= ~(1 << bit_position); 8822 value &= ~(1 << bit_position);
8813 } 8823 }
8814 return value; 8824 return value;
8815 } 8825 }
8816 }; 8826 };
8817 8827
8818 } } // namespace v8::internal 8828 } } // namespace v8::internal
8819 8829
8820 #endif // V8_OBJECTS_H_ 8830 #endif // V8_OBJECTS_H_
OLDNEW
« no previous file with comments | « src/mirror-debugger.js ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698