diff options
Diffstat (limited to 'deps/v8/src/objects-inl.h')
-rw-r--r-- | deps/v8/src/objects-inl.h | 375 |
1 files changed, 144 insertions, 231 deletions
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index 926e1c7a73..67d64c4779 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -51,12 +51,6 @@ Smi* PropertyDetails::AsSmi() const { } -PropertyDetails PropertyDetails::AsDeleted() const { - Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1)); - return PropertyDetails(smi); -} - - int PropertyDetails::field_width_in_words() const { DCHECK(location() == kField); if (!FLAG_unbox_double_fields) return 1; @@ -719,6 +713,9 @@ bool Object::IsDescriptorArray() const { } +bool Object::IsArrayList() const { return IsFixedArray(); } + + bool Object::IsLayoutDescriptor() const { return IsSmi() || IsFixedTypedArrayBase(); } @@ -758,6 +755,14 @@ bool Object::IsDeoptimizationOutputData() const { } +bool Object::IsHandlerTable() const { + if (!IsFixedArray()) return false; + // There's actually no way to see the difference between a fixed array and + // a handler table array. + return true; +} + + bool Object::IsDependentCode() const { if (!IsFixedArray()) return false; // There's actually no way to see the difference between a fixed array and @@ -1877,41 +1882,6 @@ void JSObject::initialize_elements() { } -Handle<String> Map::ExpectedTransitionKey(Handle<Map> map) { - DisallowHeapAllocation no_gc; - if (!map->HasTransitionArray()) return Handle<String>::null(); - TransitionArray* transitions = map->transitions(); - if (!transitions->IsSimpleTransition()) return Handle<String>::null(); - int transition = TransitionArray::kSimpleTransitionIndex; - PropertyDetails details = transitions->GetTargetDetails(transition); - Name* name = transitions->GetKey(transition); - if (details.type() != DATA) return Handle<String>::null(); - if (details.attributes() != NONE) return Handle<String>::null(); - if (!name->IsString()) return Handle<String>::null(); - return Handle<String>(String::cast(name)); -} - - -Handle<Map> Map::ExpectedTransitionTarget(Handle<Map> map) { - DCHECK(!ExpectedTransitionKey(map).is_null()); - return Handle<Map>(map->transitions()->GetTarget( - TransitionArray::kSimpleTransitionIndex)); -} - - -Handle<Map> Map::FindTransitionToField(Handle<Map> map, Handle<Name> key) { - DisallowHeapAllocation no_allocation; - if (!map->HasTransitionArray()) return Handle<Map>::null(); - TransitionArray* transitions = map->transitions(); - int transition = transitions->Search(kData, *key, NONE); - if (transition == TransitionArray::kNotFound) return Handle<Map>::null(); - PropertyDetails details = transitions->GetTargetDetails(transition); - if (details.type() != DATA) return Handle<Map>::null(); - DCHECK_EQ(NONE, details.attributes()); - return Handle<Map>(transitions->GetTarget(transition)); -} - - ACCESSORS(Oddball, to_string, String, kToStringOffset) ACCESSORS(Oddball, to_number, Object, kToNumberOffset) @@ -1938,16 +1908,7 @@ void Cell::set_value(Object* val, WriteBarrierMode ignored) { } ACCESSORS(PropertyCell, dependent_code, DependentCode, kDependentCodeOffset) - -Object* PropertyCell::type_raw() const { - return READ_FIELD(this, kTypeOffset); -} - - -void PropertyCell::set_type_raw(Object* val, WriteBarrierMode ignored) { - WRITE_FIELD(this, kTypeOffset, val); -} - +ACCESSORS(PropertyCell, value, Object, kValueOffset) Object* WeakCell::value() const { return READ_FIELD(this, kValueOffset); } @@ -2139,6 +2100,31 @@ void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { } +void JSObject::WriteToField(int descriptor, Object* value) { + DisallowHeapAllocation no_gc; + + DescriptorArray* desc = map()->instance_descriptors(); + PropertyDetails details = desc->GetDetails(descriptor); + + DCHECK(details.type() == DATA); + + FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); + if (details.representation().IsDouble()) { + // Nothing more to be done. + if (value->IsUninitialized()) return; + if (IsUnboxedDoubleField(index)) { + RawFastDoublePropertyAtPut(index, value->Number()); + } else { + HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); + DCHECK(box->IsMutableHeapNumber()); + box->set_value(value->Number()); + } + } else { + RawFastPropertyAtPut(index, value); + } +} + + int JSObject::GetInObjectPropertyOffset(int index) { return map()->GetInObjectPropertyOffset(index); } @@ -2371,6 +2357,7 @@ void FixedDoubleArray::FillWithHoles(int from, int to) { Object* WeakFixedArray::Get(int index) const { Object* raw = FixedArray::cast(this)->get(index + kFirstIndex); if (raw->IsSmi()) return raw; + DCHECK(raw->IsWeakCell()); return WeakCell::cast(raw)->value(); } @@ -2401,6 +2388,39 @@ void WeakFixedArray::set_last_used_index(int index) { } +int ArrayList::Length() { + if (FixedArray::cast(this)->length() == 0) return 0; + return Smi::cast(FixedArray::cast(this)->get(kLengthIndex))->value(); +} + + +void ArrayList::SetLength(int length) { + return FixedArray::cast(this)->set(kLengthIndex, Smi::FromInt(length)); +} + + +Object* ArrayList::Get(int index) { + return FixedArray::cast(this)->get(kFirstIndex + index); +} + + +Object** ArrayList::Slot(int index) { + return data_start() + kFirstIndex + index; +} + + +void ArrayList::Set(int index, Object* obj) { + FixedArray::cast(this)->set(kFirstIndex + index, obj); +} + + +void ArrayList::Clear(int index, Object* undefined) { + DCHECK(undefined->IsUndefined()); + FixedArray::cast(this) + ->set(kFirstIndex + index, undefined, SKIP_WRITE_BARRIER); +} + + void ConstantPoolArray::NumberOfEntries::increment(Type type) { DCHECK(type < NUMBER_OF_TYPES); element_counts_[type]++; @@ -3037,7 +3057,7 @@ FixedArrayBase* Map::GetInitialElements() { return empty_array; } else if (has_fixed_typed_array_elements()) { FixedTypedArrayBase* empty_array = - GetHeap()->EmptyFixedTypedArrayForMap(this); + GetHeap()->EmptyFixedTypedArrayForMap(this); DCHECK(!GetHeap()->InNewSpace(empty_array)); return empty_array; } else { @@ -3136,7 +3156,12 @@ int DescriptorArray::GetFieldIndex(int descriptor_number) { HeapType* DescriptorArray::GetFieldType(int descriptor_number) { DCHECK(GetDetails(descriptor_number).location() == kField); - return HeapType::cast(GetValue(descriptor_number)); + Object* value = GetValue(descriptor_number); + if (value->IsWeakCell()) { + if (WeakCell::cast(value)->cleared()) return HeapType::None(); + value = WeakCell::cast(value)->value(); + } + return HeapType::cast(value); } @@ -3294,6 +3319,7 @@ void SeededNumberDictionary::set_requires_slow_elements() { CAST_ACCESSOR(AccessorInfo) +CAST_ACCESSOR(ArrayList) CAST_ACCESSOR(ByteArray) CAST_ACCESSOR(Cell) CAST_ACCESSOR(Code) @@ -3324,6 +3350,7 @@ CAST_ACCESSOR(FixedDoubleArray) CAST_ACCESSOR(FixedTypedArrayBase) CAST_ACCESSOR(Foreign) CAST_ACCESSOR(GlobalObject) +CAST_ACCESSOR(HandlerTable) CAST_ACCESSOR(HeapObject) CAST_ACCESSOR(JSArray) CAST_ACCESSOR(JSArrayBuffer) @@ -4198,7 +4225,7 @@ void* FixedTypedArrayBase::DataPtr() { } -int FixedTypedArrayBase::DataSize(InstanceType type) { +int FixedTypedArrayBase::ElementSize(InstanceType type) { int element_size; switch (type) { #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ @@ -4212,7 +4239,12 @@ int FixedTypedArrayBase::DataSize(InstanceType type) { UNREACHABLE(); return 0; } - return length() * element_size; + return element_size; +} + + +int FixedTypedArrayBase::DataSize(InstanceType type) { + return length() * ElementSize(type); } @@ -4231,6 +4263,11 @@ int FixedTypedArrayBase::TypedArraySize(InstanceType type) { } +int FixedTypedArrayBase::TypedArraySize(InstanceType type, int length) { + return OBJECT_POINTER_ALIGN(kDataOffset + length * ElementSize(type)); +} + + uint8_t Uint8ArrayTraits::defaultValue() { return 0; } @@ -5250,22 +5287,6 @@ void Map::set_prototype(Object* value, WriteBarrierMode mode) { } -// If the descriptor is using the empty transition array, install a new empty -// transition array that will have place for an element transition. -static void EnsureHasTransitionArray(Handle<Map> map) { - Handle<TransitionArray> transitions; - if (!map->HasTransitionArray()) { - transitions = TransitionArray::Allocate(map->GetIsolate(), 0); - transitions->set_back_pointer_storage(map->GetBackPointer()); - } else if (!map->transitions()->IsFullTransitionArray()) { - transitions = TransitionArray::ExtendToFullTransitionArray(map); - } else { - return; - } - map->set_transitions(*transitions); -} - - LayoutDescriptor* Map::layout_descriptor_gc_safe() { Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); return LayoutDescriptor::cast_gc_safe(layout_desc); @@ -5360,158 +5381,58 @@ void Map::AppendDescriptor(Descriptor* desc) { Object* Map::GetBackPointer() { - Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); - if (object->IsTransitionArray()) { - return TransitionArray::cast(object)->back_pointer_storage(); - } else { - DCHECK(object->IsMap() || object->IsUndefined()); + Object* object = constructor_or_backpointer(); + if (object->IsMap()) { return object; } + return GetIsolate()->heap()->undefined_value(); } -bool Map::HasElementsTransition() { - return HasTransitionArray() && transitions()->HasElementsTransition(); -} - - -bool Map::HasTransitionArray() const { - Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); - return object->IsTransitionArray(); -} - - -Map* Map::elements_transition_map() { - int index = - transitions()->SearchSpecial(GetHeap()->elements_transition_symbol()); - return transitions()->GetTarget(index); +Map* Map::ElementsTransitionMap() { + return TransitionArray::SearchSpecial( + this, GetHeap()->elements_transition_symbol()); } -bool Map::CanHaveMoreTransitions() { - if (!HasTransitionArray()) return true; - return transitions()->number_of_transitions() < - TransitionArray::kMaxNumberOfTransitions; -} +ACCESSORS(Map, raw_transitions, Object, kTransitionsOffset) -Map* Map::GetTransition(int transition_index) { - return transitions()->GetTarget(transition_index); -} - - -int Map::SearchSpecialTransition(Symbol* name) { - if (HasTransitionArray()) { - return transitions()->SearchSpecial(name); - } - return TransitionArray::kNotFound; -} - - -int Map::SearchTransition(PropertyKind kind, Name* name, - PropertyAttributes attributes) { - if (HasTransitionArray()) { - return transitions()->Search(kind, name, attributes); - } - return TransitionArray::kNotFound; -} - - -FixedArray* Map::GetPrototypeTransitions() { - if (!HasTransitionArray()) return GetHeap()->empty_fixed_array(); - if (!transitions()->HasPrototypeTransitions()) { - return GetHeap()->empty_fixed_array(); - } - return transitions()->GetPrototypeTransitions(); -} - - -void Map::SetPrototypeTransitions( - Handle<Map> map, Handle<FixedArray> proto_transitions) { - EnsureHasTransitionArray(map); - int old_number_of_transitions = map->NumberOfProtoTransitions(); - if (Heap::ShouldZapGarbage() && map->HasPrototypeTransitions()) { - DCHECK(map->GetPrototypeTransitions() != *proto_transitions); - map->ZapPrototypeTransitions(); - } - map->transitions()->SetPrototypeTransitions(*proto_transitions); - map->SetNumberOfProtoTransitions(old_number_of_transitions); -} - - -bool Map::HasPrototypeTransitions() { - return HasTransitionArray() && transitions()->HasPrototypeTransitions(); +void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { + DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE); + DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) || + (value->IsMap() && GetBackPointer()->IsUndefined())); + DCHECK(!value->IsMap() || + Map::cast(value)->GetConstructor() == constructor_or_backpointer()); + set_constructor_or_backpointer(value, mode); } -TransitionArray* Map::transitions() const { - DCHECK(HasTransitionArray()); - Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); - return TransitionArray::cast(object); -} +ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) +ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) +ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset) +ACCESSORS(Map, constructor_or_backpointer, Object, + kConstructorOrBackPointerOffset) -void Map::set_transitions(TransitionArray* transition_array, - WriteBarrierMode mode) { - // Transition arrays are not shared. When one is replaced, it should not - // keep referenced objects alive, so we zap it. - // When there is another reference to the array somewhere (e.g. a handle), - // not zapping turns from a waste of memory into a source of crashes. - if (HasTransitionArray()) { -#ifdef DEBUG - for (int i = 0; i < transitions()->number_of_transitions(); i++) { - Map* target = transitions()->GetTarget(i); - if (target->instance_descriptors() == instance_descriptors()) { - Name* key = transitions()->GetKey(i); - int new_target_index; - if (TransitionArray::IsSpecialTransition(key)) { - new_target_index = transition_array->SearchSpecial(Symbol::cast(key)); - } else { - PropertyDetails details = - TransitionArray::GetTargetDetails(key, target); - new_target_index = transition_array->Search(details.kind(), key, - details.attributes()); - } - DCHECK_NE(TransitionArray::kNotFound, new_target_index); - DCHECK_EQ(target, transition_array->GetTarget(new_target_index)); - } - } -#endif - DCHECK(transitions() != transition_array); - ZapTransitions(); +Object* Map::GetConstructor() const { + Object* maybe_constructor = constructor_or_backpointer(); + // Follow any back pointers. + while (maybe_constructor->IsMap()) { + maybe_constructor = + Map::cast(maybe_constructor)->constructor_or_backpointer(); } - - WRITE_FIELD(this, kTransitionsOrBackPointerOffset, transition_array); - CONDITIONAL_WRITE_BARRIER( - GetHeap(), this, kTransitionsOrBackPointerOffset, transition_array, mode); -} - - -void Map::init_back_pointer(Object* undefined) { - DCHECK(undefined->IsUndefined()); - WRITE_FIELD(this, kTransitionsOrBackPointerOffset, undefined); + return maybe_constructor; } -void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { - DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE); - DCHECK((value->IsUndefined() && GetBackPointer()->IsMap()) || - (value->IsMap() && GetBackPointer()->IsUndefined())); - Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset); - if (object->IsTransitionArray()) { - TransitionArray::cast(object)->set_back_pointer_storage(value); - } else { - WRITE_FIELD(this, kTransitionsOrBackPointerOffset, value); - CONDITIONAL_WRITE_BARRIER( - GetHeap(), this, kTransitionsOrBackPointerOffset, value, mode); - } +void Map::SetConstructor(Object* constructor, WriteBarrierMode mode) { + // Never overwrite a back pointer with a constructor. + DCHECK(!constructor_or_backpointer()->IsMap()); + set_constructor_or_backpointer(constructor, mode); } -ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) -ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) -ACCESSORS(Map, constructor, Object, kConstructorOffset) - ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset) ACCESSORS(JSFunction, next_function_link, Object, kNextFunctionLinkOffset) @@ -5551,6 +5472,7 @@ SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset) BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols, kCanInterceptSymbolsBit) BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit) +BOOL_ACCESSORS(InterceptorInfo, flags, non_masking, kNonMasking) ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset) ACCESSORS(CallHandlerInfo, data, Object, kDataOffset) @@ -5671,6 +5593,8 @@ BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype, BOOL_ACCESSORS(FunctionTemplateInfo, flag, do_not_cache, kDoNotCacheBit) BOOL_ACCESSORS(FunctionTemplateInfo, flag, instantiated, kInstantiatedBit) +BOOL_ACCESSORS(FunctionTemplateInfo, flag, accept_any_receiver, + kAcceptAnyReceiver) BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression, kIsExpressionBit) BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel, @@ -5854,7 +5778,6 @@ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor, ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset) ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset) -ACCESSORS(CodeCache, weak_cell_cache, Object, kWeakCellCacheOffset) ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset) @@ -5932,7 +5855,10 @@ void SharedFunctionInfo::set_scope_info(ScopeInfo* value, bool SharedFunctionInfo::is_compiled() { - return code() != GetIsolate()->builtins()->builtin(Builtins::kCompileLazy); + Builtins* builtins = GetIsolate()->builtins(); + DCHECK(code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent)); + DCHECK(code() != builtins->builtin(Builtins::kCompileOptimized)); + return code() != builtins->builtin(Builtins::kCompileLazy); } @@ -6199,7 +6125,12 @@ Object* JSFunction::prototype() { DCHECK(has_prototype()); // If the function's prototype property has been set to a non-JSObject // value, that value is stored in the constructor field of the map. - if (map()->has_non_instance_prototype()) return map()->constructor(); + if (map()->has_non_instance_prototype()) { + Object* prototype = map()->GetConstructor(); + // The map must have a prototype in that field, not a back pointer. + DCHECK(!prototype->IsMap()); + return prototype; + } return instance_prototype(); } @@ -6210,7 +6141,10 @@ bool JSFunction::should_have_prototype() { bool JSFunction::is_compiled() { - return code() != GetIsolate()->builtins()->builtin(Builtins::kCompileLazy); + Builtins* builtins = GetIsolate()->builtins(); + return code() != builtins->builtin(Builtins::kCompileLazy) && + code() != builtins->builtin(Builtins::kCompileOptimized) && + code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent); } @@ -6267,20 +6201,6 @@ void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id, } -Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) { - DCHECK(id < kJSBuiltinsCount); // id is unsigned. - return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id))); -} - - -void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id, - Code* value) { - DCHECK(id < kJSBuiltinsCount); // id is unsigned. - WRITE_FIELD(this, OffsetOfCodeWithId(id), value); - DCHECK(!GetHeap()->InNewSpace(value)); -} - - ACCESSORS(JSProxy, handler, Object, kHandlerOffset) ACCESSORS(JSProxy, hash, Object, kHashOffset) ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset) @@ -6336,7 +6256,6 @@ ACCESSORS(JSGeneratorObject, context, Context, kContextOffset) ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset) SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset) ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset) -SMI_ACCESSORS(JSGeneratorObject, stack_handler_index, kStackHandlerIndexOffset) bool JSGeneratorObject::is_suspended() { DCHECK_LT(kGeneratorExecuting, kGeneratorClosed); @@ -6942,8 +6861,7 @@ Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object, return JSProxy::HasPropertyWithHandler(proxy, name); } Maybe<PropertyAttributes> result = GetPropertyAttributes(object, name); - if (!result.has_value) return Maybe<bool>(); - return maybe(result.value != ABSENT); + return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing<bool>(); } @@ -6954,8 +6872,7 @@ Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object, return JSProxy::HasPropertyWithHandler(proxy, name); } Maybe<PropertyAttributes> result = GetOwnPropertyAttributes(object, name); - if (!result.has_value) return Maybe<bool>(); - return maybe(result.value != ABSENT); + return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing<bool>(); } @@ -7014,8 +6931,7 @@ Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) { } Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver( Handle<JSObject>::cast(object), object, index, true); - if (!result.has_value) return Maybe<bool>(); - return maybe(result.value != ABSENT); + return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing<bool>(); } @@ -7027,8 +6943,7 @@ Maybe<bool> JSReceiver::HasOwnElement(Handle<JSReceiver> object, } Maybe<PropertyAttributes> result = JSObject::GetElementAttributeWithReceiver( Handle<JSObject>::cast(object), object, index, false); - if (!result.has_value) return Maybe<bool>(); - return maybe(result.value != ABSENT); + return result.IsJust() ? Just(result.FromJust() != ABSENT) : Nothing<bool>(); } @@ -7102,9 +7017,7 @@ void Dictionary<Derived, Shape, Key>::SetEntry(int entry, Handle<Object> key, Handle<Object> value, PropertyDetails details) { - DCHECK(!key->IsName() || - details.IsDeleted() || - details.dictionary_index() > 0); + DCHECK(!key->IsName() || details.dictionary_index() > 0); int index = DerivedHashTable::EntryToIndex(entry); DisallowHeapAllocation no_gc; WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc); |