Revision: 11703
Author:   [email protected]
Date:     Mon Jun  4 00:20:11 2012
Log:      Merging ContentArray into DescriptorArray

Review URL: https://chromiumcodereview.appspot.com/10412030
http://code.google.com/p/v8/source/detail?r=11703

Modified:
 /branches/bleeding_edge/src/mark-compact.cc
 /branches/bleeding_edge/src/objects-debug.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h

=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Wed May 30 08:15:17 2012
+++ /branches/bleeding_edge/src/mark-compact.cc Mon Jun  4 00:20:11 2012
@@ -1867,25 +1867,42 @@
   // Empty descriptor array is marked as a root before any maps are marked.
   ASSERT(descriptors != descriptors->GetHeap()->empty_descriptor_array());

-  // The DescriptorArray contains a pointer to its contents array, but the
-  // contents array will be marked black and hence not be visited again.
-  if (!base_marker()->MarkObjectAndPush(descriptors)) return;
-  FixedArray* contents = FixedArray::cast(
-      descriptors->get(DescriptorArray::kContentArrayIndex));
-  ASSERT(Marking::IsWhite(Marking::MarkBitFrom(contents)));
-  base_marker()->MarkObjectWithoutPush(contents);
+  if (!base_marker()->MarkObjectWithoutPush(descriptors)) return;
+  Object** descriptor_start = descriptors->data_start();
+
+ // Since the descriptor array itself is not pushed for scanning, all fields + // that point to objects manually have to be pushed, marked, and their slots
+  // recorded.
+  if (descriptors->HasEnumCache()) {
+    Object** enum_cache_slot = descriptors->GetEnumCacheSlot();
+    Object* enum_cache = *enum_cache_slot;
+    base_marker()->MarkObjectAndPush(
+        reinterpret_cast<HeapObject*>(enum_cache));
+    mark_compact_collector()->RecordSlot(descriptor_start,
+                                         enum_cache_slot,
+                                         enum_cache);
+  }

// If the descriptor contains a transition (value is a Map), we don't mark the
   // value as live. It might be set to the NULL_DESCRIPTOR in
   // ClearNonLiveTransitions later.
   for (int i = 0; i < descriptors->number_of_descriptors(); ++i) {
-    PropertyDetails details(descriptors->GetDetails(i));
-    Object** slot = descriptors->GetValueSlot(i);
-
-    if (!(*slot)->IsHeapObject()) continue;
-    HeapObject* value = HeapObject::cast(*slot);
-
-    mark_compact_collector()->RecordSlot(slot, slot, *slot);
+    Object** key_slot = descriptors->GetKeySlot(i);
+    Object* key = *key_slot;
+    if (key->IsHeapObject()) {
+      base_marker()->MarkObjectAndPush(reinterpret_cast<HeapObject*>(key));
+ mark_compact_collector()->RecordSlot(descriptor_start, key_slot, key);
+    }
+
+    Object** value_slot = descriptors->GetValueSlot(i);
+    if (!(*value_slot)->IsHeapObject()) continue;
+    HeapObject* value = HeapObject::cast(*value_slot);
+
+    mark_compact_collector()->RecordSlot(descriptor_start,
+                                         value_slot,
+                                         value);
+
+    PropertyDetails details(descriptors->GetDetails(i));

     switch (details.type()) {
       case NORMAL:
=======================================
--- /branches/bleeding_edge/src/objects-debug.cc        Wed May 23 07:24:29 2012
+++ /branches/bleeding_edge/src/objects-debug.cc        Mon Jun  4 00:20:11 2012
@@ -1013,14 +1013,9 @@
 void Map::ZapInstanceDescriptors() {
   DescriptorArray* descriptors = instance_descriptors();
   if (descriptors == GetHeap()->empty_descriptor_array()) return;
-  FixedArray* contents = FixedArray::cast(
-      descriptors->get(DescriptorArray::kContentArrayIndex));
   MemsetPointer(descriptors->data_start(),
                 GetHeap()->the_hole_value(),
                 descriptors->length());
-  MemsetPointer(contents->data_start(),
-                GetHeap()->the_hole_value(),
-                contents->length());
 }


=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Fri Jun  1 02:12:01 2012
+++ /branches/bleeding_edge/src/objects-inl.h   Mon Jun  4 00:20:11 2012
@@ -1923,6 +1923,14 @@
   }
   return number;
 }
