diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/v8/src/runtime | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/v8/src/runtime')
23 files changed, 1335 insertions, 1226 deletions
diff --git a/chromium/v8/src/runtime/runtime-array.cc b/chromium/v8/src/runtime/runtime-array.cc index 781065a371b..cc73f59524a 100644 --- a/chromium/v8/src/runtime/runtime-array.cc +++ b/chromium/v8/src/runtime/runtime-array.cc @@ -17,58 +17,6 @@ namespace v8 { namespace internal { -static void InstallCode( - Isolate* isolate, Handle<JSObject> holder, const char* name, - Handle<Code> code, int argc = -1, - BuiltinFunctionId id = static_cast<BuiltinFunctionId>(-1)) { - Handle<String> key = isolate->factory()->InternalizeUtf8String(name); - Handle<JSFunction> optimized = - isolate->factory()->NewFunctionWithoutPrototype(key, code, true); - if (argc < 0) { - optimized->shared()->DontAdaptArguments(); - } else { - optimized->shared()->set_internal_formal_parameter_count(argc); - } - if (id >= 0) { - optimized->shared()->set_builtin_function_id(id); - } - optimized->shared()->set_language_mode(STRICT); - optimized->shared()->set_native(true); - JSObject::AddProperty(holder, key, optimized, NONE); -} - -static void InstallBuiltin( - Isolate* isolate, Handle<JSObject> holder, const char* name, - Builtins::Name builtin_name, int argc = -1, - BuiltinFunctionId id = static_cast<BuiltinFunctionId>(-1)) { - InstallCode(isolate, holder, name, - handle(isolate->builtins()->builtin(builtin_name), isolate), argc, - id); -} - -RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { - HandleScope scope(isolate); - DCHECK_EQ(0, args.length()); - Handle<JSObject> holder = - isolate->factory()->NewJSObject(isolate->object_function()); - - InstallBuiltin(isolate, holder, "pop", Builtins::kFastArrayPop); - InstallBuiltin(isolate, holder, "push", Builtins::kFastArrayPush); - InstallBuiltin(isolate, holder, "shift", Builtins::kFastArrayShift); - InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift); - InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice); - InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice); - InstallBuiltin(isolate, holder, "includes", Builtins::kArrayIncludes); - InstallBuiltin(isolate, holder, "indexOf", Builtins::kArrayIndexOf); - InstallBuiltin(isolate, holder, "keys", Builtins::kArrayPrototypeKeys, 0, - kArrayKeys); - InstallBuiltin(isolate, holder, "values", Builtins::kArrayPrototypeValues, 0, - kArrayValues); - InstallBuiltin(isolate, holder, "entries", Builtins::kArrayPrototypeEntries, - 0, kArrayEntries); - return *holder; -} - RUNTIME_FUNCTION(Runtime_FixedArrayGet) { SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); @@ -99,6 +47,235 @@ RUNTIME_FUNCTION(Runtime_TransitionElementsKind) { return *object; } +namespace { +// As PrepareElementsForSort, but only on objects where elements is +// a dictionary, and it will stay a dictionary. Collates undefined and +// unexisting elements below limit from position zero of the elements. +Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object, + uint32_t limit) { + DCHECK(object->HasDictionaryElements()); + Isolate* isolate = object->GetIsolate(); + // Must stay in dictionary mode, either because of requires_slow_elements, + // or because we are not going to sort (and therefore compact) all of the + // elements. + Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); + Handle<SeededNumberDictionary> new_dict = + SeededNumberDictionary::New(isolate, dict->NumberOfElements()); + + uint32_t pos = 0; + uint32_t undefs = 0; + uint32_t max_key = 0; + int capacity = dict->Capacity(); + Handle<Smi> bailout(Smi::FromInt(-1), isolate); + // Entry to the new dictionary does not cause it to grow, as we have + // allocated one that is large enough for all entries. + DisallowHeapAllocation no_gc; + for (int i = 0; i < capacity; i++) { + Object* k; + if (!dict->ToKey(isolate, i, &k)) continue; + + DCHECK_LE(0, k->Number()); + DCHECK_LE(k->Number(), kMaxUInt32); + + HandleScope scope(isolate); + Handle<Object> value(dict->ValueAt(i), isolate); + PropertyDetails details = dict->DetailsAt(i); + if (details.kind() == kAccessor || details.IsReadOnly()) { + // Bail out and do the sorting of undefineds and array holes in JS. + // Also bail out if the element is not supposed to be moved. + return bailout; + } + + uint32_t key = NumberToUint32(k); + if (key < limit) { + if (value->IsUndefined(isolate)) { + undefs++; + } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { + // Adding an entry with the key beyond smi-range requires + // allocation. Bailout. + return bailout; + } else { + Handle<Object> result = + SeededNumberDictionary::Add(new_dict, pos, value, details); + DCHECK(result.is_identical_to(new_dict)); + USE(result); + pos++; + } + } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) { + // Adding an entry with the key beyond smi-range requires + // allocation. Bailout. + return bailout; + } else { + Handle<Object> result = + SeededNumberDictionary::Add(new_dict, key, value, details); + DCHECK(result.is_identical_to(new_dict)); + USE(result); + max_key = Max(max_key, key); + } + } + + uint32_t result = pos; + PropertyDetails no_details = PropertyDetails::Empty(); + while (undefs > 0) { + if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { + // Adding an entry with the key beyond smi-range requires + // allocation. Bailout. + return bailout; + } + HandleScope scope(isolate); + Handle<Object> result = SeededNumberDictionary::Add( + new_dict, pos, isolate->factory()->undefined_value(), no_details); + DCHECK(result.is_identical_to(new_dict)); + USE(result); + pos++; + undefs--; + } + max_key = Max(max_key, pos - 1); + + object->set_elements(*new_dict); + new_dict->UpdateMaxNumberKey(max_key, object); + JSObject::ValidateElements(*object); + + AllowHeapAllocation allocate_return_value; + return isolate->factory()->NewNumberFromUint(result); +} + +// Collects all defined (non-hole) and non-undefined (array) elements at the +// start of the elements array. If the object is in dictionary mode, it is +// converted to fast elements mode. Undefined values are placed after +// non-undefined values. Returns the number of non-undefined values. +Handle<Object> PrepareElementsForSort(Handle<JSObject> object, uint32_t limit) { + Isolate* isolate = object->GetIsolate(); + if (object->HasSloppyArgumentsElements() || !object->map()->is_extensible()) { + return handle(Smi::FromInt(-1), isolate); + } + + if (object->HasStringWrapperElements()) { + int len = String::cast(Handle<JSValue>::cast(object)->value())->length(); + return handle(Smi::FromInt(len), isolate); + } + + JSObject::ValidateElements(*object); + if (object->HasDictionaryElements()) { + // Convert to fast elements containing only the existing properties. + // Ordering is irrelevant, since we are going to sort anyway. + Handle<SeededNumberDictionary> dict(object->element_dictionary()); + if (object->IsJSArray() || dict->requires_slow_elements() || + dict->max_number_key() >= limit) { + return PrepareSlowElementsForSort(object, limit); + } + // Convert to fast elements. + Handle<Map> new_map = + JSObject::GetElementsTransitionMap(object, HOLEY_ELEMENTS); + + PretenureFlag tenure = + isolate->heap()->InNewSpace(*object) ? NOT_TENURED : TENURED; + Handle<FixedArray> fast_elements = + isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); + dict->CopyValuesTo(*fast_elements); + + JSObject::SetMapAndElements(object, new_map, fast_elements); + JSObject::ValidateElements(*object); + } else if (object->HasFixedTypedArrayElements()) { + // Typed arrays cannot have holes or undefined elements. + return handle( + Smi::FromInt(FixedArrayBase::cast(object->elements())->length()), + isolate); + } else if (!object->HasDoubleElements()) { + JSObject::EnsureWritableFastElements(object); + } + DCHECK(object->HasSmiOrObjectElements() || object->HasDoubleElements()); + + // Collect holes at the end, undefined before that and the rest at the + // start, and return the number of non-hole, non-undefined values. + + Handle<FixedArrayBase> elements_base(object->elements()); + uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); + if (limit > elements_length) { + limit = elements_length; + } + if (limit == 0) { + return handle(Smi::kZero, isolate); + } + + uint32_t result = 0; + if (elements_base->map() == isolate->heap()->fixed_double_array_map()) { + FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base); + // Split elements into defined and the_hole, in that order. + unsigned int holes = limit; + // Assume most arrays contain no holes and undefined values, so minimize the + // number of stores of non-undefined, non-the-hole values. + for (unsigned int i = 0; i < holes; i++) { + if (elements->is_the_hole(i)) { + holes--; + } else { + continue; + } + // Position i needs to be filled. + while (holes > i) { + if (elements->is_the_hole(holes)) { + holes--; + } else { + elements->set(i, elements->get_scalar(holes)); + break; + } + } + } + result = holes; + while (holes < limit) { + elements->set_the_hole(holes); + holes++; + } + } else { + FixedArray* elements = FixedArray::cast(*elements_base); + DisallowHeapAllocation no_gc; + + // Split elements into defined, undefined and the_hole, in that order. Only + // count locations for undefined and the hole, and fill them afterwards. + WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc); + unsigned int undefs = limit; + unsigned int holes = limit; + // Assume most arrays contain no holes and undefined values, so minimize the + // number of stores of non-undefined, non-the-hole values. + for (unsigned int i = 0; i < undefs; i++) { + Object* current = elements->get(i); + if (current->IsTheHole(isolate)) { + holes--; + undefs--; + } else if (current->IsUndefined(isolate)) { + undefs--; + } else { + continue; + } + // Position i needs to be filled. + while (undefs > i) { + current = elements->get(undefs); + if (current->IsTheHole(isolate)) { + holes--; + undefs--; + } else if (current->IsUndefined(isolate)) { + undefs--; + } else { + elements->set(i, current, write_barrier); + break; + } + } + } + result = undefs; + while (undefs < holes) { + elements->set_undefined(isolate, undefs); + undefs++; + } + while (holes < limit) { + elements->set_the_hole(isolate, holes); + holes++; + } + } + + return isolate->factory()->NewNumberFromUint(result); +} + +} // namespace // Moves all own elements of an object, that are below a limit, to positions // starting at zero. All undefined values are placed after non-undefined values, @@ -112,8 +289,7 @@ RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) { CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); if (object->IsJSProxy()) return Smi::FromInt(-1); - return *JSObject::PrepareElementsForSort(Handle<JSObject>::cast(object), - limit); + return *PrepareElementsForSort(Handle<JSObject>::cast(object), limit); } @@ -123,8 +299,8 @@ RUNTIME_FUNCTION(Runtime_MoveArrayContents) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0); CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1); - JSObject::ValidateElements(from); - JSObject::ValidateElements(to); + JSObject::ValidateElements(*from); + JSObject::ValidateElements(*to); Handle<FixedArrayBase> new_elements(from->elements()); ElementsKind from_kind = from->GetElementsKind(); @@ -132,10 +308,10 @@ RUNTIME_FUNCTION(Runtime_MoveArrayContents) { JSObject::SetMapAndElements(to, new_map, new_elements); to->set_length(from->length()); - JSObject::ResetElements(from); + from->initialize_elements(); from->set_length(Smi::kZero); - JSObject::ValidateElements(to); + JSObject::ValidateElements(*to); return *to; } @@ -236,13 +412,20 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) { return *isolate->factory()->NewJSArrayWithElements(keys); } +RUNTIME_FUNCTION(Runtime_NewArray) { + HandleScope scope(isolate); + DCHECK_LE(3, args.length()); + int const argc = args.length() - 3; + // TODO(bmeurer): Remove this Arguments nonsense. + Arguments argv(argc, args.arguments() - 1); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, argc + 1); + CONVERT_ARG_HANDLE_CHECKED(HeapObject, type_info, argc + 2); + // TODO(bmeurer): Use MaybeHandle to pass around the AllocationSite. + Handle<AllocationSite> site = type_info->IsAllocationSite() + ? Handle<AllocationSite>::cast(type_info) + : Handle<AllocationSite>::null(); -namespace { - -Object* ArrayConstructorCommon(Isolate* isolate, Handle<JSFunction> constructor, - Handle<JSReceiver> new_target, - Handle<AllocationSite> site, - Arguments* caller_args) { Factory* factory = isolate->factory(); // If called through new, new.target can be: @@ -256,8 +439,8 @@ Object* ArrayConstructorCommon(Isolate* isolate, Handle<JSFunction> constructor, bool holey = false; bool can_use_type_feedback = !site.is_null(); bool can_inline_array_constructor = true; - if (caller_args->length() == 1) { - Handle<Object> argument_one = caller_args->at<Object>(0); + if (argv.length() == 1) { + Handle<Object> argument_one = argv.at<Object>(0); if (argument_one->IsSmi()) { int value = Handle<Smi>::cast(argument_one)->value(); if (value < 0 || @@ -283,7 +466,7 @@ Object* ArrayConstructorCommon(Isolate* isolate, Handle<JSFunction> constructor, ElementsKind to_kind = can_use_type_feedback ? site->GetElementsKind() : initial_map->elements_kind(); - if (holey && !IsFastHoleyElementsKind(to_kind)) { + if (holey && !IsHoleyElementsKind(to_kind)) { to_kind = GetHoleyElementsKind(to_kind); // Update the allocation site info to reflect the advice alteration. if (!site.is_null()) site->SetElementsKind(to_kind); @@ -299,7 +482,7 @@ Object* ArrayConstructorCommon(Isolate* isolate, Handle<JSFunction> constructor, // If we don't care to track arrays of to_kind ElementsKind, then // don't emit a memento for them. Handle<AllocationSite> allocation_site; - if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) { + if (AllocationSite::ShouldTrack(to_kind)) { allocation_site = site; } @@ -309,8 +492,8 @@ Object* ArrayConstructorCommon(Isolate* isolate, Handle<JSFunction> constructor, factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS); ElementsKind old_kind = array->GetElementsKind(); - RETURN_FAILURE_ON_EXCEPTION( - isolate, ArrayConstructInitializeElements(array, caller_args)); + RETURN_FAILURE_ON_EXCEPTION(isolate, + ArrayConstructInitializeElements(array, &argv)); if (!site.is_null() && (old_kind != array->GetElementsKind() || !can_use_type_feedback || !can_inline_array_constructor)) { @@ -323,24 +506,6 @@ Object* ArrayConstructorCommon(Isolate* isolate, Handle<JSFunction> constructor, return *array; } -} // namespace - -RUNTIME_FUNCTION(Runtime_NewArray) { - HandleScope scope(isolate); - DCHECK_LE(3, args.length()); - int const argc = args.length() - 3; - // TODO(bmeurer): Remove this Arguments nonsense. - Arguments argv(argc, args.arguments() - 1); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, new_target, argc + 1); - CONVERT_ARG_HANDLE_CHECKED(HeapObject, type_info, argc + 2); - // TODO(bmeurer): Use MaybeHandle to pass around the AllocationSite. - Handle<AllocationSite> site = type_info->IsAllocationSite() - ? Handle<AllocationSite>::cast(type_info) - : Handle<AllocationSite>::null(); - return ArrayConstructorCommon(isolate, constructor, new_target, site, &argv); -} - RUNTIME_FUNCTION(Runtime_NormalizeElements) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -467,7 +632,7 @@ RUNTIME_FUNCTION(Runtime_ArrayIncludes_Slow) { Object::ToInteger(isolate, from_index)); if (V8_LIKELY(from_index->IsSmi())) { - int start_from = Smi::cast(*from_index)->value(); + int start_from = Smi::ToInt(*from_index); if (start_from < 0) { index = std::max<int64_t>(len + start_from, 0); } else { @@ -610,9 +775,9 @@ RUNTIME_FUNCTION(Runtime_ArrayIndexOf) { LookupIterator it = LookupIterator::PropertyOrElement( isolate, object, index_obj, &success); DCHECK(success); - if (!JSReceiver::HasProperty(&it).FromJust()) { - continue; - } + Maybe<bool> present = JSReceiver::HasProperty(&it); + MAYBE_RETURN(present, isolate->heap()->exception()); + if (!present.FromJust()) continue; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, element_k, Object::GetProperty(&it)); if (search_element->StrictEquals(*element_k)) { @@ -641,33 +806,5 @@ RUNTIME_FUNCTION(Runtime_SpreadIterablePrepare) { return *spread; } -RUNTIME_FUNCTION(Runtime_SpreadIterableFixed) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, spread, 0); - - // The caller should check if proper iteration is necessary. - Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, spread, - Execution::Call(isolate, spread_iterable_function, - isolate->factory()->undefined_value(), 1, &spread)); - - // Create a new FixedArray and put the result of the spread into it. - Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); - uint32_t spread_length; - CHECK(spread_array->length()->ToArrayIndex(&spread_length)); - - Handle<FixedArray> result = isolate->factory()->NewFixedArray(spread_length); - ElementsAccessor* accessor = spread_array->GetElementsAccessor(); - for (uint32_t i = 0; i < spread_length; i++) { - DCHECK(accessor->HasElement(*spread_array, i)); - Handle<Object> element = accessor->Get(spread_array, i); - result->set(i, *element); - } - - return *result; -} - } // namespace internal } // namespace v8 diff --git a/chromium/v8/src/runtime/runtime-atomics.cc b/chromium/v8/src/runtime/runtime-atomics.cc index 62986c66618..68a7b413b5a 100644 --- a/chromium/v8/src/runtime/runtime-atomics.cc +++ b/chromium/v8/src/runtime/runtime-atomics.cc @@ -298,7 +298,6 @@ RUNTIME_FUNCTION(Runtime_AtomicsExchange) { } UNREACHABLE(); - return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { @@ -327,7 +326,6 @@ RUNTIME_FUNCTION(Runtime_AtomicsCompareExchange) { } UNREACHABLE(); - return isolate->heap()->undefined_value(); } // ES #sec-atomics.add @@ -357,7 +355,6 @@ RUNTIME_FUNCTION(Runtime_AtomicsAdd) { } UNREACHABLE(); - return isolate->heap()->undefined_value(); } // ES #sec-atomics.sub @@ -387,7 +384,6 @@ RUNTIME_FUNCTION(Runtime_AtomicsSub) { } UNREACHABLE(); - return isolate->heap()->undefined_value(); } // ES #sec-atomics.and @@ -417,7 +413,6 @@ RUNTIME_FUNCTION(Runtime_AtomicsAnd) { } UNREACHABLE(); - return isolate->heap()->undefined_value(); } // ES #sec-atomics.or @@ -447,7 +442,6 @@ RUNTIME_FUNCTION(Runtime_AtomicsOr) { } UNREACHABLE(); - return isolate->heap()->undefined_value(); } // ES #sec-atomics.xor @@ -477,7 +471,6 @@ RUNTIME_FUNCTION(Runtime_AtomicsXor) { } UNREACHABLE(); - return isolate->heap()->undefined_value(); } } // namespace internal diff --git a/chromium/v8/src/runtime/runtime-classes.cc b/chromium/v8/src/runtime/runtime-classes.cc index feb01200455..bd7f154e502 100644 --- a/chromium/v8/src/runtime/runtime-classes.cc +++ b/chromium/v8/src/runtime/runtime-classes.cc @@ -32,7 +32,7 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructorNonCallableError) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); - Handle<Object> name(constructor->shared()->name(), isolate); + Handle<String> name(constructor->shared()->name(), isolate); THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kConstructorNonCallable, name)); } @@ -63,7 +63,7 @@ namespace { Object* ThrowNotSuperConstructor(Isolate* isolate, Handle<Object> constructor, Handle<JSFunction> function) { - Handle<Object> super_name; + Handle<String> super_name; if (constructor->IsJSFunction()) { super_name = handle(Handle<JSFunction>::cast(constructor)->shared()->name(), isolate); @@ -74,12 +74,12 @@ Object* ThrowNotSuperConstructor(Isolate* isolate, Handle<Object> constructor, super_name = Object::NoSideEffectsToString(isolate, constructor); } // null constructor - if (Handle<String>::cast(super_name)->length() == 0) { + if (super_name->length() == 0) { super_name = isolate->factory()->null_string(); } - Handle<Object> function_name(function->shared()->name(), isolate); + Handle<String> function_name(function->shared()->name(), isolate); // anonymous class - if (Handle<String>::cast(function_name)->length() == 0) { + if (function_name->length() == 0) { THROW_NEW_ERROR_RETURN_FAILURE( isolate, NewTypeError(MessageTemplate::kNotSuperConstructorAnonymousClass, diff --git a/chromium/v8/src/runtime/runtime-collections.cc b/chromium/v8/src/runtime/runtime-collections.cc index 0e311517e93..deea56fb87a 100644 --- a/chromium/v8/src/runtime/runtime-collections.cc +++ b/chromium/v8/src/runtime/runtime-collections.cc @@ -75,68 +75,14 @@ RUNTIME_FUNCTION(Runtime_SetShrink) { return isolate->heap()->undefined_value(); } - -RUNTIME_FUNCTION(Runtime_SetClear) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); - JSSet::Clear(holder); - return isolate->heap()->undefined_value(); -} - - -RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); - CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1); - CONVERT_SMI_ARG_CHECKED(kind, 2) - CHECK(kind == JSSetIterator::kKindValues || - kind == JSSetIterator::kKindEntries); - Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table())); - holder->set_table(*table); - holder->set_index(Smi::kZero); - holder->set_kind(Smi::FromInt(kind)); - return isolate->heap()->undefined_value(); -} - - RUNTIME_FUNCTION(Runtime_SetIteratorClone) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); - - Handle<JSSetIterator> result = isolate->factory()->NewJSSetIterator(); - result->set_table(holder->table()); - result->set_index(Smi::FromInt(Smi::cast(holder->index())->value())); - result->set_kind(Smi::FromInt(Smi::cast(holder->kind())->value())); - - return *result; -} - - -RUNTIME_FUNCTION(Runtime_SetIteratorNext) { - SealHandleScope shs(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_CHECKED(JSSetIterator, holder, 0); - CONVERT_ARG_CHECKED(JSArray, value_array, 1); - return holder->Next(value_array); -} - - -// The array returned contains the following information: -// 0: HasMore flag -// 1: Iteration index -// 2: Iteration kind -RUNTIME_FUNCTION(Runtime_SetIteratorDetails) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0); - Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); - details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); - details->set(1, holder->index()); - details->set(2, holder->kind()); - return *isolate->factory()->NewJSArrayWithElements(details); + return *isolate->factory()->NewJSSetIterator( + handle(holder->map(), isolate), + handle(OrderedHashSet::cast(holder->table()), isolate), + Smi::ToInt(holder->index())); } @@ -159,16 +105,6 @@ RUNTIME_FUNCTION(Runtime_MapShrink) { return isolate->heap()->undefined_value(); } - -RUNTIME_FUNCTION(Runtime_MapClear) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0); - JSMap::Clear(holder); - return isolate->heap()->undefined_value(); -} - - RUNTIME_FUNCTION(Runtime_MapGrow) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -179,54 +115,16 @@ RUNTIME_FUNCTION(Runtime_MapGrow) { return isolate->heap()->undefined_value(); } - -RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); - CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1); - CONVERT_SMI_ARG_CHECKED(kind, 2) - CHECK(kind == JSMapIterator::kKindKeys || - kind == JSMapIterator::kKindValues || - kind == JSMapIterator::kKindEntries); - Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table())); - holder->set_table(*table); - holder->set_index(Smi::kZero); - holder->set_kind(Smi::FromInt(kind)); - return isolate->heap()->undefined_value(); -} - - RUNTIME_FUNCTION(Runtime_MapIteratorClone) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); - - Handle<JSMapIterator> result = isolate->factory()->NewJSMapIterator(); - result->set_table(holder->table()); - result->set_index(Smi::FromInt(Smi::cast(holder->index())->value())); - result->set_kind(Smi::FromInt(Smi::cast(holder->kind())->value())); - - return *result; + return *isolate->factory()->NewJSMapIterator( + handle(holder->map(), isolate), + handle(OrderedHashMap::cast(holder->table()), isolate), + Smi::ToInt(holder->index())); } - -// The array returned contains the following information: -// 0: HasMore flag -// 1: Iteration index -// 2: Iteration kind -RUNTIME_FUNCTION(Runtime_MapIteratorDetails) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0); - Handle<FixedArray> details = isolate->factory()->NewFixedArray(4); - details->set(0, isolate->heap()->ToBoolean(holder->HasMore())); - details->set(1, holder->index()); - details->set(2, holder->kind()); - return *isolate->factory()->NewJSArrayWithElements(details); -} - - RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -236,16 +134,6 @@ RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { return *JSWeakCollection::GetEntries(holder, max_entries); } - -RUNTIME_FUNCTION(Runtime_MapIteratorNext) { - SealHandleScope shs(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_CHECKED(JSMapIterator, holder, 0); - CONVERT_ARG_CHECKED(JSArray, value_array, 1); - return holder->Next(value_array); -} - - RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -255,37 +143,6 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) { } -RUNTIME_FUNCTION(Runtime_WeakCollectionGet) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); - CONVERT_SMI_ARG_CHECKED(hash, 2) - CHECK(key->IsJSReceiver() || key->IsSymbol()); - Handle<ObjectHashTable> table( - ObjectHashTable::cast(weak_collection->table())); - CHECK(table->IsKey(isolate, *key)); - Handle<Object> lookup(table->Lookup(key, hash), isolate); - return lookup->IsTheHole(isolate) ? isolate->heap()->undefined_value() - : *lookup; -} - - -RUNTIME_FUNCTION(Runtime_WeakCollectionHas) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); - CONVERT_SMI_ARG_CHECKED(hash, 2) - CHECK(key->IsJSReceiver() || key->IsSymbol()); - Handle<ObjectHashTable> table( - ObjectHashTable::cast(weak_collection->table())); - CHECK(table->IsKey(isolate, *key)); - Handle<Object> lookup(table->Lookup(key, hash), isolate); - return isolate->heap()->ToBoolean(!lookup->IsTheHole(isolate)); -} - - RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); @@ -340,20 +197,6 @@ RUNTIME_FUNCTION(Runtime_IsJSSet) { return isolate->heap()->ToBoolean(obj->IsJSSet()); } -RUNTIME_FUNCTION(Runtime_IsJSMapIterator) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, obj, 0); - return isolate->heap()->ToBoolean(obj->IsJSMapIterator()); -} - -RUNTIME_FUNCTION(Runtime_IsJSSetIterator) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, obj, 0); - return isolate->heap()->ToBoolean(obj->IsJSSetIterator()); -} - RUNTIME_FUNCTION(Runtime_IsJSWeakMap) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); diff --git a/chromium/v8/src/runtime/runtime-compiler.cc b/chromium/v8/src/runtime/runtime-compiler.cc index 7b73967acc0..6cd8541585e 100644 --- a/chromium/v8/src/runtime/runtime-compiler.cc +++ b/chromium/v8/src/runtime/runtime-compiler.cc @@ -33,7 +33,9 @@ RUNTIME_FUNCTION(Runtime_CompileLazy) { #endif StackLimitCheck check(isolate); - if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); + if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) { + return isolate->StackOverflow(); + } if (!Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) { return isolate->heap()->exception(); } @@ -46,8 +48,10 @@ RUNTIME_FUNCTION(Runtime_CompileOptimized_Concurrent) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); StackLimitCheck check(isolate); - if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); - if (!Compiler::CompileOptimized(function, Compiler::CONCURRENT)) { + if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) { + return isolate->StackOverflow(); + } + if (!Compiler::CompileOptimized(function, ConcurrencyMode::kConcurrent)) { return isolate->heap()->exception(); } DCHECK(function->is_compiled()); @@ -60,8 +64,10 @@ RUNTIME_FUNCTION(Runtime_CompileOptimized_NotConcurrent) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); StackLimitCheck check(isolate); - if (check.JsHasOverflowed(1 * KB)) return isolate->StackOverflow(); - if (!Compiler::CompileOptimized(function, Compiler::NOT_CONCURRENT)) { + if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) { + return isolate->StackOverflow(); + } + if (!Compiler::CompileOptimized(function, ConcurrencyMode::kNotConcurrent)) { return isolate->heap()->exception(); } DCHECK(function->is_compiled()); @@ -73,7 +79,8 @@ RUNTIME_FUNCTION(Runtime_EvictOptimizedCodeSlot) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - DCHECK(function->is_compiled()); + DCHECK(function->shared()->is_compiled()); + function->feedback_vector()->EvictOptimizedCodeMarkedForDeoptimization( function->shared(), "Runtime_EvictOptimizedCodeSlot"); return function->code(); @@ -88,9 +95,9 @@ RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) { if (args[1]->IsJSReceiver()) { stdlib = args.at<JSReceiver>(1); } - Handle<JSObject> foreign; - if (args[2]->IsJSObject()) { - foreign = args.at<JSObject>(2); + Handle<JSReceiver> foreign; + if (args[2]->IsJSReceiver()) { + foreign = args.at<JSReceiver>(2); } Handle<JSArrayBuffer> memory; if (args[3]->IsJSArrayBuffer()) { @@ -168,22 +175,13 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { Handle<Code> optimized_code = deoptimizer->compiled_code(); DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION); + DCHECK(optimized_code->is_turbofanned()); DCHECK(type == deoptimizer->bailout_type()); DCHECK_NULL(isolate->context()); - // TODO(turbofan): For Crankshaft we restore the context before objects are - // being materialized, because it never de-materializes the context but it - // requires a context to materialize arguments objects. This is specific to - // Crankshaft and can be removed once only TurboFan goes through here. - if (!optimized_code->is_turbofanned()) { - JavaScriptFrameIterator top_it(isolate); - JavaScriptFrame* top_frame = top_it.frame(); - isolate->set_context(Context::cast(top_frame->context())); - } else { - // TODO(turbofan): We currently need the native context to materialize - // the arguments object, but only to get to its map. - isolate->set_context(function->native_context()); - } + // TODO(turbofan): We currently need the native context to materialize + // the arguments object, but only to get to its map. + isolate->set_context(function->native_context()); // Make sure to materialize objects before causing any allocation. JavaScriptFrameIterator it(isolate); @@ -191,11 +189,9 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { delete deoptimizer; // Ensure the context register is updated for materialized objects. - if (optimized_code->is_turbofanned()) { - JavaScriptFrameIterator top_it(isolate); - JavaScriptFrame* top_frame = top_it.frame(); - isolate->set_context(Context::cast(top_frame->context())); - } + JavaScriptFrameIterator top_it(isolate); + JavaScriptFrame* top_frame = top_it.frame(); + isolate->set_context(Context::cast(top_frame->context())); if (type == Deoptimizer::LAZY) { return isolate->heap()->undefined_value(); @@ -218,12 +214,6 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { if (function->feedback_vector()->optimized_code() == *optimized_code) { function->ClearOptimizedCodeSlot("notify deoptimized"); } - // Remove the code from the osr optimized code cache. - DeoptimizationInputData* deopt_data = - DeoptimizationInputData::cast(optimized_code->deoptimization_data()); - if (deopt_data->OsrAstId()->value() == BailoutId::None().ToInt()) { - isolate->EvictOSROptimizedCode(*optimized_code, "notify deoptimized"); - } } else { // TODO(titzer): we should probably do DeoptimizeCodeList(code) // unconditionally if the code is not already marked for deoptimization. @@ -275,7 +265,7 @@ BailoutId DetermineEntryAndDisarmOSRForBaseline(JavaScriptFrame* frame) { // Return a BailoutId representing an AST id of the {IterationStatement}. uint32_t pc_offset = static_cast<uint32_t>(frame->pc() - caller_code->instruction_start()); - return caller_code->TranslatePcOffsetToAstId(pc_offset); + return caller_code->TranslatePcOffsetToBytecodeOffset(pc_offset); } BailoutId DetermineEntryAndDisarmOSRForInterpreter(JavaScriptFrame* frame) { @@ -342,28 +332,23 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { DeoptimizationInputData::cast(result->deoptimization_data()); if (data->OsrPcOffset()->value() >= 0) { - DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id); + DCHECK(BailoutId(data->OsrBytecodeOffset()->value()) == ast_id); if (FLAG_trace_osr) { PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n", ast_id.ToInt(), data->OsrPcOffset()->value()); } - if (result->is_turbofanned()) { - // When we're waiting for concurrent optimization, set to compile on - // the next call - otherwise we'd run unoptimized once more - // and potentially compile for OSR another time as well. - if (function->IsMarkedForConcurrentOptimization()) { - if (FLAG_trace_osr) { - PrintF("[OSR - Re-marking "); - function->PrintName(); - PrintF(" for non-concurrent optimization]\n"); - } - function->ReplaceCode( - isolate->builtins()->builtin(Builtins::kCompileOptimized)); + DCHECK(result->is_turbofanned()); + if (!function->HasOptimizedCode()) { + // If we're not already optimized, set to optimize non-concurrently on + // the next call, otherwise we'd run unoptimized once more and + // potentially compile for OSR again. + if (FLAG_trace_osr) { + PrintF("[OSR - Re-marking "); + function->PrintName(); + PrintF(" for non-concurrent optimization]\n"); } - } else { - // Crankshafted OSR code can be installed into the function. - function->ReplaceCode(*result); + function->SetOptimizationMarker(OptimizationMarker::kCompileOptimized); } return *result; } @@ -390,33 +375,19 @@ RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) { // First check if this is a real stack overflow. StackLimitCheck check(isolate); - if (check.JsHasOverflowed()) { - SealHandleScope shs(isolate); + if (check.JsHasOverflowed(kStackSpaceRequiredForCompilation * KB)) { return isolate->StackOverflow(); } - isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions(); + // Only try to install optimized functions if the interrupt was InstallCode. + if (isolate->stack_guard()->CheckAndClearInstallCode()) { + isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctions(); + } + return (function->IsOptimized()) ? function->code() : function->shared()->code(); } - -bool CodeGenerationFromStringsAllowed(Isolate* isolate, - Handle<Context> context) { - DCHECK(context->allow_code_gen_from_strings()->IsFalse(isolate)); - // Check with callback if set. - AllowCodeGenerationFromStringsCallback callback = - isolate->allow_code_gen_callback(); - if (callback == NULL) { - // No callback set and code generation disallowed. - return false; - } else { - // Callback set. Let it decide if code generation is allowed. - VMState<EXTERNAL> state(isolate); - return callback(v8::Utils::ToLocal(context)); - } -} - static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source, Handle<SharedFunctionInfo> outer_info, LanguageMode language_mode, @@ -427,7 +398,8 @@ static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source, // Check if native context allows code generation from // strings. Throw an exception if it doesn't. if (native_context->allow_code_gen_from_strings()->IsFalse(isolate) && - !CodeGenerationFromStringsAllowed(isolate, native_context)) { + !Compiler::CodeGenerationFromStringsAllowed(isolate, native_context, + source)) { Handle<Object> error_message = native_context->ErrorMessageForCodeGenerationFromStrings(); Handle<Object> error; diff --git a/chromium/v8/src/runtime/runtime-debug.cc b/chromium/v8/src/runtime/runtime-debug.cc index b65757b2de4..b58dce22b6b 100644 --- a/chromium/v8/src/runtime/runtime-debug.cc +++ b/chromium/v8/src/runtime/runtime-debug.cc @@ -17,6 +17,7 @@ #include "src/interpreter/bytecodes.h" #include "src/interpreter/interpreter.h" #include "src/isolate-inl.h" +#include "src/objects/debug-objects-inl.h" #include "src/runtime/runtime.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects.h" @@ -146,18 +147,19 @@ static MaybeHandle<JSArray> GetIteratorInternalProperties( Isolate* isolate, Handle<IteratorType> object) { Factory* factory = isolate->factory(); Handle<IteratorType> iterator = Handle<IteratorType>::cast(object); - CHECK(iterator->kind()->IsSmi()); const char* kind = NULL; - switch (Smi::cast(iterator->kind())->value()) { - case IteratorType::kKindKeys: + switch (iterator->map()->instance_type()) { + case JS_MAP_KEY_ITERATOR_TYPE: kind = "keys"; break; - case IteratorType::kKindValues: - kind = "values"; - break; - case IteratorType::kKindEntries: + case JS_MAP_KEY_VALUE_ITERATOR_TYPE: + case JS_SET_KEY_VALUE_ITERATOR_TYPE: kind = "entries"; break; + case JS_MAP_VALUE_ITERATOR_TYPE: + case JS_SET_VALUE_ITERATOR_TYPE: + kind = "values"; + break; default: UNREACHABLE(); } @@ -921,6 +923,11 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeCount) { // Check arguments. CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0); + // Only inspect suspended generator scopes. + if (!gen->is_suspended()) { + return Smi::kZero; + } + // Count the visible scopes. int n = 0; for (ScopeIterator it(isolate, gen); !it.Done(); it.Next()) { @@ -942,6 +949,11 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) { CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0); CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]); + // Only inspect suspended generator scopes. + if (!gen->is_suspended()) { + return isolate->heap()->undefined_value(); + } + // Find the requested scope. int n = 0; ScopeIterator it(isolate, gen); @@ -1046,28 +1058,15 @@ RUNTIME_FUNCTION(Runtime_SetBreakPointsActive) { } -static bool IsPositionAlignmentCodeCorrect(int alignment) { - return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED; -} - - RUNTIME_FUNCTION(Runtime_GetBreakLocations) { HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); + DCHECK_EQ(1, args.length()); CHECK(isolate->debug()->is_active()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); - CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]); - - if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) { - return isolate->ThrowIllegalOperation(); - } - BreakPositionAlignment alignment = - static_cast<BreakPositionAlignment>(statement_aligned_code); Handle<SharedFunctionInfo> shared(fun->shared()); // Find the number of break points - Handle<Object> break_locations = - Debug::GetSourceBreakLocations(shared, alignment); + Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared); if (break_locations->IsUndefined(isolate)) { return isolate->heap()->undefined_value(); } @@ -1098,29 +1097,20 @@ RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) { return Smi::FromInt(source_position); } - // Changes the state of a break point in a script and returns source position // where break point was set. NOTE: Regarding performance see the NOTE for // GetScriptFromScriptData. // args[0]: script to set break point in // args[1]: number: break source position (within the script source) -// args[2]: number, breakpoint position alignment -// args[3]: number: break point object +// args[2]: number: break point object RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) { HandleScope scope(isolate); - DCHECK_EQ(4, args.length()); + DCHECK_EQ(3, args.length()); CHECK(isolate->debug()->is_active()); CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0); CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]); CHECK(source_position >= 0); - CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]); - CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3); - - if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) { - return isolate->ThrowIllegalOperation(); - } - BreakPositionAlignment alignment = - static_cast<BreakPositionAlignment>(statement_aligned_code); + CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2); // Get the script from the script wrapper. CHECK(wrapper->value()->IsScript()); @@ -1128,7 +1118,7 @@ RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) { // Set break point. if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg, - &source_position, alignment)) { + &source_position)) { return isolate->heap()->undefined_value(); } @@ -1567,7 +1557,7 @@ int ScriptLinePosition(Handle<Script> script, int line) { if (line == 0) return 0; // If line == line_count, we return the first position beyond the last line. if (line > line_count) return -1; - return Smi::cast(line_ends_array->get(line - 1))->value() + 1; + return Smi::ToInt(line_ends_array->get(line - 1)) + 1; } } // namespace @@ -1802,8 +1792,8 @@ RUNTIME_FUNCTION(Runtime_ScriptSourceLine) { } const int start = - (line == 0) ? 0 : Smi::cast(line_ends_array->get(line - 1))->value() + 1; - const int end = Smi::cast(line_ends_array->get(line))->value(); + (line == 0) ? 0 : Smi::ToInt(line_ends_array->get(line - 1)) + 1; + const int end = Smi::ToInt(line_ends_array->get(line)); Handle<String> source = handle(String::cast(script_handle->source()), isolate); @@ -1910,6 +1900,26 @@ RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { return NULL; } +namespace { +Handle<JSObject> MakeRangeObject(Isolate* isolate, const CoverageBlock& range) { + Factory* factory = isolate->factory(); + + Handle<String> start_string = factory->InternalizeUtf8String("start"); + Handle<String> end_string = factory->InternalizeUtf8String("end"); + Handle<String> count_string = factory->InternalizeUtf8String("count"); + + Handle<JSObject> range_obj = factory->NewJSObjectWithNullProto(); + JSObject::AddProperty(range_obj, start_string, + factory->NewNumberFromInt(range.start), NONE); + JSObject::AddProperty(range_obj, end_string, + factory->NewNumberFromInt(range.end), NONE); + JSObject::AddProperty(range_obj, count_string, + factory->NewNumberFromUint(range.count), NONE); + + return range_obj; +} +} // namespace + RUNTIME_FUNCTION(Runtime_DebugCollectCoverage) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -1927,34 +1937,36 @@ RUNTIME_FUNCTION(Runtime_DebugCollectCoverage) { // Prepare property keys. Handle<FixedArray> scripts_array = factory->NewFixedArray(num_scripts); Handle<String> script_string = factory->NewStringFromStaticChars("script"); - Handle<String> start_string = factory->NewStringFromStaticChars("start"); - Handle<String> end_string = factory->NewStringFromStaticChars("end"); - Handle<String> count_string = factory->NewStringFromStaticChars("count"); for (int i = 0; i < num_scripts; i++) { const auto& script_data = coverage->at(i); HandleScope inner_scope(isolate); + + std::vector<CoverageBlock> ranges; int num_functions = static_cast<int>(script_data.functions.size()); - Handle<FixedArray> functions_array = factory->NewFixedArray(num_functions); for (int j = 0; j < num_functions; j++) { const auto& function_data = script_data.functions[j]; - Handle<JSObject> range_obj = factory->NewJSObjectWithNullProto(); - JSObject::AddProperty(range_obj, start_string, - factory->NewNumberFromInt(function_data.start), - NONE); - JSObject::AddProperty(range_obj, end_string, - factory->NewNumberFromInt(function_data.end), NONE); - JSObject::AddProperty(range_obj, count_string, - factory->NewNumberFromUint(function_data.count), - NONE); - functions_array->set(j, *range_obj); + ranges.emplace_back(function_data.start, function_data.end, + function_data.count); + for (size_t k = 0; k < function_data.blocks.size(); k++) { + const auto& block_data = function_data.blocks[k]; + ranges.emplace_back(block_data.start, block_data.end, block_data.count); + } + } + + int num_ranges = static_cast<int>(ranges.size()); + Handle<FixedArray> ranges_array = factory->NewFixedArray(num_ranges); + for (int j = 0; j < num_ranges; j++) { + Handle<JSObject> range_object = MakeRangeObject(isolate, ranges[j]); + ranges_array->set(j, *range_object); } + Handle<JSArray> script_obj = - factory->NewJSArrayWithElements(functions_array, FAST_ELEMENTS); + factory->NewJSArrayWithElements(ranges_array, PACKED_ELEMENTS); Handle<JSObject> wrapper = Script::GetWrapper(script_data.script); JSObject::AddProperty(script_obj, script_string, wrapper, NONE); scripts_array->set(i, *script_obj); } - return *factory->NewJSArrayWithElements(scripts_array, FAST_ELEMENTS); + return *factory->NewJSArrayWithElements(scripts_array, PACKED_ELEMENTS); } RUNTIME_FUNCTION(Runtime_DebugTogglePreciseCoverage) { @@ -1965,5 +1977,35 @@ RUNTIME_FUNCTION(Runtime_DebugTogglePreciseCoverage) { return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_DebugToggleBlockCoverage) { + SealHandleScope shs(isolate); + CONVERT_BOOLEAN_ARG_CHECKED(enable, 0); + Coverage::SelectMode(isolate, enable ? debug::Coverage::kBlockCount + : debug::Coverage::kBestEffort); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_IncBlockCounter) { + SealHandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_CHECKED(JSFunction, function, 0); + CONVERT_SMI_ARG_CHECKED(coverage_array_slot_index, 1); + + DCHECK(FLAG_block_coverage); + + // It's quite possible that a function contains IncBlockCounter bytecodes, but + // no coverage info exists. This happens e.g. by selecting the best-effort + // coverage collection mode, which triggers deletion of all coverage infos in + // order to avoid memory leaks. + + SharedFunctionInfo* shared = function->shared(); + if (shared->HasCoverageInfo()) { + CoverageInfo* coverage_info = shared->GetCoverageInfo(); + coverage_info->IncrementBlockCount(coverage_array_slot_index); + } + + return isolate->heap()->undefined_value(); +} + } // namespace internal } // namespace v8 diff --git a/chromium/v8/src/runtime/runtime-function.cc b/chromium/v8/src/runtime/runtime-function.cc index c7100d1bf55..382f09c4d42 100644 --- a/chromium/v8/src/runtime/runtime-function.cc +++ b/chromium/v8/src/runtime/runtime-function.cc @@ -29,32 +29,6 @@ RUNTIME_FUNCTION(Runtime_FunctionGetName) { } } - -RUNTIME_FUNCTION(Runtime_FunctionSetName) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0); - CONVERT_ARG_HANDLE_CHECKED(String, name, 1); - - name = String::Flatten(name); - f->shared()->set_name(*name); - return isolate->heap()->undefined_value(); -} - - -RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_CHECKED(JSFunction, f, 0); - CHECK(f->RemovePrototype()); - f->shared()->SetConstructStub( - *isolate->builtins()->ConstructedNonConstructable()); - - return isolate->heap()->undefined_value(); -} - // TODO(5530): Remove once uses in debug.js are gone. RUNTIME_FUNCTION(Runtime_FunctionGetScript) { HandleScope scope(isolate); @@ -114,24 +88,12 @@ RUNTIME_FUNCTION(Runtime_FunctionGetContextData) { return fun->native_context()->debug_context_id(); } -RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) { - SealHandleScope shs(isolate); - DCHECK_EQ(2, args.length()); - - CONVERT_ARG_CHECKED(JSFunction, fun, 0); - CONVERT_ARG_CHECKED(String, name, 1); - fun->shared()->set_instance_class_name(name); - return isolate->heap()->undefined_value(); -} - - RUNTIME_FUNCTION(Runtime_FunctionSetLength) { SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); CONVERT_ARG_CHECKED(JSFunction, fun, 0); CONVERT_SMI_ARG_CHECKED(length, 1); - CHECK((length & 0xC0000000) == 0xC0000000 || (length & 0xC0000000) == 0x0); fun->shared()->set_length(length); return isolate->heap()->undefined_value(); } @@ -172,13 +134,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) { return isolate->heap()->exception(); } - // Mark both, the source and the target, as un-flushable because the - // shared unoptimized code makes them impossible to enqueue in a list. - DCHECK(target_shared->code()->gc_metadata() == NULL); - DCHECK(source_shared->code()->gc_metadata() == NULL); - target_shared->set_dont_flush(true); - source_shared->set_dont_flush(true); - // Set the code, scope info, formal parameter count, and the length // of the target shared function info. target_shared->ReplaceCode(source_shared->code()); diff --git a/chromium/v8/src/runtime/runtime-generator.cc b/chromium/v8/src/runtime/runtime-generator.cc index 74b1fe90d24..9515d8e53a1 100644 --- a/chromium/v8/src/runtime/runtime-generator.cc +++ b/chromium/v8/src/runtime/runtime-generator.cc @@ -36,13 +36,9 @@ RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) { } RUNTIME_FUNCTION(Runtime_GeneratorClose) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); - - generator->set_continuation(JSGeneratorObject::kGeneratorClosed); - - return isolate->heap()->undefined_value(); + // Runtime call is implemented in InterpreterIntrinsics and lowered in + // JSIntrinsicLowering + UNREACHABLE(); } RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) { @@ -62,68 +58,33 @@ RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) { } RUNTIME_FUNCTION(Runtime_GeneratorGetContext) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); - // Runtime call is implemented in InterpreterIntrinsics and lowered in // JSIntrinsicLowering UNREACHABLE(); - - return generator->context(); } RUNTIME_FUNCTION(Runtime_GeneratorGetInputOrDebugPos) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); - // Runtime call is implemented in InterpreterIntrinsics and lowered in // JSIntrinsicLowering UNREACHABLE(); - - return generator->input_or_debug_pos(); -} - -RUNTIME_FUNCTION(Runtime_AsyncGeneratorGetAwaitInputOrDebugPos) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSAsyncGeneratorObject, generator, 0); - return generator->await_input_or_debug_pos(); } RUNTIME_FUNCTION(Runtime_AsyncGeneratorResolve) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - // Runtime call is implemented in InterpreterIntrinsics and lowered in // JSIntrinsicLowering UNREACHABLE(); - - return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_AsyncGeneratorReject) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - // Runtime call is implemented in InterpreterIntrinsics and lowered in // JSIntrinsicLowering UNREACHABLE(); - - return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_GeneratorGetResumeMode) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0); - // Runtime call is implemented in InterpreterIntrinsics and lowered in // JSIntrinsicLowering UNREACHABLE(); - - return Smi::FromInt(generator->resume_mode()); } RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) { diff --git a/chromium/v8/src/runtime/runtime-internal.cc b/chromium/v8/src/runtime/runtime-internal.cc index 7348d5f0071..3f3f2f8185a 100644 --- a/chromium/v8/src/runtime/runtime-internal.cc +++ b/chromium/v8/src/runtime/runtime-internal.cc @@ -29,7 +29,6 @@ RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) { return isolate->heap()->undefined_value(); } - RUNTIME_FUNCTION(Runtime_ExportFromRuntime) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -42,7 +41,6 @@ RUNTIME_FUNCTION(Runtime_ExportFromRuntime) { return *container; } - RUNTIME_FUNCTION(Runtime_InstallToContext) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -51,7 +49,7 @@ RUNTIME_FUNCTION(Runtime_InstallToContext) { CHECK(isolate->bootstrapper()->IsActive()); Handle<Context> native_context = isolate->native_context(); Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); - int length = Smi::cast(array->length())->value(); + int length = Smi::ToInt(array->length()); for (int i = 0; i < length; i += 2) { CHECK(fixed_array->get(i)->IsString()); Handle<String> name(String::cast(fixed_array->get(i))); @@ -67,21 +65,18 @@ RUNTIME_FUNCTION(Runtime_InstallToContext) { return isolate->heap()->undefined_value(); } - RUNTIME_FUNCTION(Runtime_Throw) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); return isolate->Throw(args[0]); } - RUNTIME_FUNCTION(Runtime_ReThrow) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); return isolate->ReThrow(args[0]); } - RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) { SealHandleScope shs(isolate); DCHECK_LE(0, args.length()); @@ -133,7 +128,6 @@ const char* ElementsKindToType(ElementsKind fixed_elements_kind) { default: UNREACHABLE(); - return ""; } } @@ -167,14 +161,12 @@ RUNTIME_FUNCTION(Runtime_UnwindAndFindExceptionHandler) { return isolate->UnwindAndFindHandler(); } - RUNTIME_FUNCTION(Runtime_PromoteScheduledException) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); return isolate->PromoteScheduledException(); } - RUNTIME_FUNCTION(Runtime_ThrowReferenceError) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -183,7 +175,6 @@ RUNTIME_FUNCTION(Runtime_ThrowReferenceError) { isolate, NewReferenceError(MessageTemplate::kNotDefined, name)); } - RUNTIME_FUNCTION(Runtime_NewTypeError) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -194,7 +185,6 @@ RUNTIME_FUNCTION(Runtime_NewTypeError) { return *isolate->factory()->NewTypeError(message_template, arg0); } - RUNTIME_FUNCTION(Runtime_NewReferenceError) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -205,7 +195,6 @@ RUNTIME_FUNCTION(Runtime_NewReferenceError) { return *isolate->factory()->NewReferenceError(message_template, arg0); } - RUNTIME_FUNCTION(Runtime_NewSyntaxError) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -261,6 +250,13 @@ RUNTIME_FUNCTION(Runtime_ThrowIteratorResultNotAnObject) { NewTypeError(MessageTemplate::kIteratorResultNotAnObject, value)); } +RUNTIME_FUNCTION(Runtime_ThrowThrowMethodMissing) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kThrowMethodMissing)); +} + RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -304,7 +300,6 @@ RUNTIME_FUNCTION(Runtime_ThrowApplyNonFunction) { isolate, NewTypeError(MessageTemplate::kApplyNonFunction, object, type)); } - RUNTIME_FUNCTION(Runtime_StackGuard) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); @@ -318,14 +313,12 @@ RUNTIME_FUNCTION(Runtime_StackGuard) { return isolate->stack_guard()->HandleInterrupts(); } - RUNTIME_FUNCTION(Runtime_Interrupt) { SealHandleScope shs(isolate); DCHECK_EQ(0, args.length()); return isolate->stack_guard()->HandleInterrupts(); } - RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -336,7 +329,6 @@ RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE); } - RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -372,13 +364,10 @@ RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) { return *result; } - RUNTIME_FUNCTION(Runtime_IS_VAR) { UNREACHABLE(); // implemented as macro in the parser - return NULL; } - namespace { bool ComputeLocation(Isolate* isolate, MessageLocation* target) { @@ -403,14 +392,15 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) { return false; } - -Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { +Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object, + CallPrinter::IteratorHint* hint) { MessageLocation location; if (ComputeLocation(isolate, &location)) { - std::unique_ptr<ParseInfo> info(new ParseInfo(location.shared())); - if (parsing::ParseAny(info.get(), isolate)) { + ParseInfo info(location.shared()); + if (parsing::ParseAny(&info, isolate)) { CallPrinter printer(isolate, location.shared()->IsUserJavaScript()); - Handle<String> str = printer.Print(info->literal(), location.start_pos()); + Handle<String> str = printer.Print(info.literal(), location.start_pos()); + *hint = printer.GetIteratorHint(); if (str->length() > 0) return str; } else { isolate->clear_pending_exception(); @@ -419,15 +409,44 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { return Object::TypeOf(isolate, object); } +void UpdateIteratorTemplate(CallPrinter::IteratorHint hint, + MessageTemplate::Template* id) { + if (hint == CallPrinter::IteratorHint::kNormal) { + *id = MessageTemplate::kNotIterable; + } + + if (hint == CallPrinter::IteratorHint::kAsync) { + *id = MessageTemplate::kNotAsyncIterable; + } +} + } // namespace +MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate, + Handle<Object> object) { + CallPrinter::IteratorHint hint = CallPrinter::kNone; + Handle<String> callsite = RenderCallSite(isolate, object, &hint); + MessageTemplate::Template id = MessageTemplate::kNonObjectPropertyLoad; + + if (hint == CallPrinter::kNone) { + Handle<Symbol> iterator_symbol = isolate->factory()->iterator_symbol(); + THROW_NEW_ERROR(isolate, NewTypeError(id, iterator_symbol, callsite), + Object); + } + + UpdateIteratorTemplate(hint, &id); + THROW_NEW_ERROR(isolate, NewTypeError(id, callsite), Object); +} + RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - Handle<String> callsite = RenderCallSite(isolate, object); - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kCalledNonCallable, callsite)); + CallPrinter::IteratorHint hint = CallPrinter::kNone; + Handle<String> callsite = RenderCallSite(isolate, object, &hint); + MessageTemplate::Template id = MessageTemplate::kCalledNonCallable; + UpdateIteratorTemplate(hint, &id); + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite)); } RUNTIME_FUNCTION(Runtime_ThrowCalledOnNullOrUndefined) { @@ -442,9 +461,10 @@ RUNTIME_FUNCTION(Runtime_ThrowConstructedNonConstructable) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - Handle<String> callsite = RenderCallSite(isolate, object); - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kNotConstructor, callsite)); + CallPrinter::IteratorHint hint = CallPrinter::kNone; + Handle<String> callsite = RenderCallSite(isolate, object, &hint); + MessageTemplate::Template id = MessageTemplate::kNotConstructor; + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewTypeError(id, callsite)); } RUNTIME_FUNCTION(Runtime_ThrowConstructorReturnedNonObject) { @@ -478,7 +498,6 @@ RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) { isolate, object, ElementTypes::kAll)); } - RUNTIME_FUNCTION(Runtime_IncrementUseCounter) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -487,6 +506,15 @@ RUNTIME_FUNCTION(Runtime_IncrementUseCounter) { return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION( + Runtime_IncrementUseCounterConstructorReturnNonUndefinedPrimitive) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + isolate->CountUsage( + v8::Isolate::UseCounterFeature::kConstructorNonUndefinedPrimitiveReturn); + return isolate->heap()->undefined_value(); +} + RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) { HandleScope scope(isolate); if (args.length() == 0) { diff --git a/chromium/v8/src/runtime/runtime-interpreter.cc b/chromium/v8/src/runtime/runtime-interpreter.cc index 5889a477c31..815e6d0fec7 100644 --- a/chromium/v8/src/runtime/runtime-interpreter.cc +++ b/chromium/v8/src/runtime/runtime-interpreter.cc @@ -15,6 +15,7 @@ #include "src/interpreter/bytecodes.h" #include "src/isolate-inl.h" #include "src/ostreams.h" +#include "src/string-builder.h" namespace v8 { namespace internal { diff --git a/chromium/v8/src/runtime/runtime-intl.cc b/chromium/v8/src/runtime/runtime-intl.cc index 623fe05fe83..343d560a8a2 100644 --- a/chromium/v8/src/runtime/runtime-intl.cc +++ b/chromium/v8/src/runtime/runtime-intl.cc @@ -143,6 +143,11 @@ RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) { icu::Locale default_locale; + // Translate ICU's fallback locale to a well-known locale. + if (strcmp(default_locale.getName(), "en_US_POSIX") == 0) { + return *factory->NewStringFromStaticChars("en-US"); + } + // Set the locale char result[ULOC_FULLNAME_CAPACITY]; UErrorCode status = U_ZERO_ERROR; @@ -471,7 +476,7 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormatToParts) { return isolate->heap()->undefined_value(); } } - JSObject::ValidateElements(result); + JSObject::ValidateElements(*result); return *result; } diff --git a/chromium/v8/src/runtime/runtime-literals.cc b/chromium/v8/src/runtime/runtime-literals.cc index 1a2b1f584ef..4f761d5997d 100644 --- a/chromium/v8/src/runtime/runtime-literals.cc +++ b/chromium/v8/src/runtime/runtime-literals.cc @@ -14,301 +14,521 @@ namespace v8 { namespace internal { -MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( - Isolate* isolate, Handle<FeedbackVector> vector, - Handle<FixedArray> compile_time_value); - -MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( - Isolate* isolate, Handle<FeedbackVector> vector, - Handle<BoilerplateDescription> boilerplate_description, - bool use_fast_elements, bool has_null_prototype) { - Handle<Context> native_context = isolate->native_context(); - - // In case we have function literals, we want the object to be in - // slow properties mode for now. We don't go in the map cache because - // maps with constant functions can't be shared if the functions are - // not the same (which is the common case). - int number_of_properties = boilerplate_description->backing_store_size(); - - // Ignoring number_of_properties for force dictionary map with __proto__:null. - Handle<Map> map = - has_null_prototype - ? handle(native_context->slow_object_with_null_prototype_map(), - isolate) - : isolate->factory()->ObjectLiteralMapFromCache(native_context, - number_of_properties); - - PretenureFlag pretenure_flag = - isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; - - Handle<JSObject> boilerplate = - map->is_dictionary_map() - ? isolate->factory()->NewSlowJSObjectFromMap( - map, number_of_properties, pretenure_flag) - : isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); - - // Normalize the elements of the boilerplate to save space if needed. - if (!use_fast_elements) JSObject::NormalizeElements(boilerplate); - - // Add the constant properties to the boilerplate. - int length = boilerplate_description->size(); - // TODO(verwaest): Support tracking representations in the boilerplate. - for (int index = 0; index < length; index++) { - Handle<Object> key(boilerplate_description->name(index), isolate); - Handle<Object> value(boilerplate_description->value(index), isolate); - if (value->IsFixedArray()) { - // The value contains the CompileTimeValue with the boilerplate properties - // of a simple object or array literal. - Handle<FixedArray> compile_time_value = Handle<FixedArray>::cast(value); - ASSIGN_RETURN_ON_EXCEPTION( - isolate, value, - CreateLiteralBoilerplate(isolate, vector, compile_time_value), - Object); +namespace { + +bool IsUninitializedLiteralSite(Handle<Object> literal_site) { + return *literal_site == Smi::kZero; +} + +bool HasBoilerplate(Isolate* isolate, Handle<Object> literal_site) { + return !literal_site->IsSmi(); +} + +void PreInitializeLiteralSite(Handle<FeedbackVector> vector, + FeedbackSlot slot) { + vector->Set(slot, Smi::FromInt(1)); +} + +Handle<Object> InnerCreateBoilerplate(Isolate* isolate, + Handle<FixedArray> compile_time_value, + PretenureFlag pretenure_flag); + +enum DeepCopyHints { kNoHints = 0, kObjectIsShallow = 1 }; + +template <class ContextObject> +class JSObjectWalkVisitor { + public: + JSObjectWalkVisitor(ContextObject* site_context, DeepCopyHints hints) + : site_context_(site_context), hints_(hints) {} + + MUST_USE_RESULT MaybeHandle<JSObject> StructureWalk(Handle<JSObject> object); + + protected: + MUST_USE_RESULT inline MaybeHandle<JSObject> VisitElementOrProperty( + Handle<JSObject> object, Handle<JSObject> value) { + Handle<AllocationSite> current_site = site_context()->EnterNewScope(); + MaybeHandle<JSObject> copy_of_value = StructureWalk(value); + site_context()->ExitScope(current_site, value); + return copy_of_value; + } + + inline ContextObject* site_context() { return site_context_; } + inline Isolate* isolate() { return site_context()->isolate(); } + + private: + ContextObject* site_context_; + const DeepCopyHints hints_; +}; + +template <class ContextObject> +MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( + Handle<JSObject> object) { + Isolate* isolate = this->isolate(); + bool copying = ContextObject::kCopying; + bool shallow = hints_ == kObjectIsShallow; + + if (!shallow) { + StackLimitCheck check(isolate); + + if (check.HasOverflowed()) { + isolate->StackOverflow(); + return MaybeHandle<JSObject>(); } - MaybeHandle<Object> maybe_result; - uint32_t element_index = 0; - if (key->ToArrayIndex(&element_index)) { - // Array index (uint32). - if (value->IsUninitialized(isolate)) { - value = handle(Smi::kZero, isolate); + } + + if (object->map()->is_deprecated()) { + JSObject::MigrateInstance(object); + } + + Handle<JSObject> copy; + if (copying) { + // JSFunction objects are not allowed to be in normal boilerplates at all. + DCHECK(!object->IsJSFunction()); + Handle<AllocationSite> site_to_pass; + if (site_context()->ShouldCreateMemento(object)) { + site_to_pass = site_context()->current(); + } + copy = isolate->factory()->CopyJSObjectWithAllocationSite(object, + site_to_pass); + } else { + copy = object; + } + + DCHECK(copying || copy.is_identical_to(object)); + + if (shallow) return copy; + + HandleScope scope(isolate); + + // Deep copy own properties. Arrays only have 1 property "length". + if (!copy->IsJSArray()) { + if (copy->HasFastProperties()) { + Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); + int limit = copy->map()->NumberOfOwnDescriptors(); + for (int i = 0; i < limit; i++) { + DCHECK_EQ(kField, descriptors->GetDetails(i).location()); + DCHECK_EQ(kData, descriptors->GetDetails(i).kind()); + FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i); + if (copy->IsUnboxedDoubleField(index)) continue; + Object* raw = copy->RawFastPropertyAt(index); + if (raw->IsJSObject()) { + Handle<JSObject> value(JSObject::cast(raw), isolate); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, value, VisitElementOrProperty(copy, value), JSObject); + if (copying) copy->FastPropertyAtPut(index, *value); + } else if (copying && raw->IsMutableHeapNumber()) { + DCHECK(descriptors->GetDetails(i).representation().IsDouble()); + uint64_t double_value = HeapNumber::cast(raw)->value_as_bits(); + Handle<HeapNumber> value = isolate->factory()->NewHeapNumber(MUTABLE); + value->set_value_as_bits(double_value); + copy->FastPropertyAtPut(index, *value); + } } - maybe_result = JSObject::SetOwnElementIgnoreAttributes( - boilerplate, element_index, value, NONE); } else { - Handle<String> name = Handle<String>::cast(key); - DCHECK(!name->AsArrayIndex(&element_index)); - maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, - value, NONE); + Handle<NameDictionary> dict(copy->property_dictionary()); + for (int i = 0; i < dict->Capacity(); i++) { + Object* raw = dict->ValueAt(i); + if (!raw->IsJSObject()) continue; + DCHECK(dict->KeyAt(i)->IsName()); + Handle<JSObject> value(JSObject::cast(raw), isolate); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, value, VisitElementOrProperty(copy, value), JSObject); + if (copying) dict->ValueAtPut(i, *value); + } } - RETURN_ON_EXCEPTION(isolate, maybe_result, Object); + + // Assume non-arrays don't end up having elements. + if (copy->elements()->length() == 0) return copy; } - if (map->is_dictionary_map() && !has_null_prototype) { - // TODO(cbruni): avoid making the boilerplate fast again, the clone stub - // supports dict-mode objects directly. - JSObject::MigrateSlowToFast(boilerplate, - boilerplate->map()->unused_property_fields(), - "FastLiteral"); + // Deep copy own elements. + switch (copy->GetElementsKind()) { + case PACKED_ELEMENTS: + case HOLEY_ELEMENTS: { + Handle<FixedArray> elements(FixedArray::cast(copy->elements())); + if (elements->map() == isolate->heap()->fixed_cow_array_map()) { +#ifdef DEBUG + for (int i = 0; i < elements->length(); i++) { + DCHECK(!elements->get(i)->IsJSObject()); + } +#endif + } else { + for (int i = 0; i < elements->length(); i++) { + Object* raw = elements->get(i); + if (!raw->IsJSObject()) continue; + Handle<JSObject> value(JSObject::cast(raw), isolate); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, value, VisitElementOrProperty(copy, value), JSObject); + if (copying) elements->set(i, *value); + } + } + break; + } + case DICTIONARY_ELEMENTS: { + Handle<SeededNumberDictionary> element_dictionary( + copy->element_dictionary()); + int capacity = element_dictionary->Capacity(); + for (int i = 0; i < capacity; i++) { + Object* raw = element_dictionary->ValueAt(i); + if (!raw->IsJSObject()) continue; + Handle<JSObject> value(JSObject::cast(raw), isolate); + ASSIGN_RETURN_ON_EXCEPTION( + isolate, value, VisitElementOrProperty(copy, value), JSObject); + if (copying) element_dictionary->ValueAtPut(i, *value); + } + break; + } + case FAST_SLOPPY_ARGUMENTS_ELEMENTS: + case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: + UNIMPLEMENTED(); + break; + case FAST_STRING_WRAPPER_ELEMENTS: + case SLOW_STRING_WRAPPER_ELEMENTS: + UNREACHABLE(); + break; + +#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS: + + TYPED_ARRAYS(TYPED_ARRAY_CASE) +#undef TYPED_ARRAY_CASE + // Typed elements cannot be created using an object literal. + UNREACHABLE(); + break; + + case PACKED_SMI_ELEMENTS: + case HOLEY_SMI_ELEMENTS: + case PACKED_DOUBLE_ELEMENTS: + case HOLEY_DOUBLE_ELEMENTS: + case NO_ELEMENTS: + // No contained objects, nothing to do. + break; } - return boilerplate; + + return copy; } -static MaybeHandle<Object> CreateArrayLiteralBoilerplate( - Isolate* isolate, Handle<FeedbackVector> vector, - Handle<ConstantElementsPair> elements) { - // Create the JSArray. - Handle<JSFunction> constructor = isolate->array_function(); - - PretenureFlag pretenure_flag = - isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; - - Handle<JSArray> object = Handle<JSArray>::cast( - isolate->factory()->NewJSObject(constructor, pretenure_flag)); - - ElementsKind constant_elements_kind = - static_cast<ElementsKind>(elements->elements_kind()); - Handle<FixedArrayBase> constant_elements_values(elements->constant_values()); - - { - DisallowHeapAllocation no_gc; - DCHECK(IsFastElementsKind(constant_elements_kind)); - Context* native_context = isolate->context()->native_context(); - Object* map = - native_context->get(Context::ArrayMapIndex(constant_elements_kind)); - object->set_map(Map::cast(map)); +class DeprecationUpdateContext { + public: + explicit DeprecationUpdateContext(Isolate* isolate) { isolate_ = isolate; } + Isolate* isolate() { return isolate_; } + bool ShouldCreateMemento(Handle<JSObject> object) { return false; } + inline void ExitScope(Handle<AllocationSite> scope_site, + Handle<JSObject> object) {} + Handle<AllocationSite> EnterNewScope() { return Handle<AllocationSite>(); } + Handle<AllocationSite> current() { + UNREACHABLE(); + return Handle<AllocationSite>(); } - Handle<FixedArrayBase> copied_elements_values; - if (IsFastDoubleElementsKind(constant_elements_kind)) { - copied_elements_values = isolate->factory()->CopyFixedDoubleArray( - Handle<FixedDoubleArray>::cast(constant_elements_values)); - } else { - DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind)); - const bool is_cow = (constant_elements_values->map() == - isolate->heap()->fixed_cow_array_map()); - if (is_cow) { - copied_elements_values = constant_elements_values; -#if DEBUG - Handle<FixedArray> fixed_array_values = - Handle<FixedArray>::cast(copied_elements_values); - for (int i = 0; i < fixed_array_values->length(); i++) { - DCHECK(!fixed_array_values->get(i)->IsFixedArray()); + static const bool kCopying = false; + + private: + Isolate* isolate_; +}; + +// AllocationSiteCreationContext aids in the creation of AllocationSites to +// accompany object literals. +class AllocationSiteCreationContext : public AllocationSiteContext { + public: + explicit AllocationSiteCreationContext(Isolate* isolate) + : AllocationSiteContext(isolate) {} + + Handle<AllocationSite> EnterNewScope() { + Handle<AllocationSite> scope_site; + if (top().is_null()) { + // We are creating the top level AllocationSite as opposed to a nested + // AllocationSite. + InitializeTraversal(isolate()->factory()->NewAllocationSite()); + scope_site = Handle<AllocationSite>(*top(), isolate()); + if (FLAG_trace_creation_allocation_sites) { + PrintF("*** Creating top level AllocationSite %p\n", + static_cast<void*>(*scope_site)); } -#endif } else { - Handle<FixedArray> fixed_array_values = - Handle<FixedArray>::cast(constant_elements_values); - Handle<FixedArray> fixed_array_values_copy = - isolate->factory()->CopyFixedArray(fixed_array_values); - copied_elements_values = fixed_array_values_copy; - FOR_WITH_HANDLE_SCOPE( - isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { - if (fixed_array_values->get(i)->IsFixedArray()) { - // The value contains the CompileTimeValue with the - // boilerplate description of a simple object or - // array literal. - Handle<FixedArray> compile_time_value( - FixedArray::cast(fixed_array_values->get(i))); - Handle<Object> result; - ASSIGN_RETURN_ON_EXCEPTION( - isolate, result, - CreateLiteralBoilerplate(isolate, vector, compile_time_value), - Object); - fixed_array_values_copy->set(i, *result); - } - }); + DCHECK(!current().is_null()); + scope_site = isolate()->factory()->NewAllocationSite(); + if (FLAG_trace_creation_allocation_sites) { + PrintF("Creating nested site (top, current, new) (%p, %p, %p)\n", + static_cast<void*>(*top()), static_cast<void*>(*current()), + static_cast<void*>(*scope_site)); + } + current()->set_nested_site(*scope_site); + update_current_site(*scope_site); + } + DCHECK(!scope_site.is_null()); + return scope_site; + } + void ExitScope(Handle<AllocationSite> scope_site, Handle<JSObject> object) { + if (object.is_null()) return; + scope_site->set_boilerplate(*object); + if (FLAG_trace_creation_allocation_sites) { + bool top_level = + !scope_site.is_null() && top().is_identical_to(scope_site); + if (top_level) { + PrintF("*** Setting AllocationSite %p transition_info %p\n", + static_cast<void*>(*scope_site), static_cast<void*>(*object)); + } else { + PrintF("Setting AllocationSite (%p, %p) transition_info %p\n", + static_cast<void*>(*top()), static_cast<void*>(*scope_site), + static_cast<void*>(*object)); + } } } - object->set_elements(*copied_elements_values); - object->set_length(Smi::FromInt(copied_elements_values->length())); + static const bool kCopying = false; +}; + +MaybeHandle<JSObject> DeepWalk(Handle<JSObject> object, + DeprecationUpdateContext* site_context) { + JSObjectWalkVisitor<DeprecationUpdateContext> v(site_context, kNoHints); + MaybeHandle<JSObject> result = v.StructureWalk(object); + Handle<JSObject> for_assert; + DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object)); + return result; +} - JSObject::ValidateElements(object); - return object; +MaybeHandle<JSObject> DeepWalk(Handle<JSObject> object, + AllocationSiteCreationContext* site_context) { + JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, kNoHints); + MaybeHandle<JSObject> result = v.StructureWalk(object); + Handle<JSObject> for_assert; + DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object)); + return result; } -MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( - Isolate* isolate, Handle<FeedbackVector> vector, - Handle<FixedArray> compile_time_value) { - Handle<HeapObject> elements = - CompileTimeValue::GetElements(compile_time_value); - int flags = CompileTimeValue::GetLiteralTypeFlags(compile_time_value); - if (flags == CompileTimeValue::kArrayLiteralFlag) { - Handle<ConstantElementsPair> elems = - Handle<ConstantElementsPair>::cast(elements); - return CreateArrayLiteralBoilerplate(isolate, vector, elems); - } - Handle<BoilerplateDescription> props = - Handle<BoilerplateDescription>::cast(elements); - bool use_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; - bool has_null_prototype = (flags & ObjectLiteral::kHasNullPrototype) != 0; - return CreateObjectLiteralBoilerplate(isolate, vector, props, - use_fast_elements, has_null_prototype); +MaybeHandle<JSObject> DeepCopy(Handle<JSObject> object, + AllocationSiteUsageContext* site_context, + DeepCopyHints hints) { + JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, hints); + MaybeHandle<JSObject> copy = v.StructureWalk(object); + Handle<JSObject> for_assert; + DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object)); + return copy; } +struct ObjectBoilerplate { + static Handle<JSObject> Create(Isolate* isolate, + Handle<HeapObject> description, int flags, + PretenureFlag pretenure_flag) { + Handle<Context> native_context = isolate->native_context(); + Handle<BoilerplateDescription> boilerplate_description = + Handle<BoilerplateDescription>::cast(description); + bool use_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; + bool has_null_prototype = (flags & ObjectLiteral::kHasNullPrototype) != 0; + + // In case we have function literals, we want the object to be in + // slow properties mode for now. We don't go in the map cache because + // maps with constant functions can't be shared if the functions are + // not the same (which is the common case). + int number_of_properties = boilerplate_description->backing_store_size(); + + // Ignoring number_of_properties for force dictionary map with + // __proto__:null. + Handle<Map> map = + has_null_prototype + ? handle(native_context->slow_object_with_null_prototype_map(), + isolate) + : isolate->factory()->ObjectLiteralMapFromCache( + native_context, number_of_properties); + + Handle<JSObject> boilerplate = + map->is_dictionary_map() + ? isolate->factory()->NewSlowJSObjectFromMap( + map, number_of_properties, pretenure_flag) + : isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); + + // Normalize the elements of the boilerplate to save space if needed. + if (!use_fast_elements) JSObject::NormalizeElements(boilerplate); + + // Add the constant properties to the boilerplate. + int length = boilerplate_description->size(); + // TODO(verwaest): Support tracking representations in the boilerplate. + for (int index = 0; index < length; index++) { + Handle<Object> key(boilerplate_description->name(index), isolate); + Handle<Object> value(boilerplate_description->value(index), isolate); + if (value->IsFixedArray()) { + // The value contains the CompileTimeValue with the boilerplate + // properties of a simple object or array literal. + Handle<FixedArray> compile_time_value = Handle<FixedArray>::cast(value); + value = + InnerCreateBoilerplate(isolate, compile_time_value, pretenure_flag); + } + uint32_t element_index = 0; + if (key->ToArrayIndex(&element_index)) { + // Array index (uint32). + if (value->IsUninitialized(isolate)) { + value = handle(Smi::kZero, isolate); + } + JSObject::SetOwnElementIgnoreAttributes(boilerplate, element_index, + value, NONE) + .Check(); + } else { + Handle<String> name = Handle<String>::cast(key); + DCHECK(!name->AsArrayIndex(&element_index)); + JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name, value, NONE) + .Check(); + } + } -RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { - HandleScope scope(isolate); - DCHECK_EQ(4, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); - CONVERT_SMI_ARG_CHECKED(index, 1); - CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); - CONVERT_SMI_ARG_CHECKED(flags, 3); - FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); + if (map->is_dictionary_map() && !has_null_prototype) { + // TODO(cbruni): avoid making the boilerplate fast again, the clone stub + // supports dict-mode objects directly. + JSObject::MigrateSlowToFast(boilerplate, + boilerplate->map()->unused_property_fields(), + "FastLiteral"); + } + return boilerplate; + } +}; + +struct ArrayBoilerplate { + static Handle<JSObject> Create(Isolate* isolate, + Handle<HeapObject> description, int flags, + PretenureFlag pretenure_flag) { + Handle<ConstantElementsPair> elements = + Handle<ConstantElementsPair>::cast(description); + // Create the JSArray. + ElementsKind constant_elements_kind = + static_cast<ElementsKind>(elements->elements_kind()); + + Handle<FixedArrayBase> constant_elements_values( + elements->constant_values()); + Handle<FixedArrayBase> copied_elements_values; + if (IsDoubleElementsKind(constant_elements_kind)) { + copied_elements_values = isolate->factory()->CopyFixedDoubleArray( + Handle<FixedDoubleArray>::cast(constant_elements_values)); + } else { + DCHECK(IsSmiOrObjectElementsKind(constant_elements_kind)); + const bool is_cow = (constant_elements_values->map() == + isolate->heap()->fixed_cow_array_map()); + if (is_cow) { + copied_elements_values = constant_elements_values; +#if DEBUG + Handle<FixedArray> fixed_array_values = + Handle<FixedArray>::cast(copied_elements_values); + for (int i = 0; i < fixed_array_values->length(); i++) { + DCHECK(!fixed_array_values->get(i)->IsFixedArray()); + } +#endif + } else { + Handle<FixedArray> fixed_array_values = + Handle<FixedArray>::cast(constant_elements_values); + Handle<FixedArray> fixed_array_values_copy = + isolate->factory()->CopyFixedArray(fixed_array_values); + copied_elements_values = fixed_array_values_copy; + FOR_WITH_HANDLE_SCOPE( + isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { + if (fixed_array_values->get(i)->IsFixedArray()) { + // The value contains the CompileTimeValue with the + // boilerplate description of a simple object or + // array literal. + Handle<FixedArray> compile_time_value( + FixedArray::cast(fixed_array_values->get(i))); + Handle<Object> result = InnerCreateBoilerplate( + isolate, compile_time_value, pretenure_flag); + fixed_array_values_copy->set(i, *result); + } + }); + } + } - // Check if boilerplate exists. If not, create it first. - Handle<Object> boilerplate(closure->feedback_vector()->Get(literal_slot), - isolate); - if (boilerplate->IsUndefined(isolate)) { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags))); - closure->feedback_vector()->Set(literal_slot, *boilerplate); + return isolate->factory()->NewJSArrayWithElements( + copied_elements_values, constant_elements_kind, + copied_elements_values->length(), pretenure_flag); } - return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate)); -} +}; +Handle<Object> InnerCreateBoilerplate(Isolate* isolate, + Handle<FixedArray> compile_time_value, + PretenureFlag pretenure_flag) { + Handle<HeapObject> elements = + CompileTimeValue::GetElements(compile_time_value); + int flags = CompileTimeValue::GetLiteralTypeFlags(compile_time_value); + if (flags == CompileTimeValue::kArrayLiteralFlag) { + return ArrayBoilerplate::Create(isolate, elements, flags, pretenure_flag); + } + return ObjectBoilerplate::Create(isolate, elements, flags, pretenure_flag); +} -RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { - HandleScope scope(isolate); - DCHECK_EQ(4, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); - CONVERT_SMI_ARG_CHECKED(literals_index, 1); - CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, boilerplate_description, - 2); - CONVERT_SMI_ARG_CHECKED(flags, 3); +template <typename Boilerplate> +MaybeHandle<JSObject> CreateLiteral(Isolate* isolate, + Handle<JSFunction> closure, + int literals_index, + Handle<HeapObject> description, int flags) { Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); - bool use_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; - bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; - bool has_null_prototype = (flags & ObjectLiteral::kHasNullPrototype) != 0; - FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); CHECK(literals_slot.ToInt() < vector->slot_count()); - - // Check if boilerplate exists. If not, create it first. Handle<Object> literal_site(vector->Get(literals_slot), isolate); - Handle<AllocationSite> site; - Handle<JSObject> boilerplate; - if (literal_site->IsUndefined(isolate)) { - Handle<Object> raw_boilerplate; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, raw_boilerplate, - CreateObjectLiteralBoilerplate(isolate, vector, boilerplate_description, - use_fast_elements, has_null_prototype)); - boilerplate = Handle<JSObject>::cast(raw_boilerplate); - - AllocationSiteCreationContext creation_context(isolate); - site = creation_context.EnterNewScope(); - RETURN_FAILURE_ON_EXCEPTION( - isolate, JSObject::DeepWalk(boilerplate, &creation_context)); - creation_context.ExitScope(site, boilerplate); - - // Update the functions literal and return the boilerplate. - vector->Set(literals_slot, *site); - } else { - site = Handle<AllocationSite>::cast(literal_site); - boilerplate = - Handle<JSObject>(JSObject::cast(site->transition_info()), isolate); + DeepCopyHints copy_hints = + (flags & AggregateLiteral::kIsShallow) ? kObjectIsShallow : kNoHints; + if (FLAG_track_double_fields && !FLAG_unbox_double_fields) { + // Make sure we properly clone mutable heap numbers on 32-bit platforms. + copy_hints = kNoHints; } - AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); - usage_context.EnterNewScope(); - MaybeHandle<Object> maybe_copy = - JSObject::DeepCopy(boilerplate, &usage_context); - usage_context.ExitScope(site, boilerplate); - RETURN_RESULT_OR_FAILURE(isolate, maybe_copy); -} - -MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( - Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot literals_slot, - Handle<ConstantElementsPair> elements) { - // Check if boilerplate exists. If not, create it first. - Handle<Object> literal_site(vector->Get(literals_slot), isolate); Handle<AllocationSite> site; - if (literal_site->IsUndefined(isolate)) { - Handle<Object> boilerplate; - ASSIGN_RETURN_ON_EXCEPTION( - isolate, boilerplate, - CreateArrayLiteralBoilerplate(isolate, vector, elements), - AllocationSite); + Handle<JSObject> boilerplate; + if (HasBoilerplate(isolate, literal_site)) { + site = Handle<AllocationSite>::cast(literal_site); + boilerplate = Handle<JSObject>(site->boilerplate(), isolate); + } else { + // Eagerly create AllocationSites for literals that contain an Array. + bool needs_initial_allocation_site = + (flags & AggregateLiteral::kNeedsInitialAllocationSite) != 0; + // TODO(cbruni): Even in the case where we need an initial allocation site + // we could still create the boilerplate lazily to save memory. + if (!needs_initial_allocation_site && + IsUninitializedLiteralSite(literal_site)) { + PreInitializeLiteralSite(vector, literals_slot); + boilerplate = + Boilerplate::Create(isolate, description, flags, NOT_TENURED); + if (copy_hints == kNoHints) { + DeprecationUpdateContext update_context(isolate); + RETURN_ON_EXCEPTION(isolate, DeepWalk(boilerplate, &update_context), + JSObject); + } + return boilerplate; + } else { + PretenureFlag pretenure_flag = + isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; + boilerplate = + Boilerplate::Create(isolate, description, flags, pretenure_flag); + } + // Install AllocationSite objects. AllocationSiteCreationContext creation_context(isolate); site = creation_context.EnterNewScope(); - if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate), - &creation_context).is_null()) { - return Handle<AllocationSite>::null(); - } - creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); + RETURN_ON_EXCEPTION(isolate, DeepWalk(boilerplate, &creation_context), + JSObject); + creation_context.ExitScope(site, boilerplate); vector->Set(literals_slot, *site); - } else { - site = Handle<AllocationSite>::cast(literal_site); } - return site; -} - -static MaybeHandle<JSObject> CreateArrayLiteralImpl( - Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot literals_slot, - Handle<ConstantElementsPair> elements, int flags) { - CHECK(literals_slot.ToInt() < vector->slot_count()); - Handle<AllocationSite> site; - ASSIGN_RETURN_ON_EXCEPTION( - isolate, site, - GetLiteralAllocationSite(isolate, vector, literals_slot, elements), - JSObject); + STATIC_ASSERT(static_cast<int>(ObjectLiteral::kDisableMementos) == + static_cast<int>(ArrayLiteral::kDisableMementos)); + bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; - bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; - Handle<JSObject> boilerplate(JSObject::cast(site->transition_info())); + // Copy the existing boilerplate. AllocationSiteUsageContext usage_context(isolate, site, enable_mementos); usage_context.EnterNewScope(); - JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0 - ? JSObject::kNoHints - : JSObject::kObjectIsShallow; MaybeHandle<JSObject> copy = - JSObject::DeepCopy(boilerplate, &usage_context, hints); + DeepCopy(boilerplate, &usage_context, copy_hints); usage_context.ExitScope(site, boilerplate); return copy; } +} // namespace +RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { + HandleScope scope(isolate); + DCHECK_EQ(4, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); + CONVERT_SMI_ARG_CHECKED(literals_index, 1); + CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, description, 2); + CONVERT_SMI_ARG_CHECKED(flags, 3); + RETURN_RESULT_OR_FAILURE( + isolate, CreateLiteral<ObjectBoilerplate>( + isolate, closure, literals_index, description, flags)); +} RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { HandleScope scope(isolate); @@ -317,27 +537,35 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { CONVERT_SMI_ARG_CHECKED(literals_index, 1); CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); CONVERT_SMI_ARG_CHECKED(flags, 3); - - FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); - Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); RETURN_RESULT_OR_FAILURE( - isolate, - CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, flags)); + isolate, CreateLiteral<ArrayBoilerplate>(isolate, closure, literals_index, + elements, flags)); } - -RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { +RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); + DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); - CONVERT_SMI_ARG_CHECKED(literals_index, 1); - CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); + CONVERT_SMI_ARG_CHECKED(index, 1); + CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); + CONVERT_SMI_ARG_CHECKED(flags, 3); Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); - FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); - RETURN_RESULT_OR_FAILURE( - isolate, CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, - ArrayLiteral::kShallowElements)); + FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); + + // Check if boilerplate exists. If not, create it first. + Handle<Object> literal_site(vector->Get(literal_slot), isolate); + Handle<Object> boilerplate; + if (!HasBoilerplate(isolate, literal_site)) { + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags))); + if (IsUninitializedLiteralSite(literal_site)) { + PreInitializeLiteralSite(vector, literal_slot); + return *boilerplate; + } + vector->Set(literal_slot, *boilerplate); + } + return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate)); } } // namespace internal diff --git a/chromium/v8/src/runtime/runtime-liveedit.cc b/chromium/v8/src/runtime/runtime-liveedit.cc index fa49df88dad..9d57d01b7f6 100644 --- a/chromium/v8/src/runtime/runtime-liveedit.cc +++ b/chromium/v8/src/runtime/runtime-liveedit.cc @@ -44,7 +44,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) { for (int i = 0; i < found.length(); ++i) { Handle<SharedFunctionInfo> shared = found[i]; SharedInfoWrapper info_wrapper = SharedInfoWrapper::Create(isolate); - Handle<String> name(String::cast(shared->name())); + Handle<String> name(shared->name(), isolate); info_wrapper.SetProperties(name, shared->start_position(), shared->end_position(), shared); result->set(i, *info_wrapper.GetJSArray()); @@ -223,7 +223,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) { CHECK(new_shared_array->length() == old_shared_array->length()); CHECK(old_shared_array->HasFastElements()); CHECK(new_shared_array->HasFastElements()); - int array_length = Smi::cast(old_shared_array->length())->value(); + int array_length = Smi::ToInt(old_shared_array->length()); for (int i = 0; i < array_length; i++) { Handle<Object> old_element; Handle<Object> new_element; diff --git a/chromium/v8/src/runtime/runtime-module.cc b/chromium/v8/src/runtime/runtime-module.cc index 3c896d8c566..af156ea7cef 100644 --- a/chromium/v8/src/runtime/runtime-module.cc +++ b/chromium/v8/src/runtime/runtime-module.cc @@ -17,32 +17,12 @@ RUNTIME_FUNCTION(Runtime_DynamicImportCall) { CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); CONVERT_ARG_HANDLE_CHECKED(Object, specifier, 1); - Handle<JSPromise> promise = isolate->factory()->NewJSPromise(); - - Handle<String> specifier_str; - MaybeHandle<String> maybe_specifier = Object::ToString(isolate, specifier); - if (!maybe_specifier.ToHandle(&specifier_str)) { - DCHECK(isolate->has_pending_exception()); - Handle<Object> reason(isolate->pending_exception(), isolate); - isolate->clear_pending_exception(); - - Handle<Object> argv[] = {promise, reason, - isolate->factory()->ToBoolean(false)}; - - RETURN_FAILURE_ON_EXCEPTION( - isolate, Execution::Call(isolate, isolate->promise_internal_reject(), - isolate->factory()->undefined_value(), - arraysize(argv), argv)) - return *promise; - } - DCHECK(!isolate->has_pending_exception()); - Handle<Script> script(Script::cast(function->shared()->script())); Handle<String> source_url(String::cast(script->name())); - isolate->RunHostImportModuleDynamicallyCallback(source_url, specifier_str, - promise); - return *promise; + RETURN_RESULT_OR_FAILURE( + isolate, + isolate->RunHostImportModuleDynamicallyCallback(source_url, specifier)); } RUNTIME_FUNCTION(Runtime_GetModuleNamespace) { diff --git a/chromium/v8/src/runtime/runtime-object.cc b/chromium/v8/src/runtime/runtime-object.cc index eef2e6616a6..3e76e4efe2c 100644 --- a/chromium/v8/src/runtime/runtime-object.cc +++ b/chromium/v8/src/runtime/runtime-object.cc @@ -67,11 +67,11 @@ static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate, DisallowHeapAllocation no_allocation; if (receiver->IsJSGlobalObject()) { // Attempt dictionary lookup. - GlobalDictionary* dictionary = receiver->global_dictionary(); + GlobalDictionary* dictionary = + JSGlobalObject::cast(*receiver)->global_dictionary(); int entry = dictionary->FindEntry(key); if (entry != GlobalDictionary::kNotFound) { - DCHECK(dictionary->ValueAt(entry)->IsPropertyCell()); - PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry)); + PropertyCell* cell = dictionary->CellAt(entry); if (cell->property_details().kind() == kData) { Object* value = cell->value(); if (!value->IsTheHole(isolate)) { @@ -96,18 +96,17 @@ static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate, // that subsequent accesses will also call the runtime. Proactively // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of // doubles for those future calls in the case that the elements would - // become FAST_DOUBLE_ELEMENTS. + // become PACKED_DOUBLE_ELEMENTS. Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj); ElementsKind elements_kind = js_object->GetElementsKind(); - if (IsFastDoubleElementsKind(elements_kind)) { - if (Smi::cast(*key_obj)->value() >= js_object->elements()->length()) { - elements_kind = IsFastHoleyElementsKind(elements_kind) - ? FAST_HOLEY_ELEMENTS - : FAST_ELEMENTS; + if (IsDoubleElementsKind(elements_kind)) { + if (Smi::ToInt(*key_obj) >= js_object->elements()->length()) { + elements_kind = IsHoleyElementsKind(elements_kind) ? HOLEY_ELEMENTS + : PACKED_ELEMENTS; JSObject::TransitionElementsKind(js_object, elements_kind); } } else { - DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) || + DCHECK(IsSmiOrObjectElementsKind(elements_kind) || !IsFastElementsKind(elements_kind)); } } @@ -306,11 +305,9 @@ RUNTIME_FUNCTION(Runtime_AddDictionaryProperty) { DCHECK(name->IsUniqueName()); Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate); - int entry; - PropertyDetails property_details(kData, NONE, 0, PropertyCellType::kNoCell); - dictionary = - NameDictionary::Add(dictionary, name, value, property_details, &entry); - receiver->set_properties(*dictionary); + PropertyDetails property_details(kData, NONE, PropertyCellType::kNoCell); + dictionary = NameDictionary::Add(dictionary, name, value, property_details); + receiver->SetProperties(*dictionary); return *value; } @@ -387,6 +384,17 @@ RUNTIME_FUNCTION(Runtime_InternalSetPrototype) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); + if (prototype->IsJSFunction()) { + Handle<JSFunction> function = Handle<JSFunction>::cast(prototype); + if (!function->shared()->has_shared_name()) { + Handle<Map> function_map(function->map(), isolate); + if (!JSFunction::SetName(function, isolate->factory()->proto_string(), + isolate->factory()->empty_string())) { + return isolate->heap()->exception(); + } + CHECK_EQ(*function_map, function->map()); + } + } MAYBE_RETURN( JSReceiver::SetPrototype(obj, prototype, false, Object::THROW_ON_ERROR), isolate->heap()->exception()); @@ -498,7 +506,7 @@ RUNTIME_FUNCTION(Runtime_AppendElement) { RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::AddDataElement(array, index, value, NONE)); - JSObject::ValidateElements(array); + JSObject::ValidateElements(*array); return *array; } @@ -546,13 +554,11 @@ RUNTIME_FUNCTION(Runtime_DeleteProperty) { RUNTIME_FUNCTION(Runtime_ShrinkPropertyDictionary) { HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); Handle<NameDictionary> dictionary(receiver->property_dictionary(), isolate); - Handle<NameDictionary> new_properties = - NameDictionary::Shrink(dictionary, key); - receiver->set_properties(*new_properties); + Handle<NameDictionary> new_properties = NameDictionary::Shrink(dictionary); + receiver->SetProperties(*new_properties); return Smi::kZero; } @@ -669,7 +675,8 @@ RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { CHECK(field_index.property_index() < object->map()->GetInObjectProperties()); } else { - CHECK(field_index.outobject_array_index() < object->properties()->length()); + CHECK(field_index.outobject_array_index() < + object->property_dictionary()->length()); } return *JSObject::FastPropertyAt(object, Representation::Double(), field_index); @@ -762,8 +769,16 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) { if (flags & DataPropertyInLiteralFlag::kSetFunctionName) { DCHECK(value->IsJSFunction()); - JSFunction::SetName(Handle<JSFunction>::cast(value), name, - isolate->factory()->empty_string()); + Handle<JSFunction> function = Handle<JSFunction>::cast(value); + DCHECK(!function->shared()->has_shared_name()); + Handle<Map> function_map(function->map(), isolate); + if (!JSFunction::SetName(function, name, + isolate->factory()->empty_string())) { + return isolate->heap()->exception(); + } + // Class constructors do not reserve in-object space for name field. + CHECK_IMPLIES(!IsClassConstructor(function->shared()->kind()), + *function_map == function->map()); } LookupIterator it = LookupIterator::PropertyOrElement( @@ -861,7 +876,11 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) { CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); if (String::cast(getter->shared()->name())->length() == 0) { - JSFunction::SetName(getter, name, isolate->factory()->get_string()); + Handle<Map> getter_map(getter->map(), isolate); + if (!JSFunction::SetName(getter, name, isolate->factory()->get_string())) { + return isolate->heap()->exception(); + } + CHECK_EQ(*getter_map, getter->map()); } RETURN_FAILURE_ON_EXCEPTION( @@ -922,6 +941,64 @@ RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) { return *target; } +namespace { + +inline void TrySetNative(Handle<Object> maybe_func) { + if (!maybe_func->IsJSFunction()) return; + JSFunction::cast(*maybe_func)->shared()->set_native(true); +} + +inline void TrySetNativeAndLength(Handle<Object> maybe_func, int length) { + if (!maybe_func->IsJSFunction()) return; + SharedFunctionInfo* shared = JSFunction::cast(*maybe_func)->shared(); + shared->set_native(true); + if (length >= 0) { + shared->set_length(length); + } +} + +} // namespace + +RUNTIME_FUNCTION(Runtime_DefineMethodsInternal) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + CHECK(isolate->bootstrapper()->IsActive()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, source_class, 1); + CONVERT_SMI_ARG_CHECKED(length, 2); + + DCHECK(source_class->prototype()->IsJSObject()); + Handle<JSObject> source(JSObject::cast(source_class->prototype()), isolate); + + Handle<FixedArray> keys; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, keys, + KeyAccumulator::GetKeys(source, KeyCollectionMode::kOwnOnly, + ALL_PROPERTIES, + GetKeysConversion::kConvertToString)); + + for (int i = 0; i < keys->length(); ++i) { + Handle<Name> key = Handle<Name>::cast(FixedArray::get(*keys, i, isolate)); + if (*key == isolate->heap()->constructor_string()) continue; + + PropertyDescriptor descriptor; + Maybe<bool> did_get_descriptor = + JSReceiver::GetOwnPropertyDescriptor(isolate, source, key, &descriptor); + CHECK(did_get_descriptor.FromJust()); + if (descriptor.has_value()) { + TrySetNativeAndLength(descriptor.value(), length); + } else { + if (descriptor.has_get()) TrySetNative(descriptor.get()); + if (descriptor.has_set()) TrySetNative(descriptor.set()); + } + + Maybe<bool> success = JSReceiver::DefineOwnProperty( + isolate, target, key, &descriptor, Object::DONT_THROW); + CHECK(success.FromJust()); + } + return isolate->heap()->undefined_value(); +} + RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); @@ -931,7 +1008,11 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) { CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3); if (String::cast(setter->shared()->name())->length() == 0) { - JSFunction::SetName(setter, name, isolate->factory()->set_string()); + Handle<Map> setter_map(setter->map(), isolate); + if (!JSFunction::SetName(setter, name, isolate->factory()->set_string())) { + return isolate->heap()->exception(); + } + CHECK_EQ(*setter_map, setter->map()); } RETURN_FAILURE_ON_EXCEPTION( @@ -1052,10 +1133,11 @@ RUNTIME_FUNCTION(Runtime_Compare) { RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); - Maybe<bool> result = - JSReceiver::HasInPrototypeChain(isolate, object, prototype); + if (!object->IsJSReceiver()) return isolate->heap()->false_value(); + Maybe<bool> result = JSReceiver::HasInPrototypeChain( + isolate, Handle<JSReceiver>::cast(object), prototype); MAYBE_RETURN(result, isolate->heap()->exception()); return isolate->heap()->ToBoolean(result.FromJust()); } @@ -1070,26 +1152,6 @@ RUNTIME_FUNCTION(Runtime_CreateIterResultObject) { return *isolate->factory()->NewJSIteratorResult(value, done->BooleanValue()); } -RUNTIME_FUNCTION(Runtime_CreateKeyValueArray) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, key, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); - Handle<FixedArray> elements = isolate->factory()->NewFixedArray(2); - elements->set(0, *key); - elements->set(1, *value); - return *isolate->factory()->NewJSArrayWithElements(elements, FAST_ELEMENTS, - 2); -} - -RUNTIME_FUNCTION(Runtime_IsAccessCheckNeeded) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(Object, object, 0); - return isolate->heap()->ToBoolean(object->IsAccessCheckNeeded()); -} - - RUNTIME_FUNCTION(Runtime_CreateDataProperty) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); diff --git a/chromium/v8/src/runtime/runtime-proxy.cc b/chromium/v8/src/runtime/runtime-proxy.cc index de8231e2e95..05c3cf61ba8 100644 --- a/chromium/v8/src/runtime/runtime-proxy.cc +++ b/chromium/v8/src/runtime/runtime-proxy.cc @@ -14,60 +14,6 @@ namespace v8 { namespace internal { -// ES6 9.5.13 [[Call]] (thisArgument, argumentsList) -RUNTIME_FUNCTION(Runtime_JSProxyCall) { - HandleScope scope(isolate); - DCHECK_LE(2, args.length()); - // thisArgument == receiver - CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); - CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, args.length() - 1); - Handle<String> trap_name = isolate->factory()->apply_string(); - // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. - Handle<Object> handler(proxy->handler(), isolate); - // 2. If handler is null, throw a TypeError exception. - if (proxy->IsRevoked()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, NewTypeError(MessageTemplate::kProxyRevoked, trap_name)); - } - // 3. Assert: Type(handler) is Object. - DCHECK(handler->IsJSReceiver()); - // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. - Handle<JSReceiver> target(proxy->target(), isolate); - // 5. Let trap be ? GetMethod(handler, "apply"). - Handle<Object> trap; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, trap, - Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name)); - // 6. If trap is undefined, then - int const arguments_length = args.length() - 2; - if (trap->IsUndefined(isolate)) { - // 6.a. Return Call(target, thisArgument, argumentsList). - ScopedVector<Handle<Object>> argv(arguments_length); - for (int i = 0; i < arguments_length; ++i) { - argv[i] = args.at(i + 1); - } - RETURN_RESULT_OR_FAILURE( - isolate, Execution::Call(isolate, target, receiver, arguments_length, - argv.start())); - } - // 7. Let argArray be CreateArrayFromList(argumentsList). - Handle<JSArray> arg_array = isolate->factory()->NewJSArray( - FAST_ELEMENTS, arguments_length, arguments_length); - ElementsAccessor* accessor = arg_array->GetElementsAccessor(); - { - DisallowHeapAllocation no_gc; - for (int i = 0; i < arguments_length; i++) { - accessor->Set(arg_array, i, args[i + 1]); - } - } - // 8. Return Call(trap, handler, «target, thisArgument, argArray»). - Handle<Object> trap_args[] = {target, receiver, arg_array}; - RETURN_RESULT_OR_FAILURE( - isolate, - Execution::Call(isolate, trap, handler, arraysize(trap_args), trap_args)); -} - - // 9.5.14 [[Construct]] (argumentsList, newTarget) RUNTIME_FUNCTION(Runtime_JSProxyConstruct) { HandleScope scope(isolate); @@ -108,7 +54,7 @@ RUNTIME_FUNCTION(Runtime_JSProxyConstruct) { } // 7. Let argArray be CreateArrayFromList(argumentsList). Handle<JSArray> arg_array = isolate->factory()->NewJSArray( - FAST_ELEMENTS, arguments_length, arguments_length); + PACKED_ELEMENTS, arguments_length, arguments_length); ElementsAccessor* accessor = arg_array->GetElementsAccessor(); { DisallowHeapAllocation no_gc; diff --git a/chromium/v8/src/runtime/runtime-regexp.cc b/chromium/v8/src/runtime/runtime-regexp.cc index 8803deff0f6..a5d61d83487 100644 --- a/chromium/v8/src/runtime/runtime-regexp.cc +++ b/chromium/v8/src/runtime/runtime-regexp.cc @@ -39,7 +39,7 @@ int LookupNamedCapture(std::function<bool(String*)> name_matches, String* capture_name = String::cast(capture_name_map->get(name_ix)); if (!name_matches(capture_name)) continue; - maybe_capture_index = Smi::cast(capture_name_map->get(index_ix))->value(); + maybe_capture_index = Smi::ToInt(capture_name_map->get(index_ix)); break; } @@ -869,10 +869,10 @@ RUNTIME_FUNCTION(Runtime_StringSplit) { int part_count = indices->length(); Handle<JSArray> result = - isolate->factory()->NewJSArray(FAST_ELEMENTS, part_count, part_count, + isolate->factory()->NewJSArray(PACKED_ELEMENTS, part_count, part_count, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); - DCHECK(result->HasFastObjectElements()); + DCHECK(result->HasObjectElements()); Handle<FixedArray> elements(FixedArray::cast(result->elements())); @@ -890,7 +890,7 @@ RUNTIME_FUNCTION(Runtime_StringSplit) { } if (limit == 0xffffffffu) { - if (result->HasFastObjectElements()) { + if (result->HasObjectElements()) { RegExpResultsCache::Enter(isolate, subject, pattern, elements, isolate->factory()->empty_fixed_array(), RegExpResultsCache::STRING_SPLIT_SUBSTRINGS); @@ -1140,7 +1140,7 @@ Handle<JSObject> ConstructNamedCaptureGroupsObject( const int index_ix = i * 2 + 1; Handle<String> capture_name(String::cast(capture_map->get(name_ix))); - const int capture_ix = Smi::cast(capture_map->get(index_ix))->value(); + const int capture_ix = Smi::ToInt(capture_map->get(index_ix)); DCHECK(1 <= capture_ix && capture_ix <= capture_count); Handle<Object> capture_value(f_get_capture(capture_ix), isolate); @@ -1177,7 +1177,7 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, int capture_registers = (capture_count + 1) * 2; int32_t* last_match = NewArray<int32_t>(capture_registers); for (int i = 0; i < capture_registers; i++) { - last_match[i] = Smi::cast(last_match_cache->get(i))->value(); + last_match[i] = Smi::ToInt(last_match_cache->get(i)); } Handle<FixedArray> cached_fixed_array = Handle<FixedArray>(FixedArray::cast(cached_answer)); @@ -1197,7 +1197,7 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, if (global_cache.HasException()) return isolate->heap()->exception(); // Ensured in Runtime_RegExpExecMultiple. - DCHECK(result_array->HasFastObjectElements()); + DCHECK(result_array->HasObjectElements()); Handle<FixedArray> result_elements( FixedArray::cast(result_array->elements())); if (result_elements->length() < 16) { @@ -1423,7 +1423,6 @@ MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate, } UNREACHABLE(); - return MaybeHandle<String>(); } } // namespace @@ -1437,7 +1436,7 @@ RUNTIME_FUNCTION(Runtime_RegExpExecMultiple) { CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); CONVERT_ARG_HANDLE_CHECKED(RegExpMatchInfo, last_match_info, 2); CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); - CHECK(result_array->HasFastObjectElements()); + CHECK(result_array->HasObjectElements()); subject = String::Flatten(subject); CHECK(regexp->GetFlags() & JSRegExp::kGlobal); diff --git a/chromium/v8/src/runtime/runtime-scopes.cc b/chromium/v8/src/runtime/runtime-scopes.cc index 76e7c2b1861..38545139df9 100644 --- a/chromium/v8/src/runtime/runtime-scopes.cc +++ b/chromium/v8/src/runtime/runtime-scopes.cc @@ -139,7 +139,7 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, int length = declarations->length(); FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 4, { Handle<String> name(String::cast(declarations->get(i)), isolate); - FeedbackSlot slot(Smi::cast(declarations->get(i + 1))->value()); + FeedbackSlot slot(Smi::ToInt(declarations->get(i + 1))); Handle<Object> possibly_literal_slot(declarations->get(i + 2), isolate); Handle<Object> initial_value(declarations->get(i + 3), isolate); @@ -153,7 +153,7 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, // Copy the function and update its context. Use it as value. Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(initial_value); - FeedbackSlot literals_slot(Smi::cast(*possibly_literal_slot)->value()); + FeedbackSlot literals_slot(Smi::ToInt(*possibly_literal_slot)); Handle<Cell> literals(Cell::cast(feedback_vector->Get(literals_slot)), isolate); Handle<JSFunction> function = @@ -211,18 +211,6 @@ RUNTIME_FUNCTION(Runtime_DeclareGlobalsForInterpreter) { return DeclareGlobals(isolate, declarations, flags, feedback_vector); } -RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(String, name, 0); - CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); - - Handle<JSGlobalObject> global(isolate->global_object()); - RETURN_RESULT_OR_FAILURE( - isolate, Object::SetProperty(global, name, value, language_mode)); -} - namespace { Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, @@ -248,7 +236,9 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, VariableMode mode; // Check for a conflict with a lexically scoped variable - context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &init_flag, + const ContextLookupFlags lookup_flags = static_cast<ContextLookupFlags>( + FOLLOW_CONTEXT_CHAIN | STOP_AT_DECLARATION_SCOPE | SKIP_WITH_CONTEXT); + context_arg->Lookup(name, lookup_flags, &index, &attributes, &init_flag, &mode); if (attributes != ABSENT && IsLexicalVariableMode(mode)) { // ES#sec-evaldeclarationinstantiation 5.a.i.1: @@ -262,6 +252,7 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, &attributes, &init_flag, &mode); + DCHECK(holder.is_null() || !holder->IsModule()); DCHECK(!isolate->has_pending_exception()); Handle<JSObject> object; @@ -572,9 +563,9 @@ RUNTIME_FUNCTION(Runtime_NewRestParameter) { std::unique_ptr<Handle<Object>[]> arguments = GetCallerArguments(isolate, &argument_count); int num_elements = std::max(0, argument_count - start_index); - Handle<JSObject> result = - isolate->factory()->NewJSArray(FAST_ELEMENTS, num_elements, num_elements, - DONT_INITIALIZE_ARRAY_ELEMENTS); + Handle<JSObject> result = isolate->factory()->NewJSArray( + PACKED_ELEMENTS, num_elements, num_elements, + DONT_INITIALIZE_ARRAY_ELEMENTS); { DisallowHeapAllocation no_gc; FixedArray* elements = FixedArray::cast(result->elements()); @@ -823,8 +814,9 @@ RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { return isolate->heap()->true_value(); } - // If the slot was found in a context, it should be DONT_DELETE. - if (holder->IsContext()) { + // If the slot was found in a context or in module imports and exports it + // should be DONT_DELETE. + if (holder->IsContext() || holder->IsModule()) { return isolate->heap()->false_value(); } @@ -853,6 +845,9 @@ MaybeHandle<Object> LoadLookupSlot(Handle<String> name, name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); if (isolate->has_pending_exception()) return MaybeHandle<Object>(); + if (!holder.is_null() && holder->IsModule()) { + return Module::LoadVariable(Handle<Module>::cast(holder), index); + } if (index != Context::kNotFound) { DCHECK(holder->IsContext()); // If the "property" we were looking for is a local variable, the @@ -936,8 +931,9 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) { namespace { -MaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value, - LanguageMode language_mode) { +MaybeHandle<Object> StoreLookupSlot( + Handle<String> name, Handle<Object> value, LanguageMode language_mode, + ContextLookupFlags context_lookup_flags = FOLLOW_CHAINS) { Isolate* const isolate = name->GetIsolate(); Handle<Context> context(isolate->context(), isolate); @@ -945,13 +941,22 @@ MaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value, PropertyAttributes attributes; InitializationFlag flag; VariableMode mode; - Handle<Object> holder = - context->Lookup(name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); + Handle<Object> holder = context->Lookup(name, context_lookup_flags, &index, + &attributes, &flag, &mode); if (holder.is_null()) { // In case of JSProxy, an exception might have been thrown. if (isolate->has_pending_exception()) return MaybeHandle<Object>(); + } else if (holder->IsModule()) { + if ((attributes & READ_ONLY) == 0) { + Module::StoreVariable(Handle<Module>::cast(holder), index, value); + } else if (is_strict(language_mode)) { + // Setting read only property in strict mode. + THROW_NEW_ERROR(isolate, + NewTypeError(MessageTemplate::kStrictCannotAssign, name), + Object); + } + return value; } - // The property was found in a context slot. if (index != Context::kNotFound) { if (flag == kNeedsInitialization && @@ -1004,6 +1009,19 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) { RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, SLOPPY)); } +// Store into a dynamic context for sloppy-mode block-scoped function hoisting +// which leaks out of an eval. In particular, with-scopes are be skipped to +// reach the appropriate var-like declaration. +RUNTIME_FUNCTION(Runtime_StoreLookupSlot_SloppyHoisting) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, name, 0); + CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); + const ContextLookupFlags lookup_flags = static_cast<ContextLookupFlags>( + FOLLOW_CONTEXT_CHAIN | STOP_AT_DECLARATION_SCOPE | SKIP_WITH_CONTEXT); + RETURN_RESULT_OR_FAILURE(isolate, + StoreLookupSlot(name, value, SLOPPY, lookup_flags)); +} RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { HandleScope scope(isolate); diff --git a/chromium/v8/src/runtime/runtime-strings.cc b/chromium/v8/src/runtime/runtime-strings.cc index 99fbf2d475a..adc388196b0 100644 --- a/chromium/v8/src/runtime/runtime-strings.cc +++ b/chromium/v8/src/runtime/runtime-strings.cc @@ -108,7 +108,6 @@ MaybeHandle<String> StringReplaceOneCharWithString( } } - RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); @@ -197,7 +196,6 @@ RUNTIME_FUNCTION(Runtime_SubString) { return *isolate->factory()->NewSubString(string, start, end); } - RUNTIME_FUNCTION(Runtime_StringAdd) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -208,6 +206,22 @@ RUNTIME_FUNCTION(Runtime_StringAdd) { isolate->factory()->NewConsString(str1, str2)); } +RUNTIME_FUNCTION(Runtime_StringConcat) { + HandleScope scope(isolate); + DCHECK_LE(2, args.length()); + int const argc = args.length(); + ScopedVector<Handle<Object>> argv(argc); + + isolate->counters()->string_add_runtime()->Increment(); + IncrementalStringBuilder builder(isolate); + for (int i = 0; i < argc; ++i) { + Handle<String> str = Handle<String>::cast(args.at(i)); + if (str->length() != 0) { + builder.AppendString(str); + } + } + RETURN_RESULT_OR_FAILURE(isolate, builder.Finish()); +} RUNTIME_FUNCTION(Runtime_InternalizeString) { HandleScope handles(isolate); @@ -216,7 +230,6 @@ RUNTIME_FUNCTION(Runtime_InternalizeString) { return *isolate->factory()->InternalizeString(string); } - RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { HandleScope handle_scope(isolate); DCHECK_EQ(2, args.length()); @@ -236,7 +249,6 @@ RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) { return Smi::FromInt(subject->Get(i)); } - RUNTIME_FUNCTION(Runtime_StringCompare) { HandleScope handle_scope(isolate); DCHECK_EQ(2, args.length()); @@ -254,10 +266,8 @@ RUNTIME_FUNCTION(Runtime_StringCompare) { break; } UNREACHABLE(); - return Smi::kZero; } - RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); @@ -280,7 +290,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { JSObject::EnsureCanContainHeapObjectElements(array); int special_length = special->length(); - if (!array->HasFastObjectElements()) { + if (!array->HasObjectElements()) { return isolate->Throw(isolate->heap()->illegal_argument_string()); } @@ -330,7 +340,6 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { } } - RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); @@ -340,7 +349,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError()); } CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); - CHECK(array->HasFastObjectElements()); + CHECK(array->HasObjectElements()); CHECK(array_length >= 0); Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); @@ -471,7 +480,6 @@ static void JoinSparseArrayWithSeparator(FixedArray* elements, DCHECK(cursor <= buffer.length()); } - RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); @@ -480,7 +488,7 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); // elements_array is fast-mode JSarray of alternating positions // (increasing order) and strings. - CHECK(elements_array->HasFastSmiOrObjectElements()); + CHECK(elements_array->HasSmiOrObjectElements()); // array_length is length of original array (used to add separators); // separator is string to put between elements. Assumed to be non-empty. CHECK(array_length > 0); @@ -556,7 +564,6 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { } } - // Copies Latin1 characters to the given fixed array looking up // one-char strings in the cache. Gives up on the first char that is // not in the cache and fills the remainder with smi zeros. Returns @@ -587,7 +594,6 @@ static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars, return i; } - // Converts a String to JSArray. // For example, "foo" => ["f", "o", "o"]. RUNTIME_FUNCTION(Runtime_StringToArray) { @@ -635,7 +641,6 @@ RUNTIME_FUNCTION(Runtime_StringToArray) { return *isolate->factory()->NewJSArrayWithElements(elements); } - RUNTIME_FUNCTION(Runtime_StringLessThan) { HandleScope handle_scope(isolate); DCHECK_EQ(2, args.length()); @@ -651,7 +656,6 @@ RUNTIME_FUNCTION(Runtime_StringLessThan) { break; } UNREACHABLE(); - return Smi::kZero; } RUNTIME_FUNCTION(Runtime_StringLessThanOrEqual) { @@ -669,7 +673,6 @@ RUNTIME_FUNCTION(Runtime_StringLessThanOrEqual) { break; } UNREACHABLE(); - return Smi::kZero; } RUNTIME_FUNCTION(Runtime_StringGreaterThan) { @@ -687,7 +690,6 @@ RUNTIME_FUNCTION(Runtime_StringGreaterThan) { break; } UNREACHABLE(); - return Smi::kZero; } RUNTIME_FUNCTION(Runtime_StringGreaterThanOrEqual) { @@ -705,7 +707,6 @@ RUNTIME_FUNCTION(Runtime_StringGreaterThanOrEqual) { break; } UNREACHABLE(); - return Smi::kZero; } RUNTIME_FUNCTION(Runtime_StringEqual) { @@ -731,7 +732,6 @@ RUNTIME_FUNCTION(Runtime_FlattenString) { return *String::Flatten(str); } - RUNTIME_FUNCTION(Runtime_StringCharFromCode) { HandleScope handlescope(isolate); DCHECK_EQ(1, args.length()); diff --git a/chromium/v8/src/runtime/runtime-test.cc b/chromium/v8/src/runtime/runtime-test.cc index 6e1d09f6ad7..10deb672168 100644 --- a/chromium/v8/src/runtime/runtime-test.cc +++ b/chromium/v8/src/runtime/runtime-test.cc @@ -71,61 +71,18 @@ void ThrowRangeException(v8::Isolate* isolate, const char* message) { isolate->ThrowException(NewRangeException(isolate, message)); } -void RejectPromiseWithRangeError( - const v8::FunctionCallbackInfo<v8::Value>& args, const char* message) { - v8::Isolate* isolate = args.GetIsolate(); - v8::HandleScope scope(isolate); - - v8::Local<v8::Context> context = isolate->GetCurrentContext(); - v8::Local<v8::Promise::Resolver> resolver; - if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; - v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); - return_value.Set(resolver->GetPromise()); - - auto maybe = resolver->Reject(context, NewRangeException(isolate, message)); - CHECK(!maybe.IsNothing()); - return; -} - bool WasmModuleOverride(const v8::FunctionCallbackInfo<v8::Value>& args) { if (IsWasmCompileAllowed(args.GetIsolate(), args[0], false)) return false; ThrowRangeException(args.GetIsolate(), "Sync compile not allowed"); return true; } -bool WasmCompileOverride(const v8::FunctionCallbackInfo<v8::Value>& args) { - if (IsWasmCompileAllowed(args.GetIsolate(), args[0], true)) return false; - RejectPromiseWithRangeError(args, "Async compile not allowed"); - return true; -} - bool WasmInstanceOverride(const v8::FunctionCallbackInfo<v8::Value>& args) { if (IsWasmInstantiateAllowed(args.GetIsolate(), args[0], false)) return false; ThrowRangeException(args.GetIsolate(), "Sync instantiate not allowed"); return true; } -bool WasmInstantiateOverride(const v8::FunctionCallbackInfo<v8::Value>& args) { - if (IsWasmInstantiateAllowed(args.GetIsolate(), args[0], true)) return false; - RejectPromiseWithRangeError(args, "Async instantiate not allowed"); - return true; -} - -bool GetWasmFromArray(const v8::FunctionCallbackInfo<v8::Value>& args) { - CHECK(args.Length() == 1); - v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); - v8::Local<v8::Value> module = - v8::Local<v8::Object>::Cast(args[0])->Get(context, 0).ToLocalChecked(); - - v8::Local<v8::Promise::Resolver> resolver = - v8::Promise::Resolver::New(context).ToLocalChecked(); - args.GetReturnValue().Set(resolver->GetPromise()); - USE(resolver->Resolve(context, module)); - return true; -} - -bool NoExtension(const v8::FunctionCallbackInfo<v8::Value>&) { return false; } - } // namespace namespace v8 { @@ -165,14 +122,13 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) { return isolate->heap()->undefined_value(); } Handle<JSFunction> function = Handle<JSFunction>::cast(function_object); - function->shared()->set_marked_for_tier_up(false); // If the function is not optimized, just return. if (!function->IsOptimized()) return isolate->heap()->undefined_value(); - // TODO(turbofan): Deoptimization is not supported yet. + // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported. if (function->code()->is_turbofanned() && - function->shared()->asm_function()) { + !function->shared()->HasBytecodeArray()) { return isolate->heap()->undefined_value(); } @@ -196,9 +152,9 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { // If the function is not optimized, just return. if (!function->IsOptimized()) return isolate->heap()->undefined_value(); - // TODO(turbofan): Deoptimization is not supported yet. + // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported. if (function->code()->is_turbofanned() && - function->shared()->asm_function()) { + !function->shared()->HasBytecodeArray()) { return isolate->heap()->undefined_value(); } @@ -277,22 +233,41 @@ RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) { } // If the function is already optimized, just return. - if (function->IsOptimized()) return isolate->heap()->undefined_value(); + if (function->IsOptimized()) { + return isolate->heap()->undefined_value(); + } - function->MarkForOptimization(); - if (FLAG_trace_opt) { - PrintF("[manually marking "); - function->ShortPrint(); - PrintF(" for optimization]\n"); + // If the function has optimized code, ensure that we check for it and return. + if (function->HasOptimizedCode()) { + if (!function->IsInterpreted()) { + // For non I+TF path, install a shim which checks the optimization marker. + function->ReplaceCode( + isolate->builtins()->builtin(Builtins::kCheckOptimizationMarker)); + } + DCHECK(function->ChecksOptimizationMarker()); + return isolate->heap()->undefined_value(); } + ConcurrencyMode concurrency_mode = ConcurrencyMode::kNotConcurrent; if (args.length() == 2) { CONVERT_ARG_HANDLE_CHECKED(String, type, 1); if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) && isolate->concurrent_recompilation_enabled()) { - function->AttemptConcurrentOptimization(); + concurrency_mode = ConcurrencyMode::kConcurrent; } } + if (FLAG_trace_opt) { + PrintF("[manually marking "); + function->ShortPrint(); + PrintF(" for %s optimization]\n", + concurrency_mode == ConcurrencyMode::kConcurrent ? "concurrent" + : "non-concurrent"); + } + + // TODO(mvstanton): pass pretenure flag to EnsureLiterals. + JSFunction::EnsureLiterals(function); + + function->MarkForOptimization(concurrency_mode); return isolate->heap()->undefined_value(); } @@ -315,6 +290,17 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) { // If the function is already optimized, just return. if (function->IsOptimized()) return isolate->heap()->undefined_value(); + // Ensure that the function is marked for non-concurrent optimization, so that + // subsequent runs don't also optimize. + if (!function->HasOptimizedCode()) { + if (FLAG_trace_osr) { + PrintF("[OSR - OptimizeOsr marking "); + function->ShortPrint(); + PrintF(" for non-concurrent optimization]\n"); + } + function->MarkForOptimization(ConcurrencyMode::kNotConcurrent); + } + // Make the profiler arm all back edges in unoptimized code. if (it.frame()->type() == StackFrame::JAVA_SCRIPT || it.frame()->type() == StackFrame::INTERPRETED) { @@ -473,16 +459,6 @@ RUNTIME_FUNCTION(Runtime_ClearFunctionFeedback) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_SetWasmCompileFromPromiseOverload) { - isolate->set_wasm_compile_callback(GetWasmFromArray); - return isolate->heap()->undefined_value(); -} - -RUNTIME_FUNCTION(Runtime_ResetWasmOverloads) { - isolate->set_wasm_compile_callback(NoExtension); - return isolate->heap()->undefined_value(); -} - RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { // This only supports the case where the function being exported // calls an intermediate function, and the intermediate function @@ -492,9 +468,9 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { // It takes two parameters, the first one is the JSFunction, // The second one is the type CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - // If type is 0, it means that it is supposed to be a direct call into a WASM - // function - // If type is 1, it means that it is supposed to have wrappers + // If type is 0, it means that it is supposed to be a direct call into a wasm + // function. + // If type is 1, it means that it is supposed to have wrappers. CONVERT_ARG_HANDLE_CHECKED(Smi, type, 1); Handle<Code> export_code = handle(function->code()); CHECK(export_code->kind() == Code::JS_TO_WASM_FUNCTION); @@ -525,8 +501,8 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { } } CHECK(count == 1); - // check the type of the imported exported function, it should be also a WASM - // function in our case + // Check the type of the imported exported function, it should be also a wasm + // function in our case. Handle<Code> imported_fct; CHECK(type->value() == 0 || type->value() == 1); @@ -556,7 +532,6 @@ RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { ctrl.AllowAnySizeForAsync = allow_async; ctrl.MaxWasmBufferSize = static_cast<uint32_t>(block_size->value()); v8_isolate->SetWasmModuleCallback(WasmModuleOverride); - v8_isolate->SetWasmCompileCallback(WasmCompileOverride); return isolate->heap()->undefined_value(); } @@ -565,7 +540,6 @@ RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) { v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); CHECK(args.length() == 0); v8_isolate->SetWasmInstanceCallback(WasmInstanceOverride); - v8_isolate->SetWasmInstantiateCallback(WasmInstantiateOverride); return isolate->heap()->undefined_value(); } @@ -687,7 +661,6 @@ RUNTIME_FUNCTION(Runtime_Abort) { isolate->PrintStack(stderr); base::OS::Abort(); UNREACHABLE(); - return NULL; } @@ -699,7 +672,6 @@ RUNTIME_FUNCTION(Runtime_AbortJS) { isolate->PrintStack(stderr); base::OS::Abort(); UNREACHABLE(); - return NULL; } @@ -766,14 +738,6 @@ RUNTIME_FUNCTION(Runtime_TraceExit) { return obj; // return TOS } -RUNTIME_FUNCTION(Runtime_TraceTailCall) { - SealHandleScope shs(isolate); - DCHECK_EQ(0, args.length()); - PrintIndentation(isolate); - PrintF("} -> tail call ->\n"); - return isolate->heap()->undefined_value(); -} - RUNTIME_FUNCTION(Runtime_GetExceptionDetails) { HandleScope shs(isolate); DCHECK_EQ(1, args.length()); @@ -832,7 +796,8 @@ RUNTIME_FUNCTION(Runtime_IsAsmWasmCode) { } namespace { -bool DisallowCodegenFromStringsCallback(v8::Local<v8::Context> context) { +bool DisallowCodegenFromStringsCallback(v8::Local<v8::Context> context, + v8::Local<v8::String> source) { return false; } } @@ -860,11 +825,11 @@ RUNTIME_FUNCTION(Runtime_IsWasmCode) { return isolate->heap()->ToBoolean(obj->Has##Name()); \ } -ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements) -ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements) -ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements) -ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) -ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements) +ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiElements) +ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ObjectElements) +ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SmiOrObjectElements) +ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DoubleElements) +ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(HoleyElements) ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements) ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FixedTypedArrayElements) @@ -891,16 +856,12 @@ RUNTIME_FUNCTION(Runtime_SpeciesProtector) { return isolate->heap()->ToBoolean(isolate->IsArraySpeciesLookupChainIntact()); } -#define CONVERT_ARG_HANDLE_CHECKED_2(Type, name, index) \ - CHECK(Type::Is##Type(args[index])); \ - Handle<Type> name = args.at<Type>(index); - // Take a compiled wasm module, serialize it and copy the buffer into an array // buffer, which is then returned. RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { HandleScope shs(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); Handle<WasmCompiledModule> orig(module_obj->compiled_module()); std::unique_ptr<ScriptData> data = @@ -952,7 +913,7 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) { RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) { HandleScope shs(isolate); DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); CONVERT_ARG_HANDLE_CHECKED(Smi, instance_count, 1); wasm::testing::ValidateInstancesChain(isolate, module_obj, instance_count->value()); @@ -962,7 +923,7 @@ RUNTIME_FUNCTION(Runtime_ValidateWasmInstancesChain) { RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) { HandleScope shs(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED_2(WasmModuleObject, module_obj, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); wasm::testing::ValidateModuleState(isolate, module_obj); return isolate->heap()->ToBoolean(true); } @@ -970,7 +931,7 @@ RUNTIME_FUNCTION(Runtime_ValidateWasmModuleState) { RUNTIME_FUNCTION(Runtime_ValidateWasmOrphanedInstance) { HandleScope shs(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED_2(WasmInstanceObject, instance, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); wasm::testing::ValidateOrphanedInstance(isolate, instance); return isolate->heap()->ToBoolean(true); } @@ -995,10 +956,7 @@ RUNTIME_FUNCTION(Runtime_HeapObjectVerify) { RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) { DCHECK_EQ(1, args.length()); HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0); - CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj)); - Handle<WasmInstanceObject> instance = - Handle<WasmInstanceObject>::cast(instance_obj); + CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); if (!instance->has_debug_info()) return 0; uint64_t num = instance->debug_info()->NumInterpretedCalls(); return *isolate->factory()->NewNumberFromSize(static_cast<size_t>(num)); @@ -1007,11 +965,8 @@ RUNTIME_FUNCTION(Runtime_WasmNumInterpretedCalls) { RUNTIME_FUNCTION(Runtime_RedirectToWasmInterpreter) { DCHECK_EQ(2, args.length()); HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); CONVERT_SMI_ARG_CHECKED(function_index, 1); - CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj)); - Handle<WasmInstanceObject> instance = - Handle<WasmInstanceObject>::cast(instance_obj); Handle<WasmDebugInfo> debug_info = WasmInstanceObject::GetOrCreateDebugInfo(instance); WasmDebugInfo::RedirectToInterpreter(debug_info, diff --git a/chromium/v8/src/runtime/runtime-typedarray.cc b/chromium/v8/src/runtime/runtime-typedarray.cc index aa87c921eb4..54b9050b6ce 100644 --- a/chromium/v8/src/runtime/runtime-typedarray.cc +++ b/chromium/v8/src/runtime/runtime-typedarray.cc @@ -33,7 +33,9 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) { isolate, NewTypeError(MessageTemplate::kNotTypedArray)); } Handle<JSArrayBuffer> array_buffer = Handle<JSArrayBuffer>::cast(argument); - + if (!array_buffer->is_neuterable()) { + return isolate->heap()->undefined_value(); + } if (array_buffer->backing_store() == NULL) { CHECK(Smi::kZero == array_buffer->byte_length()); return isolate->heap()->undefined_value(); diff --git a/chromium/v8/src/runtime/runtime-wasm.cc b/chromium/v8/src/runtime/runtime-wasm.cc index bb5360abe99..a9f112d9755 100644 --- a/chromium/v8/src/runtime/runtime-wasm.cc +++ b/chromium/v8/src/runtime/runtime-wasm.cc @@ -180,12 +180,9 @@ RUNTIME_FUNCTION(Runtime_ClearThreadInWasm) { RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { DCHECK_EQ(3, args.length()); HandleScope scope(isolate); - CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0); + CONVERT_ARG_HANDLE_CHECKED(WasmInstanceObject, instance, 0); CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[1]); CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 2); - CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj)); - Handle<WasmInstanceObject> instance = - Handle<WasmInstanceObject>::cast(instance_obj); // The arg buffer is the raw pointer to the caller's stack. It looks like a // Smi (lowest bit not set, as checked by IsSmi), but is no valid Smi. We just diff --git a/chromium/v8/src/runtime/runtime.h b/chromium/v8/src/runtime/runtime.h index 386b1a81089..fedaa098f8e 100644 --- a/chromium/v8/src/runtime/runtime.h +++ b/chromium/v8/src/runtime/runtime.h @@ -36,27 +36,25 @@ namespace internal { // A variable number of arguments is specified by a -1, additional restrictions // are specified by inline comments -#define FOR_EACH_INTRINSIC_ARRAY(F) \ - F(SpecialArrayFunctions, 0, 1) \ - F(TransitionElementsKind, 2, 1) \ - F(RemoveArrayHoles, 2, 1) \ - F(MoveArrayContents, 2, 1) \ - F(EstimateNumberOfElements, 1, 1) \ - F(GetArrayKeys, 2, 1) \ - F(NewArray, -1 /* >= 3 */, 1) \ - F(FunctionBind, -1, 1) \ - F(NormalizeElements, 1, 1) \ - F(GrowArrayElements, 2, 1) \ - F(HasComplexElements, 1, 1) \ - F(IsArray, 1, 1) \ - F(ArrayIsArray, 1, 1) \ - F(FixedArrayGet, 2, 1) \ - F(FixedArraySet, 3, 1) \ - F(ArraySpeciesConstructor, 1, 1) \ - F(ArrayIncludes_Slow, 3, 1) \ - F(ArrayIndexOf, 3, 1) \ - F(SpreadIterablePrepare, 1, 1) \ - F(SpreadIterableFixed, 1, 1) +#define FOR_EACH_INTRINSIC_ARRAY(F) \ + F(TransitionElementsKind, 2, 1) \ + F(RemoveArrayHoles, 2, 1) \ + F(MoveArrayContents, 2, 1) \ + F(EstimateNumberOfElements, 1, 1) \ + F(GetArrayKeys, 2, 1) \ + F(NewArray, -1 /* >= 3 */, 1) \ + F(FunctionBind, -1, 1) \ + F(NormalizeElements, 1, 1) \ + F(GrowArrayElements, 2, 1) \ + F(HasComplexElements, 1, 1) \ + F(IsArray, 1, 1) \ + F(ArrayIsArray, 1, 1) \ + F(FixedArrayGet, 2, 1) \ + F(FixedArraySet, 3, 1) \ + F(ArraySpeciesConstructor, 1, 1) \ + F(ArrayIncludes_Slow, 3, 1) \ + F(ArrayIndexOf, 3, 1) \ + F(SpreadIterablePrepare, 1, 1) #define FOR_EACH_INTRINSIC_ATOMICS(F) \ F(ThrowNotIntegerSharedTypedArrayError, 1, 1) \ @@ -99,30 +97,18 @@ namespace internal { F(SetInitialize, 1, 1) \ F(SetGrow, 1, 1) \ F(SetShrink, 1, 1) \ - F(SetClear, 1, 1) \ - F(SetIteratorInitialize, 3, 1) \ F(SetIteratorClone, 1, 1) \ - F(SetIteratorNext, 2, 1) \ - F(SetIteratorDetails, 1, 1) \ F(MapInitialize, 1, 1) \ F(MapShrink, 1, 1) \ - F(MapClear, 1, 1) \ F(MapGrow, 1, 1) \ - F(MapIteratorInitialize, 3, 1) \ F(MapIteratorClone, 1, 1) \ - F(MapIteratorDetails, 1, 1) \ F(GetWeakMapEntries, 2, 1) \ - F(MapIteratorNext, 2, 1) \ F(WeakCollectionInitialize, 1, 1) \ - F(WeakCollectionGet, 3, 1) \ - F(WeakCollectionHas, 3, 1) \ F(WeakCollectionDelete, 3, 1) \ F(WeakCollectionSet, 4, 1) \ F(GetWeakSetValues, 2, 1) \ F(IsJSMap, 1, 1) \ F(IsJSSet, 1, 1) \ - F(IsJSMapIterator, 1, 1) \ - F(IsJSSetIterator, 1, 1) \ F(IsJSWeakMap, 1, 1) \ F(IsJSWeakSet, 1, 1) @@ -167,9 +153,9 @@ namespace internal { F(SetScopeVariableValue, 6, 1) \ F(DebugPrintScopes, 0, 1) \ F(SetBreakPointsActive, 1, 1) \ - F(GetBreakLocations, 2, 1) \ + F(GetBreakLocations, 1, 1) \ F(SetFunctionBreakPoint, 3, 1) \ - F(SetScriptBreakPoint, 4, 1) \ + F(SetScriptBreakPoint, 3, 1) \ F(ClearBreakPoint, 1, 1) \ F(ChangeBreakOnException, 2, 1) \ F(IsBreakOnException, 1, 1) \ @@ -207,7 +193,9 @@ namespace internal { F(DebugIsActive, 0, 1) \ F(DebugBreakInOptimizedCode, 0, 1) \ F(DebugCollectCoverage, 0, 1) \ - F(DebugTogglePreciseCoverage, 1, 1) + F(DebugTogglePreciseCoverage, 1, 1) \ + F(DebugToggleBlockCoverage, 1, 1) \ + F(IncBlockCounter, 2, 1) #define FOR_EACH_INTRINSIC_ERROR(F) F(ErrorToString, 1, 1) @@ -224,21 +212,18 @@ namespace internal { #define FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) #endif -#define FOR_EACH_INTRINSIC_INTERPRETER(F) \ - FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) \ - F(InterpreterNewClosure, 4, 1) \ +#define FOR_EACH_INTRINSIC_INTERPRETER(F) \ + FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) \ + F(InterpreterNewClosure, 4, 1) \ F(InterpreterAdvanceBytecodeOffset, 2, 1) #define FOR_EACH_INTRINSIC_FUNCTION(F) \ F(FunctionGetName, 1, 1) \ - F(FunctionSetName, 2, 1) \ - F(FunctionRemovePrototype, 1, 1) \ F(FunctionGetScript, 1, 1) \ F(FunctionGetScriptId, 1, 1) \ F(FunctionGetSourceCode, 1, 1) \ F(FunctionGetScriptSourcePosition, 1, 1) \ F(FunctionGetContextData, 1, 1) \ - F(FunctionSetInstanceClassName, 2, 1) \ F(FunctionSetLength, 2, 1) \ F(FunctionSetPrototype, 2, 1) \ F(FunctionIsAPIFunction, 1, 1) \ @@ -258,7 +243,6 @@ namespace internal { F(GeneratorGetReceiver, 1, 1) \ F(GeneratorGetContext, 1, 1) \ F(GeneratorGetInputOrDebugPos, 1, 1) \ - F(AsyncGeneratorGetAwaitInputOrDebugPos, 1, 1) \ F(AsyncGeneratorResolve, 3, 1) \ F(AsyncGeneratorReject, 2, 1) \ F(GeneratorGetContinuation, 1, 1) \ @@ -296,61 +280,62 @@ namespace internal { #define FOR_EACH_INTRINSIC_INTL(F) #endif -#define FOR_EACH_INTRINSIC_INTERNAL(F) \ - F(AllocateInNewSpace, 1, 1) \ - F(AllocateInTargetSpace, 2, 1) \ - F(AllocateSeqOneByteString, 1, 1) \ - F(AllocateSeqTwoByteString, 1, 1) \ - F(CheckIsBootstrapping, 0, 1) \ - F(CreateAsyncFromSyncIterator, 1, 1) \ - F(CreateListFromArrayLike, 1, 1) \ - F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \ - F(ExportFromRuntime, 1, 1) \ - F(IncrementUseCounter, 1, 1) \ - F(InstallToContext, 1, 1) \ - F(Interrupt, 0, 1) \ - F(IS_VAR, 1, 1) \ - F(NewReferenceError, 2, 1) \ - F(NewSyntaxError, 2, 1) \ - F(NewTypeError, 2, 1) \ - F(OrdinaryHasInstance, 2, 1) \ - F(PromoteScheduledException, 0, 1) \ - F(ReThrow, 1, 1) \ - F(RunMicrotasks, 0, 1) \ - F(StackGuard, 0, 1) \ - F(Throw, 1, 1) \ - F(ThrowApplyNonFunction, 1, 1) \ - F(ThrowCannotConvertToPrimitive, 0, 1) \ - F(ThrowCalledNonCallable, 1, 1) \ - F(ThrowCalledOnNullOrUndefined, 1, 1) \ - F(ThrowConstructedNonConstructable, 1, 1) \ - F(ThrowConstructorReturnedNonObject, 0, 1) \ - F(ThrowGeneratorRunning, 0, 1) \ - F(ThrowIllegalInvocation, 0, 1) \ - F(ThrowIncompatibleMethodReceiver, 2, 1) \ - F(ThrowInvalidHint, 1, 1) \ - F(ThrowInvalidStringLength, 0, 1) \ - F(ThrowInvalidTypedArrayAlignment, 2, 1) \ - F(ThrowIteratorResultNotAnObject, 1, 1) \ - F(ThrowSymbolIteratorInvalid, 0, 1) \ - F(ThrowNonCallableInInstanceOfCheck, 0, 1) \ - F(ThrowNonObjectInInstanceOfCheck, 0, 1) \ - F(ThrowNotConstructor, 1, 1) \ - F(ThrowRangeError, -1 /* >= 1 */, 1) \ - F(ThrowReferenceError, 1, 1) \ - F(ThrowStackOverflow, 0, 1) \ - F(ThrowSymbolAsyncIteratorInvalid, 0, 1) \ - F(ThrowTypeError, -1 /* >= 1 */, 1) \ - F(ThrowUndefinedOrNullToObject, 1, 1) \ - F(Typeof, 1, 1) \ - F(UnwindAndFindExceptionHandler, 0, 1) \ +#define FOR_EACH_INTRINSIC_INTERNAL(F) \ + F(AllocateInNewSpace, 1, 1) \ + F(AllocateInTargetSpace, 2, 1) \ + F(AllocateSeqOneByteString, 1, 1) \ + F(AllocateSeqTwoByteString, 1, 1) \ + F(CheckIsBootstrapping, 0, 1) \ + F(CreateAsyncFromSyncIterator, 1, 1) \ + F(CreateListFromArrayLike, 1, 1) \ + F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \ + F(ExportFromRuntime, 1, 1) \ + F(IncrementUseCounter, 1, 1) \ + F(IncrementUseCounterConstructorReturnNonUndefinedPrimitive, 0, 1) \ + F(InstallToContext, 1, 1) \ + F(Interrupt, 0, 1) \ + F(IS_VAR, 1, 1) \ + F(NewReferenceError, 2, 1) \ + F(NewSyntaxError, 2, 1) \ + F(NewTypeError, 2, 1) \ + F(OrdinaryHasInstance, 2, 1) \ + F(PromoteScheduledException, 0, 1) \ + F(ReThrow, 1, 1) \ + F(RunMicrotasks, 0, 1) \ + F(StackGuard, 0, 1) \ + F(Throw, 1, 1) \ + F(ThrowApplyNonFunction, 1, 1) \ + F(ThrowCannotConvertToPrimitive, 0, 1) \ + F(ThrowCalledNonCallable, 1, 1) \ + F(ThrowCalledOnNullOrUndefined, 1, 1) \ + F(ThrowConstructedNonConstructable, 1, 1) \ + F(ThrowConstructorReturnedNonObject, 0, 1) \ + F(ThrowGeneratorRunning, 0, 1) \ + F(ThrowIllegalInvocation, 0, 1) \ + F(ThrowIncompatibleMethodReceiver, 2, 1) \ + F(ThrowInvalidHint, 1, 1) \ + F(ThrowInvalidStringLength, 0, 1) \ + F(ThrowInvalidTypedArrayAlignment, 2, 1) \ + F(ThrowIteratorResultNotAnObject, 1, 1) \ + F(ThrowThrowMethodMissing, 0, 1) \ + F(ThrowSymbolIteratorInvalid, 0, 1) \ + F(ThrowNonCallableInInstanceOfCheck, 0, 1) \ + F(ThrowNonObjectInInstanceOfCheck, 0, 1) \ + F(ThrowNotConstructor, 1, 1) \ + F(ThrowRangeError, -1 /* >= 1 */, 1) \ + F(ThrowReferenceError, 1, 1) \ + F(ThrowStackOverflow, 0, 1) \ + F(ThrowSymbolAsyncIteratorInvalid, 0, 1) \ + F(ThrowTypeError, -1 /* >= 1 */, 1) \ + F(ThrowUndefinedOrNullToObject, 1, 1) \ + F(Typeof, 1, 1) \ + F(UnwindAndFindExceptionHandler, 0, 1) \ F(AllowDynamicFunction, 1, 1) #define FOR_EACH_INTRINSIC_LITERALS(F) \ F(CreateRegExpLiteral, 4, 1) \ F(CreateObjectLiteral, 4, 1) \ - F(CreateArrayLiteral, 4, 1) \ - F(CreateArrayLiteralStubBailout, 3, 1) + F(CreateArrayLiteral, 4, 1) #define FOR_EACH_INTRINSIC_LIVEEDIT(F) \ F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \ @@ -403,7 +388,7 @@ namespace internal { F(AddElement, 3, 1) \ F(AppendElement, 2, 1) \ F(DeleteProperty, 3, 1) \ - F(ShrinkPropertyDictionary, 2, 1) \ + F(ShrinkPropertyDictionary, 1, 1) \ F(HasProperty, 2, 1) \ F(GetOwnPropertyKeys, 2, 1) \ F(GetInterceptorInfo, 1, 1) \ @@ -427,6 +412,7 @@ namespace internal { F(CopyDataPropertiesWithExcludedProperties, -1 /* >= 1 */, 1) \ F(DefineGetterPropertyUnchecked, 4, 1) \ F(DefineSetterPropertyUnchecked, 4, 1) \ + F(DefineMethodsInternal, 3, 1) \ F(ToObject, 1, 1) \ F(ToPrimitive, 1, 1) \ F(ToPrimitive_Number, 1, 1) \ @@ -440,8 +426,6 @@ namespace internal { F(Compare, 3, 1) \ F(HasInPrototypeChain, 2, 1) \ F(CreateIterResultObject, 2, 1) \ - F(CreateKeyValueArray, 2, 1) \ - F(IsAccessCheckNeeded, 1, 1) \ F(CreateDataProperty, 3, 1) \ F(IterableToListCanBeElided, 1, 1) @@ -484,7 +468,6 @@ namespace internal { #define FOR_EACH_INTRINSIC_PROXY(F) \ F(IsJSProxy, 1, 1) \ - F(JSProxyCall, -1 /* >= 2 */, 1) \ F(JSProxyConstruct, -1 /* >= 3 */, 1) \ F(JSProxyGetTarget, 1, 1) \ F(JSProxyGetHandler, 1, 1) \ @@ -504,30 +487,30 @@ namespace internal { F(StringReplaceNonGlobalRegExpWithFunction, 3, 1) \ F(StringSplit, 3, 1) -#define FOR_EACH_INTRINSIC_SCOPES(F) \ - F(ThrowConstAssignError, 0, 1) \ - F(DeclareGlobals, 3, 1) \ - F(DeclareGlobalsForInterpreter, 3, 1) \ - F(InitializeVarGlobal, 3, 1) \ - F(DeclareEvalFunction, 2, 1) \ - F(DeclareEvalVar, 1, 1) \ - F(NewSloppyArguments_Generic, 1, 1) \ - F(NewStrictArguments, 1, 1) \ - F(NewRestParameter, 1, 1) \ - F(NewSloppyArguments, 3, 1) \ - F(NewArgumentsElements, 2, 1) \ - F(NewClosure, 3, 1) \ - F(NewClosure_Tenured, 3, 1) \ - F(NewScriptContext, 2, 1) \ - F(NewFunctionContext, 2, 1) \ - F(PushModuleContext, 3, 1) \ - F(PushWithContext, 3, 1) \ - F(PushCatchContext, 4, 1) \ - F(PushBlockContext, 2, 1) \ - F(DeleteLookupSlot, 1, 1) \ - F(LoadLookupSlot, 1, 1) \ - F(LoadLookupSlotInsideTypeof, 1, 1) \ - F(StoreLookupSlot_Sloppy, 2, 1) \ +#define FOR_EACH_INTRINSIC_SCOPES(F) \ + F(ThrowConstAssignError, 0, 1) \ + F(DeclareGlobals, 3, 1) \ + F(DeclareGlobalsForInterpreter, 3, 1) \ + F(DeclareEvalFunction, 2, 1) \ + F(DeclareEvalVar, 1, 1) \ + F(NewSloppyArguments_Generic, 1, 1) \ + F(NewStrictArguments, 1, 1) \ + F(NewRestParameter, 1, 1) \ + F(NewSloppyArguments, 3, 1) \ + F(NewArgumentsElements, 2, 1) \ + F(NewClosure, 3, 1) \ + F(NewClosure_Tenured, 3, 1) \ + F(NewScriptContext, 2, 1) \ + F(NewFunctionContext, 2, 1) \ + F(PushModuleContext, 3, 1) \ + F(PushWithContext, 3, 1) \ + F(PushCatchContext, 4, 1) \ + F(PushBlockContext, 2, 1) \ + F(DeleteLookupSlot, 1, 1) \ + F(LoadLookupSlot, 1, 1) \ + F(LoadLookupSlotInsideTypeof, 1, 1) \ + F(StoreLookupSlot_Sloppy, 2, 1) \ + F(StoreLookupSlot_SloppyHoisting, 2, 1) \ F(StoreLookupSlot_Strict, 2, 1) #define FOR_EACH_INTRINSIC_STRINGS(F) \ @@ -538,6 +521,7 @@ namespace internal { F(StringLastIndexOf, 2, 1) \ F(SubString, 3, 1) \ F(StringAdd, 2, 1) \ + F(StringConcat, -1 /* >= 2 */, 1) \ F(InternalizeString, 1, 1) \ F(StringCharCodeAtRT, 2, 1) \ F(StringCompare, 2, 1) \ @@ -596,14 +580,13 @@ namespace internal { F(DisassembleFunction, 1, 1) \ F(TraceEnter, 0, 1) \ F(TraceExit, 1, 1) \ - F(TraceTailCall, 0, 1) \ F(HaveSameMap, 2, 1) \ F(InNewSpace, 1, 1) \ - F(HasFastSmiElements, 1, 1) \ - F(HasFastObjectElements, 1, 1) \ - F(HasFastSmiOrObjectElements, 1, 1) \ - F(HasFastDoubleElements, 1, 1) \ - F(HasFastHoleyElements, 1, 1) \ + F(HasSmiElements, 1, 1) \ + F(HasObjectElements, 1, 1) \ + F(HasSmiOrObjectElements, 1, 1) \ + F(HasDoubleElements, 1, 1) \ + F(HasHoleyElements, 1, 1) \ F(HasDictionaryElements, 1, 1) \ F(HasSloppyArgumentsElements, 1, 1) \ F(HasFixedTypedArrayElements, 1, 1) \ @@ -628,8 +611,6 @@ namespace internal { F(ValidateWasmOrphanedInstance, 1, 1) \ F(SetWasmCompileControls, 2, 1) \ F(SetWasmInstantiateControls, 0, 1) \ - F(SetWasmCompileFromPromiseOverload, 0, 1) \ - F(ResetWasmOverloads, 0, 1) \ F(HeapObjectVerify, 1, 1) \ F(WasmNumInterpretedCalls, 1, 1) \ F(RedirectToWasmInterpreter, 2, 1) @@ -676,8 +657,6 @@ namespace internal { // Most intrinsics are implemented in the runtime/ directory, but ICs are // implemented in ic.cc for now. #define FOR_EACH_INTRINSIC_IC(F) \ - F(BinaryOpIC_Miss, 2, 1) \ - F(BinaryOpIC_MissWithAllocationSite, 3, 1) \ F(CompareIC_Miss, 3, 1) \ F(ElementsTransitionAndStoreIC_Miss, 6, 1) \ F(KeyedLoadIC_Miss, 4, 1) \ @@ -691,7 +670,6 @@ namespace internal { F(StoreCallbackProperty, 6, 1) \ F(StoreIC_Miss, 5, 1) \ F(StorePropertyWithInterceptor, 5, 1) \ - F(ToBooleanIC_Miss, 1, 1) \ F(Unreachable, 0, 1) #define FOR_EACH_INTRINSIC_RETURN_OBJECT(F) \ @@ -803,17 +781,22 @@ class Runtime : public AllStatic { MUST_USE_RESULT static MaybeHandle<JSArray> GetInternalProperties( Isolate* isolate, Handle<Object>); + + MUST_USE_RESULT static MaybeHandle<Object> ThrowIteratorError( + Isolate* isolate, Handle<Object> object); }; class RuntimeState { public: +#ifndef V8_INTL_SUPPORT unibrow::Mapping<unibrow::ToUppercase, 128>* to_upper_mapping() { return &to_upper_mapping_; } unibrow::Mapping<unibrow::ToLowercase, 128>* to_lower_mapping() { return &to_lower_mapping_; } +#endif Runtime::Function* redirected_intrinsic_functions() { return redirected_intrinsic_functions_.get(); @@ -826,8 +809,10 @@ class RuntimeState { private: RuntimeState() {} +#ifndef V8_INTL_SUPPORT unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_; unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_; +#endif std::unique_ptr<Runtime::Function[]> redirected_intrinsic_functions_; |