| 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 |