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

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: 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
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 two consecutive indices
Michael Starzinger 2012/05/24 14:02:25 Only one "two".
Toon Verwaest 2012/05/25 11:36:46 Done.
4902 // Attention, tricky index manipulation ahead: Every entry in the contents 4902 // are 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 index = Smi::cast(*DescriptorArrayHeader())->value();
4907 while (index < contents->length()) { 4907 while ((index / 2) < descriptor_array_->number_of_descriptors()) {
Michael Starzinger 2012/05/24 14:02:25 Can we hoist the division by two into a local vari
Toon Verwaest 2012/05/25 11:36:46 Done.
4908 PropertyDetails details(Smi::cast(contents->get(index | 1))); 4908 PropertyDetails details(descriptor_array_->RawGetDetails(index / 2));
4909 switch (details.type()) { 4909 switch (details.type()) {
4910 case MAP_TRANSITION: 4910 case MAP_TRANSITION:
4911 case CONSTANT_TRANSITION: 4911 case CONSTANT_TRANSITION:
4912 case ELEMENTS_TRANSITION: 4912 case ELEMENTS_TRANSITION:
4913 // We definitely have a map transition. 4913 // We definitely have a map transition.
4914 *ContentHeader() = Smi::FromInt(index + 2); 4914 *DescriptorArrayHeader() = Smi::FromInt(index + 2);
4915 return static_cast<Map*>(contents->get(index)); 4915 return static_cast<Map*>(descriptor_array_->RawGetValue(index / 2));
4916 case CALLBACKS: { 4916 case CALLBACKS: {
4917 // We might have a map transition in a getter or in a setter. 4917 // We might have a map transition in a getter or in a setter.
4918 AccessorPair* accessors = 4918 AccessorPair* accessors =
4919 static_cast<AccessorPair*>(contents->get(index & ~1)); 4919 static_cast<AccessorPair*>(descriptor_array_->RawGetValue(index / 2));
Michael Starzinger 2012/05/24 14:02:25 More than 80 characters.
Toon Verwaest 2012/05/25 11:36:46 Done.
4920 Object* accessor = 4920 Object* accessor =
4921 ((index & 1) == 0) ? accessors->getter() : accessors->setter(); 4921 ((index & 1) == 0) ? accessors->getter() : accessors->setter();
4922 index++; 4922 index++;
4923 if (accessor->IsMap()) { 4923 if (accessor->IsMap()) {
4924 *ContentHeader() = Smi::FromInt(index); 4924 *DescriptorArrayHeader() = Smi::FromInt(index);
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 index += 2;
4937 break; 4937 break;
4938 } 4938 }
4939 } 4939 }
4940 *ContentHeader() = descriptor_array_->GetHeap()->fixed_array_map(); 4940 *DescriptorArrayHeader() = descriptor_array_->GetHeap()->fixed_array_map();
4941 return NULL; 4941 return NULL;
4942 } 4942 }
4943 4943
4944 private: 4944 private:
4945 bool HasContentArray() { 4945 bool HasDescriptors() {
4946 return descriptor_array_-> length() > DescriptorArray::kContentArrayIndex; 4946 return descriptor_array_-> length() > DescriptorArray::kFirstIndex;
4947 } 4947 }
4948 4948
4949 FixedArray* ContentArray() { 4949 Object** DescriptorArrayHeader() {
4950 Object* array = descriptor_array_->get(DescriptorArray::kContentArrayIndex); 4950 return HeapObject::RawField(descriptor_array_, DescriptorArray::kMapOffset);
4951 return static_cast<FixedArray*>(array);
4952 }
4953
4954 Object** ContentHeader() {
4955 return HeapObject::RawField(ContentArray(), DescriptorArray::kMapOffset);
4956 } 4951 }
4957 4952
4958 DescriptorArray* descriptor_array_; 4953 DescriptorArray* descriptor_array_;
4959 }; 4954 };
4960 4955
4961 4956
4962 // An iterator over all prototype transitions, reusing the map field of the 4957 // An iterator over all prototype transitions, reusing the map field of the
4963 // underlying array while it is running. 4958 // underlying array while it is running.
4964 class IntrusivePrototypeTransitionIterator { 4959 class IntrusivePrototypeTransitionIterator {
4965 public: 4960 public:
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
5046 // this map's map! 5041 // this map's map!
5047 void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); } 5042 void SetParent(TraversableMap* parent) { set_map_no_write_barrier(parent); }
5048 5043
5049 // Reset the current map's map, returning the parent previously stored in it. 5044 // Reset the current map's map, returning the parent previously stored in it.
5050 TraversableMap* GetAndResetParent() { 5045 TraversableMap* GetAndResetParent() {
5051 TraversableMap* old_parent = static_cast<TraversableMap*>(map()); 5046 TraversableMap* old_parent = static_cast<TraversableMap*>(map());
5052 set_map_no_write_barrier(GetHeap()->meta_map()); 5047 set_map_no_write_barrier(GetHeap()->meta_map());
5053 return old_parent; 5048 return old_parent;
5054 } 5049 }
5055 5050
5051 // Can either be Smi (no instance descriptors), or a descriptor array with the
5052 // header overwritten as a Smi (thus iterating).
5053 DescriptorArray* MutatedInstanceDescriptors() {
5054 Object* object = *HeapObject::RawField(this, kInstanceDescriptorsOrBitField3 Offset);
5055 if (object->IsSmi()) {
5056 return GetHeap()->empty_descriptor_array();
5057 } else {
5058 DescriptorArray* descriptor_array = static_cast<DescriptorArray*>(object);
5059 Object* map = *HeapObject::RawField(descriptor_array, DescriptorArray::kMa pOffset);
5060 ASSERT(map->IsSmi());
5061 return descriptor_array;
5062 }
5063 }
5064
5056 // Start iterating over this map's children, possibly destroying a FixedArray 5065 // Start iterating over this map's children, possibly destroying a FixedArray
5057 // map (see explanation above). 5066 // map (see explanation above).
5058 void ChildIteratorStart() { 5067 void ChildIteratorStart() {
5059 IntrusiveMapTransitionIterator(instance_descriptors()).Start(); 5068 IntrusiveMapTransitionIterator(instance_descriptors()).Start();
5060 IntrusivePrototypeTransitionIterator( 5069 IntrusivePrototypeTransitionIterator(
5061 unchecked_prototype_transitions()).Start(); 5070 unchecked_prototype_transitions()).Start();
5062 } 5071 }
5063 5072
5064 // If we have an unvisited child map, return that one and advance. If we have 5073 // 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. 5074 // none, return NULL and reset any destroyed FixedArray maps.
5066 TraversableMap* ChildIteratorNext() { 5075 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 5076 IntrusivePrototypeTransitionIterator
5073 proto_iterator(unchecked_prototype_transitions()); 5077 proto_iterator(unchecked_prototype_transitions());
5074 if (proto_iterator.IsIterating()) { 5078 if (proto_iterator.IsIterating()) {
5075 Map* next = proto_iterator.Next(); 5079 Map* next = proto_iterator.Next();
5076 if (next != NULL) return static_cast<TraversableMap*>(next); 5080 if (next != NULL) return static_cast<TraversableMap*>(next);
5077 } 5081 }
5082 IntrusiveMapTransitionIterator descriptor_iterator(MutatedInstanceDescriptor s());
Michael Starzinger 2012/05/24 14:02:25 Could we just pass the map itself to the construct
Toon Verwaest 2012/05/25 11:36:46 As discussed offline, leaving it as it is. On 201
5083 if (descriptor_iterator.IsIterating()) {
5084 Map* next = descriptor_iterator.Next();
5085 if (next != NULL) return static_cast<TraversableMap*>(next);
5086 }
5078 return NULL; 5087 return NULL;
5079 } 5088 }
5080 }; 5089 };
5081 5090
5082 5091
5083 // Traverse the transition tree in postorder without using the C++ stack by 5092 // Traverse the transition tree in postorder without using the C++ stack by
5084 // doing pointer reversal. 5093 // doing pointer reversal.
5085 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { 5094 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
5086 TraversableMap* current = static_cast<TraversableMap*>(this); 5095 TraversableMap* current = static_cast<TraversableMap*>(this);
5087 current->ChildIteratorStart(); 5096 current->ChildIteratorStart();
(...skipping 7843 matching lines...) Expand 10 before | Expand all | Expand 10 after
12931 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 12940 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
12932 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 12941 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
12933 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 12942 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
12934 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 12943 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
12935 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 12944 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
12936 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 12945 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
12937 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 12946 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
12938 } 12947 }
12939 12948
12940 } } // namespace v8::internal 12949 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698