| 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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 }; | 171 }; |
| 172 | 172 |
| 173 | 173 |
| 174 // Indicates whether transitions can be added to a source map or not. | 174 // Indicates whether transitions can be added to a source map or not. |
| 175 enum TransitionFlag { | 175 enum TransitionFlag { |
| 176 INSERT_TRANSITION, | 176 INSERT_TRANSITION, |
| 177 OMIT_TRANSITION | 177 OMIT_TRANSITION |
| 178 }; | 178 }; |
| 179 | 179 |
| 180 | 180 |
| 181 // Indicates whether the transition is simple: the target map of the transition | |
| 182 // either extends the current map with a new property, or it modifies the | |
| 183 // property that was added last to the current map. | |
| 184 enum SimpleTransitionFlag { | |
| 185 SIMPLE_TRANSITION, | |
| 186 FULL_TRANSITION | |
| 187 }; | |
| 188 | |
| 189 | |
| 190 // Indicates whether we are only interested in the descriptors of a particular | |
| 191 // map, or in all descriptors in the descriptor array. | |
| 192 enum DescriptorFlag { | |
| 193 ALL_DESCRIPTORS, | |
| 194 OWN_DESCRIPTORS | |
| 195 }; | |
| 196 | |
| 197 | |
| 198 // Instance size sentinel for objects of variable size. | 181 // Instance size sentinel for objects of variable size. |
| 199 const int kVariableSizeSentinel = 0; | 182 const int kVariableSizeSentinel = 0; |
| 200 | 183 |
| 201 const int kStubMajorKeyBits = 6; | 184 const int kStubMajorKeyBits = 6; |
| 202 const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits; | 185 const int kStubMinorKeyBits = kBitsPerInt - kSmiTagSize - kStubMajorKeyBits; |
| 203 | 186 |
| 204 // All Maps have a field instance_type containing a InstanceType. | 187 // All Maps have a field instance_type containing a InstanceType. |
| 205 // It describes the type of the instances. | 188 // It describes the type of the instances. |
| 206 // | 189 // |
| 207 // As an example, a JavaScript object is a heap object and its map | 190 // As an example, a JavaScript object is a heap object and its map |
| (...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1690 | 1673 |
| 1691 MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info); | 1674 MUST_USE_RESULT MaybeObject* DefineAccessor(AccessorInfo* info); |
| 1692 | 1675 |
| 1693 // Used from Object::GetProperty(). | 1676 // Used from Object::GetProperty(). |
| 1694 MUST_USE_RESULT MaybeObject* GetPropertyWithFailedAccessCheck( | 1677 MUST_USE_RESULT MaybeObject* GetPropertyWithFailedAccessCheck( |
| 1695 Object* receiver, | 1678 Object* receiver, |
| 1696 LookupResult* result, | 1679 LookupResult* result, |
| 1697 String* name, | 1680 String* name, |
| 1698 PropertyAttributes* attributes); | 1681 PropertyAttributes* attributes); |
| 1699 MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor( | 1682 MUST_USE_RESULT MaybeObject* GetPropertyWithInterceptor( |
| 1700 Object* receiver, | 1683 JSReceiver* receiver, |
| 1701 String* name, | 1684 String* name, |
| 1702 PropertyAttributes* attributes); | 1685 PropertyAttributes* attributes); |
| 1703 MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor( | 1686 MUST_USE_RESULT MaybeObject* GetPropertyPostInterceptor( |
| 1704 Object* receiver, | 1687 JSReceiver* receiver, |
| 1705 String* name, | 1688 String* name, |
| 1706 PropertyAttributes* attributes); | 1689 PropertyAttributes* attributes); |
| 1707 MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor( | 1690 MUST_USE_RESULT MaybeObject* GetLocalPropertyPostInterceptor( |
| 1708 Object* receiver, | 1691 JSReceiver* receiver, |
| 1709 String* name, | 1692 String* name, |
| 1710 PropertyAttributes* attributes); | 1693 PropertyAttributes* attributes); |
| 1711 | 1694 |
| 1712 // Returns true if this is an instance of an api function and has | 1695 // Returns true if this is an instance of an api function and has |
| 1713 // been modified since it was created. May give false positives. | 1696 // been modified since it was created. May give false positives. |
| 1714 bool IsDirty(); | 1697 bool IsDirty(); |
| 1715 | 1698 |
| 1716 // If the receiver is a JSGlobalProxy this method will return its prototype, | 1699 // If the receiver is a JSGlobalProxy this method will return its prototype, |
| 1717 // otherwise the result is the receiver itself. | 1700 // otherwise the result is the receiver itself. |
| 1718 inline Object* BypassGlobalProxy(); | 1701 inline Object* BypassGlobalProxy(); |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2378 // object, the prefix of this array is sorted. | 2361 // object, the prefix of this array is sorted. |
| 2379 void SortPairs(FixedArray* numbers, uint32_t len); | 2362 void SortPairs(FixedArray* numbers, uint32_t len); |
| 2380 | 2363 |
| 2381 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { | 2364 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { |
| 2382 public: | 2365 public: |
| 2383 static inline int SizeOf(Map* map, HeapObject* object) { | 2366 static inline int SizeOf(Map* map, HeapObject* object) { |
| 2384 return SizeFor(reinterpret_cast<FixedArray*>(object)->length()); | 2367 return SizeFor(reinterpret_cast<FixedArray*>(object)->length()); |
| 2385 } | 2368 } |
| 2386 }; | 2369 }; |
| 2387 | 2370 |
| 2371 // WhitenessWitness is used to prove that a descriptor array is white |
| 2372 // (unmarked), so incremental write barriers can be skipped because the |
| 2373 // marking invariant cannot be broken and slots pointing into evacuation |
| 2374 // candidates will be discovered when the object is scanned. A witness is |
| 2375 // always stack-allocated right after creating an array. By allocating a |
| 2376 // witness, incremental marking is globally disabled. The witness is then |
| 2377 // passed along wherever needed to statically prove that the array is known to |
| 2378 // be white. |
| 2379 class WhitenessWitness { |
| 2380 public: |
| 2381 inline explicit WhitenessWitness(FixedArray* array); |
| 2382 inline ~WhitenessWitness(); |
| 2383 |
| 2384 private: |
| 2385 IncrementalMarking* marking_; |
| 2386 }; |
| 2387 |
| 2388 protected: | 2388 protected: |
| 2389 // Set operation on FixedArray without using write barriers. Can | 2389 // Set operation on FixedArray without using write barriers. Can |
| 2390 // only be used for storing old space objects or smis. | 2390 // only be used for storing old space objects or smis. |
| 2391 static inline void NoWriteBarrierSet(FixedArray* array, | 2391 static inline void NoWriteBarrierSet(FixedArray* array, |
| 2392 int index, | 2392 int index, |
| 2393 Object* value); | 2393 Object* value); |
| 2394 | 2394 |
| 2395 // Set operation on FixedArray without incremental write barrier. Can | 2395 // Set operation on FixedArray without incremental write barrier. Can |
| 2396 // only be used if the object is guaranteed to be white (whiteness witness | 2396 // only be used if the object is guaranteed to be white (whiteness witness |
| 2397 // is present). | 2397 // is present). |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2461 | 2461 |
| 2462 // DescriptorArrays are fixed arrays used to hold instance descriptors. | 2462 // DescriptorArrays are fixed arrays used to hold instance descriptors. |
| 2463 // The format of the these objects is: | 2463 // The format of the these objects is: |
| 2464 // [0]: Either Smi(0) if uninitialized, or a pointer to small fixed array: | 2464 // [0]: Either Smi(0) if uninitialized, or a pointer to small fixed array: |
| 2465 // [0]: pointer to fixed array with enum cache | 2465 // [0]: pointer to fixed array with enum cache |
| 2466 // [1]: either Smi(0) or pointer to fixed array with indices | 2466 // [1]: either Smi(0) or pointer to fixed array with indices |
| 2467 // [1]: first key | 2467 // [1]: first key |
| 2468 // [length() - kDescriptorSize]: last key | 2468 // [length() - kDescriptorSize]: last key |
| 2469 class DescriptorArray: public FixedArray { | 2469 class DescriptorArray: public FixedArray { |
| 2470 public: | 2470 public: |
| 2471 // WhitenessWitness is used to prove that a descriptor array is white | |
| 2472 // (unmarked), so incremental write barriers can be skipped because the | |
| 2473 // marking invariant cannot be broken and slots pointing into evacuation | |
| 2474 // candidates will be discovered when the object is scanned. A witness is | |
| 2475 // always stack-allocated right after creating an array. By allocating a | |
| 2476 // witness, incremental marking is globally disabled. The witness is then | |
| 2477 // passed along wherever needed to statically prove that the array is known to | |
| 2478 // be white. | |
| 2479 class WhitenessWitness { | |
| 2480 public: | |
| 2481 inline explicit WhitenessWitness(FixedArray* array); | |
| 2482 inline ~WhitenessWitness(); | |
| 2483 | |
| 2484 private: | |
| 2485 IncrementalMarking* marking_; | |
| 2486 }; | |
| 2487 | |
| 2488 // Returns true for both shared empty_descriptor_array and for smis, which the | 2471 // Returns true for both shared empty_descriptor_array and for smis, which the |
| 2489 // map uses to encode additional bit fields when the descriptor array is not | 2472 // map uses to encode additional bit fields when the descriptor array is not |
| 2490 // yet used. | 2473 // yet used. |
| 2491 inline bool IsEmpty(); | 2474 inline bool IsEmpty(); |
| 2492 | 2475 |
| 2493 // Returns the number of descriptors in the array. | 2476 // Returns the number of descriptors in the array. |
| 2494 int number_of_descriptors() { | 2477 int number_of_descriptors() { |
| 2495 ASSERT(length() >= kFirstIndex || IsEmpty()); | 2478 ASSERT(length() >= kFirstIndex || IsEmpty()); |
| 2496 int len = length(); | 2479 int len = length(); |
| 2497 return len == 0 ? 0 : Smi::cast(get(kDescriptorLengthIndex))->value(); | 2480 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; |
| 2498 } | 2481 } |
| 2499 | 2482 |
| 2500 int number_of_descriptors_storage() { | |
| 2501 int len = length(); | |
| 2502 return len == 0 ? 0 : (len - kFirstIndex) / kDescriptorSize; | |
| 2503 } | |
| 2504 | |
| 2505 int NumberOfSlackDescriptors() { | |
| 2506 return number_of_descriptors_storage() - number_of_descriptors(); | |
| 2507 } | |
| 2508 | |
| 2509 inline void SetNumberOfDescriptors(int number_of_descriptors); | |
| 2510 inline int number_of_entries() { return number_of_descriptors(); } | 2483 inline int number_of_entries() { return number_of_descriptors(); } |
| 2484 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } |
| 2511 | 2485 |
| 2512 bool HasEnumCache() { | 2486 bool HasEnumCache() { |
| 2513 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); | 2487 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); |
| 2514 } | 2488 } |
| 2515 | 2489 |
| 2516 void CopyEnumCacheFrom(DescriptorArray* array) { | 2490 Object* GetEnumCache() { |
| 2517 set(kEnumCacheIndex, array->get(kEnumCacheIndex)); | |
| 2518 } | |
| 2519 | |
| 2520 FixedArray* GetEnumCache() { | |
| 2521 ASSERT(HasEnumCache()); | 2491 ASSERT(HasEnumCache()); |
| 2522 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); | 2492 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
| 2523 return FixedArray::cast(bridge->get(kEnumCacheBridgeCacheIndex)); | 2493 return bridge->get(kEnumCacheBridgeCacheIndex); |
| 2524 } | |
| 2525 | |
| 2526 bool HasEnumIndicesCache() { | |
| 2527 if (IsEmpty()) return false; | |
| 2528 Object* object = get(kEnumCacheIndex); | |
| 2529 if (object->IsSmi()) return false; | |
| 2530 FixedArray* bridge = FixedArray::cast(object); | |
| 2531 return !bridge->get(kEnumCacheBridgeIndicesCacheIndex)->IsSmi(); | |
| 2532 } | |
| 2533 | |
| 2534 FixedArray* GetEnumIndicesCache() { | |
| 2535 ASSERT(HasEnumIndicesCache()); | |
| 2536 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); | |
| 2537 return FixedArray::cast(bridge->get(kEnumCacheBridgeIndicesCacheIndex)); | |
| 2538 } | 2494 } |
| 2539 | 2495 |
| 2540 Object** GetEnumCacheSlot() { | 2496 Object** GetEnumCacheSlot() { |
| 2541 ASSERT(HasEnumCache()); | 2497 ASSERT(HasEnumCache()); |
| 2542 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | 2498 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
| 2543 kEnumCacheOffset); | 2499 kEnumCacheOffset); |
| 2544 } | 2500 } |
| 2545 | 2501 |
| 2546 void ClearEnumCache(); | |
| 2547 | |
| 2548 // Initialize or change the enum cache, | 2502 // Initialize or change the enum cache, |
| 2549 // using the supplied storage for the small "bridge". | 2503 // using the supplied storage for the small "bridge". |
| 2550 void SetEnumCache(FixedArray* bridge_storage, | 2504 void SetEnumCache(FixedArray* bridge_storage, |
| 2551 FixedArray* new_cache, | 2505 FixedArray* new_cache, |
| 2552 Object* new_index_cache); | 2506 Object* new_index_cache); |
| 2553 | 2507 |
| 2554 // Accessors for fetching instance descriptor at descriptor number. | 2508 // Accessors for fetching instance descriptor at descriptor number. |
| 2555 inline String* GetKey(int descriptor_number); | 2509 inline String* GetKey(int descriptor_number); |
| 2556 inline Object** GetKeySlot(int descriptor_number); | 2510 inline Object** GetKeySlot(int descriptor_number); |
| 2557 inline Object* GetValue(int descriptor_number); | 2511 inline Object* GetValue(int descriptor_number); |
| 2558 inline Object** GetValueSlot(int descriptor_number); | 2512 inline Object** GetValueSlot(int descriptor_number); |
| 2559 inline PropertyDetails GetDetails(int descriptor_number); | 2513 inline PropertyDetails GetDetails(int descriptor_number); |
| 2560 inline PropertyType GetType(int descriptor_number); | 2514 inline PropertyType GetType(int descriptor_number); |
| 2561 inline int GetFieldIndex(int descriptor_number); | 2515 inline int GetFieldIndex(int descriptor_number); |
| 2562 inline JSFunction* GetConstantFunction(int descriptor_number); | 2516 inline JSFunction* GetConstantFunction(int descriptor_number); |
| 2563 inline Object* GetCallbacksObject(int descriptor_number); | 2517 inline Object* GetCallbacksObject(int descriptor_number); |
| 2564 inline AccessorDescriptor* GetCallbacks(int descriptor_number); | 2518 inline AccessorDescriptor* GetCallbacks(int descriptor_number); |
| 2565 | 2519 |
| 2566 inline String* GetSortedKey(int descriptor_number); | 2520 inline String* GetSortedKey(int descriptor_number); |
| 2567 inline int GetSortedKeyIndex(int descriptor_number); | 2521 inline int GetSortedKeyIndex(int descriptor_number); |
| 2568 inline void SetSortedKey(int pointer, int descriptor_number); | 2522 inline void SetSortedKey(int pointer, int descriptor_number); |
| 2569 | 2523 |
| 2570 // Accessor for complete descriptor. | 2524 // Accessor for complete descriptor. |
| 2571 inline void Get(int descriptor_number, Descriptor* desc); | 2525 inline void Get(int descriptor_number, Descriptor* desc); |
| 2572 inline void Set(int descriptor_number, | 2526 inline void Set(int descriptor_number, |
| 2573 Descriptor* desc, | 2527 Descriptor* desc, |
| 2574 const WhitenessWitness&); | 2528 const WhitenessWitness&); |
| 2575 inline void Set(int descriptor_number, Descriptor* desc); | |
| 2576 inline void EraseDescriptor(Heap* heap, int descriptor_number); | |
| 2577 | 2529 |
| 2578 // Append automatically sets the enumeration index. This should only be used | 2530 // Append automatically sets the enumeration index. This should only be used |
| 2579 // to add descriptors in bulk at the end, followed by sorting the descriptor | 2531 // to add descriptors in bulk at the end, followed by sorting the descriptor |
| 2580 // array. | 2532 // array. |
| 2581 inline void Append(Descriptor* desc, const WhitenessWitness&); | 2533 inline void Append(Descriptor* desc, |
| 2582 inline void Append(Descriptor* desc); | 2534 const WhitenessWitness&, |
| 2535 int number_of_set_descriptors); |
| 2583 | 2536 |
| 2584 // Transfer a complete descriptor from the src descriptor array to this | 2537 // Transfer a complete descriptor from the src descriptor array to this |
| 2585 // descriptor array. | 2538 // descriptor array. |
| 2586 void CopyFrom(int dst_index, | 2539 void CopyFrom(int dst_index, |
| 2587 DescriptorArray* src, | 2540 DescriptorArray* src, |
| 2588 int src_index, | 2541 int src_index, |
| 2589 const WhitenessWitness&); | 2542 const WhitenessWitness&); |
| 2590 | 2543 |
| 2591 MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index); | |
| 2592 | |
| 2593 // Sort the instance descriptors by the hash codes of their keys. | 2544 // Sort the instance descriptors by the hash codes of their keys. |
| 2594 void Sort(); | 2545 void Sort(); |
| 2546 inline void SwapSortedKeys(int first, int second); |
| 2595 | 2547 |
| 2596 // Search the instance descriptors for given name. | 2548 // Search the instance descriptors for given name. |
| 2597 INLINE(int Search(String* name, int number_of_own_descriptors)); | 2549 INLINE(int Search(String* name)); |
| 2598 | 2550 |
| 2599 // As the above, but uses DescriptorLookupCache and updates it when | 2551 // As the above, but uses DescriptorLookupCache and updates it when |
| 2600 // necessary. | 2552 // necessary. |
| 2601 INLINE(int SearchWithCache(String* name, Map* map)); | 2553 INLINE(int SearchWithCache(String* name)); |
| 2554 |
| 2555 // Tells whether the name is present int the array. |
| 2556 bool Contains(String* name) { return kNotFound != Search(name); } |
| 2602 | 2557 |
| 2603 // Allocates a DescriptorArray, but returns the singleton | 2558 // Allocates a DescriptorArray, but returns the singleton |
| 2604 // empty descriptor array object if number_of_descriptors is 0. | 2559 // empty descriptor array object if number_of_descriptors is 0. |
| 2605 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, | 2560 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); |
| 2606 int slack = 0); | |
| 2607 | 2561 |
| 2608 // Casting. | 2562 // Casting. |
| 2609 static inline DescriptorArray* cast(Object* obj); | 2563 static inline DescriptorArray* cast(Object* obj); |
| 2610 | 2564 |
| 2611 // Constant for denoting key was not found. | 2565 // Constant for denoting key was not found. |
| 2612 static const int kNotFound = -1; | 2566 static const int kNotFound = -1; |
| 2613 | 2567 |
| 2614 static const int kDescriptorLengthIndex = 0; | 2568 static const int kEnumCacheIndex = 0; |
| 2615 static const int kEnumCacheIndex = 1; | 2569 static const int kFirstIndex = 1; |
| 2616 static const int kFirstIndex = 2; | |
| 2617 | 2570 |
| 2618 // The length of the "bridge" to the enum cache. | 2571 // The length of the "bridge" to the enum cache. |
| 2619 static const int kEnumCacheBridgeLength = 2; | 2572 static const int kEnumCacheBridgeLength = 2; |
| 2620 static const int kEnumCacheBridgeCacheIndex = 0; | 2573 static const int kEnumCacheBridgeCacheIndex = 0; |
| 2621 static const int kEnumCacheBridgeIndicesCacheIndex = 1; | 2574 static const int kEnumCacheBridgeIndicesCacheIndex = 1; |
| 2622 | 2575 |
| 2623 // Layout description. | 2576 // Layout description. |
| 2624 static const int kDescriptorLengthOffset = FixedArray::kHeaderSize; | 2577 static const int kEnumCacheOffset = FixedArray::kHeaderSize; |
| 2625 static const int kEnumCacheOffset = kDescriptorLengthOffset + kPointerSize; | |
| 2626 static const int kFirstOffset = kEnumCacheOffset + kPointerSize; | 2578 static const int kFirstOffset = kEnumCacheOffset + kPointerSize; |
| 2627 | 2579 |
| 2628 // Layout description for the bridge array. | 2580 // Layout description for the bridge array. |
| 2629 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize; | 2581 static const int kEnumCacheBridgeCacheOffset = FixedArray::kHeaderSize; |
| 2630 | 2582 |
| 2631 // Layout of descriptor. | 2583 // Layout of descriptor. |
| 2632 static const int kDescriptorKey = 0; | 2584 static const int kDescriptorKey = 0; |
| 2633 static const int kDescriptorDetails = 1; | 2585 static const int kDescriptorDetails = 1; |
| 2634 static const int kDescriptorValue = 2; | 2586 static const int kDescriptorValue = 2; |
| 2635 static const int kDescriptorSize = 3; | 2587 static const int kDescriptorSize = 3; |
| 2636 | 2588 |
| 2637 #ifdef OBJECT_PRINT | 2589 #ifdef OBJECT_PRINT |
| 2638 // Print all the descriptors. | 2590 // Print all the descriptors. |
| 2639 inline void PrintDescriptors() { | 2591 inline void PrintDescriptors() { |
| 2640 PrintDescriptors(stdout); | 2592 PrintDescriptors(stdout); |
| 2641 } | 2593 } |
| 2642 void PrintDescriptors(FILE* out); | 2594 void PrintDescriptors(FILE* out); |
| 2643 #endif | 2595 #endif |
| 2644 | 2596 |
| 2645 #ifdef DEBUG | 2597 #ifdef DEBUG |
| 2646 // Is the descriptor array sorted and without duplicates? | 2598 // Is the descriptor array sorted and without duplicates? |
| 2647 bool IsSortedNoDuplicates(int valid_descriptors = -1); | 2599 bool IsSortedNoDuplicates(); |
| 2648 | 2600 |
| 2649 // Is the descriptor array consistent with the back pointers in targets? | 2601 // Is the descriptor array consistent with the back pointers in targets? |
| 2650 bool IsConsistentWithBackPointers(Map* current_map); | 2602 bool IsConsistentWithBackPointers(Map* current_map); |
| 2651 | 2603 |
| 2652 // Are two DescriptorArrays equal? | 2604 // Are two DescriptorArrays equal? |
| 2653 bool IsEqualTo(DescriptorArray* other); | 2605 bool IsEqualTo(DescriptorArray* other); |
| 2654 #endif | 2606 #endif |
| 2655 | 2607 |
| 2656 // The maximum number of descriptors we want in a descriptor array (should | 2608 // The maximum number of descriptors we want in a descriptor array (should |
| 2657 // fit in a page). | 2609 // fit in a page). |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2690 (descriptor_number * kDescriptorSize) + | 2642 (descriptor_number * kDescriptorSize) + |
| 2691 kDescriptorDetails; | 2643 kDescriptorDetails; |
| 2692 } | 2644 } |
| 2693 | 2645 |
| 2694 static int ToValueIndex(int descriptor_number) { | 2646 static int ToValueIndex(int descriptor_number) { |
| 2695 return kFirstIndex + | 2647 return kFirstIndex + |
| 2696 (descriptor_number * kDescriptorSize) + | 2648 (descriptor_number * kDescriptorSize) + |
| 2697 kDescriptorValue; | 2649 kDescriptorValue; |
| 2698 } | 2650 } |
| 2699 | 2651 |
| 2652 // Swap operation on FixedArray without using write barriers. |
| 2653 static inline void NoIncrementalWriteBarrierSwap( |
| 2654 FixedArray* array, int first, int second); |
| 2655 |
| 2700 // Swap first and second descriptor. | 2656 // Swap first and second descriptor. |
| 2701 inline void SwapSortedKeys(int first, int second); | 2657 inline void NoIncrementalWriteBarrierSwapDescriptors( |
| 2658 int first, int second); |
| 2702 | 2659 |
| 2703 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); | 2660 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); |
| 2704 }; | 2661 }; |
| 2705 | 2662 |
| 2706 | 2663 |
| 2707 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES }; | 2664 template<typename T> |
| 2708 | 2665 inline int LinearSearch(T* array, String* name, int len); |
| 2709 template<SearchMode search_mode, typename T> | |
| 2710 inline int LinearSearch(T* array, String* name, int len, int valid_entries); | |
| 2711 | 2666 |
| 2712 | 2667 |
| 2713 template<SearchMode search_mode, typename T> | 2668 template<typename T> |
| 2714 inline int Search(T* array, String* name, int valid_entries = 0); | 2669 inline int Search(T* array, String* name); |
| 2715 | 2670 |
| 2716 | 2671 |
| 2717 // HashTable is a subclass of FixedArray that implements a hash table | 2672 // HashTable is a subclass of FixedArray that implements a hash table |
| 2718 // that uses open addressing and quadratic probing. | 2673 // that uses open addressing and quadratic probing. |
| 2719 // | 2674 // |
| 2720 // In order for the quadratic probing to work, elements that have not | 2675 // In order for the quadratic probing to work, elements that have not |
| 2721 // yet been used and elements that have been deleted are | 2676 // yet been used and elements that have been deleted are |
| 2722 // distinguished. Probing continues when deleted elements are | 2677 // distinguished. Probing continues when deleted elements are |
| 2723 // encountered and stops when unused elements are encountered. | 2678 // encountered and stops when unused elements are encountered. |
| 2724 // | 2679 // |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2906 set(kCapacityIndex, Smi::FromInt(capacity)); | 2861 set(kCapacityIndex, Smi::FromInt(capacity)); |
| 2907 } | 2862 } |
| 2908 | 2863 |
| 2909 | 2864 |
| 2910 // Returns probe entry. | 2865 // Returns probe entry. |
| 2911 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { | 2866 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { |
| 2912 ASSERT(IsPowerOf2(size)); | 2867 ASSERT(IsPowerOf2(size)); |
| 2913 return (hash + GetProbeOffset(number)) & (size - 1); | 2868 return (hash + GetProbeOffset(number)) & (size - 1); |
| 2914 } | 2869 } |
| 2915 | 2870 |
| 2916 inline static uint32_t FirstProbe(uint32_t hash, uint32_t size) { | 2871 static uint32_t FirstProbe(uint32_t hash, uint32_t size) { |
| 2917 return hash & (size - 1); | 2872 return hash & (size - 1); |
| 2918 } | 2873 } |
| 2919 | 2874 |
| 2920 inline static uint32_t NextProbe( | 2875 static uint32_t NextProbe(uint32_t last, uint32_t number, uint32_t size) { |
| 2921 uint32_t last, uint32_t number, uint32_t size) { | |
| 2922 return (last + number) & (size - 1); | 2876 return (last + number) & (size - 1); |
| 2923 } | 2877 } |
| 2924 | 2878 |
| 2925 // Rehashes this hash-table into the new table. | 2879 // Rehashes this hash-table into the new table. |
| 2926 MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key); | 2880 MUST_USE_RESULT MaybeObject* Rehash(HashTable* new_table, Key key); |
| 2927 | 2881 |
| 2928 // Attempt to shrink hash table after removal of key. | 2882 // Attempt to shrink hash table after removal of key. |
| 2929 MUST_USE_RESULT MaybeObject* Shrink(Key key); | 2883 MUST_USE_RESULT MaybeObject* Shrink(Key key); |
| 2930 | 2884 |
| 2931 // Ensure enough space for n additional elements. | 2885 // Ensure enough space for n additional elements. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2998 // parameter. | 2952 // parameter. |
| 2999 bool LookupSymbolIfExists(String* str, String** symbol); | 2953 bool LookupSymbolIfExists(String* str, String** symbol); |
| 3000 bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol); | 2954 bool LookupTwoCharsSymbolIfExists(uint32_t c1, uint32_t c2, String** symbol); |
| 3001 | 2955 |
| 3002 // Casting. | 2956 // Casting. |
| 3003 static inline SymbolTable* cast(Object* obj); | 2957 static inline SymbolTable* cast(Object* obj); |
| 3004 | 2958 |
| 3005 private: | 2959 private: |
| 3006 MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s); | 2960 MUST_USE_RESULT MaybeObject* LookupKey(HashTableKey* key, Object** s); |
| 3007 | 2961 |
| 3008 template <bool seq_ascii> friend class JsonParser; | |
| 3009 | |
| 3010 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); | 2962 DISALLOW_IMPLICIT_CONSTRUCTORS(SymbolTable); |
| 3011 }; | 2963 }; |
| 3012 | 2964 |
| 3013 | 2965 |
| 3014 class MapCacheShape : public BaseShape<HashTableKey*> { | 2966 class MapCacheShape : public BaseShape<HashTableKey*> { |
| 3015 public: | 2967 public: |
| 3016 static inline bool IsMatch(HashTableKey* key, Object* value) { | 2968 static inline bool IsMatch(HashTableKey* key, Object* value) { |
| 3017 return key->IsMatch(value); | 2969 return key->IsMatch(value); |
| 3018 } | 2970 } |
| 3019 static inline uint32_t Hash(HashTableKey* key) { | 2971 static inline uint32_t Hash(HashTableKey* key) { |
| (...skipping 1693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4713 | 4665 |
| 4714 // Bit field 3. | 4666 // Bit field 3. |
| 4715 inline int bit_field3(); | 4667 inline int bit_field3(); |
| 4716 inline void set_bit_field3(int value); | 4668 inline void set_bit_field3(int value); |
| 4717 | 4669 |
| 4718 class EnumLengthBits: public BitField<int, 0, 11> {}; | 4670 class EnumLengthBits: public BitField<int, 0, 11> {}; |
| 4719 class NumberOfOwnDescriptorsBits: public BitField<int, 11, 11> {}; | 4671 class NumberOfOwnDescriptorsBits: public BitField<int, 11, 11> {}; |
| 4720 class IsShared: public BitField<bool, 22, 1> {}; | 4672 class IsShared: public BitField<bool, 22, 1> {}; |
| 4721 class FunctionWithPrototype: public BitField<bool, 23, 1> {}; | 4673 class FunctionWithPrototype: public BitField<bool, 23, 1> {}; |
| 4722 class DictionaryMap: public BitField<bool, 24, 1> {}; | 4674 class DictionaryMap: public BitField<bool, 24, 1> {}; |
| 4723 class OwnsDescriptors: public BitField<bool, 25, 1> {}; | |
| 4724 | 4675 |
| 4725 // Tells whether the object in the prototype property will be used | 4676 // Tells whether the object in the prototype property will be used |
| 4726 // for instances created from this function. If the prototype | 4677 // for instances created from this function. If the prototype |
| 4727 // property is set to a value that is not a JSObject, the prototype | 4678 // property is set to a value that is not a JSObject, the prototype |
| 4728 // property will not be used to create instances of the function. | 4679 // property will not be used to create instances of the function. |
| 4729 // See ECMA-262, 13.2.2. | 4680 // See ECMA-262, 13.2.2. |
| 4730 inline void set_non_instance_prototype(bool value); | 4681 inline void set_non_instance_prototype(bool value); |
| 4731 inline bool has_non_instance_prototype(); | 4682 inline bool has_non_instance_prototype(); |
| 4732 | 4683 |
| 4733 // Tells whether function has special prototype property. If not, prototype | 4684 // Tells whether function has special prototype property. If not, prototype |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4834 } | 4785 } |
| 4835 | 4786 |
| 4836 inline bool has_slow_elements_kind() { | 4787 inline bool has_slow_elements_kind() { |
| 4837 return elements_kind() == DICTIONARY_ELEMENTS | 4788 return elements_kind() == DICTIONARY_ELEMENTS |
| 4838 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; | 4789 || elements_kind() == NON_STRICT_ARGUMENTS_ELEMENTS; |
| 4839 } | 4790 } |
| 4840 | 4791 |
| 4841 static bool IsValidElementsTransition(ElementsKind from_kind, | 4792 static bool IsValidElementsTransition(ElementsKind from_kind, |
| 4842 ElementsKind to_kind); | 4793 ElementsKind to_kind); |
| 4843 | 4794 |
| 4844 bool StoresOwnDescriptors() { return HasTransitionArray(); } | |
| 4845 inline bool HasTransitionArray(); | 4795 inline bool HasTransitionArray(); |
| 4846 inline bool HasElementsTransition(); | 4796 inline bool HasElementsTransition(); |
| 4847 inline Map* elements_transition_map(); | 4797 inline Map* elements_transition_map(); |
| 4848 MUST_USE_RESULT inline MaybeObject* set_elements_transition_map( | 4798 MUST_USE_RESULT inline MaybeObject* set_elements_transition_map( |
| 4849 Map* transitioned_map); | 4799 Map* transitioned_map); |
| 4850 inline void SetTransition(int transition_index, Map* target); | 4800 inline void SetTransition(int index, Map* target); |
| 4851 inline Map* GetTransition(int transition_index); | 4801 MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, Map* target); |
| 4852 MUST_USE_RESULT inline MaybeObject* AddTransition(String* key, | |
| 4853 Map* target, | |
| 4854 SimpleTransitionFlag flag); | |
| 4855 DECL_ACCESSORS(transitions, TransitionArray) | 4802 DECL_ACCESSORS(transitions, TransitionArray) |
| 4856 inline void ClearTransitions(Heap* heap, | 4803 inline void ClearTransitions(Heap* heap, |
| 4857 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); | 4804 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
| 4858 | 4805 |
| 4859 // Tells whether the map is attached to SharedFunctionInfo | 4806 // Tells whether the map is attached to SharedFunctionInfo |
| 4860 // (for inobject slack tracking). | 4807 // (for inobject slack tracking). |
| 4861 inline void set_attached_to_shared_function_info(bool value); | 4808 inline void set_attached_to_shared_function_info(bool value); |
| 4862 | 4809 |
| 4863 inline bool attached_to_shared_function_info(); | 4810 inline bool attached_to_shared_function_info(); |
| 4864 | 4811 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4883 // [prototype]: implicit prototype object. | 4830 // [prototype]: implicit prototype object. |
| 4884 DECL_ACCESSORS(prototype, Object) | 4831 DECL_ACCESSORS(prototype, Object) |
| 4885 | 4832 |
| 4886 // [constructor]: points back to the function responsible for this map. | 4833 // [constructor]: points back to the function responsible for this map. |
| 4887 DECL_ACCESSORS(constructor, Object) | 4834 DECL_ACCESSORS(constructor, Object) |
| 4888 | 4835 |
| 4889 inline JSFunction* unchecked_constructor(); | 4836 inline JSFunction* unchecked_constructor(); |
| 4890 | 4837 |
| 4891 // [instance descriptors]: describes the object. | 4838 // [instance descriptors]: describes the object. |
| 4892 inline DescriptorArray* instance_descriptors(); | 4839 inline DescriptorArray* instance_descriptors(); |
| 4893 inline JSGlobalPropertyCell* descriptors_pointer(); | |
| 4894 MUST_USE_RESULT inline MaybeObject* SetDescriptors( | 4840 MUST_USE_RESULT inline MaybeObject* SetDescriptors( |
| 4895 DescriptorArray* descriptors); | 4841 DescriptorArray* descriptors, |
| 4842 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
| 4896 static void SetDescriptors(Handle<Map> map, | 4843 static void SetDescriptors(Handle<Map> map, |
| 4897 Handle<DescriptorArray> descriptors); | 4844 Handle<DescriptorArray> descriptors); |
| 4898 MUST_USE_RESULT inline MaybeObject* InitializeDescriptors( | 4845 MUST_USE_RESULT inline MaybeObject* InitializeDescriptors( |
| 4899 DescriptorArray* descriptors); | 4846 DescriptorArray* descriptors); |
| 4900 | 4847 |
| 4901 // [stub cache]: contains stubs compiled for this map. | 4848 // [stub cache]: contains stubs compiled for this map. |
| 4902 DECL_ACCESSORS(code_cache, Object) | 4849 DECL_ACCESSORS(code_cache, Object) |
| 4903 | 4850 |
| 4904 // [back pointer]: points back to the parent map from which a transition | 4851 // [back pointer]: points back to the parent map from which a transition |
| 4905 // leads to this map. The field overlaps with prototype transitions and the | 4852 // leads to this map. The field overlaps with prototype transitions and the |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4966 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 4913 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
| 4967 ASSERT(number_of_own_descriptors > 0); | 4914 ASSERT(number_of_own_descriptors > 0); |
| 4968 return number_of_own_descriptors - 1; | 4915 return number_of_own_descriptors - 1; |
| 4969 } | 4916 } |
| 4970 | 4917 |
| 4971 int NumberOfOwnDescriptors() { | 4918 int NumberOfOwnDescriptors() { |
| 4972 return NumberOfOwnDescriptorsBits::decode(bit_field3()); | 4919 return NumberOfOwnDescriptorsBits::decode(bit_field3()); |
| 4973 } | 4920 } |
| 4974 | 4921 |
| 4975 void SetNumberOfOwnDescriptors(int number) { | 4922 void SetNumberOfOwnDescriptors(int number) { |
| 4976 ASSERT(number <= instance_descriptors()->number_of_descriptors()); | |
| 4977 set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number)); | 4923 set_bit_field3(NumberOfOwnDescriptorsBits::update(bit_field3(), number)); |
| 4978 } | 4924 } |
| 4979 | 4925 |
| 4980 inline JSGlobalPropertyCell* RetrieveDescriptorsPointer(); | |
| 4981 | |
| 4982 int EnumLength() { | 4926 int EnumLength() { |
| 4983 return EnumLengthBits::decode(bit_field3()); | 4927 return EnumLengthBits::decode(bit_field3()); |
| 4984 } | 4928 } |
| 4985 | 4929 |
| 4986 void SetEnumLength(int length) { | 4930 void SetEnumLength(int index) { |
| 4987 if (length != kInvalidEnumCache) { | 4931 set_bit_field3(EnumLengthBits::update(bit_field3(), index)); |
| 4988 ASSERT(length >= 0); | |
| 4989 ASSERT(length == 0 || instance_descriptors()->HasEnumCache()); | |
| 4990 ASSERT(length <= NumberOfOwnDescriptors()); | |
| 4991 } | |
| 4992 set_bit_field3(EnumLengthBits::update(bit_field3(), length)); | |
| 4993 } | 4932 } |
| 4994 | 4933 |
| 4995 | |
| 4996 inline bool owns_descriptors(); | |
| 4997 inline void set_owns_descriptors(bool is_shared); | |
| 4998 | |
| 4999 MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); | 4934 MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); |
| 5000 MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); | 4935 MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); |
| 5001 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); | 4936 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); |
| 5002 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( | 4937 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( |
| 5003 DescriptorArray* descriptors, | 4938 DescriptorArray* descriptors, |
| 5004 String* name, | 4939 String* name, |
| 5005 TransitionFlag flag, | 4940 TransitionFlag flag); |
| 5006 int descriptor_index); | |
| 5007 MUST_USE_RESULT MaybeObject* ShareDescriptor(Descriptor* descriptor); | |
| 5008 MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, | 4941 MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, |
| 5009 TransitionFlag flag); | 4942 TransitionFlag flag); |
| 5010 MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor, | 4943 MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor, |
| 5011 TransitionFlag flag); | 4944 TransitionFlag flag); |
| 5012 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(Descriptor* descriptor, | 4945 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(Descriptor* descriptor, |
| 5013 int index, | 4946 int index, |
| 5014 TransitionFlag flag); | 4947 TransitionFlag flag); |
| 5015 MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind, | 4948 MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind, |
| 5016 TransitionFlag flag); | 4949 TransitionFlag flag); |
| 5017 | 4950 |
| 5018 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, | 4951 MUST_USE_RESULT MaybeObject* CopyNormalized(PropertyNormalizationMode mode, |
| 5019 NormalizedMapSharingMode sharing); | 4952 NormalizedMapSharingMode sharing); |
| 5020 | 4953 |
| 5021 inline void AppendDescriptor(Descriptor* desc, | 4954 inline void AppendDescriptor(Descriptor* desc, |
| 5022 const DescriptorArray::WhitenessWitness&); | 4955 const DescriptorArray::WhitenessWitness&); |
| 5023 | 4956 |
| 5024 // Returns a copy of the map, with all transitions dropped from the | 4957 // Returns a copy of the map, with all transitions dropped from the |
| 5025 // instance descriptors. | 4958 // instance descriptors. |
| 5026 MUST_USE_RESULT MaybeObject* Copy(); | 4959 MUST_USE_RESULT MaybeObject* Copy(); |
| 5027 | 4960 |
| 5028 // Returns the property index for name (only valid for FAST MODE). | 4961 // Returns the property index for name (only valid for FAST MODE). |
| 5029 int PropertyIndexFor(String* name); | 4962 int PropertyIndexFor(String* name); |
| 5030 | 4963 |
| 5031 // Returns the next free property index (only valid for FAST MODE). | 4964 // Returns the next free property index (only valid for FAST MODE). |
| 5032 int NextFreePropertyIndex(); | 4965 int NextFreePropertyIndex(); |
| 5033 | 4966 |
| 5034 // Returns the number of properties described in instance_descriptors | 4967 // Returns the number of properties described in instance_descriptors |
| 5035 // filtering out properties with the specified attributes. | 4968 // filtering out properties with the specified attributes. |
| 5036 int NumberOfDescribedProperties(DescriptorFlag which = OWN_DESCRIPTORS, | 4969 int NumberOfDescribedProperties(PropertyAttributes filter = NONE); |
| 5037 PropertyAttributes filter = NONE); | |
| 5038 | 4970 |
| 5039 // Casting. | 4971 // Casting. |
| 5040 static inline Map* cast(Object* obj); | 4972 static inline Map* cast(Object* obj); |
| 5041 | 4973 |
| 5042 // Locate an accessor in the instance descriptor. | 4974 // Locate an accessor in the instance descriptor. |
| 5043 AccessorDescriptor* FindAccessor(String* name); | 4975 AccessorDescriptor* FindAccessor(String* name); |
| 5044 | 4976 |
| 5045 // Code cache operations. | 4977 // Code cache operations. |
| 5046 | 4978 |
| 5047 // Clears the code cache. | 4979 // Clears the code cache. |
| 5048 inline void ClearCodeCache(Heap* heap); | 4980 inline void ClearCodeCache(Heap* heap); |
| 5049 | 4981 |
| 5050 // Update code cache. | 4982 // Update code cache. |
| 5051 static void UpdateCodeCache(Handle<Map> map, | 4983 static void UpdateCodeCache(Handle<Map> map, |
| 5052 Handle<String> name, | 4984 Handle<String> name, |
| 5053 Handle<Code> code); | 4985 Handle<Code> code); |
| 5054 MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code); | 4986 MUST_USE_RESULT MaybeObject* UpdateCodeCache(String* name, Code* code); |
| 5055 | 4987 |
| 5056 // Extend the descriptor array of the map with the list of descriptors. | 4988 // Extend the descriptor array of the map with the list of descriptors. |
| 5057 // In case of duplicates, the latest descriptor is used. | 4989 // In case of duplicates, the latest descriptor is used. |
| 5058 static void AppendCallbackDescriptors(Handle<Map> map, | 4990 static void CopyAppendCallbackDescriptors(Handle<Map> map, |
| 5059 Handle<Object> descriptors); | 4991 Handle<Object> descriptors); |
| 5060 | |
| 5061 static void EnsureDescriptorSlack(Handle<Map> map, int slack); | |
| 5062 | 4992 |
| 5063 // Returns the found code or undefined if absent. | 4993 // Returns the found code or undefined if absent. |
| 5064 Object* FindInCodeCache(String* name, Code::Flags flags); | 4994 Object* FindInCodeCache(String* name, Code::Flags flags); |
| 5065 | 4995 |
| 5066 // Returns the non-negative index of the code object if it is in the | 4996 // Returns the non-negative index of the code object if it is in the |
| 5067 // cache and -1 otherwise. | 4997 // cache and -1 otherwise. |
| 5068 int IndexInCodeCache(Object* name, Code* code); | 4998 int IndexInCodeCache(Object* name, Code* code); |
| 5069 | 4999 |
| 5070 // Removes a code object from the code cache at the given index. | 5000 // Removes a code object from the code cache at the given index. |
| 5071 void RemoveFromCodeCache(String* name, Code* code, int index); | 5001 void RemoveFromCodeCache(String* name, Code* code, int index); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5133 // and the values are the maps the are transitioned to. | 5063 // and the values are the maps the are transitioned to. |
| 5134 static const int kMaxCachedPrototypeTransitions = 256; | 5064 static const int kMaxCachedPrototypeTransitions = 256; |
| 5135 | 5065 |
| 5136 Map* GetPrototypeTransition(Object* prototype); | 5066 Map* GetPrototypeTransition(Object* prototype); |
| 5137 | 5067 |
| 5138 MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype, | 5068 MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype, |
| 5139 Map* map); | 5069 Map* map); |
| 5140 | 5070 |
| 5141 static const int kMaxPreAllocatedPropertyFields = 255; | 5071 static const int kMaxPreAllocatedPropertyFields = 255; |
| 5142 | 5072 |
| 5143 // Constant for denoting that the enum cache is not yet initialized. | 5073 // Constant for denoting that the Enum Cache field was not yet used. |
| 5144 static const int kInvalidEnumCache = EnumLengthBits::kMax; | 5074 static const int kInvalidEnumCache = EnumLengthBits::kMax; |
| 5145 | 5075 |
| 5146 // Layout description. | 5076 // Layout description. |
| 5147 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 5077 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
| 5148 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 5078 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
| 5149 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; | 5079 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; |
| 5150 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; | 5080 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; |
| 5151 // Storage for the transition array is overloaded to directly contain a back | 5081 // Storage for the transition array is overloaded to directly contain a back |
| 5152 // pointer if unused. When the map has transitions, the back pointer is | 5082 // pointer if unused. When the map has transitions, the back pointer is |
| 5153 // transferred to the transition array and accessed through an extra | 5083 // transferred to the transition array and accessed through an extra |
| (...skipping 1896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7050 void AddSurrogatePairNoIndex(uc32 c); | 6980 void AddSurrogatePairNoIndex(uc32 c); |
| 7051 | 6981 |
| 7052 // Returns the value to store in the hash field of a string with | 6982 // Returns the value to store in the hash field of a string with |
| 7053 // the given length and contents. | 6983 // the given length and contents. |
| 7054 uint32_t GetHashField(); | 6984 uint32_t GetHashField(); |
| 7055 | 6985 |
| 7056 // Returns true if the characters seen so far make up a legal array | 6986 // Returns true if the characters seen so far make up a legal array |
| 7057 // index. | 6987 // index. |
| 7058 bool is_array_index() { return is_array_index_; } | 6988 bool is_array_index() { return is_array_index_; } |
| 7059 | 6989 |
| 6990 bool is_valid() { return is_valid_; } |
| 6991 |
| 6992 void invalidate() { is_valid_ = false; } |
| 6993 |
| 7060 // Calculated hash value for a string consisting of 1 to | 6994 // Calculated hash value for a string consisting of 1 to |
| 7061 // String::kMaxArrayIndexSize digits with no leading zeros (except "0"). | 6995 // String::kMaxArrayIndexSize digits with no leading zeros (except "0"). |
| 7062 // value is represented decimal value. | 6996 // value is represented decimal value. |
| 7063 static uint32_t MakeArrayIndexHash(uint32_t value, int length); | 6997 static uint32_t MakeArrayIndexHash(uint32_t value, int length); |
| 7064 | 6998 |
| 7065 // No string is allowed to have a hash of zero. That value is reserved | 6999 // No string is allowed to have a hash of zero. That value is reserved |
| 7066 // for internal properties. If the hash calculation yields zero then we | 7000 // for internal properties. If the hash calculation yields zero then we |
| 7067 // use 27 instead. | 7001 // use 27 instead. |
| 7068 static const int kZeroHash = 27; | 7002 static const int kZeroHash = 27; |
| 7069 | 7003 |
| 7070 private: | 7004 private: |
| 7071 uint32_t array_index() { | 7005 uint32_t array_index() { |
| 7072 ASSERT(is_array_index()); | 7006 ASSERT(is_array_index()); |
| 7073 return array_index_; | 7007 return array_index_; |
| 7074 } | 7008 } |
| 7075 | 7009 |
| 7076 inline uint32_t GetHash(); | 7010 inline uint32_t GetHash(); |
| 7077 | 7011 |
| 7078 // Reusable parts of the hashing algorithm. | |
| 7079 INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint32_t c)); | |
| 7080 INLINE(static uint32_t GetHashCore(uint32_t running_hash)); | |
| 7081 | |
| 7082 int length_; | 7012 int length_; |
| 7083 uint32_t raw_running_hash_; | 7013 uint32_t raw_running_hash_; |
| 7084 uint32_t array_index_; | 7014 uint32_t array_index_; |
| 7085 bool is_array_index_; | 7015 bool is_array_index_; |
| 7086 bool is_first_char_; | 7016 bool is_first_char_; |
| 7017 bool is_valid_; |
| 7087 friend class TwoCharHashTableKey; | 7018 friend class TwoCharHashTableKey; |
| 7088 | |
| 7089 template <bool seq_ascii> friend class JsonParser; | |
| 7090 }; | 7019 }; |
| 7091 | 7020 |
| 7092 | 7021 |
| 7093 class IncrementalAsciiStringHasher { | |
| 7094 public: | |
| 7095 explicit inline IncrementalAsciiStringHasher(uint32_t seed, char first_char); | |
| 7096 inline void AddCharacter(uc32 c); | |
| 7097 inline uint32_t GetHash(); | |
| 7098 | |
| 7099 private: | |
| 7100 int length_; | |
| 7101 uint32_t raw_running_hash_; | |
| 7102 uint32_t array_index_; | |
| 7103 bool is_array_index_; | |
| 7104 char first_char_; | |
| 7105 }; | |
| 7106 | |
| 7107 | |
| 7108 // Calculates string hash. | 7022 // Calculates string hash. |
| 7109 template <typename schar> | 7023 template <typename schar> |
| 7110 inline uint32_t HashSequentialString(const schar* chars, | 7024 inline uint32_t HashSequentialString(const schar* chars, |
| 7111 int length, | 7025 int length, |
| 7112 uint32_t seed); | 7026 uint32_t seed); |
| 7113 | 7027 |
| 7114 | 7028 |
| 7115 // The characteristics of a string are stored in its map. Retrieving these | 7029 // The characteristics of a string are stored in its map. Retrieving these |
| 7116 // few bits of information is moderately expensive, involving two memory | 7030 // few bits of information is moderately expensive, involving two memory |
| 7117 // loads where the second is dependent on the first. To improve efficiency | 7031 // loads where the second is dependent on the first. To improve efficiency |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7465 static void WriteToFlat(String* source, | 7379 static void WriteToFlat(String* source, |
| 7466 sinkchar* sink, | 7380 sinkchar* sink, |
| 7467 int from, | 7381 int from, |
| 7468 int to); | 7382 int to); |
| 7469 | 7383 |
| 7470 static inline bool IsAscii(const char* chars, int length) { | 7384 static inline bool IsAscii(const char* chars, int length) { |
| 7471 const char* limit = chars + length; | 7385 const char* limit = chars + length; |
| 7472 #ifdef V8_HOST_CAN_READ_UNALIGNED | 7386 #ifdef V8_HOST_CAN_READ_UNALIGNED |
| 7473 ASSERT(kMaxAsciiCharCode == 0x7F); | 7387 ASSERT(kMaxAsciiCharCode == 0x7F); |
| 7474 const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80; | 7388 const uintptr_t non_ascii_mask = kUintptrAllBitsSet / 0xFF * 0x80; |
| 7475 while (chars + sizeof(uintptr_t) <= limit) { | 7389 while (chars <= limit - sizeof(uintptr_t)) { |
| 7476 if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) { | 7390 if (*reinterpret_cast<const uintptr_t*>(chars) & non_ascii_mask) { |
| 7477 return false; | 7391 return false; |
| 7478 } | 7392 } |
| 7479 chars += sizeof(uintptr_t); | 7393 chars += sizeof(uintptr_t); |
| 7480 } | 7394 } |
| 7481 #endif | 7395 #endif |
| 7482 while (chars < limit) { | 7396 while (chars < limit) { |
| 7483 if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false; | 7397 if (static_cast<uint8_t>(*chars) > kMaxAsciiCharCodeU) return false; |
| 7484 ++chars; | 7398 ++chars; |
| 7485 } | 7399 } |
| (...skipping 1552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9038 } else { | 8952 } else { |
| 9039 value &= ~(1 << bit_position); | 8953 value &= ~(1 << bit_position); |
| 9040 } | 8954 } |
| 9041 return value; | 8955 return value; |
| 9042 } | 8956 } |
| 9043 }; | 8957 }; |
| 9044 | 8958 |
| 9045 } } // namespace v8::internal | 8959 } } // namespace v8::internal |
| 9046 | 8960 |
| 9047 #endif // V8_OBJECTS_H_ | 8961 #endif // V8_OBJECTS_H_ |
| OLD | NEW |