Moving the WhitenessWitness back to DescriptorArray.

TransitionArrays never allocate while being created.

Review URL: https://chromiumcodereview.appspot.com/10908237

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12519 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
verwaest@chromium.org 2012-09-14 15:10:31 +00:00
parent cb72bf5735
commit 204d22a583
6 changed files with 51 additions and 58 deletions

View File

@ -2167,14 +2167,14 @@ void DescriptorArray::SwapSortedKeys(int first, int second) {
} }
FixedArray::WhitenessWitness::WhitenessWitness(FixedArray* array) DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array)
: marking_(array->GetHeap()->incremental_marking()) { : marking_(array->GetHeap()->incremental_marking()) {
marking_->EnterNoMarkingScope(); marking_->EnterNoMarkingScope();
ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT); ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
} }
FixedArray::WhitenessWitness::~WhitenessWitness() { DescriptorArray::WhitenessWitness::~WhitenessWitness() {
marking_->LeaveNoMarkingScope(); marking_->LeaveNoMarkingScope();
} }

View File

@ -5022,7 +5022,7 @@ MaybeObject* Map::ShareDescriptor(Descriptor* descriptor) {
DescriptorArray* new_descriptors; DescriptorArray* new_descriptors;
MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1); MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
FixedArray::WhitenessWitness witness(new_descriptors); DescriptorArray::WhitenessWitness witness(new_descriptors);
for (int i = 0; i < old_size; ++i) { for (int i = 0; i < old_size; ++i) {
new_descriptors->CopyFrom(i, descriptors, i, witness); new_descriptors->CopyFrom(i, descriptors, i, witness);
@ -5212,7 +5212,7 @@ MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor,
MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1); MaybeObject* maybe_descriptors = DescriptorArray::Allocate(old_size + 1);
if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
FixedArray::WhitenessWitness witness(new_descriptors); DescriptorArray::WhitenessWitness witness(new_descriptors);
// Copy the descriptors, inserting a descriptor. // Copy the descriptors, inserting a descriptor.
for (int i = 0; i < old_size; ++i) { for (int i = 0; i < old_size; ++i) {
@ -12921,7 +12921,7 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
return maybe_descriptors; return maybe_descriptors;
} }
FixedArray::WhitenessWitness witness(descriptors); DescriptorArray::WhitenessWitness witness(descriptors);
int number_of_allocated_fields = int number_of_allocated_fields =
number_of_fields + unused_property_fields - inobject_props; number_of_fields + unused_property_fields - inobject_props;

View File

@ -2375,23 +2375,6 @@ class FixedArray: public FixedArrayBase {
} }
}; };
// WhitenessWitness is used to prove that a descriptor array is white
// (unmarked), so incremental write barriers can be skipped because the
// marking invariant cannot be broken and slots pointing into evacuation
// candidates will be discovered when the object is scanned. A witness is
// always stack-allocated right after creating an array. By allocating a
// witness, incremental marking is globally disabled. The witness is then
// passed along wherever needed to statically prove that the array is known to
// be white.
class WhitenessWitness {
public:
inline explicit WhitenessWitness(FixedArray* array);
inline ~WhitenessWitness();
private:
IncrementalMarking* marking_;
};
protected: protected:
// Set operation on FixedArray without using write barriers. Can // Set operation on FixedArray without using write barriers. Can
// only be used for storing old space objects or smis. // only be used for storing old space objects or smis.
@ -2475,6 +2458,23 @@ class FixedDoubleArray: public FixedArrayBase {
// [length() - kDescriptorSize]: last key // [length() - kDescriptorSize]: last key
class DescriptorArray: public FixedArray { class DescriptorArray: public FixedArray {
public: public:
// WhitenessWitness is used to prove that a descriptor array is white
// (unmarked), so incremental write barriers can be skipped because the
// marking invariant cannot be broken and slots pointing into evacuation
// candidates will be discovered when the object is scanned. A witness is
// always stack-allocated right after creating an array. By allocating a
// witness, incremental marking is globally disabled. The witness is then
// passed along wherever needed to statically prove that the array is known to
// be white.
class WhitenessWitness {
public:
inline explicit WhitenessWitness(FixedArray* array);
inline ~WhitenessWitness();
private:
IncrementalMarking* marking_;
};
// Returns true for both shared empty_descriptor_array and for smis, which the // Returns true for both shared empty_descriptor_array and for smis, which the
// map uses to encode additional bit fields when the descriptor array is not // map uses to encode additional bit fields when the descriptor array is not
// yet used. // yet used.

View File

@ -200,16 +200,13 @@ int TransitionArray::Search(String* name) {
} }
void TransitionArray::Set(int transition_number, void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number,
String* key, String* key,
Map* target, Map* target) {
const WhitenessWitness&) { FixedArray::NoIncrementalWriteBarrierSet(
NoIncrementalWriteBarrierSet(this, this, ToKeyIndex(transition_number), key);
ToKeyIndex(transition_number), FixedArray::NoIncrementalWriteBarrierSet(
key); this, ToTargetIndex(transition_number), target);
NoIncrementalWriteBarrierSet(this,
ToTargetIndex(transition_number),
target);
} }

View File

@ -58,14 +58,12 @@ MaybeObject* TransitionArray::Allocate(int number_of_transitions,
} }
void TransitionArray::CopyFrom(TransitionArray* origin, void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
int origin_transition, int origin_transition,
int target_transition, int target_transition) {
const WhitenessWitness& witness) { NoIncrementalWriteBarrierSet(target_transition,
Set(target_transition, origin->GetKey(origin_transition),
origin->GetKey(origin_transition), origin->GetTarget(origin_transition));
origin->GetTarget(origin_transition),
witness);
} }
@ -84,9 +82,7 @@ MaybeObject* TransitionArray::NewWith(
MaybeObject* maybe_array = TransitionArray::Allocate(1, descriptors_pointer); MaybeObject* maybe_array = TransitionArray::Allocate(1, descriptors_pointer);
if (!maybe_array->To(&result)) return maybe_array; if (!maybe_array->To(&result)) return maybe_array;
FixedArray::WhitenessWitness witness(result); result->NoIncrementalWriteBarrierSet(0, name, target);
result->Set(0, name, target, witness);
result->set_back_pointer_storage(back_pointer); result->set_back_pointer_storage(back_pointer);
return result; return result;
} }
@ -113,26 +109,28 @@ MaybeObject* TransitionArray::CopyInsert(String* name, Map* target) {
result->SetPrototypeTransitions(GetPrototypeTransitions()); result->SetPrototypeTransitions(GetPrototypeTransitions());
} }
FixedArray::WhitenessWitness witness(result);
if (insertion_index != kNotFound) { if (insertion_index != kNotFound) {
for (int i = 0; i < number_of_transitions; ++i) { for (int i = 0; i < number_of_transitions; ++i) {
if (i != insertion_index) result->CopyFrom(this, i, i, witness); if (i != insertion_index) {
result->NoIncrementalWriteBarrierCopyFrom(this, i, i);
}
} }
result->Set(insertion_index, name, target, witness); result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
return result; return result;
} }
insertion_index = 0; insertion_index = 0;
for (; insertion_index < number_of_transitions; ++insertion_index) { for (; insertion_index < number_of_transitions; ++insertion_index) {
if (InsertionPointFound(GetKey(insertion_index), name)) break; if (InsertionPointFound(GetKey(insertion_index), name)) break;
result->CopyFrom(this, insertion_index, insertion_index, witness); result->NoIncrementalWriteBarrierCopyFrom(
this, insertion_index, insertion_index);
} }
result->Set(insertion_index, name, target, witness); result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
for (; insertion_index < number_of_transitions; ++insertion_index) { for (; insertion_index < number_of_transitions; ++insertion_index) {
result->CopyFrom(this, insertion_index, insertion_index + 1, witness); result->NoIncrementalWriteBarrierCopyFrom(
this, insertion_index, insertion_index + 1);
} }
result->set_back_pointer_storage(back_pointer_storage()); result->set_back_pointer_storage(back_pointer_storage());

View File

@ -111,10 +111,9 @@ class TransitionArray: public FixedArray {
MUST_USE_RESULT MaybeObject* CopyInsert(String* name, Map* target); MUST_USE_RESULT MaybeObject* CopyInsert(String* name, Map* target);
// Copy a single transition from the origin array. // Copy a single transition from the origin array.
inline void CopyFrom(TransitionArray* origin, inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
int origin_transition, int origin_transition,
int target_transition, int target_transition);
const WhitenessWitness& witness);
// Search a transition for a given property name. // Search a transition for a given property name.
inline int Search(String* name); inline int Search(String* name);
@ -182,10 +181,9 @@ class TransitionArray: public FixedArray {
kTransitionTarget; kTransitionTarget;
} }
inline void Set(int transition_number, inline void NoIncrementalWriteBarrierSet(int transition_number,
String* key, String* key,
Map* target, Map* target);
const WhitenessWitness&);
DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray); DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray);
}; };