diff options
author | Michaël Zasso <targos@protonmail.com> | 2016-09-06 22:49:51 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2016-09-22 09:51:19 +0200 |
commit | ec02b811a8a5c999bab4de312be2d732b7d9d50b (patch) | |
tree | ca3068017254f238cf413a451c57a803572983a4 /deps/v8/src/objects-inl.h | |
parent | d2eb7ce0105369a9cad82787cb33a665e9bd00ad (diff) | |
download | node-new-ec02b811a8a5c999bab4de312be2d732b7d9d50b.tar.gz |
deps: update V8 to 5.4.500.27
Pick up latest commit from the 5.4-lkgr branch.
deps: edit V8 gitignore to allow trace event copy
deps: update V8 trace event to 315bf1e2d45be7d53346c31cfcc37424a32c30c8
deps: edit V8 gitignore to allow gtest_prod.h copy
deps: update V8 gtest to 6f8a66431cb592dad629028a50b3dd418a408c87
PR-URL: https://github.com/nodejs/node/pull/8317
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/objects-inl.h')
-rw-r--r-- | deps/v8/src/objects-inl.h | 916 |
1 files changed, 628 insertions, 288 deletions
diff --git a/deps/v8/src/objects-inl.h b/deps/v8/src/objects-inl.h index b75dd1c969..3d82bf8205 100644 --- a/deps/v8/src/objects-inl.h +++ b/deps/v8/src/objects-inl.h @@ -14,6 +14,7 @@ #include "src/base/atomicops.h" #include "src/base/bits.h" +#include "src/builtins/builtins.h" #include "src/contexts-inl.h" #include "src/conversions-inl.h" #include "src/factory.h" @@ -22,8 +23,9 @@ #include "src/handles-inl.h" #include "src/heap/heap-inl.h" #include "src/heap/heap.h" -#include "src/isolate.h" #include "src/isolate-inl.h" +#include "src/isolate.h" +#include "src/keys.h" #include "src/layout-descriptor-inl.h" #include "src/lookup.h" #include "src/objects.h" @@ -76,25 +78,35 @@ int PropertyDetails::field_width_in_words() const { int holder::name() const { return READ_INT_FIELD(this, offset); } \ void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); } - -#define ACCESSORS(holder, name, type, offset) \ - type* holder::name() const { return type::cast(READ_FIELD(this, offset)); } \ - void holder::set_##name(type* value, WriteBarrierMode mode) { \ - WRITE_FIELD(this, offset, value); \ - CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \ +#define ACCESSORS_CHECKED(holder, name, type, offset, condition) \ + type* holder::name() const { \ + DCHECK(condition); \ + return type::cast(READ_FIELD(this, offset)); \ + } \ + void holder::set_##name(type* value, WriteBarrierMode mode) { \ + DCHECK(condition); \ + WRITE_FIELD(this, offset, value); \ + CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \ } +#define ACCESSORS(holder, name, type, offset) \ + ACCESSORS_CHECKED(holder, name, type, offset, true) // Getter that returns a Smi as an int and writes an int as a Smi. -#define SMI_ACCESSORS(holder, name, offset) \ - int holder::name() const { \ - Object* value = READ_FIELD(this, offset); \ - return Smi::cast(value)->value(); \ - } \ - void holder::set_##name(int value) { \ - WRITE_FIELD(this, offset, Smi::FromInt(value)); \ +#define SMI_ACCESSORS_CHECKED(holder, name, offset, condition) \ + int holder::name() const { \ + DCHECK(condition); \ + Object* value = READ_FIELD(this, offset); \ + return Smi::cast(value)->value(); \ + } \ + void holder::set_##name(int value) { \ + DCHECK(condition); \ + WRITE_FIELD(this, offset, Smi::FromInt(value)); \ } +#define SMI_ACCESSORS(holder, name, offset) \ + SMI_ACCESSORS_CHECKED(holder, name, offset, true) + #define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset) \ int holder::synchronized_##name() const { \ Object* value = ACQUIRE_READ_FIELD(this, offset); \ @@ -159,6 +171,15 @@ SIMD128_TYPES(SIMD128_TYPE_CHECKER) return IsHeapObject() && HeapObject::cast(this)->Is##type_(); \ } HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DEF) +#undef IS_TYPE_FUNCTION_DEF + +#define IS_TYPE_FUNCTION_DEF(Type, Value) \ + bool Object::Is##Type(Isolate* isolate) const { \ + return this == isolate->heap()->Value(); \ + } \ + bool HeapObject::Is##Type(Isolate* isolate) const { \ + return this == isolate->heap()->Value(); \ + } ODDBALL_LIST(IS_TYPE_FUNCTION_DEF) #undef IS_TYPE_FUNCTION_DEF @@ -244,7 +265,6 @@ bool HeapObject::IsExternalTwoByteString() const { String::cast(this)->IsTwoByteRepresentation(); } - bool Object::HasValidElements() { // Dictionary is covered under FixedArray. return IsFixedArray() || IsFixedDoubleArray() || IsFixedTypedArrayBase(); @@ -283,12 +303,12 @@ bool Object::FilterKey(PropertyFilter filter) { Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object, Representation representation) { - if (representation.IsSmi() && object->IsUninitialized()) { + if (representation.IsSmi() && object->IsUninitialized(isolate)) { return handle(Smi::FromInt(0), isolate); } if (!representation.IsDouble()) return object; double value; - if (object->IsUninitialized()) { + if (object->IsUninitialized(isolate)) { value = 0; } else if (object->IsMutableHeapNumber()) { value = HeapNumber::cast(*object)->value(); @@ -302,7 +322,7 @@ Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object, Representation representation) { - DCHECK(!object->IsUninitialized()); + DCHECK(!object->IsUninitialized(isolate)); if (!representation.IsDouble()) { DCHECK(object->FitsRepresentation(representation)); return object; @@ -685,6 +705,8 @@ bool HeapObject::IsJSWeakCollection() const { return IsJSWeakMap() || IsJSWeakSet(); } +bool HeapObject::IsJSCollection() const { return IsJSMap() || IsJSSet(); } + bool HeapObject::IsDescriptorArray() const { return IsFixedArray(); } bool HeapObject::IsArrayList() const { return IsFixedArray(); } @@ -730,6 +752,14 @@ bool HeapObject::IsHandlerTable() const { return true; } +bool HeapObject::IsTemplateList() const { + if (!IsFixedArray()) return false; + // There's actually no way to see the difference between a fixed array and + // a template list. + if (FixedArray::cast(this)->length() < 1) return false; + return true; +} + bool HeapObject::IsDependentCode() const { if (!IsFixedArray()) return false; // There's actually no way to see the difference between a fixed array and @@ -776,11 +806,12 @@ TYPE_CHECKER(Cell, CELL_TYPE) TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE) TYPE_CHECKER(WeakCell, WEAK_CELL_TYPE) TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE) -TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE) -TYPE_CHECKER(JSModule, JS_MODULE_TYPE) -TYPE_CHECKER(JSValue, JS_VALUE_TYPE) TYPE_CHECKER(JSDate, JS_DATE_TYPE) +TYPE_CHECKER(JSError, JS_ERROR_TYPE) +TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE) TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE) +TYPE_CHECKER(JSPromise, JS_PROMISE_TYPE) +TYPE_CHECKER(JSValue, JS_VALUE_TYPE) bool HeapObject::IsAbstractCode() const { return IsBytecodeArray() || IsCode(); @@ -839,15 +870,16 @@ bool Object::IsSeededNumberDictionary() const { return IsDictionary(); } - -bool Object::IsUnseededNumberDictionary() const { - return IsDictionary(); +bool HeapObject::IsUnseededNumberDictionary() const { + return map() == GetHeap()->unseeded_number_dictionary_map(); } bool HeapObject::IsStringTable() const { return IsHashTable(); } bool HeapObject::IsStringSet() const { return IsHashTable(); } +bool HeapObject::IsObjectHashSet() const { return IsHashTable(); } + bool HeapObject::IsNormalizedMapCache() const { return NormalizedMapCache::IsNormalizedMapCache(this); } @@ -875,10 +907,6 @@ bool HeapObject::IsCompilationCacheTable() const { return IsHashTable(); } bool HeapObject::IsCodeCacheHashTable() const { return IsHashTable(); } -bool HeapObject::IsPolymorphicCodeCacheHashTable() const { - return IsHashTable(); -} - bool HeapObject::IsMapCache() const { return IsHashTable(); } bool HeapObject::IsObjectHashTable() const { return IsHashTable(); } @@ -941,13 +969,6 @@ bool HeapObject::IsStruct() const { STRUCT_LIST(MAKE_STRUCT_PREDICATE) #undef MAKE_STRUCT_PREDICATE -#define MAKE_ODDBALL_PREDICATE(Name) \ - bool HeapObject::Is##Name() const { \ - return IsOddball() && Oddball::cast(this)->kind() == Oddball::k##Name; \ - } -ODDBALL_LIST(MAKE_ODDBALL_PREDICATE) - -#undef MAKE_ODDBALL_PREDICATE double Object::Number() const { DCHECK(IsNumber()); return IsSmi() @@ -973,7 +994,8 @@ Representation Object::OptimalRepresentation() { return Representation::Smi(); } else if (FLAG_track_double_fields && IsHeapNumber()) { return Representation::Double(); - } else if (FLAG_track_computed_fields && IsUninitialized()) { + } else if (FLAG_track_computed_fields && + IsUninitialized(HeapObject::cast(this)->GetIsolate())) { return Representation::None(); } else if (FLAG_track_heap_object_fields) { DCHECK(IsHeapObject()); @@ -1099,8 +1121,7 @@ MaybeHandle<Object> JSReceiver::GetPrototype(Isolate* isolate, Handle<JSReceiver> receiver) { // We don't expect access checks to be needed on JSProxy objects. DCHECK(!receiver->IsAccessCheckNeeded() || receiver->IsJSObject()); - PrototypeIterator iter(isolate, receiver, - PrototypeIterator::START_AT_RECEIVER, + PrototypeIterator iter(isolate, receiver, kStartAtReceiver, PrototypeIterator::END_AT_NON_HIDDEN); do { if (!iter.AdvanceFollowingProxies()) return MaybeHandle<Object>(); @@ -1115,6 +1136,27 @@ MaybeHandle<Object> JSReceiver::GetProperty(Isolate* isolate, return GetProperty(receiver, str); } +// static +MUST_USE_RESULT MaybeHandle<FixedArray> JSReceiver::OwnPropertyKeys( + Handle<JSReceiver> object) { + return KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, + ALL_PROPERTIES, + GetKeysConversion::kConvertToString); +} + +bool JSObject::PrototypeHasNoElements(Isolate* isolate, JSObject* object) { + DisallowHeapAllocation no_gc; + HeapObject* prototype = HeapObject::cast(object->map()->prototype()); + HeapObject* null = isolate->heap()->null_value(); + HeapObject* empty = isolate->heap()->empty_fixed_array(); + while (prototype != null) { + Map* map = prototype->map(); + if (map->instance_type() <= LAST_CUSTOM_ELEMENTS_RECEIVER) return false; + if (JSObject::cast(prototype)->elements() != empty) return false; + prototype = HeapObject::cast(map->prototype()); + } + return true; +} #define FIELD_ADDR(p, offset) \ (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) @@ -1151,6 +1193,12 @@ MaybeHandle<Object> JSReceiver::GetProperty(Isolate* isolate, object, HeapObject::RawField(object, offset), value); \ heap->RecordWrite(object, offset, value); +#define FIXED_ARRAY_ELEMENTS_WRITE_BARRIER(heap, array, start, length) \ + do { \ + heap->RecordFixedArrayElements(array, start, length); \ + heap->incremental_marking()->IterateBlackObject(array); \ + } while (false) + #define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \ if (mode != SKIP_WRITE_BARRIER) { \ if (mode == UPDATE_WRITE_BARRIER) { \ @@ -1261,8 +1309,7 @@ Map* MapWord::ToMap() { return reinterpret_cast<Map*>(value_); } - -bool MapWord::IsForwardingAddress() { +bool MapWord::IsForwardingAddress() const { return HAS_SMI_TAG(reinterpret_cast<Object*>(value_)); } @@ -1741,7 +1788,7 @@ inline bool AllocationSite::DigestPretenuringFeedback( PrintIsolate(GetIsolate(), "pretenuring: AllocationSite(%p): (created, found, ratio) " "(%d, %d, %f) %s => %s\n", - this, create_count, found_count, ratio, + static_cast<void*>(this), create_count, found_count, ratio, PretenureDecisionName(current_decision), PretenureDecisionName(pretenure_decision())); } @@ -1785,15 +1832,14 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object, Object** objects, uint32_t count, EnsureElementsMode mode) { - ElementsKind current_kind = object->map()->elements_kind(); + ElementsKind current_kind = object->GetElementsKind(); ElementsKind target_kind = current_kind; { DisallowHeapAllocation no_allocation; DCHECK(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); bool is_holey = IsFastHoleyElementsKind(current_kind); if (current_kind == FAST_HOLEY_ELEMENTS) return; - Heap* heap = object->GetHeap(); - Object* the_hole = heap->the_hole_value(); + Object* the_hole = object->GetHeap()->the_hole_value(); for (uint32_t i = 0; i < count; ++i) { Object* current = *objects++; if (current == the_hole) { @@ -1909,10 +1955,16 @@ InterceptorInfo* Map::GetIndexedInterceptor() { constructor->shared()->get_api_func_data()->indexed_property_handler()); } +double Oddball::to_number_raw() const { + return READ_DOUBLE_FIELD(this, kToNumberRawOffset); +} + +void Oddball::set_to_number_raw(double value) { + WRITE_DOUBLE_FIELD(this, kToNumberRawOffset, value); +} ACCESSORS(Oddball, to_string, String, kToStringOffset) ACCESSORS(Oddball, to_number, Object, kToNumberOffset) -ACCESSORS(Oddball, to_boolean, Oddball, kToBooleanOffset) ACCESSORS(Oddball, type_of, String, kTypeOfOffset) @@ -1965,10 +2017,9 @@ void WeakCell::initialize(HeapObject* val) { // We just have to execute the generational barrier here because we never // mark through a weak cell and collect evacuation candidates when we process // all weak cells. - WriteBarrierMode mode = - Page::FromAddress(this->address())->IsFlagSet(Page::BLACK_PAGE) - ? UPDATE_WRITE_BARRIER - : UPDATE_WEAK_WRITE_BARRIER; + WriteBarrierMode mode = Marking::IsBlack(ObjectMarking::MarkBitFrom(this)) + ? UPDATE_WRITE_BARRIER + : UPDATE_WEAK_WRITE_BARRIER; CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kValueOffset, val, mode); } @@ -1992,9 +2043,7 @@ void WeakCell::clear_next(Object* the_hole_value) { set_next(the_hole_value, SKIP_WRITE_BARRIER); } - -bool WeakCell::next_cleared() { return next()->IsTheHole(); } - +bool WeakCell::next_cleared() { return next()->IsTheHole(GetIsolate()); } int JSObject::GetHeaderSize() { return GetHeaderSize(map()->instance_type()); } @@ -2005,12 +2054,11 @@ int JSObject::GetHeaderSize(InstanceType type) { // field operations considerably on average. if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize; switch (type) { + case JS_API_OBJECT_TYPE: case JS_SPECIAL_API_OBJECT_TYPE: return JSObject::kHeaderSize; case JS_GENERATOR_OBJECT_TYPE: return JSGeneratorObject::kSize; - case JS_MODULE_TYPE: - return JSModule::kSize; case JS_GLOBAL_PROXY_TYPE: return JSGlobalProxy::kSize; case JS_GLOBAL_OBJECT_TYPE: @@ -2051,6 +2099,10 @@ int JSObject::GetHeaderSize(InstanceType type) { return JSObject::kHeaderSize; case JS_MESSAGE_OBJECT_TYPE: return JSMessageObject::kSize; + case JS_ARGUMENTS_TYPE: + return JSArgumentsObject::kHeaderSize; + case JS_ERROR_TYPE: + return JSObject::kHeaderSize; default: UNREACHABLE(); return 0; @@ -2170,7 +2222,9 @@ void JSObject::WriteToField(int descriptor, PropertyDetails details, FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); if (details.representation().IsDouble()) { // Nothing more to be done. - if (value->IsUninitialized()) return; + if (value->IsUninitialized(this->GetIsolate())) { + return; + } if (IsUnboxedDoubleField(index)) { RawFastDoublePropertyAtPut(index, value->Number()); } else { @@ -2263,9 +2317,12 @@ bool Object::ToArrayIndex(uint32_t* index) { void Object::VerifyApiCallResultType() { #if DEBUG - if (!(IsSmi() || IsString() || IsSymbol() || IsJSReceiver() || - IsHeapNumber() || IsSimd128Value() || IsUndefined() || IsTrue() || - IsFalse() || IsNull())) { + if (IsSmi()) return; + DCHECK(IsHeapObject()); + Isolate* isolate = HeapObject::cast(this)->GetIsolate(); + if (!(IsString() || IsSymbol() || IsJSReceiver() || IsHeapNumber() || + IsSimd128Value() || IsUndefined(isolate) || IsTrue(isolate) || + IsFalse(isolate) || IsNull(isolate))) { FATAL("API call returned invalid object"); } #endif // DEBUG @@ -2281,12 +2338,24 @@ Handle<Object> FixedArray::get(FixedArray* array, int index, Isolate* isolate) { return handle(array->get(index), isolate); } +template <class T> +MaybeHandle<T> FixedArray::GetValue(Isolate* isolate, int index) const { + Object* obj = get(index); + if (obj->IsUndefined(isolate)) return MaybeHandle<T>(); + return Handle<T>(T::cast(obj), isolate); +} + +template <class T> +Handle<T> FixedArray::GetValueChecked(Isolate* isolate, int index) const { + Object* obj = get(index); + CHECK(!obj->IsUndefined(isolate)); + return Handle<T>(T::cast(obj), isolate); +} bool FixedArray::is_the_hole(int index) { return get(index) == GetHeap()->the_hole_value(); } - void FixedArray::set(int index, Smi* value) { DCHECK(map() != GetHeap()->fixed_cow_array_map()); DCHECK(index >= 0 && index < this->length()); @@ -2441,14 +2510,13 @@ 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::Set(int index, Object* obj, WriteBarrierMode mode) { + FixedArray::cast(this)->set(kFirstIndex + index, obj, mode); } void ArrayList::Clear(int index, Object* undefined) { - DCHECK(undefined->IsUndefined()); + DCHECK(undefined->IsUndefined(GetIsolate())); FixedArray::cast(this) ->set(kFirstIndex + index, undefined, SKIP_WRITE_BARRIER); } @@ -2780,18 +2848,18 @@ void Map::SetEnumLength(int length) { FixedArrayBase* Map::GetInitialElements() { + FixedArrayBase* result = nullptr; if (has_fast_elements() || has_fast_string_wrapper_elements()) { - DCHECK(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); - return GetHeap()->empty_fixed_array(); + result = GetHeap()->empty_fixed_array(); + } else if (has_fast_sloppy_arguments_elements()) { + result = GetHeap()->empty_sloppy_arguments_elements(); } else if (has_fixed_typed_array_elements()) { - FixedTypedArrayBase* empty_array = - GetHeap()->EmptyFixedTypedArrayForMap(this); - DCHECK(!GetHeap()->InNewSpace(empty_array)); - return empty_array; + result = GetHeap()->EmptyFixedTypedArrayForMap(this); } else { UNREACHABLE(); } - return NULL; + DCHECK(!GetHeap()->InNewSpace(result)); + return result; } // static @@ -3018,12 +3086,14 @@ int HashTableBase::ComputeCapacity(int at_least_space_for) { return Max(capacity, kMinCapacity); } -bool HashTableBase::IsKey(Heap* heap, Object* k) { +bool HashTableBase::IsKey(Isolate* isolate, Object* k) { + Heap* heap = isolate->heap(); return k != heap->the_hole_value() && k != heap->undefined_value(); } bool HashTableBase::IsKey(Object* k) { - return !k->IsTheHole() && !k->IsUndefined(); + Isolate* isolate = this->GetIsolate(); + return !k->IsTheHole(isolate) && !k->IsUndefined(isolate); } @@ -3036,6 +3106,10 @@ void HashTableBase::SetNumberOfDeletedElements(int nod) { set(kNumberOfDeletedElementsIndex, Smi::FromInt(nod)); } +template <typename Key> +Map* BaseShape<Key>::GetMap(Isolate* isolate) { + return isolate->heap()->hash_table_map(); +} template <typename Derived, typename Shape, typename Key> int HashTable<Derived, Shape, Key>::FindEntry(Key key) { @@ -3048,7 +3122,6 @@ int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key) { return FindEntry(isolate, key, HashTable::Hash(key)); } - // Find entry for key otherwise return kNotFound. template <typename Derived, typename Shape, typename Key> int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key, @@ -3057,18 +3130,39 @@ int HashTable<Derived, Shape, Key>::FindEntry(Isolate* isolate, Key key, uint32_t entry = FirstProbe(hash, capacity); uint32_t count = 1; // EnsureCapacity will guarantee the hash table is never full. + Object* undefined = isolate->heap()->undefined_value(); + Object* the_hole = isolate->heap()->the_hole_value(); while (true) { Object* element = KeyAt(entry); // Empty entry. Uses raw unchecked accessors because it is called by the // string table during bootstrapping. - if (element == isolate->heap()->root(Heap::kUndefinedValueRootIndex)) break; - if (element != isolate->heap()->root(Heap::kTheHoleValueRootIndex) && - Shape::IsMatch(key, element)) return entry; + if (element == undefined) break; + if (element != the_hole && Shape::IsMatch(key, element)) return entry; entry = NextProbe(entry, count++, capacity); } return kNotFound; } +template <typename Derived, typename Shape, typename Key> +bool HashTable<Derived, Shape, Key>::Has(Key key) { + return FindEntry(key) != kNotFound; +} + +template <typename Derived, typename Shape, typename Key> +bool HashTable<Derived, Shape, Key>::Has(Isolate* isolate, Key key) { + return FindEntry(isolate, key) != kNotFound; +} + +bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key, int32_t hash) { + return FindEntry(isolate, key, hash) != kNotFound; +} + +bool ObjectHashSet::Has(Isolate* isolate, Handle<Object> key) { + Object* hash = key->GetHash(); + if (!hash->IsSmi()) return false; + return FindEntry(isolate, key, Smi::cast(hash)->value()) != kNotFound; +} + bool StringSetShape::IsMatch(String* key, Object* value) { return value->IsString() && key->Equals(String::cast(value)); } @@ -3148,7 +3242,6 @@ CAST_ACCESSOR(JSGlobalProxy) CAST_ACCESSOR(JSMap) CAST_ACCESSOR(JSMapIterator) CAST_ACCESSOR(JSMessageObject) -CAST_ACCESSOR(JSModule) CAST_ACCESSOR(JSObject) CAST_ACCESSOR(JSProxy) CAST_ACCESSOR(JSReceiver) @@ -3157,6 +3250,7 @@ CAST_ACCESSOR(JSSet) CAST_ACCESSOR(JSSetIterator) CAST_ACCESSOR(JSTypedArray) CAST_ACCESSOR(JSValue) +CAST_ACCESSOR(JSWeakCollection) CAST_ACCESSOR(JSWeakMap) CAST_ACCESSOR(JSWeakSet) CAST_ACCESSOR(LayoutDescriptor) @@ -3166,11 +3260,12 @@ CAST_ACCESSOR(NameDictionary) CAST_ACCESSOR(NormalizedMapCache) CAST_ACCESSOR(Object) CAST_ACCESSOR(ObjectHashTable) +CAST_ACCESSOR(ObjectHashSet) CAST_ACCESSOR(Oddball) CAST_ACCESSOR(OrderedHashMap) CAST_ACCESSOR(OrderedHashSet) -CAST_ACCESSOR(PolymorphicCodeCacheHashTable) CAST_ACCESSOR(PropertyCell) +CAST_ACCESSOR(TemplateList) CAST_ACCESSOR(ScopeInfo) CAST_ACCESSOR(SeededNumberDictionary) CAST_ACCESSOR(SeqOneByteString) @@ -3185,6 +3280,7 @@ CAST_ACCESSOR(StringSet) CAST_ACCESSOR(StringTable) CAST_ACCESSOR(Struct) CAST_ACCESSOR(Symbol) +CAST_ACCESSOR(TemplateInfo) CAST_ACCESSOR(Uint16x8) CAST_ACCESSOR(Uint32x4) CAST_ACCESSOR(Uint8x16) @@ -3318,11 +3414,19 @@ LiteralsArray* LiteralsArray::cast(Object* object) { TypeFeedbackVector* LiteralsArray::feedback_vector() const { + if (length() == 0) { + return TypeFeedbackVector::cast( + const_cast<FixedArray*>(FixedArray::cast(this))); + } return TypeFeedbackVector::cast(get(kVectorIndex)); } void LiteralsArray::set_feedback_vector(TypeFeedbackVector* vector) { + if (length() <= kVectorIndex) { + DCHECK(vector->length() == 0); + return; + } set(kVectorIndex, vector); } @@ -3336,6 +3440,9 @@ void LiteralsArray::set_literal(int literal_index, Object* literal) { set(kFirstLiteralIndex + literal_index, literal); } +void LiteralsArray::set_literal_undefined(int literal_index) { + set_undefined(kFirstLiteralIndex + literal_index); +} int LiteralsArray::literals_count() const { return length() - kFirstLiteralIndex; @@ -3358,12 +3465,6 @@ int HandlerTable::GetRangeData(int index) const { return Smi::cast(get(index * kRangeEntrySize + kRangeDataIndex))->value(); } -HandlerTable::CatchPrediction HandlerTable::GetRangePrediction( - int index) const { - return HandlerPredictionField::decode( - Smi::cast(get(index * kRangeEntrySize + kRangeHandlerIndex))->value()); -} - void HandlerTable::SetRangeStart(int index, int value) { set(index * kRangeEntrySize + kRangeStartIndex, Smi::FromInt(value)); } @@ -3390,11 +3491,8 @@ void HandlerTable::SetReturnOffset(int index, int value) { set(index * kReturnEntrySize + kReturnOffsetIndex, Smi::FromInt(value)); } - -void HandlerTable::SetReturnHandler(int index, int offset, - CatchPrediction prediction) { - int value = HandlerOffsetField::encode(offset) | - HandlerPredictionField::encode(prediction); +void HandlerTable::SetReturnHandler(int index, int offset) { + int value = HandlerOffsetField::encode(offset); set(index * kReturnEntrySize + kReturnHandlerIndex, Smi::FromInt(value)); } @@ -3916,24 +4014,43 @@ void StringCharacterStream::VisitTwoByteString( int ByteArray::Size() { return RoundUp(length() + kHeaderSize, kPointerSize); } - byte ByteArray::get(int index) { DCHECK(index >= 0 && index < this->length()); return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize); } +const byte* ByteArray::data() const { + return reinterpret_cast<const byte*>(FIELD_ADDR_CONST(this, kHeaderSize)); +} void ByteArray::set(int index, byte value) { DCHECK(index >= 0 && index < this->length()); WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value); } +void ByteArray::copy_in(int index, const byte* buffer, int length) { + DCHECK(index >= 0 && length >= 0 && index + length >= index && + index + length <= this->length()); + byte* dst_addr = FIELD_ADDR(this, kHeaderSize + index * kCharSize); + memcpy(dst_addr, buffer, length); +} + +void ByteArray::copy_out(int index, byte* buffer, int length) { + DCHECK(index >= 0 && length >= 0 && index + length >= index && + index + length <= this->length()); + const byte* src_addr = FIELD_ADDR(this, kHeaderSize + index * kCharSize); + memcpy(buffer, src_addr, length); +} int ByteArray::get_int(int index) { - DCHECK(index >= 0 && (index * kIntSize) < this->length()); + DCHECK(index >= 0 && index < this->length() / kIntSize); return READ_INT_FIELD(this, kHeaderSize + index * kIntSize); } +void ByteArray::set_int(int index, int value) { + DCHECK(index >= 0 && index < this->length() / kIntSize); + WRITE_INT_FIELD(this, kHeaderSize + index * kIntSize, value); +} ByteArray* ByteArray::FromDataStartAddress(Address address) { DCHECK_TAG_ALIGNED(address); @@ -3995,6 +4112,16 @@ void BytecodeArray::set_interrupt_budget(int interrupt_budget) { WRITE_INT_FIELD(this, kInterruptBudgetOffset, interrupt_budget); } +int BytecodeArray::osr_loop_nesting_level() const { + return READ_INT8_FIELD(this, kOSRNestingLevelOffset); +} + +void BytecodeArray::set_osr_loop_nesting_level(int depth) { + DCHECK(0 <= depth && depth <= AbstractCode::kMaxLoopNestingMarker); + STATIC_ASSERT(AbstractCode::kMaxLoopNestingMarker < kMaxInt8); + WRITE_INT8_FIELD(this, kOSRNestingLevelOffset, depth); +} + int BytecodeArray::parameter_count() const { // Parameter count is stored as the size on stack of the parameters to allow // it to be used directly by generated code. @@ -4014,6 +4141,13 @@ Address BytecodeArray::GetFirstBytecodeAddress() { int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); } +int BytecodeArray::SizeIncludingMetadata() { + int size = BytecodeArraySize(); + size += constant_pool()->Size(); + size += handler_table()->Size(); + size += source_position_table()->Size(); + return size; +} ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset) @@ -4189,7 +4323,7 @@ void FixedTypedArray<Traits>::SetValue(uint32_t index, Object* value) { } else { // Clamp undefined to the default value. All other types have been // converted to a number type further up in the call chain. - DCHECK(value->IsUndefined()); + DCHECK(value->IsUndefined(GetIsolate())); } set(index, cast_value); } @@ -4461,11 +4595,6 @@ bool Map::is_undetectable() { } -void Map::set_is_observed() { set_bit_field(bit_field() | (1 << kIsObserved)); } - -bool Map::is_observed() { return ((1 << kIsObserved) & bit_field()) != 0; } - - void Map::set_has_named_interceptor() { set_bit_field(bit_field() | (1 << kHasNamedInterceptor)); } @@ -4511,6 +4640,10 @@ bool Map::is_prototype_map() const { return IsPrototypeMapBits::decode(bit_field2()); } +bool Map::should_be_fast_prototype_map() const { + if (!prototype_info()->IsPrototypeInfo()) return false; + return PrototypeInfo::cast(prototype_info())->should_be_fast_map(); +} void Map::set_elements_kind(ElementsKind elements_kind) { DCHECK(static_cast<int>(elements_kind) < kElementsKindCount); @@ -4547,6 +4680,10 @@ bool Map::has_sloppy_arguments_elements() { return IsSloppyArgumentsElements(elements_kind()); } +bool Map::has_fast_sloppy_arguments_elements() { + return elements_kind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS; +} + bool Map::has_fast_string_wrapper_elements() { return elements_kind() == FAST_STRING_WRAPPER_ELEMENTS; } @@ -4614,6 +4751,13 @@ bool Map::is_migration_target() { return IsMigrationTarget::decode(bit_field3()); } +void Map::set_immutable_proto(bool value) { + set_bit_field3(ImmutablePrototype::update(bit_field3(), value)); +} + +bool Map::is_immutable_proto() { + return ImmutablePrototype::decode(bit_field3()); +} void Map::set_new_target_is_base(bool value) { set_bit_field3(NewTargetIsBase::update(bit_field3(), value)); @@ -4644,7 +4788,9 @@ bool Map::is_stable() { bool Map::has_code_cache() { - return code_cache() != GetIsolate()->heap()->empty_fixed_array(); + // Code caches are always fixed arrays. The empty fixed array is used as a + // sentinel for an absent code cache. + return code_cache()->length() != 0; } @@ -4776,43 +4922,25 @@ Code::Kind Code::kind() { return ExtractKindFromFlags(flags()); } - bool Code::IsCodeStubOrIC() { - return kind() == STUB || kind() == HANDLER || kind() == LOAD_IC || - kind() == KEYED_LOAD_IC || kind() == CALL_IC || kind() == STORE_IC || - kind() == KEYED_STORE_IC || kind() == BINARY_OP_IC || - kind() == COMPARE_IC || kind() == TO_BOOLEAN_IC; -} - - -bool Code::IsJavaScriptCode() { - return kind() == FUNCTION || kind() == OPTIMIZED_FUNCTION || - is_interpreter_entry_trampoline(); -} - - -InlineCacheState Code::ic_state() { - InlineCacheState result = ExtractICStateFromFlags(flags()); - // Only allow uninitialized or debugger states for non-IC code - // objects. This is used in the debugger to determine whether or not - // a call to code object has been replaced with a debug break call. - DCHECK(is_inline_cache_stub() || - result == UNINITIALIZED || - result == DEBUG_STUB); - return result; + switch (kind()) { + case STUB: + case HANDLER: +#define CASE_KIND(kind) case kind: + IC_KIND_LIST(CASE_KIND) +#undef CASE_KIND + return true; + default: + return false; + } } - ExtraICState Code::extra_ic_state() { - DCHECK(is_inline_cache_stub() || ic_state() == DEBUG_STUB); + DCHECK(is_inline_cache_stub() || is_debug_stub()); return ExtractExtraICStateFromFlags(flags()); } -Code::StubType Code::type() { - return ExtractTypeFromFlags(flags()); -} - // For initialization. void Code::set_raw_kind_specific_flags1(int value) { WRITE_INT_FIELD(this, kKindSpecificFlags1Offset, value); @@ -4834,18 +4962,21 @@ inline bool Code::is_hydrogen_stub() { return is_crankshafted() && kind() != OPTIMIZED_FUNCTION; } +inline bool Code::is_interpreter_trampoline_builtin() { + Builtins* builtins = GetIsolate()->builtins(); + return this == *builtins->InterpreterEntryTrampoline() || + this == *builtins->InterpreterEnterBytecodeDispatch() || + this == *builtins->InterpreterMarkBaselineOnReturn(); +} -inline bool Code::is_interpreter_entry_trampoline() { - Handle<Code> interpreter_entry = - GetIsolate()->builtins()->InterpreterEntryTrampoline(); - return interpreter_entry.location() != nullptr && *interpreter_entry == this; +inline bool Code::has_unwinding_info() const { + return HasUnwindingInfoField::decode(READ_UINT32_FIELD(this, kFlagsOffset)); } -inline bool Code::is_interpreter_enter_bytecode_dispatch() { - Handle<Code> interpreter_handler = - GetIsolate()->builtins()->InterpreterEnterBytecodeDispatch(); - return interpreter_handler.location() != nullptr && - *interpreter_handler == this; +inline void Code::set_has_unwinding_info(bool state) { + uint32_t previous = READ_UINT32_FIELD(this, kFlagsOffset); + uint32_t updated_value = HasUnwindingInfoField::update(previous, state); + WRITE_UINT32_FIELD(this, kFlagsOffset, updated_value); } inline void Code::set_is_crankshafted(bool value) { @@ -4882,6 +5013,18 @@ inline void Code::set_can_have_weak_objects(bool value) { WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); } +inline bool Code::is_construct_stub() { + DCHECK(kind() == BUILTIN); + return IsConstructStubField::decode( + READ_UINT32_FIELD(this, kKindSpecificFlags1Offset)); +} + +inline void Code::set_is_construct_stub(bool value) { + DCHECK(kind() == BUILTIN); + int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset); + int updated = IsConstructStubField::update(previous, value); + WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated); +} bool Code::has_deoptimization_support() { DCHECK_EQ(FUNCTION, kind()); @@ -4937,7 +5080,7 @@ int Code::allow_osr_at_loop_nesting_level() { void Code::set_allow_osr_at_loop_nesting_level(int level) { DCHECK_EQ(FUNCTION, kind()); - DCHECK(level >= 0 && level <= kMaxLoopNestingMarker); + DCHECK(level >= 0 && level <= AbstractCode::kMaxLoopNestingMarker); int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset); int updated = AllowOSRAtLoopNestingLevelField::update(previous, level); WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated); @@ -5051,18 +5194,19 @@ bool Code::is_inline_cache_stub() { } } - -bool Code::is_keyed_stub() { - return is_keyed_load_stub() || is_keyed_store_stub(); +bool Code::is_debug_stub() { + if (kind() != BUILTIN) return false; + switch (builtin_index()) { +#define CASE_DEBUG_BUILTIN(name) case Builtins::k##name: + BUILTIN_LIST_DBG(CASE_DEBUG_BUILTIN) +#undef CASE_DEBUG_BUILTIN + return true; + default: + return false; + } + return false; } - - -bool Code::is_debug_stub() { return ic_state() == DEBUG_STUB; } bool Code::is_handler() { return kind() == HANDLER; } -bool Code::is_load_stub() { return kind() == LOAD_IC; } -bool Code::is_keyed_load_stub() { return kind() == KEYED_LOAD_IC; } -bool Code::is_store_stub() { return kind() == STORE_IC; } -bool Code::is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } bool Code::is_call_stub() { return kind() == CALL_IC; } bool Code::is_binary_op_stub() { return kind() == BINARY_OP_IC; } bool Code::is_compare_ic_stub() { return kind() == COMPARE_IC; } @@ -5070,14 +5214,6 @@ bool Code::is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; } bool Code::is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; } bool Code::is_wasm_code() { return kind() == WASM_FUNCTION; } -bool Code::embeds_maps_weakly() { - Kind k = kind(); - return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC || - k == KEYED_STORE_IC) && - ic_state() == MONOMORPHIC; -} - - Address Code::constant_pool() { Address constant_pool = NULL; if (FLAG_enable_embedded_constant_pool) { @@ -5089,28 +5225,18 @@ Address Code::constant_pool() { return constant_pool; } -Code::Flags Code::ComputeFlags(Kind kind, InlineCacheState ic_state, - ExtraICState extra_ic_state, StubType type, +Code::Flags Code::ComputeFlags(Kind kind, ExtraICState extra_ic_state, CacheHolderFlag holder) { // Compute the bit mask. - unsigned int bits = KindField::encode(kind) | ICStateField::encode(ic_state) | - TypeField::encode(type) | + unsigned int bits = KindField::encode(kind) | ExtraICStateField::encode(extra_ic_state) | CacheHolderField::encode(holder); return static_cast<Flags>(bits); } -Code::Flags Code::ComputeMonomorphicFlags(Kind kind, - ExtraICState extra_ic_state, - CacheHolderFlag holder, - StubType type) { - return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, holder); -} - - -Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, StubType type, +Code::Flags Code::ComputeHandlerFlags(Kind handler_kind, CacheHolderFlag holder) { - return ComputeFlags(Code::HANDLER, MONOMORPHIC, handler_kind, type, holder); + return ComputeFlags(Code::HANDLER, handler_kind, holder); } @@ -5119,33 +5245,17 @@ Code::Kind Code::ExtractKindFromFlags(Flags flags) { } -InlineCacheState Code::ExtractICStateFromFlags(Flags flags) { - return ICStateField::decode(flags); -} - - ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) { return ExtraICStateField::decode(flags); } -Code::StubType Code::ExtractTypeFromFlags(Flags flags) { - return TypeField::decode(flags); -} - CacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) { return CacheHolderField::decode(flags); } - -Code::Flags Code::RemoveTypeFromFlags(Flags flags) { - int bits = flags & ~TypeField::kMask; - return static_cast<Flags>(bits); -} - - -Code::Flags Code::RemoveTypeAndHolderFromFlags(Flags flags) { - int bits = flags & ~TypeField::kMask & ~CacheHolderField::kMask; +Code::Flags Code::RemoveHolderFromFlags(Flags flags) { + int bits = flags & ~CacheHolderField::kMask; return static_cast<Flags>(bits); } @@ -5223,6 +5333,39 @@ int AbstractCode::instruction_size() { } } +ByteArray* AbstractCode::source_position_table() { + if (IsCode()) { + return GetCode()->source_position_table(); + } else { + return GetBytecodeArray()->source_position_table(); + } +} + +void AbstractCode::set_source_position_table(ByteArray* source_position_table) { + if (IsCode()) { + GetCode()->set_source_position_table(source_position_table); + } else { + GetBytecodeArray()->set_source_position_table(source_position_table); + } +} + +int AbstractCode::LookupRangeInHandlerTable( + int code_offset, int* data, HandlerTable::CatchPrediction* prediction) { + if (IsCode()) { + return GetCode()->LookupRangeInHandlerTable(code_offset, data, prediction); + } else { + return GetBytecodeArray()->LookupRangeInHandlerTable(code_offset, data, + prediction); + } +} + +int AbstractCode::SizeIncludingMetadata() { + if (IsCode()) { + return GetCode()->SizeIncludingMetadata(); + } else { + return GetBytecodeArray()->SizeIncludingMetadata(); + } +} int AbstractCode::ExecutableSize() { if (IsCode()) { return GetCode()->ExecutableSize(); @@ -5274,20 +5417,20 @@ Object* Map::prototype() const { void Map::set_prototype(Object* value, WriteBarrierMode mode) { - DCHECK(value->IsNull() || value->IsJSReceiver()); + DCHECK(value->IsNull(GetIsolate()) || value->IsJSReceiver()); WRITE_FIELD(this, kPrototypeOffset, value); CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode); } LayoutDescriptor* Map::layout_descriptor_gc_safe() { - Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); + Object* layout_desc = READ_FIELD(this, kLayoutDescriptorOffset); return LayoutDescriptor::cast_gc_safe(layout_desc); } bool Map::HasFastPointerLayout() const { - Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset); + Object* layout_desc = READ_FIELD(this, kLayoutDescriptorOffset); return LayoutDescriptor::IsFastPointerLayout(layout_desc); } @@ -5335,8 +5478,7 @@ void Map::InitializeDescriptors(DescriptorArray* descriptors, ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset) -ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset) - +ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDescriptorOffset) void Map::set_bit_field3(uint32_t bits) { if (kInt32Size != kPointerSize) { @@ -5407,14 +5549,14 @@ void Map::set_prototype_info(Object* value, WriteBarrierMode mode) { void Map::SetBackPointer(Object* value, WriteBarrierMode mode) { DCHECK(instance_type() >= FIRST_JS_RECEIVER_TYPE); - DCHECK((value->IsMap() && GetBackPointer()->IsUndefined())); + DCHECK(value->IsMap()); + DCHECK(GetBackPointer()->IsUndefined(GetIsolate())); DCHECK(!value->IsMap() || Map::cast(value)->GetConstructor() == constructor_or_backpointer()); set_constructor_or_backpointer(value, mode); } - -ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) +ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset) ACCESSORS(Map, dependent_code, DependentCode, kDependentCodeOffset) ACCESSORS(Map, weak_cell_cache, Object, kWeakCellCacheOffset) ACCESSORS(Map, constructor_or_backpointer, Object, @@ -5445,8 +5587,6 @@ Handle<Map> Map::CopyInitialMap(Handle<Map> map) { } -ACCESSORS(JSBoundFunction, length, Object, kLengthOffset) -ACCESSORS(JSBoundFunction, name, Object, kNameOffset) ACCESSORS(JSBoundFunction, bound_target_function, JSReceiver, kBoundTargetFunctionOffset) ACCESSORS(JSBoundFunction, bound_this, Object, kBoundThisOffset) @@ -5469,13 +5609,58 @@ ACCESSORS(AccessorInfo, expected_receiver_type, Object, ACCESSORS(AccessorInfo, getter, Object, kGetterOffset) ACCESSORS(AccessorInfo, setter, Object, kSetterOffset) +ACCESSORS(AccessorInfo, js_getter, Object, kJsGetterOffset) ACCESSORS(AccessorInfo, data, Object, kDataOffset) ACCESSORS(Box, value, Object, kValueOffset) +Map* PrototypeInfo::ObjectCreateMap() { + return Map::cast(WeakCell::cast(object_create_map())->value()); +} + +// static +void PrototypeInfo::SetObjectCreateMap(Handle<PrototypeInfo> info, + Handle<Map> map) { + Handle<WeakCell> cell = Map::WeakCellForMap(map); + info->set_object_create_map(*cell); +} + +bool PrototypeInfo::HasObjectCreateMap() { + Object* cache = object_create_map(); + return cache->IsWeakCell() && !WeakCell::cast(cache)->cleared(); +} + +bool FunctionTemplateInfo::instantiated() { + return shared_function_info()->IsSharedFunctionInfo(); +} + +FunctionTemplateInfo* FunctionTemplateInfo::GetParent(Isolate* isolate) { + Object* parent = parent_template(); + return parent->IsUndefined(isolate) ? nullptr + : FunctionTemplateInfo::cast(parent); +} + +ObjectTemplateInfo* ObjectTemplateInfo::GetParent(Isolate* isolate) { + Object* maybe_ctor = constructor(); + if (maybe_ctor->IsUndefined(isolate)) return nullptr; + FunctionTemplateInfo* constructor = FunctionTemplateInfo::cast(maybe_ctor); + while (true) { + constructor = constructor->GetParent(isolate); + if (constructor == nullptr) return nullptr; + Object* maybe_obj = constructor->instance_template(); + if (!maybe_obj->IsUndefined(isolate)) { + return ObjectTemplateInfo::cast(maybe_obj); + } + } + return nullptr; +} + ACCESSORS(PrototypeInfo, prototype_users, Object, kPrototypeUsersOffset) +ACCESSORS(PrototypeInfo, object_create_map, Object, kObjectCreateMap) SMI_ACCESSORS(PrototypeInfo, registry_slot, kRegistrySlotOffset) ACCESSORS(PrototypeInfo, validity_cell, Object, kValidityCellOffset) +SMI_ACCESSORS(PrototypeInfo, bit_field, kBitFieldOffset) +BOOL_ACCESSORS(PrototypeInfo, bit_field, should_be_fast_map, kShouldBeFastBit) ACCESSORS(SloppyBlockWithEvalContextExtension, scope_info, ScopeInfo, kScopeInfoOffset) @@ -5485,9 +5670,10 @@ ACCESSORS(SloppyBlockWithEvalContextExtension, extension, JSObject, ACCESSORS(AccessorPair, getter, Object, kGetterOffset) ACCESSORS(AccessorPair, setter, Object, kSetterOffset) -ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset) -ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset) ACCESSORS(AccessCheckInfo, callback, Object, kCallbackOffset) +ACCESSORS(AccessCheckInfo, named_interceptor, Object, kNamedInterceptorOffset) +ACCESSORS(AccessCheckInfo, indexed_interceptor, Object, + kIndexedInterceptorOffset) ACCESSORS(AccessCheckInfo, data, Object, kDataOffset) ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset) @@ -5528,11 +5714,47 @@ ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object, kInstanceCallHandlerOffset) ACCESSORS(FunctionTemplateInfo, access_check_info, Object, kAccessCheckInfoOffset) +ACCESSORS(FunctionTemplateInfo, shared_function_info, Object, + kSharedFunctionInfoOffset) + SMI_ACCESSORS(FunctionTemplateInfo, flag, kFlagOffset) ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset) -ACCESSORS(ObjectTemplateInfo, internal_field_count, Object, - kInternalFieldCountOffset) +ACCESSORS(ObjectTemplateInfo, data, Object, kDataOffset) + +int ObjectTemplateInfo::internal_field_count() const { + Object* value = data(); + DCHECK(value->IsSmi()); + return InternalFieldCount::decode(Smi::cast(value)->value()); +} + +void ObjectTemplateInfo::set_internal_field_count(int count) { + return set_data(Smi::FromInt( + InternalFieldCount::update(Smi::cast(data())->value(), count))); +} + +bool ObjectTemplateInfo::immutable_proto() const { + Object* value = data(); + DCHECK(value->IsSmi()); + return IsImmutablePrototype::decode(Smi::cast(value)->value()); +} + +void ObjectTemplateInfo::set_immutable_proto(bool immutable) { + return set_data(Smi::FromInt( + IsImmutablePrototype::update(Smi::cast(data())->value(), immutable))); +} + +int TemplateList::length() const { + return Smi::cast(FixedArray::cast(this)->get(kLengthIndex))->value(); +} + +Object* TemplateList::get(int index) const { + return FixedArray::cast(this)->get(kFirstElementIndex + index); +} + +void TemplateList::set(int index, Object* value) { + FixedArray::cast(this)->set(kFirstElementIndex + index, value); +} ACCESSORS(AllocationSite, transition_info, Object, kTransitionInfoOffset) ACCESSORS(AllocationSite, nested_site, Object, kNestedSiteOffset) @@ -5553,13 +5775,18 @@ ACCESSORS(Script, context_data, Object, kContextOffset) ACCESSORS(Script, wrapper, HeapObject, kWrapperOffset) SMI_ACCESSORS(Script, type, kTypeOffset) ACCESSORS(Script, line_ends, Object, kLineEndsOffset) -ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset) -SMI_ACCESSORS(Script, eval_from_instructions_offset, - kEvalFrominstructionsOffsetOffset) +ACCESSORS_CHECKED(Script, eval_from_shared, Object, kEvalFromSharedOffset, + this->type() != TYPE_WASM) +SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset, + this->type() != TYPE_WASM) ACCESSORS(Script, shared_function_infos, Object, kSharedFunctionInfosOffset) SMI_ACCESSORS(Script, flags, kFlagsOffset) ACCESSORS(Script, source_url, Object, kSourceUrlOffset) ACCESSORS(Script, source_mapping_url, Object, kSourceMappingUrlOffset) +ACCESSORS_CHECKED(Script, wasm_object, JSObject, kEvalFromSharedOffset, + this->type() == TYPE_WASM) +SMI_ACCESSORS_CHECKED(Script, wasm_function_index, kEvalFromPositionOffset, + this->type() == TYPE_WASM) Script::CompilationType Script::compilation_type() { return BooleanBit::get(flags(), kCompilationTypeBit) ? @@ -5593,24 +5820,44 @@ void Script::set_origin_options(ScriptOriginOptions origin_options) { ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex) -ACCESSORS(DebugInfo, abstract_code, AbstractCode, kAbstractCodeIndex) +ACCESSORS(DebugInfo, debug_bytecode_array, Object, kDebugBytecodeArrayIndex) ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex) -BytecodeArray* DebugInfo::original_bytecode_array() { +bool DebugInfo::HasDebugBytecodeArray() { + return debug_bytecode_array()->IsBytecodeArray(); +} + +bool DebugInfo::HasDebugCode() { + Code* code = shared()->code(); + bool has = code->kind() == Code::FUNCTION; + DCHECK(!has || code->has_debug_break_slots()); + return has; +} + +BytecodeArray* DebugInfo::OriginalBytecodeArray() { + DCHECK(HasDebugBytecodeArray()); return shared()->bytecode_array(); } -SMI_ACCESSORS(BreakPointInfo, code_offset, kCodeOffsetIndex) +BytecodeArray* DebugInfo::DebugBytecodeArray() { + DCHECK(HasDebugBytecodeArray()); + return BytecodeArray::cast(debug_bytecode_array()); +} + +Code* DebugInfo::DebugCode() { + DCHECK(HasDebugCode()); + return shared()->code(); +} + SMI_ACCESSORS(BreakPointInfo, source_position, kSourcePositionIndex) -SMI_ACCESSORS(BreakPointInfo, statement_position, kStatementPositionIndex) ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex) ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset) ACCESSORS(SharedFunctionInfo, optimized_code_map, FixedArray, kOptimizedCodeMapOffset) ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset) -ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector, - kFeedbackVectorOffset) +ACCESSORS(SharedFunctionInfo, feedback_metadata, TypeFeedbackMetadata, + kFeedbackMetadataOffset) #if TRACE_MAPS SMI_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset) #endif @@ -5634,7 +5881,6 @@ BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype, kRemovePrototypeBit) 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_named_expression, @@ -5769,14 +6015,14 @@ void SharedFunctionInfo::set_optimization_disabled(bool disable) { LanguageMode SharedFunctionInfo::language_mode() { - STATIC_ASSERT(LANGUAGE_END == 3); + STATIC_ASSERT(LANGUAGE_END == 2); return construct_language_mode( BooleanBit::get(compiler_hints(), kStrictModeFunction)); } void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) { - STATIC_ASSERT(LANGUAGE_END == 3); + STATIC_ASSERT(LANGUAGE_END == 2); // We only allow language mode transitions that set the same language mode // again or go up in the chain: DCHECK(is_sloppy(this->language_mode()) || is_strict(language_mode)); @@ -5798,7 +6044,6 @@ void SharedFunctionInfo::set_kind(FunctionKind kind) { set_compiler_hints(hints); } - BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, needs_home_object, kNeedsHomeObject) BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative) @@ -5814,6 +6059,7 @@ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_crankshaft, BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_flush, kDontFlush) BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_arrow, kIsArrow) BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator) +BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_async, kIsAsyncFunction) BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method, kIsConciseMethod) BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_getter_function, @@ -5822,11 +6068,12 @@ BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_setter_function, kIsSetterFunction) BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor, kIsDefaultConstructor) +BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_asm_wasm_broken, + kIsAsmWasmBroken) -ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset) -ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset) - -ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset) +inline bool SharedFunctionInfo::is_resumable() const { + return is_generator() || is_async(); +} bool Script::HasValidSource() { Object* src = this->source(); @@ -5889,6 +6136,9 @@ void SharedFunctionInfo::ReplaceCode(Code* value) { if (is_compiled()) set_never_compiled(false); } +bool SharedFunctionInfo::HasBaselineCode() const { + return code()->kind() == Code::FUNCTION; +} ScopeInfo* SharedFunctionInfo::scope_info() const { return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset)); @@ -5905,11 +6155,11 @@ void SharedFunctionInfo::set_scope_info(ScopeInfo* value, mode); } - -bool SharedFunctionInfo::is_compiled() { +bool SharedFunctionInfo::is_compiled() const { Builtins* builtins = GetIsolate()->builtins(); DCHECK(code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent)); DCHECK(code() != builtins->builtin(Builtins::kCompileOptimized)); + DCHECK(code() != builtins->builtin(Builtins::kCompileBaseline)); return code() != builtins->builtin(Builtins::kCompileLazy); } @@ -5933,8 +6183,8 @@ DebugInfo* SharedFunctionInfo::GetDebugInfo() { bool SharedFunctionInfo::HasDebugCode() { - return HasBytecodeArray() || - (code()->kind() == Code::FUNCTION && code()->has_debug_break_slots()); + if (HasBaselineCode()) return code()->has_debug_break_slots(); + return HasBytecodeArray(); } @@ -5949,7 +6199,7 @@ FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() { } void SharedFunctionInfo::set_api_func_data(FunctionTemplateInfo* data) { - DCHECK(function_data()->IsUndefined()); + DCHECK(function_data()->IsUndefined(GetIsolate())); set_function_data(data); } @@ -5957,19 +6207,37 @@ bool SharedFunctionInfo::HasBytecodeArray() { return function_data()->IsBytecodeArray(); } - BytecodeArray* SharedFunctionInfo::bytecode_array() { DCHECK(HasBytecodeArray()); return BytecodeArray::cast(function_data()); } void SharedFunctionInfo::set_bytecode_array(BytecodeArray* bytecode) { - DCHECK(function_data()->IsUndefined()); + DCHECK(function_data()->IsUndefined(GetIsolate())); set_function_data(bytecode); } void SharedFunctionInfo::ClearBytecodeArray() { - DCHECK(function_data()->IsUndefined() || HasBytecodeArray()); + DCHECK(function_data()->IsUndefined(GetIsolate()) || HasBytecodeArray()); + set_function_data(GetHeap()->undefined_value()); +} + +bool SharedFunctionInfo::HasAsmWasmData() { + return function_data()->IsFixedArray(); +} + +FixedArray* SharedFunctionInfo::asm_wasm_data() { + DCHECK(HasAsmWasmData()); + return FixedArray::cast(function_data()); +} + +void SharedFunctionInfo::set_asm_wasm_data(FixedArray* data) { + DCHECK(function_data()->IsUndefined(GetIsolate()) || HasAsmWasmData()); + set_function_data(data); +} + +void SharedFunctionInfo::ClearAsmWasmData() { + DCHECK(function_data()->IsUndefined(GetIsolate()) || HasAsmWasmData()); set_function_data(GetHeap()->undefined_value()); } @@ -5995,12 +6263,13 @@ String* SharedFunctionInfo::inferred_name() { if (HasInferredName()) { return String::cast(function_identifier()); } - DCHECK(function_identifier()->IsUndefined() || HasBuiltinFunctionId()); - return GetIsolate()->heap()->empty_string(); + Isolate* isolate = GetIsolate(); + DCHECK(function_identifier()->IsUndefined(isolate) || HasBuiltinFunctionId()); + return isolate->heap()->empty_string(); } void SharedFunctionInfo::set_inferred_name(String* inferred_name) { - DCHECK(function_identifier()->IsUndefined() || HasInferredName()); + DCHECK(function_identifier()->IsUndefined(GetIsolate()) || HasInferredName()); set_function_identifier(inferred_name); } @@ -6086,7 +6355,7 @@ void SharedFunctionInfo::set_disable_optimization_reason(BailoutReason reason) { bool SharedFunctionInfo::IsBuiltin() { Object* script_obj = script(); - if (script_obj->IsUndefined()) return true; + if (script_obj->IsUndefined(GetIsolate())) return true; Script* script = Script::cast(script_obj); Script::Type type = static_cast<Script::Type>(script->type()); return type != Script::TYPE_NORMAL; @@ -6105,6 +6374,10 @@ bool JSFunction::IsOptimized() { return code()->kind() == Code::OPTIMIZED_FUNCTION; } +bool JSFunction::IsMarkedForBaseline() { + return code() == + GetIsolate()->builtins()->builtin(Builtins::kCompileBaseline); +} bool JSFunction::IsMarkedForOptimization() { return code() == GetIsolate()->builtins()->builtin( @@ -6147,7 +6420,7 @@ void Map::InobjectSlackTrackingStep() { AbstractCode* JSFunction::abstract_code() { Code* code = this->code(); - if (code->is_interpreter_entry_trampoline()) { + if (code->is_interpreter_trampoline_builtin()) { return AbstractCode::cast(shared()->bytecode_array()); } else { return AbstractCode::cast(code); @@ -6215,7 +6488,7 @@ Context* JSFunction::native_context() { return context()->native_context(); } void JSFunction::set_context(Object* value) { - DCHECK(value->IsUndefined() || value->IsContext()); + DCHECK(value->IsUndefined(GetIsolate()) || value->IsContext()); WRITE_FIELD(this, kContextOffset, value); WRITE_BARRIER(GetHeap(), this, kContextOffset, value); } @@ -6235,7 +6508,8 @@ bool JSFunction::has_initial_map() { bool JSFunction::has_instance_prototype() { - return has_initial_map() || !prototype_or_initial_map()->IsTheHole(); + return has_initial_map() || + !prototype_or_initial_map()->IsTheHole(GetIsolate()); } @@ -6270,16 +6544,16 @@ Object* JSFunction::prototype() { bool JSFunction::is_compiled() { Builtins* builtins = GetIsolate()->builtins(); return code() != builtins->builtin(Builtins::kCompileLazy) && + code() != builtins->builtin(Builtins::kCompileBaseline) && code() != builtins->builtin(Builtins::kCompileOptimized) && code() != builtins->builtin(Builtins::kCompileOptimizedConcurrent); } - -int JSFunction::NumberOfLiterals() { - return literals()->length(); +TypeFeedbackVector* JSFunction::feedback_vector() { + LiteralsArray* array = literals(); + return array->feedback_vector(); } - ACCESSORS(JSProxy, target, JSReceiver, kTargetOffset) ACCESSORS(JSProxy, handler, Object, kHandlerOffset) ACCESSORS(JSProxy, hash, Object, kHashOffset) @@ -6325,28 +6599,25 @@ void Foreign::set_foreign_address(Address value) { ACCESSORS(JSGeneratorObject, function, JSFunction, kFunctionOffset) ACCESSORS(JSGeneratorObject, context, Context, kContextOffset) ACCESSORS(JSGeneratorObject, receiver, Object, kReceiverOffset) -ACCESSORS(JSGeneratorObject, input, Object, kInputOffset) +ACCESSORS(JSGeneratorObject, input_or_debug_pos, Object, kInputOrDebugPosOffset) +SMI_ACCESSORS(JSGeneratorObject, resume_mode, kResumeModeOffset) SMI_ACCESSORS(JSGeneratorObject, continuation, kContinuationOffset) ACCESSORS(JSGeneratorObject, operand_stack, FixedArray, kOperandStackOffset) -bool JSGeneratorObject::is_suspended() { - DCHECK_LT(kGeneratorExecuting, kGeneratorClosed); - DCHECK_EQ(kGeneratorClosed, 0); - return continuation() > 0; +bool JSGeneratorObject::is_suspended() const { + DCHECK_LT(kGeneratorExecuting, 0); + DCHECK_LT(kGeneratorClosed, 0); + return continuation() >= 0; } -bool JSGeneratorObject::is_closed() { +bool JSGeneratorObject::is_closed() const { return continuation() == kGeneratorClosed; } -bool JSGeneratorObject::is_executing() { +bool JSGeneratorObject::is_executing() const { return continuation() == kGeneratorExecuting; } -ACCESSORS(JSModule, context, Object, kContextOffset) -ACCESSORS(JSModule, scope_info, ScopeInfo, kScopeInfoOffset) - - ACCESSORS(JSValue, value, Object, kValueOffset) @@ -6387,14 +6658,15 @@ INT_ACCESSORS(Code, constant_pool_offset, kConstantPoolOffset) ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset) ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset) ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset) +ACCESSORS(Code, source_position_table, ByteArray, kSourcePositionTableOffset) ACCESSORS(Code, raw_type_feedback_info, Object, kTypeFeedbackInfoOffset) ACCESSORS(Code, next_code_link, Object, kNextCodeLinkOffset) - void Code::WipeOutHeader() { WRITE_FIELD(this, kRelocationInfoOffset, NULL); WRITE_FIELD(this, kHandlerTableOffset, NULL); WRITE_FIELD(this, kDeoptimizationDataOffset, NULL); + WRITE_FIELD(this, kSourcePositionTableOffset, NULL); // Do not wipe out major/minor keys on a code stub or IC if (!READ_FIELD(this, kTypeFeedbackInfoOffset)->IsSmi()) { WRITE_FIELD(this, kTypeFeedbackInfoOffset, NULL); @@ -6444,11 +6716,48 @@ byte* Code::instruction_end() { return instruction_start() + instruction_size(); } +int Code::GetUnwindingInfoSizeOffset() const { + DCHECK(has_unwinding_info()); + return RoundUp(kHeaderSize + instruction_size(), kInt64Size); +} + +int Code::unwinding_info_size() const { + DCHECK(has_unwinding_info()); + return static_cast<int>( + READ_UINT64_FIELD(this, GetUnwindingInfoSizeOffset())); +} + +void Code::set_unwinding_info_size(int value) { + DCHECK(has_unwinding_info()); + WRITE_UINT64_FIELD(this, GetUnwindingInfoSizeOffset(), value); +} + +byte* Code::unwinding_info_start() { + DCHECK(has_unwinding_info()); + return FIELD_ADDR(this, GetUnwindingInfoSizeOffset()) + kInt64Size; +} + +byte* Code::unwinding_info_end() { + DCHECK(has_unwinding_info()); + return unwinding_info_start() + unwinding_info_size(); +} int Code::body_size() { - return RoundUp(instruction_size(), kObjectAlignment); + int unpadded_body_size = + has_unwinding_info() + ? static_cast<int>(unwinding_info_end() - instruction_start()) + : instruction_size(); + return RoundUp(unpadded_body_size, kObjectAlignment); } +int Code::SizeIncludingMetadata() { + int size = CodeSize(); + size += relocation_info()->Size(); + size += deoptimization_data()->Size(); + size += handler_table()->Size(); + if (kind() == FUNCTION) size += source_position_table()->Size(); + return size; +} ByteArray* Code::unchecked_relocation_info() { return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset)); @@ -6623,7 +6932,7 @@ ACCESSORS(JSRegExp, source, Object, kSourceOffset) JSRegExp::Type JSRegExp::TypeTag() { Object* data = this->data(); - if (data->IsUndefined()) return JSRegExp::NOT_COMPILED; + if (data->IsUndefined(GetIsolate())) return JSRegExp::NOT_COMPILED; Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex)); return static_cast<JSRegExp::Type>(smi->value()); } @@ -6681,16 +6990,18 @@ ElementsKind JSObject::GetElementsKind() { // pointer may point to a one pointer filler map. if (ElementsAreSafeToExamine()) { Map* map = fixed_array->map(); - DCHECK((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 && - fixed_array->IsFixedArray() && - fixed_array->IsDictionary()) || - (kind > DICTIONARY_ELEMENTS)); + if (IsFastSmiOrObjectElementsKind(kind)) { + DCHECK(map == GetHeap()->fixed_array_map() || + map == GetHeap()->fixed_cow_array_map()); + } else if (IsFastDoubleElementsKind(kind)) { + DCHECK(fixed_array->IsFixedDoubleArray() || + fixed_array == GetHeap()->empty_fixed_array()); + } else if (kind == DICTIONARY_ELEMENTS) { + DCHECK(fixed_array->IsFixedArray()); + DCHECK(fixed_array->IsDictionary()); + } else { + DCHECK(kind > DICTIONARY_ELEMENTS); + } DCHECK(!IsSloppyArgumentsElements(kind) || (elements()->IsFixedArray() && elements()->length() >= 2)); } @@ -7140,7 +7451,7 @@ Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object, Handle<Name> name) { if (object->IsJSObject()) { // Shortcut LookupIterator it = LookupIterator::PropertyOrElement( - object->GetIsolate(), object, name, object, LookupIterator::HIDDEN); + object->GetIsolate(), object, name, object, LookupIterator::OWN); return HasProperty(&it); } @@ -7150,6 +7461,19 @@ Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object, return Just(attributes.FromJust() != ABSENT); } +Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object, + uint32_t index) { + if (object->IsJSObject()) { // Shortcut + LookupIterator it(object->GetIsolate(), object, index, object, + LookupIterator::OWN); + return HasProperty(&it); + } + + Maybe<PropertyAttributes> attributes = + JSReceiver::GetOwnPropertyAttributes(object, index); + MAYBE_RETURN(attributes, Nothing<bool>()); + return Just(attributes.FromJust() != ABSENT); +} Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( Handle<JSReceiver> object, Handle<Name> name) { @@ -7162,10 +7486,16 @@ Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes( Handle<JSReceiver> object, Handle<Name> name) { LookupIterator it = LookupIterator::PropertyOrElement( - name->GetIsolate(), object, name, object, LookupIterator::HIDDEN); + name->GetIsolate(), object, name, object, LookupIterator::OWN); return GetPropertyAttributes(&it); } +Maybe<PropertyAttributes> JSReceiver::GetOwnPropertyAttributes( + Handle<JSReceiver> object, uint32_t index) { + LookupIterator it(object->GetIsolate(), object, index, object, + LookupIterator::OWN); + return GetPropertyAttributes(&it); +} Maybe<bool> JSReceiver::HasElement(Handle<JSReceiver> object, uint32_t index) { LookupIterator it(object->GetIsolate(), object, index, object); @@ -7184,7 +7514,7 @@ Maybe<PropertyAttributes> JSReceiver::GetElementAttributes( Maybe<PropertyAttributes> JSReceiver::GetOwnElementAttributes( Handle<JSReceiver> object, uint32_t index) { Isolate* isolate = object->GetIsolate(); - LookupIterator it(isolate, object, index, object, LookupIterator::HIDDEN); + LookupIterator it(isolate, object, index, object, LookupIterator::OWN); return GetPropertyAttributes(&it); } @@ -7200,19 +7530,20 @@ bool JSGlobalProxy::IsDetachedFrom(JSGlobalObject* global) const { return iter.GetCurrent() != global; } - -Handle<Smi> JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver> object) { - return object->IsJSProxy() - ? JSProxy::GetOrCreateIdentityHash(Handle<JSProxy>::cast(object)) - : JSObject::GetOrCreateIdentityHash(Handle<JSObject>::cast(object)); +Smi* JSReceiver::GetOrCreateIdentityHash(Isolate* isolate, + Handle<JSReceiver> object) { + return object->IsJSProxy() ? JSProxy::GetOrCreateIdentityHash( + isolate, Handle<JSProxy>::cast(object)) + : JSObject::GetOrCreateIdentityHash( + isolate, Handle<JSObject>::cast(object)); } -Handle<Object> JSReceiver::GetIdentityHash(Isolate* isolate, - Handle<JSReceiver> receiver) { - return receiver->IsJSProxy() ? JSProxy::GetIdentityHash( - isolate, Handle<JSProxy>::cast(receiver)) - : JSObject::GetIdentityHash( - isolate, Handle<JSObject>::cast(receiver)); +Object* JSReceiver::GetIdentityHash(Isolate* isolate, + Handle<JSReceiver> receiver) { + return receiver->IsJSProxy() + ? JSProxy::GetIdentityHash(Handle<JSProxy>::cast(receiver)) + : JSObject::GetIdentityHash(isolate, + Handle<JSObject>::cast(receiver)); } @@ -7260,6 +7591,9 @@ void AccessorInfo::set_property_attributes(PropertyAttributes attributes) { set_flag(AttributesField::update(flag(), attributes)); } +bool FunctionTemplateInfo::IsTemplateFor(JSObject* object) { + return IsTemplateFor(object->map()); +} bool AccessorInfo::IsCompatibleReceiver(Object* receiver) { if (!HasExpectedReceiverType()) return true; @@ -7289,8 +7623,9 @@ void AccessorPair::set(AccessorComponent component, Object* value) { void AccessorPair::SetComponents(Object* getter, Object* setter) { - if (!getter->IsNull()) set_getter(getter); - if (!setter->IsNull()) set_setter(setter); + Isolate* isolate = GetIsolate(); + if (!getter->IsNull(isolate)) set_getter(getter); + if (!setter->IsNull(isolate)) set_setter(setter); } @@ -7310,7 +7645,7 @@ bool AccessorPair::ContainsAccessor() { bool AccessorPair::IsJSAccessor(Object* obj) { - return obj->IsCallable() || obj->IsUndefined(); + return obj->IsCallable() || obj->IsUndefined(GetIsolate()); } @@ -7337,14 +7672,16 @@ void BaseDictionaryShape<Key>::SetEntry(Dictionary* dict, int entry, Handle<Object> key, Handle<Object> value, PropertyDetails details) { - STATIC_ASSERT(Dictionary::kEntrySize == 3); + STATIC_ASSERT(Dictionary::kEntrySize == 2 || Dictionary::kEntrySize == 3); DCHECK(!key->IsName() || details.dictionary_index() > 0); int index = dict->EntryToIndex(entry); DisallowHeapAllocation no_gc; WriteBarrierMode mode = dict->GetWriteBarrierMode(no_gc); - dict->set(index, *key, mode); - dict->set(index + 1, *value, mode); - dict->set(index + 2, details.AsSmi()); + dict->set(index + Dictionary::kEntryKeyIndex, *key, mode); + dict->set(index + Dictionary::kEntryValueIndex, *value, mode); + if (Dictionary::kEntrySize == 3) { + dict->set(index + Dictionary::kEntryDetailsIndex, details.AsSmi()); + } } @@ -7358,8 +7695,8 @@ void GlobalDictionaryShape::SetEntry(Dictionary* dict, int entry, int index = dict->EntryToIndex(entry); DisallowHeapAllocation no_gc; WriteBarrierMode mode = dict->GetWriteBarrierMode(no_gc); - dict->set(index, *key, mode); - dict->set(index + 1, *value, mode); + dict->set(index + Dictionary::kEntryKeyIndex, *key, mode); + dict->set(index + Dictionary::kEntryValueIndex, *value, mode); PropertyCell::cast(*value)->set_property_details(details); } @@ -7381,6 +7718,9 @@ uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key, return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0); } +Map* UnseededNumberDictionaryShape::GetMap(Isolate* isolate) { + return *isolate->factory()->unseeded_number_dictionary_map(); +} uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) { return ComputeIntegerHash(key, seed); @@ -7455,7 +7795,8 @@ void GlobalDictionaryShape::DetailsAtPut(Dictionary* dict, int entry, template <typename Dictionary> bool GlobalDictionaryShape::IsDeleted(Dictionary* dict, int entry) { DCHECK(dict->ValueAt(entry)->IsPropertyCell()); - return PropertyCell::cast(dict->ValueAt(entry))->value()->IsTheHole(); + Isolate* isolate = dict->GetIsolate(); + return PropertyCell::cast(dict->ValueAt(entry))->value()->IsTheHole(isolate); } @@ -7555,7 +7896,6 @@ void Map::ClearCodeCache(Heap* heap) { // Please note this function is used during marking: // - MarkCompactCollector::MarkUnmarkedObject // - IncrementalMarking::Step - DCHECK(!heap->InNewSpace(heap->empty_fixed_array())); WRITE_FIELD(this, kCodeCacheOffset, heap->empty_fixed_array()); } @@ -7730,7 +8070,7 @@ Object* OrderedHashTableIterator<Derived, TableType>::CurrentKey() { TableType* table(TableType::cast(this->table())); int index = Smi::cast(this->index())->value(); Object* key = table->KeyAt(index); - DCHECK(!key->IsTheHole()); + DCHECK(!key->IsTheHole(table->GetIsolate())); return key; } @@ -7750,7 +8090,7 @@ Object* JSMapIterator::CurrentValue() { OrderedHashMap* table(OrderedHashMap::cast(this->table())); int index = Smi::cast(this->index())->value(); Object* value = table->ValueAt(index); - DCHECK(!value->IsTheHole()); + DCHECK(!value->IsTheHole(table->GetIsolate())); return value; } |