summaryrefslogtreecommitdiff
path: root/deps/v8/src/objects.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/objects.cc')
-rw-r--r--deps/v8/src/objects.cc814
1 files changed, 365 insertions, 449 deletions
diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc
index 811656ad9a..6ccdbf4e34 100644
--- a/deps/v8/src/objects.cc
+++ b/deps/v8/src/objects.cc
@@ -61,25 +61,33 @@
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT
+#include "src/objects/js-break-iterator.h"
#include "src/objects/js-collator.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-collection-inl.h"
+#ifdef V8_INTL_SUPPORT
+#include "src/objects/js-date-time-format.h"
+#endif // V8_INTL_SUPPORT
#include "src/objects/js-generator-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/js-list-format.h"
#include "src/objects/js-locale.h"
+#include "src/objects/js-number-format.h"
+#include "src/objects/js-plural-rules.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/js-regexp-inl.h"
#include "src/objects/js-regexp-string-iterator.h"
#ifdef V8_INTL_SUPPORT
-#include "src/objects/js-plural-rules.h"
#include "src/objects/js-relative-time-format.h"
+#include "src/objects/js-segmenter.h"
#endif // V8_INTL_SUPPORT
#include "src/objects/literal-objects-inl.h"
#include "src/objects/map.h"
#include "src/objects/microtask-inl.h"
+#include "src/objects/microtask-queue-inl.h"
#include "src/objects/module-inl.h"
#include "src/objects/promise-inl.h"
+#include "src/objects/stack-frame-info-inl.h"
#include "src/parsing/preparsed-scope-data.h"
#include "src/property-descriptor.h"
#include "src/prototype.h"
@@ -364,8 +372,17 @@ Handle<String> Object::NoSideEffectsToString(Isolate* isolate,
Handle<Object> input) {
DisallowJavascriptExecution no_js(isolate);
- if (input->IsString() || input->IsNumeric() || input->IsOddball()) {
+ if (input->IsString() || input->IsNumber() || input->IsOddball()) {
return Object::ToString(isolate, input).ToHandleChecked();
+ } else if (input->IsBigInt()) {
+ MaybeHandle<String> maybe_string =
+ BigInt::ToString(isolate, Handle<BigInt>::cast(input), 10, kDontThrow);
+ Handle<String> result;
+ if (maybe_string.ToHandle(&result)) return result;
+ // BigInt-to-String conversion can fail on 32-bit platforms where
+ // String::kMaxLength is too small to fit this BigInt.
+ return isolate->factory()->NewStringFromStaticChars(
+ "<a very large BigInt>");
} else if (input->IsFunction()) {
// -- F u n c t i o n
Handle<String> fun_str;
@@ -1444,16 +1461,24 @@ int JSObject::GetHeaderSize(InstanceType type,
case JS_MODULE_NAMESPACE_TYPE:
return JSModuleNamespace::kHeaderSize;
#ifdef V8_INTL_SUPPORT
+ case JS_INTL_V8_BREAK_ITERATOR_TYPE:
+ return JSV8BreakIterator::kSize;
case JS_INTL_COLLATOR_TYPE:
return JSCollator::kSize;
+ case JS_INTL_DATE_TIME_FORMAT_TYPE:
+ return JSDateTimeFormat::kSize;
case JS_INTL_LIST_FORMAT_TYPE:
return JSListFormat::kSize;
case JS_INTL_LOCALE_TYPE:
return JSLocale::kSize;
+ case JS_INTL_NUMBER_FORMAT_TYPE:
+ return JSNumberFormat::kSize;
case JS_INTL_PLURAL_RULES_TYPE:
return JSPluralRules::kSize;
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
return JSRelativeTimeFormat::kSize;
+ case JS_INTL_SEGMENTER_TYPE:
+ return JSSegmenter::kSize;
#endif // V8_INTL_SUPPORT
case WASM_GLOBAL_TYPE:
return WasmGlobalObject::kSize;
@@ -2202,9 +2227,8 @@ V8_WARN_UNUSED_RESULT Maybe<bool> FastAssign(
if (use_set) {
LookupIterator it(target, next_key, target);
- Maybe<bool> result =
- Object::SetProperty(&it, prop_value, LanguageMode::kStrict,
- Object::CERTAINLY_NOT_STORE_FROM_KEYED);
+ Maybe<bool> result = Object::SetProperty(
+ &it, prop_value, LanguageMode::kStrict, StoreOrigin::kNamed);
if (result.IsNothing()) return result;
if (stable) stable = from->map() == *map;
} else {
@@ -2267,7 +2291,8 @@ Maybe<bool> JSReceiver::SetOrCopyDataProperties(
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
isolate, status,
Runtime::SetObjectProperty(isolate, target, next_key, prop_value,
- LanguageMode::kStrict),
+ LanguageMode::kStrict,
+ StoreOrigin::kMaybeKeyed),
Nothing<bool>());
} else {
if (excluded_properties != nullptr &&
@@ -2536,12 +2561,12 @@ std::ostream& operator<<(std::ostream& os, const Brief& v) {
HeapObject* heap_object;
if (maybe_object->ToSmi(&smi)) {
smi->SmiPrint(os);
- } else if (maybe_object->IsClearedWeakHeapObject()) {
+ } else if (maybe_object->IsCleared()) {
os << "[cleared]";
- } else if (maybe_object->ToWeakHeapObject(&heap_object)) {
+ } else if (maybe_object->GetHeapObjectIfWeak(&heap_object)) {
os << "[weak] ";
heap_object->HeapObjectShortPrint(os);
- } else if (maybe_object->ToStrongHeapObject(&heap_object)) {
+ } else if (maybe_object->GetHeapObjectIfStrong(&heap_object)) {
heap_object->HeapObjectShortPrint(os);
} else {
UNREACHABLE();
@@ -2599,7 +2624,7 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
// Externalizing twice leaks the external resource, so it's
// prohibited by the API.
DCHECK(this->SupportsExternalization());
- DCHECK(!resource->IsCompressible());
+ DCHECK(resource->IsCacheable());
#ifdef ENABLE_SLOW_DCHECKS
if (FLAG_enable_slow_asserts) {
// Assert that the resource and the string are equivalent.
@@ -2612,7 +2637,7 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
#endif // DEBUG
int size = this->Size(); // Byte size of the original string.
// Abort if size does not allow in-place conversion.
- if (size < ExternalString::kShortSize) return false;
+ if (size < ExternalString::kUncachedSize) return false;
Isolate* isolate;
// Read-only strings cannot be made external, since that would mutate the
// string.
@@ -2626,23 +2651,25 @@ bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
}
// Morph the string to an external string by replacing the map and
// reinitializing the fields. This won't work if the space the existing
- // string occupies is too small for a regular external string.
- // Instead, we resort to a short external string instead, omitting
- // the field caching the address of the backing store. When we encounter
- // short external strings in generated code, we need to bailout to runtime.
+ // string occupies is too small for a regular external string. Instead, we
+ // resort to an uncached external string instead, omitting the field caching
+ // the address of the backing store. When we encounter uncached external
+ // strings in generated code, we need to bailout to runtime.
Map* new_map;
ReadOnlyRoots roots(heap);
if (size < ExternalString::kSize) {
if (is_internalized) {
- new_map =
- is_one_byte
- ? roots
- .short_external_internalized_string_with_one_byte_data_map()
- : roots.short_external_internalized_string_map();
+ if (is_one_byte) {
+ new_map =
+ roots
+ .uncached_external_internalized_string_with_one_byte_data_map();
+ } else {
+ new_map = roots.uncached_external_internalized_string_map();
+ }
} else {
new_map = is_one_byte
- ? roots.short_external_string_with_one_byte_data_map()
- : roots.short_external_string_map();
+ ? roots.uncached_external_string_with_one_byte_data_map()
+ : roots.uncached_external_string_map();
}
} else {
new_map =
@@ -2679,7 +2706,7 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
// Externalizing twice leaks the external resource, so it's
// prohibited by the API.
DCHECK(this->SupportsExternalization());
- DCHECK(!resource->IsCompressible());
+ DCHECK(resource->IsCacheable());
#ifdef ENABLE_SLOW_DCHECKS
if (FLAG_enable_slow_asserts) {
// Assert that the resource and the string are equivalent.
@@ -2697,7 +2724,7 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
#endif // DEBUG
int size = this->Size(); // Byte size of the original string.
// Abort if size does not allow in-place conversion.
- if (size < ExternalString::kShortSize) return false;
+ if (size < ExternalString::kUncachedSize) return false;
Isolate* isolate;
// Read-only strings cannot be made external, since that would mutate the
// string.
@@ -2712,16 +2739,16 @@ bool String::MakeExternal(v8::String::ExternalOneByteStringResource* resource) {
// Morph the string to an external string by replacing the map and
// reinitializing the fields. This won't work if the space the existing
- // string occupies is too small for a regular external string.
- // Instead, we resort to a short external string instead, omitting
- // the field caching the address of the backing store. When we encounter
- // short external strings in generated code, we need to bailout to runtime.
+ // string occupies is too small for a regular external string. Instead, we
+ // resort to an uncached external string instead, omitting the field caching
+ // the address of the backing store. When we encounter uncached external
+ // strings in generated code, we need to bailout to runtime.
Map* new_map;
ReadOnlyRoots roots(heap);
if (size < ExternalString::kSize) {
new_map = is_internalized
- ? roots.short_external_one_byte_internalized_string_map()
- : roots.short_external_one_byte_string_map();
+ ? roots.uncached_external_one_byte_internalized_string_map()
+ : roots.uncached_external_one_byte_string_map();
} else {
new_map = is_internalized
? roots.external_one_byte_internalized_string_map()
@@ -3069,6 +3096,7 @@ VisitorId Map::GetVisitorId(Map* map) {
case STRING_TABLE_TYPE:
case SCOPE_INFO_TYPE:
case SCRIPT_CONTEXT_TABLE_TYPE:
+ case AWAIT_CONTEXT_TYPE:
case BLOCK_CONTEXT_TYPE:
case CATCH_CONTEXT_TYPE:
case DEBUG_EVALUATE_CONTEXT_TYPE:
@@ -3137,6 +3165,12 @@ VisitorId Map::GetVisitorId(Map* map) {
case JS_ARRAY_BUFFER_TYPE:
return kVisitJSArrayBuffer;
+ case JS_DATA_VIEW_TYPE:
+ return kVisitJSDataView;
+
+ case JS_TYPED_ARRAY_TYPE:
+ return kVisitJSTypedArray;
+
case SMALL_ORDERED_HASH_MAP_TYPE:
return kVisitSmallOrderedHashMap;
@@ -3170,11 +3204,10 @@ VisitorId Map::GetVisitorId(Map* map) {
case JS_DATE_TYPE:
case JS_ARRAY_ITERATOR_TYPE:
case JS_ARRAY_TYPE:
+ case JS_FUNCTION_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
case JS_MESSAGE_OBJECT_TYPE:
- case JS_TYPED_ARRAY_TYPE:
- case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
@@ -3187,12 +3220,17 @@ VisitorId Map::GetVisitorId(Map* map) {
case JS_REGEXP_TYPE:
case JS_REGEXP_STRING_ITERATOR_TYPE:
#ifdef V8_INTL_SUPPORT
+ case JS_INTL_V8_BREAK_ITERATOR_TYPE:
case JS_INTL_COLLATOR_TYPE:
+ case JS_INTL_DATE_TIME_FORMAT_TYPE:
case JS_INTL_LIST_FORMAT_TYPE:
case JS_INTL_LOCALE_TYPE:
+ case JS_INTL_NUMBER_FORMAT_TYPE:
case JS_INTL_PLURAL_RULES_TYPE:
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
+ case JS_INTL_SEGMENTER_TYPE:
#endif // V8_INTL_SUPPORT
+ case WASM_EXCEPTION_TYPE:
case WASM_GLOBAL_TYPE:
case WASM_MEMORY_TYPE:
case WASM_MODULE_TYPE:
@@ -3203,9 +3241,6 @@ VisitorId Map::GetVisitorId(Map* map) {
case JS_SPECIAL_API_OBJECT_TYPE:
return kVisitJSApiObject;
- case JS_FUNCTION_TYPE:
- return kVisitJSFunction;
-
case FILLER_TYPE:
case FOREIGN_TYPE:
case HEAP_NUMBER_TYPE:
@@ -3234,7 +3269,7 @@ VisitorId Map::GetVisitorId(Map* map) {
case ALLOCATION_SITE_TYPE:
return kVisitAllocationSite;
-#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
+#define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE
if (instance_type == PROTOTYPE_INFO_TYPE) {
@@ -3335,7 +3370,7 @@ bool JSObject::IsUnmodifiedApiObject(Object** o) {
HeapObject* heap_object = HeapObject::cast(object);
if (!object->IsJSObject()) return false;
JSObject* js_object = JSObject::cast(object);
- if (!js_object->IsApiWrapper()) return false;
+ if (!js_object->IsDroppableApiWrapper()) return false;
Object* maybe_constructor = js_object->map()->GetConstructor();
if (!maybe_constructor->IsJSFunction()) return false;
JSFunction* constructor = JSFunction::cast(maybe_constructor);
@@ -3372,6 +3407,15 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT
}
os << ">";
} break;
+ case AWAIT_CONTEXT_TYPE: {
+ os << "<AwaitContext generator= ";
+ HeapStringAllocator allocator;
+ StringStream accumulator(&allocator);
+ Context::cast(this)->extension()->ShortPrint(&accumulator);
+ os << accumulator.ToCString().get();
+ os << '>';
+ break;
+ }
case BLOCK_CONTEXT_TYPE:
os << "<BlockContext[" << FixedArray::cast(this)->length() << "]>";
break;
@@ -3524,8 +3568,8 @@ void HeapObject::HeapObjectShortPrint(std::ostream& os) { // NOLINT
case JS_MESSAGE_OBJECT_TYPE:
os << "<JSMessageObject>";
break;
-#define MAKE_STRUCT_CASE(NAME, Name, name) \
- case NAME##_TYPE: \
+#define MAKE_STRUCT_CASE(TYPE, Name, name) \
+ case TYPE: \
os << "<" #Name; \
Name::cast(this)->BriefPrintDetails(os); \
os << ">"; \
@@ -3923,14 +3967,14 @@ MaybeObjectHandle Map::WrapFieldType(Isolate* isolate, Handle<FieldType> type) {
// static
FieldType* Map::UnwrapFieldType(MaybeObject* wrapped_type) {
- if (wrapped_type->IsClearedWeakHeapObject()) {
+ if (wrapped_type->IsCleared()) {
return FieldType::None();
}
HeapObject* heap_object;
- if (wrapped_type->ToWeakHeapObject(&heap_object)) {
+ if (wrapped_type->GetHeapObjectIfWeak(&heap_object)) {
return FieldType::cast(heap_object);
}
- return FieldType::cast(wrapped_type->ToObject());
+ return wrapped_type->cast<FieldType>();
}
MaybeHandle<Map> Map::CopyWithField(Isolate* isolate, Handle<Map> map,
@@ -4325,8 +4369,10 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
heap->ClearRecordedSlot(*object,
HeapObject::RawField(*object, index.offset()));
} else {
- DCHECK(!heap->HasRecordedSlot(
- *object, HeapObject::RawField(*object, index.offset())));
+#ifdef DEBUG
+ heap->VerifyClearedSlot(*object,
+ HeapObject::RawField(*object, index.offset()));
+#endif
}
} else {
object->RawFastPropertyAtPut(index, value);
@@ -4691,8 +4737,8 @@ Map* Map::FindFieldOwner(Isolate* isolate, int descriptor) const {
void Map::UpdateFieldType(Isolate* isolate, int descriptor, Handle<Name> name,
PropertyConstness new_constness,
Representation new_representation,
- MaybeObjectHandle new_wrapped_type) {
- DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeakHeapObject());
+ const MaybeObjectHandle& new_wrapped_type) {
+ DCHECK(new_wrapped_type->IsSmi() || new_wrapped_type->IsWeak());
// We store raw pointers in the queue, so no allocations are allowed.
DisallowHeapAllocation no_allocation;
PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
@@ -4841,25 +4887,6 @@ Handle<Map> Map::ReconfigureElementsKind(Isolate* isolate, Handle<Map> map,
return mu.ReconfigureElementsKind(new_elements_kind);
}
-// Generalize all fields and update the transition tree.
-Handle<Map> Map::GeneralizeAllFields(Isolate* isolate, Handle<Map> map) {
- Handle<FieldType> any_type = FieldType::Any(isolate);
-
- Handle<DescriptorArray> descriptors(map->instance_descriptors(), isolate);
- for (int i = 0; i < map->NumberOfOwnDescriptors(); ++i) {
- PropertyDetails details = descriptors->GetDetails(i);
- if (details.location() == kField) {
- DCHECK_EQ(kData, details.kind());
- MapUpdater mu(isolate, map);
- map = mu.ReconfigureToDataField(i, details.attributes(),
- PropertyConstness::kMutable,
- Representation::Tagged(), any_type);
- }
- }
- return map;
-}
-
-
// static
MaybeHandle<Map> Map::TryUpdate(Isolate* isolate, Handle<Map> old_map) {
DisallowHeapAllocation no_allocation;
@@ -4988,18 +5015,16 @@ Maybe<bool> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
MaybeHandle<Object> Object::SetProperty(Isolate* isolate, Handle<Object> object,
Handle<Name> name, Handle<Object> value,
LanguageMode language_mode,
- StoreFromKeyed store_mode) {
+ StoreOrigin store_origin) {
LookupIterator it(isolate, object, name);
- MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_mode));
+ MAYBE_RETURN_NULL(SetProperty(&it, value, language_mode, store_origin));
return value;
}
-
Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
Handle<Object> value,
LanguageMode language_mode,
- StoreFromKeyed store_mode,
- bool* found) {
+ StoreOrigin store_origin, bool* found) {
it->UpdateProtector();
DCHECK(it->IsFound());
ShouldThrow should_throw =
@@ -5104,14 +5129,13 @@ Maybe<bool> Object::SetPropertyInternal(LookupIterator* it,
return Nothing<bool>();
}
-
Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
LanguageMode language_mode,
- StoreFromKeyed store_mode) {
+ StoreOrigin store_origin) {
if (it->IsFound()) {
bool found = true;
Maybe<bool> result =
- SetPropertyInternal(it, value, language_mode, store_mode, &found);
+ SetPropertyInternal(it, value, language_mode, store_origin, &found);
if (found) return result;
}
@@ -5126,19 +5150,18 @@ Maybe<bool> Object::SetProperty(LookupIterator* it, Handle<Object> value,
ShouldThrow should_throw =
is_sloppy(language_mode) ? kDontThrow : kThrowOnError;
- return AddDataProperty(it, value, NONE, should_throw, store_mode);
+ return AddDataProperty(it, value, NONE, should_throw, store_origin);
}
-
Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
LanguageMode language_mode,
- StoreFromKeyed store_mode) {
+ StoreOrigin store_origin) {
Isolate* isolate = it->isolate();
if (it->IsFound()) {
bool found = true;
Maybe<bool> result =
- SetPropertyInternal(it, value, language_mode, store_mode, &found);
+ SetPropertyInternal(it, value, language_mode, store_origin, &found);
if (found) return result;
}
@@ -5217,7 +5240,7 @@ Maybe<bool> Object::SetSuperProperty(LookupIterator* it, Handle<Object> value,
}
}
- return AddDataProperty(&own_lookup, value, NONE, should_throw, store_mode);
+ return AddDataProperty(&own_lookup, value, NONE, should_throw, store_origin);
}
Maybe<bool> Object::CannotCreateProperty(Isolate* isolate,
@@ -5314,11 +5337,10 @@ Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) {
return Just(true);
}
-
Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
PropertyAttributes attributes,
ShouldThrow should_throw,
- StoreFromKeyed store_mode) {
+ StoreOrigin store_origin) {
if (!it->GetReceiver()->IsJSReceiver()) {
return CannotCreateProperty(it->isolate(), it->GetReceiver(), it->GetName(),
value, should_throw);
@@ -5380,7 +5402,7 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value,
// Migrate to the most up-to-date map that will be able to store |value|
// under it->name() with |attributes|.
it->PrepareTransitionToDataProperty(receiver, value, attributes,
- store_mode);
+ store_origin);
DCHECK_EQ(LookupIterator::TRANSITION, it->state());
it->ApplyTransitionToDataProperty(receiver);
@@ -5859,7 +5881,7 @@ Maybe<bool> JSProxy::SetProperty(Handle<JSProxy> proxy, Handle<Name> name,
LookupIterator it =
LookupIterator::PropertyOrElement(isolate, receiver, name, target);
return Object::SetSuperProperty(&it, value, language_mode,
- Object::MAY_BE_STORE_FROM_KEYED);
+ StoreOrigin::kMaybeKeyed);
}
Handle<Object> trap_result;
@@ -6225,7 +6247,7 @@ void JSObject::AddProperty(Isolate* isolate, Handle<JSObject> object,
DCHECK(object->map()->is_extensible() || name->IsPrivate());
#endif
CHECK(AddDataProperty(&it, value, attributes, kThrowOnError,
- CERTAINLY_NOT_STORE_FROM_KEYED)
+ StoreOrigin::kNamed)
.IsJust());
}
@@ -6328,7 +6350,7 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
}
return AddDataProperty(it, value, attributes, should_throw,
- CERTAINLY_NOT_STORE_FROM_KEYED);
+ StoreOrigin::kNamed);
}
MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes(
@@ -6408,7 +6430,7 @@ MaybeHandle<Map> NormalizedMapCache::Get(Handle<Map> fast_map,
DisallowHeapAllocation no_gc;
MaybeObject* value = WeakFixedArray::Get(GetIndex(fast_map));
HeapObject* heap_object;
- if (!value->ToWeakHeapObject(&heap_object)) {
+ if (!value->GetHeapObjectIfWeak(&heap_object)) {
return MaybeHandle<Map>();
}
@@ -6698,6 +6720,11 @@ Object* SetHashAndUpdateProperties(Isolate* isolate, HeapObject* properties,
return properties;
}
+ if (properties->IsGlobalDictionary()) {
+ GlobalDictionary::cast(properties)->SetHash(hash);
+ return properties;
+ }
+
DCHECK(properties->IsNameDictionary());
NameDictionary::cast(properties)->SetHash(hash);
return properties;
@@ -8096,144 +8123,6 @@ Maybe<bool> JSProxy::GetOwnPropertyDescriptor(Isolate* isolate,
}
-bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
- ElementsKind kind,
- Object* object) {
- Isolate* isolate = GetIsolate();
- if (IsObjectElementsKind(kind) || kind == FAST_STRING_WRAPPER_ELEMENTS) {
- int length = IsJSArray() ? Smi::ToInt(JSArray::cast(this)->length())
- : elements->length();
- for (int i = 0; i < length; ++i) {
- Object* element = elements->get(i);
- if (!element->IsTheHole(isolate) && element == object) return true;
- }
- } else {
- DCHECK(kind == DICTIONARY_ELEMENTS || kind == SLOW_STRING_WRAPPER_ELEMENTS);
- Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
- if (!key->IsUndefined(isolate)) return true;
- }
- return false;
-}
-
-
-// Check whether this object references another object.
-bool JSObject::ReferencesObject(Object* obj) {
- Map* map_of_this = map();
- Heap* heap = GetHeap();
- DisallowHeapAllocation no_allocation;
-
- // Is the object the constructor for this object?
- if (map_of_this->GetConstructor() == obj) {
- return true;
- }
-
- // Is the object the prototype for this object?
- if (map_of_this->prototype() == obj) {
- return true;
- }
-
- // Check if the object is among the named properties.
- Object* key = SlowReverseLookup(obj);
- if (!key->IsUndefined(heap->isolate())) {
- return true;
- }
-
- // Check if the object is among the indexed properties.
- ElementsKind kind = GetElementsKind();
- switch (kind) {
- // Raw pixels and external arrays do not reference other
- // objects.
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
- case TYPE##_ELEMENTS: \
- break;
-
- TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
-
- case PACKED_DOUBLE_ELEMENTS:
- case HOLEY_DOUBLE_ELEMENTS:
- break;
- case PACKED_SMI_ELEMENTS:
- case HOLEY_SMI_ELEMENTS:
- break;
- case PACKED_ELEMENTS:
- case HOLEY_ELEMENTS:
- case DICTIONARY_ELEMENTS:
- case FAST_STRING_WRAPPER_ELEMENTS:
- case SLOW_STRING_WRAPPER_ELEMENTS: {
- FixedArray* elements = FixedArray::cast(this->elements());
- if (ReferencesObjectFromElements(elements, kind, obj)) return true;
- break;
- }
- case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
- case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
- SloppyArgumentsElements* elements =
- SloppyArgumentsElements::cast(this->elements());
- // Check the mapped parameters.
- for (uint32_t i = 0; i < elements->parameter_map_length(); ++i) {
- Object* value = elements->get_mapped_entry(i);
- if (!value->IsTheHole(heap->isolate()) && value == obj) return true;
- }
- // Check the arguments.
- FixedArray* arguments = elements->arguments();
- kind = arguments->IsNumberDictionary() ? DICTIONARY_ELEMENTS
- : HOLEY_ELEMENTS;
- if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
- break;
- }
- case NO_ELEMENTS:
- break;
- }
-
- // For functions check the context.
- if (IsJSFunction()) {
- // Get the constructor function for arguments array.
- Map* arguments_map =
- heap->isolate()->context()->native_context()->sloppy_arguments_map();
- JSFunction* arguments_function =
- JSFunction::cast(arguments_map->GetConstructor());
-
- // Get the context and don't check if it is the native context.
- JSFunction* f = JSFunction::cast(this);
- Context* context = f->context();
- if (context->IsNativeContext()) {
- return false;
- }
-
- // Check the non-special context slots.
- for (int i = Context::MIN_CONTEXT_SLOTS; i < context->length(); i++) {
- // Only check JS objects.
- if (context->get(i)->IsJSObject()) {
- JSObject* ctxobj = JSObject::cast(context->get(i));
- // If it is an arguments array check the content.
- if (ctxobj->map()->GetConstructor() == arguments_function) {
- if (ctxobj->ReferencesObject(obj)) {
- return true;
- }
- } else if (ctxobj == obj) {
- return true;
- }
- }
- }
-
- // Check the context extension (if any) if it can have references.
- if (context->has_extension() && !context->IsCatchContext() &&
- !context->IsModuleContext()) {
- // With harmony scoping, a JSFunction may have a script context.
- // TODO(mvstanton): walk into the ScopeInfo.
- if (context->IsScriptContext()) {
- return false;
- }
-
- return context->extension_object()->ReferencesObject(obj);
- }
- }
-
- // No references to object.
- return false;
-}
-
-
Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver,
IntegrityLevel level,
ShouldThrow should_throw) {
@@ -8758,7 +8647,7 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
// typed array elements. Freeze works only if there are no actual elements.
if (object->HasFixedTypedArrayElements()) {
if (attrs == FROZEN &&
- JSArrayBufferView::cast(*object)->byte_length()->Number() > 0) {
+ JSArrayBufferView::cast(*object)->byte_length() > 0) {
isolate->Throw(*isolate->factory()->NewTypeError(
MessageTemplate::kCannotFreezeArrayBufferView));
return Nothing<bool>();
@@ -9937,7 +9826,7 @@ Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map,
Handle<Object> value,
PropertyAttributes attributes,
PropertyConstness constness,
- StoreFromKeyed store_mode) {
+ StoreOrigin store_origin) {
RuntimeCallTimerScope stats_scope(
isolate, *map,
map->is_prototype_map()
@@ -9966,7 +9855,7 @@ Handle<Map> Map::TransitionToDataProperty(Isolate* isolate, Handle<Map> map,
TransitionFlag flag = INSERT_TRANSITION;
MaybeHandle<Map> maybe_map;
- if (!map->TooManyFastProperties(store_mode)) {
+ if (!map->TooManyFastProperties(store_origin)) {
if (!FLAG_track_constant_fields && value->IsJSFunction()) {
maybe_map =
Map::CopyWithConstant(isolate, map, name, value, attributes, flag);
@@ -10142,7 +10031,7 @@ Handle<Map> Map::TransitionToAccessorProperty(Isolate* isolate, Handle<Map> map,
pair = AccessorPair::Copy(isolate, Handle<AccessorPair>::cast(maybe_pair));
} else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
- map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) {
+ map->TooManyFastProperties(StoreOrigin::kNamed)) {
return Map::Normalize(isolate, map, CLEAR_INOBJECT_PROPERTIES,
"TooManyAccessors");
} else {
@@ -10229,7 +10118,7 @@ Handle<DescriptorArray> DescriptorArray::CopyUpToAddAttributes(
// READ_ONLY is an invalid attribute for JS setters/getters.
HeapObject* heap_object;
if (details.kind() != kAccessor ||
- !(value_or_field_type->ToStrongHeapObject(&heap_object) &&
+ !(value_or_field_type->GetHeapObjectIfStrong(&heap_object) &&
heap_object->IsAccessorPair())) {
mask |= READ_ONLY;
}
@@ -10463,11 +10352,6 @@ Handle<FixedArray> ArrayList::Elements(Isolate* isolate,
return result;
}
-bool ArrayList::IsFull() {
- int capacity = length();
- return kFirstIndex + Length() == capacity;
-}
-
namespace {
Handle<FixedArray> EnsureSpaceInFixedArray(Isolate* isolate,
@@ -10501,7 +10385,7 @@ Handle<ArrayList> ArrayList::EnsureSpace(Isolate* isolate,
// static
Handle<WeakArrayList> WeakArrayList::AddToEnd(Isolate* isolate,
Handle<WeakArrayList> array,
- MaybeObjectHandle value) {
+ const MaybeObjectHandle& value) {
int length = array->length();
array = EnsureSpace(isolate, array, length + 1);
// Reload length; GC might have removed elements from the array.
@@ -10532,14 +10416,14 @@ Handle<WeakArrayList> WeakArrayList::EnsureSpace(Isolate* isolate,
int WeakArrayList::CountLiveWeakReferences() const {
int live_weak_references = 0;
for (int i = 0; i < length(); i++) {
- if (Get(i)->IsWeakHeapObject()) {
+ if (Get(i)->IsWeak()) {
++live_weak_references;
}
}
return live_weak_references;
}
-bool WeakArrayList::RemoveOne(MaybeObjectHandle value) {
+bool WeakArrayList::RemoveOne(const MaybeObjectHandle& value) {
if (length() == 0) return false;
// Optimize for the most recently added element to be removed again.
int last_index = length() - 1;
@@ -10585,7 +10469,7 @@ Handle<WeakArrayList> PrototypeUsers::Add(Isolate* isolate,
if (empty_slot != kNoEmptySlotsMarker) {
DCHECK_GE(empty_slot, kFirstIndex);
CHECK_LT(empty_slot, array->length());
- int next_empty_slot = Smi::ToInt(array->Get(empty_slot)->ToSmi());
+ int next_empty_slot = Smi::ToInt(array->Get(empty_slot)->cast<Smi>());
array->Set(empty_slot, HeapObjectReference::Weak(*value));
if (assigned_index != nullptr) *assigned_index = empty_slot;
@@ -10624,11 +10508,13 @@ WeakArrayList* PrototypeUsers::Compact(Handle<WeakArrayList> array, Heap* heap,
int copy_to = kFirstIndex;
for (int i = kFirstIndex; i < array->length(); i++) {
MaybeObject* element = array->Get(i);
- if (element->IsSmi()) continue;
- if (element->IsClearedWeakHeapObject()) continue;
- HeapObject* value = element->ToWeakHeapObject();
- callback(value, i, copy_to);
- new_array->Set(copy_to++, element);
+ HeapObject* value;
+ if (element->GetHeapObjectIfWeak(&value)) {
+ callback(value, i, copy_to);
+ new_array->Set(copy_to++, element);
+ } else {
+ DCHECK(element->IsCleared() || element->IsSmi());
+ }
}
new_array->set_length(copy_to);
set_empty_slot_index(*new_array, kNoEmptySlotsMarker);
@@ -10707,7 +10593,7 @@ Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
// Allocate the array of keys.
Handle<WeakFixedArray> result =
factory->NewWeakFixedArrayWithMap<DescriptorArray>(
- Heap::kDescriptorArrayMapRootIndex, LengthFor(size), pretenure);
+ RootIndex::kDescriptorArrayMap, LengthFor(size), pretenure);
result->Set(kDescriptorLengthIndex,
MaybeObject::FromObject(Smi::FromInt(number_of_descriptors)));
result->Set(kEnumCacheIndex, MaybeObject::FromObject(
@@ -11104,32 +10990,6 @@ std::unique_ptr<char[]> String::ToCString(AllowNullsFlag allow_nulls,
}
-const uc16* String::GetTwoByteData(unsigned start) {
- DCHECK(!IsOneByteRepresentationUnderneath());
- switch (StringShape(this).representation_tag()) {
- case kSeqStringTag:
- return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start);
- case kExternalStringTag:
- return ExternalTwoByteString::cast(this)->
- ExternalTwoByteStringGetData(start);
- case kSlicedStringTag: {
- SlicedString* slice = SlicedString::cast(this);
- return slice->parent()->GetTwoByteData(start + slice->offset());
- }
- case kConsStringTag:
- case kThinStringTag:
- UNREACHABLE();
- }
- UNREACHABLE();
-}
-
-
-const uc16* SeqTwoByteString::SeqTwoByteStringGetData(unsigned start) {
- return reinterpret_cast<uc16*>(
- reinterpret_cast<char*>(this) - kHeapObjectTag + kHeaderSize) + start;
-}
-
-
void Relocatable::PostGarbageCollectionProcessing(Isolate* isolate) {
Relocatable* current = isolate->relocatable_top();
while (current != nullptr) {
@@ -11185,15 +11045,13 @@ FlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str)
PostGarbageCollection();
}
-
FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input)
: Relocatable(isolate),
- str_(0),
+ str_(nullptr),
is_one_byte_(true),
length_(input.length()),
start_(input.start()) {}
-
void FlatStringReader::PostGarbageCollection() {
if (str_ == nullptr) return;
Handle<String> str(str_);
@@ -11638,7 +11496,7 @@ class StringComparator {
};
public:
- inline StringComparator() {}
+ inline StringComparator() = default;
template<typename Chars1, typename Chars2>
static inline bool Equals(State* state_1, State* state_2, int to_check) {
@@ -12838,7 +12696,7 @@ void InvalidatePrototypeChainsInternal(Map* map) {
for (int i = PrototypeUsers::kFirstIndex; i < prototype_users->length();
++i) {
HeapObject* heap_object;
- if (prototype_users->Get(i)->ToWeakHeapObject(&heap_object) &&
+ if (prototype_users->Get(i)->GetHeapObjectIfWeak(&heap_object) &&
heap_object->IsMap()) {
// Walk the prototype chain (backwards, towards leaf objects) if
// necessary.
@@ -13135,9 +12993,14 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case JS_GENERATOR_OBJECT_TYPE:
#ifdef V8_INTL_SUPPORT
case JS_INTL_COLLATOR_TYPE:
+ case JS_INTL_DATE_TIME_FORMAT_TYPE:
case JS_INTL_LIST_FORMAT_TYPE:
+ case JS_INTL_LOCALE_TYPE:
+ case JS_INTL_NUMBER_FORMAT_TYPE:
case JS_INTL_PLURAL_RULES_TYPE:
case JS_INTL_RELATIVE_TIME_FORMAT_TYPE:
+ case JS_INTL_SEGMENTER_TYPE:
+ case JS_INTL_V8_BREAK_ITERATOR_TYPE:
#endif
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
case JS_MAP_TYPE:
@@ -13198,7 +13061,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case FIXED_##TYPE##_ARRAY_TYPE:
#undef TYPED_ARRAY_CASE
-#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE:
+#define MAKE_STRUCT_CASE(TYPE, Name, name) case TYPE:
STRUCT_LIST(MAKE_STRUCT_CASE)
#undef MAKE_STRUCT_CASE
// We must not end up here for these instance types at all.
@@ -13268,6 +13131,8 @@ namespace {
bool FastInitializeDerivedMap(Isolate* isolate, Handle<JSFunction> new_target,
Handle<JSFunction> constructor,
Handle<Map> constructor_initial_map) {
+ // Use the default intrinsic prototype instead.
+ if (!new_target->has_prototype_slot()) return false;
// Check that |function|'s initial map still in sync with the |constructor|,
// otherwise we must create a new initial map for |function|.
if (new_target->has_initial_map() &&
@@ -13342,9 +13207,14 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
Handle<Object> prototype;
if (new_target->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(new_target);
- // Make sure the new.target.prototype is cached.
- EnsureHasInitialMap(function);
- prototype = handle(function->prototype(), isolate);
+ if (function->has_prototype_slot()) {
+ // Make sure the new.target.prototype is cached.
+ EnsureHasInitialMap(function);
+ prototype = handle(function->prototype(), isolate);
+ } else {
+ // No prototype property, use the intrinsict default proto further down.
+ prototype = isolate->factory()->undefined_value();
+ }
} else {
Handle<String> prototype_string = isolate->factory()->prototype_string();
ASSIGN_RETURN_ON_EXCEPTION(
@@ -13384,8 +13254,8 @@ MaybeHandle<Map> JSFunction::GetDerivedMap(Isolate* isolate,
}
int JSFunction::ComputeInstanceSizeWithMinSlack(Isolate* isolate) {
- if (has_prototype_slot() && has_initial_map() &&
- initial_map()->IsInobjectSlackTrackingInProgress()) {
+ CHECK(has_initial_map());
+ if (initial_map()->IsInobjectSlackTrackingInProgress()) {
int slack = initial_map()->ComputeMinObjectSlack(isolate);
return initial_map()->InstanceSizeFromSlack(slack);
}
@@ -13488,64 +13358,16 @@ Handle<String> JSFunction::ToString(Handle<JSFunction> function) {
return NativeCodeFunctionSourceString(shared_info);
}
- if (FLAG_harmony_function_tostring) {
- if (shared_info->function_token_position() == kNoSourcePosition) {
- // If the function token position isn't valid, return [native code] to
- // ensure calling eval on the returned source code throws rather than
- // giving inconsistent call behaviour.
- isolate->CountUsage(v8::Isolate::UseCounterFeature::
- kFunctionTokenOffsetTooLongForToString);
- return NativeCodeFunctionSourceString(shared_info);
- }
- return Handle<String>::cast(
- SharedFunctionInfo::GetSourceCodeHarmony(shared_info));
- }
-
- IncrementalStringBuilder builder(isolate);
- FunctionKind kind = shared_info->kind();
- if (!IsArrowFunction(kind)) {
- if (IsConciseMethod(kind)) {
- if (IsAsyncGeneratorFunction(kind)) {
- builder.AppendCString("async *");
- } else if (IsGeneratorFunction(kind)) {
- builder.AppendCharacter('*');
- } else if (IsAsyncFunction(kind)) {
- builder.AppendCString("async ");
- }
- } else {
- if (IsAsyncGeneratorFunction(kind)) {
- builder.AppendCString("async function* ");
- } else if (IsGeneratorFunction(kind)) {
- builder.AppendCString("function* ");
- } else if (IsAsyncFunction(kind)) {
- builder.AppendCString("async function ");
- } else {
- builder.AppendCString("function ");
- }
- }
- if (shared_info->name_should_print_as_anonymous()) {
- builder.AppendCString("anonymous");
- } else if (!shared_info->is_anonymous_expression()) {
- builder.AppendString(handle(shared_info->Name(), isolate));
- }
- }
- if (shared_info->is_wrapped()) {
- builder.AppendCharacter('(');
- Handle<FixedArray> args(
- Script::cast(shared_info->script())->wrapped_arguments(), isolate);
- int argc = args->length();
- for (int i = 0; i < argc; i++) {
- if (i > 0) builder.AppendCString(", ");
- builder.AppendString(Handle<String>(String::cast(args->get(i)), isolate));
- }
- builder.AppendCString(") {\n");
- }
- builder.AppendString(
- Handle<String>::cast(SharedFunctionInfo::GetSourceCode(shared_info)));
- if (shared_info->is_wrapped()) {
- builder.AppendCString("\n}");
+ if (shared_info->function_token_position() == kNoSourcePosition) {
+ // If the function token position isn't valid, return [native code] to
+ // ensure calling eval on the returned source code throws rather than
+ // giving inconsistent call behaviour.
+ isolate->CountUsage(
+ v8::Isolate::UseCounterFeature::kFunctionTokenOffsetTooLongForToString);
+ return NativeCodeFunctionSourceString(shared_info);
}
- return builder.Finish().ToHandleChecked();
+ return Handle<String>::cast(
+ SharedFunctionInfo::GetSourceCodeHarmony(shared_info));
}
void Oddball::Initialize(Isolate* isolate, Handle<Oddball> oddball,
@@ -13590,7 +13412,8 @@ int Script::GetEvalPosition() {
void Script::InitLineEnds(Handle<Script> script) {
Isolate* isolate = script->GetIsolate();
if (!script->line_ends()->IsUndefined(isolate)) return;
- DCHECK_NE(Script::TYPE_WASM, script->type());
+ DCHECK(script->type() != Script::TYPE_WASM ||
+ script->source_mapping_url()->IsString());
Object* src_obj = script->source();
if (!src_obj->IsString()) {
@@ -13775,7 +13598,7 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
MaybeObject* shared =
shared_function_infos()->Get(fun->function_literal_id());
HeapObject* heap_object;
- if (!shared->ToStrongOrWeakHeapObject(&heap_object) ||
+ if (!shared->GetHeapObject(&heap_object) ||
heap_object->IsUndefined(isolate)) {
return MaybeHandle<SharedFunctionInfo>();
}
@@ -13855,7 +13678,7 @@ SharedFunctionInfo* SharedFunctionInfo::ScriptIterator::Next() {
while (index_ < shared_function_infos_->length()) {
MaybeObject* raw = shared_function_infos_->Get(index_++);
HeapObject* heap_object;
- if (!raw->ToStrongOrWeakHeapObject(&heap_object) ||
+ if (!raw->GetHeapObject(&heap_object) ||
heap_object->IsUndefined(isolate_)) {
continue;
}
@@ -13911,7 +13734,7 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
DCHECK_LT(function_literal_id, list->length());
MaybeObject* maybe_object = list->Get(function_literal_id);
HeapObject* heap_object;
- if (maybe_object->ToWeakHeapObject(&heap_object)) {
+ if (maybe_object->GetHeapObjectIfWeak(&heap_object)) {
DCHECK_EQ(heap_object, *shared);
}
#endif
@@ -13951,7 +13774,7 @@ void SharedFunctionInfo::SetScript(Handle<SharedFunctionInfo> shared,
MaybeObject* raw =
old_script->shared_function_infos()->Get(function_literal_id);
HeapObject* heap_object;
- if (raw->ToWeakHeapObject(&heap_object) && heap_object == *shared) {
+ if (raw->GetHeapObjectIfWeak(&heap_object) && heap_object == *shared) {
old_script->shared_function_infos()->Set(
function_literal_id, HeapObjectReference::Strong(
ReadOnlyRoots(isolate).undefined_value()));
@@ -14323,6 +14146,75 @@ void SharedFunctionInfo::SetFunctionTokenPosition(int function_token_position,
set_raw_function_token_offset(offset);
}
+int SharedFunctionInfo::StartPosition() const {
+ Object* maybe_scope_info = name_or_scope_info();
+ if (maybe_scope_info->IsScopeInfo()) {
+ ScopeInfo* info = ScopeInfo::cast(maybe_scope_info);
+ if (info->HasPositionInfo()) {
+ return info->StartPosition();
+ }
+ } else if (HasUncompiledData()) {
+ // Works with or without scope.
+ return uncompiled_data()->start_position();
+ } else if (IsApiFunction() || HasBuiltinId()) {
+ DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
+ return 0;
+ }
+ return kNoSourcePosition;
+}
+
+int SharedFunctionInfo::EndPosition() const {
+ Object* maybe_scope_info = name_or_scope_info();
+ if (maybe_scope_info->IsScopeInfo()) {
+ ScopeInfo* info = ScopeInfo::cast(maybe_scope_info);
+ if (info->HasPositionInfo()) {
+ return info->EndPosition();
+ }
+ } else if (HasUncompiledData()) {
+ // Works with or without scope.
+ return uncompiled_data()->end_position();
+ } else if (IsApiFunction() || HasBuiltinId()) {
+ DCHECK_IMPLIES(HasBuiltinId(), builtin_id() != Builtins::kCompileLazy);
+ return 0;
+ }
+ return kNoSourcePosition;
+}
+
+int SharedFunctionInfo::FunctionLiteralId(Isolate* isolate) const {
+ // Fast path for the common case when the SFI is uncompiled and so the
+ // function literal id is already in the uncompiled data.
+ if (HasUncompiledData()) {
+ int id = uncompiled_data()->function_literal_id();
+ // Make sure the id is what we should have found with the slow path.
+ DCHECK_EQ(id, FindIndexInScript(isolate));
+ return id;
+ }
+
+ // Otherwise, search for the function in the SFI's script's function list,
+ // and return its index in that list.e
+ return FindIndexInScript(isolate);
+}
+
+void SharedFunctionInfo::SetPosition(int start_position, int end_position) {
+ Object* maybe_scope_info = name_or_scope_info();
+ if (maybe_scope_info->IsScopeInfo()) {
+ ScopeInfo* info = ScopeInfo::cast(maybe_scope_info);
+ if (info->HasPositionInfo()) {
+ info->SetPositionInfo(start_position, end_position);
+ }
+ } else if (HasUncompiledData()) {
+ if (HasUncompiledDataWithPreParsedScope()) {
+ // Clear out preparsed scope data, since the position setter invalidates
+ // any scope data.
+ ClearPreParsedScopeData();
+ }
+ uncompiled_data()->set_start_position(start_position);
+ uncompiled_data()->set_end_position(end_position);
+ } else {
+ UNREACHABLE();
+ }
+}
+
void Map::StartInobjectSlackTracking() {
DCHECK(!IsInobjectSlackTrackingInProgress());
if (UnusedPropertyFields() == 0) return;
@@ -14374,11 +14266,6 @@ void Code::FlushICache() const {
Assembler::FlushICache(raw_instruction_start(), raw_instruction_size());
}
-void Code::CopyFrom(Heap* heap, const CodeDesc& desc) {
- CopyFromNoFlush(heap, desc);
- FlushICache();
-}
-
void Code::CopyFromNoFlush(Heap* heap, const CodeDesc& desc) {
// Copy code.
CopyBytes(reinterpret_cast<byte*>(raw_instruction_start()), desc.buffer,
@@ -14589,7 +14476,7 @@ const char* Code::Kind2String(Kind kind) {
// Identify kind of code.
const char* AbstractCode::Kind2String(Kind kind) {
if (kind < AbstractCode::INTERPRETED_FUNCTION)
- return Code::Kind2String((Code::Kind)kind);
+ return Code::Kind2String(static_cast<Code::Kind>(kind));
if (kind == AbstractCode::INTERPRETED_FUNCTION) return "INTERPRETED_FUNCTION";
UNREACHABLE();
}
@@ -14809,14 +14696,22 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
case Translation::INT32_REGISTER: {
int reg_code = iterator.Next();
- os << "{input=" << converter.NameOfCPURegister(reg_code) << "}";
+ os << "{input=" << converter.NameOfCPURegister(reg_code)
+ << " (int32)}";
+ break;
+ }
+
+ case Translation::INT64_REGISTER: {
+ int reg_code = iterator.Next();
+ os << "{input=" << converter.NameOfCPURegister(reg_code)
+ << " (int64)}";
break;
}
case Translation::UINT32_REGISTER: {
int reg_code = iterator.Next();
os << "{input=" << converter.NameOfCPURegister(reg_code)
- << " (unsigned)}";
+ << " (uint32)}";
break;
}
@@ -14852,13 +14747,19 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
case Translation::INT32_STACK_SLOT: {
int input_slot_index = iterator.Next();
- os << "{input=" << input_slot_index << "}";
+ os << "{input=" << input_slot_index << " (int32)}";
+ break;
+ }
+
+ case Translation::INT64_STACK_SLOT: {
+ int input_slot_index = iterator.Next();
+ os << "{input=" << input_slot_index << " (int64)}";
break;
}
case Translation::UINT32_STACK_SLOT: {
int input_slot_index = iterator.Next();
- os << "{input=" << input_slot_index << " (unsigned)}";
+ os << "{input=" << input_slot_index << " (uint32)}";
break;
}
@@ -15223,7 +15124,8 @@ void DependentCode::SetDependentCode(Handle<HeapObject> object,
}
}
-void DependentCode::InstallDependency(Isolate* isolate, MaybeObjectHandle code,
+void DependentCode::InstallDependency(Isolate* isolate,
+ const MaybeObjectHandle& code,
Handle<HeapObject> object,
DependencyGroup group) {
Handle<DependentCode> old_deps(DependentCode::GetDependentCode(object),
@@ -15237,7 +15139,7 @@ void DependentCode::InstallDependency(Isolate* isolate, MaybeObjectHandle code,
Handle<DependentCode> DependentCode::InsertWeakCode(
Isolate* isolate, Handle<DependentCode> entries, DependencyGroup group,
- MaybeObjectHandle code) {
+ const MaybeObjectHandle& code) {
if (entries->length() == 0 || entries->group() > group) {
// There is no such group.
return DependentCode::New(isolate, group, code, entries);
@@ -15270,7 +15172,7 @@ Handle<DependentCode> DependentCode::InsertWeakCode(
Handle<DependentCode> DependentCode::New(Isolate* isolate,
DependencyGroup group,
- MaybeObjectHandle object,
+ const MaybeObjectHandle& object,
Handle<DependentCode> next) {
Handle<DependentCode> result = Handle<DependentCode>::cast(
isolate->factory()->NewWeakFixedArray(kCodesStartIndex + 1, TENURED));
@@ -15295,7 +15197,7 @@ bool DependentCode::Compact() {
int new_count = 0;
for (int i = 0; i < old_count; i++) {
MaybeObject* obj = object_at(i);
- if (!obj->IsClearedWeakHeapObject()) {
+ if (!obj->IsCleared()) {
if (i != new_count) {
copy(i, new_count);
}
@@ -15309,38 +15211,6 @@ bool DependentCode::Compact() {
return new_count < old_count;
}
-bool DependentCode::Contains(DependencyGroup group, MaybeObject* code) {
- if (this->length() == 0 || this->group() > group) {
- // There is no such group.
- return false;
- }
- if (this->group() < group) {
- // The group comes later in the list.
- return next_link()->Contains(group, code);
- }
- DCHECK_EQ(group, this->group());
- int count = this->count();
- for (int i = 0; i < count; i++) {
- if (object_at(i) == code) return true;
- }
- return false;
-}
-
-
-bool DependentCode::IsEmpty(DependencyGroup group) {
- if (this->length() == 0 || this->group() > group) {
- // There is no such group.
- return true;
- }
- if (this->group() < group) {
- // The group comes later in the list.
- return next_link()->IsEmpty(group);
- }
- DCHECK_EQ(group, this->group());
- return count() == 0;
-}
-
-
bool DependentCode::MarkCodeForDeoptimization(
Isolate* isolate,
DependentCode::DependencyGroup group) {
@@ -15359,8 +15229,8 @@ bool DependentCode::MarkCodeForDeoptimization(
int count = this->count();
for (int i = 0; i < count; i++) {
MaybeObject* obj = object_at(i);
- if (obj->IsClearedWeakHeapObject()) continue;
- Code* code = Code::cast(obj->ToWeakHeapObject());
+ if (obj->IsCleared()) continue;
+ Code* code = Code::cast(obj->GetHeapObjectAssumeWeak());
if (!code->marked_for_deoptimization()) {
code->SetMarkedForDeoptimization(DependencyGroupName(group));
marked = true;
@@ -15974,19 +15844,6 @@ void JSObject::TransitionElementsKind(Handle<JSObject> object,
}
-// static
-bool Map::IsValidElementsTransition(ElementsKind from_kind,
- ElementsKind to_kind) {
- // Transitions can't go backwards.
- if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
- return false;
- }
-
- // Transitions from HOLEY -> PACKED are not allowed.
- return !IsHoleyElementsKind(from_kind) || IsHoleyElementsKind(to_kind);
-}
-
-
bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
Map* map = array->map();
// Fast path: "length" is the first fast property of arrays. Since it's not
@@ -16134,6 +15991,18 @@ bool FixedArrayBase::IsCowArray() const {
}
bool JSObject::IsApiWrapper() {
+ // These object types can carry information relevant for embedders. The
+ // *_API_* types are generated through templates which can have embedder
+ // fields. The other types have their embedder fields added at compile time.
+ auto instance_type = map()->instance_type();
+ return instance_type == JS_API_OBJECT_TYPE ||
+ instance_type == JS_ARRAY_BUFFER_TYPE ||
+ instance_type == JS_DATA_VIEW_TYPE ||
+ instance_type == JS_SPECIAL_API_OBJECT_TYPE ||
+ instance_type == JS_TYPED_ARRAY_TYPE;
+}
+
+bool JSObject::IsDroppableApiWrapper() {
auto instance_type = map()->instance_type();
return instance_type == JS_API_OBJECT_TYPE ||
instance_type == JS_SPECIAL_API_OBJECT_TYPE;
@@ -16141,9 +16010,9 @@ bool JSObject::IsApiWrapper() {
const char* Symbol::PrivateSymbolToName() const {
ReadOnlyRoots roots = GetReadOnlyRoots();
-#define SYMBOL_CHECK_AND_PRINT(name) \
+#define SYMBOL_CHECK_AND_PRINT(_, name) \
if (this == roots.name()) return #name;
- PRIVATE_SYMBOL_LIST(SYMBOL_CHECK_AND_PRINT)
+ PRIVATE_SYMBOL_LIST_GENERATOR(SYMBOL_CHECK_AND_PRINT, /* not used */)
#undef SYMBOL_CHECK_AND_PRINT
return "UNKNOWN";
}
@@ -16754,8 +16623,7 @@ Handle<Derived> HashTable<Derived, Shape>::NewInternal(
Isolate* isolate, int capacity, PretenureFlag pretenure) {
Factory* factory = isolate->factory();
int length = EntryToIndex(capacity);
- Heap::RootListIndex map_root_index =
- static_cast<Heap::RootListIndex>(Shape::GetMapRootIndex());
+ RootIndex map_root_index = Shape::GetMapRootIndex();
Handle<FixedArray> array =
factory->NewFixedArrayWithMap(map_root_index, length, pretenure);
Handle<Derived> table = Handle<Derived>::cast(array);
@@ -17264,7 +17132,7 @@ class StringTableNoAllocateKey : public StringTableKey {
set_hash_field(string->hash_field());
}
- ~StringTableNoAllocateKey() {
+ ~StringTableNoAllocateKey() override {
if (one_byte_) {
if (one_byte_content_ != one_byte_buffer_) delete[] one_byte_content_;
} else {
@@ -17436,18 +17304,6 @@ Handle<ObjectHashSet> ObjectHashSet::Add(Isolate* isolate,
return set;
}
-Handle<Object> CompilationCacheTable::Lookup(Handle<String> src,
- Handle<SharedFunctionInfo> shared,
- LanguageMode language_mode) {
- Isolate* isolate = GetIsolate();
- StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
- int entry = FindEntry(isolate, &key);
- if (entry == kNotFound) return isolate->factory()->undefined_value();
- int index = EntryToIndex(entry);
- if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value();
- return Handle<Object>(get(index + 1), isolate);
-}
-
namespace {
const int kLiteralEntryLength = 2;
@@ -17468,8 +17324,7 @@ int SearchLiteralsMapEntry(CompilationCacheTable* cache, int cache_entry,
WeakFixedArray* literals_map = WeakFixedArray::cast(obj);
int length = literals_map->length();
for (int i = 0; i < length; i += kLiteralEntryLength) {
- DCHECK(literals_map->Get(i + kLiteralContextOffset)
- ->IsWeakOrClearedHeapObject());
+ DCHECK(literals_map->Get(i + kLiteralContextOffset)->IsWeakOrCleared());
if (literals_map->Get(i + kLiteralContextOffset) ==
HeapObjectReference::Weak(native_context)) {
return i;
@@ -17511,8 +17366,7 @@ void AddToFeedbackCellsMap(Handle<CompilationCacheTable> cache, int cache_entry,
DCHECK_LT(entry, 0);
int length = old_literals_map->length();
for (int i = 0; i < length; i += kLiteralEntryLength) {
- if (old_literals_map->Get(i + kLiteralContextOffset)
- ->IsClearedWeakHeapObject()) {
+ if (old_literals_map->Get(i + kLiteralContextOffset)->IsCleared()) {
new_literals_map = old_literals_map;
entry = i;
break;
@@ -17535,11 +17389,11 @@ void AddToFeedbackCellsMap(Handle<CompilationCacheTable> cache, int cache_entry,
#ifdef DEBUG
for (int i = 0; i < new_literals_map->length(); i += kLiteralEntryLength) {
MaybeObject* object = new_literals_map->Get(i + kLiteralContextOffset);
- DCHECK(object->IsClearedWeakHeapObject() ||
- object->ToWeakHeapObject()->IsNativeContext());
+ DCHECK(object->IsCleared() ||
+ object->GetHeapObjectAssumeWeak()->IsNativeContext());
object = new_literals_map->Get(i + kLiteralLiteralsOffset);
- DCHECK(object->IsClearedWeakHeapObject() ||
- object->ToWeakHeapObject()->IsFeedbackCell());
+ DCHECK(object->IsCleared() ||
+ object->GetHeapObjectAssumeWeak()->IsFeedbackCell());
}
#endif
@@ -17559,9 +17413,9 @@ FeedbackCell* SearchLiteralsMap(CompilationCacheTable* cache, int cache_entry,
DCHECK_LE(entry + kLiteralEntryLength, literals_map->length());
MaybeObject* object = literals_map->Get(entry + kLiteralLiteralsOffset);
- result = object->IsClearedWeakHeapObject()
+ result = object->IsCleared()
? nullptr
- : FeedbackCell::cast(object->ToWeakHeapObject());
+ : FeedbackCell::cast(object->GetHeapObjectAssumeWeak());
}
DCHECK(result == nullptr || result->IsFeedbackCell());
return result;
@@ -17618,21 +17472,6 @@ Handle<Object> CompilationCacheTable::LookupRegExp(Handle<String> src,
return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
}
-Handle<CompilationCacheTable> CompilationCacheTable::Put(
- Handle<CompilationCacheTable> cache, Handle<String> src,
- Handle<SharedFunctionInfo> shared, LanguageMode language_mode,
- Handle<Object> value) {
- Isolate* isolate = cache->GetIsolate();
- StringSharedKey key(src, shared, language_mode, kNoSourcePosition);
- Handle<Object> k = key.AsHandle(isolate);
- cache = EnsureCapacity(isolate, cache, 1);
- int entry = cache->FindInsertionEntry(key.Hash());
- cache->set(EntryToIndex(entry), *k);
- cache->set(EntryToIndex(entry) + 1, *value);
- cache->ElementAdded();
- return cache;
-}
-
Handle<CompilationCacheTable> CompilationCacheTable::PutScript(
Handle<CompilationCacheTable> cache, Handle<String> src,
Handle<Context> native_context, LanguageMode language_mode,
@@ -18220,8 +18059,7 @@ Handle<Derived> ObjectHashTableBase<Derived, Shape>::Put(Isolate* isolate,
if (capacity > ObjectHashTable::kMaxCapacity) {
for (size_t i = 0; i < 2; ++i) {
isolate->heap()->CollectAllGarbage(
- Heap::kFinalizeIncrementalMarkingMask,
- GarbageCollectionReason::kFullHashtable);
+ Heap::kNoGCFlags, GarbageCollectionReason::kFullHashtable);
}
table->Rehash(isolate);
}
@@ -18390,8 +18228,10 @@ MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor,
Handle<JSReceiver> new_target, double tv) {
Isolate* const isolate = constructor->GetIsolate();
Handle<JSObject> result;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
- JSObject::New(constructor, new_target), JSDate);
+ ASSIGN_RETURN_ON_EXCEPTION(
+ isolate, result,
+ JSObject::New(constructor, new_target, Handle<AllocationSite>::null()),
+ JSDate);
if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) {
tv = DoubleToInteger(tv) + 0.0;
} else {
@@ -18818,6 +18658,82 @@ MaybeHandle<Name> FunctionTemplateInfo::TryGetCachedPropertyName(
return MaybeHandle<Name>();
}
+Smi* Smi::LexicographicCompare(Isolate* isolate, Smi* x, Smi* y) {
+ DisallowHeapAllocation no_allocation;
+ DisallowJavascriptExecution no_js(isolate);
+
+ int x_value = Smi::ToInt(x);
+ int y_value = Smi::ToInt(y);
+
+ // If the integers are equal so are the string representations.
+ if (x_value == y_value) return Smi::FromInt(0);
+
+ // If one of the integers is zero the normal integer order is the
+ // same as the lexicographic order of the string representations.
+ if (x_value == 0 || y_value == 0)
+ return Smi::FromInt(x_value < y_value ? -1 : 1);
+
+ // If only one of the integers is negative the negative number is
+ // smallest because the char code of '-' is less than the char code
+ // of any digit. Otherwise, we make both values positive.
+
+ // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
+ // architectures using 32-bit Smis.
+ uint32_t x_scaled = x_value;
+ uint32_t y_scaled = y_value;
+ if (x_value < 0 || y_value < 0) {
+ if (y_value >= 0) return Smi::FromInt(-1);
+ if (x_value >= 0) return Smi::FromInt(1);
+ x_scaled = -x_value;
+ y_scaled = -y_value;
+ }
+
+ // clang-format off
+ static const uint32_t kPowersOf10[] = {
+ 1, 10, 100, 1000,
+ 10 * 1000, 100 * 1000, 1000 * 1000, 10 * 1000 * 1000,
+ 100 * 1000 * 1000, 1000 * 1000 * 1000};
+ // clang-format on
+
+ // If the integers have the same number of decimal digits they can be
+ // compared directly as the numeric order is the same as the
+ // lexicographic order. If one integer has fewer digits, it is scaled
+ // by some power of 10 to have the same number of digits as the longer
+ // integer. If the scaled integers are equal it means the shorter
+ // integer comes first in the lexicographic order.
+
+ // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ int x_log2 = 31 - base::bits::CountLeadingZeros(x_scaled);
+ int x_log10 = ((x_log2 + 1) * 1233) >> 12;
+ x_log10 -= x_scaled < kPowersOf10[x_log10];
+
+ int y_log2 = 31 - base::bits::CountLeadingZeros(y_scaled);
+ int y_log10 = ((y_log2 + 1) * 1233) >> 12;
+ y_log10 -= y_scaled < kPowersOf10[y_log10];
+
+ int tie = 0;
+
+ if (x_log10 < y_log10) {
+ // X has fewer digits. We would like to simply scale up X but that
+ // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
+ // be scaled up to 9_000_000_000. So we scale up by the next
+ // smallest power and scale down Y to drop one digit. It is OK to
+ // drop one digit from the longer integer since the final digit is
+ // past the length of the shorter integer.
+ x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
+ y_scaled /= 10;
+ tie = -1;
+ } else if (y_log10 < x_log10) {
+ y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
+ x_scaled /= 10;
+ tie = 1;
+ }
+
+ if (x_scaled < y_scaled) return Smi::FromInt(-1);
+ if (x_scaled > y_scaled) return Smi::FromInt(1);
+ return Smi::FromInt(tie);
+}
+
// Force instantiation of template instances class.
// Please note this list is compiler dependent.
// Keep this at the end of this file