Chromium Code Reviews| 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 |