+
+
+Object** DescriptorArray::GetKeySlot(int descriptor_number) {
+  ASSERT(descriptor_number < number_of_descriptors());
+  return HeapObject::RawField(
+      reinterpret_cast<HeapObject*>(this),
+      OffsetOfElementAt(ToKeyIndex(descriptor_number)));
+}


 String* DescriptorArray::GetKey(int descriptor_number) {
@@ -1933,32 +1941,34 @@

 Object** DescriptorArray::GetValueSlot(int descriptor_number) {
   ASSERT(descriptor_number < number_of_descriptors());
-  return GetContentArray()->data_start() + ToValueIndex(descriptor_number);
+  return HeapObject::RawField(
+      reinterpret_cast<HeapObject*>(this),
+      OffsetOfElementAt(ToValueIndex(descriptor_number)));
 }


 Object* DescriptorArray::GetValue(int descriptor_number) {
   ASSERT(descriptor_number < number_of_descriptors());
-  return GetContentArray()->get(ToValueIndex(descriptor_number));
+  return get(ToValueIndex(descriptor_number));
 }


void DescriptorArray::SetNullValueUnchecked(int descriptor_number, Heap* heap) {
   ASSERT(descriptor_number < number_of_descriptors());
- GetContentArray()->set_null_unchecked(heap, ToValueIndex(descriptor_number));
+  set_null_unchecked(heap, ToValueIndex(descriptor_number));
 }


 PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
   ASSERT(descriptor_number < number_of_descriptors());
- Object* details = GetContentArray()->get(ToDetailsIndex(descriptor_number));
+  Object* details = get(ToDetailsIndex(descriptor_number));
   return PropertyDetails(Smi::cast(details));
 }


void DescriptorArray::SetDetailsUnchecked(int descriptor_number, Smi* value) {
   ASSERT(descriptor_number < number_of_descriptors());
- GetContentArray()->set_unchecked(ToDetailsIndex(descriptor_number), value);
+  set_unchecked(ToDetailsIndex(descriptor_number), value);
 }


@@ -2042,11 +2052,10 @@
   NoIncrementalWriteBarrierSet(this,
                                ToKeyIndex(descriptor_number),
                                desc->GetKey());
-  FixedArray* content_array = GetContentArray();
-  NoIncrementalWriteBarrierSet(content_array,
+  NoIncrementalWriteBarrierSet(this,
                                ToValueIndex(descriptor_number),
                                desc->GetValue());
-  NoIncrementalWriteBarrierSet(content_array,
+  NoIncrementalWriteBarrierSet(this,
                                ToDetailsIndex(descriptor_number),
                                desc->GetDetails().AsSmi());
 }
@@ -2055,11 +2064,10 @@
 void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
     int first, int second) {
NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
-  FixedArray* content_array = GetContentArray();
-  NoIncrementalWriteBarrierSwap(content_array,
+  NoIncrementalWriteBarrierSwap(this,
                                 ToValueIndex(first),
                                 ToValueIndex(second));
-  NoIncrementalWriteBarrierSwap(content_array,
+  NoIncrementalWriteBarrierSwap(this,
                                 ToDetailsIndex(first),
                                 ToDetailsIndex(second));
 }
@@ -2070,7 +2078,6 @@
   marking_->EnterNoMarkingScope();
   if (array->number_of_descriptors() > 0) {
     ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
- ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
   }
 }

=======================================
--- /branches/bleeding_edge/src/objects.cc      Fri Jun  1 03:51:36 2012
+++ /branches/bleeding_edge/src/objects.cc      Mon Jun  4 00:20:11 2012
@@ -5116,18 +5116,18 @@
     int index = raw_index / 2;
     int number_of_descriptors = descriptor_array_->number_of_descriptors();
     while (index < number_of_descriptors) {
-      PropertyDetails details(RawGetDetails(index));
+      PropertyDetails details(descriptor_array_->GetDetails(index));
       switch (details.type()) {
         case MAP_TRANSITION:
         case CONSTANT_TRANSITION:
         case ELEMENTS_TRANSITION:
           // We definitely have a map transition.
           *DescriptorArrayHeader() = Smi::FromInt(raw_index + 2);
-          return static_cast<Map*>(RawGetValue(index));
+          return static_cast<Map*>(descriptor_array_->GetValue(index));
         case CALLBACKS: {
           // We might have a map transition in a getter or in a setter.
           AccessorPair* accessors =
-              static_cast<AccessorPair*>(RawGetValue(index));
+ static_cast<AccessorPair*>(descriptor_array_->GetValue(index));
           Object* accessor;
           if ((raw_index & 1) == 0) {
             accessor = accessors->setter();
@@ -5167,24 +5167,6 @@
return HeapObject::RawField(descriptor_array_, DescriptorArray::kMapOffset);
   }

-  FixedArray* RawGetContentArray() {
-      Object* array =
-          descriptor_array_->get(DescriptorArray::kContentArrayIndex);
-      return static_cast<FixedArray*>(array);
-  }
-
-  Object* RawGetValue(int descriptor_number) {
-    return RawGetContentArray()->get(
-        DescriptorArray::ToValueIndex(descriptor_number));
-  }
-
-  PropertyDetails RawGetDetails(int descriptor_number) {
-    Object* details = RawGetContentArray()->get(
-        DescriptorArray::ToDetailsIndex(descriptor_number));
-    return PropertyDetails(Smi::cast(details));
-  }
-
-
   DescriptorArray* descriptor_array_;
 };

@@ -5883,13 +5865,7 @@
   // Do not use DescriptorArray::cast on incomplete object.
   FixedArray* result = FixedArray::cast(array);

-  // Allocate the content array and set it in the descriptor array.
-  { MaybeObject* maybe_array =
-        heap->AllocateFixedArray(number_of_descriptors << 1);
-    if (!maybe_array->ToObject(&array)) return maybe_array;
-  }
   result->set(kBitField3StorageIndex, Smi::FromInt(0));
-  result->set(kContentArrayIndex, array);
   result->set(kEnumerationIndexIndex,
               Smi::FromInt(PropertyDetails::kInitialIndex));
   return result;
@@ -6216,9 +6192,9 @@
   if (other->IsEmpty()) return false;
   if (length() != other->length()) return false;
   for (int i = 0; i < length(); ++i) {
-    if (get(i) != other->get(i) && i != kContentArrayIndex) return false;
-  }
-  return GetContentArray()->IsEqualTo(other->GetContentArray());
+    if (get(i) != other->get(i)) return false;
+  }
+  return true;
 }
 #endif

=======================================
--- /branches/bleeding_edge/src/objects.h       Fri Jun  1 03:51:36 2012
+++ /branches/bleeding_edge/src/objects.h       Mon Jun  4 00:20:11 2012
@@ -2403,7 +2403,7 @@
   int number_of_descriptors() {
     ASSERT(length() > kFirstIndex || IsEmpty());
     int len = length();
-    return len <= kFirstIndex ? 0 : len - kFirstIndex;
+    return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kDescriptorSize;
   }

   int NextEnumerationIndex() {
@@ -2432,6 +2432,12 @@
     FixedArray* bridge = FixedArray::cast(get(kEnumerationIndexIndex));
     return bridge->get(kEnumCacheBridgeCacheIndex);
   }
+
+  Object** GetEnumCacheSlot() {
+    ASSERT(HasEnumCache());
+    return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
+                                kEnumerationIndexOffset);
+  }

