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