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 2591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2602 inline void PrintDescriptors() { | 2602 inline void PrintDescriptors() { |
2603 PrintDescriptors(stdout); | 2603 PrintDescriptors(stdout); |
2604 } | 2604 } |
2605 void PrintDescriptors(FILE* out); | 2605 void PrintDescriptors(FILE* out); |
2606 #endif | 2606 #endif |
2607 | 2607 |
2608 #ifdef DEBUG | 2608 #ifdef DEBUG |
2609 // Is the descriptor array sorted and without duplicates? | 2609 // Is the descriptor array sorted and without duplicates? |
2610 bool IsSortedNoDuplicates(); | 2610 bool IsSortedNoDuplicates(); |
2611 | 2611 |
| 2612 // Is the descriptor array consistent with the back pointers in targets? |
| 2613 bool IsConsistentWithBackPointers(Map* current_map); |
| 2614 |
2612 // Are two DescriptorArrays equal? | 2615 // Are two DescriptorArrays equal? |
2613 bool IsEqualTo(DescriptorArray* other); | 2616 bool IsEqualTo(DescriptorArray* other); |
2614 #endif | 2617 #endif |
2615 | 2618 |
2616 // The maximum number of descriptors we want in a descriptor array (should | 2619 // The maximum number of descriptors we want in a descriptor array (should |
2617 // fit in a page). | 2620 // fit in a page). |
2618 static const int kMaxNumberOfDescriptors = 1024 + 512; | 2621 static const int kMaxNumberOfDescriptors = 1024 + 512; |
2619 | 2622 |
2620 private: | 2623 private: |
2621 // An entry in a DescriptorArray, represented as an (array, index) pair. | 2624 // An entry in a DescriptorArray, represented as an (array, index) pair. |
(...skipping 2090 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4712 // [instance descriptors]: describes the object. | 4715 // [instance descriptors]: describes the object. |
4713 DECL_ACCESSORS(instance_descriptors, DescriptorArray) | 4716 DECL_ACCESSORS(instance_descriptors, DescriptorArray) |
4714 | 4717 |
4715 // Sets the instance descriptor array for the map to be an empty descriptor | 4718 // Sets the instance descriptor array for the map to be an empty descriptor |
4716 // array. | 4719 // array. |
4717 inline void clear_instance_descriptors(); | 4720 inline void clear_instance_descriptors(); |
4718 | 4721 |
4719 // [stub cache]: contains stubs compiled for this map. | 4722 // [stub cache]: contains stubs compiled for this map. |
4720 DECL_ACCESSORS(code_cache, Object) | 4723 DECL_ACCESSORS(code_cache, Object) |
4721 | 4724 |
| 4725 // [back pointer]: points back to the parent map from which a transition |
| 4726 // leads to this map. The field overlaps with prototype transitions and the |
| 4727 // back pointer will be moved into the prototype transitions array if |
| 4728 // required. |
| 4729 inline Object* GetBackPointer(); |
| 4730 inline void SetBackPointer(Object* value, |
| 4731 WriteBarrierMode mode = UPDATE_WRITE_BARRIER); |
| 4732 |
4722 // [prototype transitions]: cache of prototype transitions. | 4733 // [prototype transitions]: cache of prototype transitions. |
4723 // Prototype transition is a transition that happens | 4734 // Prototype transition is a transition that happens |
4724 // when we change object's prototype to a new one. | 4735 // when we change object's prototype to a new one. |
4725 // Cache format: | 4736 // Cache format: |
4726 // 0: finger - index of the first free cell in the cache | 4737 // 0: finger - index of the first free cell in the cache |
4727 // 1 + 2 * i: prototype | 4738 // 1: back pointer that overlaps with prototype transitions field. |
4728 // 2 + 2 * i: target map | 4739 // 2 + 2 * i: prototype |
| 4740 // 3 + 2 * i: target map |
4729 DECL_ACCESSORS(prototype_transitions, FixedArray) | 4741 DECL_ACCESSORS(prototype_transitions, FixedArray) |
4730 | 4742 |
4731 inline FixedArray* unchecked_prototype_transitions(); | 4743 inline void init_prototype_transitions(Object* undefined); |
| 4744 inline HeapObject* unchecked_prototype_transitions(); |
4732 | 4745 |
4733 static const int kProtoTransitionHeaderSize = 1; | 4746 static const int kProtoTransitionHeaderSize = 2; |
4734 static const int kProtoTransitionNumberOfEntriesOffset = 0; | 4747 static const int kProtoTransitionNumberOfEntriesOffset = 0; |
| 4748 static const int kProtoTransitionBackPointerOffset = 1; |
4735 static const int kProtoTransitionElementsPerEntry = 2; | 4749 static const int kProtoTransitionElementsPerEntry = 2; |
4736 static const int kProtoTransitionPrototypeOffset = 0; | 4750 static const int kProtoTransitionPrototypeOffset = 0; |
4737 static const int kProtoTransitionMapOffset = 1; | 4751 static const int kProtoTransitionMapOffset = 1; |
4738 | 4752 |
4739 inline int NumberOfProtoTransitions() { | 4753 inline int NumberOfProtoTransitions() { |
4740 FixedArray* cache = prototype_transitions(); | 4754 FixedArray* cache = prototype_transitions(); |
4741 if (cache->length() == 0) return 0; | 4755 if (cache->length() == 0) return 0; |
4742 return | 4756 return |
4743 Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value(); | 4757 Smi::cast(cache->get(kProtoTransitionNumberOfEntriesOffset))->value(); |
4744 } | 4758 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4796 // Returns the found code or undefined if absent. | 4810 // Returns the found code or undefined if absent. |
4797 Object* FindInCodeCache(String* name, Code::Flags flags); | 4811 Object* FindInCodeCache(String* name, Code::Flags flags); |
4798 | 4812 |
4799 // Returns the non-negative index of the code object if it is in the | 4813 // Returns the non-negative index of the code object if it is in the |
4800 // cache and -1 otherwise. | 4814 // cache and -1 otherwise. |
4801 int IndexInCodeCache(Object* name, Code* code); | 4815 int IndexInCodeCache(Object* name, Code* code); |
4802 | 4816 |
4803 // Removes a code object from the code cache at the given index. | 4817 // Removes a code object from the code cache at the given index. |
4804 void RemoveFromCodeCache(String* name, Code* code, int index); | 4818 void RemoveFromCodeCache(String* name, Code* code, int index); |
4805 | 4819 |
4806 // For every transition in this map, makes the transition's | 4820 // Set all map transitions from this map to dead maps to null. Also clear |
4807 // target's prototype pointer point back to this map. | 4821 // back pointers in transition targets so that we do not process this map |
4808 // This is undone in MarkCompactCollector::ClearNonLiveTransitions(). | 4822 // again while following back pointers. |
4809 void CreateBackPointers(); | 4823 void ClearNonLiveTransitions(Heap* heap); |
4810 | |
4811 void CreateOneBackPointer(Object* transition_target); | |
4812 | |
4813 // Set all map transitions from this map to dead maps to null. | |
4814 // Also, restore the original prototype on the targets of these | |
4815 // transitions, so that we do not process this map again while | |
4816 // following back pointers. | |
4817 void ClearNonLiveTransitions(Heap* heap, Object* real_prototype); | |
4818 | |
4819 // Restore a possible back pointer in the prototype field of object. | |
4820 // Return true in that case and false otherwise. Set *keep_entry to | |
4821 // true when a live map transition has been found. | |
4822 bool RestoreOneBackPointer(Object* object, | |
4823 Object* real_prototype, | |
4824 bool* keep_entry); | |
4825 | 4824 |
4826 // Computes a hash value for this map, to be used in HashTables and such. | 4825 // Computes a hash value for this map, to be used in HashTables and such. |
4827 int Hash(); | 4826 int Hash(); |
4828 | 4827 |
4829 // Compares this map to another to see if they describe equivalent objects. | 4828 // Compares this map to another to see if they describe equivalent objects. |
4830 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if | 4829 // If |mode| is set to CLEAR_INOBJECT_PROPERTIES, |other| is treated as if |
4831 // it had exactly zero inobject properties. | 4830 // it had exactly zero inobject properties. |
4832 // The "shared" flags of both this map and |other| are ignored. | 4831 // The "shared" flags of both this map and |other| are ignored. |
4833 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); | 4832 bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode); |
4834 | 4833 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4896 // through an extra indirection. | 4895 // through an extra indirection. |
4897 // TODO(1399): It should be possible to make room for bit_field3 in the map | 4896 // TODO(1399): It should be possible to make room for bit_field3 in the map |
4898 // without overloading the instance descriptors field, but the map is | 4897 // without overloading the instance descriptors field, but the map is |
4899 // currently perfectly aligned to 32 bytes and extending it at all would | 4898 // currently perfectly aligned to 32 bytes and extending it at all would |
4900 // double its size. After the increment GC work lands, this size restriction | 4899 // double its size. After the increment GC work lands, this size restriction |
4901 // could be loosened and bit_field3 moved directly back in the map. | 4900 // could be loosened and bit_field3 moved directly back in the map. |
4902 static const int kInstanceDescriptorsOrBitField3Offset = | 4901 static const int kInstanceDescriptorsOrBitField3Offset = |
4903 kConstructorOffset + kPointerSize; | 4902 kConstructorOffset + kPointerSize; |
4904 static const int kCodeCacheOffset = | 4903 static const int kCodeCacheOffset = |
4905 kInstanceDescriptorsOrBitField3Offset + kPointerSize; | 4904 kInstanceDescriptorsOrBitField3Offset + kPointerSize; |
4906 static const int kPrototypeTransitionsOffset = | 4905 static const int kPrototypeTransitionsOrBackPointerOffset = |
4907 kCodeCacheOffset + kPointerSize; | 4906 kCodeCacheOffset + kPointerSize; |
4908 static const int kPadStart = kPrototypeTransitionsOffset + kPointerSize; | 4907 static const int kPadStart = |
| 4908 kPrototypeTransitionsOrBackPointerOffset + kPointerSize; |
4909 static const int kSize = MAP_POINTER_ALIGN(kPadStart); | 4909 static const int kSize = MAP_POINTER_ALIGN(kPadStart); |
4910 | 4910 |
4911 // Layout of pointer fields. Heap iteration code relies on them | 4911 // Layout of pointer fields. Heap iteration code relies on them |
4912 // being continuously allocated. | 4912 // being continuously allocated. |
4913 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; | 4913 static const int kPointerFieldsBeginOffset = Map::kPrototypeOffset; |
4914 static const int kPointerFieldsEndOffset = | 4914 static const int kPointerFieldsEndOffset = |
4915 Map::kPrototypeTransitionsOffset + kPointerSize; | 4915 kPrototypeTransitionsOrBackPointerOffset + kPointerSize; |
4916 | 4916 |
4917 // Byte offsets within kInstanceSizesOffset. | 4917 // Byte offsets within kInstanceSizesOffset. |
4918 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0; | 4918 static const int kInstanceSizeOffset = kInstanceSizesOffset + 0; |
4919 static const int kInObjectPropertiesByte = 1; | 4919 static const int kInObjectPropertiesByte = 1; |
4920 static const int kInObjectPropertiesOffset = | 4920 static const int kInObjectPropertiesOffset = |
4921 kInstanceSizesOffset + kInObjectPropertiesByte; | 4921 kInstanceSizesOffset + kInObjectPropertiesByte; |
4922 static const int kPreAllocatedPropertyFieldsByte = 2; | 4922 static const int kPreAllocatedPropertyFieldsByte = 2; |
4923 static const int kPreAllocatedPropertyFieldsOffset = | 4923 static const int kPreAllocatedPropertyFieldsOffset = |
4924 kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte; | 4924 kInstanceSizesOffset + kPreAllocatedPropertyFieldsByte; |
4925 static const int kVisitorIdByte = 3; | 4925 static const int kVisitorIdByte = 3; |
(...skipping 3732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8658 } else { | 8658 } else { |
8659 value &= ~(1 << bit_position); | 8659 value &= ~(1 << bit_position); |
8660 } | 8660 } |
8661 return value; | 8661 return value; |
8662 } | 8662 } |
8663 }; | 8663 }; |
8664 | 8664 |
8665 } } // namespace v8::internal | 8665 } } // namespace v8::internal |
8666 | 8666 |
8667 #endif // V8_OBJECTS_H_ | 8667 #endif // V8_OBJECTS_H_ |
OLD | NEW |