OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 22 matching lines...) Expand all Loading... | |
33 #include "list.h" | 33 #include "list.h" |
34 #include "smart-array-pointer.h" | 34 #include "smart-array-pointer.h" |
35 #include "unicode-inl.h" | 35 #include "unicode-inl.h" |
36 #if V8_TARGET_ARCH_ARM | 36 #if V8_TARGET_ARCH_ARM |
37 #include "arm/constants-arm.h" | 37 #include "arm/constants-arm.h" |
38 #elif V8_TARGET_ARCH_MIPS | 38 #elif V8_TARGET_ARCH_MIPS |
39 #include "mips/constants-mips.h" | 39 #include "mips/constants-mips.h" |
40 #endif | 40 #endif |
41 #include "v8checks.h" | 41 #include "v8checks.h" |
42 | 42 |
43 | |
43 // | 44 // |
44 // Most object types in the V8 JavaScript are described in this file. | 45 // Most object types in the V8 JavaScript are described in this file. |
45 // | 46 // |
46 // Inheritance hierarchy: | 47 // Inheritance hierarchy: |
47 // - MaybeObject (an object or a failure) | 48 // - MaybeObject (an object or a failure) |
48 // - Failure (immediate for marking failed operation) | 49 // - Failure (immediate for marking failed operation) |
49 // - Object | 50 // - Object |
50 // - Smi (immediate small integer) | 51 // - Smi (immediate small integer) |
51 // - HeapObject (superclass for everything allocated in the heap) | 52 // - HeapObject (superclass for everything allocated in the heap) |
52 // - JSReceiver (suitable for property access) | 53 // - JSReceiver (suitable for property access) |
(...skipping 2126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2179 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { | 2180 class BodyDescriptor : public FlexibleBodyDescriptor<kHeaderSize> { |
2180 public: | 2181 public: |
2181 static inline int SizeOf(Map* map, HeapObject* object) { | 2182 static inline int SizeOf(Map* map, HeapObject* object) { |
2182 return SizeFor(reinterpret_cast<FixedArray*>(object)->length()); | 2183 return SizeFor(reinterpret_cast<FixedArray*>(object)->length()); |
2183 } | 2184 } |
2184 }; | 2185 }; |
2185 | 2186 |
2186 protected: | 2187 protected: |
2187 // Set operation on FixedArray without using write barriers. Can | 2188 // Set operation on FixedArray without using write barriers. Can |
2188 // only be used for storing old space objects or smis. | 2189 // only be used for storing old space objects or smis. |
2189 static inline void fast_set(FixedArray* array, int index, Object* value); | 2190 static inline void NoWriteBarrierSet(FixedArray* array, |
2191 int index, | |
2192 Object* value); | |
2190 | 2193 |
2191 private: | 2194 private: |
2192 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); | 2195 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); |
2193 }; | 2196 }; |
2194 | 2197 |
2195 | 2198 |
2196 // FixedDoubleArray describes fixed-sized arrays with element type double. | 2199 // FixedDoubleArray describes fixed-sized arrays with element type double. |
2197 class FixedDoubleArray: public FixedArrayBase { | 2200 class FixedDoubleArray: public FixedArrayBase { |
2198 public: | 2201 public: |
2199 inline void Initialize(FixedArray* from); | 2202 inline void Initialize(FixedArray* from); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2244 | 2247 |
2245 #ifdef DEBUG | 2248 #ifdef DEBUG |
2246 void FixedDoubleArrayVerify(); | 2249 void FixedDoubleArrayVerify(); |
2247 #endif | 2250 #endif |
2248 | 2251 |
2249 private: | 2252 private: |
2250 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray); | 2253 DISALLOW_IMPLICIT_CONSTRUCTORS(FixedDoubleArray); |
2251 }; | 2254 }; |
2252 | 2255 |
2253 | 2256 |
2257 class IncrementalMarking; | |
2258 | |
2259 | |
2254 // DescriptorArrays are fixed arrays used to hold instance descriptors. | 2260 // DescriptorArrays are fixed arrays used to hold instance descriptors. |
2255 // The format of the these objects is: | 2261 // The format of the these objects is: |
2256 // TODO(1399): It should be possible to make room for bit_field3 in the map | 2262 // TODO(1399): It should be possible to make room for bit_field3 in the map |
2257 // without overloading the instance descriptors field in the map | 2263 // without overloading the instance descriptors field in the map |
2258 // (and storing it in the DescriptorArray when the map has one). | 2264 // (and storing it in the DescriptorArray when the map has one). |
2259 // [0]: storage for bit_field3 for Map owning this object (Smi) | 2265 // [0]: storage for bit_field3 for Map owning this object (Smi) |
2260 // [1]: point to a fixed array with (value, detail) pairs. | 2266 // [1]: point to a fixed array with (value, detail) pairs. |
2261 // [2]: next enumeration index (Smi), or pointer to small fixed array: | 2267 // [2]: next enumeration index (Smi), or pointer to small fixed array: |
2262 // [0]: next enumeration index (Smi) | 2268 // [0]: next enumeration index (Smi) |
2263 // [1]: pointer to fixed array with enum cache | 2269 // [1]: pointer to fixed array with enum cache |
(...skipping 21 matching lines...) Expand all Loading... | |
2285 return Smi::cast(obj)->value(); | 2291 return Smi::cast(obj)->value(); |
2286 } else { | 2292 } else { |
2287 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); | 2293 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); |
2288 return Smi::cast(index)->value(); | 2294 return Smi::cast(index)->value(); |
2289 } | 2295 } |
2290 } | 2296 } |
2291 | 2297 |
2292 // Set next enumeration index and flush any enum cache. | 2298 // Set next enumeration index and flush any enum cache. |
2293 void SetNextEnumerationIndex(int value) { | 2299 void SetNextEnumerationIndex(int value) { |
2294 if (!IsEmpty()) { | 2300 if (!IsEmpty()) { |
2295 fast_set(this, kEnumerationIndexIndex, Smi::FromInt(value)); | 2301 NoWriteBarrierSet(this, kEnumerationIndexIndex, Smi::FromInt(value)); |
2296 } | 2302 } |
2297 } | 2303 } |
2298 bool HasEnumCache() { | 2304 bool HasEnumCache() { |
2299 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); | 2305 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); |
2300 } | 2306 } |
2301 | 2307 |
2302 Object* GetEnumCache() { | 2308 Object* GetEnumCache() { |
2303 ASSERT(HasEnumCache()); | 2309 ASSERT(HasEnumCache()); |
2304 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); | 2310 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); |
2305 return bridge->get(kEnumCacheBridgeCacheIndex); | 2311 return bridge->get(kEnumCacheBridgeCacheIndex); |
(...skipping 16 matching lines...) Expand all Loading... | |
2322 inline PropertyType GetType(int descriptor_number); | 2328 inline PropertyType GetType(int descriptor_number); |
2323 inline int GetFieldIndex(int descriptor_number); | 2329 inline int GetFieldIndex(int descriptor_number); |
2324 inline JSFunction* GetConstantFunction(int descriptor_number); | 2330 inline JSFunction* GetConstantFunction(int descriptor_number); |
2325 inline Object* GetCallbacksObject(int descriptor_number); | 2331 inline Object* GetCallbacksObject(int descriptor_number); |
2326 inline AccessorDescriptor* GetCallbacks(int descriptor_number); | 2332 inline AccessorDescriptor* GetCallbacks(int descriptor_number); |
2327 inline bool IsProperty(int descriptor_number); | 2333 inline bool IsProperty(int descriptor_number); |
2328 inline bool IsTransition(int descriptor_number); | 2334 inline bool IsTransition(int descriptor_number); |
2329 inline bool IsNullDescriptor(int descriptor_number); | 2335 inline bool IsNullDescriptor(int descriptor_number); |
2330 inline bool IsDontEnum(int descriptor_number); | 2336 inline bool IsDontEnum(int descriptor_number); |
2331 | 2337 |
2338 class WhitenessWitness { | |
2339 public: | |
2340 inline explicit WhitenessWitness(DescriptorArray* array); | |
2341 inline ~WhitenessWitness(); | |
2342 | |
2343 private: | |
2344 IncrementalMarking* marking_; | |
2345 }; | |
2346 | |
2332 // Accessor for complete descriptor. | 2347 // Accessor for complete descriptor. |
2333 inline void Get(int descriptor_number, Descriptor* desc); | 2348 inline void Get(int descriptor_number, Descriptor* desc); |
2334 inline void Set(int descriptor_number, Descriptor* desc); | 2349 inline void Set(int descriptor_number, |
2350 Descriptor* desc, | |
2351 const WhitenessWitness&); | |
2335 | 2352 |
2336 // Transfer complete descriptor from another descriptor array to | 2353 // Transfer complete descriptor from another descriptor array to |
2337 // this one. | 2354 // this one. |
2338 inline void CopyFrom(int index, DescriptorArray* src, int src_index); | 2355 inline void CopyFrom(int index, |
2356 DescriptorArray* src, | |
2357 int src_index, | |
2358 const WhitenessWitness&); | |
2339 | 2359 |
2340 // Copy the descriptor array, insert a new descriptor and optionally | 2360 // Copy the descriptor array, insert a new descriptor and optionally |
2341 // remove map transitions. If the descriptor is already present, it is | 2361 // remove map transitions. If the descriptor is already present, it is |
2342 // replaced. If a replaced descriptor is a real property (not a transition | 2362 // replaced. If a replaced descriptor is a real property (not a transition |
2343 // or null), its enumeration index is kept as is. | 2363 // or null), its enumeration index is kept as is. |
2344 // If adding a real property, map transitions must be removed. If adding | 2364 // If adding a real property, map transitions must be removed. If adding |
2345 // a transition, they must not be removed. All null descriptors are removed. | 2365 // a transition, they must not be removed. All null descriptors are removed. |
2346 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, | 2366 MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor, |
2347 TransitionFlag transition_flag); | 2367 TransitionFlag transition_flag); |
2348 | 2368 |
2349 // Remove all transitions. Return a copy of the array with all transitions | 2369 // Remove all transitions. Return a copy of the array with all transitions |
2350 // removed, or a Failure object if the new array could not be allocated. | 2370 // removed, or a Failure object if the new array could not be allocated. |
2351 MUST_USE_RESULT MaybeObject* RemoveTransitions(); | 2371 MUST_USE_RESULT MaybeObject* RemoveTransitions(); |
2352 | 2372 |
2353 // Sort the instance descriptors by the hash codes of their keys. | 2373 // Sort the instance descriptors by the hash codes of their keys. |
2354 // Does not check for duplicates. | 2374 // Does not check for duplicates. |
2355 void SortUnchecked(); | 2375 void SortUnchecked(const WhitenessWitness&); |
2356 | 2376 |
2357 // Sort the instance descriptors by the hash codes of their keys. | 2377 // Sort the instance descriptors by the hash codes of their keys. |
2358 // Checks the result for duplicates. | 2378 // Checks the result for duplicates. |
2359 void Sort(); | 2379 void Sort(const WhitenessWitness&); |
2360 | 2380 |
2361 // Search the instance descriptors for given name. | 2381 // Search the instance descriptors for given name. |
2362 inline int Search(String* name); | 2382 inline int Search(String* name); |
2363 | 2383 |
2364 // As the above, but uses DescriptorLookupCache and updates it when | 2384 // As the above, but uses DescriptorLookupCache and updates it when |
2365 // necessary. | 2385 // necessary. |
2366 inline int SearchWithCache(String* name); | 2386 inline int SearchWithCache(String* name); |
2367 | 2387 |
2368 // Tells whether the name is present int the array. | 2388 // Tells whether the name is present int the array. |
2369 bool Contains(String* name) { return kNotFound != Search(name); } | 2389 bool Contains(String* name) { return kNotFound != Search(name); } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2442 | 2462 |
2443 static int ToValueIndex(int descriptor_number) { | 2463 static int ToValueIndex(int descriptor_number) { |
2444 return descriptor_number << 1; | 2464 return descriptor_number << 1; |
2445 } | 2465 } |
2446 | 2466 |
2447 bool is_null_descriptor(int descriptor_number) { | 2467 bool is_null_descriptor(int descriptor_number) { |
2448 return PropertyDetails(GetDetails(descriptor_number)).type() == | 2468 return PropertyDetails(GetDetails(descriptor_number)).type() == |
2449 NULL_DESCRIPTOR; | 2469 NULL_DESCRIPTOR; |
2450 } | 2470 } |
2451 // Swap operation on FixedArray without using write barriers. | 2471 // Swap operation on FixedArray without using write barriers. |
2452 static inline void fast_swap(FixedArray* array, int first, int second); | 2472 static inline void NoWriteBarrierSwap(FixedArray* array, |
2473 int first, | |
2474 int second); | |
2453 | 2475 |
2454 // Swap descriptor first and second. | 2476 // Swap descriptor first and second. |
2455 inline void Swap(int first, int second); | 2477 inline void NoWriteBarrierSwapDescriptors(int first, int second); |
2456 | 2478 |
2457 FixedArray* GetContentArray() { | 2479 FixedArray* GetContentArray() { |
2458 return FixedArray::cast(get(kContentArrayIndex)); | 2480 return FixedArray::cast(get(kContentArrayIndex)); |
2459 } | 2481 } |
2460 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); | 2482 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); |
2461 }; | 2483 }; |
2462 | 2484 |
2463 | 2485 |
2464 // HashTable is a subclass of FixedArray that implements a hash table | 2486 // HashTable is a subclass of FixedArray that implements a hash table |
2465 // that uses open addressing and quadratic probing. | 2487 // that uses open addressing and quadratic probing. |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2587 // has the given hash value. | 2609 // has the given hash value. |
2588 uint32_t FindInsertionEntry(uint32_t hash); | 2610 uint32_t FindInsertionEntry(uint32_t hash); |
2589 | 2611 |
2590 // Returns the index for an entry (of the key) | 2612 // Returns the index for an entry (of the key) |
2591 static inline int EntryToIndex(int entry) { | 2613 static inline int EntryToIndex(int entry) { |
2592 return (entry * kEntrySize) + kElementsStartIndex; | 2614 return (entry * kEntrySize) + kElementsStartIndex; |
2593 } | 2615 } |
2594 | 2616 |
2595 // Update the number of elements in the hash table. | 2617 // Update the number of elements in the hash table. |
2596 void SetNumberOfElements(int nof) { | 2618 void SetNumberOfElements(int nof) { |
2597 fast_set(this, kNumberOfElementsIndex, Smi::FromInt(nof)); | 2619 NoWriteBarrierSet(this, kNumberOfElementsIndex, Smi::FromInt(nof)); |
2598 } | 2620 } |
2599 | 2621 |
2600 // Update the number of deleted elements in the hash table. | 2622 // Update the number of deleted elements in the hash table. |
2601 void SetNumberOfDeletedElements(int nod) { | 2623 void SetNumberOfDeletedElements(int nod) { |
2602 fast_set(this, kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); | 2624 NoWriteBarrierSet(this, kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); |
2603 } | 2625 } |
2604 | 2626 |
2605 // Sets the capacity of the hash table. | 2627 // Sets the capacity of the hash table. |
2606 void SetCapacity(int capacity) { | 2628 void SetCapacity(int capacity) { |
2607 // To scale a computed hash code to fit within the hash table, we | 2629 // To scale a computed hash code to fit within the hash table, we |
2608 // use bit-wise AND with a mask, so the capacity must be positive | 2630 // use bit-wise AND with a mask, so the capacity must be positive |
2609 // and non-zero. | 2631 // and non-zero. |
2610 ASSERT(capacity > 0); | 2632 ASSERT(capacity > 0); |
2611 ASSERT(capacity <= kMaxCapacity); | 2633 ASSERT(capacity <= kMaxCapacity); |
2612 fast_set(this, kCapacityIndex, Smi::FromInt(capacity)); | 2634 NoWriteBarrierSet(this, kCapacityIndex, Smi::FromInt(capacity)); |
2613 } | 2635 } |
2614 | 2636 |
2615 | 2637 |
2616 // Returns probe entry. | 2638 // Returns probe entry. |
2617 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { | 2639 static uint32_t GetProbe(uint32_t hash, uint32_t number, uint32_t size) { |
2618 ASSERT(IsPowerOf2(size)); | 2640 ASSERT(IsPowerOf2(size)); |
2619 return (hash + GetProbeOffset(number)) & (size - 1); | 2641 return (hash + GetProbeOffset(number)) & (size - 1); |
2620 } | 2642 } |
2621 | 2643 |
2622 static uint32_t FirstProbe(uint32_t hash, uint32_t size) { | 2644 static uint32_t FirstProbe(uint32_t hash, uint32_t size) { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2809 | 2831 |
2810 enum SortMode { UNSORTED, SORTED }; | 2832 enum SortMode { UNSORTED, SORTED }; |
2811 // Copies keys to preallocated fixed array. | 2833 // Copies keys to preallocated fixed array. |
2812 void CopyKeysTo(FixedArray* storage, | 2834 void CopyKeysTo(FixedArray* storage, |
2813 PropertyAttributes filter, | 2835 PropertyAttributes filter, |
2814 SortMode sort_mode); | 2836 SortMode sort_mode); |
2815 // Fill in details for properties into storage. | 2837 // Fill in details for properties into storage. |
2816 void CopyKeysTo(FixedArray* storage, int index, SortMode sort_mode); | 2838 void CopyKeysTo(FixedArray* storage, int index, SortMode sort_mode); |
2817 | 2839 |
2818 // Accessors for next enumeration index. | 2840 // Accessors for next enumeration index. |
2819 void SetNextEnumerationIndex(int index) { | 2841 void SetNextEnumerationIndex(int index) { |
Erik Corry
2011/10/21 10:17:43
You could just write this->set(kBlabla, Smi::FromI
| |
2820 this->fast_set(this, kNextEnumerationIndexIndex, Smi::FromInt(index)); | 2842 NoWriteBarrierSet(this, kNextEnumerationIndexIndex, Smi::FromInt(index)); |
2821 } | 2843 } |
2822 | 2844 |
2823 int NextEnumerationIndex() { | 2845 int NextEnumerationIndex() { |
2824 return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value(); | 2846 return Smi::cast(FixedArray::get(kNextEnumerationIndexIndex))->value(); |
2825 } | 2847 } |
2826 | 2848 |
2827 // Returns a new array for dictionary usage. Might return Failure. | 2849 // Returns a new array for dictionary usage. Might return Failure. |
2828 MUST_USE_RESULT static MaybeObject* Allocate(int at_least_space_for); | 2850 MUST_USE_RESULT static MaybeObject* Allocate(int at_least_space_for); |
2829 | 2851 |
2830 // Ensure enough space for n additional elements. | 2852 // Ensure enough space for n additional elements. |
(...skipping 4834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7665 } else { | 7687 } else { |
7666 value &= ~(1 << bit_position); | 7688 value &= ~(1 << bit_position); |
7667 } | 7689 } |
7668 return value; | 7690 return value; |
7669 } | 7691 } |
7670 }; | 7692 }; |
7671 | 7693 |
7672 } } // namespace v8::internal | 7694 } } // namespace v8::internal |
7673 | 7695 |
7674 #endif // V8_OBJECTS_H_ | 7696 #endif // V8_OBJECTS_H_ |
OLD | NEW |