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 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |