| 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 2454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2465 // Returns the number of descriptors in the array. | 2465 // Returns the number of descriptors in the array. |
| 2466 int number_of_descriptors() { | 2466 int number_of_descriptors() { |
| 2467 ASSERT(MayContainTransitions() || IsEmpty()); | 2467 ASSERT(MayContainTransitions() || IsEmpty()); |
| 2468 int len = length(); | 2468 int len = length(); |
| 2469 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; | 2469 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize; |
| 2470 } | 2470 } |
| 2471 | 2471 |
| 2472 inline int number_of_entries() { return number_of_descriptors(); } | 2472 inline int number_of_entries() { return number_of_descriptors(); } |
| 2473 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } | 2473 inline int NextEnumerationIndex() { return number_of_descriptors() + 1; } |
| 2474 | 2474 |
| 2475 int LastAdded() { | |
| 2476 ASSERT(!IsEmpty()); | |
| 2477 Object* obj = get(kLastAddedIndex); | |
| 2478 if (obj->IsSmi()) { | |
| 2479 return Smi::cast(obj)->value(); | |
| 2480 } else { | |
| 2481 Object* index = FixedArray::cast(obj)->get(kEnumCacheBridgeLastAdded); | |
| 2482 return Smi::cast(index)->value(); | |
| 2483 } | |
| 2484 } | |
| 2485 | |
| 2486 // Set index of the last added descriptor and flush any enum cache. | |
| 2487 void SetLastAdded(int index) { | |
| 2488 ASSERT(!IsEmpty() || index > 0); | |
| 2489 set(kLastAddedIndex, Smi::FromInt(index)); | |
| 2490 } | |
| 2491 | |
| 2492 int NumberOfSetDescriptors() { | |
| 2493 ASSERT(!IsEmpty()); | |
| 2494 if (LastAdded() == kNoneAdded) return 0; | |
| 2495 return GetDetails(LastAdded()).index(); | |
| 2496 } | |
| 2497 | |
| 2498 bool HasEnumCache() { | 2475 bool HasEnumCache() { |
| 2499 return !IsEmpty() && !get(kLastAddedIndex)->IsSmi(); | 2476 return !IsEmpty() && !get(kEnumCacheIndex)->IsSmi(); |
| 2500 } | 2477 } |
| 2501 | 2478 |
| 2502 Object* GetEnumCache() { | 2479 Object* GetEnumCache() { |
| 2503 ASSERT(HasEnumCache()); | 2480 ASSERT(HasEnumCache()); |
| 2504 FixedArray* bridge = FixedArray::cast(get(kLastAddedIndex)); | 2481 FixedArray* bridge = FixedArray::cast(get(kEnumCacheIndex)); |
| 2505 return bridge->get(kEnumCacheBridgeCacheIndex); | 2482 return bridge->get(kEnumCacheBridgeCacheIndex); |
| 2506 } | 2483 } |
| 2507 | 2484 |
| 2508 Object** GetEnumCacheSlot() { | 2485 Object** GetEnumCacheSlot() { |
| 2509 ASSERT(HasEnumCache()); | 2486 ASSERT(HasEnumCache()); |
| 2510 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | 2487 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
| 2511 kLastAddedOffset); | 2488 kEnumCacheOffset); |
| 2512 } | 2489 } |
| 2513 | 2490 |
| 2514 Object** GetTransitionsSlot() { | 2491 Object** GetTransitionsSlot() { |
| 2515 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), | 2492 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this), |
| 2516 kTransitionsOffset); | 2493 kTransitionsOffset); |
| 2517 } | 2494 } |
| 2518 | 2495 |
| 2519 DECL_ACCESSORS(back_pointer_storage, Object) | 2496 DECL_ACCESSORS(back_pointer_storage, Object) |
| 2520 | 2497 |
| 2521 // Initialize or change the enum cache, | 2498 // Initialize or change the enum cache, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2583 // empty descriptor array object if number_of_descriptors is 0. | 2560 // empty descriptor array object if number_of_descriptors is 0. |
| 2584 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, | 2561 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_descriptors, |
| 2585 SharedMode shared_mode); | 2562 SharedMode shared_mode); |
| 2586 | 2563 |
| 2587 // Casting. | 2564 // Casting. |
| 2588 static inline DescriptorArray* cast(Object* obj); | 2565 static inline DescriptorArray* cast(Object* obj); |
| 2589 | 2566 |
| 2590 // Constant for denoting key was not found. | 2567 // Constant for denoting key was not found. |
| 2591 static const int kNotFound = -1; | 2568 static const int kNotFound = -1; |
| 2592 | 2569 |
| 2593 // Constant for denoting that the LastAdded field was not yet set. | |
| 2594 static const int kNoneAdded = -1; | |
| 2595 | |
| 2596 static const int kBackPointerStorageIndex = 0; | 2570 static const int kBackPointerStorageIndex = 0; |
| 2597 static const int kLastAddedIndex = 1; | 2571 static const int kEnumCacheIndex = 1; |
| 2598 static const int kTransitionsIndex = 2; | 2572 static const int kTransitionsIndex = 2; |
| 2599 static const int kFirstIndex = 3; | 2573 static const int kFirstIndex = 3; |
| 2600 | 2574 |
| 2601 // The length of the "bridge" to the enum cache. | 2575 // The length of the "bridge" to the enum cache. |
| 2602 static const int kEnumCacheBridgeLength = 3; | 2576 static const int kEnumCacheBridgeLength = 3; |
| 2603 static const int kEnumCacheBridgeLastAdded = 0; | 2577 static const int kEnumCacheBridgeLastAdded = 0; |
| 2604 static const int kEnumCacheBridgeCacheIndex = 1; | 2578 static const int kEnumCacheBridgeCacheIndex = 1; |
| 2605 static const int kEnumCacheBridgeIndicesCacheIndex = 2; | 2579 static const int kEnumCacheBridgeIndicesCacheIndex = 2; |
| 2606 | 2580 |
| 2607 // Layout description. | 2581 // Layout description. |
| 2608 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; | 2582 static const int kBackPointerStorageOffset = FixedArray::kHeaderSize; |
| 2609 static const int kLastAddedOffset = kBackPointerStorageOffset + | 2583 static const int kEnumCacheOffset = kBackPointerStorageOffset + |
| 2610 kPointerSize; | 2584 kPointerSize; |
| 2611 static const int kTransitionsOffset = kLastAddedOffset + kPointerSize; | 2585 static const int kTransitionsOffset = kEnumCacheOffset + kPointerSize; |
| 2612 static const int kFirstOffset = kTransitionsOffset + kPointerSize; | 2586 static const int kFirstOffset = kTransitionsOffset + kPointerSize; |
| 2613 | 2587 |
| 2614 // Layout description for the bridge array. | 2588 // Layout description for the bridge array. |
| 2615 static const int kEnumCacheBridgeLastAddedOffset = FixedArray::kHeaderSize; | 2589 static const int kEnumCacheBridgeLastAddedOffset = FixedArray::kHeaderSize; |
| 2616 static const int kEnumCacheBridgeCacheOffset = | 2590 static const int kEnumCacheBridgeCacheOffset = |
| 2617 kEnumCacheBridgeLastAddedOffset + kPointerSize; | 2591 kEnumCacheBridgeLastAddedOffset + kPointerSize; |
| 2618 | 2592 |
| 2619 // Layout of descriptor. | 2593 // Layout of descriptor. |
| 2620 static const int kDescriptorKey = 0; | 2594 static const int kDescriptorKey = 0; |
| 2621 static const int kDescriptorDetails = 1; | 2595 static const int kDescriptorDetails = 1; |
| (...skipping 2045 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4667 inline void set_bit_field(byte value); | 4641 inline void set_bit_field(byte value); |
| 4668 | 4642 |
| 4669 // Bit field 2. | 4643 // Bit field 2. |
| 4670 inline byte bit_field2(); | 4644 inline byte bit_field2(); |
| 4671 inline void set_bit_field2(byte value); | 4645 inline void set_bit_field2(byte value); |
| 4672 | 4646 |
| 4673 // Bit field 3. | 4647 // Bit field 3. |
| 4674 inline int bit_field3(); | 4648 inline int bit_field3(); |
| 4675 inline void set_bit_field3(int value); | 4649 inline void set_bit_field3(int value); |
| 4676 | 4650 |
| 4651 class IsShared: public BitField<bool, 0, 1> {}; |
| 4652 class FunctionWithPrototype: public BitField<bool, 1, 1> {}; |
| 4653 class LastAddedBits: public BitField<int, 2, 11> {}; |
| 4654 |
| 4677 // Tells whether the object in the prototype property will be used | 4655 // Tells whether the object in the prototype property will be used |
| 4678 // for instances created from this function. If the prototype | 4656 // for instances created from this function. If the prototype |
| 4679 // property is set to a value that is not a JSObject, the prototype | 4657 // property is set to a value that is not a JSObject, the prototype |
| 4680 // property will not be used to create instances of the function. | 4658 // property will not be used to create instances of the function. |
| 4681 // See ECMA-262, 13.2.2. | 4659 // See ECMA-262, 13.2.2. |
| 4682 inline void set_non_instance_prototype(bool value); | 4660 inline void set_non_instance_prototype(bool value); |
| 4683 inline bool has_non_instance_prototype(); | 4661 inline bool has_non_instance_prototype(); |
| 4684 | 4662 |
| 4685 // Tells whether function has special prototype property. If not, prototype | 4663 // Tells whether function has special prototype property. If not, prototype |
| 4686 // property will not be created when accessed (will return undefined), | 4664 // property will not be created when accessed (will return undefined), |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4891 // with the given holder if the name is found. The holder may be | 4869 // with the given holder if the name is found. The holder may be |
| 4892 // NULL when this function is used from the compiler. | 4870 // NULL when this function is used from the compiler. |
| 4893 void LookupDescriptor(JSObject* holder, | 4871 void LookupDescriptor(JSObject* holder, |
| 4894 String* name, | 4872 String* name, |
| 4895 LookupResult* result); | 4873 LookupResult* result); |
| 4896 | 4874 |
| 4897 void LookupTransition(JSObject* holder, | 4875 void LookupTransition(JSObject* holder, |
| 4898 String* name, | 4876 String* name, |
| 4899 LookupResult* result); | 4877 LookupResult* result); |
| 4900 | 4878 |
| 4879 void SetLastAdded(int index) { |
| 4880 set_bit_field3(LastAddedBits::update(bit_field3(), index)); |
| 4881 } |
| 4882 |
| 4883 int LastAdded() { |
| 4884 return LastAddedBits::decode(bit_field3()); |
| 4885 } |
| 4886 |
| 4887 int NumberOfSetDescriptors() { |
| 4888 ASSERT(!instance_descriptors()->IsEmpty()); |
| 4889 if (LastAdded() == kNoneAdded) return 0; |
| 4890 return instance_descriptors()->GetDetails(LastAdded()).index(); |
| 4891 } |
| 4892 |
| 4901 MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); | 4893 MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); |
| 4902 MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); | 4894 MUST_USE_RESULT MaybeObject* CopyWithPreallocatedFieldDescriptors(); |
| 4903 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); | 4895 MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); |
| 4904 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( | 4896 MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( |
| 4905 DescriptorArray* descriptors, | 4897 DescriptorArray* descriptors, |
| 4906 String* name, | 4898 String* name, |
| 4907 int last_added, | 4899 int last_added, |
| 4908 TransitionFlag flag); | 4900 TransitionFlag flag); |
| 4909 MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, | 4901 MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, |
| 4910 TransitionFlag flag); | 4902 TransitionFlag flag); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5026 // and the values are the maps the are transitioned to. | 5018 // and the values are the maps the are transitioned to. |
| 5027 static const int kMaxCachedPrototypeTransitions = 256; | 5019 static const int kMaxCachedPrototypeTransitions = 256; |
| 5028 | 5020 |
| 5029 Map* GetPrototypeTransition(Object* prototype); | 5021 Map* GetPrototypeTransition(Object* prototype); |
| 5030 | 5022 |
| 5031 MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype, | 5023 MUST_USE_RESULT MaybeObject* PutPrototypeTransition(Object* prototype, |
| 5032 Map* map); | 5024 Map* map); |
| 5033 | 5025 |
| 5034 static const int kMaxPreAllocatedPropertyFields = 255; | 5026 static const int kMaxPreAllocatedPropertyFields = 255; |
| 5035 | 5027 |
| 5028 // Constant for denoting that the LastAdded field was not yet set. |
| 5029 static const int kNoneAdded = LastAddedBits::kMax; |
| 5030 |
| 5036 // Layout description. | 5031 // Layout description. |
| 5037 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; | 5032 static const int kInstanceSizesOffset = HeapObject::kHeaderSize; |
| 5038 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; | 5033 static const int kInstanceAttributesOffset = kInstanceSizesOffset + kIntSize; |
| 5039 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; | 5034 static const int kPrototypeOffset = kInstanceAttributesOffset + kIntSize; |
| 5040 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; | 5035 static const int kConstructorOffset = kPrototypeOffset + kPointerSize; |
| 5041 // Storage for instance descriptors is overloaded to also contain additional | 5036 // Storage for instance descriptors is overloaded to also contain additional |
| 5042 // map flags when unused (bit_field3). When the map has instance descriptors, | 5037 // map flags when unused (bit_field3). When the map has instance descriptors, |
| 5043 // the flags are transferred to the instance descriptor array and accessed | 5038 // the flags are transferred to the instance descriptor array and accessed |
| 5044 // through an extra indirection. | 5039 // through an extra indirection. |
| 5045 static const int kInstanceDescriptorsOrBackPointerOffset = | 5040 static const int kInstanceDescriptorsOrBackPointerOffset = |
| (...skipping 3835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8881 } else { | 8876 } else { |
| 8882 value &= ~(1 << bit_position); | 8877 value &= ~(1 << bit_position); |
| 8883 } | 8878 } |
| 8884 return value; | 8879 return value; |
| 8885 } | 8880 } |
| 8886 }; | 8881 }; |
| 8887 | 8882 |
| 8888 } } // namespace v8::internal | 8883 } } // namespace v8::internal |
| 8889 | 8884 |
| 8890 #endif // V8_OBJECTS_H_ | 8885 #endif // V8_OBJECTS_H_ |
| OLD | NEW |