Handlefy Descriptor and other code in objects.cc

R=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20628 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1b841f36
This diff is collapsed.
......@@ -1419,13 +1419,14 @@ class DictionaryElementsAccessor
// Adjusts the length of the dictionary backing store and returns the new
// length according to ES5 section 15.4.5.2 behavior.
MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize(
FixedArrayBase* store,
JSArray* array,
Object* length_object,
static Handle<Object> SetLengthWithoutNormalize(
Handle<FixedArrayBase> store,
Handle<JSArray> array,
Handle<Object> length_object,
uint32_t length) {
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
Heap* heap = array->GetHeap();
Handle<SeededNumberDictionary> dict =
Handle<SeededNumberDictionary>::cast(store);
Isolate* isolate = array->GetIsolate();
int capacity = dict->Capacity();
uint32_t new_length = length;
uint32_t old_length = static_cast<uint32_t>(array->length()->Number());
......@@ -1433,6 +1434,7 @@ class DictionaryElementsAccessor
// Find last non-deletable element in range of elements to be
// deleted and adjust range accordingly.
for (int i = 0; i < capacity; i++) {
DisallowHeapAllocation no_gc;
Object* key = dict->KeyAt(i);
if (key->IsNumber()) {
uint32_t number = static_cast<uint32_t>(key->Number());
......@@ -1443,8 +1445,7 @@ class DictionaryElementsAccessor
}
}
if (new_length != length) {
MaybeObject* maybe_object = heap->NumberFromUint32(new_length);
if (!maybe_object->To(&length_object)) return maybe_object;
length_object = isolate->factory()->NewNumberFromUint(new_length);
}
}
......@@ -1452,13 +1453,12 @@ class DictionaryElementsAccessor
// If the length of a slow array is reset to zero, we clear
// the array and flush backing storage. This has the added
// benefit that the array returns to fast mode.
Object* obj;
MaybeObject* maybe_obj = array->ResetElements();
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
JSObject::ResetElements(array);
} else {
DisallowHeapAllocation no_gc;
// Remove elements that should be deleted.
int removed_entries = 0;
Object* the_hole_value = heap->the_hole_value();
Object* the_hole_value = isolate->heap()->the_hole_value();
for (int i = 0; i < capacity; i++) {
Object* key = dict->KeyAt(i);
if (key->IsNumber()) {
......@@ -1476,18 +1476,6 @@ class DictionaryElementsAccessor
return length_object;
}
// TODO(ishell): Temporary wrapper until handlified.
MUST_USE_RESULT static Handle<Object> SetLengthWithoutNormalize(
Handle<FixedArrayBase> store,
Handle<JSArray> array,
Handle<Object> length_object,
uint32_t length) {
CALL_HEAP_FUNCTION(array->GetIsolate(),
SetLengthWithoutNormalize(
*store, *array, *length_object, length),
Object);
}
MUST_USE_RESULT static MaybeObject* DeleteCommon(
JSObject* obj,
uint32_t key,
......
......@@ -143,6 +143,23 @@ Handle<DescriptorArray> Factory::NewDescriptorArray(int number_of_descriptors,
}
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) {
......
......@@ -57,6 +57,8 @@ class Factory V8_FINAL {
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);
......
......@@ -1750,28 +1750,6 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
}
MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
ElementsKind to_kind) {
Map* current_map = map();
ElementsKind from_kind = current_map->elements_kind();
if (from_kind == to_kind) return current_map;
Context* native_context = isolate->context()->native_context();
Object* maybe_array_maps = native_context->js_array_maps();
if (maybe_array_maps->IsFixedArray()) {
FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
if (array_maps->get(from_kind) == current_map) {
Object* maybe_transitioned_map = array_maps->get(to_kind);
if (maybe_transitioned_map->IsMap()) {
return Map::cast(maybe_transitioned_map);
}
}
}
return GetElementsTransitionMapSlow(to_kind);
}
void JSObject::SetMapAndElements(Handle<JSObject> object,
Handle<Map> new_map,
Handle<FixedArrayBase> value) {
......@@ -1800,50 +1778,8 @@ void JSObject::initialize_properties() {
void JSObject::initialize_elements() {
if (map()->has_fast_smi_or_object_elements() ||
map()->has_fast_double_elements()) {
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
} else if (map()->has_external_array_elements()) {
ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(map());
ASSERT(!GetHeap()->InNewSpace(empty_array));
WRITE_FIELD(this, kElementsOffset, empty_array);
} else if (map()->has_fixed_typed_array_elements()) {
FixedTypedArrayBase* empty_array =
GetHeap()->EmptyFixedTypedArrayForMap(map());
ASSERT(!GetHeap()->InNewSpace(empty_array));
WRITE_FIELD(this, kElementsOffset, empty_array);
} else {
UNREACHABLE();
}
}
MaybeObject* JSObject::ResetElements() {
if (map()->is_observed()) {
// Maintain invariant that observed elements are always in dictionary mode.
SeededNumberDictionary* dictionary;
MaybeObject* maybe = SeededNumberDictionary::Allocate(GetHeap(), 0);
if (!maybe->To(&dictionary)) return maybe;
if (map() == GetHeap()->sloppy_arguments_elements_map()) {
FixedArray::cast(elements())->set(1, dictionary);
} else {
set_elements(dictionary);
}
return this;
}
ElementsKind elements_kind = GetInitialFastElementsKind();
if (!FLAG_smi_only_arrays) {
elements_kind = FastSmiToObjectElementsKind(elements_kind);
}
MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
Map* map;
if (!maybe->To(&map)) return maybe;
set_map(map);
initialize_elements();
return this;
FixedArrayBase* elements = map()->GetInitialElements();
WRITE_FIELD(this, kElementsOffset, elements);
}
......@@ -2692,6 +2628,27 @@ void Map::LookupTransition(JSObject* holder,
}
FixedArrayBase* Map::GetInitialElements() {
if (has_fast_smi_or_object_elements() ||
has_fast_double_elements()) {
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
return GetHeap()->empty_fixed_array();
} else if (has_external_array_elements()) {
ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(this);
ASSERT(!GetHeap()->InNewSpace(empty_array));
return empty_array;
} else if (has_fixed_typed_array_elements()) {
FixedTypedArrayBase* empty_array =
GetHeap()->EmptyFixedTypedArrayForMap(this);
ASSERT(!GetHeap()->InNewSpace(empty_array));
return empty_array;
} else {
UNREACHABLE();
}
return NULL;
}
Object** DescriptorArray::GetKeySlot(int descriptor_number) {
ASSERT(descriptor_number < number_of_descriptors());
return RawFieldOfElementAt(ToKeyIndex(descriptor_number));
......@@ -2796,8 +2753,8 @@ AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
desc->Init(GetKey(descriptor_number),
GetValue(descriptor_number),
desc->Init(handle(GetKey(descriptor_number), GetIsolate()),
handle(GetValue(descriptor_number), GetIsolate()),
GetDetails(descriptor_number));
}
......@@ -2810,10 +2767,10 @@ void DescriptorArray::Set(int descriptor_number,
NoIncrementalWriteBarrierSet(this,
ToKeyIndex(descriptor_number),
desc->GetKey());
*desc->GetKey());
NoIncrementalWriteBarrierSet(this,
ToValueIndex(descriptor_number),
desc->GetValue());
*desc->GetValue());
NoIncrementalWriteBarrierSet(this,
ToDetailsIndex(descriptor_number),
desc->GetDetails().AsSmi());
......@@ -2824,14 +2781,15 @@ void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
// Range check.
ASSERT(descriptor_number < number_of_descriptors());
set(ToKeyIndex(descriptor_number), desc->GetKey());
set(ToValueIndex(descriptor_number), desc->GetValue());
set(ToKeyIndex(descriptor_number), *desc->GetKey());
set(ToValueIndex(descriptor_number), *desc->GetValue());
set(ToDetailsIndex(descriptor_number), desc->GetDetails().AsSmi());
}
void DescriptorArray::Append(Descriptor* desc,
const WhitenessWitness& witness) {
DisallowHeapAllocation no_gc;
int descriptor_number = number_of_descriptors();
SetNumberOfDescriptors(descriptor_number + 1);
Set(descriptor_number, desc, witness);
......@@ -2851,6 +2809,7 @@ void DescriptorArray::Append(Descriptor* desc,
void DescriptorArray::Append(Descriptor* desc) {
DisallowHeapAllocation no_gc;
int descriptor_number = number_of_descriptors();
SetNumberOfDescriptors(descriptor_number + 1);
Set(descriptor_number, desc);
......@@ -5066,14 +5025,6 @@ bool Map::CanHaveMoreTransitions() {
}
MaybeObject* Map::AddTransition(Name* key,
Map* target,
SimpleTransitionFlag flag) {
if (HasTransitionArray()) return transitions()->CopyInsert(key, target);
return TransitionArray::NewWith(flag, key, target, GetBackPointer());
}
void Map::SetTransition(int transition_index, Map* target) {
transitions()->SetTarget(transition_index, target);
}
......@@ -5090,18 +5041,6 @@ int Map::SearchTransition(Name* name) {
}
MaybeObject* Map::set_elements_transition_map(Map* transitioned_map) {
TransitionArray* transitions;
MaybeObject* maybe_transitions = AddTransition(
GetHeap()->elements_transition_symbol(),
transitioned_map,
FULL_TRANSITION);
if (!maybe_transitions->To(&transitions)) return maybe_transitions;
set_transitions(transitions);
return transitions;
}
FixedArray* Map::GetPrototypeTransitions() {
if (!HasTransitionArray()) return GetHeap()->empty_fixed_array();
if (!transitions()->HasPrototypeTransitions()) {
......
This diff is collapsed.
......@@ -2186,7 +2186,6 @@ class JSObject: public JSReceiver {
// arguments object.
DECL_ACCESSORS(elements, FixedArrayBase)
inline void initialize_elements();
MUST_USE_RESULT inline MaybeObject* ResetElements();
static void ResetElements(Handle<JSObject> object);
static inline void SetMapAndElements(Handle<JSObject> object,
Handle<Map> map,
......@@ -2580,10 +2579,7 @@ class JSObject: public JSReceiver {
// map and the ElementsKind set.
static Handle<Map> GetElementsTransitionMap(Handle<JSObject> object,
ElementsKind to_kind);
inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap(
Isolate* isolate,
ElementsKind elements_kind);
MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow(
static Handle<Map> GetElementsTransitionMapSlow(Handle<JSObject> object,
ElementsKind elements_kind);
static void TransitionElementsKind(Handle<JSObject> object,
......@@ -3481,17 +3477,13 @@ class DescriptorArray: public FixedArray {
int new_size,
DescriptorArray* other);
MUST_USE_RESULT MaybeObject* CopyUpTo(int enumeration_index) {
return CopyUpToAddAttributes(enumeration_index, NONE);
}
static Handle<DescriptorArray> CopyUpTo(Handle<DescriptorArray> desc,
int enumeration_index);
static Handle<DescriptorArray> CopyUpToAddAttributes(
Handle<DescriptorArray> desc,
int enumeration_index,
PropertyAttributes attributes);
MUST_USE_RESULT MaybeObject* CopyUpToAddAttributes(
int enumeration_index,
PropertyAttributes attributes);
// Sort the instance descriptors by the hash codes of their keys.
void Sort();
......@@ -6172,20 +6164,17 @@ class Map: public HeapObject {
inline bool HasTransitionArray();
inline bool HasElementsTransition();
inline Map* elements_transition_map();
MUST_USE_RESULT inline MaybeObject* set_elements_transition_map(
Map* transitioned_map);
static Handle<TransitionArray> SetElementsTransitionMap(
Handle<Map> map, Handle<Map> transitioned_map);
inline void SetTransition(int transition_index, Map* target);
inline Map* GetTransition(int transition_index);
inline int SearchTransition(Name* name);
inline FixedArrayBase* GetInitialElements();
static Handle<TransitionArray> AddTransition(Handle<Map> map,
Handle<Name> key,
Handle<Map> target,
SimpleTransitionFlag flag);
MUST_USE_RESULT inline MaybeObject* AddTransition(Name* key,
Map* target,
SimpleTransitionFlag flag);
DECL_ACCESSORS(transitions, TransitionArray)
inline void ClearTransitions(Heap* heap,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
......@@ -6391,36 +6380,41 @@ class Map: public HeapObject {
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,
static Handle<Map> CopyReplaceDescriptors(
Handle<Map> map,
Handle<DescriptorArray> descriptors,
TransitionFlag flag,
Handle<Name> name);
MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors(
DescriptorArray* descriptors,
Handle<Name> name,
SimpleTransitionFlag simple_flag = FULL_TRANSITION);
static Handle<Map> CopyReplaceDescriptors(
Handle<Map> map,
Handle<DescriptorArray> descriptors,
TransitionFlag flag,
Name* name = NULL,
SimpleTransitionFlag simple_flag = FULL_TRANSITION);
static Handle<Map> CopyInstallDescriptors(
Handle<Map> map,
int new_descriptor,
Handle<DescriptorArray> descriptors);
MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors,
static Handle<Map> ShareDescriptor(Handle<Map> map,
Handle<DescriptorArray> descriptors,
Descriptor* descriptor);
MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor,
static Handle<Map> CopyAddDescriptor(Handle<Map> map,
Descriptor* descriptor,
TransitionFlag flag);
MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor,
static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
Descriptor* descriptor,
TransitionFlag flag);
MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor(
DescriptorArray* descriptors,
static Handle<Map> CopyReplaceDescriptor(
Handle<Map> map,
Handle<DescriptorArray> descriptors,
Descriptor* descriptor,
int index,
TransitionFlag flag);
MUST_USE_RESULT MaybeObject* AsElementsKind(ElementsKind kind);
static Handle<Map> AsElementsKind(Handle<Map> map, ElementsKind kind);
MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind,
static Handle<Map> CopyAsElementsKind(Handle<Map> map,
ElementsKind kind,
TransitionFlag flag);
static Handle<Map> CopyForObserved(Handle<Map> map);
......@@ -6437,7 +6431,6 @@ class Map: public HeapObject {
static Handle<Map> Copy(Handle<Map> map);
static Handle<Map> Create(Handle<JSFunction> constructor,
int extra_inobject_properties);
MUST_USE_RESULT MaybeObject* Copy();
// Returns the next free property index (only valid for FAST MODE).
int NextFreePropertyIndex();
......
......@@ -6,6 +6,7 @@
#define V8_PROPERTY_H_
#include "isolate.h"
#include "factory.h"
namespace v8 {
namespace internal {
......@@ -17,17 +18,15 @@ namespace internal {
// optionally a piece of data.
class Descriptor BASE_EMBEDDED {
public:
MUST_USE_RESULT MaybeObject* KeyToUniqueName() {
void KeyToUniqueName() {
if (!key_->IsUniqueName()) {
MaybeObject* maybe_result =
key_->GetIsolate()->heap()->InternalizeString(String::cast(key_));
if (!maybe_result->To(&key_)) return maybe_result;
key_ = key_->GetIsolate()->factory()->InternalizeString(
Handle<String>::cast(key_));
}
return key_;
}
Name* GetKey() { return key_; }
Object* GetValue() { return value_; }
Handle<Name> GetKey() { return key_; }
Handle<Object> GetValue() { return value_; }
PropertyDetails GetDetails() { return details_; }
#ifdef OBJECT_PRINT
......@@ -37,26 +36,26 @@ class Descriptor BASE_EMBEDDED {
void SetSortedKeyIndex(int index) { details_ = details_.set_pointer(index); }
private:
Name* key_;
Object* value_;
Handle<Name> key_;
Handle<Object> value_;
PropertyDetails details_;
protected:
Descriptor() : details_(Smi::FromInt(0)) {}
void Init(Name* key, Object* value, PropertyDetails details) {
void Init(Handle<Name> key, Handle<Object> value, PropertyDetails details) {
key_ = key;
value_ = value;
details_ = details;
}
Descriptor(Name* key, Object* value, PropertyDetails details)
Descriptor(Handle<Name> key, Handle<Object> value, PropertyDetails details)
: key_(key),
value_(value),
details_(details) { }
Descriptor(Name* key,
Object* value,
Descriptor(Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes,
PropertyType type,
Representation representation,
......@@ -71,19 +70,19 @@ class Descriptor BASE_EMBEDDED {
class FieldDescriptor V8_FINAL : public Descriptor {
public:
FieldDescriptor(Name* key,
FieldDescriptor(Handle<Name> key,
int field_index,
PropertyAttributes attributes,
Representation representation)
: Descriptor(key, Smi::FromInt(0), attributes,
: Descriptor(key, handle(Smi::FromInt(0), key->GetIsolate()), attributes,
FIELD, representation, field_index) {}
};
class ConstantDescriptor V8_FINAL : public Descriptor {
public:
ConstantDescriptor(Name* key,
Object* value,
ConstantDescriptor(Handle<Name> key,
Handle<Object> value,
PropertyAttributes attributes)
: Descriptor(key, value, attributes, CONSTANT,
value->OptimalRepresentation()) {}
......@@ -92,8 +91,8 @@ class ConstantDescriptor V8_FINAL : public Descriptor {
class CallbacksDescriptor V8_FINAL : public Descriptor {
public:
CallbacksDescriptor(Name* key,
Object* foreign,
CallbacksDescriptor(Handle<Name> key,
Handle<Object> foreign,
PropertyAttributes attributes)
: Descriptor(key, foreign, attributes, CALLBACKS,
Representation::Tagged()) {}
......
......@@ -2944,32 +2944,32 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
RUNTIME_ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
String* name = isolate->heap()->prototype_string();
Handle<String> name = isolate->factory()->prototype_string();
if (function->HasFastProperties()) {
// Construct a new field descriptor with updated attributes.
DescriptorArray* instance_desc = function->map()->instance_descriptors();
Handle<DescriptorArray> instance_desc =
handle(function->map()->instance_descriptors());
int index = instance_desc->SearchWithCache(name, function->map());
int index = instance_desc->SearchWithCache(*name, function->map());
ASSERT(index != DescriptorArray::kNotFound);
PropertyDetails details = instance_desc->GetDetails(index);
CallbacksDescriptor new_desc(name,
instance_desc->GetValue(index),
CallbacksDescriptor new_desc(
name,
handle(instance_desc->GetValue(index), isolate),
static_cast<PropertyAttributes>(details.attributes() | READ_ONLY));
// Create a new map featuring the new field descriptors array.
Map* new_map;
MaybeObject* maybe_map =
function->map()->CopyReplaceDescriptor(
instance_desc, &new_desc, index, OMIT_TRANSITION);
if (!maybe_map->To(&new_map)) return maybe_map;
Handle<Map> map = handle(function->map());
Handle<Map> new_map = Map::CopyReplaceDescriptor(
map, instance_desc, &new_desc, index, OMIT_TRANSITION);
JSObject::MigrateToMap(function, handle(new_map));
JSObject::MigrateToMap(function, new_map);
} else { // Dictionary properties.
// Directly manipulate the property details.
DisallowHeapAllocation no_gc;
int entry = function->property_dictionary()->FindEntry(name);
int entry = function->property_dictionary()->FindEntry(*name);
ASSERT(entry != NameDictionary::kNotFound);
PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
PropertyDetails new_details(
......
......@@ -55,6 +55,17 @@ MaybeObject* TransitionArray::Allocate(Isolate* isolate,
}
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;
}
void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
int origin_transition,
int target_transition) {
......@@ -69,23 +80,20 @@ static bool InsertionPointFound(Name* key1, Name* key2) {
}
MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
Name* key,
Map* target,
Object* back_pointer) {
TransitionArray* result;
MaybeObject* maybe_result;
Handle<TransitionArray> TransitionArray::NewWith(SimpleTransitionFlag flag,
Handle<Name> key,
Handle<Map> target,
Handle<Object> back_pointer) {
Handle<TransitionArray> result;
Factory* factory = key->GetIsolate()->factory();
if (flag == SIMPLE_TRANSITION) {
maybe_result = AllocateRaw(target->GetIsolate(), kSimpleTransitionSize);
if (!maybe_result->To(&result)) return maybe_result;
result->set(kSimpleTransitionTarget, target);
result = factory->NewSimpleTransitionArray(target);
} else {
maybe_result = Allocate(target->GetIsolate(), 1);
if (!maybe_result->To(&result)) return maybe_result;
result->NoIncrementalWriteBarrierSet(0, key, target);
result = factory->NewTransitionArray(1);
result->NoIncrementalWriteBarrierSet(0, *key, *target);
}
result->set_back_pointer_storage(back_pointer);
result->set_back_pointer_storage(*back_pointer);
return result;
}
......@@ -106,49 +114,67 @@ MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
}
MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) {
TransitionArray* result;
Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map,
Handle<Name> name,
Handle<Map> target) {
ASSERT(map->HasTransitionArray());
Handle<TransitionArray> result;
int number_of_transitions = this->number_of_transitions();
int number_of_transitions = map->transitions()->number_of_transitions();
int new_size = number_of_transitions;
int insertion_index = this->Search(name);
int insertion_index = map->transitions()->Search(*name);
if (insertion_index == kNotFound) ++new_size;
MaybeObject* maybe_array;
maybe_array = TransitionArray::Allocate(GetIsolate(), new_size);
if (!maybe_array->To(&result)) return maybe_array;
result = map->GetIsolate()->factory()->NewTransitionArray(new_size);
// The map's transition array may have grown smaller during the allocation
// above as it was weakly traversed. Trim the result copy if needed, and
// recompute variables.
DisallowHeapAllocation no_gc;
TransitionArray* array = map->transitions();
if (array->number_of_transitions() != number_of_transitions) {
ASSERT(array->number_of_transitions() < number_of_transitions);
number_of_transitions = array->number_of_transitions();
new_size = number_of_transitions;
insertion_index = array->Search(*name);
if (insertion_index == kNotFound) ++new_size;
if (HasPrototypeTransitions()) {
result->SetPrototypeTransitions(GetPrototypeTransitions());
result->Shrink(new_size);
}
if (array->HasPrototypeTransitions()) {
result->SetPrototypeTransitions(array->GetPrototypeTransitions());
}
if (insertion_index != kNotFound) {
for (int i = 0; i < number_of_transitions; ++i) {
if (i != insertion_index) {
result->NoIncrementalWriteBarrierCopyFrom(this, i, i);
result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
}
}
result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
result->set_back_pointer_storage(back_pointer_storage());
result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
result->set_back_pointer_storage(array->back_pointer_storage());
return result;
}
insertion_index = 0;
for (; insertion_index < number_of_transitions; ++insertion_index) {
if (InsertionPointFound(GetKey(insertion_index), name)) break;
if (InsertionPointFound(array->GetKey(insertion_index), *name)) break;
result->NoIncrementalWriteBarrierCopyFrom(
this, insertion_index, insertion_index);
array, insertion_index, insertion_index);
}
result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
for (; insertion_index < number_of_transitions; ++insertion_index) {
result->NoIncrementalWriteBarrierCopyFrom(
this, insertion_index, insertion_index + 1);
array, insertion_index, insertion_index + 1);
}
result->set_back_pointer_storage(back_pointer_storage());
result->set_back_pointer_storage(array->back_pointer_storage());
return result;
}
......
......@@ -96,18 +96,19 @@ class TransitionArray: public FixedArray {
inline int number_of_entries() { return number_of_transitions(); }
// Allocate a new transition array with a single entry.
static MUST_USE_RESULT MaybeObject* NewWith(
SimpleTransitionFlag flag,
Name* key,
Map* target,
Object* back_pointer);
static Handle<TransitionArray> NewWith(SimpleTransitionFlag flag,
Handle<Name> key,
Handle<Map> target,
Handle<Object> back_pointer);
MUST_USE_RESULT MaybeObject* ExtendToFullTransitionArray();
// Copy the transition array, inserting a new transition.
// TODO(verwaest): This should not cause an existing transition to be
// overwritten.
MUST_USE_RESULT MaybeObject* CopyInsert(Name* name, Map* target);
static Handle<TransitionArray> CopyInsert(Handle<Map> map,
Handle<Name> name,
Handle<Map> target);
// Copy a single transition from the origin array.
inline void NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
......@@ -121,6 +122,9 @@ class TransitionArray: public FixedArray {
MUST_USE_RESULT static MaybeObject* 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() &&
......
......@@ -142,8 +142,8 @@ TEST(StressJS) {
v8::internal::DescriptorArray::WhitenessWitness witness(*new_descriptors);
map->set_instance_descriptors(*new_descriptors);
CallbacksDescriptor d(*name,
*foreign,
CallbacksDescriptor d(name,
foreign,
static_cast<PropertyAttributes>(0));
map->AppendDescriptor(&d, witness);
......
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