// TODO(1399): It should be possible to make room for bit_field3 in the map // without overloading the instance descriptors field in the map
@@ -2447,6 +2453,7 @@

   // Accessors for fetching instance descriptor at descriptor number.
   inline String* GetKey(int descriptor_number);
+  inline Object** GetKeySlot(int descriptor_number);
   inline Object* GetValue(int descriptor_number);
   inline Object** GetValueSlot(int descriptor_number);
   inline void SetNullValueUnchecked(int descriptor_number, Heap* heap);
@@ -2552,9 +2559,8 @@
   static const int kNotFound = -1;

   static const int kBitField3StorageIndex = 0;
-  static const int kContentArrayIndex = 1;
-  static const int kEnumerationIndexIndex = 2;
-  static const int kFirstIndex = 3;
+  static const int kEnumerationIndexIndex = 1;
+  static const int kFirstIndex = 2;

   // The length of the "bridge" to the enum cache.
   static const int kEnumCacheBridgeLength = 3;
@@ -2564,8 +2570,8 @@

   // Layout description.
   static const int kBitField3StorageOffset = FixedArray::kHeaderSize;
- static const int kContentArrayOffset = kBitField3StorageOffset + kPointerSize; - static const int kEnumerationIndexOffset = kContentArrayOffset + kPointerSize;
+  static const int kEnumerationIndexOffset = kBitField3StorageOffset +
+                                             kPointerSize;
   static const int kFirstOffset = kEnumerationIndexOffset + kPointerSize;

   // Layout description for the bridge array.
@@ -2573,6 +2579,12 @@
   static const int kEnumCacheBridgeCacheOffset =
     kEnumCacheBridgeEnumOffset + kPointerSize;

+  // Layout of descriptor.
+  static const int kDescriptorKey = 0;
+  static const int kDescriptorDetails = 1;
+  static const int kDescriptorValue = 2;
+  static const int kDescriptorSize = 3;
+
 #ifdef OBJECT_PRINT
   // Print all the descriptors.
   inline void PrintDescriptors() {
@@ -2597,8 +2609,6 @@
   static const int kMaxNumberOfDescriptors = 1024 + 512;

  private:
-  friend class IntrusiveMapTransitionIterator;
-
   // An entry in a DescriptorArray, represented as an (array, index) pair.
   class Entry {
    public:
@@ -2615,15 +2625,21 @@

   // Conversion from descriptor number to array indices.
   static int ToKeyIndex(int descriptor_number) {
-    return descriptor_number+kFirstIndex;
+    return kFirstIndex +
+           (descriptor_number * kDescriptorSize) +
+           kDescriptorKey;
   }

   static int ToDetailsIndex(int descriptor_number) {
-    return (descriptor_number << 1) + 1;
+    return kFirstIndex +
+           (descriptor_number * kDescriptorSize) +
+           kDescriptorDetails;
   }

   static int ToValueIndex(int descriptor_number) {
-    return descriptor_number << 1;
+    return kFirstIndex +
+           (descriptor_number * kDescriptorSize) +
+           kDescriptorValue;
   }

   // Swap operation on FixedArray without using write barriers.
@@ -2634,10 +2650,6 @@
   inline void NoIncrementalWriteBarrierSwapDescriptors(
       int first, int second);

-  FixedArray* GetContentArray() {
-    return FixedArray::cast(get(kContentArrayIndex));
-  }
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(DescriptorArray);
 };

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to