| 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 |