Reviewers: Michael Starzinger,
Description:
Decoupling MarkDescriptorArray as much as possible from the ContentArray.
Please review this at https://chromiumcodereview.appspot.com/10417030/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/mark-compact.cc
M src/objects-inl.h
M src/objects.h
M src/objects.cc
Index: src/mark-compact.cc
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index
c455564b41a736d268db2e81a9259fec07b261bd..87eac19a9d3e038a1773f4a7bdf3de2d95a1ec9d
100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -1872,17 +1872,16 @@ void
Marker<T>::MarkDescriptorArray(DescriptorArray* descriptors) {
if (!base_marker()->MarkObjectAndPush(descriptors)) return;
FixedArray* contents = FixedArray::cast(
descriptors->get(DescriptorArray::kContentArrayIndex));
- ASSERT(contents->length() >= 2);
ASSERT(Marking::IsWhite(Marking::MarkBitFrom(contents)));
base_marker()->MarkObjectWithoutPush(contents);
// Contents contains (value, details) pairs. 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 < contents->length(); i += 2) {
- PropertyDetails details(Smi::cast(contents->get(i + 1)));
+ for (int i = 0; i < descriptors->number_of_descriptors(); ++i) {
+ PropertyDetails details(descriptors->GetDetails(i));
+ Object** slot = descriptors->GetValueSlot(i);
- Object** slot = contents->data_start() + i;
if (!(*slot)->IsHeapObject()) continue;
HeapObject* value = HeapObject::cast(*slot);
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
93cb0fc809c5d6cd83c6adb5346b14cd926fa8f9..6e7b116283c4f1b91bc1f935ce7fc3d2ce89ae4f
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1928,6 +1928,10 @@ String* DescriptorArray::GetKey(int
descriptor_number) {
return String::cast(get(ToKeyIndex(descriptor_number)));
}
+Object** DescriptorArray::GetValueSlot(int descriptor_number) {
+ ASSERT(descriptor_number < number_of_descriptors());
+ return GetContentArray()->data_start() + ToValueIndex(descriptor_number);
+}
Object* DescriptorArray::GetValue(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
4e4fb385b966f7f5949a35a7e2ad1e8ad9fed9c1..ca290780fca6aa1f85ffdb8c1e1fbb10b5054be4
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -5838,7 +5838,11 @@ MaybeObject* DescriptorArray::RemoveTransitions() {
return new_descriptors;
}
-
+// We need the whiteness witness since sort will reshuffle the entries in
the
+// descriptor array. If the descriptor array were to be gray, the sort
would
+// potentially swap a black and a white member. This would resulting in
+// accidentally reclaiming the white member if the descriptor array owned
the
+// unique pointer.
void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
// In-place heap sort.
int len = number_of_descriptors();
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
116c92b54025c5ec938a81c04c0c4d87085d5460..c9a47c599c6ece3bade6c02acd0c50c39feebbf9
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -2474,6 +2474,7 @@ class DescriptorArray: public FixedArray {
// Accessors for fetching instance descriptor at descriptor number.
inline String* GetKey(int descriptor_number);
inline Object* GetValue(int descriptor_number);
+ inline Object** GetValueSlot(int descriptor_number);
inline PropertyDetails GetDetails(int descriptor_number);
inline Object* RawGetValue(int descriptor_number);
@@ -2488,6 +2489,13 @@ class DescriptorArray: public FixedArray {
inline bool IsTransitionOnly(int descriptor_number);
inline bool IsNullDescriptor(int descriptor_number);
+ // WhitenessWitness is used to prove that a specific descriptor array is
white
+ // (unmarked), so potentially unique heap objects can be freely assigned
+ // without potentially causing memory leaks. A witness is always
+ // stack-allocated right after creating a descriptor array. By
allocating a witness,
+ // incremental marking is globally disabled. The witness is then passed
along
+ // wherever needed to statically prove that the descriptor array is
known to
+ // be white.
class WhitenessWitness {
public:
inline explicit WhitenessWitness(DescriptorArray* array);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev