From 41b6c8a0f152d9c6684effc7a5f785bf3e32462c Mon Sep 17 00:00:00 2001 From: "mvstanton@chromium.org" Date: Wed, 9 Apr 2014 14:26:32 +0000 Subject: [PATCH] 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 --- src/bootstrapper.cc | 89 ++++---- src/elements.cc | 36 +-- src/factory.cc | 17 ++ src/factory.h | 2 + src/objects-inl.h | 123 +++------- src/objects.cc | 555 ++++++++++++++++++++++------------------------ src/objects.h | 69 +++--- src/property.h | 37 ++-- src/runtime.cc | 24 +- src/transitions.cc | 86 ++++--- src/transitions.h | 16 +- test/cctest/test-alloc.cc | 4 +- 12 files changed, 501 insertions(+), 557 deletions(-) diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index f930bd1..b2420e0 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -399,19 +399,19 @@ void Genesis::SetFunctionInstanceDescriptor( map->set_instance_descriptors(*descriptors); { // Add length. - CallbacksDescriptor d(*factory()->length_string(), *length, attribs); + CallbacksDescriptor d(factory()->length_string(), length, attribs); map->AppendDescriptor(&d, witness); } { // Add name. - CallbacksDescriptor d(*factory()->name_string(), *name, attribs); + CallbacksDescriptor d(factory()->name_string(), name, attribs); map->AppendDescriptor(&d, witness); } { // Add arguments. - CallbacksDescriptor d(*factory()->arguments_string(), *args, attribs); + CallbacksDescriptor d(factory()->arguments_string(), args, attribs); map->AppendDescriptor(&d, witness); } { // Add caller. - CallbacksDescriptor d(*factory()->caller_string(), *caller, attribs); + CallbacksDescriptor d(factory()->caller_string(), caller, attribs); map->AppendDescriptor(&d, witness); } if (prototypeMode != DONT_ADD_PROTOTYPE) { @@ -419,7 +419,7 @@ void Genesis::SetFunctionInstanceDescriptor( if (prototypeMode == ADD_WRITEABLE_PROTOTYPE) { attribs = static_cast(attribs & ~READ_ONLY); } - CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs); + CallbacksDescriptor d(factory()->prototype_string(), prototype, attribs); map->AppendDescriptor(&d, witness); } } @@ -540,27 +540,27 @@ void Genesis::SetStrictFunctionInstanceDescriptor( map->set_instance_descriptors(*descriptors); { // Add length. - CallbacksDescriptor d(*factory()->length_string(), *length, ro_attribs); + CallbacksDescriptor d(factory()->length_string(), length, ro_attribs); map->AppendDescriptor(&d, witness); } { // Add name. - CallbacksDescriptor d(*factory()->name_string(), *name, ro_attribs); + CallbacksDescriptor d(factory()->name_string(), name, ro_attribs); map->AppendDescriptor(&d, witness); } { // Add arguments. - CallbacksDescriptor d(*factory()->arguments_string(), *arguments, + CallbacksDescriptor d(factory()->arguments_string(), arguments, rw_attribs); map->AppendDescriptor(&d, witness); } { // Add caller. - CallbacksDescriptor d(*factory()->caller_string(), *caller, rw_attribs); + CallbacksDescriptor d(factory()->caller_string(), caller, rw_attribs); map->AppendDescriptor(&d, witness); } if (prototypeMode != DONT_ADD_PROTOTYPE) { // Add prototype. PropertyAttributes attribs = prototypeMode == ADD_WRITEABLE_PROTOTYPE ? rw_attribs : ro_attribs; - CallbacksDescriptor d(*factory()->prototype_string(), *prototype, attribs); + CallbacksDescriptor d(factory()->prototype_string(), prototype, attribs); map->AppendDescriptor(&d, witness); } } @@ -872,7 +872,7 @@ void Genesis::InitializeGlobal(Handle inner_global, initial_map->set_instance_descriptors(*array_descriptors); { // Add length. - CallbacksDescriptor d(*factory->length_string(), *array_length, attribs); + CallbacksDescriptor d(factory->length_string(), array_length, attribs); array_function->initial_map()->AppendDescriptor(&d, witness); } @@ -927,7 +927,7 @@ void Genesis::InitializeGlobal(Handle inner_global, string_map->set_instance_descriptors(*string_descriptors); { // Add length. - CallbacksDescriptor d(*factory->length_string(), *string_length, attribs); + CallbacksDescriptor d(factory->length_string(), string_length, attribs); string_map->AppendDescriptor(&d, witness); } } @@ -964,7 +964,7 @@ void Genesis::InitializeGlobal(Handle inner_global, { // ECMA-262, section 15.10.7.1. - FieldDescriptor field(heap->source_string(), + FieldDescriptor field(factory->source_string(), JSRegExp::kSourceFieldIndex, final, Representation::Tagged()); @@ -972,7 +972,7 @@ void Genesis::InitializeGlobal(Handle inner_global, } { // ECMA-262, section 15.10.7.2. - FieldDescriptor field(heap->global_string(), + FieldDescriptor field(factory->global_string(), JSRegExp::kGlobalFieldIndex, final, Representation::Tagged()); @@ -980,7 +980,7 @@ void Genesis::InitializeGlobal(Handle inner_global, } { // ECMA-262, section 15.10.7.3. - FieldDescriptor field(heap->ignore_case_string(), + FieldDescriptor field(factory->ignore_case_string(), JSRegExp::kIgnoreCaseFieldIndex, final, Representation::Tagged()); @@ -988,7 +988,7 @@ void Genesis::InitializeGlobal(Handle inner_global, } { // ECMA-262, section 15.10.7.4. - FieldDescriptor field(heap->multiline_string(), + FieldDescriptor field(factory->multiline_string(), JSRegExp::kMultilineFieldIndex, final, Representation::Tagged()); @@ -998,7 +998,7 @@ void Genesis::InitializeGlobal(Handle inner_global, // ECMA-262, section 15.10.7.5. PropertyAttributes writable = static_cast(DONT_ENUM | DONT_DELETE); - FieldDescriptor field(heap->last_index_string(), + FieldDescriptor field(factory->last_index_string(), JSRegExp::kLastIndexFieldIndex, writable, Representation::Tagged()); @@ -1181,18 +1181,18 @@ void Genesis::InitializeGlobal(Handle inner_global, { // length FieldDescriptor d( - *factory->length_string(), 0, DONT_ENUM, Representation::Tagged()); + factory->length_string(), 0, DONT_ENUM, Representation::Tagged()); map->AppendDescriptor(&d, witness); } { // callee - CallbacksDescriptor d(*factory->callee_string(), - *callee, + CallbacksDescriptor d(factory->callee_string(), + callee, attributes); map->AppendDescriptor(&d, witness); } { // caller - CallbacksDescriptor d(*factory->caller_string(), - *caller, + CallbacksDescriptor d(factory->caller_string(), + caller, attributes); map->AppendDescriptor(&d, witness); } @@ -1388,7 +1388,7 @@ void Genesis::InitializeExperimentalGlobal() { Handle value_string = factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("value")); - FieldDescriptor value_descr(*value_string, + FieldDescriptor value_descr(value_string, JSGeneratorObject::kResultValuePropertyIndex, NONE, Representation::Tagged()); @@ -1396,7 +1396,7 @@ void Genesis::InitializeExperimentalGlobal() { Handle done_string = factory()->InternalizeOneByteString( STATIC_ASCII_VECTOR("done")); - FieldDescriptor done_descr(*done_string, + FieldDescriptor done_descr(done_string, JSGeneratorObject::kResultDonePropertyIndex, NONE, Representation::Tagged()); @@ -1620,7 +1620,7 @@ Handle Genesis::InstallInternalArray( { // Add length. CallbacksDescriptor d( - *factory()->length_string(), *array_length, attribs); + factory()->length_string(), array_length, attribs); array_function->initial_map()->AppendDescriptor(&d, witness); } @@ -1761,71 +1761,71 @@ bool Genesis::InstallNatives() { { CallbacksDescriptor d( - *factory()->source_string(), *script_source, attribs); + factory()->source_string(), script_source, attribs); script_map->AppendDescriptor(&d, witness); } { - CallbacksDescriptor d(*factory()->name_string(), *script_name, attribs); + CallbacksDescriptor d(factory()->name_string(), script_name, attribs); script_map->AppendDescriptor(&d, witness); } { - CallbacksDescriptor d(*id_string, *script_id, attribs); + CallbacksDescriptor d(id_string, script_id, attribs); script_map->AppendDescriptor(&d, witness); } { - CallbacksDescriptor d(*line_offset_string, *script_line_offset, attribs); + CallbacksDescriptor d(line_offset_string, script_line_offset, attribs); script_map->AppendDescriptor(&d, witness); } { CallbacksDescriptor d( - *column_offset_string, *script_column_offset, attribs); + column_offset_string, script_column_offset, attribs); script_map->AppendDescriptor(&d, witness); } { - CallbacksDescriptor d(*type_string, *script_type, attribs); + CallbacksDescriptor d(type_string, script_type, attribs); script_map->AppendDescriptor(&d, witness); } { CallbacksDescriptor d( - *compilation_type_string, *script_compilation_type, attribs); + compilation_type_string, script_compilation_type, attribs); script_map->AppendDescriptor(&d, witness); } { - CallbacksDescriptor d(*line_ends_string, *script_line_ends, attribs); + CallbacksDescriptor d(line_ends_string, script_line_ends, attribs); script_map->AppendDescriptor(&d, witness); } { CallbacksDescriptor d( - *context_data_string, *script_context_data, attribs); + context_data_string, script_context_data, attribs); script_map->AppendDescriptor(&d, witness); } { CallbacksDescriptor d( - *eval_from_script_string, *script_eval_from_script, attribs); + eval_from_script_string, script_eval_from_script, attribs); script_map->AppendDescriptor(&d, witness); } { CallbacksDescriptor d( - *eval_from_script_position_string, - *script_eval_from_script_position, + eval_from_script_position_string, + script_eval_from_script_position, attribs); script_map->AppendDescriptor(&d, witness); } { CallbacksDescriptor d( - *eval_from_function_name_string, - *script_eval_from_function_name, + eval_from_function_name_string, + script_eval_from_function_name, attribs); script_map->AppendDescriptor(&d, witness); } @@ -1956,17 +1956,18 @@ bool Genesis::InstallNatives() { JSFunction* array_function = native_context()->array_function(); Handle array_descriptors( array_function->initial_map()->instance_descriptors()); - String* length = heap()->length_string(); + Handle length = factory()->length_string(); int old = array_descriptors->SearchWithCache( - length, array_function->initial_map()); + *length, array_function->initial_map()); ASSERT(old != DescriptorArray::kNotFound); CallbacksDescriptor desc(length, - array_descriptors->GetValue(old), + handle(array_descriptors->GetValue(old), + isolate()), array_descriptors->GetDetails(old).attributes()); initial_map->AppendDescriptor(&desc, witness); } { - FieldDescriptor index_field(heap()->index_string(), + FieldDescriptor index_field(factory()->index_string(), JSRegExpResult::kIndexIndex, NONE, Representation::Tagged()); @@ -1974,7 +1975,7 @@ bool Genesis::InstallNatives() { } { - FieldDescriptor input_field(heap()->input_string(), + FieldDescriptor input_field(factory()->input_string(), JSRegExpResult::kInputIndex, NONE, Representation::Tagged()); diff --git a/src/elements.cc b/src/elements.cc index b0761a0..5f2b0b0 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -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 SetLengthWithoutNormalize( + Handle store, + Handle array, + Handle length_object, uint32_t length) { - SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); - Heap* heap = array->GetHeap(); + Handle dict = + Handle::cast(store); + Isolate* isolate = array->GetIsolate(); int capacity = dict->Capacity(); uint32_t new_length = length; uint32_t old_length = static_cast(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(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 SetLengthWithoutNormalize( - Handle store, - Handle array, - Handle 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, diff --git a/src/factory.cc b/src/factory.cc index 6803c04..053f870 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -143,6 +143,23 @@ Handle Factory::NewDescriptorArray(int number_of_descriptors, } +Handle Factory::NewTransitionArray(int number_of_transitions) { + ASSERT(0 <= number_of_transitions); + CALL_HEAP_FUNCTION(isolate(), + TransitionArray::Allocate( + isolate(), number_of_transitions), + TransitionArray); +} + + +Handle Factory::NewSimpleTransitionArray(Handle target) { + CALL_HEAP_FUNCTION(isolate(), + TransitionArray::AllocateSimple( + isolate(), *target), + TransitionArray); +} + + Handle Factory::NewDeoptimizationInputData( int deopt_entry_count, PretenureFlag pretenure) { diff --git a/src/factory.h b/src/factory.h index dc8c789..c94a126 100644 --- a/src/factory.h +++ b/src/factory.h @@ -57,6 +57,8 @@ class Factory V8_FINAL { Handle NewDescriptorArray(int number_of_descriptors, int slack = 0); + Handle NewTransitionArray(int number_of_transitions); + Handle NewSimpleTransitionArray(Handle target); Handle NewDeoptimizationInputData( int deopt_entry_count, PretenureFlag pretenure); diff --git a/src/objects-inl.h b/src/objects-inl.h index cedd6f4..6502288 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1750,28 +1750,6 @@ void JSObject::EnsureCanContainElements(Handle 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 object, Handle new_map, Handle 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()) { diff --git a/src/objects.cc b/src/objects.cc index 4a988e3..859cb8a 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -2004,16 +2004,14 @@ static Handle NewStorageFor(Isolate* isolate, } -static MaybeObject* CopyAddFieldDescriptor(Map* map, - Name* name, - int index, - PropertyAttributes attributes, - Representation representation, - TransitionFlag flag) { - Map* new_map; +static Handle CopyAddFieldDescriptor(Handle map, + Handle 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 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 CopyAddFieldDescriptor(Handle map, - Handle 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 object, Handle name, Handle value, @@ -2081,25 +2066,13 @@ void JSObject::AddFastProperty(Handle 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 CopyAddConstantDescriptor(Handle map, Handle name, Handle 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 Map::SetElementsTransitionMap( + Handle map, Handle transitioned_map) { + Handle 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 Map::AddTransition(Handle map, Handle key, Handle 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::CopyGeneralizeAllRepresentations(Handle 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 entry(AccessorInfo::cast(callbacks->get(i))); + Handle 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 key, + Handle entry, int valid_descriptors, Handle 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 key, + Handle entry, int valid_descriptors, Handle 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 key, + Handle entry, int valid_descriptors, Handle 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 key, + Handle entry, int valid_descriptors, Handle 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 AddMissingElementsTransitions(Handle map, + ElementsKind to_kind) { ASSERT(IsTransitionElementsKind(map->elements_kind())); - Map* current_map = map; + Handle 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 JSObject::GetElementsTransitionMap(Handle object, ElementsKind to_kind) { Isolate* isolate = object->GetIsolate(); - CALL_HEAP_FUNCTION(isolate, - object->GetElementsTransitionMap(isolate, to_kind), - Map); + Handle 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 JSObject::GetElementsTransitionMapSlow(Handle object, + ElementsKind to_kind) { + Handle 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::AsElementsKind(Handle map, ElementsKind kind) { - CALL_HEAP_FUNCTION(map->GetIsolate(), - map->AsElementsKind(kind), - Map); -} - - -MaybeObject* Map::AsElementsKind(ElementsKind kind) { - Map* closest_map = FindClosestElementsTransition(this, kind); + Handle closest_map(FindClosestElementsTransition(*map, kind)); if (closest_map->elements_kind() == kind) { return closest_map; @@ -3898,12 +3895,6 @@ MaybeHandle JSProxy::CallTrap(Handle proxy, } -// TODO(mstarzinger): Temporary wrapper until handlified. -static Handle MapAsElementsKind(Handle map, ElementsKind kind) { - CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map); -} - - void JSObject::AllocateStorageForMap(Handle object, Handle map) { ASSERT(object->map()->inobject_properties() == map->inobject_properties()); ElementsKind obj_kind = object->map()->elements_kind(); @@ -3919,7 +3910,7 @@ void JSObject::AllocateStorageForMap(Handle object, Handle 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 object, void JSObject::ResetElements(Handle 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 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 = JSObject::GetElementsTransitionMap(object, elements_kind); + DisallowHeapAllocation no_gc; + Handle elements(map->GetInitialElements()); + JSObject::SetMapAndElements(object, map, elements); } @@ -6489,22 +6498,12 @@ static bool TryAccessorTransition(Handle 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 CopyInsertDescriptor(Handle map, Handle name, Handle 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::ShareDescriptor(Handle map, + Handle 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 result = Map::CopyDropDescriptors(map); - int old_size = descriptors->number_of_descriptors(); + Handle name = descriptor->GetKey(); - DescriptorArray* new_descriptors; + Handle 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 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::CopyReplaceDescriptors(Handle map, Handle descriptors, TransitionFlag flag, - Handle name) { - CALL_HEAP_FUNCTION(map->GetIsolate(), - map->CopyReplaceDescriptors(*descriptors, flag, *name), - Map); + SimpleTransitionFlag simple_flag) { + return Map::CopyReplaceDescriptors( + map, descriptors, flag, Handle::null(), simple_flag); } -MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, - TransitionFlag flag, - Name* name, - SimpleTransitionFlag simple_flag) { +Handle Map::CopyReplaceDescriptors(Handle map, + Handle descriptors, + TransitionFlag flag, + Handle 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 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 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::CopyInstallDescriptors(Handle map, } -MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) { +Handle Map::CopyAsElementsKind(Handle 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 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 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::CopyForObserved(Handle map) { Handle Map::Copy(Handle 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 descriptors(map->instance_descriptors()); + int number_of_own_descriptors = map->NumberOfOwnDescriptors(); + Handle new_descriptors = + DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors); + return Map::CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION); } @@ -7108,33 +7088,31 @@ Handle Map::Create(Handle constructor, } -MaybeObject* Map::CopyAddDescriptor(Descriptor* descriptor, - TransitionFlag flag) { - DescriptorArray* descriptors = instance_descriptors(); +Handle Map::CopyAddDescriptor(Handle map, + Descriptor* descriptor, + TransitionFlag flag) { + Handle 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 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 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::CopyInsertDescriptor(Handle map, + Descriptor* descriptor, + TransitionFlag flag) { + Handle 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::CopyUpToAddAttributes( +Handle DescriptorArray::CopyUpTo( Handle 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::CopyUpToAddAttributes( + Handle 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 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(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::CopyReplaceDescriptor(Handle map, + Handle 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 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 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::Merge(Handle 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::Merge(Handle 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::Merge(Handle 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 object) { } -static MUST_USE_RESULT MaybeObject* CacheInitialJSArrayMaps( - Context* native_context, Map* initial_map) { +Handle CacheInitialJSArrayMaps( + Handle native_context, Handle 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 maps = factory->NewFixedArrayWithHoles( + kElementsKindCount, TENURED); - Map* current_map = initial_map; + Handle 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 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 CacheInitialJSArrayMaps(Handle native_context, - Handle initial_map) { - CALL_HEAP_FUNCTION(native_context->GetIsolate(), - CacheInitialJSArrayMaps(*native_context, *initial_map), - Object); -} - - void JSFunction::SetInstancePrototype(Handle function, Handle 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 { diff --git a/src/objects.h b/src/objects.h index 6365a94..3c0eb5c 100644 --- a/src/objects.h +++ b/src/objects.h @@ -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 object); static inline void SetMapAndElements(Handle object, Handle map, @@ -2580,11 +2579,8 @@ class JSObject: public JSReceiver { // map and the ElementsKind set. static Handle GetElementsTransitionMap(Handle object, ElementsKind to_kind); - inline MUST_USE_RESULT MaybeObject* GetElementsTransitionMap( - Isolate* isolate, - ElementsKind elements_kind); - MUST_USE_RESULT MaybeObject* GetElementsTransitionMapSlow( - ElementsKind elements_kind); + static Handle GetElementsTransitionMapSlow(Handle object, + ElementsKind elements_kind); static void TransitionElementsKind(Handle object, ElementsKind to_kind); @@ -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 CopyUpTo(Handle desc, + int enumeration_index); static Handle CopyUpToAddAttributes( Handle 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 SetElementsTransitionMap( + Handle map, Handle 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 AddTransition(Handle map, Handle key, Handle 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,37 +6380,42 @@ class Map: public HeapObject { MUST_USE_RESULT MaybeObject* RawCopy(int instance_size); static Handle CopyDropDescriptors(Handle map); MUST_USE_RESULT MaybeObject* CopyDropDescriptors(); - static Handle CopyReplaceDescriptors(Handle map, - Handle descriptors, - TransitionFlag flag, - Handle name); - MUST_USE_RESULT MaybeObject* CopyReplaceDescriptors( - DescriptorArray* descriptors, + static Handle CopyReplaceDescriptors( + Handle map, + Handle descriptors, + TransitionFlag flag, + Handle name, + SimpleTransitionFlag simple_flag = FULL_TRANSITION); + static Handle CopyReplaceDescriptors( + Handle map, + Handle descriptors, TransitionFlag flag, - Name* name = NULL, SimpleTransitionFlag simple_flag = FULL_TRANSITION); static Handle CopyInstallDescriptors( Handle map, int new_descriptor, Handle descriptors); - MUST_USE_RESULT MaybeObject* ShareDescriptor(DescriptorArray* descriptors, - Descriptor* descriptor); - MUST_USE_RESULT MaybeObject* CopyAddDescriptor(Descriptor* descriptor, - TransitionFlag flag); - MUST_USE_RESULT MaybeObject* CopyInsertDescriptor(Descriptor* descriptor, - TransitionFlag flag); - MUST_USE_RESULT MaybeObject* CopyReplaceDescriptor( - DescriptorArray* descriptors, + static Handle ShareDescriptor(Handle map, + Handle descriptors, + Descriptor* descriptor); + static Handle CopyAddDescriptor(Handle map, + Descriptor* descriptor, + TransitionFlag flag); + static Handle CopyInsertDescriptor(Handle map, + Descriptor* descriptor, + TransitionFlag flag); + static Handle CopyReplaceDescriptor( + Handle map, + Handle descriptors, Descriptor* descriptor, int index, TransitionFlag flag); - MUST_USE_RESULT MaybeObject* AsElementsKind(ElementsKind kind); - static Handle AsElementsKind(Handle map, ElementsKind kind); - MUST_USE_RESULT MaybeObject* CopyAsElementsKind(ElementsKind kind, - TransitionFlag flag); + static Handle CopyAsElementsKind(Handle map, + ElementsKind kind, + TransitionFlag flag); static Handle CopyForObserved(Handle map); @@ -6437,7 +6431,6 @@ class Map: public HeapObject { static Handle Copy(Handle map); static Handle Create(Handle constructor, int extra_inobject_properties); - MUST_USE_RESULT MaybeObject* Copy(); // Returns the next free property index (only valid for FAST MODE). int NextFreePropertyIndex(); diff --git a/src/property.h b/src/property.h index 087e0a3..4ddcab0 100644 --- a/src/property.h +++ b/src/property.h @@ -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::cast(key_)); } - return key_; } - Name* GetKey() { return key_; } - Object* GetValue() { return value_; } + Handle GetKey() { return key_; } + Handle 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 key_; + Handle value_; PropertyDetails details_; protected: Descriptor() : details_(Smi::FromInt(0)) {} - void Init(Name* key, Object* value, PropertyDetails details) { + void Init(Handle key, Handle value, PropertyDetails details) { key_ = key; value_ = value; details_ = details; } - Descriptor(Name* key, Object* value, PropertyDetails details) + Descriptor(Handle key, Handle value, PropertyDetails details) : key_(key), value_(value), details_(details) { } - Descriptor(Name* key, - Object* value, + Descriptor(Handle key, + Handle 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 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 key, + Handle 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 key, + Handle foreign, PropertyAttributes attributes) : Descriptor(key, foreign, attributes, CALLBACKS, Representation::Tagged()) {} diff --git a/src/runtime.cc b/src/runtime.cc index cae4aff..3148327 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -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 name = isolate->factory()->prototype_string(); if (function->HasFastProperties()) { // Construct a new field descriptor with updated attributes. - DescriptorArray* instance_desc = function->map()->instance_descriptors(); + Handle 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(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 = handle(function->map()); + Handle 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( diff --git a/src/transitions.cc b/src/transitions.cc index 9d3f038..76af6d5 100644 --- a/src/transitions.cc +++ b/src/transitions.cc @@ -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::NewWith(SimpleTransitionFlag flag, + Handle key, + Handle target, + Handle back_pointer) { + Handle 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::CopyInsert(Handle map, + Handle name, + Handle target) { + ASSERT(map->HasTransitionArray()); + Handle 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; } diff --git a/src/transitions.h b/src/transitions.h index 220d549..6ee2f86 100644 --- a/src/transitions.h +++ b/src/transitions.h @@ -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 NewWith(SimpleTransitionFlag flag, + Handle key, + Handle target, + Handle 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 CopyInsert(Handle map, + Handle name, + Handle 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() && diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc index 0d4ab88..95c9b4a 100644 --- a/test/cctest/test-alloc.cc +++ b/test/cctest/test-alloc.cc @@ -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(0)); map->AppendDescriptor(&d, witness); -- 2.7.4