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

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 2 Created 8 years, 6 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
« no previous file with comments | « 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 5071 matching lines...) Expand 10 before | Expand all | Expand 10 after
5082 5082
5083 // An iterator over all map transitions in an descriptor array, reusing the map 5083 // An iterator over all map transitions in an descriptor array, reusing the map
5084 // field of the contens array while it is running. 5084 // field of the contens array while it is running.
5085 class IntrusiveMapTransitionIterator { 5085 class IntrusiveMapTransitionIterator {
5086 public: 5086 public:
5087 explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array) 5087 explicit IntrusiveMapTransitionIterator(DescriptorArray* descriptor_array)
5088 : descriptor_array_(descriptor_array) { } 5088 : descriptor_array_(descriptor_array) { }
5089 5089
5090 void Start() { 5090 void Start() {
5091 ASSERT(!IsIterating()); 5091 ASSERT(!IsIterating());
5092 if (HasContentArray()) *ContentHeader() = Smi::FromInt(0); 5092 if (HasDescriptors()) *DescriptorArrayHeader() = Smi::FromInt(0);
5093 } 5093 }
5094 5094
5095 bool IsIterating() { 5095 bool IsIterating() {
5096 return HasContentArray() && (*ContentHeader())->IsSmi(); 5096 return HasDescriptors() && (*DescriptorArrayHeader())->IsSmi();
5097 } 5097 }
5098 5098
5099 Map* Next() { 5099 Map* Next() {
5100 ASSERT(IsIterating()); 5100 ASSERT(IsIterating());
5101 FixedArray* contents = ContentArray(); 5101 // Attention, tricky index manipulation ahead: Two consecutive indices are
5102 // Attention, tricky index manipulation ahead: Every entry in the contents 5102 // assigned to each descriptor. Most descriptors directly advance to the
5103 // array consists of a value/details pair, so the index is typically even. 5103 // next descriptor by adding 2 to the index. The exceptions are the
5104 // An exception is made for CALLBACKS entries: An even index means we look 5104 // CALLBACKS entries: An even index means we look at its getter, and an odd
5105 // at its getter, and an odd index means we look at its setter. 5105 // index means we look at its setter.
5106 int index = Smi::cast(*ContentHeader())->value(); 5106 int raw_index = Smi::cast(*DescriptorArrayHeader())->value();
5107 while (index < contents->length()) { 5107 int index = raw_index / 2;
5108 PropertyDetails details(Smi::cast(contents->get(index | 1))); 5108 while (index < descriptor_array_->number_of_descriptors()) {
5109 PropertyDetails details(RawGetDetails(index));
5109 switch (details.type()) { 5110 switch (details.type()) {
5110 case MAP_TRANSITION: 5111 case MAP_TRANSITION:
5111 case CONSTANT_TRANSITION: 5112 case CONSTANT_TRANSITION:
5112 case ELEMENTS_TRANSITION: 5113 case ELEMENTS_TRANSITION:
5113 // We definitely have a map transition. 5114 // We definitely have a map transition.
5114 *ContentHeader() = Smi::FromInt(index + 2); 5115 *DescriptorArrayHeader() = Smi::FromInt(raw_index + 2);
5115 return static_cast<Map*>(contents->get(index)); 5116 return static_cast<Map*>(RawGetValue(index));
5116 case CALLBACKS: { 5117 case CALLBACKS: {
5117 // We might have a map transition in a getter or in a setter. 5118 // We might have a map transition in a getter or in a setter.
5118 AccessorPair* accessors = 5119 AccessorPair* accessors =
5119 static_cast<AccessorPair*>(contents->get(index & ~1)); 5120 static_cast<AccessorPair*>(RawGetValue(index));
5120 Object* accessor = 5121 Object* accessor = ((raw_index & 1) == 0)
5121 ((index & 1) == 0) ? accessors->getter() : accessors->setter(); 5122 ? accessors->getter()
5122 index++; 5123 : accessors->setter();
5123 if (accessor->IsMap()) { 5124 if (accessor->IsMap()) {
5124 *ContentHeader() = Smi::FromInt(index); 5125 *DescriptorArrayHeader() = Smi::FromInt(raw_index + 1);
5125 return static_cast<Map*>(accessor); 5126 return static_cast<Map*>(accessor);
5126 } 5127 }
5127 break; 5128 break;
5128 } 5129 }
5129 case NORMAL: 5130 case NORMAL:
5130 case FIELD: 5131 case FIELD:
5131 case CONSTANT_FUNCTION: 5132 case CONSTANT_FUNCTION:
5132 case HANDLER: 5133 case HANDLER:
5133 case INTERCEPTOR: 5134 case INTERCEPTOR:
5134 case NULL_DESCRIPTOR: 5135 case NULL_DESCRIPTOR:
5135 // We definitely have no map transition. 5136 // We definitely have no map transition.
5136 index += 2; 5137 raw_index += 2;
5138 ++index;
5137 break; 5139 break;
5138 } 5140 }
5139 } 5141 }
5140 *ContentHeader() = descriptor_array_->GetHeap()->fixed_array_map(); 5142 *DescriptorArrayHeader() = descriptor_array_->GetHeap()->fixed_array_map();
5141 return NULL; 5143 return NULL;
5142 } 5144 }
5143 5145
5144 private: 5146 private:
5145 bool HasContentArray() { 5147 bool HasDescriptors() {
5146 return descriptor_array_-> length() > DescriptorArray::kContentArrayIndex; 5148 return descriptor_array_-> length() > DescriptorArray::kFirstIndex;
5147 } 5149 }
5148 5150
5149 FixedArray* ContentArray() { 5151 Object** DescriptorArrayHeader() {
5150 Object* array = descriptor_array_->get(DescriptorArray::kContentArrayIndex); 5152 return HeapObject::RawField(descriptor_array_, DescriptorArray::kMapOffset);
5151 return static_cast<FixedArray*>(array);
5152 } 5153 }
5153 5154
5154 Object** ContentHeader() { 5155 FixedArray* RawGetContentArray() {
5155 return HeapObject::RawField(ContentArray(), DescriptorArray::kMapOffset); 5156 Object* array =
5157 descriptor_array_->get(DescriptorArray::kContentArrayIndex);
5158 return static_cast<FixedArray*>(array);
5156 } 5159 }
5157 5160
5161 Object* RawGetValue(int descriptor_number) {
5162 return RawGetContentArray()->get(
5163 DescriptorArray::ToValueIndex(descriptor_number));
5164 }
5165
5166 PropertyDetails RawGetDetails(int descriptor_number) {
5167 Object* details = RawGetContentArray()->get(
5168 DescriptorArray::ToDetailsIndex(descriptor_number));
5169 return PropertyDetails(Smi::cast(details));
5170 }
5171
5172
5158 DescriptorArray* descriptor_array_; 5173 DescriptorArray* descriptor_array_;
5159 }; 5174 };
5160 5175
5161 5176
5162 // An iterator over all prototype transitions, reusing the map field of the 5177 // An iterator over all prototype transitions, reusing the map field of the
5163 // underlying array while it is running. 5178 // underlying array while it is running.
5164 class IntrusivePrototypeTransitionIterator { 5179 class IntrusivePrototypeTransitionIterator {
5165 public: 5180 public:
5166 explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans) 5181 explicit IntrusivePrototypeTransitionIterator(HeapObject* proto_trans)
5167 : proto_trans_(proto_trans) { } 5182 : proto_trans_(proto_trans) { }
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
5246 // this map's map! 5261 // this map's map!
5247 void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); } 5262 void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); }
5248 5263
5249 // Reset the current map's map, returning the parent previously stored in it. 5264 // Reset the current map's map, returning the parent previously stored in it.
5250 TraversableMap* GetAndResetParent() { 5265 TraversableMap* GetAndResetParent() {
5251 TraversableMap* old_parent = static_cast<TraversableMap*>(map()); 5266 TraversableMap* old_parent = static_cast<TraversableMap*>(map());
5252 set_map_no_write_barrier(GetHeap()->meta_map()); 5267 set_map_no_write_barrier(GetHeap()->meta_map());
5253 return old_parent; 5268 return old_parent;
5254 } 5269 }
5255 5270
5271 // Can either be Smi (no instance descriptors), or a descriptor array with the
5272 // header overwritten as a Smi (thus iterating).
5273 DescriptorArray* MutatedInstanceDescriptors() {
5274 Object* object =
5275 *HeapObject::RawField(this, kInstanceDescriptorsOrBitField3Offset);
5276 if (object->IsSmi()) {
5277 return GetHeap()->empty_descriptor_array();
5278 } else {
5279 DescriptorArray* descriptor_array =
5280 static_cast<DescriptorArray*>(object);
5281 Object* map =
5282 *HeapObject::RawField(descriptor_array, DescriptorArray::kMapOffset);
5283 ASSERT(map->IsSmi());
5284 return descriptor_array;
5285 }
5286 }
5287
5256 // Start iterating over this map's children, possibly destroying a FixedArray 5288 // Start iterating over this map's children, possibly destroying a FixedArray
5257 // map (see explanation above). 5289 // map (see explanation above).
5258 void ChildIteratorStart() { 5290 void ChildIteratorStart() {
5259 IntrusiveMapTransitionIterator(instance_descriptors()).Start(); 5291 IntrusiveMapTransitionIterator(instance_descriptors()).Start();
5260 IntrusivePrototypeTransitionIterator( 5292 IntrusivePrototypeTransitionIterator(
5261 unchecked_prototype_transitions()).Start(); 5293 unchecked_prototype_transitions()).Start();
5262 } 5294 }
5263 5295
5264 // If we have an unvisited child map, return that one and advance. If we have 5296 // If we have an unvisited child map, return that one and advance. If we have
5265 // none, return NULL and reset any destroyed FixedArray maps. 5297 // none, return NULL and reset any destroyed FixedArray maps.
5266 TraversableMap* ChildIteratorNext() { 5298 TraversableMap* ChildIteratorNext() {
5267 IntrusiveMapTransitionIterator descriptor_iterator(instance_descriptors());
5268 if (descriptor_iterator.IsIterating()) {
5269 Map* next = descriptor_iterator.Next();
5270 if (next != NULL) return static_cast<TraversableMap*>(next);
5271 }
5272 IntrusivePrototypeTransitionIterator 5299 IntrusivePrototypeTransitionIterator
5273 proto_iterator(unchecked_prototype_transitions()); 5300 proto_iterator(unchecked_prototype_transitions());
5274 if (proto_iterator.IsIterating()) { 5301 if (proto_iterator.IsIterating()) {
5275 Map* next = proto_iterator.Next(); 5302 Map* next = proto_iterator.Next();
5276 if (next != NULL) return static_cast<TraversableMap*>(next); 5303 if (next != NULL) return static_cast<TraversableMap*>(next);
5277 } 5304 }
5305 IntrusiveMapTransitionIterator
5306 descriptor_iterator(MutatedInstanceDescriptors());
5307 if (descriptor_iterator.IsIterating()) {
5308 Map* next = descriptor_iterator.Next();
5309 if (next != NULL) return static_cast<TraversableMap*>(next);
5310 }
5278 return NULL; 5311 return NULL;
5279 } 5312 }
5280 }; 5313 };
5281 5314
5282 5315
5283 // Traverse the transition tree in postorder without using the C++ stack by 5316 // Traverse the transition tree in postorder without using the C++ stack by
5284 // doing pointer reversal. 5317 // doing pointer reversal.
5285 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { 5318 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
5286 TraversableMap* current = static_cast<TraversableMap*>(this); 5319 TraversableMap* current = static_cast<TraversableMap*>(this);
5287 current->ChildIteratorStart(); 5320 current->ChildIteratorStart();
(...skipping 7908 matching lines...) Expand 10 before | Expand all | Expand 10 after
13196 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13229 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13197 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13230 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13198 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13231 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13199 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13232 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13200 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13233 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13201 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13234 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13202 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13235 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13203 } 13236 }
13204 13237
13205 } } // namespace v8::internal 13238 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698