Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: src/objects.cc

Issue 10411067: TraversableMap only dependent on DescriptorArray (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing comments Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 4871 matching lines...) Expand 10 before | Expand all | Expand 10 after
4882 4882
4883 // An iterator over all map transitions in an descriptor array, reusing the map 4883 // An iterator over all map transitions in an descriptor array, reusing the map
4884 // field of the contens array while it is running. 4884 // field of the contens array while it is running.
4885 class IntrusiveMapTransitionIterator { 4885 class IntrusiveMapTransitionIterator {
4886 public: 4886 public:
4887 explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array) 4887 explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array)
4888 : descriptor_array_(descriptor_array) { } 4888 : descriptor_array_(descriptor_array) { }
4889 4889
4890 void Start() { 4890 void Start() {
4891 ASSERT(!IsIterating()); 4891 ASSERT(!IsIterating());
4892 if (HasContentArray()) *ContentHeader() = Smi::FromInt(0); 4892 if (HasDescriptors()) *DescriptorArrayHeader() = Smi::FromInt(0);
4893 } 4893 }
4894 4894
4895 bool IsIterating() { 4895 bool IsIterating() {
4896 return HasContentArray() && (*ContentHeader())->IsSmi(); 4896 return HasDescriptors() && (*DescriptorArrayHeader())->IsSmi();
4897 } 4897 }
4898 4898
4899 Map* Next() { 4899 Map* Next() {
4900 ASSERT(IsIterating()); 4900 ASSERT(IsIterating());
4901 FixedArray* contents = ContentArray(); 4901 // Attention, tricky index manipulation ahead: Two consecutive indices are
4902 // Attention, tricky index manipulation ahead: Every entry in the contents 4902 // assigned to each descriptor. Most descriptors directly advance to the
4903 // array consists of a value/details pair, so the index is typically even. 4903 // next descriptor by adding 2 to the index. The exceptions are the
4904 // An exception is made for CALLBACKS entries: An even index means we look 4904 // CALLBACKS entries: An even index means we look at its getter, and an odd
4905 // at its getter, and an odd index means we look at its setter. 4905 // index means we look at its setter.
4906 int index = Smi::cast(*ContentHeader())->value(); 4906 int raw_index = Smi::cast(*DescriptorArrayHeader())->value();
4907 while (index < contents->length()) { 4907 int index = raw_index / 2;
4908 PropertyDetails details(Smi::cast(contents->get(index | 1))); 4908 while (index < descriptor_array_->number_of_descriptors()) {
4909 PropertyDetails details(RawGetDetails(index));
4909 switch (details.type()) { 4910 switch (details.type()) {
4910 case MAP_TRANSITION: 4911 case MAP_TRANSITION:
4911 case CONSTANT_TRANSITION: 4912 case CONSTANT_TRANSITION:
4912 case ELEMENTS_TRANSITION: 4913 case ELEMENTS_TRANSITION:
4913 // We definitely have a map transition. 4914 // We definitely have a map transition.
4914 *ContentHeader() = Smi::FromInt(index + 2); 4915 *DescriptorArrayHeader() = Smi::FromInt(raw_index + 2);
4915 return static_cast<Map*>(contents->get(index)); 4916 return static_cast<Map*>(RawGetValue(index));
4916 case CALLBACKS: { 4917 case CALLBACKS: {
4917 // We might have a map transition in a getter or in a setter. 4918 // We might have a map transition in a getter or in a setter.
4918 AccessorPair* accessors = 4919 AccessorPair* accessors =
4919 static_cast<AccessorPair*>(contents->get(index & ~1)); 4920 static_cast<AccessorPair*>(RawGetValue(index));
4920 Object* accessor = 4921 Object* accessor =
4921 ((index & 1) == 0) ? accessors->getter() : accessors->setter(); 4922 ((raw_index & 1) == 0) ? accessors->getter():accessors->setter();
Michael Starzinger 2012/05/25 12:18:00 Spaces to the left and right of ":". I know it wil
Toon Verwaest 2012/05/25 12:32:09 Done.
4922 index++;
4923 if (accessor->IsMap()) { 4923 if (accessor->IsMap()) {
4924 *ContentHeader() = Smi::FromInt(index); 4924 *DescriptorArrayHeader() = Smi::FromInt(raw_index + 1);
4925 return static_cast<Map*>(accessor); 4925 return static_cast<Map*>(accessor);
4926 } 4926 }
4927 break; 4927 break;
4928 } 4928 }
4929 case NORMAL: 4929 case NORMAL:
4930 case FIELD: 4930 case FIELD:
4931 case CONSTANT_FUNCTION: 4931 case CONSTANT_FUNCTION:
4932 case HANDLER: 4932 case HANDLER:
4933 case INTERCEPTOR: 4933 case INTERCEPTOR:
4934 case NULL_DESCRIPTOR: 4934 case NULL_DESCRIPTOR:
4935 // We definitely have no map transition. 4935 // We definitely have no map transition.
4936 index += 2; 4936 raw_index += 2;
4937 ++index;
4937 break; 4938 break;
4938 } 4939 }
4939 } 4940 }
4940 *ContentHeader() = descriptor_array_->GetHeap()->fixed_array_map(); 4941 *DescriptorArrayHeader() = descriptor_array_->GetHeap()->fixed_array_map();
4941 return NULL; 4942 return NULL;
4942 } 4943 }
4943 4944
4944 private: 4945 private:
4945 bool HasContentArray() { 4946 bool HasDescriptors() {
4946 return descriptor_array_-> length() > DescriptorArray::kContentArrayIndex; 4947 return descriptor_array_-> length() > DescriptorArray::kFirstIndex;
4947 } 4948 }
4948 4949
4949 FixedArray* ContentArray() { 4950 Object** DescriptorArrayHeader() {
4950 Object* array = descriptor_array_->get(DescriptorArray::kContentArrayIndex); 4951 return HeapObject::RawField(descriptor_array_, DescriptorArray::kMapOffset);
4951 return static_cast<FixedArray*>(array);
4952 } 4952 }
4953 4953
4954 Object** ContentHeader() { 4954 FixedArray* RawGetContentArray() {
4955 return HeapObject::RawField(ContentArray(), DescriptorArray::kMapOffset); 4955 Object* array =
4956 descriptor_array_->get(DescriptorArray::kContentArrayIndex);
4957 return static_cast<FixedArray*>(array);
4956 } 4958 }
4957 4959
4960 Object* RawGetValue(int descriptor_number) {
4961 return RawGetContentArray()->get(
4962 DescriptorArray::ToValueIndex(descriptor_number));
4963 }
4964
4965 PropertyDetails RawGetDetails(int descriptor_number) {
4966 Object* details = RawGetContentArray()->get(
4967 DescriptorArray::ToDetailsIndex(descriptor_number));
4968 return PropertyDetails(Smi::cast(details));
4969 }
4970
4971
4958 DescriptorArray* descriptor_array_; 4972 DescriptorArray* descriptor_array_;
4959 }; 4973 };
4960 4974
4961 4975
4962 // An iterator over all prototype transitions, reusing the map field of the 4976 // An iterator over all prototype transitions, reusing the map field of the
4963 // underlying array while it is running. 4977 // underlying array while it is running.
4964 class IntrusivePrototypeTransitionIterator { 4978 class IntrusivePrototypeTransitionIterator {
4965 public: 4979 public:
4966 explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans) 4980 explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans)
4967 : proto_trans_(proto_trans) { } 4981 : proto_trans_(proto_trans) { }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5046 // this map's map! 5060 // this map's map!
5047 void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); } 5061 void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); }
5048 5062
5049 // Reset the current map's map, returning the parent previously stored in it. 5063 // Reset the current map's map, returning the parent previously stored in it.
5050 TraversableMap* GetAndResetParent() { 5064 TraversableMap* GetAndResetParent() {
5051 TraversableMap* old_parent = static_cast<TraversableMap*>(map()); 5065 TraversableMap* old_parent = static_cast<TraversableMap*>(map());
5052 set_map_no_write_barrier(GetHeap()->meta_map()); 5066 set_map_no_write_barrier(GetHeap()->meta_map());
5053 return old_parent; 5067 return old_parent;
5054 } 5068 }
5055 5069
5070 // Can either be Smi (no instance descriptors), or a descriptor array with the
5071 // header overwritten as a Smi (thus iterating).
5072 DescriptorArray* MutatedInstanceDescriptors() {
5073 Object* object =
5074 *HeapObject::RawField(this, kInstanceDescriptorsOrBitField3Offset);
5075 if (object->IsSmi()) {
5076 return GetHeap()->empty_descriptor_array();
5077 } else {
5078 DescriptorArray* descriptor_array =
5079 static_cast<DescriptorArray*>(object);
5080 Object* map =
5081 *HeapObject::RawField(descriptor_array, DescriptorArray::kMapOffset);
5082 ASSERT(map->IsSmi());
5083 return descriptor_array;
5084 }
5085 }
5086
5056 // Start iterating over this map's children, possibly destroying a FixedArray 5087 // Start iterating over this map's children, possibly destroying a FixedArray
5057 // map (see explanation above). 5088 // map (see explanation above).
5058 void ChildIteratorStart() { 5089 void ChildIteratorStart() {
5059 IntrusiveMapTransitionIterator(instance_descriptors()).Start(); 5090 IntrusiveMapTransitionIterator(instance_descriptors()).Start();
5060 IntrusivePrototypeTransitionIterator( 5091 IntrusivePrototypeTransitionIterator(
5061 unchecked_prototype_transitions()).Start(); 5092 unchecked_prototype_transitions()).Start();
5062 } 5093 }
5063 5094
5064 // If we have an unvisited child map, return that one and advance. If we have 5095 // If we have an unvisited child map, return that one and advance. If we have
5065 // none, return NULL and reset any destroyed FixedArray maps. 5096 // none, return NULL and reset any destroyed FixedArray maps.
5066 TraversableMap* ChildIteratorNext() { 5097 TraversableMap* ChildIteratorNext() {
5067 IntrusiveMapTransitionIterator descriptor_iterator(instance_descriptors());
5068 if (descriptor_iterator.IsIterating()) {
5069 Map* next = descriptor_iterator.Next();
5070 if (next != NULL) return static_cast<TraversableMap*>(next);
5071 }
5072 IntrusivePrototypeTransitionIterator 5098 IntrusivePrototypeTransitionIterator
5073 proto_iterator(unchecked_prototype_transitions()); 5099 proto_iterator(unchecked_prototype_transitions());
5074 if (proto_iterator.IsIterating()) { 5100 if (proto_iterator.IsIterating()) {
5075 Map* next = proto_iterator.Next(); 5101 Map* next = proto_iterator.Next();
5076 if (next != NULL) return static_cast<TraversableMap*>(next); 5102 if (next != NULL) return static_cast<TraversableMap*>(next);
5077 } 5103 }
5104 IntrusiveMapTransitionIterator
5105 descriptor_iterator(MutatedInstanceDescriptors());
5106 if (descriptor_iterator.IsIterating()) {
5107 Map* next = descriptor_iterator.Next();
5108 if (next != NULL) return static_cast<TraversableMap*>(next);
5109 }
5078 return NULL; 5110 return NULL;
5079 } 5111 }
5080 }; 5112 };
5081 5113
5082 5114
5083 // Traverse the transition tree in postorder without using the C++ stack by 5115 // Traverse the transition tree in postorder without using the C++ stack by
5084 // doing pointer reversal. 5116 // doing pointer reversal.
5085 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { 5117 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
5086 TraversableMap* current = static_cast<TraversableMap*>(this); 5118 TraversableMap* current = static_cast<TraversableMap*>(this);
5087 current->ChildIteratorStart(); 5119 current->ChildIteratorStart();
(...skipping 7843 matching lines...) Expand 10 before | Expand all | Expand 10 after
12931 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 12963 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
12932 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 12964 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
12933 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 12965 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
12934 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 12966 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
12935 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 12967 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
12936 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 12968 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
12937 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 12969 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
12938 } 12970 }
12939 12971
12940 } } // namespace v8::internal 12972 } } // namespace v8::internal
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698