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) {
}
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(
int deopt_entry_count,
PretenureFlag pretenure) {
......
......@@ -55,10 +55,6 @@ class Factory V8_FINAL {
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(
int deopt_entry_count,
PretenureFlag pretenure);
......
......@@ -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_->EnterNoMarkingScope();
ASSERT(!marking_->IsMarking() ||
......@@ -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
// transition array that will have place for an element transition.
static MaybeObject* EnsureHasTransitionArray(Map* map) {
TransitionArray* transitions;
MaybeObject* maybe_transitions;
static void EnsureHasTransitionArray(Handle<Map> map) {
Handle<TransitionArray> transitions;
if (!map->HasTransitionArray()) {
maybe_transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
transitions = TransitionArray::Allocate(map->GetIsolate(), 0);
transitions->set_back_pointer_storage(map->GetBackPointer());
} else if (!map->transitions()->IsFullTransitionArray()) {
maybe_transitions = map->transitions()->ExtendToFullTransitionArray();
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
transitions = TransitionArray::ExtendToFullTransitionArray(
handle(map->transitions()));
} else {
return map;
return;
}
map->set_transitions(transitions);
return transitions;
map->set_transitions(*transitions);
}
......@@ -5018,12 +5015,11 @@ void Map::ClearTransitions(Heap* heap, WriteBarrierMode mode) {
}
void Map::AppendDescriptor(Descriptor* desc,
const DescriptorArray::WhitenessWitness& witness) {
void Map::AppendDescriptor(Descriptor* desc) {
DescriptorArray* descriptors = instance_descriptors();
int number_of_own_descriptors = NumberOfOwnDescriptors();
ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
descriptors->Append(desc, witness);
descriptors->Append(desc);
SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
}
......@@ -5089,19 +5085,18 @@ FixedArray* Map::GetPrototypeTransitions() {
}
MaybeObject* Map::SetPrototypeTransitions(FixedArray* proto_transitions) {
MaybeObject* allow_prototype = EnsureHasTransitionArray(this);
if (allow_prototype->IsFailure()) return allow_prototype;
int old_number_of_transitions = NumberOfProtoTransitions();
void Map::SetPrototypeTransitions(
Handle<Map> map, Handle<FixedArray> proto_transitions) {
EnsureHasTransitionArray(map);
int old_number_of_transitions = map->NumberOfProtoTransitions();
#ifdef DEBUG
if (HasPrototypeTransitions()) {
ASSERT(GetPrototypeTransitions() != proto_transitions);
ZapPrototypeTransitions();
if (map->HasPrototypeTransitions()) {
ASSERT(map->GetPrototypeTransitions() != *proto_transitions);
map->ZapPrototypeTransitions();
}
#endif
transitions()->SetPrototypeTransitions(proto_transitions);
SetNumberOfProtoTransitions(old_number_of_transitions);
return this;
map->transitions()->SetPrototypeTransitions(*proto_transitions);
map->SetNumberOfProtoTransitions(old_number_of_transitions);
}
......
This diff is collapsed.
......@@ -3349,23 +3349,6 @@ class ConstantPoolArray: public FixedArrayBase {
// [2 + number of descriptors * kDescriptorSize]: start of slack
class DescriptorArray: public FixedArray {
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
// map uses to encode additional bit fields when the descriptor array is not
// yet used.
......@@ -3455,15 +3438,12 @@ class DescriptorArray: public FixedArray {
// Accessor for complete descriptor.
inline void Get(int descriptor_number, Descriptor* desc);
inline void Set(int descriptor_number,
Descriptor* desc,
const WhitenessWitness&);
inline void Set(int descriptor_number, Descriptor* desc);
void Replace(int descriptor_number, Descriptor* descriptor);
// Append automatically sets the enumeration index. This should only be used
// to add descriptors in bulk at the end, followed by sorting the descriptor
// array.
inline void Append(Descriptor* desc, const WhitenessWitness&);
inline void Append(Descriptor* desc);
static Handle<DescriptorArray> Merge(Handle<Map> left_map,
......@@ -3502,9 +3482,9 @@ class DescriptorArray: public FixedArray {
// Allocates a DescriptorArray, but returns the singleton
// empty descriptor array object if number_of_descriptors is 0.
MUST_USE_RESULT static MaybeObject* Allocate(Isolate* isolate,
int number_of_descriptors,
int slack = 0);
static Handle<DescriptorArray> Allocate(Isolate* isolate,
int number_of_descriptors,
int slack = 0);
// Casting.
static inline DescriptorArray* cast(Object* obj);
......@@ -3558,6 +3538,23 @@ class DescriptorArray: public FixedArray {
}
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.
class Entry {
public:
......@@ -3597,7 +3594,11 @@ class DescriptorArray: public FixedArray {
DescriptorArray* src,
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.
inline void SwapSortedKeys(int first, int second);
......@@ -4099,11 +4100,6 @@ class NameDictionary: public Dictionary<NameDictionaryShape, Name*> {
static void DoGenerateNewEnumerationIndices(
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
// HashTable::FindEntry.
int FindEntry(Name* key);
......@@ -6336,8 +6332,8 @@ class Map: public HeapObject {
// 2 + 2 * i: prototype
// 3 + 2 * i: target map
inline FixedArray* GetPrototypeTransitions();
MUST_USE_RESULT inline MaybeObject* SetPrototypeTransitions(
FixedArray* prototype_transitions);
static inline void SetPrototypeTransitions(
Handle<Map> map, Handle<FixedArray> prototype_transitions);
inline bool HasPrototypeTransitions();
static const int kProtoTransitionHeaderSize = 1;
......@@ -6432,7 +6428,6 @@ class Map: public HeapObject {
static Handle<Map> RawCopy(Handle<Map> map, int instance_size);
MUST_USE_RESULT MaybeObject* RawCopy(int instance_size);
static Handle<Map> CopyDropDescriptors(Handle<Map> map);
MUST_USE_RESULT MaybeObject* CopyDropDescriptors();
static Handle<Map> CopyReplaceDescriptors(
Handle<Map> map,
Handle<DescriptorArray> descriptors,
......@@ -6476,8 +6471,7 @@ class Map: public HeapObject {
PropertyNormalizationMode mode,
NormalizedMapSharingMode sharing);
inline void AppendDescriptor(Descriptor* desc,
const DescriptorArray::WhitenessWitness&);
inline void AppendDescriptor(Descriptor* desc);
// Returns a copy of the map, with all transitions dropped from the
// instance descriptors.
......
......@@ -35,34 +35,21 @@ namespace v8 {
namespace internal {
static MaybeObject* AllocateRaw(Isolate* isolate, int length) {
// Use FixedArray to not use TransitionArray::cast on incomplete object.
FixedArray* array;
MaybeObject* maybe_array = isolate->heap()->AllocateFixedArray(length);
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;
Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate,
int number_of_transitions) {
Handle<FixedArray> array =
isolate->factory()->NewFixedArray(ToKeyIndex(number_of_transitions));
array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
return array;
return Handle<TransitionArray>::cast(array);
}
MaybeObject* TransitionArray::AllocateSimple(Isolate* isolate,
Map* target) {
FixedArray* array;
MaybeObject* maybe_array =
AllocateRaw(isolate, kSimpleTransitionSize);
if (!maybe_array->To(&array)) return maybe_array;
array->set(kSimpleTransitionTarget, target);
return array;
Handle<TransitionArray> TransitionArray::AllocateSimple(Isolate* isolate,
Handle<Map> target) {
Handle<FixedArray> array =
isolate->factory()->NewFixedArray(kSimpleTransitionSize);
array->set(kSimpleTransitionTarget, *target);
return Handle<TransitionArray>::cast(array);
}
......@@ -85,12 +72,12 @@ Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
Handle<Map> target,
SimpleTransitionFlag flag) {
Handle<TransitionArray> result;
Factory* factory = name->GetIsolate()->factory();
Isolate* isolate = name->GetIsolate();
if (flag == SIMPLE_TRANSITION) {
result = factory->NewSimpleTransitionArray(target);
result = AllocateSimple(isolate, target);
} else {
result = factory->NewTransitionArray(1);
result = Allocate(isolate, 1);
result->NoIncrementalWriteBarrierSet(0, *name, *target);
}
result->set_back_pointer_storage(map->GetBackPointer());
......@@ -98,18 +85,18 @@ Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
}
MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
ASSERT(!IsFullTransitionArray());
int nof = number_of_transitions();
TransitionArray* result;
MaybeObject* maybe_result = Allocate(GetIsolate(), nof);
if (!maybe_result->To(&result)) return maybe_result;
Handle<TransitionArray> TransitionArray::ExtendToFullTransitionArray(
Handle<TransitionArray> array) {
ASSERT(!array->IsFullTransitionArray());
int nof = array->number_of_transitions();
Handle<TransitionArray> result = Allocate(array->GetIsolate(), nof);
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;
}
......@@ -128,8 +115,7 @@ Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map,
int insertion_index = map->transitions()->Search(*name);
if (insertion_index == kNotFound) ++new_size;
Handle<TransitionArray> result =
map->GetIsolate()->factory()->NewTransitionArray(new_size);
Handle<TransitionArray> result = Allocate(map->GetIsolate(), new_size);
// 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
......
......@@ -95,13 +95,8 @@ class TransitionArray: public FixedArray {
inline int number_of_entries() { return number_of_transitions(); }
// Allocate a new transition array with a single entry.
static Handle<TransitionArray> NewWith(Handle<Map> map,
Handle<Name> name,
Handle<Map> target,
SimpleTransitionFlag flag);
MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();
static Handle<TransitionArray> ExtendToFullTransitionArray(
Handle<TransitionArray> array);
// Create a transition array, copying from the owning map if it already has
// one, otherwise creating a new one according to flag.
......@@ -112,21 +107,13 @@ class TransitionArray: public FixedArray {
Handle<Map> target,
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.
inline int Search(Name* name);
// Allocates a TransitionArray.
MUST_USE_RESULT static MaybeObject* Allocate(
static Handle<TransitionArray> Allocate(
Isolate* isolate, int number_of_transitions);
MUST_USE_RESULT static MaybeObject* AllocateSimple(
Isolate* isolate, Map* target);
bool IsSimpleTransition() {
return length() == kSimpleTransitionSize &&
get(kSimpleTransitionTarget)->IsHeapObject() &&
......@@ -204,10 +191,24 @@ class TransitionArray: public FixedArray {
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,
Name* key,
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);
};
......
......@@ -137,15 +137,12 @@ TEST(StressJS) {
factory->NewStringFromAscii(Vector<const char>("get", 3));
ASSERT(instance_descriptors->IsEmpty());
Handle<DescriptorArray> new_descriptors = factory->NewDescriptorArray(0, 1);
v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
map->set_instance_descriptors(*new_descriptors);
Map::EnsureDescriptorSlack(map, 1);
CallbacksDescriptor d(name,
foreign,
static_cast<PropertyAttributes>(0));
map->AppendDescriptor(&d, witness);
map->AppendDescriptor(&d);
// Add the Foo constructor the global object.
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