diff options
author | Michaƫl Zasso <targos@protonmail.com> | 2018-01-24 20:16:06 +0100 |
---|---|---|
committer | Myles Borins <mylesborins@google.com> | 2018-01-24 15:02:20 -0800 |
commit | 4c4af643e5042d615a60c6bbc05aee9d81b903e5 (patch) | |
tree | 3fb0a97988fe4439ae3ae06f26915d1dcf8cab92 /deps/v8/src/runtime | |
parent | fa9f31a4fda5a3782c652e56e394465805ebb50f (diff) | |
download | android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.tar.gz android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.tar.bz2 android-node-v8-4c4af643e5042d615a60c6bbc05aee9d81b903e5.zip |
deps: update V8 to 6.4.388.40
PR-URL: https://github.com/nodejs/node/pull/17489
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/src/runtime')
26 files changed, 1234 insertions, 679 deletions
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc index 782acc72c5..f07c842bae 100644 --- a/deps/v8/src/runtime/runtime-array.cc +++ b/deps/v8/src/runtime/runtime-array.cc @@ -37,9 +37,9 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) { // 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()); + Handle<NumberDictionary> dict(object->element_dictionary(), isolate); + Handle<NumberDictionary> new_dict = + NumberDictionary::New(isolate, dict->NumberOfElements()); uint32_t pos = 0; uint32_t undefs = 0; @@ -70,7 +70,7 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) { undefs++; } else { Handle<Object> result = - SeededNumberDictionary::Add(new_dict, pos, value, details); + NumberDictionary::Add(new_dict, pos, value, details); // Add should not grow the dictionary since we allocated the right size. DCHECK(result.is_identical_to(new_dict)); USE(result); @@ -78,7 +78,7 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) { } } else { Handle<Object> result = - SeededNumberDictionary::Add(new_dict, key, value, details); + NumberDictionary::Add(new_dict, key, value, details); // Add should not grow the dictionary since we allocated the right size. DCHECK(result.is_identical_to(new_dict)); USE(result); @@ -95,7 +95,7 @@ Object* PrepareSlowElementsForSort(Handle<JSObject> object, uint32_t limit) { return bailout; } HandleScope scope(isolate); - Handle<Object> result = SeededNumberDictionary::Add( + Handle<Object> result = NumberDictionary::Add( new_dict, pos, isolate->factory()->undefined_value(), no_details); // Add should not grow the dictionary since we allocated the right size. DCHECK(result.is_identical_to(new_dict)); @@ -130,7 +130,7 @@ Object* PrepareElementsForSort(Handle<JSObject> object, uint32_t limit) { 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()); + Handle<NumberDictionary> dict(object->element_dictionary()); if (object->IsJSArray() || dict->requires_slow_elements() || dict->max_number_key() >= limit) { return PrepareSlowElementsForSort(object, limit); @@ -294,7 +294,7 @@ RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) { FixedArrayBase* elements = array->elements(); SealHandleScope shs(isolate); if (elements->IsDictionary()) { - int result = SeededNumberDictionary::cast(elements)->NumberOfElements(); + int result = NumberDictionary::cast(elements)->NumberOfElements(); return Smi::FromInt(result); } else { DCHECK(array->length()->IsSmi()); @@ -378,6 +378,44 @@ RUNTIME_FUNCTION(Runtime_GetArrayKeys) { return *isolate->factory()->NewJSArrayWithElements(keys); } +RUNTIME_FUNCTION(Runtime_TrySliceSimpleNonFastElements) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); + CONVERT_SMI_ARG_CHECKED(first, 1); + CONVERT_SMI_ARG_CHECKED(count, 2); + uint32_t length = first + count; + + // Only handle elements kinds that have a ElementsAccessor Slice + // implementation. + if (receiver->IsJSArray()) { + // This "fastish" path must make sure the destination array is a JSArray. + if (!isolate->IsArraySpeciesLookupChainIntact() || + !JSArray::cast(*receiver)->HasArrayPrototype(isolate)) { + return Smi::FromInt(0); + } + } else { + int len; + if (!receiver->IsJSObject() || + !JSSloppyArgumentsObject::GetSloppyArgumentsLength( + isolate, Handle<JSObject>::cast(receiver), &len) || + (length > static_cast<uint32_t>(len))) { + return Smi::FromInt(0); + } + } + + // This "fastish" path must also ensure that elements are simple (no + // geters/setters), no elements on prototype chain. + Handle<JSObject> object(Handle<JSObject>::cast(receiver)); + if (!JSObject::PrototypeHasNoElements(isolate, *object) || + object->HasComplexElements()) { + return Smi::FromInt(0); + } + + ElementsAccessor* accessor = object->GetElementsAccessor(); + return *accessor->Slice(object, first, length); +} + RUNTIME_FUNCTION(Runtime_NewArray) { HandleScope scope(isolate); DCHECK_LE(3, args.length()); diff --git a/deps/v8/src/runtime/runtime-bigint.cc b/deps/v8/src/runtime/runtime-bigint.cc index d6b7dfb550..ce513d2f92 100644 --- a/deps/v8/src/runtime/runtime-bigint.cc +++ b/deps/v8/src/runtime/runtime-bigint.cc @@ -8,18 +8,57 @@ #include "src/counters.h" #include "src/objects-inl.h" #include "src/objects/bigint.h" -#include "src/parsing/token.h" namespace v8 { namespace internal { -RUNTIME_FUNCTION(Runtime_BigIntEqual) { +RUNTIME_FUNCTION(Runtime_BigIntCompareToBigInt) { + SealHandleScope shs(isolate); + DCHECK_EQ(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0); + CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1); + CONVERT_ARG_HANDLE_CHECKED(BigInt, rhs, 2); + bool result = ComparisonResultToBool(static_cast<Operation>(mode->value()), + BigInt::CompareToBigInt(lhs, rhs)); + return *isolate->factory()->ToBoolean(result); +} + +RUNTIME_FUNCTION(Runtime_BigIntCompareToNumber) { + SealHandleScope shs(isolate); + DCHECK_EQ(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Smi, mode, 0); + CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 1); + CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 2); + bool result = ComparisonResultToBool(static_cast<Operation>(mode->value()), + BigInt::CompareToNumber(lhs, rhs)); + return *isolate->factory()->ToBoolean(result); +} + +RUNTIME_FUNCTION(Runtime_BigIntEqualToBigInt) { SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(BigInt, rhs, 1); + bool result = BigInt::EqualToBigInt(*lhs, *rhs); + return *isolate->factory()->ToBoolean(result); +} + +RUNTIME_FUNCTION(Runtime_BigIntEqualToNumber) { + SealHandleScope shs(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0); CONVERT_ARG_HANDLE_CHECKED(Object, rhs, 1); - bool result = lhs->IsBigInt() && rhs->IsBigInt() && - BigInt::Equal(BigInt::cast(*lhs), BigInt::cast(*rhs)); + bool result = BigInt::EqualToNumber(lhs, rhs); + return *isolate->factory()->ToBoolean(result); +} + +RUNTIME_FUNCTION(Runtime_BigIntEqualToString) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(BigInt, lhs, 0); + CONVERT_ARG_HANDLE_CHECKED(String, rhs, 1); + rhs = String::Flatten(rhs); + bool result = BigInt::EqualToString(lhs, rhs); return *isolate->factory()->ToBoolean(result); } @@ -30,12 +69,20 @@ RUNTIME_FUNCTION(Runtime_BigIntToBoolean) { return *isolate->factory()->ToBoolean(bigint->ToBoolean()); } +RUNTIME_FUNCTION(Runtime_BigIntToNumber) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0); + return *BigInt::ToNumber(x); +} + RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, left_obj, 0); CONVERT_ARG_HANDLE_CHECKED(Object, right_obj, 1); CONVERT_SMI_ARG_CHECKED(opcode, 2); + Operation op = static_cast<Operation>(opcode); if (!left_obj->IsBigInt() || !right_obj->IsBigInt()) { THROW_NEW_ERROR_RETURN_FAILURE( @@ -44,22 +91,70 @@ RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) { Handle<BigInt> left(Handle<BigInt>::cast(left_obj)); Handle<BigInt> right(Handle<BigInt>::cast(right_obj)); MaybeHandle<BigInt> result; - switch (opcode) { - case Token::ADD: + switch (op) { + case Operation::kAdd: result = BigInt::Add(left, right); break; - case Token::SUB: + case Operation::kSubtract: result = BigInt::Subtract(left, right); break; - case Token::MUL: + case Operation::kMultiply: result = BigInt::Multiply(left, right); break; - case Token::DIV: + case Operation::kDivide: result = BigInt::Divide(left, right); break; - case Token::MOD: + case Operation::kModulus: result = BigInt::Remainder(left, right); break; + case Operation::kExponentiate: + UNIMPLEMENTED(); + break; + case Operation::kBitwiseAnd: + result = BigInt::BitwiseAnd(left, right); + break; + case Operation::kBitwiseOr: + result = BigInt::BitwiseOr(left, right); + break; + case Operation::kBitwiseXor: + result = BigInt::BitwiseXor(left, right); + break; + case Operation::kShiftLeft: + result = BigInt::LeftShift(left, right); + break; + case Operation::kShiftRight: + result = BigInt::SignedRightShift(left, right); + break; + case Operation::kShiftRightLogical: + result = BigInt::UnsignedRightShift(left, right); + break; + default: + UNREACHABLE(); + } + RETURN_RESULT_OR_FAILURE(isolate, result); +} + +RUNTIME_FUNCTION(Runtime_BigIntUnaryOp) { + HandleScope scope(isolate); + DCHECK_EQ(2, args.length()); + CONVERT_ARG_HANDLE_CHECKED(BigInt, x, 0); + CONVERT_SMI_ARG_CHECKED(opcode, 1); + Operation op = static_cast<Operation>(opcode); + + MaybeHandle<BigInt> result; + switch (op) { + case Operation::kBitwiseNot: + result = BigInt::BitwiseNot(x); + break; + case Operation::kNegate: + result = BigInt::UnaryMinus(x); + break; + case Operation::kIncrement: + result = BigInt::Increment(x); + break; + case Operation::kDecrement: + result = BigInt::Decrement(x); + break; default: UNREACHABLE(); } diff --git a/deps/v8/src/runtime/runtime-classes.cc b/deps/v8/src/runtime/runtime-classes.cc index 815501bcfa..37e647c7dd 100644 --- a/deps/v8/src/runtime/runtime-classes.cc +++ b/deps/v8/src/runtime/runtime-classes.cc @@ -13,6 +13,7 @@ #include "src/elements.h" #include "src/isolate-inl.h" #include "src/messages.h" +#include "src/objects/literal-objects-inl.h" #include "src/runtime/runtime.h" namespace v8 { @@ -104,10 +105,449 @@ RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) { return isolate->heap()->home_object_symbol(); } -static MaybeHandle<Object> DefineClass(Isolate* isolate, - Handle<Object> super_class, - Handle<JSFunction> constructor, - int start_position, int end_position) { +namespace { + +template <typename Dictionary> +Handle<Name> KeyToName(Isolate* isolate, Handle<Object> key); + +template <> +Handle<Name> KeyToName<NameDictionary>(Isolate* isolate, Handle<Object> key) { + DCHECK(key->IsName()); + return Handle<Name>::cast(key); +} + +template <> +Handle<Name> KeyToName<NumberDictionary>(Isolate* isolate, Handle<Object> key) { + DCHECK(key->IsNumber()); + return isolate->factory()->NumberToString(key); +} + +inline void SetHomeObject(Isolate* isolate, JSFunction* method, + JSObject* home_object) { + if (method->shared()->needs_home_object()) { + const int kPropertyIndex = JSFunction::kMaybeHomeObjectDescriptorIndex; + CHECK_EQ(method->map()->instance_descriptors()->GetKey(kPropertyIndex), + isolate->heap()->home_object_symbol()); + + FieldIndex field_index = + FieldIndex::ForDescriptor(method->map(), kPropertyIndex); + method->RawFastPropertyAtPut(field_index, home_object); + } +} + +// Gets |index|'th argument which may be a class constructor object, a class +// prototype object or a class method. In the latter case the following +// post-processing may be required: +// 1) set [[HomeObject]] slot to given |home_object| value if the method's +// shared function info indicates that the method requires that; +// 2) set method's name to a concatenation of |name_prefix| and |key| if the +// method's shared function info indicates that method does not have a +// shared name. +template <typename Dictionary> +MaybeHandle<Object> GetMethodAndSetHomeObjectAndName( + Isolate* isolate, Arguments& args, Smi* index, Handle<JSObject> home_object, + Handle<String> name_prefix, Handle<Object> key) { + int int_index = Smi::ToInt(index); + + // Class constructor and prototype values do not require post processing. + if (int_index < ClassBoilerplate::kFirstDynamicArgumentIndex) { + return args.at<Object>(int_index); + } + + Handle<JSFunction> method = args.at<JSFunction>(int_index); + + SetHomeObject(isolate, *method, *home_object); + + if (!method->shared()->has_shared_name()) { + // TODO(ishell): method does not have a shared name at this point only if + // the key is a computed property name. However, the bytecode generator + // explicitly generates ToName bytecodes to ensure that the computed + // property name is properly converted to Name. So, we can actually be smart + // here and avoid converting Smi keys back to Name. + Handle<Name> name = KeyToName<Dictionary>(isolate, key); + if (!JSFunction::SetName(method, name, name_prefix)) { + return MaybeHandle<Object>(); + } + } + return method; +} + +// Gets |index|'th argument which may be a class constructor object, a class +// prototype object or a class method. In the latter case the following +// post-processing may be required: +// 1) set [[HomeObject]] slot to given |home_object| value if the method's +// shared function info indicates that the method requires that; +// This is a simplified version of GetMethodWithSharedNameAndSetHomeObject() +// function above that is used when it's guaranteed that the method has +// shared name. +Object* GetMethodWithSharedNameAndSetHomeObject(Isolate* isolate, + Arguments& args, Object* index, + JSObject* home_object) { + DisallowHeapAllocation no_gc; + int int_index = Smi::ToInt(index); + + // Class constructor and prototype values do not require post processing. + if (int_index < ClassBoilerplate::kFirstDynamicArgumentIndex) { + return args[int_index]; + } + + Handle<JSFunction> method = args.at<JSFunction>(int_index); + + SetHomeObject(isolate, *method, home_object); + + DCHECK(method->shared()->has_shared_name()); + return *method; +} + +template <typename Dictionary> +Handle<Dictionary> ShallowCopyDictionaryTemplate( + Isolate* isolate, Handle<Dictionary> dictionary_template) { + Handle<Map> dictionary_map(dictionary_template->map(), isolate); + Handle<Dictionary> dictionary = + Handle<Dictionary>::cast(isolate->factory()->CopyFixedArrayWithMap( + dictionary_template, dictionary_map)); + // Clone all AccessorPairs in the dictionary. + int capacity = dictionary->Capacity(); + for (int i = 0; i < capacity; i++) { + Object* value = dictionary->ValueAt(i); + if (value->IsAccessorPair()) { + Handle<AccessorPair> pair(AccessorPair::cast(value), isolate); + pair = AccessorPair::Copy(pair); + dictionary->ValueAtPut(i, *pair); + } + } + return dictionary; +} + +template <typename Dictionary> +bool SubstituteValues(Isolate* isolate, Handle<Dictionary> dictionary, + Handle<JSObject> receiver, Arguments& args, + bool* install_name_accessor = nullptr) { + Handle<Name> name_string = isolate->factory()->name_string(); + + // Replace all indices with proper methods. + int capacity = dictionary->Capacity(); + for (int i = 0; i < capacity; i++) { + Object* maybe_key = dictionary->KeyAt(i); + if (!Dictionary::IsKey(isolate, maybe_key)) continue; + if (install_name_accessor && *install_name_accessor && + (maybe_key == *name_string)) { + *install_name_accessor = false; + } + Handle<Object> key(maybe_key, isolate); + Handle<Object> value(dictionary->ValueAt(i), isolate); + if (value->IsAccessorPair()) { + Handle<AccessorPair> pair = Handle<AccessorPair>::cast(value); + Object* tmp = pair->getter(); + if (tmp->IsSmi()) { + Handle<Object> result; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, result, + GetMethodAndSetHomeObjectAndName<Dictionary>( + isolate, args, Smi::cast(tmp), receiver, + isolate->factory()->get_string(), key), + false); + pair->set_getter(*result); + } + tmp = pair->setter(); + if (tmp->IsSmi()) { + Handle<Object> result; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, result, + GetMethodAndSetHomeObjectAndName<Dictionary>( + isolate, args, Smi::cast(tmp), receiver, + isolate->factory()->set_string(), key), + false); + pair->set_setter(*result); + } + } else if (value->IsSmi()) { + Handle<Object> result; + ASSIGN_RETURN_ON_EXCEPTION_VALUE( + isolate, result, + GetMethodAndSetHomeObjectAndName<Dictionary>( + isolate, args, Smi::cast(*value), receiver, + isolate->factory()->empty_string(), key), + false); + dictionary->ValueAtPut(i, *result); + } + } + return true; +} + +bool AddDescriptorsByTemplate( + Isolate* isolate, Handle<Map> map, + Handle<DescriptorArray> descriptors_template, + Handle<NumberDictionary> elements_dictionary_template, + Handle<JSObject> receiver, Arguments& args) { + int nof_descriptors = descriptors_template->number_of_descriptors(); + + Handle<DescriptorArray> descriptors = + DescriptorArray::Allocate(isolate, nof_descriptors, 0); + + Handle<NumberDictionary> elements_dictionary = + *elements_dictionary_template == + isolate->heap()->empty_slow_element_dictionary() + ? elements_dictionary_template + : ShallowCopyDictionaryTemplate(isolate, + elements_dictionary_template); + + // Read values from |descriptors_template| and store possibly post-processed + // values into "instantiated" |descriptors| array. + for (int i = 0; i < nof_descriptors; i++) { + Object* value = descriptors_template->GetValue(i); + if (value->IsAccessorPair()) { + Handle<AccessorPair> pair = + AccessorPair::Copy(handle(AccessorPair::cast(value), isolate)); + value = *pair; + } + DisallowHeapAllocation no_gc; + Name* name = descriptors_template->GetKey(i); + DCHECK(name->IsUniqueName()); + PropertyDetails details = descriptors_template->GetDetails(i); + if (details.location() == kDescriptor) { + if (details.kind() == kData) { + if (value->IsSmi()) { + value = GetMethodWithSharedNameAndSetHomeObject(isolate, args, value, + *receiver); + } + details = + details.CopyWithRepresentation(value->OptimalRepresentation()); + + } else { + DCHECK_EQ(kAccessor, details.kind()); + if (value->IsAccessorPair()) { + AccessorPair* pair = AccessorPair::cast(value); + Object* tmp = pair->getter(); + if (tmp->IsSmi()) { + pair->set_getter(GetMethodWithSharedNameAndSetHomeObject( + isolate, args, tmp, *receiver)); + } + tmp = pair->setter(); + if (tmp->IsSmi()) { + pair->set_setter(GetMethodWithSharedNameAndSetHomeObject( + isolate, args, tmp, *receiver)); + } + } + } + } else { + DCHECK_EQ(kField, details.location()); + DCHECK(!details.representation().IsDouble()); + } + DCHECK(value->FitsRepresentation(details.representation())); + descriptors->Set(i, name, value, details); + } + + map->InitializeDescriptors(*descriptors, + LayoutDescriptor::FastPointerLayout()); + + if (elements_dictionary->NumberOfElements() > 0) { + if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary, + receiver, args)) { + return false; + } + map->set_elements_kind(DICTIONARY_ELEMENTS); + } + + // Atomically commit the changes. + receiver->synchronized_set_map(*map); + if (elements_dictionary->NumberOfElements() > 0) { + receiver->set_elements(*elements_dictionary); + } + return true; +} + +bool AddDescriptorsByTemplate( + Isolate* isolate, Handle<Map> map, + Handle<NameDictionary> properties_dictionary_template, + Handle<NumberDictionary> elements_dictionary_template, + Handle<FixedArray> computed_properties, Handle<JSObject> receiver, + bool install_name_accessor, Arguments& args) { + int computed_properties_length = computed_properties->length(); + + // Shallow-copy properties template. + Handle<NameDictionary> properties_dictionary = + ShallowCopyDictionaryTemplate(isolate, properties_dictionary_template); + Handle<NumberDictionary> elements_dictionary = + ShallowCopyDictionaryTemplate(isolate, elements_dictionary_template); + + typedef ClassBoilerplate::ValueKind ValueKind; + typedef ClassBoilerplate::ComputedEntryFlags ComputedEntryFlags; + + // Merge computed properties with properties and elements dictionary + // templates. + int i = 0; + while (i < computed_properties_length) { + int flags = Smi::ToInt(computed_properties->get(i++)); + + ValueKind value_kind = ComputedEntryFlags::ValueKindBits::decode(flags); + int key_index = ComputedEntryFlags::KeyIndexBits::decode(flags); + Object* value = Smi::FromInt(key_index + 1); // Value follows name. + + Handle<Object> key = args.at<Object>(key_index); + DCHECK(key->IsName()); + uint32_t element; + Handle<Name> name = Handle<Name>::cast(key); + if (name->AsArrayIndex(&element)) { + ClassBoilerplate::AddToElementsTemplate( + isolate, elements_dictionary, element, key_index, value_kind, value); + + } else { + name = isolate->factory()->InternalizeName(name); + ClassBoilerplate::AddToPropertiesTemplate( + isolate, properties_dictionary, name, key_index, value_kind, value); + } + } + + // Replace all indices with proper methods. + if (!SubstituteValues<NameDictionary>(isolate, properties_dictionary, + receiver, args, + &install_name_accessor)) { + return false; + } + if (install_name_accessor) { + PropertyAttributes attribs = + static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); + PropertyDetails details(kAccessor, attribs, PropertyCellType::kNoCell); + Handle<NameDictionary> dict = NameDictionary::Add( + properties_dictionary, isolate->factory()->name_string(), + isolate->factory()->function_name_accessor(), details); + CHECK_EQ(*dict, *properties_dictionary); + } + + if (elements_dictionary->NumberOfElements() > 0) { + if (!SubstituteValues<NumberDictionary>(isolate, elements_dictionary, + receiver, args)) { + return false; + } + map->set_elements_kind(DICTIONARY_ELEMENTS); + } + + // Atomically commit the changes. + receiver->synchronized_set_map(*map); + receiver->set_raw_properties_or_hash(*properties_dictionary); + if (elements_dictionary->NumberOfElements() > 0) { + receiver->set_elements(*elements_dictionary); + } + return true; +} + +Handle<JSObject> CreateClassPrototype(Isolate* isolate) { + Factory* factory = isolate->factory(); + + const int kInobjectFields = 0; + + // Just use some JSObject map of certain size. + Handle<Map> map = factory->ObjectLiteralMapFromCache( + isolate->native_context(), kInobjectFields); + + return factory->NewJSObjectFromMap(map); +} + +bool InitClassPrototype(Isolate* isolate, + Handle<ClassBoilerplate> class_boilerplate, + Handle<JSObject> prototype, + Handle<Object> prototype_parent, + Handle<JSFunction> constructor, Arguments& args) { + Handle<Map> map(prototype->map(), isolate); + map = Map::CopyDropDescriptors(map); + map->set_is_prototype_map(true); + Map::SetPrototype(map, prototype_parent); + constructor->set_prototype_or_initial_map(*prototype); + map->SetConstructor(*constructor); + + Handle<FixedArray> computed_properties( + class_boilerplate->instance_computed_properties(), isolate); + Handle<NumberDictionary> elements_dictionary_template( + NumberDictionary::cast(class_boilerplate->instance_elements_template()), + isolate); + + Handle<Object> properties_template( + class_boilerplate->instance_properties_template(), isolate); + if (properties_template->IsDictionary()) { + Handle<NameDictionary> properties_dictionary_template = + Handle<NameDictionary>::cast(properties_template); + + map->set_dictionary_map(true); + map->set_migration_target(false); + map->set_may_have_interesting_symbols(true); + map->set_construction_counter(Map::kNoSlackTracking); + + // We care about name property only for class constructor. + const bool install_name_accessor = false; + + return AddDescriptorsByTemplate( + isolate, map, properties_dictionary_template, + elements_dictionary_template, computed_properties, prototype, + install_name_accessor, args); + } else { + Handle<DescriptorArray> descriptors_template = + Handle<DescriptorArray>::cast(properties_template); + + // The size of the prototype object is known at this point. + // So we can create it now and then add the rest instance methods to the + // map. + return AddDescriptorsByTemplate(isolate, map, descriptors_template, + elements_dictionary_template, prototype, + args); + } +} + +bool InitClassConstructor(Isolate* isolate, + Handle<ClassBoilerplate> class_boilerplate, + Handle<Object> constructor_parent, + Handle<JSFunction> constructor, Arguments& args) { + Handle<Map> map(constructor->map(), isolate); + map = Map::CopyDropDescriptors(map); + DCHECK(map->is_prototype_map()); + + if (!constructor_parent.is_null()) { + // Set map's prototype without enabling prototype setup mode for superclass + // because it does not make sense. + Map::SetPrototype(map, constructor_parent, false); + } + + Handle<NumberDictionary> elements_dictionary_template( + NumberDictionary::cast(class_boilerplate->static_elements_template()), + isolate); + Handle<FixedArray> computed_properties( + class_boilerplate->static_computed_properties(), isolate); + + Handle<Object> properties_template( + class_boilerplate->static_properties_template(), isolate); + + if (properties_template->IsDictionary()) { + Handle<NameDictionary> properties_dictionary_template = + Handle<NameDictionary>::cast(properties_template); + + map->set_dictionary_map(true); + map->InitializeDescriptors(isolate->heap()->empty_descriptor_array(), + LayoutDescriptor::FastPointerLayout()); + map->set_migration_target(false); + map->set_may_have_interesting_symbols(true); + map->set_construction_counter(Map::kNoSlackTracking); + + bool install_name_accessor = + class_boilerplate->install_class_name_accessor() != 0; + + return AddDescriptorsByTemplate( + isolate, map, properties_dictionary_template, + elements_dictionary_template, computed_properties, constructor, + install_name_accessor, args); + } else { + Handle<DescriptorArray> descriptors_template = + Handle<DescriptorArray>::cast(properties_template); + + return AddDescriptorsByTemplate(isolate, map, descriptors_template, + elements_dictionary_template, constructor, + args); + } +} + +MaybeHandle<Object> DefineClass(Isolate* isolate, + Handle<ClassBoilerplate> class_boilerplate, + Handle<Object> super_class, + Handle<JSFunction> constructor, + Arguments& args) { Handle<Object> prototype_parent; Handle<Object> constructor_parent; @@ -132,7 +572,10 @@ static MaybeHandle<Object> DefineClass(Isolate* isolate, prototype_parent), Object); } - constructor_parent = super_class; + // Create new handle to avoid |constructor_parent| corruption because of + // |super_class| handle value overwriting via storing to + // args[ClassBoilerplate::kPrototypeArgumentIndex] below. + constructor_parent = handle(*super_class, isolate); } else { THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kExtendsValueNotConstructor, @@ -141,95 +584,33 @@ static MaybeHandle<Object> DefineClass(Isolate* isolate, } } - Handle<Map> map = - isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); - map->set_is_prototype_map(true); - Map::SetPrototype(map, prototype_parent); - map->SetConstructor(*constructor); - Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map); - - JSFunction::SetPrototype(constructor, prototype); - PropertyAttributes attribs = - static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY); - RETURN_ON_EXCEPTION(isolate, - JSObject::SetOwnPropertyIgnoreAttributes( - constructor, isolate->factory()->prototype_string(), - prototype, attribs), - Object); + Handle<JSObject> prototype = CreateClassPrototype(isolate); + DCHECK_EQ(*constructor, args[ClassBoilerplate::kConstructorArgumentIndex]); + args[ClassBoilerplate::kPrototypeArgumentIndex] = *prototype; - if (!constructor_parent.is_null()) { - MAYBE_RETURN_NULL(JSObject::SetPrototype(constructor, constructor_parent, - false, Object::THROW_ON_ERROR)); + if (!InitClassConstructor(isolate, class_boilerplate, constructor_parent, + constructor, args) || + !InitClassPrototype(isolate, class_boilerplate, prototype, + prototype_parent, constructor, args)) { + DCHECK(isolate->has_pending_exception()); + return MaybeHandle<Object>(); } - - JSObject::AddProperty(prototype, isolate->factory()->constructor_string(), - constructor, DONT_ENUM); - - // Install private properties that are used to construct the FunctionToString. - RETURN_ON_EXCEPTION( - isolate, - Object::SetProperty( - constructor, isolate->factory()->class_start_position_symbol(), - handle(Smi::FromInt(start_position), isolate), STRICT), - Object); - RETURN_ON_EXCEPTION( - isolate, Object::SetProperty( - constructor, isolate->factory()->class_end_position_symbol(), - handle(Smi::FromInt(end_position), isolate), STRICT), - Object); - - // Caller already has access to constructor, so return the prototype. return prototype; } +} // namespace RUNTIME_FUNCTION(Runtime_DefineClass) { HandleScope scope(isolate); - DCHECK_EQ(4, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0); + DCHECK_LE(ClassBoilerplate::kFirstDynamicArgumentIndex, args.length()); + CONVERT_ARG_HANDLE_CHECKED(ClassBoilerplate, class_boilerplate, 0); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1); - CONVERT_SMI_ARG_CHECKED(start_position, 2); - CONVERT_SMI_ARG_CHECKED(end_position, 3); + CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 2); + DCHECK_EQ(class_boilerplate->arguments_count(), args.length()); RETURN_RESULT_OR_FAILURE( - isolate, DefineClass(isolate, super_class, constructor, start_position, - end_position)); -} - -namespace { -void InstallClassNameAccessor(Isolate* isolate, Handle<JSObject> object) { - PropertyAttributes attrs = - static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY); - // Cannot fail since this should only be called when creating an object - // literal. - CHECK(!JSObject::SetAccessor( - object, Accessors::FunctionNameInfo(object->GetIsolate(), attrs)) - .is_null()); -} -} // anonymous namespace - -RUNTIME_FUNCTION(Runtime_InstallClassNameAccessor) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); - InstallClassNameAccessor(isolate, object); - return *object; -} - -RUNTIME_FUNCTION(Runtime_InstallClassNameAccessorWithCheck) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); - - // If a property named "name" is already defined, exit. - Handle<Name> key = isolate->factory()->name_string(); - if (JSObject::HasRealNamedProperty(object, key).FromMaybe(false)) { - return *object; - } - - // Define the "name" accessor. - InstallClassNameAccessor(isolate, object); - return *object; + isolate, + DefineClass(isolate, class_boilerplate, super_class, constructor, args)); } namespace { @@ -376,8 +757,9 @@ RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) { CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); - RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver, - name, value, STRICT)); + RETURN_RESULT_OR_FAILURE( + isolate, StoreToSuper(isolate, home_object, receiver, name, value, + LanguageMode::kStrict)); } @@ -389,8 +771,9 @@ RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) { CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); - RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver, - name, value, SLOPPY)); + RETURN_RESULT_OR_FAILURE( + isolate, StoreToSuper(isolate, home_object, receiver, name, value, + LanguageMode::kSloppy)); } static MaybeHandle<Object> StoreKeyedToSuper( @@ -424,8 +807,8 @@ RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) { CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); RETURN_RESULT_OR_FAILURE( - isolate, - StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT)); + isolate, StoreKeyedToSuper(isolate, home_object, receiver, key, value, + LanguageMode::kStrict)); } @@ -438,8 +821,8 @@ RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) { CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); RETURN_RESULT_OR_FAILURE( - isolate, - StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY)); + isolate, StoreKeyedToSuper(isolate, home_object, receiver, key, value, + LanguageMode::kSloppy)); } diff --git a/deps/v8/src/runtime/runtime-collections.cc b/deps/v8/src/runtime/runtime-collections.cc index 06f4a89346..44e947aafe 100644 --- a/deps/v8/src/runtime/runtime-collections.cc +++ b/deps/v8/src/runtime/runtime-collections.cc @@ -97,7 +97,7 @@ RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]); - CHECK(max_entries >= 0); + CHECK_GE(max_entries, 0); return *JSWeakCollection::GetEntries(holder, max_entries); } @@ -116,10 +116,18 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) { 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()); + +#ifdef DEBUG + DCHECK(key->IsJSReceiver()); + DCHECK(ObjectHashTableShape::IsLive(isolate, *key)); Handle<ObjectHashTable> table( ObjectHashTable::cast(weak_collection->table())); - CHECK(table->IsKey(isolate, *key)); + // Should only be called when shrinking the table is necessary. See + // HashTable::Shrink(). + DCHECK(table->NumberOfElements() - 1 <= (table->Capacity() >> 2) && + table->NumberOfElements() - 1 >= 16); +#endif + bool was_present = JSWeakCollection::Delete(weak_collection, key, hash); return isolate->heap()->ToBoolean(was_present); } @@ -130,12 +138,20 @@ RUNTIME_FUNCTION(Runtime_WeakCollectionSet) { DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0); CONVERT_ARG_HANDLE_CHECKED(Object, key, 1); - CHECK(key->IsJSReceiver() || key->IsSymbol()); CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); CONVERT_SMI_ARG_CHECKED(hash, 3) + +#ifdef DEBUG + DCHECK(key->IsJSReceiver()); + DCHECK(ObjectHashTableShape::IsLive(isolate, *key)); Handle<ObjectHashTable> table( ObjectHashTable::cast(weak_collection->table())); - CHECK(table->IsKey(isolate, *key)); + // Should only be called when rehashing or resizing the table is necessary. + // See ObjectHashTable::Put() and HashTable::HasSufficientCapacityToAdd(). + DCHECK((table->NumberOfDeletedElements() << 1) > table->NumberOfElements() || + !table->HasSufficientCapacityToAdd(1)); +#endif + JSWeakCollection::Set(weak_collection, key, value, hash); return *weak_collection; } @@ -146,7 +162,7 @@ RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]); - CHECK(max_values >= 0); + CHECK_GE(max_values, 0); return *JSWeakCollection::GetEntries(holder, max_values); } diff --git a/deps/v8/src/runtime/runtime-compiler.cc b/deps/v8/src/runtime/runtime-compiler.cc index b445037d08..92ba3e6c3f 100644 --- a/deps/v8/src/runtime/runtime-compiler.cc +++ b/deps/v8/src/runtime/runtime-compiler.cc @@ -128,12 +128,21 @@ RUNTIME_FUNCTION(Runtime_InstantiateAsmJs) { return Smi::kZero; } -namespace { - -void MaterializeHeapObjectsAndDeleteDeoptimizer(Isolate* isolate, - Deoptimizer* deoptimizer) { +RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); + DCHECK(deoptimizer->compiled_code()->kind() == Code::OPTIMIZED_FUNCTION); + DCHECK(deoptimizer->compiled_code()->is_turbofanned()); DCHECK(AllowHeapAllocation::IsAllowed()); DCHECK_NULL(isolate->context()); + + TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); + TRACE_EVENT0("v8", "V8.DeoptimizeCode"); + Handle<JSFunction> function = deoptimizer->function(); + Deoptimizer::BailoutType type = deoptimizer->bailout_type(); + bool preserve_optimized_code = deoptimizer->preserve_optimized(); + // TODO(turbofan): We currently need the native context to materialize // the arguments object, but only to get to its map. isolate->set_context(deoptimizer->function()->native_context()); @@ -146,39 +155,9 @@ void MaterializeHeapObjectsAndDeleteDeoptimizer(Isolate* isolate, JavaScriptFrameIterator top_it(isolate); JavaScriptFrame* top_frame = top_it.frame(); isolate->set_context(Context::cast(top_frame->context())); -} -} // namespace - -RUNTIME_FUNCTION(Runtime_NotifyStubFailure) { - HandleScope scope(isolate); - DCHECK_EQ(0, args.length()); - Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); - DCHECK(deoptimizer->compiled_code()->kind() == Code::OPTIMIZED_FUNCTION); - DCHECK(deoptimizer->compiled_code()->is_turbofanned()); - MaterializeHeapObjectsAndDeleteDeoptimizer(isolate, deoptimizer); - return isolate->heap()->undefined_value(); -} - -RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { - HandleScope scope(isolate); - DCHECK_EQ(0, args.length()); - Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate); - DCHECK(deoptimizer->compiled_code()->kind() == Code::OPTIMIZED_FUNCTION); - DCHECK(deoptimizer->compiled_code()->is_turbofanned()); - - TimerEventScope<TimerEventDeoptimizeCode> timer(isolate); - TRACE_EVENT0("v8", "V8.DeoptimizeCode"); - Handle<JSFunction> function = deoptimizer->function(); - Deoptimizer::BailoutType type = deoptimizer->bailout_type(); - - MaterializeHeapObjectsAndDeleteDeoptimizer(isolate, deoptimizer); - - // TODO(mstarzinger): The marking of the function for deoptimization is the - // only difference to {Runtime_NotifyStubFailure} by now and we should also - // do this if the top-most frame is a builtin stub to avoid deoptimization - // loops. This would also unify the two runtime functions. - if (type != Deoptimizer::LAZY) { + // Invalidate the underlying optimized code on non-lazy deopts. + if (type != Deoptimizer::LAZY && !preserve_optimized_code) { Deoptimizer::DeoptimizeFunction(*function); } @@ -232,9 +211,6 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - // We're not prepared to handle a function with arguments object. - DCHECK(!function->shared()->uses_arguments()); - // Only reachable when OST is enabled. CHECK(FLAG_use_osr); @@ -263,8 +239,8 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { Handle<Code> result; if (maybe_result.ToHandle(&result) && result->kind() == Code::OPTIMIZED_FUNCTION) { - DeoptimizationInputData* data = - DeoptimizationInputData::cast(result->deoptimization_data()); + DeoptimizationData* data = + DeoptimizationData::cast(result->deoptimization_data()); if (data->OsrPcOffset()->value() >= 0) { DCHECK(BailoutId(data->OsrBytecodeOffset()->value()) == ast_id); @@ -299,7 +275,7 @@ RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) { if (!function->IsOptimized()) { function->set_code(function->shared()->code()); } - return NULL; + return nullptr; } static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source, diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc index 9251fa3a7f..d7395c7a7f 100644 --- a/deps/v8/src/runtime/runtime-debug.cc +++ b/deps/v8/src/runtime/runtime-debug.cc @@ -21,16 +21,23 @@ #include "src/isolate-inl.h" #include "src/objects/debug-objects-inl.h" #include "src/runtime/runtime.h" +#include "src/snapshot/snapshot.h" #include "src/wasm/wasm-objects-inl.h" namespace v8 { namespace internal { -RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) { +RUNTIME_FUNCTION_RETURN_PAIR(Runtime_DebugBreakOnBytecode) { + using interpreter::Bytecode; + using interpreter::Bytecodes; + using interpreter::OperandScale; + SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); HandleScope scope(isolate); + // Return value can be changed by debugger. Last set value will be used as + // return value. ReturnValueScope result_scope(isolate->debug()); isolate->debug()->set_return_value(*value); @@ -45,16 +52,22 @@ RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) { SharedFunctionInfo* shared = interpreted_frame->function()->shared(); BytecodeArray* bytecode_array = shared->bytecode_array(); int bytecode_offset = interpreted_frame->GetBytecodeOffset(); - interpreter::Bytecode bytecode = - interpreter::Bytecodes::FromByte(bytecode_array->get(bytecode_offset)); - if (bytecode == interpreter::Bytecode::kReturn) { + Bytecode bytecode = Bytecodes::FromByte(bytecode_array->get(bytecode_offset)); + if (bytecode == Bytecode::kReturn) { // If we are returning, reset the bytecode array on the interpreted stack // frame to the non-debug variant so that the interpreter entry trampoline // sees the return bytecode rather than the DebugBreak. interpreted_frame->PatchBytecodeArray(bytecode_array); } - return isolate->interpreter()->GetBytecodeHandler( - bytecode, interpreter::OperandScale::kSingle); + + // We do not have to deal with operand scale here. If the bytecode at the + // break is prefixed by operand scaling, we would have patched over the + // scaling prefix. We now simply dispatch to the handler for the prefix. + OperandScale operand_scale = OperandScale::kSingle; + Code* code = isolate->interpreter()->GetAndMaybeDeserializeBytecodeHandler( + bytecode, operand_scale); + + return MakePair(isolate->debug()->return_value(), code); } @@ -96,9 +109,8 @@ RUNTIME_FUNCTION(Runtime_ScheduleBreak) { return isolate->heap()->undefined_value(); } - static Handle<Object> DebugGetProperty(LookupIterator* it, - bool* has_caught = NULL) { + bool* has_caught = nullptr) { for (; it->IsFound(); it->Next()) { switch (it->state()) { case LookupIterator::NOT_FOUND: @@ -122,7 +134,7 @@ static Handle<Object> DebugGetProperty(LookupIterator* it, if (!maybe_result.ToHandle(&result)) { result = handle(it->isolate()->pending_exception(), it->isolate()); it->isolate()->clear_pending_exception(); - if (has_caught != NULL) *has_caught = true; + if (has_caught != nullptr) *has_caught = true; } return result; } @@ -140,7 +152,7 @@ static MaybeHandle<JSArray> GetIteratorInternalProperties( Isolate* isolate, Handle<IteratorType> object) { Factory* factory = isolate->factory(); Handle<IteratorType> iterator = Handle<IteratorType>::cast(object); - const char* kind = NULL; + const char* kind = nullptr; switch (iterator->map()->instance_type()) { case JS_MAP_KEY_ITERATOR_TYPE: kind = "keys"; @@ -435,7 +447,6 @@ RUNTIME_FUNCTION(Runtime_GetFrameCount) { } std::vector<FrameSummary> frames; - frames.reserve(FLAG_max_inlining_levels + 1); for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) { frames.clear(); it.frame()->Summarize(&frames); @@ -1106,7 +1117,7 @@ RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) { 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); + CHECK_GE(source_position, 0); CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2); // Get the script from the script wrapper. @@ -1300,7 +1311,7 @@ RUNTIME_FUNCTION(Runtime_DebugReferencedBy) { CONVERT_ARG_HANDLE_CHECKED(Object, filter, 1); CHECK(filter->IsUndefined(isolate) || filter->IsJSObject()); CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]); - CHECK(max_references >= 0); + CHECK_GE(max_references, 0); std::vector<Handle<JSObject>> instances; Heap* heap = isolate->heap(); @@ -1356,7 +1367,7 @@ RUNTIME_FUNCTION(Runtime_DebugConstructedBy) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0); CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]); - CHECK(max_references >= 0); + CHECK_GE(max_references, 0); std::vector<Handle<JSObject>> instances; Heap* heap = isolate->heap(); @@ -1469,7 +1480,7 @@ RUNTIME_FUNCTION(Runtime_GetDebugContext) { RUNTIME_FUNCTION(Runtime_CollectGarbage) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); - isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, + isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask, GarbageCollectionReason::kRuntime); return isolate->heap()->undefined_value(); } @@ -1501,8 +1512,8 @@ RUNTIME_FUNCTION(Runtime_GetScript) { Handle<Script> found; { Script::Iterator iterator(isolate); - Script* script = NULL; - while ((script = iterator.Next()) != NULL) { + Script* script = nullptr; + while ((script = iterator.Next()) != nullptr) { if (!script->name()->IsString()) continue; String* name = String::cast(script->name()); if (name->Equals(*script_name)) { @@ -1678,8 +1689,8 @@ Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script, // Slow traversal over all scripts on the heap. bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) { Script::Iterator iterator(isolate); - Script* script = NULL; - while ((script = iterator.Next()) != NULL) { + Script* script = nullptr; + while ((script = iterator.Next()) != nullptr) { if (script->id() == needle) { *result = handle(script); return true; @@ -1858,9 +1869,9 @@ RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionPromiseCreated) { Handle<Symbol> async_stack_id_symbol = isolate->factory()->promise_async_stack_id_symbol(); JSObject::SetProperty(promise, async_stack_id_symbol, - handle(Smi::FromInt(id), isolate), STRICT) + handle(Smi::FromInt(id), isolate), + LanguageMode::kStrict) .Assert(); - isolate->debug()->OnAsyncTaskEvent(debug::kDebugEnqueueAsyncFunction, id, 0); return isolate->heap()->undefined_value(); } @@ -1874,20 +1885,6 @@ RUNTIME_FUNCTION(Runtime_DebugPromiseReject) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_DebugAsyncEventEnqueueRecurring) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); - CONVERT_SMI_ARG_CHECKED(status, 1); - if (isolate->debug()->is_active()) { - isolate->debug()->OnAsyncTaskEvent( - status == v8::Promise::kFulfilled ? debug::kDebugEnqueuePromiseResolve - : debug::kDebugEnqueuePromiseReject, - isolate->debug()->NextAsyncTaskId(promise), 0); - } - return isolate->heap()->undefined_value(); -} - RUNTIME_FUNCTION(Runtime_DebugIsActive) { SealHandleScope shs(isolate); return Smi::FromInt(isolate->debug()->is_active()); @@ -1895,7 +1892,7 @@ RUNTIME_FUNCTION(Runtime_DebugIsActive) { RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { UNIMPLEMENTED(); - return NULL; + return nullptr; } namespace { diff --git a/deps/v8/src/runtime/runtime-function.cc b/deps/v8/src/runtime/runtime-function.cc index bbb54404a1..c78ac8f6b1 100644 --- a/deps/v8/src/runtime/runtime-function.cc +++ b/deps/v8/src/runtime/runtime-function.cc @@ -97,18 +97,6 @@ RUNTIME_FUNCTION(Runtime_FunctionSetLength) { } -RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) { - HandleScope scope(isolate); - DCHECK_EQ(2, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); - CHECK(fun->IsConstructor()); - JSFunction::SetPrototype(fun, value); - return args[0]; // return TOS -} - - RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); @@ -220,15 +208,6 @@ RUNTIME_FUNCTION(Runtime_Call) { } -// ES6 section 9.2.1.2, OrdinaryCallBindThis for sloppy callee. -RUNTIME_FUNCTION(Runtime_ConvertReceiver) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); - return *Object::ConvertReceiver(isolate, receiver).ToHandleChecked(); -} - - RUNTIME_FUNCTION(Runtime_IsFunction) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc index 813a774611..6d0e2b8439 100644 --- a/deps/v8/src/runtime/runtime-internal.cc +++ b/deps/v8/src/runtime/runtime-internal.cc @@ -59,7 +59,7 @@ RUNTIME_FUNCTION(Runtime_InstallToContext) { if (index == Context::kNotFound) { index = Context::IntrinsicIndexForName(name); } - CHECK(index != Context::kNotFound); + CHECK_NE(index, Context::kNotFound); native_context->set(index, *object); } return isolate->heap()->undefined_value(); @@ -317,8 +317,8 @@ RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) { DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(size, 0); CHECK(IsAligned(size, kPointerSize)); - CHECK(size > 0); - CHECK(size <= kMaxRegularHeapObjectSize); + CHECK_GT(size, 0); + CHECK_LE(size, kMaxRegularHeapObjectSize); return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE); } @@ -328,7 +328,7 @@ RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) { CONVERT_SMI_ARG_CHECKED(size, 0); CONVERT_SMI_ARG_CHECKED(flags, 1); CHECK(IsAligned(size, kPointerSize)); - CHECK(size > 0); + CHECK_GT(size, 0); bool double_align = AllocateDoubleAlignFlag::decode(flags); AllocationSpace space = AllocateTargetSpace::decode(flags); CHECK(size <= kMaxRegularHeapObjectSize || space == LO_SPACE); @@ -370,7 +370,6 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) { // baseline code. For optimized code this will use the deoptimization // information to get canonical location information. std::vector<FrameSummary> frames; - frames.reserve(FLAG_max_inlining_levels + 1); it.frame()->Summarize(&frames); auto& summary = frames.back().AsJavaScript(); Handle<SharedFunctionInfo> shared(summary.function()->shared()); @@ -527,7 +526,7 @@ RUNTIME_FUNCTION(Runtime_DeserializeLazy) { DCHECK_EQ(Builtins::TFJ, Builtins::KindOf(builtin_id)); if (FLAG_trace_lazy_deserialization) { - PrintF("Lazy-deserializing %s\n", Builtins::name(builtin_id)); + PrintF("Lazy-deserializing builtin %s\n", Builtins::name(builtin_id)); } Code* code = Snapshot::DeserializeBuiltin(isolate, builtin_id); diff --git a/deps/v8/src/runtime/runtime-interpreter.cc b/deps/v8/src/runtime/runtime-interpreter.cc index 75e211bf24..b65a2327a3 100644 --- a/deps/v8/src/runtime/runtime-interpreter.cc +++ b/deps/v8/src/runtime/runtime-interpreter.cc @@ -13,12 +13,34 @@ #include "src/interpreter/bytecode-flags.h" #include "src/interpreter/bytecode-register.h" #include "src/interpreter/bytecodes.h" +#include "src/interpreter/interpreter.h" #include "src/isolate-inl.h" #include "src/ostreams.h" +#include "src/snapshot/snapshot.h" namespace v8 { namespace internal { +RUNTIME_FUNCTION(Runtime_InterpreterDeserializeLazy) { + HandleScope scope(isolate); + + DCHECK(FLAG_lazy_handler_deserialization); + DCHECK(FLAG_lazy_deserialization); + DCHECK_EQ(2, args.length()); + CONVERT_SMI_ARG_CHECKED(bytecode_int, 0); + CONVERT_SMI_ARG_CHECKED(operand_scale_int, 1); + + using interpreter::Bytecode; + using interpreter::Bytecodes; + using interpreter::OperandScale; + + Bytecode bytecode = Bytecodes::FromByte(bytecode_int); + OperandScale operand_scale = static_cast<OperandScale>(operand_scale_int); + + return isolate->interpreter()->GetAndMaybeDeserializeBytecodeHandler( + bytecode, operand_scale); +} + RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); @@ -173,5 +195,40 @@ RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) { #endif +#ifdef V8_TRACE_FEEDBACK_UPDATES + +RUNTIME_FUNCTION(Runtime_InterpreterTraceUpdateFeedback) { + if (!FLAG_trace_feedback_updates) { + return isolate->heap()->undefined_value(); + } + + SealHandleScope shs(isolate); + DCHECK_EQ(3, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); + CONVERT_SMI_ARG_CHECKED(slot, 1); + CONVERT_ARG_CHECKED(String, reason, 2); + + int slot_count = function->feedback_vector()->metadata()->slot_count(); + + OFStream os(stdout); + os << "[Feedback slot " << slot << "/" << slot_count << " in "; + function->shared()->ShortPrint(os); + os << " updated to "; + function->feedback_vector()->FeedbackSlotPrint(os, FeedbackSlot(slot)); + os << " - "; + + StringCharacterStream stream(reason); + while (stream.HasMore()) { + uint16_t character = stream.GetNext(); + PrintF("%c", character); + } + + os << "]" << std::endl; + + return isolate->heap()->undefined_value(); +} + +#endif + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-intl.cc b/deps/v8/src/runtime/runtime-intl.cc index 783450c8ef..c4f132b134 100644 --- a/deps/v8/src/runtime/runtime-intl.cc +++ b/deps/v8/src/runtime/runtime-intl.cc @@ -8,6 +8,7 @@ #include "src/runtime/runtime-utils.h" +#include <cmath> #include <memory> #include "src/api-natives.h" @@ -45,12 +46,8 @@ #include "unicode/uloc.h" #include "unicode/unistr.h" #include "unicode/unum.h" -#include "unicode/uvernum.h" #include "unicode/uversion.h" -#if U_ICU_VERSION_MAJOR_NUM >= 59 -#include "unicode/char16ptr.h" -#endif namespace v8 { namespace internal { @@ -105,7 +102,7 @@ RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) { DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, service, 0); - const icu::Locale* available_locales = NULL; + const icu::Locale* available_locales = nullptr; int32_t count = 0; if (service->IsUtf8EqualTo(CStrVector("collator"))) { @@ -217,7 +214,7 @@ RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) { CONVERT_ARG_HANDLE_CHECKED(String, type, 1); Handle<Symbol> marker = isolate->factory()->intl_initialized_marker_symbol(); - JSObject::SetProperty(input, marker, type, STRICT).Assert(); + JSObject::SetProperty(input, marker, type, LanguageMode::kStrict).Assert(); return isolate->heap()->undefined_value(); } @@ -260,17 +257,21 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormat) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); - CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); + CONVERT_NUMBER_ARG_HANDLE_CHECKED(date, 1); - Handle<Object> value; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(date)); + double date_value = date->Number(); + // Check for +-Infinity and Nan + if (!std::isfinite(date_value)) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError(MessageTemplate::kInvalidTimeValue)); + } icu::SimpleDateFormat* date_format = DateFormat::UnpackDateFormat(isolate, date_format_holder); CHECK_NOT_NULL(date_format); icu::UnicodeString result; - date_format->format(value->Number(), result); + date_format->format(date_value, result); RETURN_RESULT_OR_FAILURE( isolate, isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>( @@ -362,10 +363,13 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormatToParts) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); - CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); + CONVERT_NUMBER_ARG_HANDLE_CHECKED(date, 1); - Handle<Object> value; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(date)); + double date_value = date->Number(); + if (!std::isfinite(date_value)) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError(MessageTemplate::kInvalidTimeValue)); + } icu::SimpleDateFormat* date_format = DateFormat::UnpackDateFormat(isolate, date_format_holder); @@ -375,7 +379,7 @@ RUNTIME_FUNCTION(Runtime_InternalDateFormatToParts) { icu::FieldPositionIterator fp_iter; icu::FieldPosition fp; UErrorCode status = U_ZERO_ERROR; - date_format->format(value->Number(), formatted, &fp_iter, status); + date_format->format(date_value, formatted, &fp_iter, status); if (U_FAILURE(status)) return isolate->heap()->undefined_value(); Handle<JSArray> result = factory->NewJSArray(0); @@ -473,21 +477,12 @@ RUNTIME_FUNCTION(Runtime_CurrencyDigits) { CONVERT_ARG_HANDLE_CHECKED(String, currency, 0); - // TODO(littledan): Avoid transcoding the string twice - v8::String::Utf8Value currency_string(v8_isolate, - v8::Utils::ToLocal(currency)); - icu::UnicodeString currency_icu = - icu::UnicodeString::fromUTF8(*currency_string); + v8::String::Value currency_string(v8_isolate, v8::Utils::ToLocal(currency)); DisallowHeapAllocation no_gc; UErrorCode status = U_ZERO_ERROR; -#if U_ICU_VERSION_MAJOR_NUM >= 59 - uint32_t fraction_digits = ucurr_getDefaultFractionDigits( - icu::toUCharPtr(currency_icu.getTerminatedBuffer()), &status); -#else uint32_t fraction_digits = ucurr_getDefaultFractionDigits( - currency_icu.getTerminatedBuffer(), &status); -#endif + reinterpret_cast<const UChar*>(*currency_string), &status); // For missing currency codes, default to the most common, 2 if (!U_SUCCESS(status)) fraction_digits = 2; return Smi::FromInt(fraction_digits); @@ -660,7 +655,7 @@ RUNTIME_FUNCTION(Runtime_CreateBreakIterator) { if (!break_iterator) return isolate->ThrowIllegalOperation(); local_object->SetEmbedderField(0, reinterpret_cast<Smi*>(break_iterator)); - // Make sure that the pointer to adopted text is NULL. + // Make sure that the pointer to adopted text is nullptr. local_object->SetEmbedderField(1, static_cast<Smi*>(nullptr)); // Make object handle weak so we can delete the break iterator once GC kicks @@ -800,7 +795,7 @@ RUNTIME_FUNCTION(Runtime_StringLocaleConvertCase) { // Primary language tag can be up to 8 characters long in theory. // https://tools.ietf.org/html/bcp47#section-2.2.1 - DCHECK(lang_arg->length() <= 8); + DCHECK_LE(lang_arg->length(), 8); lang_arg = String::Flatten(lang_arg); s = String::Flatten(s); diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc index 0dc15793a9..c82a449bda 100644 --- a/deps/v8/src/runtime/runtime-literals.cc +++ b/deps/v8/src/runtime/runtime-literals.cc @@ -165,8 +165,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( break; } case DICTIONARY_ELEMENTS: { - Handle<SeededNumberDictionary> element_dictionary( - copy->element_dictionary()); + Handle<NumberDictionary> element_dictionary(copy->element_dictionary()); int capacity = element_dictionary->Capacity(); for (int i = 0; i < capacity; i++) { Object* raw = element_dictionary->ValueAt(i); @@ -373,7 +372,7 @@ struct ObjectBoilerplate { // TODO(cbruni): avoid making the boilerplate fast again, the clone stub // supports dict-mode objects directly. JSObject::MigrateSlowToFast(boilerplate, - boilerplate->map()->unused_property_fields(), + boilerplate->map()->UnusedPropertyFields(), "FastLiteral"); } return boilerplate; diff --git a/deps/v8/src/runtime/runtime-maths.cc b/deps/v8/src/runtime/runtime-maths.cc index bb8436cd11..1804f93229 100644 --- a/deps/v8/src/runtime/runtime-maths.cc +++ b/deps/v8/src/runtime/runtime-maths.cc @@ -8,7 +8,6 @@ #include "src/assembler.h" #include "src/base/utils/random-number-generator.h" #include "src/bootstrapper.h" -#include "src/codegen.h" #include "src/counters.h" #include "src/double.h" #include "src/objects-inl.h" diff --git a/deps/v8/src/runtime/runtime-module.cc b/deps/v8/src/runtime/runtime-module.cc index 6d83443ea8..bb16a772c0 100644 --- a/deps/v8/src/runtime/runtime-module.cc +++ b/deps/v8/src/runtime/runtime-module.cc @@ -57,5 +57,12 @@ RUNTIME_FUNCTION(Runtime_StoreModuleVariable) { return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_GetImportMetaObject) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + Handle<Module> module(isolate->context()->module()); + return *isolate->RunHostInitializeImportMetaObjectCallback(module); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-numbers.cc b/deps/v8/src/runtime/runtime-numbers.cc index e8c1d00573..8e351b3c74 100644 --- a/deps/v8/src/runtime/runtime-numbers.cc +++ b/deps/v8/src/runtime/runtime-numbers.cc @@ -7,7 +7,6 @@ #include "src/arguments.h" #include "src/base/bits.h" #include "src/bootstrapper.h" -#include "src/codegen.h" #include "src/isolate-inl.h" namespace v8 { @@ -108,9 +107,11 @@ RUNTIME_FUNCTION(Runtime_NumberToSmi) { return isolate->heap()->nan_value(); } - -// Compare two Smis as if they were converted to strings and then -// compared lexicographically. +// Compare two Smis x, y as if they were converted to strings and then +// compared lexicographically. Returns: +// -1 if x < y +// 0 if x == y +// 1 if x > y RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); @@ -118,12 +119,12 @@ RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { CONVERT_SMI_ARG_CHECKED(y_value, 1); // If the integers are equal so are the string representations. - if (x_value == y_value) return Smi::FromInt(EQUAL); + if (x_value == y_value) return Smi::FromInt(0); // If one of the integers is zero the normal integer order is the // same as the lexicographic order of the string representations. if (x_value == 0 || y_value == 0) - return Smi::FromInt(x_value < y_value ? LESS : GREATER); + return Smi::FromInt(x_value < y_value ? -1 : 1); // If only one of the integers is negative the negative number is // smallest because the char code of '-' is less than the char code @@ -134,8 +135,8 @@ RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { uint32_t x_scaled = x_value; uint32_t y_scaled = y_value; if (x_value < 0 || y_value < 0) { - if (y_value >= 0) return Smi::FromInt(LESS); - if (x_value >= 0) return Smi::FromInt(GREATER); + if (y_value >= 0) return Smi::FromInt(-1); + if (x_value >= 0) return Smi::FromInt(1); x_scaled = -x_value; y_scaled = -y_value; } @@ -153,15 +154,15 @@ RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { // integer comes first in the lexicographic order. // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - int x_log2 = 31 - base::bits::CountLeadingZeros32(x_scaled); + int x_log2 = 31 - base::bits::CountLeadingZeros(x_scaled); int x_log10 = ((x_log2 + 1) * 1233) >> 12; x_log10 -= x_scaled < kPowersOf10[x_log10]; - int y_log2 = 31 - base::bits::CountLeadingZeros32(y_scaled); + int y_log2 = 31 - base::bits::CountLeadingZeros(y_scaled); int y_log10 = ((y_log2 + 1) * 1233) >> 12; y_log10 -= y_scaled < kPowersOf10[y_log10]; - int tie = EQUAL; + int tie = 0; if (x_log10 < y_log10) { // X has fewer digits. We would like to simply scale up X but that @@ -172,15 +173,15 @@ RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) { // past the length of the shorter integer. x_scaled *= kPowersOf10[y_log10 - x_log10 - 1]; y_scaled /= 10; - tie = LESS; + tie = -1; } else if (y_log10 < x_log10) { y_scaled *= kPowersOf10[x_log10 - y_log10 - 1]; x_scaled /= 10; - tie = GREATER; + tie = 1; } - if (x_scaled < y_scaled) return Smi::FromInt(LESS); - if (x_scaled > y_scaled) return Smi::FromInt(GREATER); + if (x_scaled < y_scaled) return Smi::FromInt(-1); + if (x_scaled > y_scaled) return Smi::FromInt(1); return Smi::FromInt(tie); } diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index 4c8805eb25..057ead9407 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -305,7 +305,7 @@ RUNTIME_FUNCTION(Runtime_ObjectHasOwnProperty) { Maybe<bool> result = JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key); - if (!result.IsJust()) return isolate->heap()->exception(); + if (result.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(result.FromJust()); } else if (object->IsString()) { @@ -420,9 +420,8 @@ RUNTIME_FUNCTION(Runtime_InternalSetPrototype) { CHECK_EQ(*function_map, function->map()); } } - MAYBE_RETURN( - JSReceiver::SetPrototype(obj, prototype, false, Object::THROW_ON_ERROR), - isolate->heap()->exception()); + MAYBE_RETURN(JSReceiver::SetPrototype(obj, prototype, false, kThrowOnError), + isolate->heap()->exception()); return *obj; } @@ -478,7 +477,7 @@ RUNTIME_FUNCTION(Runtime_AddNamedProperty) { DCHECK(!name->ToArrayIndex(&index)); LookupIterator it(object, name, object, LookupIterator::OWN_SKIP_INTERCEPTOR); Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); - if (!maybe.IsJust()) return isolate->heap()->exception(); + if (maybe.IsNothing()) return isolate->heap()->exception(); DCHECK(!it.IsFound()); #endif @@ -504,7 +503,7 @@ RUNTIME_FUNCTION(Runtime_AddElement) { LookupIterator it(isolate, object, index, object, LookupIterator::OWN_SKIP_INTERCEPTOR); Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); - if (!maybe.IsJust()) return isolate->heap()->exception(); + if (maybe.IsNothing()) return isolate->heap()->exception(); DCHECK(!it.IsFound()); if (object->IsJSArray()) { @@ -609,7 +608,7 @@ RUNTIME_FUNCTION(Runtime_HasProperty) { // Lookup the {name} on {receiver}. Maybe<bool> maybe = JSReceiver::HasProperty(receiver, name); - if (!maybe.IsJust()) return isolate->heap()->exception(); + if (maybe.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(maybe.FromJust()); } @@ -676,8 +675,8 @@ RUNTIME_FUNCTION(Runtime_NewObject) { RETURN_RESULT_OR_FAILURE(isolate, JSObject::New(target, new_target)); } - -RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) { +RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTrackingForMap) { + DisallowHeapAllocation no_gc; HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -693,7 +692,7 @@ RUNTIME_FUNCTION(Runtime_LoadMutableDouble) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1); - CHECK((index->value() & 1) == 1); + CHECK_EQ(index->value() & 1, 1); FieldIndex field_index = FieldIndex::ForLoadByFieldIndex(object->map(), index->value()); if (field_index.is_inobject()) { @@ -810,9 +809,9 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) { isolate, object, name, object, LookupIterator::OWN); // Cannot fail since this should only be called when // creating an object literal. - CHECK(JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs, - Object::DONT_THROW) - .IsJust()); + CHECK( + JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs, kDontThrow) + .IsJust()); return *object; } @@ -1020,7 +1019,7 @@ RUNTIME_FUNCTION(Runtime_DefineMethodsInternal) { } Maybe<bool> success = JSReceiver::DefineOwnProperty( - isolate, target, key, &descriptor, Object::DONT_THROW); + isolate, target, key, &descriptor, kDontThrow); CHECK(success.FromJust()); } return isolate->heap()->undefined_value(); @@ -1049,15 +1048,12 @@ RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) { return isolate->heap()->undefined_value(); } - RUNTIME_FUNCTION(Runtime_ToObject) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); - RETURN_RESULT_OR_FAILURE(isolate, Object::ToObject(isolate, object)); + // Runtime call is implemented in InterpreterIntrinsics and lowered in + // JSIntrinsicLowering. + UNREACHABLE(); } - RUNTIME_FUNCTION(Runtime_ToPrimitive) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -1081,6 +1077,12 @@ RUNTIME_FUNCTION(Runtime_ToNumber) { RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumber(input)); } +RUNTIME_FUNCTION(Runtime_ToNumeric) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, input, 0); + RETURN_RESULT_OR_FAILURE(isolate, Object::ToNumeric(input)); +} RUNTIME_FUNCTION(Runtime_ToInteger) { HandleScope scope(isolate); @@ -1131,32 +1133,6 @@ RUNTIME_FUNCTION(Runtime_SameValueZero) { return isolate->heap()->ToBoolean(x->SameValueZero(y)); } - -// TODO(bmeurer): Kill this special wrapper and use TF compatible LessThan, -// GreaterThan, etc. which return true or false. -RUNTIME_FUNCTION(Runtime_Compare) { - HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, ncr, 2); - Maybe<ComparisonResult> result = Object::Compare(x, y); - if (result.IsJust()) { - switch (result.FromJust()) { - case ComparisonResult::kLessThan: - return Smi::FromInt(LESS); - case ComparisonResult::kEqual: - return Smi::FromInt(EQUAL); - case ComparisonResult::kGreaterThan: - return Smi::FromInt(GREATER); - case ComparisonResult::kUndefined: - return *ncr; - } - UNREACHABLE(); - } - return isolate->heap()->exception(); -} - RUNTIME_FUNCTION(Runtime_HasInPrototypeChain) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -1189,9 +1165,8 @@ RUNTIME_FUNCTION(Runtime_CreateDataProperty) { LookupIterator it = LookupIterator::PropertyOrElement( isolate, o, key, &success, LookupIterator::OWN); if (!success) return isolate->heap()->exception(); - MAYBE_RETURN( - JSReceiver::CreateDataProperty(&it, value, Object::THROW_ON_ERROR), - isolate->heap()->exception()); + MAYBE_RETURN(JSReceiver::CreateDataProperty(&it, value, kThrowOnError), + isolate->heap()->exception()); return *value; } diff --git a/deps/v8/src/runtime/runtime-operators.cc b/deps/v8/src/runtime/runtime-operators.cc index 2a9255b77e..42a7e21b82 100644 --- a/deps/v8/src/runtime/runtime-operators.cc +++ b/deps/v8/src/runtime/runtime-operators.cc @@ -114,7 +114,7 @@ RUNTIME_FUNCTION(Runtime_Equal) { CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); Maybe<bool> result = Object::Equals(x, y); - if (!result.IsJust()) return isolate->heap()->exception(); + if (result.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(result.FromJust()); } @@ -124,7 +124,7 @@ RUNTIME_FUNCTION(Runtime_NotEqual) { CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); Maybe<bool> result = Object::Equals(x, y); - if (!result.IsJust()) return isolate->heap()->exception(); + if (result.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(!result.FromJust()); } @@ -150,7 +150,7 @@ RUNTIME_FUNCTION(Runtime_LessThan) { CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); Maybe<bool> result = Object::LessThan(x, y); - if (!result.IsJust()) return isolate->heap()->exception(); + if (result.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(result.FromJust()); } @@ -160,7 +160,7 @@ RUNTIME_FUNCTION(Runtime_GreaterThan) { CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); Maybe<bool> result = Object::GreaterThan(x, y); - if (!result.IsJust()) return isolate->heap()->exception(); + if (result.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(result.FromJust()); } @@ -170,7 +170,7 @@ RUNTIME_FUNCTION(Runtime_LessThanOrEqual) { CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); Maybe<bool> result = Object::LessThanOrEqual(x, y); - if (!result.IsJust()) return isolate->heap()->exception(); + if (result.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(result.FromJust()); } @@ -180,7 +180,7 @@ RUNTIME_FUNCTION(Runtime_GreaterThanOrEqual) { CONVERT_ARG_HANDLE_CHECKED(Object, x, 0); CONVERT_ARG_HANDLE_CHECKED(Object, y, 1); Maybe<bool> result = Object::GreaterThanOrEqual(x, y); - if (!result.IsJust()) return isolate->heap()->exception(); + if (result.IsNothing()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(result.FromJust()); } diff --git a/deps/v8/src/runtime/runtime-promise.cc b/deps/v8/src/runtime/runtime-promise.cc index 855f5360fe..1d8ca623e1 100644 --- a/deps/v8/src/runtime/runtime-promise.cc +++ b/deps/v8/src/runtime/runtime-promise.cc @@ -45,9 +45,6 @@ RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) { // undefined, which will be interpreted by PromiseRejectEvent // as being a caught exception event. rejected_promise = isolate->GetPromiseOnStackOnThrow(); - isolate->debug()->OnAsyncTaskEvent( - debug::kDebugEnqueuePromiseReject, - isolate->debug()->NextAsyncTaskId(promise), 0); } PromiseRejectEvent(isolate, promise, rejected_promise, value, true); return isolate->heap()->undefined_value(); @@ -83,7 +80,7 @@ RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) { RUNTIME_FUNCTION(Runtime_EnqueuePromiseResolveThenableJob) { HandleScope scope(isolate); - DCHECK(args.length() == 1); + DCHECK_EQ(args.length(), 1); CONVERT_ARG_HANDLE_CHECKED(PromiseResolveThenableJobInfo, info, 0); isolate->EnqueueMicrotask(info); return isolate->heap()->undefined_value(); diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc index bb4a6457c8..2ba760b847 100644 --- a/deps/v8/src/runtime/runtime-regexp.cc +++ b/deps/v8/src/runtime/runtime-regexp.cc @@ -21,6 +21,20 @@ namespace internal { namespace { +// Returns -1 for failure. +uint32_t GetArgcForReplaceCallable(uint32_t num_captures, + bool has_named_captures) { + const uint32_t kAdditionalArgsWithoutNamedCaptures = 2; + const uint32_t kAdditionalArgsWithNamedCaptures = 3; + if (num_captures > Code::kMaxArguments) return -1; + uint32_t argc = has_named_captures + ? num_captures + kAdditionalArgsWithNamedCaptures + : num_captures + kAdditionalArgsWithoutNamedCaptures; + STATIC_ASSERT(Code::kMaxArguments < std::numeric_limits<uint32_t>::max() - + kAdditionalArgsWithNamedCaptures); + return (argc > Code::kMaxArguments) ? -1 : argc; +} + // Looks up the capture of the given name. Returns the (1-based) numbered // capture index or -1 on failure. int LookupNamedCapture(std::function<bool(String*)> name_matches, @@ -404,7 +418,7 @@ void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern, while (limit > 0) { pos = reinterpret_cast<const uint8_t*>( memchr(pos, pattern, subject_end - pos)); - if (pos == NULL) return; + if (pos == nullptr) return; indices->push_back(static_cast<int>(pos - subject_start)); pos++; limit--; @@ -633,7 +647,7 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( if (global_cache.HasException()) return isolate->heap()->exception(); int32_t* current_match = global_cache.FetchNext(); - if (current_match == NULL) { + if (current_match == nullptr) { if (global_cache.HasException()) return isolate->heap()->exception(); return *subject; } @@ -669,7 +683,7 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString( prev = end; current_match = global_cache.FetchNext(); - } while (current_match != NULL); + } while (current_match != nullptr); if (global_cache.HasException()) return isolate->heap()->exception(); @@ -706,7 +720,7 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString( if (global_cache.HasException()) return isolate->heap()->exception(); int32_t* current_match = global_cache.FetchNext(); - if (current_match == NULL) { + if (current_match == nullptr) { if (global_cache.HasException()) return isolate->heap()->exception(); return *subject; } @@ -742,7 +756,7 @@ MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString( prev = end; current_match = global_cache.FetchNext(); - } while (current_match != NULL); + } while (current_match != nullptr); if (global_cache.HasException()) return isolate->heap()->exception(); @@ -808,19 +822,6 @@ Object* StringReplaceGlobalRegExpWithStringHelper( } // namespace -RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) { - HandleScope scope(isolate); - DCHECK_EQ(4, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(String, subject, 0); - CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2); - CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); - CONVERT_ARG_HANDLE_CHECKED(RegExpMatchInfo, last_match_info, 3); - - return StringReplaceGlobalRegExpWithStringHelper( - isolate, regexp, subject, replacement, last_match_info); -} - RUNTIME_FUNCTION(Runtime_StringSplit) { HandleScope handle_scope(isolate); DCHECK_EQ(3, args.length()); @@ -902,33 +903,6 @@ RUNTIME_FUNCTION(Runtime_StringSplit) { return *result; } -// ES##sec-regexpcreate -// RegExpCreate ( P, F ) -RUNTIME_FUNCTION(Runtime_RegExpCreate) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(Object, source_object, 0); - - Handle<String> source; - if (source_object->IsUndefined(isolate)) { - source = isolate->factory()->empty_string(); - } else { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, source, Object::ToString(isolate, source_object)); - } - - Handle<Map> map(isolate->regexp_function()->initial_map()); - Handle<JSRegExp> regexp = - Handle<JSRegExp>::cast(isolate->factory()->NewJSObjectFromMap(map)); - - JSRegExp::Flags flags = JSRegExp::kNone; - - RETURN_FAILURE_ON_EXCEPTION(isolate, - JSRegExp::Initialize(regexp, source, flags)); - - return *regexp; -} - RUNTIME_FUNCTION(Runtime_RegExpExec) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); @@ -1216,7 +1190,7 @@ static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject, while (true) { int32_t* current_match = global_cache.FetchNext(); - if (current_match == NULL) break; + if (current_match == nullptr) break; match_start = current_match[0]; builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch); if (match_end < match_start) { @@ -1358,7 +1332,7 @@ MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate, String); last_index = PositiveNumberToUint32(*last_index_obj); - if (static_cast<int>(last_index) > string->length()) last_index = 0; + if (last_index > static_cast<uint32_t>(string->length())) last_index = 0; } Handle<Object> match_indices_obj; @@ -1477,7 +1451,7 @@ RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) { isolate, last_index_obj, Object::ToLength(isolate, last_index_obj)); last_index = PositiveNumberToUint32(*last_index_obj); - if (static_cast<int>(last_index) > subject->length()) last_index = 0; + if (last_index > static_cast<uint32_t>(subject->length())) last_index = 0; } Handle<Object> match_indices_obj; @@ -1523,7 +1497,11 @@ RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) { } DCHECK_IMPLIES(has_named_captures, FLAG_harmony_regexp_named_captures); - const int argc = has_named_captures ? m + 3 : m + 2; + const uint32_t argc = GetArgcForReplaceCallable(m, has_named_captures); + if (argc == static_cast<uint32_t>(-1)) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError(MessageTemplate::kTooManyArguments)); + } ScopedVector<Handle<Object>> argv(argc); int cursor = 0; @@ -1668,7 +1646,7 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) { static const int kInitialArraySize = 8; Handle<FixedArray> elems = factory->NewFixedArrayWithHoles(kInitialArraySize); - int num_elems = 0; + uint32_t num_elems = 0; uint32_t string_index = 0; uint32_t prev_string_index = 0; @@ -1682,8 +1660,8 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) { factory->undefined_value())); if (result->IsNull(isolate)) { - string_index = RegExpUtils::AdvanceStringIndex(isolate, string, - string_index, unicode); + string_index = static_cast<uint32_t>(RegExpUtils::AdvanceStringIndex( + isolate, string, string_index, unicode)); continue; } @@ -1697,8 +1675,8 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) { const uint32_t end = std::min(PositiveNumberToUint32(*last_index_obj), length); if (end == prev_string_index) { - string_index = RegExpUtils::AdvanceStringIndex(isolate, string, - string_index, unicode); + string_index = static_cast<uint32_t>(RegExpUtils::AdvanceStringIndex( + isolate, string, string_index, unicode)); continue; } @@ -1706,7 +1684,7 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) { Handle<String> substr = factory->NewSubString(string, prev_string_index, string_index); elems = FixedArray::SetAndGrow(elems, num_elems++, substr); - if (static_cast<uint32_t>(num_elems) == limit) { + if (num_elems == limit) { return *NewJSArrayWithElements(isolate, elems, num_elems); } } @@ -1720,14 +1698,14 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, num_captures_obj, Object::ToLength(isolate, num_captures_obj)); - const int num_captures = PositiveNumberToUint32(*num_captures_obj); + const uint32_t num_captures = PositiveNumberToUint32(*num_captures_obj); - for (int i = 1; i < num_captures; i++) { + for (uint32_t i = 1; i < num_captures; i++) { Handle<Object> capture; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, capture, Object::GetElement(isolate, result, i)); elems = FixedArray::SetAndGrow(elems, num_elems++, capture); - if (static_cast<uint32_t>(num_elems) == limit) { + if (num_elems == limit) { return *NewJSArrayWithElements(isolate, elems, num_elems); } } @@ -1834,7 +1812,8 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, captures_length_obj, Object::ToLength(isolate, captures_length_obj)); - const int captures_length = PositiveNumberToUint32(*captures_length_obj); + const uint32_t captures_length = + PositiveNumberToUint32(*captures_length_obj); Handle<Object> match_obj; ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, match_obj, @@ -1859,7 +1838,7 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { // Do not reserve capacity since captures_length is user-controlled. ZoneVector<Handle<Object>> captures(&zone); - for (int n = 0; n < captures_length; n++) { + for (uint32_t n = 0; n < captures_length; n++) { Handle<Object> capture; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, capture, Object::GetElement(isolate, result, n)); @@ -1883,12 +1862,17 @@ RUNTIME_FUNCTION(Runtime_RegExpReplace) { Handle<String> replacement; if (functional_replace) { - const int argc = - has_named_captures ? captures_length + 3 : captures_length + 2; + const uint32_t argc = + GetArgcForReplaceCallable(captures_length, has_named_captures); + if (argc == static_cast<uint32_t>(-1)) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewRangeError(MessageTemplate::kTooManyArguments)); + } + ScopedVector<Handle<Object>> argv(argc); int cursor = 0; - for (int j = 0; j < captures_length; j++) { + for (uint32_t j = 0; j < captures_length; j++) { argv[cursor++] = captures[j]; } @@ -1946,6 +1930,9 @@ RUNTIME_FUNCTION(Runtime_RegExpExecReThrow) { RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); + // TODO(pwong): To follow the spec more closely and simplify calling code, + // this could handle the canonicalization of pattern and flags. See + // https://tc39.github.io/ecma262/#sec-regexpinitialize CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); CONVERT_ARG_HANDLE_CHECKED(String, source, 1); CONVERT_ARG_HANDLE_CHECKED(String, flags, 2); diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index d4bfceb257..61795fc6cb 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -69,7 +69,7 @@ Object* DeclareGlobal( } LookupIterator it(global, name, global, lookup_config); Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); - if (!maybe.IsJust()) return isolate->heap()->exception(); + if (maybe.IsNothing()) return isolate->heap()->exception(); if (it.IsFound()) { PropertyAttributes old_attributes = maybe.FromJust(); @@ -82,7 +82,7 @@ Object* DeclareGlobal( if ((old_attributes & DONT_DELETE) != 0) { // Only allow reconfiguring globals to functions in user code (no // natives, which are marked as read-only). - DCHECK((attr & READ_ONLY) == 0); + DCHECK_EQ(attr & READ_ONLY, 0); // Check whether we can reconfigure the existing property into a // function. @@ -470,7 +470,7 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee, } } - DCHECK(context_index >= 0); + DCHECK_GE(context_index, 0); arguments->set_the_hole(index); parameter_map->set( index + 2, @@ -595,11 +595,14 @@ RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { iterator.Advance(); JavaScriptFrame* function_frame = JavaScriptFrame::cast(iterator.frame()); DCHECK(function_frame->is_java_script()); - int argc = function_frame->GetArgumentsLength(); + int argc = function_frame->ComputeParametersCount(); Address fp = function_frame->fp(); if (function_frame->has_adapted_arguments()) { iterator.Advance(); - fp = iterator.frame()->fp(); + ArgumentsAdaptorFrame* adaptor_frame = + ArgumentsAdaptorFrame::cast(iterator.frame()); + argc = adaptor_frame->ComputeParametersCount(); + fp = adaptor_frame->fp(); } Object** parameters = reinterpret_cast<Object**>( @@ -684,7 +687,7 @@ static Object* FindNameClash(Handle<ScopeInfo> scope_info, LookupIterator it(global_object, name, global_object, LookupIterator::OWN_SKIP_INTERCEPTOR); Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); - if (!maybe.IsJust()) return isolate->heap()->exception(); + if (maybe.IsNothing()) return isolate->heap()->exception(); if ((maybe.FromJust() & DONT_DELETE) != 0) { // ES#sec-globaldeclarationinstantiation 5.a: // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError @@ -841,7 +844,7 @@ RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { namespace { MaybeHandle<Object> LoadLookupSlot(Handle<String> name, - Object::ShouldThrow should_throw, + ShouldThrow should_throw, Handle<Object>* receiver_return = nullptr) { Isolate* const isolate = name->GetIsolate(); @@ -892,7 +895,7 @@ MaybeHandle<Object> LoadLookupSlot(Handle<String> name, return value; } - if (should_throw == Object::THROW_ON_ERROR) { + if (should_throw == kThrowOnError) { // The property doesn't exist - throw exception. THROW_NEW_ERROR( isolate, NewReferenceError(MessageTemplate::kNotDefined, name), Object); @@ -910,8 +913,7 @@ RUNTIME_FUNCTION(Runtime_LoadLookupSlot) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); - RETURN_RESULT_OR_FAILURE(isolate, - LoadLookupSlot(name, Object::THROW_ON_ERROR)); + RETURN_RESULT_OR_FAILURE(isolate, LoadLookupSlot(name, kThrowOnError)); } @@ -919,7 +921,7 @@ RUNTIME_FUNCTION(Runtime_LoadLookupSlotInsideTypeof) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); - RETURN_RESULT_OR_FAILURE(isolate, LoadLookupSlot(name, Object::DONT_THROW)); + RETURN_RESULT_OR_FAILURE(isolate, LoadLookupSlot(name, kDontThrow)); } @@ -931,7 +933,7 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotForCall) { Handle<Object> value; Handle<Object> receiver; ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, value, LoadLookupSlot(name, Object::THROW_ON_ERROR, &receiver), + isolate, value, LoadLookupSlot(name, kThrowOnError, &receiver), MakePair(isolate->heap()->exception(), nullptr)); return MakePair(*value, *receiver); } @@ -1012,7 +1014,8 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Sloppy) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); - RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, SLOPPY)); + RETURN_RESULT_OR_FAILURE(isolate, + StoreLookupSlot(name, value, LanguageMode::kSloppy)); } // Store into a dynamic context for sloppy-mode block-scoped function hoisting @@ -1025,8 +1028,9 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot_SloppyHoisting) { 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)); + RETURN_RESULT_OR_FAILURE( + isolate, + StoreLookupSlot(name, value, LanguageMode::kSloppy, lookup_flags)); } RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { @@ -1034,7 +1038,8 @@ RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, name, 0); CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); - RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); + RETURN_RESULT_OR_FAILURE(isolate, + StoreLookupSlot(name, value, LanguageMode::kStrict)); } } // namespace internal diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc index 1382362cce..1e2d1f5a56 100644 --- a/deps/v8/src/runtime/runtime-strings.cc +++ b/deps/v8/src/runtime/runtime-strings.cc @@ -237,8 +237,9 @@ RUNTIME_FUNCTION(Runtime_SubString) { } else { return isolate->ThrowIllegalOperation(); } - // The following condition is intentionally robust because the SubStringStub - // delegates here and we test this in cctest/test-strings/RobustSubStringStub. + // The following condition is intentionally robust because the SubString + // builtin delegates here and we test this in + // cctest/test-strings/RobustSubStringStub. if (end < start || start < 0 || end > string->length()) { return isolate->ThrowIllegalOperation(); } @@ -284,25 +285,6 @@ RUNTIME_FUNCTION(Runtime_StringCharCodeAt) { return Smi::FromInt(subject->Get(i)); } -RUNTIME_FUNCTION(Runtime_StringCompare) { - HandleScope handle_scope(isolate); - DCHECK_EQ(2, args.length()); - CONVERT_ARG_HANDLE_CHECKED(String, x, 0); - CONVERT_ARG_HANDLE_CHECKED(String, y, 1); - isolate->counters()->string_compare_runtime()->Increment(); - switch (String::Compare(x, y)) { - case ComparisonResult::kLessThan: - return Smi::FromInt(LESS); - case ComparisonResult::kEqual: - return Smi::FromInt(EQUAL); - case ComparisonResult::kGreaterThan: - return Smi::FromInt(GREATER); - case ComparisonResult::kUndefined: - break; - } - UNREACHABLE(); -} - RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); @@ -315,11 +297,11 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { size_t actual_array_length = 0; CHECK(TryNumberToSize(array->length(), &actual_array_length)); - CHECK(array_length >= 0); + CHECK_GE(array_length, 0); CHECK(static_cast<size_t>(array_length) <= actual_array_length); // This assumption is used by the slice encoding in one or two smis. - DCHECK(Smi::kMaxValue >= String::kMaxLength); + DCHECK_GE(Smi::kMaxValue, String::kMaxLength); CHECK(array->HasFastElements()); JSObject::EnsureCanContainHeapObjectElements(array); @@ -385,7 +367,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { } CONVERT_ARG_HANDLE_CHECKED(String, separator, 2); CHECK(array->HasObjectElements()); - CHECK(array_length >= 0); + CHECK_GE(array_length, 0); Handle<FixedArray> fixed_array(FixedArray::cast(array->elements())); if (fixed_array->length() < array_length) { @@ -401,7 +383,7 @@ RUNTIME_FUNCTION(Runtime_StringBuilderJoin) { } int separator_length = separator->length(); - CHECK(separator_length > 0); + CHECK_GT(separator_length, 0); int max_nof_separators = (String::kMaxLength + separator_length - 1) / separator_length; if (max_nof_separators < (array_length - 1)) { @@ -508,7 +490,7 @@ static void JoinSparseArrayWithSeparator(FixedArray* elements, int last_array_index = static_cast<int>(array_length - 1); // Array length must be representable as a signed 32-bit number, // otherwise the total string length would have been too large. - DCHECK(array_length <= 0x7fffffff); // Is int32_t. + DCHECK_LE(array_length, 0x7fffffff); // Is int32_t. int repeat = last_array_index - previous_separator_position; WriteRepeatToFlat<Char>(separator, buffer, cursor, repeat, separator_length); cursor += repeat * separator_length; @@ -526,7 +508,7 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { 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); + CHECK_GT(array_length, 0); // Find total length of join result. int string_length = 0; @@ -534,7 +516,7 @@ RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) { bool overflow = false; CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length()); CHECK(elements_length <= elements_array->elements()->length()); - CHECK((elements_length & 1) == 0); // Even length. + CHECK_EQ(elements_length & 1, 0); // Even length. FixedArray* elements = FixedArray::cast(elements_array->elements()); { DisallowHeapAllocation no_gc; @@ -616,7 +598,7 @@ static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars, elements->set(i, value, mode); } if (i < length) { - DCHECK(Smi::kZero == 0); + static_assert(Smi::kZero == 0, "Can use memset since Smi::kZero is 0"); memset(elements->data_start() + i, 0, kPointerSize * (length - i)); } #ifdef DEBUG @@ -669,7 +651,7 @@ RUNTIME_FUNCTION(Runtime_StringToArray) { #ifdef DEBUG for (int i = 0; i < length; ++i) { - DCHECK(String::cast(elements->get(i))->length() == 1); + DCHECK_EQ(String::cast(elements->get(i))->length(), 1); } #endif @@ -681,16 +663,10 @@ RUNTIME_FUNCTION(Runtime_StringLessThan) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, x, 0); CONVERT_ARG_HANDLE_CHECKED(String, y, 1); - switch (String::Compare(x, y)) { - case ComparisonResult::kLessThan: - return isolate->heap()->true_value(); - case ComparisonResult::kEqual: - case ComparisonResult::kGreaterThan: - return isolate->heap()->false_value(); - case ComparisonResult::kUndefined: - break; - } - UNREACHABLE(); + ComparisonResult result = String::Compare(x, y); + DCHECK_NE(result, ComparisonResult::kUndefined); + return isolate->heap()->ToBoolean( + ComparisonResultToBool(Operation::kLessThan, result)); } RUNTIME_FUNCTION(Runtime_StringLessThanOrEqual) { @@ -698,16 +674,10 @@ RUNTIME_FUNCTION(Runtime_StringLessThanOrEqual) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, x, 0); CONVERT_ARG_HANDLE_CHECKED(String, y, 1); - switch (String::Compare(x, y)) { - case ComparisonResult::kEqual: - case ComparisonResult::kLessThan: - return isolate->heap()->true_value(); - case ComparisonResult::kGreaterThan: - return isolate->heap()->false_value(); - case ComparisonResult::kUndefined: - break; - } - UNREACHABLE(); + ComparisonResult result = String::Compare(x, y); + DCHECK_NE(result, ComparisonResult::kUndefined); + return isolate->heap()->ToBoolean( + ComparisonResultToBool(Operation::kLessThanOrEqual, result)); } RUNTIME_FUNCTION(Runtime_StringGreaterThan) { @@ -715,16 +685,10 @@ RUNTIME_FUNCTION(Runtime_StringGreaterThan) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, x, 0); CONVERT_ARG_HANDLE_CHECKED(String, y, 1); - switch (String::Compare(x, y)) { - case ComparisonResult::kGreaterThan: - return isolate->heap()->true_value(); - case ComparisonResult::kEqual: - case ComparisonResult::kLessThan: - return isolate->heap()->false_value(); - case ComparisonResult::kUndefined: - break; - } - UNREACHABLE(); + ComparisonResult result = String::Compare(x, y); + DCHECK_NE(result, ComparisonResult::kUndefined); + return isolate->heap()->ToBoolean( + ComparisonResultToBool(Operation::kGreaterThan, result)); } RUNTIME_FUNCTION(Runtime_StringGreaterThanOrEqual) { @@ -732,16 +696,10 @@ RUNTIME_FUNCTION(Runtime_StringGreaterThanOrEqual) { DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(String, x, 0); CONVERT_ARG_HANDLE_CHECKED(String, y, 1); - switch (String::Compare(x, y)) { - case ComparisonResult::kEqual: - case ComparisonResult::kGreaterThan: - return isolate->heap()->true_value(); - case ComparisonResult::kLessThan: - return isolate->heap()->false_value(); - case ComparisonResult::kUndefined: - break; - } - UNREACHABLE(); + ComparisonResult result = String::Compare(x, y); + DCHECK_NE(result, ComparisonResult::kUndefined); + return isolate->heap()->ToBoolean( + ComparisonResultToBool(Operation::kGreaterThanOrEqual, result)); } RUNTIME_FUNCTION(Runtime_StringEqual) { diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index 19a4af50d1..b3cdf3fe67 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -17,9 +17,11 @@ #include "src/runtime-profiler.h" #include "src/snapshot/code-serializer.h" #include "src/snapshot/natives.h" +#include "src/trap-handler/trap-handler.h" #include "src/wasm/memory-tracing.h" #include "src/wasm/wasm-module.h" #include "src/wasm/wasm-objects-inl.h" +#include "src/wasm/wasm-serialization.h" namespace { struct WasmCompileControls { @@ -127,12 +129,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) { // If the function is not optimized, just return. if (!function->IsOptimized()) return isolate->heap()->undefined_value(); - // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported. - if (function->code()->is_turbofanned() && - !function->shared()->HasBytecodeArray()) { - return isolate->heap()->undefined_value(); - } - Deoptimizer::DeoptimizeFunction(*function); return isolate->heap()->undefined_value(); @@ -153,12 +149,6 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) { // If the function is not optimized, just return. if (!function->IsOptimized()) return isolate->heap()->undefined_value(); - // TODO(turbofan): Deoptimization from AstGraphBuilder is not supported. - if (function->code()->is_turbofanned() && - !function->shared()->HasBytecodeArray()) { - return isolate->heap()->undefined_value(); - } - Deoptimizer::DeoptimizeFunction(*function); return isolate->heap()->undefined_value(); @@ -482,7 +472,7 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { // calls an intermediate function, and the intermediate function // calls exactly one imported function HandleScope scope(isolate); - CHECK(args.length() == 2); + CHECK_EQ(args.length(), 2); // It takes two parameters, the first one is the JSFunction, // The second one is the type CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); @@ -492,48 +482,100 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { CONVERT_ARG_HANDLE_CHECKED(Smi, type, 1); Handle<Code> export_code = handle(function->code()); CHECK(export_code->kind() == Code::JS_TO_WASM_FUNCTION); - int const mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); + int const mask = + RelocInfo::ModeMask(FLAG_wasm_jit_to_native ? RelocInfo::JS_TO_WASM_CALL + : RelocInfo::CODE_TARGET); // check the type of the $export_fct - Handle<Code> export_fct; + wasm::WasmCode* export_fct = nullptr; + Handle<Code> export_fct_handle; + wasm::WasmCode* intermediate_fct = nullptr; + Handle<Code> intermediate_fct_handle; + int count = 0; for (RelocIterator it(*export_code, mask); !it.done(); it.next()) { RelocInfo* rinfo = it.rinfo(); - Address target_address = rinfo->target_address(); - Code* target = Code::GetCodeFromTargetAddress(target_address); - if (target->kind() == Code::WASM_FUNCTION) { - ++count; - export_fct = handle(target); + Address target_address = FLAG_wasm_jit_to_native + ? rinfo->js_to_wasm_address() + : rinfo->target_address(); + if (FLAG_wasm_jit_to_native) { + wasm::WasmCode* target = + isolate->wasm_code_manager()->LookupCode(target_address); + if (target->kind() == wasm::WasmCode::Function) { + ++count; + export_fct = target; + } + } else { + Code* target = Code::GetCodeFromTargetAddress(target_address); + if (target->kind() == Code::WASM_FUNCTION) { + ++count; + export_fct_handle = handle(target); + } } } - CHECK(count == 1); + CHECK_EQ(count, 1); // check the type of the intermediate_fct - Handle<Code> intermediate_fct; count = 0; - for (RelocIterator it(*export_fct, mask); !it.done(); it.next()) { - RelocInfo* rinfo = it.rinfo(); - Address target_address = rinfo->target_address(); - Code* target = Code::GetCodeFromTargetAddress(target_address); - if (target->kind() == Code::WASM_FUNCTION) { - ++count; - intermediate_fct = handle(target); + if (FLAG_wasm_jit_to_native) { + for (RelocIterator it(export_fct->instructions(), export_fct->reloc_info(), + export_fct->constant_pool(), + RelocInfo::ModeMask(RelocInfo::WASM_CALL)); + !it.done(); it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + wasm::WasmCode* target = + isolate->wasm_code_manager()->LookupCode(target_address); + if (target->kind() == wasm::WasmCode::Function) { + ++count; + intermediate_fct = target; + } + } + } else { + count = 0; + for (RelocIterator it(*export_fct_handle, mask); !it.done(); it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + Code* target = Code::GetCodeFromTargetAddress(target_address); + if (target->kind() == Code::WASM_FUNCTION) { + ++count; + intermediate_fct_handle = handle(target); + } } } - CHECK(count == 1); + CHECK_EQ(count, 1); // 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); - Code::Kind target_kind = - type->value() == 0 ? Code::WASM_FUNCTION : Code::WASM_TO_JS_FUNCTION; count = 0; - for (RelocIterator it(*intermediate_fct, mask); !it.done(); it.next()) { - RelocInfo* rinfo = it.rinfo(); - Address target_address = rinfo->target_address(); - Code* target = Code::GetCodeFromTargetAddress(target_address); - if (target->kind() == target_kind) { - ++count; - imported_fct = handle(target); + if (FLAG_wasm_jit_to_native) { + wasm::WasmCode::Kind target_kind = type->value() == 0 + ? wasm::WasmCode::WasmToWasmWrapper + : wasm::WasmCode::WasmToJsWrapper; + for (RelocIterator it(intermediate_fct->instructions(), + intermediate_fct->reloc_info(), + intermediate_fct->constant_pool(), + RelocInfo::ModeMask(RelocInfo::WASM_CALL)); + !it.done(); it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + wasm::WasmCode* target = + isolate->wasm_code_manager()->LookupCode(target_address); + if (target->kind() == target_kind) { + ++count; + } + } + } else { + Code::Kind target_kind = type->value() == 0 ? Code::WASM_TO_WASM_FUNCTION + : Code::WASM_TO_JS_FUNCTION; + count = 0; + for (RelocIterator it(*intermediate_fct_handle, mask); !it.done(); + it.next()) { + RelocInfo* rinfo = it.rinfo(); + Address target_address = rinfo->target_address(); + Code* target = Code::GetCodeFromTargetAddress(target_address); + if (target->kind() == target_kind) { + ++count; + } } } CHECK_LE(count, 1); @@ -543,7 +585,7 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) { RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { HandleScope scope(isolate); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); - CHECK(args.length() == 2); + CHECK_EQ(args.length(), 2); CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0); CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1); WasmCompileControls& ctrl = (*g_PerIsolateWasmControls.Pointer())[v8_isolate]; @@ -556,7 +598,7 @@ RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) { RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) { HandleScope scope(isolate); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); - CHECK(args.length() == 0); + CHECK_EQ(args.length(), 0); v8_isolate->SetWasmInstanceCallback(WasmInstanceOverride); return isolate->heap()->undefined_value(); } @@ -650,12 +692,25 @@ RUNTIME_FUNCTION(Runtime_DebugTrace) { RUNTIME_FUNCTION(Runtime_DebugTrackRetainingPath) { HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); + DCHECK_LE(1, args.length()); + DCHECK_GE(2, args.length()); if (!FLAG_track_retaining_path) { PrintF("DebugTrackRetainingPath requires --track-retaining-path flag.\n"); } else { CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0); - isolate->heap()->AddRetainingPathTarget(object); + RetainingPathOption option = RetainingPathOption::kDefault; + if (args.length() == 2) { + CONVERT_ARG_HANDLE_CHECKED(String, str, 1); + const char track_ephemeral_path[] = "track-ephemeral-path"; + if (str->IsOneByteEqualTo(STATIC_CHAR_VECTOR(track_ephemeral_path))) { + option = RetainingPathOption::kTrackEphemeralPath; + } else if (str->length() != 0) { + PrintF("Unexpected second argument of DebugTrackRetainingPath.\n"); + PrintF("Expected an empty string or '%s', got '%s'.\n", + track_ephemeral_path, str->ToCString().get()); + } + } + isolate->heap()->AddRetainingPathTarget(object, option); } return isolate->heap()->undefined_value(); } @@ -802,11 +857,11 @@ RUNTIME_FUNCTION(Runtime_GetExceptionDetails) { key = factory->NewStringFromAsciiChecked("start_pos"); value = handle(Smi::FromInt(message_obj->start_position()), isolate); - JSObject::SetProperty(message, key, value, STRICT).Assert(); + JSObject::SetProperty(message, key, value, LanguageMode::kStrict).Assert(); key = factory->NewStringFromAsciiChecked("end_pos"); value = handle(Smi::FromInt(message_obj->end_position()), isolate); - JSObject::SetProperty(message, key, value, STRICT).Assert(); + JSObject::SetProperty(message, key, value, LanguageMode::kStrict).Assert(); return *message; } @@ -855,12 +910,18 @@ RUNTIME_FUNCTION(Runtime_DisallowCodegenFromStrings) { DCHECK_EQ(1, args.length()); CONVERT_BOOLEAN_ARG_CHECKED(flag, 0); v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); - if (flag) { - v8_isolate->SetAllowCodeGenerationFromStringsCallback( - DisallowCodegenFromStringsCallback); - } else { - v8_isolate->SetAllowCodeGenerationFromStringsCallback(nullptr); - } + v8_isolate->SetAllowCodeGenerationFromStringsCallback( + flag ? DisallowCodegenFromStringsCallback : nullptr); + return isolate->heap()->undefined_value(); +} + +RUNTIME_FUNCTION(Runtime_DisallowWasmCodegen) { + SealHandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_BOOLEAN_ARG_CHECKED(flag, 0); + v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate); + v8_isolate->SetAllowWasmCodeGenerationCallback( + flag ? DisallowCodegenFromStringsCallback : nullptr); return isolate->heap()->undefined_value(); } @@ -932,13 +993,24 @@ RUNTIME_FUNCTION(Runtime_SerializeWasmModule) { CONVERT_ARG_HANDLE_CHECKED(WasmModuleObject, module_obj, 0); Handle<WasmCompiledModule> orig(module_obj->compiled_module()); - std::unique_ptr<ScriptData> data = - WasmCompiledModuleSerializer::SerializeWasmModule(isolate, orig); - void* buff = isolate->array_buffer_allocator()->Allocate(data->length()); - Handle<JSArrayBuffer> ret = isolate->factory()->NewJSArrayBuffer(); - JSArrayBuffer::Setup(ret, isolate, false, buff, data->length()); - memcpy(buff, data->data(), data->length()); - return *ret; + if (FLAG_wasm_jit_to_native) { + std::pair<std::unique_ptr<byte[]>, size_t> serialized_module = + wasm::NativeModuleSerializer::SerializeWholeModule(isolate, orig); + int data_size = static_cast<int>(serialized_module.second); + void* buff = isolate->array_buffer_allocator()->Allocate(data_size); + Handle<JSArrayBuffer> ret = isolate->factory()->NewJSArrayBuffer(); + JSArrayBuffer::Setup(ret, isolate, false, buff, data_size); + memcpy(buff, serialized_module.first.get(), data_size); + return *ret; + } else { + std::unique_ptr<ScriptData> data = + WasmCompiledModuleSerializer::SerializeWasmModule(isolate, orig); + void* buff = isolate->array_buffer_allocator()->Allocate(data->length()); + Handle<JSArrayBuffer> ret = isolate->factory()->NewJSArrayBuffer(); + JSArrayBuffer::Setup(ret, isolate, false, buff, data->length()); + memcpy(buff, data->data(), data->length()); + return *ret; + } } // Take an array buffer and attempt to reconstruct a compiled wasm module. @@ -950,22 +1022,31 @@ RUNTIME_FUNCTION(Runtime_DeserializeWasmModule) { CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, wire_bytes, 1); Address mem_start = static_cast<Address>(buffer->backing_store()); - int mem_size = static_cast<int>(buffer->byte_length()->Number()); + size_t mem_size = static_cast<size_t>(buffer->byte_length()->Number()); // DeserializeWasmModule will allocate. We assume JSArrayBuffer doesn't // get relocated. - ScriptData sc(mem_start, mem_size); bool already_external = wire_bytes->is_external(); if (!already_external) { wire_bytes->set_is_external(true); isolate->heap()->UnregisterArrayBuffer(*wire_bytes); } - MaybeHandle<FixedArray> maybe_compiled_module = - WasmCompiledModuleSerializer::DeserializeWasmModule( - isolate, &sc, - Vector<const uint8_t>( - reinterpret_cast<uint8_t*>(wire_bytes->backing_store()), - static_cast<int>(wire_bytes->byte_length()->Number()))); + MaybeHandle<FixedArray> maybe_compiled_module; + if (FLAG_wasm_jit_to_native) { + maybe_compiled_module = + wasm::NativeModuleDeserializer::DeserializeFullBuffer( + isolate, {mem_start, mem_size}, + Vector<const uint8_t>( + reinterpret_cast<uint8_t*>(wire_bytes->backing_store()), + static_cast<int>(wire_bytes->byte_length()->Number()))); + } else { + ScriptData sc(mem_start, static_cast<int>(mem_size)); + maybe_compiled_module = WasmCompiledModuleSerializer::DeserializeWasmModule( + isolate, &sc, + Vector<const uint8_t>( + reinterpret_cast<uint8_t*>(wire_bytes->backing_store()), + static_cast<int>(wire_bytes->byte_length()->Number()))); + } if (!already_external) { wire_bytes->set_is_external(false); isolate->heap()->RegisterNewArrayBuffer(*wire_bytes); @@ -1058,8 +1139,10 @@ RUNTIME_FUNCTION(Runtime_WasmTraceMemory) { uint32_t addr = (static_cast<uint32_t>(addr_low) & 0xffff) | (static_cast<uint32_t>(addr_high) << 16); - uint8_t* mem_start = reinterpret_cast<uint8_t*>( - frame->wasm_instance()->memory_buffer()->allocation_base()); + uint8_t* mem_start = reinterpret_cast<uint8_t*>(frame->wasm_instance() + ->memory_object() + ->array_buffer() + ->allocation_base()); int func_index = frame->function_index(); int pos = frame->position(); // TODO(titzer): eliminate dependency on WasmModule definition here. @@ -1071,6 +1154,22 @@ RUNTIME_FUNCTION(Runtime_WasmTraceMemory) { return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_IsLiftoffFunction) { + HandleScope shs(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); + CHECK(WasmExportedFunction::IsWasmExportedFunction(*function)); + WasmCodeWrapper wrapper = + WasmExportedFunction::cast(*function)->GetWasmCode(); + if (!wrapper.IsCodeObject()) { + const wasm::WasmCode* wasm_code = wrapper.GetWasmCode(); + return isolate->heap()->ToBoolean(wasm_code->is_liftoff()); + } else { + Handle<Code> wasm_code = wrapper.GetCode(); + return isolate->heap()->ToBoolean(!wasm_code->is_turbofanned()); + } +} + RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -1081,6 +1180,5 @@ RUNTIME_FUNCTION(Runtime_CompleteInobjectSlackTracking) { return isolate->heap()->undefined_value(); } - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc index 8dfa8f166c..5820c4b6a4 100644 --- a/deps/v8/src/runtime/runtime-typedarray.cc +++ b/deps/v8/src/runtime/runtime-typedarray.cc @@ -36,8 +36,8 @@ RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) { if (!array_buffer->is_neuterable()) { return isolate->heap()->undefined_value(); } - if (array_buffer->backing_store() == NULL) { - CHECK(Smi::kZero == array_buffer->byte_length()); + if (array_buffer->backing_store() == nullptr) { + CHECK_EQ(Smi::kZero, array_buffer->byte_length()); return isolate->heap()->undefined_value(); } // Shared array buffers should never be neutered. @@ -200,7 +200,7 @@ RUNTIME_FUNCTION(Runtime_IsSharedInteger32TypedArray) { RUNTIME_FUNCTION(Runtime_TypedArraySpeciesCreateByLength) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(args.length(), 2); Handle<JSTypedArray> exemplar = args.at<JSTypedArray>(0); Handle<Object> length = args.at(1); int argc = 1; @@ -230,8 +230,8 @@ Object* TypedArraySetFromOverlapping(Isolate* isolate, size_t source_byte_length = NumberToSize(source->byte_length()); size_t target_byte_length = NumberToSize(target->byte_length()); - CHECK_LE(offset + source->length(), target->length()); - CHECK_GE(target->length(), source->length()); + CHECK_LE(offset, target->length_value()); + CHECK_LE(source->length_value(), target->length_value() - offset); CHECK(source->length()->IsSmi()); CHECK(!target->WasNeutered()); diff --git a/deps/v8/src/runtime/runtime-utils.h b/deps/v8/src/runtime/runtime-utils.h index 4218510a26..4a80ff5d40 100644 --- a/deps/v8/src/runtime/runtime-utils.h +++ b/deps/v8/src/runtime/runtime-utils.h @@ -94,9 +94,9 @@ namespace internal { // Cast the given argument to PropertyAttributes and store its value in a // variable with the given name. If the argument is not a Smi or the // enum value is out of range, we crash safely. -#define CONVERT_PROPERTY_ATTRIBUTES_CHECKED(name, index) \ - CHECK(args[index]->IsSmi()); \ - CHECK((args.smi_at(index) & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); \ +#define CONVERT_PROPERTY_ATTRIBUTES_CHECKED(name, index) \ + CHECK(args[index]->IsSmi()); \ + CHECK_EQ(args.smi_at(index) & ~(READ_ONLY | DONT_ENUM | DONT_DELETE), 0); \ PropertyAttributes name = static_cast<PropertyAttributes>(args.smi_at(index)); // A mechanism to return a pair of Object pointers in registers (if possible). diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc index 8ed4e7c57d..e8aef3fa97 100644 --- a/deps/v8/src/runtime/runtime-wasm.cc +++ b/deps/v8/src/runtime/runtime-wasm.cc @@ -16,6 +16,7 @@ #include "src/trap-handler/trap-handler.h" #include "src/v8memory.h" #include "src/wasm/module-compiler.h" +#include "src/wasm/wasm-heap.h" #include "src/wasm/wasm-objects.h" #include "src/wasm/wasm-opcodes.h" @@ -29,18 +30,41 @@ WasmInstanceObject* GetWasmInstanceOnStackTop(Isolate* isolate) { const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); Address pc = Memory::Address_at(entry + StandardFrameConstants::kCallerPCOffset); - Code* code = isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code; - DCHECK_EQ(Code::WASM_FUNCTION, code->kind()); - WasmInstanceObject* owning_instance = - WasmInstanceObject::GetOwningInstance(code); + WasmInstanceObject* owning_instance = nullptr; + if (FLAG_wasm_jit_to_native) { + owning_instance = WasmInstanceObject::GetOwningInstance( + isolate->wasm_code_manager()->LookupCode(pc)); + } else { + owning_instance = WasmInstanceObject::GetOwningInstanceGC( + isolate->inner_pointer_to_code_cache()->GetCacheEntry(pc)->code); + } CHECK_NOT_NULL(owning_instance); return owning_instance; } + Context* GetWasmContextOnStackTop(Isolate* isolate) { return GetWasmInstanceOnStackTop(isolate) ->compiled_module() ->ptr_to_native_context(); } + +class ClearThreadInWasmScope { + public: + explicit ClearThreadInWasmScope(bool coming_from_wasm) + : coming_from_wasm_(coming_from_wasm) { + DCHECK_EQ(trap_handler::UseTrapHandler() && coming_from_wasm, + trap_handler::IsThreadInWasm()); + if (coming_from_wasm) trap_handler::ClearThreadInWasm(); + } + ~ClearThreadInWasmScope() { + DCHECK(!trap_handler::IsThreadInWasm()); + if (coming_from_wasm_) trap_handler::SetThreadInWasm(); + } + + private: + const bool coming_from_wasm_; +}; + } // namespace RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { @@ -50,6 +74,9 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate), isolate); + // This runtime function is always being called from wasm code. + ClearThreadInWasmScope flag_scope(true); + // Set the current isolate's context. DCHECK_NULL(isolate->context()); isolate->set_context(instance->compiled_module()->ptr_to_native_context()); @@ -58,68 +85,19 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { WasmInstanceObject::GrowMemory(isolate, instance, delta_pages)); } -Object* ThrowRuntimeError(Isolate* isolate, int message_id, int byte_offset, - bool patch_source_position) { +RUNTIME_FUNCTION(Runtime_ThrowWasmError) { + DCHECK_EQ(1, args.length()); + CONVERT_SMI_ARG_CHECKED(message_id, 0); + ClearThreadInWasmScope clear_wasm_flag(isolate->context() == nullptr); + HandleScope scope(isolate); DCHECK_NULL(isolate->context()); isolate->set_context(GetWasmContextOnStackTop(isolate)); Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError( static_cast<MessageTemplate::Template>(message_id)); - - if (!patch_source_position) { - return isolate->Throw(*error_obj); - } - - // For wasm traps, the byte offset (a.k.a source position) can not be - // determined from relocation info, since the explicit checks for traps - // converge in one singe block which calls this runtime function. - // We hence pass the byte offset explicitely, and patch it into the top-most - // frame (a wasm frame) on the collected stack trace. - // TODO(wasm): This implementation is temporary, see bug #5007: - // https://bugs.chromium.org/p/v8/issues/detail?id=5007 - Handle<JSObject> error = Handle<JSObject>::cast(error_obj); - Handle<Object> stack_trace_obj = JSReceiver::GetDataProperty( - error, isolate->factory()->stack_trace_symbol()); - // Patch the stack trace (array of <receiver, function, code, position>). - if (stack_trace_obj->IsJSArray()) { - Handle<FrameArray> stack_elements( - FrameArray::cast(JSArray::cast(*stack_trace_obj)->elements())); - DCHECK(stack_elements->Code(0)->kind() == AbstractCode::WASM_FUNCTION); - DCHECK_LE(0, stack_elements->Offset(0)->value()); - stack_elements->SetOffset(0, Smi::FromInt(-1 - byte_offset)); - } - - // Patch the detailed stack trace (array of JSObjects with various - // properties). - Handle<Object> detailed_stack_trace_obj = JSReceiver::GetDataProperty( - error, isolate->factory()->detailed_stack_trace_symbol()); - if (detailed_stack_trace_obj->IsFixedArray()) { - Handle<FixedArray> stack_elements( - FixedArray::cast(*detailed_stack_trace_obj)); - DCHECK_GE(stack_elements->length(), 1); - Handle<StackFrameInfo> top_frame( - StackFrameInfo::cast(stack_elements->get(0))); - if (top_frame->column_number()) { - top_frame->set_column_number(byte_offset + 1); - } - } - return isolate->Throw(*error_obj); } -RUNTIME_FUNCTION(Runtime_ThrowWasmErrorFromTrapIf) { - DCHECK_EQ(1, args.length()); - CONVERT_SMI_ARG_CHECKED(message_id, 0); - return ThrowRuntimeError(isolate, message_id, 0, false); -} - -RUNTIME_FUNCTION(Runtime_ThrowWasmError) { - DCHECK_EQ(2, args.length()); - CONVERT_SMI_ARG_CHECKED(message_id, 0); - CONVERT_SMI_ARG_CHECKED(byte_offset, 1); - return ThrowRuntimeError(isolate, message_id, byte_offset, true); -} - RUNTIME_FUNCTION(Runtime_ThrowWasmStackOverflow) { SealHandleScope shs(isolate); DCHECK_LE(0, args.length()); @@ -149,7 +127,7 @@ RUNTIME_FUNCTION(Runtime_WasmThrowCreate) { CHECK(!JSReceiver::SetProperty(exception, isolate->factory()->InternalizeUtf8String( wasm::WasmException::kRuntimeIdStr), - id, STRICT) + id, LanguageMode::kStrict) .is_null()); CONVERT_SMI_ARG_CHECKED(size, 1); Handle<JSTypedArray> values = @@ -157,7 +135,7 @@ RUNTIME_FUNCTION(Runtime_WasmThrowCreate) { CHECK(!JSReceiver::SetProperty(exception, isolate->factory()->InternalizeUtf8String( wasm::WasmException::kRuntimeValuesStr), - values, STRICT) + values, LanguageMode::kStrict) .is_null()); return isolate->heap()->undefined_value(); } @@ -253,11 +231,11 @@ RUNTIME_FUNCTION(Runtime_WasmExceptionSetElement) { } RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { - DCHECK_EQ(3, args.length()); + DCHECK_EQ(2, args.length()); HandleScope scope(isolate); - 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); + CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[0]); + CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 1); + Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate)); // 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 @@ -266,6 +244,8 @@ RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { CHECK(arg_buffer_obj->IsSmi()); uint8_t* arg_buffer = reinterpret_cast<uint8_t*>(*arg_buffer_obj); + ClearThreadInWasmScope wasm_flag(true); + // Set the current isolate's context. DCHECK_NULL(isolate->context()); isolate->set_context(instance->compiled_module()->ptr_to_native_context()); @@ -297,11 +277,7 @@ RUNTIME_FUNCTION(Runtime_WasmStackGuard) { DCHECK_EQ(0, args.length()); DCHECK(!trap_handler::UseTrapHandler() || trap_handler::IsThreadInWasm()); - struct ClearAndRestoreThreadInWasm { - ClearAndRestoreThreadInWasm() { trap_handler::ClearThreadInWasm(); } - - ~ClearAndRestoreThreadInWasm() { trap_handler::SetThreadInWasm(); } - } restore_thread_in_wasm; + ClearThreadInWasmScope wasm_flag(true); // Set the current isolate's context. DCHECK_NULL(isolate->context()); @@ -318,7 +294,15 @@ RUNTIME_FUNCTION(Runtime_WasmCompileLazy) { DCHECK_EQ(0, args.length()); HandleScope scope(isolate); - return *wasm::CompileLazy(isolate); + if (FLAG_wasm_jit_to_native) { + Address new_func = wasm::CompileLazy(isolate); + // The alternative to this is having 2 lazy compile builtins. The builtins + // are part of the snapshot, so the flag has no impact on the codegen there. + return reinterpret_cast<Object*>(new_func - Code::kHeaderSize + + kHeapObjectTag); + } else { + return *wasm::CompileLazyOnGCHeap(isolate); + } } } // namespace internal diff --git a/deps/v8/src/runtime/runtime.cc b/deps/v8/src/runtime/runtime.cc index e6fa5a19cf..26880cdafa 100644 --- a/deps/v8/src/runtime/runtime.cc +++ b/deps/v8/src/runtime/runtime.cc @@ -108,7 +108,7 @@ const Runtime::Function* Runtime::FunctionForName(const unsigned char* name, if (entry) { return reinterpret_cast<Function*>(entry->value); } - return NULL; + return nullptr; } @@ -118,7 +118,7 @@ const Runtime::Function* Runtime::FunctionForEntry(Address entry) { return &(kIntrinsicFunctions[i]); } } - return NULL; + return nullptr; } diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index a11d274d25..da16ee5fc8 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -36,22 +36,23 @@ 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(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(ArraySpeciesConstructor, 1, 1) \ - F(ArrayIncludes_Slow, 3, 1) \ - F(ArrayIndexOf, 3, 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(TrySliceSimpleNonFastElements, 3, 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(ArraySpeciesConstructor, 1, 1) \ + F(ArrayIncludes_Slow, 3, 1) \ + F(ArrayIndexOf, 3, 1) \ F(SpreadIterablePrepare, 1, 1) #define FOR_EACH_INTRINSIC_ATOMICS(F) \ @@ -69,27 +70,31 @@ namespace internal { F(SetAllowAtomicsWait, 1, 1) #define FOR_EACH_INTRINSIC_BIGINT(F) \ - F(BigIntEqual, 2, 1) \ + F(BigIntBinaryOp, 3, 1) \ + F(BigIntCompareToBigInt, 3, 1) \ + F(BigIntCompareToNumber, 3, 1) \ + F(BigIntEqualToBigInt, 2, 1) \ + F(BigIntEqualToNumber, 2, 1) \ + F(BigIntEqualToString, 2, 1) \ F(BigIntToBoolean, 1, 1) \ - F(BigIntBinaryOp, 3, 1) - -#define FOR_EACH_INTRINSIC_CLASSES(F) \ - F(ThrowUnsupportedSuperError, 0, 1) \ - F(ThrowConstructorNonCallableError, 1, 1) \ - F(ThrowStaticPrototypeError, 0, 1) \ - F(ThrowSuperAlreadyCalledError, 0, 1) \ - F(ThrowSuperNotCalled, 0, 1) \ - F(ThrowNotSuperConstructor, 2, 1) \ - F(HomeObjectSymbol, 0, 1) \ - F(DefineClass, 4, 1) \ - F(InstallClassNameAccessor, 1, 1) \ - F(InstallClassNameAccessorWithCheck, 1, 1) \ - F(LoadFromSuper, 3, 1) \ - F(LoadKeyedFromSuper, 3, 1) \ - F(StoreToSuper_Strict, 4, 1) \ - F(StoreToSuper_Sloppy, 4, 1) \ - F(StoreKeyedToSuper_Strict, 4, 1) \ - F(StoreKeyedToSuper_Sloppy, 4, 1) \ + F(BigIntToNumber, 1, 1) \ + F(BigIntUnaryOp, 2, 1) + +#define FOR_EACH_INTRINSIC_CLASSES(F) \ + F(ThrowUnsupportedSuperError, 0, 1) \ + F(ThrowConstructorNonCallableError, 1, 1) \ + F(ThrowStaticPrototypeError, 0, 1) \ + F(ThrowSuperAlreadyCalledError, 0, 1) \ + F(ThrowSuperNotCalled, 0, 1) \ + F(ThrowNotSuperConstructor, 2, 1) \ + F(HomeObjectSymbol, 0, 1) \ + F(DefineClass, -1 /* >= 3 */, 1) \ + F(LoadFromSuper, 3, 1) \ + F(LoadKeyedFromSuper, 3, 1) \ + F(StoreToSuper_Strict, 4, 1) \ + F(StoreToSuper_Sloppy, 4, 1) \ + F(StoreKeyedToSuper_Strict, 4, 1) \ + F(StoreKeyedToSuper_Sloppy, 4, 1) \ F(GetSuperConstructor, 1, 1) #define FOR_EACH_INTRINSIC_COLLECTIONS(F) \ @@ -117,7 +122,6 @@ namespace internal { F(CompileOptimized_Concurrent, 1, 1) \ F(CompileOptimized_NotConcurrent, 1, 1) \ F(EvictOptimizedCodeSlot, 1, 1) \ - F(NotifyStubFailure, 0, 1) \ F(NotifyDeoptimized, 0, 1) \ F(CompileForOnStackReplacement, 1, 1) \ F(ResolvePossiblyDirectEval, 6, 1) \ @@ -130,7 +134,6 @@ namespace internal { #define FOR_EACH_INTRINSIC_DEBUG(F) \ F(HandleDebuggerStatement, 0, 1) \ - F(DebugBreakOnBytecode, 1, 1) \ F(SetDebugEventListener, 2, 1) \ F(ScheduleBreak, 0, 1) \ F(DebugGetInternalProperties, 1, 1) \ @@ -186,7 +189,6 @@ namespace internal { F(DebugPushPromise, 1, 1) \ F(DebugPopPromise, 0, 1) \ F(DebugPromiseReject, 2, 1) \ - F(DebugAsyncEventEnqueueRecurring, 2, 1) \ F(DebugAsyncFunctionPromiseCreated, 1, 1) \ F(DebugIsActive, 0, 1) \ F(DebugBreakInOptimizedCode, 0, 1) \ @@ -209,8 +211,17 @@ namespace internal { #define FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) #endif -#define FOR_EACH_INTRINSIC_INTERPRETER(F) \ - FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) \ +#ifdef V8_TRACE_FEEDBACK_UPDATES +#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F) \ + F(InterpreterTraceUpdateFeedback, 3, 1) +#else +#define FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F) +#endif + +#define FOR_EACH_INTRINSIC_INTERPRETER(F) \ + FOR_EACH_INTRINSIC_INTERPRETER_TRACE(F) \ + FOR_EACH_INTRINSIC_INTERPRETER_TRACE_FEEDBACK(F) \ + F(InterpreterDeserializeLazy, 2, 1) \ F(InterpreterNewClosure, 4, 1) #define FOR_EACH_INTRINSIC_FUNCTION(F) \ @@ -221,13 +232,11 @@ namespace internal { F(FunctionGetScriptSourcePosition, 1, 1) \ F(FunctionGetContextData, 1, 1) \ F(FunctionSetLength, 2, 1) \ - F(FunctionSetPrototype, 2, 1) \ F(FunctionIsAPIFunction, 1, 1) \ F(SetCode, 2, 1) \ F(SetNativeFlag, 1, 1) \ F(IsConstructor, 1, 1) \ F(Call, -1 /* >= 2 */, 1) \ - F(ConvertReceiver, 1, 1) \ F(IsFunction, 1, 1) \ F(FunctionToString, 1, 1) @@ -354,6 +363,7 @@ namespace internal { #define FOR_EACH_INTRINSIC_MODULE(F) \ F(DynamicImportCall, 2, 1) \ + F(GetImportMetaObject, 0, 1) \ F(GetModuleNamespace, 1, 1) \ F(LoadModuleVariable, 1, 1) \ F(StoreModuleVariable, 2, 1) @@ -394,7 +404,7 @@ namespace internal { F(ToFastProperties, 1, 1) \ F(AllocateHeapNumber, 0, 1) \ F(NewObject, 2, 1) \ - F(FinalizeInstanceSize, 1, 1) \ + F(CompleteInobjectSlackTrackingForMap, 1, 1) \ F(LoadMutableDouble, 2, 1) \ F(TryMigrateInstance, 1, 1) \ F(IsJSGlobalProxy, 1, 1) \ @@ -416,13 +426,13 @@ namespace internal { F(ToPrimitive, 1, 1) \ F(ToPrimitive_Number, 1, 1) \ F(ToNumber, 1, 1) \ + F(ToNumeric, 1, 1) \ F(ToInteger, 1, 1) \ F(ToLength, 1, 1) \ F(ToString, 1, 1) \ F(ToName, 1, 1) \ F(SameValue, 2, 1) \ F(SameValueZero, 2, 1) \ - F(Compare, 3, 1) \ F(HasInPrototypeChain, 2, 1) \ F(CreateIterResultObject, 2, 1) \ F(CreateDataProperty, 3, 1) \ @@ -478,7 +488,6 @@ namespace internal { #define FOR_EACH_INTRINSIC_REGEXP(F) \ F(IsRegExp, 1, 1) \ - F(RegExpCreate, 1, 1) \ F(RegExpExec, 4, 1) \ F(RegExpExecMultiple, 4, 1) \ F(RegExpExecReThrow, 0, 1) \ @@ -486,7 +495,6 @@ namespace internal { F(RegExpInternalReplace, 3, 1) \ F(RegExpReplace, 3, 1) \ F(RegExpSplit, 3, 1) \ - F(StringReplaceGlobalRegExpWithString, 4, 1) \ F(StringReplaceNonGlobalRegExpWithFunction, 3, 1) \ F(StringSplit, 3, 1) @@ -528,7 +536,6 @@ namespace internal { F(StringAdd, 2, 1) \ F(InternalizeString, 1, 1) \ F(StringCharCodeAt, 2, 1) \ - F(StringCompare, 2, 1) \ F(StringBuilderConcat, 3, 1) \ F(StringBuilderJoin, 3, 1) \ F(SparseJoinWithSeparator, 3, 1) \ @@ -572,7 +579,7 @@ namespace internal { F(SetAllocationTimeout, -1 /* 2 || 3 */, 1) \ F(DebugPrint, 1, 1) \ F(DebugTrace, 0, 1) \ - F(DebugTrackRetainingPath, 1, 1) \ + F(DebugTrackRetainingPath, -1, 1) \ F(PrintWithNameForAssert, 2, 1) \ F(GetExceptionDetails, 1, 1) \ F(GlobalPrint, 1, 1) \ @@ -613,6 +620,7 @@ namespace internal { F(IsWasmTrapHandlerEnabled, 0, 1) \ F(GetWasmRecoveredTrapCount, 0, 1) \ F(DisallowCodegenFromStrings, 1, 1) \ + F(DisallowWasmCodegen, 1, 1) \ F(ValidateWasmInstancesChain, 2, 1) \ F(ValidateWasmModuleState, 1, 1) \ F(ValidateWasmOrphanedInstance, 1, 1) \ @@ -622,7 +630,8 @@ namespace internal { F(WasmNumInterpretedCalls, 1, 1) \ F(RedirectToWasmInterpreter, 2, 1) \ F(WasmTraceMemory, 4, 1) \ - F(CompleteInobjectSlackTracking, 1, 1) + F(CompleteInobjectSlackTracking, 1, 1) \ + F(IsLiftoffFunction, 1, 1) #define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \ F(ArrayBufferGetByteLength, 1, 1) \ @@ -643,8 +652,7 @@ namespace internal { #define FOR_EACH_INTRINSIC_WASM(F) \ F(WasmGrowMemory, 1, 1) \ - F(ThrowWasmError, 2, 1) \ - F(ThrowWasmErrorFromTrapIf, 1, 1) \ + F(ThrowWasmError, 1, 1) \ F(ThrowWasmStackOverflow, 0, 1) \ F(WasmThrowTypeError, 0, 1) \ F(WasmThrowCreate, 2, 1) \ @@ -652,12 +660,13 @@ namespace internal { F(WasmGetExceptionRuntimeId, 0, 1) \ F(WasmExceptionSetElement, 2, 1) \ F(WasmExceptionGetElement, 1, 1) \ - F(WasmRunInterpreter, 3, 1) \ + F(WasmRunInterpreter, 2, 1) \ F(WasmStackGuard, 0, 1) \ F(WasmCompileLazy, 0, 1) #define FOR_EACH_INTRINSIC_RETURN_PAIR(F) \ - F(LoadLookupSlotForCall, 1, 2) + F(LoadLookupSlotForCall, 1, 2) \ + F(DebugBreakOnBytecode, 1, 2) // Most intrinsics are implemented in the runtime/ directory, but ICs are // implemented in ic.cc for now. @@ -672,6 +681,7 @@ namespace internal { F(LoadIC_Miss, 4, 1) \ F(LoadPropertyWithInterceptor, 5, 1) \ F(StoreCallbackProperty, 6, 1) \ + F(StoreGlobalIC_Slow, 5, 1) \ F(StoreIC_Miss, 5, 1) \ F(StorePropertyWithInterceptor, 5, 1) \ F(Unreachable, 0, 1) |