Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 4a988e30fb82da8d1b00c8f0d552262893daef81..859cb8a520acc9c7d55c21439ebe5ca9d677cf47 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2004,16 +2004,14 @@ static Handle<Object> NewStorageFor(Isolate* isolate, |
} |
-static MaybeObject* CopyAddFieldDescriptor(Map* map, |
- Name* name, |
- int index, |
- PropertyAttributes attributes, |
- Representation representation, |
- TransitionFlag flag) { |
- Map* new_map; |
+static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, |
+ Handle<Name> name, |
+ int index, |
+ PropertyAttributes attributes, |
+ Representation representation, |
+ TransitionFlag flag) { |
FieldDescriptor new_field_desc(name, index, attributes, representation); |
- MaybeObject* maybe_map = map->CopyAddDescriptor(&new_field_desc, flag); |
- if (!maybe_map->To(&new_map)) return maybe_map; |
+ Handle<Map> new_map = Map::CopyAddDescriptor(map, &new_field_desc, flag); |
int unused_property_fields = map->unused_property_fields() - 1; |
if (unused_property_fields < 0) { |
unused_property_fields += JSObject::kFieldsAdded; |
@@ -2023,19 +2021,6 @@ static MaybeObject* CopyAddFieldDescriptor(Map* map, |
} |
-static Handle<Map> CopyAddFieldDescriptor(Handle<Map> map, |
- Handle<Name> name, |
- int index, |
- PropertyAttributes attributes, |
- Representation representation, |
- TransitionFlag flag) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), |
- CopyAddFieldDescriptor( |
- *map, *name, index, attributes, representation, flag), |
- Map); |
-} |
- |
- |
void JSObject::AddFastProperty(Handle<JSObject> object, |
Handle<Name> name, |
Handle<Object> value, |
@@ -2081,25 +2066,13 @@ void JSObject::AddFastProperty(Handle<JSObject> object, |
} |
-static MaybeObject* CopyAddConstantDescriptor(Map* map, |
- Name* name, |
- Object* value, |
- PropertyAttributes attributes, |
- TransitionFlag flag) { |
- ConstantDescriptor new_constant_desc(name, value, attributes); |
- return map->CopyAddDescriptor(&new_constant_desc, flag); |
-} |
- |
- |
static Handle<Map> CopyAddConstantDescriptor(Handle<Map> map, |
Handle<Name> name, |
Handle<Object> value, |
PropertyAttributes attributes, |
TransitionFlag flag) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), |
- CopyAddConstantDescriptor( |
- *map, *name, *value, attributes, flag), |
- Map); |
+ ConstantDescriptor new_constant_desc(name, value, attributes); |
+ return Map::CopyAddDescriptor(map, &new_constant_desc, flag); |
} |
@@ -2392,6 +2365,18 @@ bool Map::InstancesNeedRewriting(Map* target, |
} |
+Handle<TransitionArray> Map::SetElementsTransitionMap( |
+ Handle<Map> map, Handle<Map> transitioned_map) { |
+ Handle<TransitionArray> transitions = Map::AddTransition( |
+ map, |
+ map->GetIsolate()->factory()->elements_transition_symbol(), |
+ transitioned_map, |
+ FULL_TRANSITION); |
+ map->set_transitions(*transitions); |
+ return transitions; |
+} |
+ |
+ |
// To migrate an instance to a map: |
// - First check whether the instance needs to be rewritten. If not, simply |
// change the map. |
@@ -2516,9 +2501,11 @@ Handle<TransitionArray> Map::AddTransition(Handle<Map> map, |
Handle<Name> key, |
Handle<Map> target, |
SimpleTransitionFlag flag) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), |
- map->AddTransition(*key, *target, flag), |
- TransitionArray); |
+ if (map->HasTransitionArray()) { |
+ return TransitionArray::CopyInsert(map, key, target); |
+ } |
+ return TransitionArray::NewWith( |
+ flag, key, target, handle(map->GetBackPointer(), map->GetIsolate())); |
} |
@@ -2556,7 +2543,8 @@ Handle<Map> Map::CopyGeneralizeAllRepresentations(Handle<Map> map, |
// Unless the instance is being migrated, ensure that modify_index is a field. |
PropertyDetails details = descriptors->GetDetails(modify_index); |
if (store_mode == FORCE_FIELD && details.type() != FIELD) { |
- FieldDescriptor d(descriptors->GetKey(modify_index), |
+ FieldDescriptor d(handle(descriptors->GetKey(modify_index), |
+ map->GetIsolate()), |
new_map->NumberOfFields(), |
attributes, |
Representation::Tagged()); |
@@ -3172,8 +3160,8 @@ static int AppendUniqueCallbacks(NeanderArray* callbacks, |
// back to front so that the last callback with a given name takes |
// precedence over previously added callbacks with that name. |
for (int i = nof_callbacks - 1; i >= 0; i--) { |
- AccessorInfo* entry = AccessorInfo::cast(callbacks->get(i)); |
- Name* key = Name::cast(entry->name()); |
+ Handle<AccessorInfo> entry(AccessorInfo::cast(callbacks->get(i))); |
+ Handle<Name> key(Name::cast(entry->name())); |
// Check if a descriptor with this name already exists before writing. |
if (!T::Contains(key, entry, valid_descriptors, array)) { |
T::Insert(key, entry, valid_descriptors, array); |
@@ -3186,16 +3174,18 @@ static int AppendUniqueCallbacks(NeanderArray* callbacks, |
struct DescriptorArrayAppender { |
typedef DescriptorArray Array; |
- static bool Contains(Name* key, |
- AccessorInfo* entry, |
+ static bool Contains(Handle<Name> key, |
+ Handle<AccessorInfo> entry, |
int valid_descriptors, |
Handle<DescriptorArray> array) { |
- return array->Search(key, valid_descriptors) != DescriptorArray::kNotFound; |
+ DisallowHeapAllocation no_gc; |
+ return array->Search(*key, valid_descriptors) != DescriptorArray::kNotFound; |
} |
- static void Insert(Name* key, |
- AccessorInfo* entry, |
+ static void Insert(Handle<Name> key, |
+ Handle<AccessorInfo> entry, |
int valid_descriptors, |
Handle<DescriptorArray> array) { |
+ DisallowHeapAllocation no_gc; |
CallbacksDescriptor desc(key, entry, entry->property_attributes()); |
array->Append(&desc); |
} |
@@ -3204,20 +3194,21 @@ struct DescriptorArrayAppender { |
struct FixedArrayAppender { |
typedef FixedArray Array; |
- static bool Contains(Name* key, |
- AccessorInfo* entry, |
+ static bool Contains(Handle<Name> key, |
+ Handle<AccessorInfo> entry, |
int valid_descriptors, |
Handle<FixedArray> array) { |
for (int i = 0; i < valid_descriptors; i++) { |
- if (key == AccessorInfo::cast(array->get(i))->name()) return true; |
+ if (*key == AccessorInfo::cast(array->get(i))->name()) return true; |
} |
return false; |
} |
- static void Insert(Name* key, |
- AccessorInfo* entry, |
+ static void Insert(Handle<Name> key, |
+ Handle<AccessorInfo> entry, |
int valid_descriptors, |
Handle<FixedArray> array) { |
- array->set(valid_descriptors, entry); |
+ DisallowHeapAllocation no_gc; |
+ array->set(valid_descriptors, *entry); |
} |
}; |
@@ -3335,26 +3326,24 @@ bool Map::IsMapInArrayPrototypeChain() { |
} |
-static MaybeObject* AddMissingElementsTransitions(Map* map, |
- ElementsKind to_kind) { |
+static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, |
+ ElementsKind to_kind) { |
ASSERT(IsTransitionElementsKind(map->elements_kind())); |
- Map* current_map = map; |
+ Handle<Map> current_map = map; |
ElementsKind kind = map->elements_kind(); |
while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
kind = GetNextTransitionElementsKind(kind); |
- MaybeObject* maybe_next_map = |
- current_map->CopyAsElementsKind(kind, INSERT_TRANSITION); |
- if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
+ current_map = Map::CopyAsElementsKind( |
+ current_map, kind, INSERT_TRANSITION); |
} |
// In case we are exiting the fast elements kind system, just add the map in |
// the end. |
if (kind != to_kind) { |
- MaybeObject* maybe_next_map = |
- current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION); |
- if (!maybe_next_map->To(¤t_map)) return maybe_next_map; |
+ current_map = Map::CopyAsElementsKind( |
+ current_map, to_kind, INSERT_TRANSITION); |
} |
ASSERT(current_map->elements_kind() == to_kind); |
@@ -3365,14 +3354,30 @@ static MaybeObject* AddMissingElementsTransitions(Map* map, |
Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, |
ElementsKind to_kind) { |
Isolate* isolate = object->GetIsolate(); |
- CALL_HEAP_FUNCTION(isolate, |
- object->GetElementsTransitionMap(isolate, to_kind), |
- Map); |
+ Handle<Map> current_map(object->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()) { |
+ DisallowHeapAllocation no_gc; |
+ 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 handle(Map::cast(maybe_transitioned_map)); |
+ } |
+ } |
+ } |
+ |
+ return GetElementsTransitionMapSlow(object, to_kind); |
} |
-MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) { |
- Map* start_map = map(); |
+Handle<Map> JSObject::GetElementsTransitionMapSlow(Handle<JSObject> object, |
+ ElementsKind to_kind) { |
+ Handle<Map> start_map(object->map()); |
ElementsKind from_kind = start_map->elements_kind(); |
if (from_kind == to_kind) { |
@@ -3393,24 +3398,16 @@ MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) { |
} |
if (!allow_store_transition) { |
- return start_map->CopyAsElementsKind(to_kind, OMIT_TRANSITION); |
+ return Map::CopyAsElementsKind(start_map, to_kind, OMIT_TRANSITION); |
} |
- return start_map->AsElementsKind(to_kind); |
+ return Map::AsElementsKind(start_map, to_kind); |
} |
-// TODO(ishell): Temporary wrapper until handlified. |
// static |
Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), |
- map->AsElementsKind(kind), |
- Map); |
-} |
- |
- |
-MaybeObject* Map::AsElementsKind(ElementsKind kind) { |
- Map* closest_map = FindClosestElementsTransition(this, kind); |
+ Handle<Map> closest_map(FindClosestElementsTransition(*map, kind)); |
if (closest_map->elements_kind() == kind) { |
return closest_map; |
@@ -3898,12 +3895,6 @@ MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, |
} |
-// TODO(mstarzinger): Temporary wrapper until handlified. |
-static Handle<Map> MapAsElementsKind(Handle<Map> map, ElementsKind kind) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map); |
-} |
- |
- |
void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { |
ASSERT(object->map()->inobject_properties() == map->inobject_properties()); |
ElementsKind obj_kind = object->map()->elements_kind(); |
@@ -3919,7 +3910,7 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { |
} else { |
TransitionElementsKind(object, to_kind); |
} |
- map = MapAsElementsKind(map, to_kind); |
+ map = Map::AsElementsKind(map, to_kind); |
} |
JSObject::MigrateToMap(object, map); |
} |
@@ -4758,9 +4749,27 @@ void JSObject::TransformToFastProperties(Handle<JSObject> object, |
void JSObject::ResetElements(Handle<JSObject> object) { |
- CALL_HEAP_FUNCTION_VOID( |
- object->GetIsolate(), |
- object->ResetElements()); |
+ if (object->map()->is_observed()) { |
+ // Maintain invariant that observed elements are always in dictionary mode. |
+ Factory* factory = object->GetIsolate()->factory(); |
+ Handle<SeededNumberDictionary> dictionary = |
+ factory->NewSeededNumberDictionary(0); |
+ if (object->map() == *factory->sloppy_arguments_elements_map()) { |
+ FixedArray::cast(object->elements())->set(1, *dictionary); |
+ } else { |
+ object->set_elements(*dictionary); |
+ } |
+ return; |
+ } |
+ |
+ ElementsKind elements_kind = GetInitialFastElementsKind(); |
+ if (!FLAG_smi_only_arrays) { |
+ elements_kind = FastSmiToObjectElementsKind(elements_kind); |
+ } |
+ Handle<Map> map = JSObject::GetElementsTransitionMap(object, elements_kind); |
+ DisallowHeapAllocation no_gc; |
+ Handle<FixedArrayBase> elements(map->GetInitialElements()); |
+ JSObject::SetMapAndElements(object, map, elements); |
} |
@@ -6489,22 +6498,12 @@ static bool TryAccessorTransition(Handle<JSObject> self, |
} |
-static MaybeObject* CopyInsertDescriptor(Map* map, |
- Name* name, |
- AccessorPair* accessors, |
- PropertyAttributes attributes) { |
- CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
- return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); |
-} |
- |
- |
static Handle<Map> CopyInsertDescriptor(Handle<Map> map, |
Handle<Name> name, |
Handle<AccessorPair> accessors, |
PropertyAttributes attributes) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), |
- CopyInsertDescriptor(*map, *name, *accessors, attributes), |
- Map); |
+ CallbacksDescriptor new_accessors_desc(name, accessors, attributes); |
+ return Map::CopyInsertDescriptor(map, &new_accessors_desc, INSERT_TRANSITION); |
} |
@@ -6831,42 +6830,38 @@ MaybeObject* Map::CopyDropDescriptors() { |
} |
-MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, |
- Descriptor* descriptor) { |
+Handle<Map> Map::ShareDescriptor(Handle<Map> map, |
+ Handle<DescriptorArray> descriptors, |
+ Descriptor* descriptor) { |
// Sanity check. This path is only to be taken if the map owns its descriptor |
// array, implying that its NumberOfOwnDescriptors equals the number of |
// descriptors in the descriptor array. |
- ASSERT(NumberOfOwnDescriptors() == |
- instance_descriptors()->number_of_descriptors()); |
- Map* result; |
- MaybeObject* maybe_result = CopyDropDescriptors(); |
- if (!maybe_result->To(&result)) return maybe_result; |
- |
- Name* name = descriptor->GetKey(); |
- |
- TransitionArray* transitions; |
- MaybeObject* maybe_transitions = |
- AddTransition(name, result, SIMPLE_TRANSITION); |
- if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
+ ASSERT(map->NumberOfOwnDescriptors() == |
+ map->instance_descriptors()->number_of_descriptors()); |
+ Handle<Map> result = Map::CopyDropDescriptors(map); |
- int old_size = descriptors->number_of_descriptors(); |
+ Handle<Name> name = descriptor->GetKey(); |
- DescriptorArray* new_descriptors; |
+ Handle<TransitionArray> transitions = |
+ Map::AddTransition(map, name, result, SIMPLE_TRANSITION); |
if (descriptors->NumberOfSlackDescriptors() > 0) { |
- new_descriptors = descriptors; |
- new_descriptors->Append(descriptor); |
+ descriptors->Append(descriptor); |
+ result->SetBackPointer(*map); |
+ result->InitializeDescriptors(*descriptors); |
} else { |
+ int old_size = descriptors->number_of_descriptors(); |
// Descriptor arrays grow by 50%. |
- MaybeObject* maybe_descriptors = DescriptorArray::Allocate( |
- GetIsolate(), old_size, old_size < 4 ? 1 : old_size / 2); |
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
+ Handle<DescriptorArray> new_descriptors = |
+ map->GetIsolate()->factory()->NewDescriptorArray( |
+ old_size, old_size < 4 ? 1 : old_size / 2); |
- DescriptorArray::WhitenessWitness witness(new_descriptors); |
+ DisallowHeapAllocation no_gc; |
+ DescriptorArray::WhitenessWitness witness(*new_descriptors); |
// Copy the descriptors, inserting a descriptor. |
for (int i = 0; i < old_size; ++i) { |
- new_descriptors->CopyFrom(i, descriptors, i, witness); |
+ new_descriptors->CopyFrom(i, *descriptors, i, witness); |
} |
new_descriptors->Append(descriptor, witness); |
@@ -6878,31 +6873,32 @@ MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, |
// enumerated descriptors than available in the original cache, the cache |
// will be lazily replaced by the extended cache when needed. |
if (descriptors->HasEnumCache()) { |
- new_descriptors->CopyEnumCacheFrom(descriptors); |
+ new_descriptors->CopyEnumCacheFrom(*descriptors); |
} |
- Map* map; |
+ Map* walk_map; |
// Replace descriptors by new_descriptors in all maps that share it. |
- GetHeap()->incremental_marking()->RecordWrites(descriptors); |
- for (Object* current = GetBackPointer(); |
+ map->GetHeap()->incremental_marking()->RecordWrites(*descriptors); |
+ for (Object* current = map->GetBackPointer(); |
!current->IsUndefined(); |
- current = map->GetBackPointer()) { |
- map = Map::cast(current); |
- if (map->instance_descriptors() != descriptors) break; |
- map->set_instance_descriptors(new_descriptors); |
+ current = walk_map->GetBackPointer()) { |
+ walk_map = Map::cast(current); |
+ if (walk_map->instance_descriptors() != *descriptors) break; |
+ walk_map->set_instance_descriptors(*new_descriptors); |
} |
- set_instance_descriptors(new_descriptors); |
+ map->set_instance_descriptors(*new_descriptors); |
} |
+ |
+ result->SetBackPointer(*map); |
+ result->InitializeDescriptors(*new_descriptors); |
} |
- result->SetBackPointer(this); |
- result->InitializeDescriptors(new_descriptors); |
- ASSERT(result->NumberOfOwnDescriptors() == NumberOfOwnDescriptors() + 1); |
+ ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
- set_transitions(transitions); |
- set_owns_descriptors(false); |
+ map->set_transitions(*transitions); |
+ map->set_owns_descriptors(false); |
return result; |
} |
@@ -6911,31 +6907,27 @@ MaybeObject* Map::ShareDescriptor(DescriptorArray* descriptors, |
Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
Handle<DescriptorArray> descriptors, |
TransitionFlag flag, |
- Handle<Name> name) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), |
- map->CopyReplaceDescriptors(*descriptors, flag, *name), |
- Map); |
+ SimpleTransitionFlag simple_flag) { |
+ return Map::CopyReplaceDescriptors( |
+ map, descriptors, flag, Handle<Name>::null(), simple_flag); |
} |
-MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, |
- TransitionFlag flag, |
- Name* name, |
- SimpleTransitionFlag simple_flag) { |
+Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
+ Handle<DescriptorArray> descriptors, |
+ TransitionFlag flag, |
+ Handle<Name> name, |
+ SimpleTransitionFlag simple_flag) { |
ASSERT(descriptors->IsSortedNoDuplicates()); |
- Map* result; |
- MaybeObject* maybe_result = CopyDropDescriptors(); |
- if (!maybe_result->To(&result)) return maybe_result; |
- |
- result->InitializeDescriptors(descriptors); |
+ Handle<Map> result = CopyDropDescriptors(map); |
+ result->InitializeDescriptors(*descriptors); |
- if (flag == INSERT_TRANSITION && CanHaveMoreTransitions()) { |
- TransitionArray* transitions; |
- MaybeObject* maybe_transitions = AddTransition(name, result, simple_flag); |
- if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
- set_transitions(transitions); |
- result->SetBackPointer(this); |
+ if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
+ Handle<TransitionArray> transitions = Map::AddTransition( |
+ map, name, result, simple_flag); |
+ map->set_transitions(*transitions); |
+ result->SetBackPointer(*map); |
} else { |
descriptors->InitializeRepresentations(Representation::Tagged()); |
} |
@@ -6978,52 +6970,48 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
} |
-MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { |
+Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
+ TransitionFlag flag) { |
if (flag == INSERT_TRANSITION) { |
- ASSERT(!HasElementsTransition() || |
- ((elements_transition_map()->elements_kind() == DICTIONARY_ELEMENTS || |
+ ASSERT(!map->HasElementsTransition() || |
+ ((map->elements_transition_map()->elements_kind() == |
+ DICTIONARY_ELEMENTS || |
IsExternalArrayElementsKind( |
- elements_transition_map()->elements_kind())) && |
+ map->elements_transition_map()->elements_kind())) && |
(kind == DICTIONARY_ELEMENTS || |
IsExternalArrayElementsKind(kind)))); |
ASSERT(!IsFastElementsKind(kind) || |
- IsMoreGeneralElementsKindTransition(elements_kind(), kind)); |
- ASSERT(kind != elements_kind()); |
+ IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
+ ASSERT(kind != map->elements_kind()); |
} |
bool insert_transition = |
- flag == INSERT_TRANSITION && !HasElementsTransition(); |
+ flag == INSERT_TRANSITION && !map->HasElementsTransition(); |
- if (insert_transition && owns_descriptors()) { |
+ if (insert_transition && map->owns_descriptors()) { |
// In case the map owned its own descriptors, share the descriptors and |
// transfer ownership to the new map. |
- Map* new_map; |
- MaybeObject* maybe_new_map = CopyDropDescriptors(); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ Handle<Map> new_map = Map::CopyDropDescriptors(map); |
- MaybeObject* added_elements = set_elements_transition_map(new_map); |
- if (added_elements->IsFailure()) return added_elements; |
+ SetElementsTransitionMap(map, new_map); |
new_map->set_elements_kind(kind); |
- new_map->InitializeDescriptors(instance_descriptors()); |
- new_map->SetBackPointer(this); |
- set_owns_descriptors(false); |
+ new_map->InitializeDescriptors(map->instance_descriptors()); |
+ new_map->SetBackPointer(*map); |
+ map->set_owns_descriptors(false); |
return new_map; |
} |
// In case the map did not own its own descriptors, a split is forced by |
// copying the map; creating a new descriptor array cell. |
// Create a new free-floating map only if we are not allowed to store it. |
- Map* new_map; |
- MaybeObject* maybe_new_map = Copy(); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ Handle<Map> new_map = Map::Copy(map); |
new_map->set_elements_kind(kind); |
if (insert_transition) { |
- MaybeObject* added_elements = set_elements_transition_map(new_map); |
- if (added_elements->IsFailure()) return added_elements; |
- new_map->SetBackPointer(this); |
+ SetElementsTransitionMap(map, new_map); |
+ new_map->SetBackPointer(*map); |
} |
return new_map; |
@@ -7063,19 +7051,11 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
Handle<Map> Map::Copy(Handle<Map> map) { |
- CALL_HEAP_FUNCTION(map->GetIsolate(), map->Copy(), Map); |
-} |
- |
- |
-MaybeObject* Map::Copy() { |
- DescriptorArray* descriptors = instance_descriptors(); |
- DescriptorArray* new_descriptors; |
- int number_of_own_descriptors = NumberOfOwnDescriptors(); |
- MaybeObject* maybe_descriptors = |
- descriptors->CopyUpTo(number_of_own_descriptors); |
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
- |
- return CopyReplaceDescriptors(new_descriptors, OMIT_TRANSITION); |
+ Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
+ int number_of_own_descriptors = map->NumberOfOwnDescriptors(); |
+ Handle<DescriptorArray> new_descriptors = |
+ DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); |
+ return Map::CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION); |
} |
@@ -7108,33 +7088,31 @@ Handle<Map> Map::Create(Handle<JSFunction> constructor, |
} |
-MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, |
- TransitionFlag flag) { |
- DescriptorArray* descriptors = instance_descriptors(); |
+Handle<Map> Map::CopyAddDescriptor(Handle<Map> map, |
+ Descriptor* descriptor, |
+ TransitionFlag flag) { |
+ Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
// Ensure the key is unique. |
- MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ descriptor->KeyToUniqueName(); |
- int old_size = NumberOfOwnDescriptors(); |
+ int old_size = map->NumberOfOwnDescriptors(); |
int new_size = old_size + 1; |
if (flag == INSERT_TRANSITION && |
- owns_descriptors() && |
- CanHaveMoreTransitions()) { |
- return ShareDescriptor(descriptors, descriptor); |
+ map->owns_descriptors() && |
+ map->CanHaveMoreTransitions()) { |
+ return Map::ShareDescriptor(map, descriptors, descriptor); |
} |
- DescriptorArray* new_descriptors; |
- MaybeObject* maybe_descriptors = |
- DescriptorArray::Allocate(GetIsolate(), old_size, 1); |
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
+ Handle<DescriptorArray> new_descriptors = |
+ map->GetIsolate()->factory()->NewDescriptorArray(old_size, 1); |
- DescriptorArray::WhitenessWitness witness(new_descriptors); |
+ DescriptorArray::WhitenessWitness witness(*new_descriptors); |
// Copy the descriptors, inserting a descriptor. |
for (int i = 0; i < old_size; ++i) { |
- new_descriptors->CopyFrom(i, descriptors, i, witness); |
+ new_descriptors->CopyFrom(i, *descriptors, i, witness); |
} |
if (old_size != descriptors->number_of_descriptors()) { |
@@ -7145,53 +7123,57 @@ MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, |
new_descriptors->Append(descriptor, witness); |
} |
- Name* key = descriptor->GetKey(); |
- return CopyReplaceDescriptors(new_descriptors, flag, key, SIMPLE_TRANSITION); |
+ Handle<Name> key = descriptor->GetKey(); |
+ return Map::CopyReplaceDescriptors( |
+ map, new_descriptors, flag, key, SIMPLE_TRANSITION); |
} |
-MaybeObject* Map::CopyInsertDescriptor(Descriptor* descriptor, |
- TransitionFlag flag) { |
- DescriptorArray* old_descriptors = instance_descriptors(); |
+Handle<Map> Map::CopyInsertDescriptor(Handle<Map> map, |
+ Descriptor* descriptor, |
+ TransitionFlag flag) { |
+ Handle<DescriptorArray> old_descriptors(map->instance_descriptors()); |
// Ensure the key is unique. |
- MaybeObject* maybe_result = descriptor->KeyToUniqueName(); |
- if (maybe_result->IsFailure()) return maybe_result; |
+ descriptor->KeyToUniqueName(); |
// We replace the key if it is already present. |
- int index = old_descriptors->SearchWithCache(descriptor->GetKey(), this); |
+ int index = old_descriptors->SearchWithCache(*descriptor->GetKey(), *map); |
if (index != DescriptorArray::kNotFound) { |
- return CopyReplaceDescriptor(old_descriptors, descriptor, index, flag); |
+ return Map::CopyReplaceDescriptor( |
+ map, old_descriptors, descriptor, index, flag); |
} |
- return CopyAddDescriptor(descriptor, flag); |
+ return Map::CopyAddDescriptor(map, descriptor, flag); |
} |
-Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( |
+Handle<DescriptorArray> DescriptorArray::CopyUpTo( |
Handle<DescriptorArray> desc, |
- int enumeration_index, |
- PropertyAttributes attributes) { |
- CALL_HEAP_FUNCTION(desc->GetIsolate(), |
- desc->CopyUpToAddAttributes(enumeration_index, attributes), |
- DescriptorArray); |
+ int enumeration_index) { |
+ return DescriptorArray::CopyUpToAddAttributes(desc, |
+ enumeration_index, |
+ NONE); |
} |
-MaybeObject* DescriptorArray::CopyUpToAddAttributes( |
- int enumeration_index, PropertyAttributes attributes) { |
- if (enumeration_index == 0) return GetHeap()->empty_descriptor_array(); |
+Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes( |
+ Handle<DescriptorArray> desc, |
+ int enumeration_index, |
+ PropertyAttributes attributes) { |
+ if (enumeration_index == 0) { |
+ return desc->GetIsolate()->factory()->empty_descriptor_array(); |
+ } |
int size = enumeration_index; |
- DescriptorArray* descriptors; |
- MaybeObject* maybe_descriptors = Allocate(GetIsolate(), size); |
- if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; |
- DescriptorArray::WhitenessWitness witness(descriptors); |
+ Handle<DescriptorArray> descriptors = |
+ desc->GetIsolate()->factory()->NewDescriptorArray(size); |
+ DescriptorArray::WhitenessWitness witness(*descriptors); |
if (attributes != NONE) { |
for (int i = 0; i < size; ++i) { |
- Object* value = GetValue(i); |
- PropertyDetails details = GetDetails(i); |
+ Object* value = desc->GetValue(i); |
+ PropertyDetails details = desc->GetDetails(i); |
int mask = DONT_DELETE | DONT_ENUM; |
// READ_ONLY is an invalid attribute for JS setters/getters. |
if (details.type() != CALLBACKS || !value->IsAccessorPair()) { |
@@ -7199,59 +7181,59 @@ MaybeObject* DescriptorArray::CopyUpToAddAttributes( |
} |
details = details.CopyAddAttributes( |
static_cast<PropertyAttributes>(attributes & mask)); |
- Descriptor desc(GetKey(i), value, details); |
- descriptors->Set(i, &desc, witness); |
+ Descriptor inner_desc(handle(desc->GetKey(i)), |
+ handle(value, desc->GetIsolate()), |
+ details); |
+ descriptors->Set(i, &inner_desc, witness); |
} |
} else { |
for (int i = 0; i < size; ++i) { |
- descriptors->CopyFrom(i, this, i, witness); |
+ descriptors->CopyFrom(i, *desc, i, witness); |
} |
} |
- if (number_of_descriptors() != enumeration_index) descriptors->Sort(); |
+ if (desc->number_of_descriptors() != enumeration_index) descriptors->Sort(); |
return descriptors; |
} |
-MaybeObject* Map::CopyReplaceDescriptor(DescriptorArray* descriptors, |
- Descriptor* descriptor, |
- int insertion_index, |
- TransitionFlag flag) { |
+Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map, |
+ Handle<DescriptorArray> descriptors, |
+ Descriptor* descriptor, |
+ int insertion_index, |
+ TransitionFlag flag) { |
// Ensure the key is unique. |
- MaybeObject* maybe_failure = descriptor->KeyToUniqueName(); |
- if (maybe_failure->IsFailure()) return maybe_failure; |
+ descriptor->KeyToUniqueName(); |
- Name* key = descriptor->GetKey(); |
- ASSERT(key == descriptors->GetKey(insertion_index)); |
+ Handle<Name> key = descriptor->GetKey(); |
+ ASSERT(*key == descriptors->GetKey(insertion_index)); |
- int new_size = NumberOfOwnDescriptors(); |
+ int new_size = map->NumberOfOwnDescriptors(); |
ASSERT(0 <= insertion_index && insertion_index < new_size); |
ASSERT_LT(insertion_index, new_size); |
- DescriptorArray* new_descriptors; |
- MaybeObject* maybe_descriptors = |
- DescriptorArray::Allocate(GetIsolate(), new_size); |
- if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
- DescriptorArray::WhitenessWitness witness(new_descriptors); |
+ Handle<DescriptorArray> new_descriptors = |
+ map->GetIsolate()->factory()->NewDescriptorArray(new_size); |
+ DescriptorArray::WhitenessWitness witness(*new_descriptors); |
for (int i = 0; i < new_size; ++i) { |
if (i == insertion_index) { |
new_descriptors->Set(i, descriptor, witness); |
} else { |
- new_descriptors->CopyFrom(i, descriptors, i, witness); |
+ new_descriptors->CopyFrom(i, *descriptors, i, witness); |
} |
} |
- // Re-sort if descriptors were removed. |
- if (new_size != descriptors->length()) new_descriptors->Sort(); |
+ new_descriptors->Sort(); |
SimpleTransitionFlag simple_flag = |
(insertion_index == descriptors->number_of_descriptors() - 1) |
? SIMPLE_TRANSITION |
: FULL_TRANSITION; |
- return CopyReplaceDescriptors(new_descriptors, flag, key, simple_flag); |
+ return Map::CopyReplaceDescriptors( |
+ map, new_descriptors, flag, key, simple_flag); |
} |
@@ -8095,7 +8077,9 @@ void DescriptorArray::CopyFrom(int dst_index, |
const WhitenessWitness& witness) { |
Object* value = src->GetValue(src_index); |
PropertyDetails details = src->GetDetails(src_index); |
- Descriptor desc(src->GetKey(src_index), value, details); |
+ Descriptor desc(handle(src->GetKey(src_index)), |
+ handle(value, src->GetIsolate()), |
+ details); |
Set(dst_index, &desc, witness); |
} |
@@ -8138,8 +8122,8 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map, |
int current_offset = 0; |
for (descriptor = 0; descriptor < verbatim; descriptor++) { |
if (left->GetDetails(descriptor).type() == FIELD) current_offset++; |
- Descriptor d(right->GetKey(descriptor), |
- right->GetValue(descriptor), |
+ Descriptor d(handle(right->GetKey(descriptor)), |
+ handle(right->GetValue(descriptor), right->GetIsolate()), |
right->GetDetails(descriptor)); |
result->Set(descriptor, &d); |
} |
@@ -8155,14 +8139,14 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map, |
left->GetValue(descriptor) != right->GetValue(descriptor))) { |
Representation representation = left_details.representation().generalize( |
right_details.representation()); |
- FieldDescriptor d(left->GetKey(descriptor), |
+ FieldDescriptor d(handle(left->GetKey(descriptor)), |
current_offset++, |
right_details.attributes(), |
representation); |
result->Set(descriptor, &d); |
} else { |
- Descriptor d(right->GetKey(descriptor), |
- right->GetValue(descriptor), |
+ Descriptor d(handle(right->GetKey(descriptor)), |
+ handle(right->GetValue(descriptor), right->GetIsolate()), |
right_details); |
result->Set(descriptor, &d); |
} |
@@ -8173,14 +8157,14 @@ Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map, |
PropertyDetails right_details = right->GetDetails(descriptor); |
if (right_details.type() == FIELD || |
(store_mode == FORCE_FIELD && descriptor == modify_index)) { |
- FieldDescriptor d(right->GetKey(descriptor), |
+ FieldDescriptor d(handle(right->GetKey(descriptor)), |
current_offset++, |
right_details.attributes(), |
right_details.representation()); |
result->Set(descriptor, &d); |
} else { |
- Descriptor d(right->GetKey(descriptor), |
- right->GetValue(descriptor), |
+ Descriptor d(handle(right->GetKey(descriptor)), |
+ handle(right->GetValue(descriptor), right->GetIsolate()), |
right_details); |
result->Set(descriptor, &d); |
} |
@@ -9784,48 +9768,37 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object) { |
} |
-static MUST_USE_RESULT MaybeObject* CacheInitialJSArrayMaps( |
- Context* native_context, Map* initial_map) { |
+Handle<Object> CacheInitialJSArrayMaps( |
+ Handle<Context> native_context, Handle<Map> initial_map) { |
// Replace all of the cached initial array maps in the native context with |
// the appropriate transitioned elements kind maps. |
- Heap* heap = native_context->GetHeap(); |
- MaybeObject* maybe_maps = |
- heap->AllocateFixedArrayWithHoles(kElementsKindCount, TENURED); |
- FixedArray* maps; |
- if (!maybe_maps->To(&maps)) return maybe_maps; |
+ Factory* factory = native_context->GetIsolate()->factory(); |
+ Handle<FixedArray> maps = factory->NewFixedArrayWithHoles( |
+ kElementsKindCount, TENURED); |
- Map* current_map = initial_map; |
+ Handle<Map> current_map = initial_map; |
ElementsKind kind = current_map->elements_kind(); |
ASSERT(kind == GetInitialFastElementsKind()); |
- maps->set(kind, current_map); |
+ maps->set(kind, *current_map); |
for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
i < kFastElementsKindCount; ++i) { |
- Map* new_map; |
+ Handle<Map> new_map; |
ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); |
if (current_map->HasElementsTransition()) { |
- new_map = current_map->elements_transition_map(); |
+ new_map = handle(current_map->elements_transition_map()); |
ASSERT(new_map->elements_kind() == next_kind); |
} else { |
- MaybeObject* maybe_new_map = |
- current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ new_map = Map::CopyAsElementsKind( |
+ current_map, next_kind, INSERT_TRANSITION); |
} |
- maps->set(next_kind, new_map); |
+ maps->set(next_kind, *new_map); |
current_map = new_map; |
} |
- native_context->set_js_array_maps(maps); |
+ native_context->set_js_array_maps(*maps); |
return initial_map; |
} |
-Handle<Object> CacheInitialJSArrayMaps(Handle<Context> native_context, |
- Handle<Map> initial_map) { |
- CALL_HEAP_FUNCTION(native_context->GetIsolate(), |
- CacheInitialJSArrayMaps(*native_context, *initial_map), |
- Object); |
-} |
- |
- |
void JSFunction::SetInstancePrototype(Handle<JSFunction> function, |
Handle<Object> value) { |
ASSERT(value->IsJSReceiver()); |
@@ -15716,7 +15689,9 @@ MaybeObject* NameDictionary::TransformPropertiesToFastFor( |
PropertyType type = details.type(); |
if (value->IsJSFunction()) { |
- ConstantDescriptor d(key, value, details.attributes()); |
+ ConstantDescriptor d(handle(key), |
+ handle(value, GetIsolate()), |
+ details.attributes()); |
descriptors->Set(enumeration_index - 1, &d, witness); |
} else if (type == NORMAL) { |
if (current_offset < inobject_props) { |
@@ -15727,15 +15702,15 @@ MaybeObject* NameDictionary::TransformPropertiesToFastFor( |
int offset = current_offset - inobject_props; |
fields->set(offset, value); |
} |
- FieldDescriptor d(key, |
+ FieldDescriptor d(handle(key), |
current_offset++, |
details.attributes(), |
// TODO(verwaest): value->OptimalRepresentation(); |
Representation::Tagged()); |
descriptors->Set(enumeration_index - 1, &d, witness); |
} else if (type == CALLBACKS) { |
- CallbacksDescriptor d(key, |
- value, |
+ CallbacksDescriptor d(handle(key), |
+ handle(value, GetIsolate()), |
details.attributes()); |
descriptors->Set(enumeration_index - 1, &d, witness); |
} else { |