diff options
Diffstat (limited to 'deps/v8/src/objects-inl.h')
-rw-r--r-- | deps/v8/src/objects-inl.h | 325 |
1 files changed, 116 insertions, 209 deletions
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 4afbe3edd7..459420c5d3 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -128,6 +128,18 @@ PropertyDetails PropertyDetails::AsDeleted() { } +bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, + ElementsKind to_kind) { + if (to_kind == FAST_ELEMENTS) { + return from_kind == FAST_SMI_ONLY_ELEMENTS || + from_kind == FAST_DOUBLE_ELEMENTS; + } else { + return to_kind == FAST_DOUBLE_ELEMENTS && + from_kind == FAST_SMI_ONLY_ELEMENTS; + } +} + + bool Object::IsFixedArrayBase() { return IsFixedArray() || IsFixedDoubleArray(); } @@ -1232,26 +1244,35 @@ FixedArrayBase* JSObject::elements() { return static_cast<FixedArrayBase*>(array); } - -void JSObject::ValidateElements() { +void JSObject::ValidateSmiOnlyElements() { #if DEBUG - if (FLAG_enable_slow_asserts) { - ElementsAccessor* accessor = GetElementsAccessor(); - accessor->Validate(this); + if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { + Heap* heap = GetHeap(); + // Don't use elements, since integrity checks will fail if there + // are filler pointers in the array. + FixedArray* fixed_array = + reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset)); + Map* map = fixed_array->map(); + // Arrays that have been shifted in place can't be verified. + if (map != heap->raw_unchecked_one_pointer_filler_map() && + map != heap->raw_unchecked_two_pointer_filler_map() && + map != heap->free_space_map()) { + for (int i = 0; i < fixed_array->length(); i++) { + Object* current = fixed_array->get(i); + ASSERT(current->IsSmi() || current->IsTheHole()); + } + } } #endif } MaybeObject* JSObject::EnsureCanContainHeapObjectElements() { - ValidateElements(); - ElementsKind elements_kind = map()->elements_kind(); - if (!IsFastObjectElementsKind(elements_kind)) { - if (IsFastHoleyElementsKind(elements_kind)) { - return TransitionElementsKind(FAST_HOLEY_ELEMENTS); - } else { - return TransitionElementsKind(FAST_ELEMENTS); - } +#if DEBUG + ValidateSmiOnlyElements(); +#endif + if ((map()->elements_kind() != FAST_ELEMENTS)) { + return TransitionElementsKind(FAST_ELEMENTS); } return this; } @@ -1263,34 +1284,20 @@ MaybeObject* JSObject::EnsureCanContainElements(Object** objects, ElementsKind current_kind = map()->elements_kind(); ElementsKind target_kind = current_kind; ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); - bool is_holey = IsFastHoleyElementsKind(current_kind); - if (current_kind == FAST_HOLEY_ELEMENTS) return this; + if (current_kind == FAST_ELEMENTS) return this; + Heap* heap = GetHeap(); Object* the_hole = heap->the_hole_value(); Object* heap_number_map = heap->heap_number_map(); for (uint32_t i = 0; i < count; ++i) { Object* current = *objects++; - if (current == the_hole) { - is_holey = true; - target_kind = GetHoleyElementsKind(target_kind); - } else if (!current->IsSmi()) { + if (!current->IsSmi() && current != the_hole) { if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && - HeapObject::cast(current)->map() == heap_number_map && - IsFastSmiElementsKind(target_kind)) { - if (is_holey) { - target_kind = FAST_HOLEY_DOUBLE_ELEMENTS; - } else { - target_kind = FAST_DOUBLE_ELEMENTS; - } + HeapObject::cast(current)->map() == heap_number_map) { + target_kind = FAST_DOUBLE_ELEMENTS; } else { - if (!current->IsNumber()) { - if (is_holey) { - target_kind = FAST_HOLEY_ELEMENTS; - break; - } else { - target_kind = FAST_ELEMENTS; - } - } + target_kind = FAST_ELEMENTS; + break; } } } @@ -1303,7 +1310,6 @@ MaybeObject* JSObject::EnsureCanContainElements(Object** objects, MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, - uint32_t length, EnsureElementsMode mode) { if (elements->map() != GetHeap()->fixed_double_array_map()) { ASSERT(elements->map() == GetHeap()->fixed_array_map() || @@ -1312,19 +1318,11 @@ MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, mode = DONT_ALLOW_DOUBLE_ELEMENTS; } Object** objects = FixedArray::cast(elements)->GetFirstElementAddress(); - return EnsureCanContainElements(objects, length, mode); + return EnsureCanContainElements(objects, elements->length(), mode); } ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS); - if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) { - return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS); - } else if (GetElementsKind() == FAST_SMI_ELEMENTS) { - FixedDoubleArray* double_array = FixedDoubleArray::cast(elements); - for (uint32_t i = 0; i < length; ++i) { - if (double_array->is_the_hole(i)) { - return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS); - } - } + if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { return TransitionElementsKind(FAST_DOUBLE_ELEMENTS); } @@ -1336,20 +1334,21 @@ 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* global_context = isolate->context()->global_context(); - Object* maybe_array_maps = global_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); + if (current_map == global_context->smi_js_array_map()) { + if (to_kind == FAST_ELEMENTS) { + return global_context->object_js_array_map(); + } else { + if (to_kind == FAST_DOUBLE_ELEMENTS) { + return global_context->double_js_array_map(); + } else { + ASSERT(to_kind == DICTIONARY_ELEMENTS); } } } - return GetElementsTransitionMapSlow(to_kind); } @@ -1358,6 +1357,9 @@ void JSObject::set_map_and_elements(Map* new_map, FixedArrayBase* value, WriteBarrierMode mode) { ASSERT(value->HasValidElements()); +#ifdef DEBUG + ValidateSmiOnlyElements(); +#endif if (new_map != NULL) { if (mode == UPDATE_WRITE_BARRIER) { set_map(new_map); @@ -1366,7 +1368,8 @@ void JSObject::set_map_and_elements(Map* new_map, set_map_no_write_barrier(new_map); } } - ASSERT((map()->has_fast_smi_or_object_elements() || + ASSERT((map()->has_fast_elements() || + map()->has_fast_smi_only_elements() || (value == GetHeap()->empty_fixed_array())) == (value->map() == GetHeap()->fixed_array_map() || value->map() == GetHeap()->fixed_cow_array_map())); @@ -1389,7 +1392,8 @@ void JSObject::initialize_properties() { void JSObject::initialize_elements() { - ASSERT(map()->has_fast_smi_or_object_elements() || + ASSERT(map()->has_fast_elements() || + map()->has_fast_smi_only_elements() || map()->has_fast_double_elements()); ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); @@ -1398,10 +1402,9 @@ void JSObject::initialize_elements() { MaybeObject* JSObject::ResetElements() { Object* obj; - ElementsKind elements_kind = GetInitialFastElementsKind(); - if (!FLAG_smi_only_arrays) { - elements_kind = FastSmiToObjectElementsKind(elements_kind); - } + ElementsKind elements_kind = FLAG_smi_only_arrays + ? FAST_SMI_ONLY_ELEMENTS + : FAST_ELEMENTS; MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), elements_kind); if (!maybe_obj->ToObject(&obj)) return maybe_obj; @@ -1673,11 +1676,6 @@ Object* FixedArray::get(int index) { } -bool FixedArray::is_the_hole(int index) { - return get(index) == GetHeap()->the_hole_value(); -} - - void FixedArray::set(int index, Smi* value) { ASSERT(map() != HEAP->fixed_cow_array_map()); ASSERT(index >= 0 && index < this->length()); @@ -2859,15 +2857,15 @@ bool Map::has_non_instance_prototype() { void Map::set_function_with_prototype(bool value) { if (value) { - set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype)); + set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype)); } else { - set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype)); + set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype)); } } bool Map::function_with_prototype() { - return ((1 << kFunctionWithPrototype) & bit_field3()) != 0; + return ((1 << kFunctionWithPrototype) & bit_field2()) != 0; } @@ -3195,18 +3193,6 @@ void Code::set_compare_state(byte value) { } -byte Code::compare_operation() { - ASSERT(is_compare_ic_stub()); - return READ_BYTE_FIELD(this, kCompareOperationOffset); -} - - -void Code::set_compare_operation(byte value) { - ASSERT(is_compare_ic_stub()); - WRITE_BYTE_FIELD(this, kCompareOperationOffset, value); -} - - byte Code::to_boolean_state() { ASSERT(is_to_boolean_ic_stub()); return READ_BYTE_FIELD(this, kToBooleanTypeOffset); @@ -3353,9 +3339,6 @@ void Map::clear_instance_descriptors() { Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); if (!object->IsSmi()) { -#ifdef DEBUG - ZapInstanceDescriptors(); -#endif WRITE_FIELD( this, kInstanceDescriptorsOrBitField3Offset, @@ -3381,11 +3364,6 @@ void Map::set_instance_descriptors(DescriptorArray* value, } } ASSERT(!is_shared()); -#ifdef DEBUG - if (value != instance_descriptors()) { - ZapInstanceDescriptors(); - } -#endif WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value); CONDITIONAL_WRITE_BARRIER( heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode); @@ -3417,71 +3395,14 @@ void Map::set_bit_field3(int value) { } -Object* Map::GetBackPointer() { - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); - if (object->IsFixedArray()) { - return FixedArray::cast(object)->get(kProtoTransitionBackPointerOffset); - } else { - return object; - } -} - - -void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { - Heap* heap = GetHeap(); - ASSERT(instance_type() >= FIRST_JS_RECEIVER_TYPE); - ASSERT((value->IsUndefined() && GetBackPointer()->IsMap()) || - (value->IsMap() && GetBackPointer()->IsUndefined())); - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); - if (object->IsFixedArray()) { - FixedArray::cast(object)->set( - kProtoTransitionBackPointerOffset, value, mode); - } else { - WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value); - CONDITIONAL_WRITE_BARRIER( - heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode); - } -} - - -FixedArray* Map::prototype_transitions() { - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); - if (object->IsFixedArray()) { - return FixedArray::cast(object); - } else { - return GetHeap()->empty_fixed_array(); - } -} - - -void Map::set_prototype_transitions(FixedArray* value, WriteBarrierMode mode) { - Heap* heap = GetHeap(); - ASSERT(value != heap->empty_fixed_array()); - value->set(kProtoTransitionBackPointerOffset, GetBackPointer()); -#ifdef DEBUG - if (value != prototype_transitions()) { - ZapPrototypeTransitions(); - } -#endif - WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, value); - CONDITIONAL_WRITE_BARRIER( - heap, this, kPrototypeTransitionsOrBackPointerOffset, value, mode); -} - - -void Map::init_prototype_transitions(Object* undefined) { - ASSERT(undefined->IsUndefined()); - WRITE_FIELD(this, kPrototypeTransitionsOrBackPointerOffset, undefined); -} - - -HeapObject* Map::unchecked_prototype_transitions() { - Object* object = READ_FIELD(this, kPrototypeTransitionsOrBackPointerOffset); - return reinterpret_cast<HeapObject*>(object); +FixedArray* Map::unchecked_prototype_transitions() { + return reinterpret_cast<FixedArray*>( + READ_FIELD(this, kPrototypeTransitionsOffset)); } ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) +ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset) ACCESSORS(Map, constructor, Object, kConstructorOffset) ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) @@ -3739,12 +3660,6 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) { } -int SharedFunctionInfo::profiler_ticks() { - if (code()->kind() != Code::FUNCTION) return 0; - return code()->profiler_ticks(); -} - - LanguageMode SharedFunctionInfo::language_mode() { int hints = compiler_hints(); if (BooleanBit::get(hints, kExtendedModeFunction)) { @@ -4010,32 +3925,27 @@ MaybeObject* JSFunction::set_initial_map_and_cache_transitions( global_context->get(Context::ARRAY_FUNCTION_INDEX); if (array_function->IsJSFunction() && this == JSFunction::cast(array_function)) { - // Replace all of the cached initial array maps in the global context with - // the appropriate transitioned elements kind maps. - Heap* heap = GetHeap(); - MaybeObject* maybe_maps = - heap->AllocateFixedArrayWithHoles(kElementsKindCount); - FixedArray* maps; - if (!maybe_maps->To(&maps)) return maybe_maps; - - Map* current_map = initial_map; - ElementsKind kind = current_map->elements_kind(); - ASSERT(kind == GetInitialFastElementsKind()); - maps->set(kind, current_map); - for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; - i < kFastElementsKindCount; ++i) { - ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i); - MaybeObject* maybe_new_map = current_map->CopyDropTransitions(); - Map* new_map = NULL; - if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; - new_map->set_elements_kind(transitioned_kind); - maybe_new_map = current_map->AddElementsTransition(transitioned_kind, - new_map); - if (maybe_new_map->IsFailure()) return maybe_new_map; - maps->set(transitioned_kind, new_map); - current_map = new_map; - } - global_context->set_js_array_maps(maps); + ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); + + MaybeObject* maybe_map = initial_map->CopyDropTransitions(); + Map* new_double_map = NULL; + if (!maybe_map->To<Map>(&new_double_map)) return maybe_map; + new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); + maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, + new_double_map); + if (maybe_map->IsFailure()) return maybe_map; + + maybe_map = new_double_map->CopyDropTransitions(); + Map* new_object_map = NULL; + if (!maybe_map->To<Map>(&new_object_map)) return maybe_map; + new_object_map->set_elements_kind(FAST_ELEMENTS); + maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS, + new_object_map); + if (maybe_map->IsFailure()) return maybe_map; + + global_context->set_smi_js_array_map(initial_map); + global_context->set_double_js_array_map(new_double_map); + global_context->set_object_js_array_map(new_object_map); } set_initial_map(initial_map); return this; @@ -4371,18 +4281,18 @@ ElementsKind JSObject::GetElementsKind() { FixedArrayBase* fixed_array = reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); Map* map = fixed_array->map(); - ASSERT((IsFastSmiOrObjectElementsKind(kind) && - (map == GetHeap()->fixed_array_map() || - map == GetHeap()->fixed_cow_array_map())) || - (IsFastDoubleElementsKind(kind) && - (fixed_array->IsFixedDoubleArray() || - fixed_array == GetHeap()->empty_fixed_array())) || - (kind == DICTIONARY_ELEMENTS && + ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && + (map == GetHeap()->fixed_array_map() || + map == GetHeap()->fixed_cow_array_map())) || + (kind == FAST_DOUBLE_ELEMENTS && + (fixed_array->IsFixedDoubleArray() || + fixed_array == GetHeap()->empty_fixed_array())) || + (kind == DICTIONARY_ELEMENTS && fixed_array->IsFixedArray() && - fixed_array->IsDictionary()) || - (kind > DICTIONARY_ELEMENTS)); - ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || - (elements()->IsFixedArray() && elements()->length() >= 2)); + fixed_array->IsDictionary()) || + (kind > DICTIONARY_ELEMENTS)); + ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || + (elements()->IsFixedArray() && elements()->length() >= 2)); #endif return kind; } @@ -4393,28 +4303,25 @@ ElementsAccessor* JSObject::GetElementsAccessor() { } -bool JSObject::HasFastObjectElements() { - return IsFastObjectElementsKind(GetElementsKind()); +bool JSObject::HasFastElements() { + return GetElementsKind() == FAST_ELEMENTS; } -bool JSObject::HasFastSmiElements() { - return IsFastSmiElementsKind(GetElementsKind()); +bool JSObject::HasFastSmiOnlyElements() { + return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; } -bool JSObject::HasFastSmiOrObjectElements() { - return IsFastSmiOrObjectElementsKind(GetElementsKind()); +bool JSObject::HasFastTypeElements() { + ElementsKind elements_kind = GetElementsKind(); + return elements_kind == FAST_SMI_ONLY_ELEMENTS || + elements_kind == FAST_ELEMENTS; } bool JSObject::HasFastDoubleElements() { - return IsFastDoubleElementsKind(GetElementsKind()); -} - - -bool JSObject::HasFastHoleyElements() { - return IsFastHoleyElementsKind(GetElementsKind()); + return GetElementsKind() == FAST_DOUBLE_ELEMENTS; } @@ -4471,7 +4378,7 @@ bool JSObject::HasIndexedInterceptor() { MaybeObject* JSObject::EnsureWritableFastElements() { - ASSERT(HasFastSmiOrObjectElements()); + ASSERT(HasFastTypeElements()); FixedArray* elems = FixedArray::cast(elements()); Isolate* isolate = GetIsolate(); if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; @@ -4829,7 +4736,7 @@ void Map::ClearCodeCache(Heap* heap) { void JSArray::EnsureSize(int required_size) { - ASSERT(HasFastSmiOrObjectElements()); + ASSERT(HasFastTypeElements()); FixedArray* elts = FixedArray::cast(elements()); const int kArraySizeThatFitsComfortablyInNewSpace = 128; if (elts->length() < required_size) { @@ -4861,13 +4768,13 @@ bool JSArray::AllowsSetElementsLength() { MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { MaybeObject* maybe_result = EnsureCanContainElements( - storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS); + storage, ALLOW_COPIED_DOUBLE_ELEMENTS); if (maybe_result->IsFailure()) return maybe_result; ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && - IsFastDoubleElementsKind(GetElementsKind())) || + GetElementsKind() == FAST_DOUBLE_ELEMENTS) || ((storage->map() != GetHeap()->fixed_double_array_map()) && - (IsFastObjectElementsKind(GetElementsKind()) || - (IsFastSmiElementsKind(GetElementsKind()) && + ((GetElementsKind() == FAST_ELEMENTS) || + (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); set_elements(storage); set_length(Smi::FromInt(storage->length())); |