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 2387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2398 public: | 2398 public: |
2399 // Returns true for both shared empty_descriptor_array and for smis, which the | 2399 // Returns true for both shared empty_descriptor_array and for smis, which the |
2400 // map uses to encode additional bit fields when the descriptor array is not | 2400 // map uses to encode additional bit fields when the descriptor array is not |
2401 // yet used. | 2401 // yet used. |
2402 inline bool IsEmpty(); | 2402 inline bool IsEmpty(); |
2403 | 2403 |
2404 // Returns the number of descriptors in the array. | 2404 // Returns the number of descriptors in the array. |
2405 int number_of_descriptors() { | 2405 int number_of_descriptors() { |
2406 ASSERT(length() > kFirstIndex || IsEmpty()); | 2406 ASSERT(length() > kFirstIndex || IsEmpty()); |
2407 int len = length(); | 2407 int len = length(); |
2408 return len <= kFirstIndex ? 0 : len - kFirstIndex; | 2408 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; |
2409 } | 2409 } |
2410 | 2410 |
2411 int NextEnumerationIndex() { | 2411 int NextEnumerationIndex() { |
2412 if (IsEmpty()) return PropertyDetails::kInitialIndex; | 2412 if (IsEmpty()) return PropertyDetails::kInitialIndex; |
2413 Object* obj = get(kEnumerationIndexIndex); | 2413 Object* obj = get(kEnumerationIndexIndex); |
2414 if (obj->IsSmi()) { | 2414 if (obj->IsSmi()) { |
2415 return Smi::cast(obj)->value(); | 2415 return Smi::cast(obj)->value(); |
2416 } else { | 2416 } else { |
2417 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); | 2417 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeEnumIndex); |
2418 return Smi::cast(index)->value(); | 2418 return Smi::cast(index)->value(); |
2419 } | 2419 } |
2420 } | 2420 } |
2421 | 2421 |
2422 // Set next enumeration index and flush any enum cache. | 2422 // Set next enumeration index and flush any enum cache. |
2423 void SetNextEnumerationIndex(int value) { | 2423 void SetNextEnumerationIndex(int value) { |
2424 if (!IsEmpty()) { | 2424 if (!IsEmpty()) { |
2425 set(kEnumerationIndexIndex, Smi::FromInt(value)); | 2425 set(kEnumerationIndexIndex, Smi::FromInt(value)); |
2426 } | 2426 } |
2427 } | 2427 } |
2428 bool HasEnumCache() { | 2428 bool HasEnumCache() { |
2429 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); | 2429 return !IsEmpty() && !get(kEnumerationIndexIndex)->IsSmi(); |
2430 } | 2430 } |
2431 | 2431 |
2432 Object* GetEnumCache() { | 2432 Object* GetEnumCache() { |
2433 ASSERT(HasEnumCache()); | 2433 ASSERT(HasEnumCache()); |
2434 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); | 2434 FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex)); |
2435 return bridge->get(kEnumCacheBridgeCacheIndex); | 2435 return bridge->get(kEnumCacheBridgeCacheIndex); |
2436 } | 2436 } |
2437 | 2437 |
| 2438 Object** GetEnumCacheSlot() { |
| 2439 ASSERT(HasEnumCache()); |
| 2440 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
| 2441 kEnumerationIndexOffset); |
| 2442 } |
| 2443 |
2438 // TODO(1399): It should be possible to make room for bit_field3 in the map | 2444 // TODO(1399): It should be possible to make room for bit_field3 in the map |
2439 // without overloading the instance descriptors field in the map | 2445 // without overloading the instance descriptors field in the map |
2440 // (and storing it in the DescriptorArray when the map has one). | 2446 // (and storing it in the DescriptorArray when the map has one). |
2441 inline int bit_field3_storage(); | 2447 inline int bit_field3_storage(); |
2442 inline void set_bit_field3_storage(int value); | 2448 inline void set_bit_field3_storage(int value); |
2443 | 2449 |
2444 // Initialize or change the enum cache, | 2450 // Initialize or change the enum cache, |
2445 // using the supplied storage for the small "bridge". | 2451 // using the supplied storage for the small "bridge". |
2446 void SetEnumCache(FixedArray* bridge_storage, | 2452 void SetEnumCache(FixedArray* bridge_storage, |
2447 FixedArray* new_cache, | 2453 FixedArray* new_cache, |
2448 Object* new_index_cache); | 2454 Object* new_index_cache); |
2449 | 2455 |
2450 // Accessors for fetching instance descriptor at descriptor number. | 2456 // Accessors for fetching instance descriptor at descriptor number. |
2451 inline String* GetKey(int descriptor_number); | 2457 inline String* GetKey(int descriptor_number); |
| 2458 inline Object** GetKeySlot(int descriptor_number); |
2452 inline Object* GetValue(int descriptor_number); | 2459 inline Object* GetValue(int descriptor_number); |
2453 inline Object** GetValueSlot(int descriptor_number); | 2460 inline Object** GetValueSlot(int descriptor_number); |
2454 inline void SetNullValueUnchecked(int descriptor_number, Heap* heap); | 2461 inline void SetNullValueUnchecked(int descriptor_number, Heap* heap); |
2455 inline PropertyDetails GetDetails(int descriptor_number); | 2462 inline PropertyDetails GetDetails(int descriptor_number); |
2456 inline void SetDetailsUnchecked(int descriptor_number, Smi* value); | 2463 inline void SetDetailsUnchecked(int descriptor_number, Smi* value); |
2457 inline PropertyType GetType(int descriptor_number); | 2464 inline PropertyType GetType(int descriptor_number); |
2458 inline int GetFieldIndex(int descriptor_number); | 2465 inline int GetFieldIndex(int descriptor_number); |
2459 inline JSFunction* GetConstantFunction(int descriptor_number); | 2466 inline JSFunction* GetConstantFunction(int descriptor_number); |
2460 inline Object* GetCallbacksObject(int descriptor_number); | 2467 inline Object* GetCallbacksObject(int descriptor_number); |
2461 inline AccessorDescriptor* GetCallbacks(int descriptor_number); | 2468 inline AccessorDescriptor* GetCallbacks(int descriptor_number); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2547 // empty descriptor array object if number_of_descriptors is 0. | 2554 // empty descriptor array object if number_of_descriptors is 0. |
2548 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); | 2555 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors); |
2549 | 2556 |
2550 // Casting. | 2557 // Casting. |
2551 static inline DescriptorArray* cast(Object* obj); | 2558 static inline DescriptorArray* cast(Object* obj); |
2552 | 2559 |
2553 // Constant for denoting key was not found. | 2560 // Constant for denoting key was not found. |
2554 static const int kNotFound = -1; | 2561 static const int kNotFound = -1; |
2555 | 2562 |
2556 static const int kBitField3StorageIndex = 0; | 2563 static const int kBitField3StorageIndex = 0; |
2557 static const int kContentArrayIndex = 1; | 2564 static const int kEnumerationIndexIndex = 1; |
2558 static const int kEnumerationIndexIndex = 2; | 2565 static const int kFirstIndex = 2; |
2559 static const int kFirstIndex = 3; | |
2560 | 2566 |
2561 // The length of the "bridge" to the enum cache. | 2567 // The length of the "bridge" to the enum cache. |
2562 static const int kEnumCacheBridgeLength = 3; | 2568 static const int kEnumCacheBridgeLength = 3; |
2563 static const int kEnumCacheBridgeEnumIndex = 0; | 2569 static const int kEnumCacheBridgeEnumIndex = 0; |
2564 static const int kEnumCacheBridgeCacheIndex = 1; | 2570 static const int kEnumCacheBridgeCacheIndex = 1; |
2565 static const int kEnumCacheBridgeIndicesCacheIndex = 2; | 2571 static const int kEnumCacheBridgeIndicesCacheIndex = 2; |
2566 | 2572 |
2567 // Layout description. | 2573 // Layout description. |
2568 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; | 2574 static const int kBitField3StorageOffset = FixedArray::kHeaderSize; |
2569 static const int kContentArrayOffset = kBitField3StorageOffset + kPointerSize; | 2575 static const int kEnumerationIndexOffset = kBitField3StorageOffset + |
2570 static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize; | 2576 kPointerSize; |
2571 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; | 2577 static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize; |
2572 | 2578 |
2573 // Layout description for the bridge array. | 2579 // Layout description for the bridge array. |
2574 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; | 2580 static const int kEnumCacheBridgeEnumOffset = FixedArray::kHeaderSize; |
2575 static const int kEnumCacheBridgeCacheOffset = | 2581 static const int kEnumCacheBridgeCacheOffset = |
2576 kEnumCacheBridgeEnumOffset + kPointerSize; | 2582 kEnumCacheBridgeEnumOffset + kPointerSize; |
2577 | 2583 |
| 2584 // Layout of descriptor. |
| 2585 static const int kDescriptorKey = 0; |
| 2586 static const int kDescriptorDetails = 1; |
| 2587 static const int kDescriptorValue = 2; |
| 2588 static const int kDescriptorSize = 3; |
| 2589 |
2578 #ifdef OBJECT_PRINT | 2590 #ifdef OBJECT_PRINT |
2579 // Print all the descriptors. | 2591 // Print all the descriptors. |
2580 inline void PrintDescriptors() { | 2592 inline void PrintDescriptors() { |
2581 PrintDescriptors(stdout); | 2593 PrintDescriptors(stdout); |
2582 } | 2594 } |
2583 void PrintDescriptors(FILE* out); | 2595 void PrintDescriptors(FILE* out); |
2584 #endif | 2596 #endif |
2585 | 2597 |
2586 #ifdef DEBUG | 2598 #ifdef DEBUG |
2587 // Is the descriptor array sorted and without duplicates? | 2599 // Is the descriptor array sorted and without duplicates? |
2588 bool IsSortedNoDuplicates(); | 2600 bool IsSortedNoDuplicates(); |
2589 | 2601 |
2590 // Is the descriptor array consistent with the back pointers in targets? | 2602 // Is the descriptor array consistent with the back pointers in targets? |
2591 bool IsConsistentWithBackPointers(Map* current_map); | 2603 bool IsConsistentWithBackPointers(Map* current_map); |
2592 | 2604 |
2593 // Are two DescriptorArrays equal? | 2605 // Are two DescriptorArrays equal? |
2594 bool IsEqualTo(DescriptorArray* other); | 2606 bool IsEqualTo(DescriptorArray* other); |
2595 #endif | 2607 #endif |
2596 | 2608 |
2597 // The maximum number of descriptors we want in a descriptor array (should | 2609 // The maximum number of descriptors we want in a descriptor array (should |
2598 // fit in a page). | 2610 // fit in a page). |
2599 static const int kMaxNumberOfDescriptors = 1024 + 512; | 2611 static const int kMaxNumberOfDescriptors = 1024 + 512; |
2600 | 2612 |
2601 private: | 2613 private: |
2602 friend class IntrusiveMapTransitionIterator; | |
2603 | |
2604 // An entry in a DescriptorArray, represented as an (array, index) pair. | 2614 // An entry in a DescriptorArray, represented as an (array, index) pair. |
2605 class Entry { | 2615 class Entry { |
2606 public: | 2616 public: |
2607 inline explicit Entry(DescriptorArray* descs, int index) : | 2617 inline explicit Entry(DescriptorArray* descs, int index) : |
2608 descs_(descs), index_(index) { } | 2618 descs_(descs), index_(index) { } |
2609 | 2619 |
2610 inline PropertyType type() { return descs_->GetType(index_); } | 2620 inline PropertyType type() { return descs_->GetType(index_); } |
2611 inline Object* GetCallbackObject() { return descs_->GetValue(index_); } | 2621 inline Object* GetCallbackObject() { return descs_->GetValue(index_); } |
2612 | 2622 |
2613 private: | 2623 private: |
2614 DescriptorArray* descs_; | 2624 DescriptorArray* descs_; |
2615 int index_; | 2625 int index_; |
2616 }; | 2626 }; |
2617 | 2627 |
2618 // Conversion from descriptor number to array indices. | 2628 // Conversion from descriptor number to array indices. |
2619 static int ToKeyIndex(int descriptor_number) { | 2629 static int ToKeyIndex(int descriptor_number) { |
2620 return descriptor_number+kFirstIndex; | 2630 return kFirstIndex + |
| 2631 (descriptor_number * kDescriptorSize) + |
| 2632 kDescriptorKey; |
2621 } | 2633 } |
2622 | 2634 |
2623 static int ToDetailsIndex(int descriptor_number) { | 2635 static int ToDetailsIndex(int descriptor_number) { |
2624 return (descriptor_number << 1) + 1; | 2636 return kFirstIndex + |
| 2637 (descriptor_number * kDescriptorSize) + |
| 2638 kDescriptorDetails; |
2625 } | 2639 } |
2626 | 2640 |
2627 static int ToValueIndex(int descriptor_number) { | 2641 static int ToValueIndex(int descriptor_number) { |
2628 return descriptor_number << 1; | 2642 return kFirstIndex + |
| 2643 (descriptor_number * kDescriptorSize) + |
| 2644 kDescriptorValue; |
2629 } | 2645 } |
2630 | 2646 |
2631 // Swap operation on FixedArray without using write barriers. | 2647 // Swap operation on FixedArray without using write barriers. |
2632 static inline void NoIncrementalWriteBarrierSwap( | 2648 static inline void NoIncrementalWriteBarrierSwap( |
2633 FixedArray* array, int first, int second); | 2649 FixedArray* array, int first, int second); |
2634 | 2650 |
2635 // Swap descriptor first and second. | 2651 // Swap descriptor first and second. |
2636 inline void NoIncrementalWriteBarrierSwapDescriptors( | 2652 inline void NoIncrementalWriteBarrierSwapDescriptors( |
2637 int first, int second); | 2653 int first, int second); |
2638 | 2654 |
2639 FixedArray* GetContentArray() { | |
2640 return FixedArray::cast(get(kContentArrayIndex)); | |
2641 } | |
2642 | |
2643 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); | 2655 DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray); |
2644 }; | 2656 }; |
2645 | 2657 |
2646 | 2658 |
2647 // HashTable is a subclass of FixedArray that implements a hash table | 2659 // HashTable is a subclass of FixedArray that implements a hash table |
2648 // that uses open addressing and quadratic probing. | 2660 // that uses open addressing and quadratic probing. |
2649 // | 2661 // |
2650 // In order for the quadratic probing to work, elements that have not | 2662 // In order for the quadratic probing to work, elements that have not |
2651 // yet been used and elements that have been deleted are | 2663 // yet been used and elements that have been deleted are |
2652 // distinguished. Probing continues when deleted elements are | 2664 // distinguished. Probing continues when deleted elements are |
(...skipping 6013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8666 } else { | 8678 } else { |
8667 value &= ~(1 << bit_position); | 8679 value &= ~(1 << bit_position); |
8668 } | 8680 } |
8669 return value; | 8681 return value; |
8670 } | 8682 } |
8671 }; | 8683 }; |
8672 | 8684 |
8673 } } // namespace v8::internal | 8685 } } // namespace v8::internal |
8674 | 8686 |
8675 #endif // V8_OBJECTS_H_ | 8687 #endif // V8_OBJECTS_H_ |
OLD | NEW |