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

Side by Side Diff: src/objects.h

Issue 11028027: Revert trunk to bleeding_edge at r12484 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/mksnapshot.cc ('k') | src/objects.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/mksnapshot.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698