Handlify Map::CopyDropDescriptors().

* And contain knowledge better in TransitionArray and DescriptorArray (for example WhitenessWitness is now private to DescriptorArray).
* And remove some factory methods
* And handlify some other things.

R=verwaest@chromium.org

Review URL: https://codereview.chromium.org/234783002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20686 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 93c97174
This diff is collapsed.
...@@ -133,33 +133,6 @@ Handle<WeakHashTable> Factory::NewWeakHashTable(int at_least_space_for) { ...@@ -133,33 +133,6 @@ Handle<WeakHashTable> Factory::NewWeakHashTable(int at_least_space_for) {
} }
Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors,
int slack) {
ASSERT(0 <= number_of_descriptors);
CALL_HEAP_FUNCTION(isolate(),
DescriptorArray::Allocate(
isolate(), number_of_descriptors, slack),
DescriptorArray);
}
Handle<TransitionArray> Factory::NewTransitionArray(int number_of_transitions) {
ASSERT(0 <= number_of_transitions);
CALL_HEAP_FUNCTION(isolate(),
TransitionArray::Allocate(
isolate(), number_of_transitions),
TransitionArray);
}
Handle<TransitionArray> Factory::NewSimpleTransitionArray(Handle<Map> target) {
CALL_HEAP_FUNCTION(isolate(),
TransitionArray::AllocateSimple(
isolate(), *target),
TransitionArray);
}
Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData( Handle<DeoptimizationInputData> Factory::NewDeoptimizationInputData(
int deopt_entry_count, int deopt_entry_count,
PretenureFlag pretenure) { PretenureFlag pretenure) {
......
...@@ -55,10 +55,6 @@ class Factory V8_FINAL { ...@@ -55,10 +55,6 @@ class Factory V8_FINAL {
Handle<WeakHashTable> NewWeakHashTable(int at_least_space_for); Handle<WeakHashTable> NewWeakHashTable(int at_least_space_for);
Handle<DescriptorArray> NewDescriptorArray(int number_of_descriptors,
int slack = 0);
Handle<TransitionArray> NewTransitionArray(int number_of_transitions);
Handle<TransitionArray> NewSimpleTransitionArray(Handle<Map> target);
Handle<DeoptimizationInputData> NewDeoptimizationInputData( Handle<DeoptimizationInputData> NewDeoptimizationInputData(
int deopt_entry_count, int deopt_entry_count,
PretenureFlag pretenure); PretenureFlag pretenure);
......
...@@ -2835,7 +2835,7 @@ void DescriptorArray::SwapSortedKeys(int first, int second) { ...@@ -2835,7 +2835,7 @@ void DescriptorArray::SwapSortedKeys(int first, int second) {
} }
DescriptorArray::WhitenessWitness::WhitenessWitness(FixedArray* array) DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
: marking_(array->GetHeap()->incremental_marking()) { : marking_(array->GetHeap()->incremental_marking()) {
marking_->EnterNoMarkingScope(); marking_->EnterNoMarkingScope();
ASSERT(!marking_->IsMarking() || ASSERT(!marking_->IsMarking() ||
...@@ -4963,21 +4963,18 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) { ...@@ -4963,21 +4963,18 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) {
// If the descriptor is using the empty transition array, install a new empty // If the descriptor is using the empty transition array, install a new empty
// transition array that will have place for an element transition. // transition array that will have place for an element transition.
static MaybeObject* EnsureHasTransitionArray(Map* map) { static void EnsureHasTransitionArray(Handle<Map> map) {
TransitionArray* transitions; Handle<TransitionArray> transitions;
MaybeObject* maybe_transitions;
if (!map->HasTransitionArray()) { if (!map->HasTransitionArray()) {
maybe_transitions = TransitionArray::Allocate(map->GetIsolate(), 0); transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
transitions->set_back_pointer_storage(map->GetBackPointer()); transitions->set_back_pointer_storage(map->GetBackPointer());
} else if (!map->transitions()->IsFullTransitionArray()) { } else if (!map->transitions()->IsFullTransitionArray()) {
maybe_transitions = map->transitions()->ExtendToFullTransitionArray(); transitions = TransitionArray::ExtendToFullTransitionArray(
if (!maybe_transitions->To(&transitions)) return maybe_transitions; handle(map->transitions()));
} else { } else {
return map; return;
} }
map->set_transitions(transitions); map->set_transitions(*transitions);
return transitions;
} }
...@@ -5018,12 +5015,11 @@ void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) { ...@@ -5018,12 +5015,11 @@ void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
} }
void Map::AppendDescriptor(Descriptor* desc, void Map::AppendDescriptor(Descriptor* desc) {
const DescriptorArray::WhitenessWitness& witness) {
DescriptorArray* descriptors = instance_descriptors(); DescriptorArray* descriptors = instance_descriptors();
int number_of_own_descriptors = NumberOfOwnDescriptors(); int number_of_own_descriptors = NumberOfOwnDescriptors();
ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
descriptors->Append(desc, witness); descriptors->Append(desc);
SetNumberOfOwnDescriptors(number_of_own_descriptors + 1); SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
} }
...@@ -5089,19 +5085,18 @@ FixedArray* Map::GetPrototypeTransitions() { ...@@ -5089,19 +5085,18 @@ FixedArray* Map::GetPrototypeTransitions() {
} }
MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) { void Map::SetPrototypeTransitions(
MaybeObject* allow_prototype = EnsureHasTransitionArray(this); Handle<Map> map, Handle<FixedArray> proto_transitions) {
if (allow_prototype->IsFailure()) return allow_prototype; EnsureHasTransitionArray(map);
int old_number_of_transitions = NumberOfProtoTransitions(); int old_number_of_transitions = map->NumberOfProtoTransitions();
#ifdef DEBUG #ifdef DEBUG
if (HasPrototypeTransitions()) { if (map->HasPrototypeTransitions()) {
ASSERT(GetPrototypeTransitions() != proto_transitions); ASSERT(map->GetPrototypeTransitions() != *proto_transitions);
ZapPrototypeTransitions(); map->ZapPrototypeTransitions();
} }
#endif #endif
transitions()->SetPrototypeTransitions(proto_transitions); map->transitions()->SetPrototypeTransitions(*proto_transitions);
SetNumberOfProtoTransitions(old_number_of_transitions); map->SetNumberOfProtoTransitions(old_number_of_transitions);
return this;
} }
......
This diff is collapsed.
...@@ -3349,23 +3349,6 @@ class ConstantPoolArray: public FixedArrayBase { ...@@ -3349,23 +3349,6 @@ class ConstantPoolArray: public FixedArrayBase {
// [2 + number of descriptors * kDescriptorSize]: start of slack // [2 + number of descriptors * kDescriptorSize]: start of slack
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.
...@@ -3455,15 +3438,12 @@ class DescriptorArray: public FixedArray { ...@@ -3455,15 +3438,12 @@ class DescriptorArray: public FixedArray {
// Accessor for complete descriptor. // Accessor for complete descriptor.
inline void Get(int descriptor_number, Descriptor* desc); inline void Get(int descriptor_number, Descriptor* desc);
inline void Set(int descriptor_number, inline void Set(int descriptor_number, Descriptor* desc);
Descriptor* desc,
const WhitenessWitness&);
void Replace(int descriptor_number, Descriptor* descriptor); void Replace(int descriptor_number, Descriptor* descriptor);
// Append automatically sets the enumeration index. This should only be used // Append automatically sets the enumeration index. This should only be used
// to add descriptors in bulk at the end, followed by sorting the descriptor // to add descriptors in bulk at the end, followed by sorting the descriptor
// array. // array.
inline void Append(Descriptor* desc, const WhitenessWitness&);
inline void Append(Descriptor* desc); inline void Append(Descriptor* desc);
static Handle<DescriptorArray> Merge(Handle<Map> left_map, static Handle<DescriptorArray> Merge(Handle<Map> left_map,
...@@ -3502,9 +3482,9 @@ class DescriptorArray: public FixedArray { ...@@ -3502,9 +3482,9 @@ class DescriptorArray: public FixedArray {
// Allocates a DescriptorArray, but returns the singleton // Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0. // empty descriptor array object if number_of_descriptors is 0.
MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate, static Handle<DescriptorArray> Allocate(Isolate* isolate,
int number_of_descriptors, int number_of_descriptors,
int slack = 0); int slack = 0);
// Casting. // Casting.
static inline DescriptorArray* cast(Object* obj); static inline DescriptorArray* cast(Object* obj);
...@@ -3558,6 +3538,23 @@ class DescriptorArray: public FixedArray { ...@@ -3558,6 +3538,23 @@ class DescriptorArray: public FixedArray {
} }
private: private:
// 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(DescriptorArray* array);
inline ~WhitenessWitness();
private:
IncrementalMarking* marking_;
};
// An entry in a DescriptorArray, represented as an (array, index) pair. // An entry in a DescriptorArray, represented as an (array, index) pair.
class Entry { class Entry {
public: public:
...@@ -3597,7 +3594,11 @@ class DescriptorArray: public FixedArray { ...@@ -3597,7 +3594,11 @@ class DescriptorArray: public FixedArray {
DescriptorArray* src, DescriptorArray* src,
const WhitenessWitness&); const WhitenessWitness&);
inline void Set(int descriptor_number, Descriptor* desc); inline void Set(int descriptor_number,
Descriptor* desc,
const WhitenessWitness&);
inline void Append(Descriptor* desc, const WhitenessWitness&);
// Swap first and second descriptor. // Swap first and second descriptor.
inline void SwapSortedKeys(int first, int second); inline void SwapSortedKeys(int first, int second);
...@@ -4099,11 +4100,6 @@ class NameDictionary: public Dictionary<NameDictionaryShape, Name*> { ...@@ -4099,11 +4100,6 @@ class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
static void DoGenerateNewEnumerationIndices( static void DoGenerateNewEnumerationIndices(
Handle<NameDictionary> dictionary); Handle<NameDictionary> dictionary);
// For transforming properties of a JSObject.
MUST_USE_RESULT MaybeObject* TransformPropertiesToFastFor(
JSObject* obj,
int unused_property_fields);
// Find entry for key, otherwise return kNotFound. Optimized version of // Find entry for key, otherwise return kNotFound. Optimized version of
// HashTable::FindEntry. // HashTable::FindEntry.
int FindEntry(Name* key); int FindEntry(Name* key);
...@@ -6336,8 +6332,8 @@ class Map: public HeapObject { ...@@ -6336,8 +6332,8 @@ class Map: public HeapObject {
// 2 + 2 * i: prototype // 2 + 2 * i: prototype
// 3 + 2 * i: target map // 3 + 2 * i: target map
inline FixedArray* GetPrototypeTransitions(); inline FixedArray* GetPrototypeTransitions();
MUST_USE_RESULT inline MaybeObject* SetPrototypeTransitions( static inline void SetPrototypeTransitions(
FixedArray* prototype_transitions); Handle<Map> map, Handle<FixedArray> prototype_transitions);
inline bool HasPrototypeTransitions(); inline bool HasPrototypeTransitions();
static const int kProtoTransitionHeaderSize = 1; static const int kProtoTransitionHeaderSize = 1;
...@@ -6432,7 +6428,6 @@ class Map: public HeapObject { ...@@ -6432,7 +6428,6 @@ class Map: public HeapObject {
static Handle<Map> RawCopy(Handle<Map> map, int instance_size); static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
static Handle<Map> CopyDropDescriptors(Handle<Map> map); static Handle<Map> CopyDropDescriptors(Handle<Map> map);
MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
static Handle<Map> CopyReplaceDescriptors( static Handle<Map> CopyReplaceDescriptors(
Handle<Map> map, Handle<Map> map,
Handle<DescriptorArray> descriptors, Handle<DescriptorArray> descriptors,
...@@ -6476,8 +6471,7 @@ class Map: public HeapObject { ...@@ -6476,8 +6471,7 @@ class Map: public HeapObject {
PropertyNormalizationMode mode, PropertyNormalizationMode mode,
NormalizedMapSharingMode sharing); NormalizedMapSharingMode sharing);
inline void AppendDescriptor(Descriptor* desc, inline void AppendDescriptor(Descriptor* desc);
const DescriptorArray::WhitenessWitness&);
// Returns a copy of the map, with all transitions dropped from the // Returns a copy of the map, with all transitions dropped from the
// instance descriptors. // instance descriptors.
......
...@@ -35,34 +35,21 @@ namespace v8 { ...@@ -35,34 +35,21 @@ namespace v8 {
namespace internal { namespace internal {
static MaybeObject* AllocateRaw(Isolate* isolate, int length) { Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate,
// Use FixedArray to not use TransitionArray::cast on incomplete object. int number_of_transitions) {
FixedArray* array; Handle<FixedArray> array =
MaybeObject* maybe_array = isolate->heap()->AllocateFixedArray(length); isolate->factory()->NewFixedArray(ToKeyIndex(number_of_transitions));
if (!maybe_array->To(&array)) return maybe_array;
return array;
}
MaybeObject* TransitionArray::Allocate(Isolate* isolate,
int number_of_transitions) {
FixedArray* array;
MaybeObject* maybe_array =
AllocateRaw(isolate, ToKeyIndex(number_of_transitions));
if (!maybe_array->To(&array)) return maybe_array;
array->set(kPrototypeTransitionsIndex, Smi::FromInt(0)); array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
return array; return Handle<TransitionArray>::cast(array);
} }
MaybeObject* TransitionArray::AllocateSimple(Isolate* isolate, Handle<TransitionArray> TransitionArray::AllocateSimple(Isolate* isolate,
Map* target) { Handle<Map> target) {
FixedArray* array; Handle<FixedArray> array =
MaybeObject* maybe_array = isolate->factory()->NewFixedArray(kSimpleTransitionSize);
AllocateRaw(isolate, kSimpleTransitionSize); array->set(kSimpleTransitionTarget, *target);
if (!maybe_array->To(&array)) return maybe_array; return Handle<TransitionArray>::cast(array);
array->set(kSimpleTransitionTarget, target);
return array;
} }
...@@ -85,12 +72,12 @@ Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, ...@@ -85,12 +72,12 @@ Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
Handle<Map> target, Handle<Map> target,
SimpleTransitionFlag flag) { SimpleTransitionFlag flag) {
Handle<TransitionArray> result; Handle<TransitionArray> result;
Factory* factory = name->GetIsolate()->factory(); Isolate* isolate = name->GetIsolate();
if (flag == SIMPLE_TRANSITION) { if (flag == SIMPLE_TRANSITION) {
result = factory->NewSimpleTransitionArray(target); result = AllocateSimple(isolate, target);
} else { } else {
result = factory->NewTransitionArray(1); result = Allocate(isolate, 1);
result->NoIncrementalWriteBarrierSet(0, *name, *target); result->NoIncrementalWriteBarrierSet(0, *name, *target);
} }
result->set_back_pointer_storage(map->GetBackPointer()); result->set_back_pointer_storage(map->GetBackPointer());
...@@ -98,18 +85,18 @@ Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, ...@@ -98,18 +85,18 @@ Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
} }
MaybeObject* TransitionArray::ExtendToFullTransitionArray() { Handle<TransitionArray> TransitionArray::ExtendToFullTransitionArray(
ASSERT(!IsFullTransitionArray()); Handle<TransitionArray> array) {
int nof = number_of_transitions(); ASSERT(!array->IsFullTransitionArray());
TransitionArray* result; int nof = array->number_of_transitions();
MaybeObject* maybe_result = Allocate(GetIsolate(), nof); Handle<TransitionArray> result = Allocate(array->GetIsolate(), nof);
if (!maybe_result->To(&result)) return maybe_result;
if (nof == 1) { if (nof == 1) {
result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0); result->NoIncrementalWriteBarrierCopyFrom(
*array, kSimpleTransitionIndex, 0);
} }
result->set_back_pointer_storage(back_pointer_storage()); result->set_back_pointer_storage(array->back_pointer_storage());
return result; return result;
} }
...@@ -128,8 +115,7 @@ Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map, ...@@ -128,8 +115,7 @@ Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map,
int insertion_index = map->transitions()->Search(*name); int insertion_index = map->transitions()->Search(*name);
if (insertion_index == kNotFound) ++new_size; if (insertion_index == kNotFound) ++new_size;
Handle<TransitionArray> result = Handle<TransitionArray> result = Allocate(map->GetIsolate(), new_size);
map->GetIsolate()->factory()->NewTransitionArray(new_size);
// The map's transition array may have disappeared or grown smaller during // The map's transition array may have disappeared or grown smaller during
// the allocation above as it was weakly traversed. Trim the result copy if // the allocation above as it was weakly traversed. Trim the result copy if
......
...@@ -95,13 +95,8 @@ class TransitionArray: public FixedArray { ...@@ -95,13 +95,8 @@ class TransitionArray: public FixedArray {
inline int number_of_entries() { return number_of_transitions(); } inline int number_of_entries() { return number_of_transitions(); }
// Allocate a new transition array with a single entry. static Handle<TransitionArray> ExtendToFullTransitionArray(
static Handle<TransitionArray> NewWith(Handle<Map> map, Handle<TransitionArray> array);
Handle<Name> name,
Handle<Map> target,
SimpleTransitionFlag flag);
MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();
// Create a transition array, copying from the owning map if it already has // Create a transition array, copying from the owning map if it already has
// one, otherwise creating a new one according to flag. // one, otherwise creating a new one according to flag.
...@@ -112,21 +107,13 @@ class TransitionArray: public FixedArray { ...@@ -112,21 +107,13 @@ class TransitionArray: public FixedArray {
Handle<Map> target, Handle<Map> target,
SimpleTransitionFlag flag); SimpleTransitionFlag flag);
// Copy a single transition from the origin array.
inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
int origin_transition,
int target_transition);
// Search a transition for a given property name. // Search a transition for a given property name.
inline int Search(Name* name); inline int Search(Name* name);
// Allocates a TransitionArray. // Allocates a TransitionArray.
MUST_USE_RESULT static MaybeObject* Allocate( static Handle<TransitionArray> Allocate(
Isolate* isolate, int number_of_transitions); Isolate* isolate, int number_of_transitions);
MUST_USE_RESULT static MaybeObject* AllocateSimple(
Isolate* isolate, Map* target);
bool IsSimpleTransition() { bool IsSimpleTransition() {
return length() == kSimpleTransitionSize && return length() == kSimpleTransitionSize &&
get(kSimpleTransitionTarget)->IsHeapObject() && get(kSimpleTransitionTarget)->IsHeapObject() &&
...@@ -204,10 +191,24 @@ class TransitionArray: public FixedArray { ...@@ -204,10 +191,24 @@ class TransitionArray: public FixedArray {
kTransitionTarget; kTransitionTarget;
} }
static Handle<TransitionArray> AllocateSimple(
Isolate* isolate, Handle<Map> target);
// Allocate a new transition array with a single entry.
static Handle<TransitionArray> NewWith(Handle<Map> map,
Handle<Name> name,
Handle<Map> target,
SimpleTransitionFlag flag);
inline void NoIncrementalWriteBarrierSet(int transition_number, inline void NoIncrementalWriteBarrierSet(int transition_number,
Name* key, Name* key,
Map* target); Map* target);
// Copy a single transition from the origin array.
inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
int origin_transition,
int target_transition);
DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray); DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray);
}; };
......
...@@ -137,15 +137,12 @@ TEST(StressJS) { ...@@ -137,15 +137,12 @@ TEST(StressJS) {
factory->NewStringFromAscii(Vector<const char>("get", 3)); factory->NewStringFromAscii(Vector<const char>("get", 3));
ASSERT(instance_descriptors->IsEmpty()); ASSERT(instance_descriptors->IsEmpty());
Handle<DescriptorArray> new_descriptors = factory->NewDescriptorArray(0, 1); Map::EnsureDescriptorSlack(map, 1);
v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
map->set_instance_descriptors(*new_descriptors);
CallbacksDescriptor d(name, CallbacksDescriptor d(name,
foreign, foreign,
static_cast<PropertyAttributes>(0)); static_cast<PropertyAttributes>(0));
map->AppendDescriptor(&d, witness); map->AppendDescriptor(&d);
// Add the Foo constructor the global object. // Add the Foo constructor the global object.
env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "Foo"), env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "Foo"),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment