diff options
author | Michaël Zasso <targos@protonmail.com> | 2017-05-02 10:50:00 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2017-05-06 20:02:35 +0200 |
commit | 60d1aac8d225e844e68ae48e8f3d58802e635fbe (patch) | |
tree | 922f347dd054db18d88666fad7181e5a777f4022 /deps/v8/src/runtime | |
parent | 73d9c0f903ae371cd5011af64c3a6f69a1bda978 (diff) | |
download | android-node-v8-60d1aac8d225e844e68ae48e8f3d58802e635fbe.tar.gz android-node-v8-60d1aac8d225e844e68ae48e8f3d58802e635fbe.tar.bz2 android-node-v8-60d1aac8d225e844e68ae48e8f3d58802e635fbe.zip |
deps: update V8 to 5.8.283.38
PR-URL: https://github.com/nodejs/node/pull/12784
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com>
Diffstat (limited to 'deps/v8/src/runtime')
24 files changed, 749 insertions, 2047 deletions
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc index a9cbc208b3..07c6ad0116 100644 --- a/deps/v8/src/runtime/runtime-array.cc +++ b/deps/v8/src/runtime/runtime-array.cc @@ -37,7 +37,7 @@ static void InstallCode( BuiltinFunctionId id = static_cast<BuiltinFunctionId>(-1)) { Handle<String> key = isolate->factory()->InternalizeUtf8String(name); Handle<JSFunction> optimized = - isolate->factory()->NewFunctionWithoutPrototype(key, code); + isolate->factory()->NewFunctionWithoutPrototype(key, code, true); if (argc < 0) { optimized->shared()->DontAdaptArguments(); } else { @@ -46,6 +46,8 @@ static void InstallCode( if (id >= 0) { optimized->shared()->set_builtin_function_id(id); } + optimized->shared()->set_language_mode(STRICT); + optimized->shared()->set_native(true); JSObject::AddProperty(holder, key, optimized, NONE); } @@ -78,11 +80,9 @@ RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) { kArrayValues); InstallBuiltin(isolate, holder, "entries", Builtins::kArrayPrototypeEntries, 0, kArrayEntries); - return *holder; } - RUNTIME_FUNCTION(Runtime_FixedArrayGet) { SealHandleScope shs(isolate); DCHECK_EQ(2, args.length()); @@ -475,23 +475,32 @@ RUNTIME_FUNCTION(Runtime_ArrayIncludes_Slow) { // Let n be ? ToInteger(fromIndex). (If fromIndex is undefined, this step // produces the value 0.) - int64_t start_from; - { + int64_t index = 0; + if (!from_index->IsUndefined(isolate)) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, from_index, Object::ToInteger(isolate, from_index)); - double fp = from_index->Number(); - if (fp > len) return isolate->heap()->false_value(); - start_from = static_cast<int64_t>(fp); - } - int64_t index; - if (start_from >= 0) { - index = start_from; - } else { - index = len + start_from; - if (index < 0) { - index = 0; + if (V8_LIKELY(from_index->IsSmi())) { + int start_from = Smi::cast(*from_index)->value(); + if (start_from < 0) { + index = std::max<int64_t>(len + start_from, 0); + } else { + index = start_from; + } + } else { + DCHECK(from_index->IsHeapNumber()); + double start_from = from_index->Number(); + if (start_from >= len) return isolate->heap()->false_value(); + if (V8_LIKELY(std::isfinite(start_from))) { + if (start_from < 0) { + index = static_cast<int64_t>(std::max<double>(start_from + len, 0)); + } else { + index = start_from; + } + } } + + DCHECK_GE(index, 0); } // If the receiver is not a special receiver type, and the length is a valid @@ -646,5 +655,33 @@ RUNTIME_FUNCTION(Runtime_SpreadIterablePrepare) { return *spread; } +RUNTIME_FUNCTION(Runtime_SpreadIterableFixed) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, spread, 0); + + // The caller should check if proper iteration is necessary. + Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, spread, + Execution::Call(isolate, spread_iterable_function, + isolate->factory()->undefined_value(), 1, &spread)); + + // Create a new FixedArray and put the result of the spread into it. + Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); + uint32_t spread_length; + CHECK(spread_array->length()->ToArrayIndex(&spread_length)); + + Handle<FixedArray> result = isolate->factory()->NewFixedArray(spread_length); + ElementsAccessor* accessor = spread_array->GetElementsAccessor(); + for (uint32_t i = 0; i < spread_length; i++) { + DCHECK(accessor->HasElement(spread_array, i)); + Handle<Object> element = accessor->Get(spread_array, i); + result->set(i, *element); + } + + return *result; +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-classes.cc b/deps/v8/src/runtime/runtime-classes.cc index 246079232b..9398586de5 100644 --- a/deps/v8/src/runtime/runtime-classes.cc +++ b/deps/v8/src/runtime/runtime-classes.cc @@ -459,48 +459,5 @@ RUNTIME_FUNCTION(Runtime_GetSuperConstructor) { return prototype; } -RUNTIME_FUNCTION(Runtime_NewWithSpread) { - HandleScope scope(isolate); - DCHECK_LE(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, constructor, 0); - CONVERT_ARG_HANDLE_CHECKED(Object, new_target, 1); - - int constructor_argc = args.length() - 2; - CONVERT_ARG_HANDLE_CHECKED(Object, spread, args.length() - 1); - - // Iterate over the spread if we need to. - if (spread->IterationHasObservableEffects()) { - Handle<JSFunction> spread_iterable_function = isolate->spread_iterable(); - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, spread, - Execution::Call(isolate, spread_iterable_function, - isolate->factory()->undefined_value(), 1, &spread)); - } - - uint32_t spread_length; - Handle<JSArray> spread_array = Handle<JSArray>::cast(spread); - CHECK(spread_array->length()->ToArrayIndex(&spread_length)); - int result_length = constructor_argc - 1 + spread_length; - ScopedVector<Handle<Object>> construct_args(result_length); - - // Append each of the individual args to the result. - for (int i = 0; i < constructor_argc - 1; i++) { - construct_args[i] = args.at<Object>(2 + i); - } - - // Append element of the spread to the result. - ElementsAccessor* accessor = spread_array->GetElementsAccessor(); - for (uint32_t i = 0; i < spread_length; i++) { - DCHECK(accessor->HasElement(spread_array, i)); - Handle<Object> element = accessor->Get(spread_array, i); - construct_args[constructor_argc - 1 + i] = element; - } - - // Call the constructor. - RETURN_RESULT_OR_FAILURE( - isolate, Execution::New(isolate, constructor, new_target, result_length, - construct_args.start())); -} - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-collections.cc b/deps/v8/src/runtime/runtime-collections.cc index 15c1fab76f..214ce1c4e6 100644 --- a/deps/v8/src/runtime/runtime-collections.cc +++ b/deps/v8/src/runtime/runtime-collections.cc @@ -233,32 +233,7 @@ RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) { CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]); CHECK(max_entries >= 0); - - Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); - if (max_entries == 0 || max_entries > table->NumberOfElements()) { - max_entries = table->NumberOfElements(); - } - Handle<FixedArray> entries = - isolate->factory()->NewFixedArray(max_entries * 2); - // Allocation can cause GC can delete weak elements. Reload. - if (max_entries > table->NumberOfElements()) { - max_entries = table->NumberOfElements(); - } - - { - DisallowHeapAllocation no_gc; - int count = 0; - for (int i = 0; count / 2 < max_entries && i < table->Capacity(); i++) { - Handle<Object> key(table->KeyAt(i), isolate); - if (table->IsKey(isolate, *key)) { - entries->set(count++, *key); - Object* value = table->Lookup(key); - entries->set(count++, value); - } - } - DCHECK_EQ(max_entries * 2, count); - } - return *isolate->factory()->NewJSArrayWithElements(entries); + return *JSWeakCollection::GetEntries(holder, max_entries); } @@ -348,26 +323,7 @@ RUNTIME_FUNCTION(Runtime_GetWeakSetValues) { CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0); CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]); CHECK(max_values >= 0); - - Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table())); - if (max_values == 0 || max_values > table->NumberOfElements()) { - max_values = table->NumberOfElements(); - } - Handle<FixedArray> values = isolate->factory()->NewFixedArray(max_values); - // Recompute max_values because GC could have removed elements from the table. - if (max_values > table->NumberOfElements()) { - max_values = table->NumberOfElements(); - } - { - DisallowHeapAllocation no_gc; - int count = 0; - for (int i = 0; count < max_values && i < table->Capacity(); i++) { - Object* key = table->KeyAt(i); - if (table->IsKey(isolate, key)) values->set(count++, key); - } - DCHECK_EQ(max_values, count); - } - return *isolate->factory()->NewJSArrayWithElements(values); + return *JSWeakCollection::GetEntries(holder, max_values); } } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-compiler.cc b/deps/v8/src/runtime/runtime-compiler.cc index f1c76bb2ac..f929d73697 100644 --- a/deps/v8/src/runtime/runtime-compiler.cc +++ b/deps/v8/src/runtime/runtime-compiler.cc @@ -182,6 +182,10 @@ RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) { JavaScriptFrameIterator top_it(isolate); JavaScriptFrame* top_frame = top_it.frame(); isolate->set_context(Context::cast(top_frame->context())); + } else { + // TODO(turbofan): We currently need the native context to materialize + // the arguments object, but only to get to its map. + isolate->set_context(function->native_context()); } // Make sure to materialize objects before causing any allocation. @@ -442,9 +446,10 @@ static Object* CompileGlobalEval(Isolate* isolate, Handle<String> source, static const ParseRestriction restriction = NO_PARSE_RESTRICTION; Handle<JSFunction> compiled; ASSIGN_RETURN_ON_EXCEPTION_VALUE( - isolate, compiled, Compiler::GetFunctionFromEval( - source, outer_info, context, language_mode, - restriction, eval_scope_position, eval_position), + isolate, compiled, + Compiler::GetFunctionFromEval(source, outer_info, context, language_mode, + restriction, kNoSourcePosition, + eval_scope_position, eval_position), isolate->heap()->exception()); return *compiled; } diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc index d24a450cbf..3649621b09 100644 --- a/deps/v8/src/runtime/runtime-debug.cc +++ b/deps/v8/src/runtime/runtime-debug.cc @@ -6,6 +6,7 @@ #include "src/arguments.h" #include "src/compiler.h" +#include "src/debug/debug-coverage.h" #include "src/debug/debug-evaluate.h" #include "src/debug/debug-frames.h" #include "src/debug/debug-scopes.h" @@ -27,29 +28,28 @@ RUNTIME_FUNCTION(Runtime_DebugBreak) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); - isolate->debug()->set_return_value(value); + HandleScope scope(isolate); + ReturnValueScope result_scope(isolate->debug()); + isolate->debug()->set_return_value(*value); // Get the top-most JavaScript frame. JavaScriptFrameIterator it(isolate); isolate->debug()->Break(it.frame()); - - isolate->debug()->SetAfterBreakTarget(it.frame()); - return *isolate->debug()->return_value(); + return isolate->debug()->return_value(); } RUNTIME_FUNCTION(Runtime_DebugBreakOnBytecode) { SealHandleScope shs(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(Object, value, 0); - isolate->debug()->set_return_value(value); + HandleScope scope(isolate); + ReturnValueScope result_scope(isolate->debug()); + isolate->debug()->set_return_value(*value); // Get the top-most JavaScript frame. JavaScriptFrameIterator it(isolate); isolate->debug()->Break(it.frame()); - // If live-edit has dropped frames, we are not going back to dispatch. - if (LiveEdit::SetAfterBreakTarget(isolate->debug())) return Smi::kZero; - // Return the handler from the original bytecode array. DCHECK(it.frame()->is_interpreted()); InterpretedFrame* interpreted_frame = @@ -84,8 +84,13 @@ RUNTIME_FUNCTION(Runtime_SetDebugEventListener) { CHECK(args[0]->IsJSFunction() || args[0]->IsNullOrUndefined(isolate)); CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0); CONVERT_ARG_HANDLE_CHECKED(Object, data, 1); - isolate->debug()->SetEventListener(callback, data); - + if (callback->IsJSFunction()) { + JavaScriptDebugDelegate* delegate = new JavaScriptDebugDelegate( + isolate, Handle<JSFunction>::cast(callback), data); + isolate->debug()->SetDebugDelegate(delegate, true); + } else { + isolate->debug()->SetDebugDelegate(nullptr, false); + } return isolate->heap()->undefined_value(); } @@ -632,7 +637,7 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { // to the frame information. Handle<Object> return_value = isolate->factory()->undefined_value(); if (at_return) { - return_value = isolate->debug()->return_value(); + return_value = handle(isolate->debug()->return_value(), isolate); } // Now advance to the arguments adapter frame (if any). It contains all @@ -731,9 +736,12 @@ RUNTIME_FUNCTION(Runtime_GetFrameDetails) { } // Add the receiver (same as in function frame). - Handle<Object> receiver(it.frame()->receiver(), isolate); + Handle<Object> receiver = frame_inspector.summary().receiver(); DCHECK(function->shared()->IsUserJavaScript()); - DCHECK_IMPLIES(is_sloppy(shared->language_mode()), receiver->IsJSReceiver()); + // Optimized frames only restore the receiver as best-effort (see + // OptimizedFrame::Summarize). + DCHECK_IMPLIES(!is_optimized && is_sloppy(shared->language_mode()), + receiver->IsJSReceiver()); details->set(kFrameDetailsReceiverIndex, *receiver); DCHECK_EQ(details_size, details_index); @@ -751,8 +759,10 @@ RUNTIME_FUNCTION(Runtime_GetScopeCount) { // Get the frame where the debugging is performed. StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); - JavaScriptFrameIterator it(isolate, id); - JavaScriptFrame* frame = it.frame(); + StackTraceFrameIterator it(isolate, id); + StandardFrame* frame = it.frame(); + if (it.frame()->is_wasm()) return 0; + FrameInspector frame_inspector(frame, 0, isolate); // Count the visible scopes. @@ -786,8 +796,9 @@ RUNTIME_FUNCTION(Runtime_GetScopeDetails) { // Get the frame where the debugging is performed. StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); - JavaScriptFrameIterator frame_it(isolate, id); - JavaScriptFrame* frame = frame_it.frame(); + StackTraceFrameIterator frame_it(isolate, id); + // Wasm has no scopes, this must be javascript. + JavaScriptFrame* frame = JavaScriptFrame::cast(frame_it.frame()); FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); // Find the requested scope. @@ -975,8 +986,9 @@ RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) { // Get the frame where the debugging is performed. StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); - JavaScriptFrameIterator frame_it(isolate, id); - JavaScriptFrame* frame = frame_it.frame(); + StackTraceFrameIterator frame_it(isolate, id); + // Wasm has no scopes, this must be javascript. + JavaScriptFrame* frame = JavaScriptFrame::cast(frame_it.frame()); FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); ScopeIterator it(isolate, &frame_inspector); @@ -1178,7 +1190,7 @@ RUNTIME_FUNCTION(Runtime_PrepareStep) { // Get the step action and check validity. StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1])); if (step_action != StepIn && step_action != StepNext && - step_action != StepOut && step_action != StepFrame) { + step_action != StepOut) { return isolate->Throw(isolate->heap()->illegal_argument_string()); } @@ -1190,19 +1202,6 @@ RUNTIME_FUNCTION(Runtime_PrepareStep) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_PrepareStepFrame) { - HandleScope scope(isolate); - DCHECK_EQ(0, args.length()); - CHECK(isolate->debug()->CheckExecutionState()); - - // Clear all current stepping setup. - isolate->debug()->ClearStepping(); - - // Prepare step. - isolate->debug()->PrepareStep(StepFrame); - return isolate->heap()->undefined_value(); -} - // Clear all stepping set by PrepareStep. RUNTIME_FUNCTION(Runtime_ClearStepping) { HandleScope scope(isolate); @@ -1218,19 +1217,20 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) { // Check the execution state and decode arguments frame and source to be // evaluated. - DCHECK_EQ(4, args.length()); + DCHECK_EQ(5, args.length()); CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]); CHECK(isolate->debug()->CheckExecutionState(break_id)); CONVERT_SMI_ARG_CHECKED(wrapped_id, 1); CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]); CONVERT_ARG_HANDLE_CHECKED(String, source, 3); + CONVERT_BOOLEAN_ARG_CHECKED(throw_on_side_effect, 4); StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id); RETURN_RESULT_OR_FAILURE( - isolate, - DebugEvaluate::Local(isolate, id, inlined_jsframe_index, source)); + isolate, DebugEvaluate::Local(isolate, id, inlined_jsframe_index, source, + throw_on_side_effect)); } @@ -1253,10 +1253,6 @@ RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); - // This runtime function is used by the debugger to determine whether the - // debugger is active or not. Hence we fail gracefully here and don't crash. - if (!isolate->debug()->is_active()) return isolate->ThrowIllegalOperation(); - Handle<FixedArray> instances; { DebugScope debug_scope(isolate->debug()); @@ -1452,26 +1448,6 @@ RUNTIME_FUNCTION(Runtime_FunctionGetDebugName) { } -// Calls specified function with or without entering the debugger. -// This is used in unit tests to run code as if debugger is entered or simply -// to have a stack with C++ frame in the middle. -RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); - - DebugScope debug_scope(isolate->debug()); - if (debug_scope.failed()) { - DCHECK(isolate->has_pending_exception()); - return isolate->heap()->exception(); - } - - RETURN_RESULT_OR_FAILURE( - isolate, Execution::Call(isolate, function, - handle(function->global_proxy()), 0, NULL)); -} - - RUNTIME_FUNCTION(Runtime_GetDebugContext) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -1662,7 +1638,8 @@ namespace { int ScriptLinePositionWithOffset(Handle<Script> script, int line, int offset) { if (line < 0 || offset < 0) return -1; - if (line == 0) return ScriptLinePosition(script, line) + offset; + if (line == 0 || offset == 0) + return ScriptLinePosition(script, line) + offset; Script::PositionInfo info; if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) { @@ -1874,13 +1851,6 @@ RUNTIME_FUNCTION(Runtime_DebugPopPromise) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_DebugNextAsyncTaskId) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); - return Smi::FromInt(isolate->debug()->NextAsyncTaskId(promise)); -} - RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionPromiseCreated) { DCHECK_EQ(1, args.length()); HandleScope scope(isolate); @@ -1892,7 +1862,7 @@ RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionPromiseCreated) { JSObject::SetProperty(promise, async_stack_id_symbol, handle(Smi::FromInt(id), isolate), STRICT) .Assert(); - isolate->debug()->OnAsyncTaskEvent(debug::kDebugEnqueueAsyncFunction, id); + isolate->debug()->OnAsyncTaskEvent(debug::kDebugEnqueueAsyncFunction, id, 0); return isolate->heap()->undefined_value(); } @@ -1915,7 +1885,7 @@ RUNTIME_FUNCTION(Runtime_DebugAsyncEventEnqueueRecurring) { isolate->debug()->OnAsyncTaskEvent( status == v8::Promise::kFulfilled ? debug::kDebugEnqueuePromiseResolve : debug::kDebugEnqueuePromiseReject, - isolate->debug()->NextAsyncTaskId(promise)); + isolate->debug()->NextAsyncTaskId(promise), 0); } return isolate->heap()->undefined_value(); } @@ -1925,11 +1895,59 @@ RUNTIME_FUNCTION(Runtime_DebugIsActive) { return Smi::FromInt(isolate->debug()->is_active()); } - RUNTIME_FUNCTION(Runtime_DebugBreakInOptimizedCode) { UNIMPLEMENTED(); return NULL; } +RUNTIME_FUNCTION(Runtime_DebugCollectCoverage) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + // Collect coverage data. + std::unique_ptr<Coverage> coverage(Coverage::Collect(isolate, false)); + Factory* factory = isolate->factory(); + // Turn the returned data structure into JavaScript. + // Create an array of scripts. + int num_scripts = static_cast<int>(coverage->size()); + // Prepare property keys. + Handle<FixedArray> scripts_array = factory->NewFixedArray(num_scripts); + Handle<String> script_string = factory->NewStringFromStaticChars("script"); + Handle<String> start_string = factory->NewStringFromStaticChars("start"); + Handle<String> end_string = factory->NewStringFromStaticChars("end"); + Handle<String> count_string = factory->NewStringFromStaticChars("count"); + for (int i = 0; i < num_scripts; i++) { + const auto& script_data = coverage->at(i); + HandleScope inner_scope(isolate); + int num_functions = static_cast<int>(script_data.functions.size()); + Handle<FixedArray> functions_array = factory->NewFixedArray(num_functions); + for (int j = 0; j < num_functions; j++) { + const auto& function_data = script_data.functions[j]; + Handle<JSObject> range_obj = factory->NewJSObjectWithNullProto(); + JSObject::AddProperty(range_obj, start_string, + factory->NewNumberFromInt(function_data.start), + NONE); + JSObject::AddProperty(range_obj, end_string, + factory->NewNumberFromInt(function_data.end), NONE); + JSObject::AddProperty(range_obj, count_string, + factory->NewNumberFromUint(function_data.count), + NONE); + functions_array->set(j, *range_obj); + } + Handle<JSArray> script_obj = + factory->NewJSArrayWithElements(functions_array, FAST_ELEMENTS); + Handle<JSObject> wrapper = Script::GetWrapper(script_data.script); + JSObject::AddProperty(script_obj, script_string, wrapper, NONE); + scripts_array->set(i, *script_obj); + } + return *factory->NewJSArrayWithElements(scripts_array, FAST_ELEMENTS); +} + +RUNTIME_FUNCTION(Runtime_DebugTogglePreciseCoverage) { + SealHandleScope shs(isolate); + CONVERT_BOOLEAN_ARG_CHECKED(enable, 0); + Coverage::TogglePrecise(isolate, enable); + return isolate->heap()->undefined_value(); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-forin.cc b/deps/v8/src/runtime/runtime-forin.cc index bd37cdcf2f..9a7c539865 100644 --- a/deps/v8/src/runtime/runtime-forin.cc +++ b/deps/v8/src/runtime/runtime-forin.cc @@ -160,22 +160,5 @@ RUNTIME_FUNCTION(Runtime_ForInFilter) { HasEnumerableProperty(isolate, receiver, key)); } - -RUNTIME_FUNCTION(Runtime_ForInNext) { - HandleScope scope(isolate); - DCHECK_EQ(4, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - CONVERT_ARG_HANDLE_CHECKED(FixedArray, cache_array, 1); - CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 2); - CONVERT_SMI_ARG_CHECKED(index, 3); - Handle<Object> key = handle(cache_array->get(index), isolate); - // Don't need filtering if expected map still matches that of the receiver. - if (receiver->map() == *cache_type) { - return *key; - } - RETURN_RESULT_OR_FAILURE(isolate, - HasEnumerableProperty(isolate, receiver, key)); -} - } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-function.cc b/deps/v8/src/runtime/runtime-function.cc index 31da4a4535..ac8a430761 100644 --- a/deps/v8/src/runtime/runtime-function.cc +++ b/deps/v8/src/runtime/runtime-function.cc @@ -190,7 +190,6 @@ RUNTIME_FUNCTION(Runtime_SetCode) { target_shared->set_scope_info(source_shared->scope_info()); target_shared->set_outer_scope_info(source_shared->outer_scope_info()); target_shared->set_length(source_shared->length()); - target_shared->set_num_literals(source_shared->num_literals()); target_shared->set_feedback_metadata(source_shared->feedback_metadata()); target_shared->set_internal_formal_parameter_count( source_shared->internal_formal_parameter_count()); diff --git a/deps/v8/src/runtime/runtime-futex.cc b/deps/v8/src/runtime/runtime-futex.cc index 4af0831acf..b6582ffc7f 100644 --- a/deps/v8/src/runtime/runtime-futex.cc +++ b/deps/v8/src/runtime/runtime-futex.cc @@ -29,6 +29,11 @@ RUNTIME_FUNCTION(Runtime_AtomicsWait) { CHECK_EQ(sta->type(), kExternalInt32Array); CHECK(timeout == V8_INFINITY || !std::isnan(timeout)); + if (!isolate->allow_atomics_wait()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kAtomicsWaitNotAllowed)); + } + Handle<JSArrayBuffer> array_buffer = sta->GetBuffer(); size_t addr = (index << 2) + NumberToSize(sta->byte_offset()); @@ -40,7 +45,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsWake) { DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0); CONVERT_SIZE_ARG_CHECKED(index, 1); - CONVERT_INT32_ARG_CHECKED(count, 2); + CONVERT_UINT32_ARG_CHECKED(count, 2); CHECK(sta->GetBuffer()->is_shared()); CHECK_LT(index, NumberToSize(sta->length())); CHECK_EQ(sta->type(), kExternalInt32Array); @@ -65,5 +70,14 @@ RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) { return FutexEmulation::NumWaitersForTesting(isolate, array_buffer, addr); } + +RUNTIME_FUNCTION(Runtime_SetAllowAtomicsWait) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_BOOLEAN_ARG_CHECKED(set, 0); + + isolate->set_allow_atomics_wait(set); + return isolate->heap()->undefined_value(); +} } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-i18n.cc b/deps/v8/src/runtime/runtime-i18n.cc index 6630fadc10..e89175a37d 100644 --- a/deps/v8/src/runtime/runtime-i18n.cc +++ b/deps/v8/src/runtime/runtime-i18n.cc @@ -43,6 +43,7 @@ #include "unicode/uloc.h" #include "unicode/unistr.h" #include "unicode/unum.h" +#include "unicode/ustring.h" #include "unicode/uversion.h" @@ -609,10 +610,11 @@ RUNTIME_FUNCTION(Runtime_InternalCompare) { String::FlatContent flat2 = string2->GetFlatContent(); std::unique_ptr<uc16[]> sap1; std::unique_ptr<uc16[]> sap2; - const UChar* string_val1 = GetUCharBufferFromFlat(flat1, &sap1, length1); - const UChar* string_val2 = GetUCharBufferFromFlat(flat2, &sap2, length2); - result = - collator->compare(string_val1, length1, string_val2, length2, status); + icu::UnicodeString string_val1( + FALSE, GetUCharBufferFromFlat(flat1, &sap1, length1), length1); + icu::UnicodeString string_val2( + FALSE, GetUCharBufferFromFlat(flat2, &sap2, length2), length2); + result = collator->compare(string_val1, string_val2, status); } if (U_FAILURE(status)) return isolate->ThrowIllegalOperation(); @@ -831,6 +833,8 @@ MUST_USE_RESULT Object* LocaleConvertCase(Handle<String> s, Isolate* isolate, Handle<SeqTwoByteString> result; std::unique_ptr<uc16[]> sap; + if (dest_length == 0) return isolate->heap()->empty_string(); + // This is not a real loop. It'll be executed only once (no overflow) or // twice (overflow). for (int i = 0; i < 2; ++i) { @@ -1041,7 +1045,7 @@ MUST_USE_RESULT Object* ConvertToLower(Handle<String> s, Isolate* isolate) { MUST_USE_RESULT Object* ConvertToUpper(Handle<String> s, Isolate* isolate) { int32_t length = s->length(); - if (s->HasOnlyOneByteChars()) { + if (s->HasOnlyOneByteChars() && length > 0) { Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc index 6ff0a09b61..83995098c0 100644 --- a/deps/v8/src/runtime/runtime-internal.cc +++ b/deps/v8/src/runtime/runtime-internal.cc @@ -43,19 +43,6 @@ RUNTIME_FUNCTION(Runtime_ExportFromRuntime) { } -RUNTIME_FUNCTION(Runtime_ExportExperimentalFromRuntime) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSObject, container, 0); - CHECK(isolate->bootstrapper()->IsActive()); - JSObject::NormalizeProperties(container, KEEP_INOBJECT_PROPERTIES, 10, - "ExportExperimentalFromRuntime"); - Bootstrapper::ExportExperimentalFromRuntime(isolate, container); - JSObject::MigrateSlowToFast(container, 0, "ExportExperimentalFromRuntime"); - return *container; -} - - RUNTIME_FUNCTION(Runtime_InstallToContext) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -101,6 +88,13 @@ RUNTIME_FUNCTION(Runtime_ThrowStackOverflow) { return isolate->StackOverflow(); } +RUNTIME_FUNCTION(Runtime_ThrowSymbolAsyncIteratorInvalid) { + HandleScope scope(isolate); + DCHECK_EQ(0, args.length()); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kSymbolAsyncIteratorInvalid)); +} + RUNTIME_FUNCTION(Runtime_ThrowTypeError) { HandleScope scope(isolate); DCHECK_LE(1, args.length()); @@ -225,6 +219,26 @@ RUNTIME_FUNCTION(Runtime_ThrowSymbolIteratorInvalid) { isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid)); } +RUNTIME_FUNCTION(Runtime_ThrowNonCallableInInstanceOfCheck) { + HandleScope scope(isolate); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kNonCallableInInstanceOfCheck)); +} + +RUNTIME_FUNCTION(Runtime_ThrowNonObjectInInstanceOfCheck) { + HandleScope scope(isolate); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kNonObjectInInstanceOfCheck)); +} + +RUNTIME_FUNCTION(Runtime_ThrowNotConstructor) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kNotConstructor, object)); +} + RUNTIME_FUNCTION(Runtime_ThrowNotGeneric) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -299,6 +313,7 @@ RUNTIME_FUNCTION(Runtime_AllocateSeqOneByteString) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(length, 0); + if (length == 0) return isolate->heap()->empty_string(); Handle<SeqOneByteString> result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, isolate->factory()->NewRawOneByteString(length)); @@ -309,6 +324,7 @@ RUNTIME_FUNCTION(Runtime_AllocateSeqTwoByteString) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_SMI_ARG_CHECKED(length, 0); + if (length == 0) return isolate->heap()->empty_string(); Handle<SeqTwoByteString> result; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, result, isolate->factory()->NewRawTwoByteString(length)); @@ -350,8 +366,7 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) { Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { MessageLocation location; if (ComputeLocation(isolate, &location)) { - Zone zone(isolate->allocator(), ZONE_NAME); - std::unique_ptr<ParseInfo> info(new ParseInfo(&zone, location.shared())); + std::unique_ptr<ParseInfo> info(new ParseInfo(location.shared())); if (parsing::ParseAny(info.get())) { CallPrinter printer(isolate, location.shared()->IsUserJavaScript()); Handle<String> str = printer.Print(info->literal(), location.start_pos()); @@ -365,7 +380,6 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object) { } // namespace - RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); @@ -496,5 +510,20 @@ RUNTIME_FUNCTION(Runtime_AllowDynamicFunction) { Builtins::AllowDynamicFunction(isolate, target, global_proxy)); } +RUNTIME_FUNCTION(Runtime_CreateAsyncFromSyncIterator) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + + CONVERT_ARG_HANDLE_CHECKED(Object, sync_iterator, 0); + + if (!sync_iterator->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, NewTypeError(MessageTemplate::kSymbolIteratorInvalid)); + } + + return *isolate->factory()->NewJSAsyncFromSyncIterator( + Handle<JSReceiver>::cast(sync_iterator)); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime-interpreter.cc b/deps/v8/src/runtime/runtime-interpreter.cc index 2201b4c337..9f3897bf64 100644 --- a/deps/v8/src/runtime/runtime-interpreter.cc +++ b/deps/v8/src/runtime/runtime-interpreter.cc @@ -23,10 +23,15 @@ RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); + CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1); + CONVERT_SMI_ARG_CHECKED(index, 2); CONVERT_SMI_ARG_CHECKED(pretenured_flag, 3); Handle<Context> context(isolate->context(), isolate); + FeedbackSlot slot = FeedbackVector::ToSlot(index); + Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate); return *isolate->factory()->NewFunctionFromSharedFunctionInfo( - shared, context, static_cast<PretenureFlag>(pretenured_flag)); + shared, context, vector_cell, + static_cast<PretenureFlag>(pretenured_flag)); } namespace { diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc index 45b83293b6..7beadf5e0b 100644 --- a/deps/v8/src/runtime/runtime-literals.cc +++ b/deps/v8/src/runtime/runtime-literals.cc @@ -15,31 +15,23 @@ namespace v8 { namespace internal { static Handle<Map> ComputeObjectLiteralMap( - Handle<Context> context, Handle<FixedArray> constant_properties, + Handle<Context> context, + Handle<BoilerplateDescription> boilerplate_description, bool* is_result_from_cache) { - int properties_length = constant_properties->length(); - int number_of_properties = properties_length / 2; - - for (int p = 0; p != properties_length; p += 2) { - Object* key = constant_properties->get(p); - uint32_t element_index = 0; - if (key->ToArrayIndex(&element_index)) { - // An index key does not require space in the property backing store. - number_of_properties--; - } - } + int number_of_properties = boilerplate_description->backing_store_size(); Isolate* isolate = context->GetIsolate(); return isolate->factory()->ObjectLiteralMapFromCache( context, number_of_properties, is_result_from_cache); } MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( - Isolate* isolate, Handle<LiteralsArray> literals, - Handle<FixedArray> constant_properties); + Isolate* isolate, Handle<FeedbackVector> vector, + Handle<BoilerplateDescription> boilerplate_description); MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( - Isolate* isolate, Handle<LiteralsArray> literals, - Handle<FixedArray> constant_properties, bool should_have_fast_elements) { + Isolate* isolate, Handle<FeedbackVector> vector, + Handle<BoilerplateDescription> boilerplate_description, + bool should_have_fast_elements) { Handle<Context> context = isolate->native_context(); // In case we have function literals, we want the object to be in @@ -47,11 +39,11 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( // maps with constant functions can't be shared if the functions are // not the same (which is the common case). bool is_result_from_cache = false; - Handle<Map> map = ComputeObjectLiteralMap(context, constant_properties, + Handle<Map> map = ComputeObjectLiteralMap(context, boilerplate_description, &is_result_from_cache); PretenureFlag pretenure_flag = - isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; + isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; Handle<JSObject> boilerplate = isolate->factory()->NewJSObjectFromMap(map, pretenure_flag); @@ -60,26 +52,27 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate); // Add the constant properties to the boilerplate. - int length = constant_properties->length(); + int length = boilerplate_description->size(); bool should_transform = !is_result_from_cache && boilerplate->HasFastProperties(); bool should_normalize = should_transform; if (should_normalize) { // TODO(verwaest): We might not want to ever normalize here. - JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, - length / 2, "Boilerplate"); + JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES, length, + "Boilerplate"); } // TODO(verwaest): Support tracking representations in the boilerplate. - for (int index = 0; index < length; index += 2) { - Handle<Object> key(constant_properties->get(index + 0), isolate); - Handle<Object> value(constant_properties->get(index + 1), isolate); - if (value->IsFixedArray()) { - // The value contains the constant_properties of a + for (int index = 0; index < length; index++) { + Handle<Object> key(boilerplate_description->name(index), isolate); + Handle<Object> value(boilerplate_description->value(index), isolate); + if (value->IsBoilerplateDescription()) { + // The value contains the boilerplate properties of a // simple object or array literal. - Handle<FixedArray> array = Handle<FixedArray>::cast(value); + Handle<BoilerplateDescription> boilerplate = + Handle<BoilerplateDescription>::cast(value); ASSIGN_RETURN_ON_EXCEPTION( - isolate, value, CreateLiteralBoilerplate(isolate, literals, array), - Object); + isolate, value, + CreateLiteralBoilerplate(isolate, vector, boilerplate), Object); } MaybeHandle<Object> maybe_result; uint32_t element_index = 0; @@ -112,13 +105,13 @@ MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate( } static MaybeHandle<Object> CreateArrayLiteralBoilerplate( - Isolate* isolate, Handle<LiteralsArray> literals, + Isolate* isolate, Handle<FeedbackVector> vector, Handle<ConstantElementsPair> elements) { // Create the JSArray. Handle<JSFunction> constructor = isolate->array_function(); PretenureFlag pretenure_flag = - isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED; + isolate->heap()->InNewSpace(*vector) ? NOT_TENURED : TENURED; Handle<JSArray> object = Handle<JSArray>::cast( isolate->factory()->NewJSObject(constructor, pretenure_flag)); @@ -161,15 +154,16 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate( copied_elements_values = fixed_array_values_copy; FOR_WITH_HANDLE_SCOPE( isolate, int, i = 0, i, i < fixed_array_values->length(), i++, { - if (fixed_array_values->get(i)->IsFixedArray()) { - // The value contains the constant_properties of a + if (fixed_array_values->get(i)->IsBoilerplateDescription()) { + // The value contains the boilerplate properties of a // simple object or array literal. - Handle<FixedArray> fa( - FixedArray::cast(fixed_array_values->get(i))); + Handle<BoilerplateDescription> boilerplate( + BoilerplateDescription::cast(fixed_array_values->get(i))); Handle<Object> result; ASSIGN_RETURN_ON_EXCEPTION( isolate, result, - CreateLiteralBoilerplate(isolate, literals, fa), Object); + CreateLiteralBoilerplate(isolate, vector, boilerplate), + Object); fixed_array_values_copy->set(i, *result); } }); @@ -183,22 +177,24 @@ static MaybeHandle<Object> CreateArrayLiteralBoilerplate( } MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate( - Isolate* isolate, Handle<LiteralsArray> literals, - Handle<FixedArray> array) { + Isolate* isolate, Handle<FeedbackVector> vector, + Handle<BoilerplateDescription> array) { Handle<HeapObject> elements = CompileTimeValue::GetElements(array); switch (CompileTimeValue::GetLiteralType(array)) { case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: { - Handle<FixedArray> props = Handle<FixedArray>::cast(elements); - return CreateObjectLiteralBoilerplate(isolate, literals, props, true); + Handle<BoilerplateDescription> props = + Handle<BoilerplateDescription>::cast(elements); + return CreateObjectLiteralBoilerplate(isolate, vector, props, true); } case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: { - Handle<FixedArray> props = Handle<FixedArray>::cast(elements); - return CreateObjectLiteralBoilerplate(isolate, literals, props, false); + Handle<BoilerplateDescription> props = + Handle<BoilerplateDescription>::cast(elements); + return CreateObjectLiteralBoilerplate(isolate, vector, props, false); } case CompileTimeValue::ARRAY_LITERAL: { Handle<ConstantElementsPair> elems = Handle<ConstantElementsPair>::cast(elements); - return CreateArrayLiteralBoilerplate(isolate, literals, elems); + return CreateArrayLiteralBoilerplate(isolate, vector, elems); } default: UNREACHABLE(); @@ -214,13 +210,15 @@ RUNTIME_FUNCTION(Runtime_CreateRegExpLiteral) { CONVERT_SMI_ARG_CHECKED(index, 1); CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2); CONVERT_SMI_ARG_CHECKED(flags, 3); + FeedbackSlot literal_slot(FeedbackVector::ToSlot(index)); // Check if boilerplate exists. If not, create it first. - Handle<Object> boilerplate(closure->literals()->literal(index), isolate); + Handle<Object> boilerplate(closure->feedback_vector()->Get(literal_slot), + isolate); if (boilerplate->IsUndefined(isolate)) { ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, boilerplate, JSRegExp::New(pattern, JSRegExp::Flags(flags))); - closure->literals()->set_literal(index, *boilerplate); + closure->feedback_vector()->Set(literal_slot, *boilerplate); } return *JSRegExp::Copy(Handle<JSRegExp>::cast(boilerplate)); } @@ -231,24 +229,25 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { DCHECK_EQ(4, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 0); CONVERT_SMI_ARG_CHECKED(literals_index, 1); - CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2); + CONVERT_ARG_HANDLE_CHECKED(BoilerplateDescription, boilerplate_description, + 2); CONVERT_SMI_ARG_CHECKED(flags, 3); - Handle<LiteralsArray> literals(closure->literals(), isolate); + Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; - CHECK(literals_index >= 0); - CHECK(literals_index < literals->literals_count()); + FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); + CHECK(literals_slot.ToInt() < vector->slot_count()); // Check if boilerplate exists. If not, create it first. - Handle<Object> literal_site(literals->literal(literals_index), isolate); + Handle<Object> literal_site(vector->Get(literals_slot), isolate); Handle<AllocationSite> site; Handle<JSObject> boilerplate; if (literal_site->IsUndefined(isolate)) { Handle<Object> raw_boilerplate; ASSIGN_RETURN_FAILURE_ON_EXCEPTION( isolate, raw_boilerplate, - CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, + CreateObjectLiteralBoilerplate(isolate, vector, boilerplate_description, should_have_fast_elements)); boilerplate = Handle<JSObject>::cast(raw_boilerplate); @@ -259,7 +258,7 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { creation_context.ExitScope(site, boilerplate); // Update the functions literal and return the boilerplate. - literals->set_literal(literals_index, *site); + vector->Set(literals_slot, *site); } else { site = Handle<AllocationSite>::cast(literal_site); boilerplate = @@ -275,16 +274,16 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { } MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( - Isolate* isolate, Handle<LiteralsArray> literals, int literals_index, + Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot literals_slot, Handle<ConstantElementsPair> elements) { // Check if boilerplate exists. If not, create it first. - Handle<Object> literal_site(literals->literal(literals_index), isolate); + Handle<Object> literal_site(vector->Get(literals_slot), isolate); Handle<AllocationSite> site; if (literal_site->IsUndefined(isolate)) { Handle<Object> boilerplate; ASSIGN_RETURN_ON_EXCEPTION( isolate, boilerplate, - CreateArrayLiteralBoilerplate(isolate, literals, elements), + CreateArrayLiteralBoilerplate(isolate, vector, elements), AllocationSite); AllocationSiteCreationContext creation_context(isolate); @@ -295,7 +294,7 @@ MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( } creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate)); - literals->set_literal(literals_index, *site); + vector->Set(literals_slot, *site); } else { site = Handle<AllocationSite>::cast(literal_site); } @@ -304,13 +303,13 @@ MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite( } static MaybeHandle<JSObject> CreateArrayLiteralImpl( - Isolate* isolate, Handle<LiteralsArray> literals, int literals_index, + Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot literals_slot, Handle<ConstantElementsPair> elements, int flags) { - CHECK(literals_index >= 0 && literals_index < literals->literals_count()); + CHECK(literals_slot.ToInt() < vector->slot_count()); Handle<AllocationSite> site; ASSIGN_RETURN_ON_EXCEPTION( isolate, site, - GetLiteralAllocationSite(isolate, literals, literals_index, elements), + GetLiteralAllocationSite(isolate, vector, literals_slot, elements), JSObject); bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; @@ -335,10 +334,11 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) { CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); CONVERT_SMI_ARG_CHECKED(flags, 3); - Handle<LiteralsArray> literals(closure->literals(), isolate); + FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); + Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); RETURN_RESULT_OR_FAILURE( - isolate, CreateArrayLiteralImpl(isolate, literals, literals_index, - elements, flags)); + isolate, + CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, flags)); } @@ -349,11 +349,11 @@ RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) { CONVERT_SMI_ARG_CHECKED(literals_index, 1); CONVERT_ARG_HANDLE_CHECKED(ConstantElementsPair, elements, 2); - Handle<LiteralsArray> literals(closure->literals(), isolate); + Handle<FeedbackVector> vector(closure->feedback_vector(), isolate); + FeedbackSlot literals_slot(FeedbackVector::ToSlot(literals_index)); RETURN_RESULT_OR_FAILURE( - isolate, - CreateArrayLiteralImpl(isolate, literals, literals_index, elements, - ArrayLiteral::kShallowElements)); + isolate, CreateArrayLiteralImpl(isolate, vector, literals_slot, elements, + ArrayLiteral::kShallowElements)); } } // namespace internal diff --git a/deps/v8/src/runtime/runtime-maths.cc b/deps/v8/src/runtime/runtime-maths.cc index 5bd7bde1eb..4cb4f006ff 100644 --- a/deps/v8/src/runtime/runtime-maths.cc +++ b/deps/v8/src/runtime/runtime-maths.cc @@ -9,6 +9,9 @@ #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" namespace v8 { namespace internal { diff --git a/deps/v8/src/runtime/runtime-module.cc b/deps/v8/src/runtime/runtime-module.cc index f2a9761203..f36a09b410 100644 --- a/deps/v8/src/runtime/runtime-module.cc +++ b/deps/v8/src/runtime/runtime-module.cc @@ -5,10 +5,19 @@ #include "src/runtime/runtime-utils.h" #include "src/arguments.h" +#include "src/counters.h" +#include "src/objects-inl.h" namespace v8 { namespace internal { +RUNTIME_FUNCTION(Runtime_DynamicImportCall) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + // TODO(gsathya): Implement ImportCall. + return isolate->heap()->undefined_value(); +} + RUNTIME_FUNCTION(Runtime_GetModuleNamespace) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc index 710f7b0bd2..dd24728457 100644 --- a/deps/v8/src/runtime/runtime-object.cc +++ b/deps/v8/src/runtime/runtime-object.cc @@ -56,6 +56,14 @@ static MaybeHandle<Object> KeyedGetObjectProperty(Isolate* isolate, DisallowHeapAllocation no_allocation; Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj); Handle<Name> key = Handle<Name>::cast(key_obj); + // Get to a ThinString's referenced internalized string, but don't + // otherwise force internalization. We assume that internalization + // (which is a dictionary lookup with a non-internalized key) is + // about as expensive as doing the property dictionary lookup with + // the non-internalized key directly. + if (key->IsThinString()) { + key = handle(Handle<ThinString>::cast(key)->actual(), isolate); + } if (receiver->IsJSGlobalObject()) { // Attempt dictionary lookup. GlobalDictionary* dictionary = receiver->global_dictionary(); @@ -578,6 +586,7 @@ RUNTIME_FUNCTION(Runtime_TryMigrateInstance) { CONVERT_ARG_HANDLE_CHECKED(Object, object, 0); if (!object->IsJSObject()) return Smi::kZero; Handle<JSObject> js_object = Handle<JSObject>::cast(object); + // It could have been a DCHECK but we call this function directly from tests. if (!js_object->map()->is_deprecated()) return Smi::kZero; // This call must not cause lazy deopts, because it's called from deferred // code where we can't handle lazy deopts for lack of a suitable bailout @@ -746,7 +755,7 @@ RUNTIME_FUNCTION(Runtime_DefineGetterPropertyUnchecked) { RUNTIME_FUNCTION(Runtime_CopyDataProperties) { HandleScope scope(isolate); - DCHECK(args.length() == 2); + DCHECK_EQ(2, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0); CONVERT_ARG_HANDLE_CHECKED(Object, source, 1); @@ -755,12 +764,46 @@ RUNTIME_FUNCTION(Runtime_CopyDataProperties) { return isolate->heap()->undefined_value(); } - MAYBE_RETURN( - JSReceiver::SetOrCopyDataProperties(isolate, target, source, false), - isolate->heap()->exception()); + MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source, + nullptr, false), + isolate->heap()->exception()); return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_CopyDataPropertiesWithExcludedProperties) { + HandleScope scope(isolate); + DCHECK_LE(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(Object, source, 0); + + // 2. If source is undefined or null, let keys be an empty List. + if (source->IsUndefined(isolate) || source->IsNull(isolate)) { + return isolate->heap()->undefined_value(); + } + + ScopedVector<Handle<Object>> excluded_properties(args.length() - 1); + for (int i = 1; i < args.length(); i++) { + Handle<Object> property = args.at(i); + uint32_t property_num; + // We convert string to number if possible, in cases of computed + // properties resolving to numbers, which would've been strings + // instead because of our call to %ToName() in the desugaring for + // computed properties. + if (property->IsString() && + String::cast(*property)->AsArrayIndex(&property_num)) { + property = isolate->factory()->NewNumberFromUint(property_num); + } + + excluded_properties[i - 1] = property; + } + + Handle<JSObject> target = + isolate->factory()->NewJSObject(isolate->object_function()); + MAYBE_RETURN(JSReceiver::SetOrCopyDataProperties(isolate, target, source, + &excluded_properties, false), + isolate->heap()->exception()); + return *target; +} + RUNTIME_FUNCTION(Runtime_DefineSetterPropertyUnchecked) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); diff --git a/deps/v8/src/runtime/runtime-promise.cc b/deps/v8/src/runtime/runtime-promise.cc index ec340e5b0a..7f8419940a 100644 --- a/deps/v8/src/runtime/runtime-promise.cc +++ b/deps/v8/src/runtime/runtime-promise.cc @@ -3,8 +3,11 @@ // found in the LICENSE file. #include "src/runtime/runtime-utils.h" +#include "src/arguments.h" +#include "src/counters.h" #include "src/debug/debug.h" #include "src/elements.h" +#include "src/objects-inl.h" namespace v8 { namespace internal { @@ -44,7 +47,7 @@ RUNTIME_FUNCTION(Runtime_PromiseRejectEventFromStack) { rejected_promise = isolate->GetPromiseOnStackOnThrow(); isolate->debug()->OnAsyncTaskEvent( debug::kDebugEnqueuePromiseReject, - isolate->debug()->NextAsyncTaskId(promise)); + isolate->debug()->NextAsyncTaskId(promise), 0); } PromiseRejectEvent(isolate, promise, rejected_promise, value, true); return isolate->heap()->undefined_value(); @@ -71,83 +74,11 @@ RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) { return isolate->heap()->undefined_value(); } -namespace { - -// In an async function, reuse the existing stack related to the outer -// Promise. Otherwise, e.g. in a direct call to then, save a new stack. -// Promises with multiple reactions with one or more of them being async -// functions will not get a good stack trace, as async functions require -// different stacks from direct Promise use, but we save and restore a -// stack once for all reactions. -// -// If this isn't a case of async function, we return false, otherwise -// we set the correct id and return true. -// -// TODO(littledan): Improve this case. -bool GetDebugIdForAsyncFunction(Isolate* isolate, - Handle<PromiseReactionJobInfo> info, - int* debug_id) { - // deferred_promise can be Undefined, FixedArray or userland promise object. - if (!info->deferred_promise()->IsJSPromise()) { - return false; - } - - Handle<JSPromise> deferred_promise(JSPromise::cast(info->deferred_promise()), - isolate); - Handle<Symbol> handled_by_symbol = - isolate->factory()->promise_handled_by_symbol(); - Handle<Object> handled_by_promise = - JSObject::GetDataProperty(deferred_promise, handled_by_symbol); - - if (!handled_by_promise->IsJSPromise()) { - return false; - } - - Handle<JSPromise> handled_by_promise_js = - Handle<JSPromise>::cast(handled_by_promise); - Handle<Symbol> async_stack_id_symbol = - isolate->factory()->promise_async_stack_id_symbol(); - Handle<Object> id = - JSObject::GetDataProperty(handled_by_promise_js, async_stack_id_symbol); - - // id can be Undefined or Smi. - if (!id->IsSmi()) { - return false; - } - - *debug_id = Handle<Smi>::cast(id)->value(); - return true; -} - -void SetDebugInfo(Isolate* isolate, Handle<JSPromise> promise, - Handle<PromiseReactionJobInfo> info, int status) { - int id = kDebugPromiseNoID; - if (!GetDebugIdForAsyncFunction(isolate, info, &id)) { - id = isolate->debug()->NextAsyncTaskId(promise); - DCHECK(status != v8::Promise::kPending); - } - info->set_debug_id(id); -} - -void EnqueuePromiseReactionJob(Isolate* isolate, Handle<JSPromise> promise, - Handle<PromiseReactionJobInfo> info, - int status) { - if (isolate->debug()->is_active()) { - SetDebugInfo(isolate, promise, info, status); - } - - isolate->EnqueueMicrotask(info); -} - -} // namespace - RUNTIME_FUNCTION(Runtime_EnqueuePromiseReactionJob) { HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); - CONVERT_ARG_HANDLE_CHECKED(PromiseReactionJobInfo, info, 1); - CONVERT_SMI_ARG_CHECKED(status, 2); - EnqueuePromiseReactionJob(isolate, promise, info, status); + DCHECK_EQ(1, args.length()); + CONVERT_ARG_HANDLE_CHECKED(PromiseReactionJobInfo, info, 0); + isolate->EnqueueMicrotask(info); return isolate->heap()->undefined_value(); } @@ -198,15 +129,6 @@ RUNTIME_FUNCTION(Runtime_PromiseMarkAsHandled) { return isolate->heap()->undefined_value(); } -RUNTIME_FUNCTION(Runtime_PromiseMarkHandledHint) { - SealHandleScope shs(isolate); - DCHECK_EQ(1, args.length()); - CONVERT_ARG_CHECKED(JSPromise, promise, 0); - - promise->set_handled_hint(true); - return isolate->heap()->undefined_value(); -} - RUNTIME_FUNCTION(Runtime_PromiseHookInit) { HandleScope scope(isolate); DCHECK_EQ(2, args.length()); @@ -228,18 +150,24 @@ RUNTIME_FUNCTION(Runtime_PromiseHookResolve) { RUNTIME_FUNCTION(Runtime_PromiseHookBefore) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); - isolate->RunPromiseHook(PromiseHookType::kBefore, promise, - isolate->factory()->undefined_value()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); + if (promise->IsJSPromise()) { + isolate->RunPromiseHook(PromiseHookType::kBefore, + Handle<JSPromise>::cast(promise), + isolate->factory()->undefined_value()); + } return isolate->heap()->undefined_value(); } RUNTIME_FUNCTION(Runtime_PromiseHookAfter) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); - CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0); - isolate->RunPromiseHook(PromiseHookType::kAfter, promise, - isolate->factory()->undefined_value()); + CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0); + if (promise->IsJSPromise()) { + isolate->RunPromiseHook(PromiseHookType::kAfter, + Handle<JSPromise>::cast(promise), + isolate->factory()->undefined_value()); + } return isolate->heap()->undefined_value(); } diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc index 9a489ecff8..aec9556510 100644 --- a/deps/v8/src/runtime/runtime-regexp.cc +++ b/deps/v8/src/runtime/runtime-regexp.cc @@ -431,6 +431,9 @@ MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString( } else { result_len = static_cast<int>(result_len_64); } + if (result_len == 0) { + return isolate->heap()->empty_string(); + } int subject_pos = 0; int result_pos = 0; @@ -1081,15 +1084,32 @@ MUST_USE_RESULT MaybeHandle<String> StringReplaceNonGlobalRegExpWithFunction( Factory* factory = isolate->factory(); Handle<RegExpMatchInfo> last_match_info = isolate->regexp_last_match_info(); - // TODO(jgruber): This is a pattern we could refactor. + const int flags = regexp->GetFlags(); + + DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, regexp)); + DCHECK_EQ(flags & JSRegExp::kGlobal, 0); + + // TODO(jgruber): This should be an easy port to CSA with massive payback. + + const bool sticky = (flags & JSRegExp::kSticky) != 0; + uint32_t last_index = 0; + if (sticky) { + Handle<Object> last_index_obj(regexp->LastIndex(), isolate); + ASSIGN_RETURN_ON_EXCEPTION(isolate, last_index_obj, + Object::ToLength(isolate, last_index_obj), + String); + last_index = PositiveNumberToUint32(*last_index_obj); + + if (static_cast<int>(last_index) > subject->length()) last_index = 0; + } + Handle<Object> match_indices_obj; ASSIGN_RETURN_ON_EXCEPTION( isolate, match_indices_obj, - RegExpImpl::Exec(regexp, subject, 0, last_match_info), String); + RegExpImpl::Exec(regexp, subject, last_index, last_match_info), String); if (match_indices_obj->IsNull(isolate)) { - RETURN_ON_EXCEPTION(isolate, RegExpUtils::SetLastIndex(isolate, regexp, 0), - String); + if (sticky) regexp->SetLastIndex(0); return subject; } @@ -1099,6 +1119,8 @@ MUST_USE_RESULT MaybeHandle<String> StringReplaceNonGlobalRegExpWithFunction( const int index = match_indices->Capture(0); const int end_of_match = match_indices->Capture(1); + if (sticky) regexp->SetLastIndex(end_of_match); + IncrementalStringBuilder builder(isolate); builder.AppendString(factory->NewSubString(subject, 0, index)); @@ -1150,10 +1172,9 @@ MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate, Handle<Object> replace_obj) { Factory* factory = isolate->factory(); - // TODO(jgruber): We need the even stricter guarantee of an unmodified - // JSRegExp map here for access to GetFlags to be legal. const int flags = regexp->GetFlags(); const bool global = (flags & JSRegExp::kGlobal) != 0; + const bool sticky = (flags & JSRegExp::kSticky) != 0; // Functional fast-paths are dispatched directly by replace builtin. DCHECK(!replace_obj->IsCallable()); @@ -1168,14 +1189,24 @@ MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate, if (!global) { // Non-global regexp search, string replace. + uint32_t last_index = 0; + if (sticky) { + Handle<Object> last_index_obj(regexp->LastIndex(), isolate); + ASSIGN_RETURN_ON_EXCEPTION(isolate, last_index_obj, + Object::ToLength(isolate, last_index_obj), + String); + last_index = PositiveNumberToUint32(*last_index_obj); + + if (static_cast<int>(last_index) > string->length()) last_index = 0; + } + Handle<Object> match_indices_obj; ASSIGN_RETURN_ON_EXCEPTION( isolate, match_indices_obj, - RegExpImpl::Exec(regexp, string, 0, last_match_info), String); + RegExpImpl::Exec(regexp, string, last_index, last_match_info), String); if (match_indices_obj->IsNull(isolate)) { - RETURN_ON_EXCEPTION( - isolate, RegExpUtils::SetLastIndex(isolate, regexp, 0), String); + if (sticky) regexp->SetLastIndex(0); return string; } @@ -1184,6 +1215,8 @@ MUST_USE_RESULT MaybeHandle<String> RegExpReplace(Isolate* isolate, const int start_index = match_indices->Capture(0); const int end_index = match_indices->Capture(1); + if (sticky) regexp->SetLastIndex(end_index); + IncrementalStringBuilder builder(isolate); builder.AppendString(factory->NewSubString(string, 0, start_index)); @@ -1265,6 +1298,8 @@ RUNTIME_FUNCTION(Runtime_StringReplaceNonGlobalRegExpWithFunction) { CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1); CONVERT_ARG_HANDLE_CHECKED(JSObject, replace, 2); + DCHECK(RegExpUtils::IsUnmodifiedRegExp(isolate, regexp)); + RETURN_RESULT_OR_FAILURE(isolate, StringReplaceNonGlobalRegExpWithFunction( isolate, subject, regexp, replace)); } diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc index de121ecfb5..76e7c2b186 100644 --- a/deps/v8/src/runtime/runtime-scopes.cc +++ b/deps/v8/src/runtime/runtime-scopes.cc @@ -46,7 +46,7 @@ Object* DeclareGlobal( Handle<Object> value, PropertyAttributes attr, bool is_var, bool is_function_declaration, RedeclarationType redeclaration_type, Handle<FeedbackVector> feedback_vector = Handle<FeedbackVector>(), - FeedbackVectorSlot slot = FeedbackVectorSlot::Invalid()) { + FeedbackSlot slot = FeedbackSlot::Invalid()) { Handle<ScriptContextTable> script_contexts( global->native_context()->script_context_table()); ScriptContextTable::LookupResult lookup; @@ -86,8 +86,7 @@ Object* DeclareGlobal( // Check whether we can reconfigure the existing property into a // function. - PropertyDetails old_details = it.property_details(); - if (old_details.IsReadOnly() || old_details.IsDontEnum() || + if (old_attributes & READ_ONLY || old_attributes & DONT_ENUM || (it.state() == LookupIterator::ACCESSOR)) { // ECMA-262 section 15.1.11 GlobalDeclarationInstantiation 5.d: // If hasRestrictedGlobal is true, throw a SyntaxError exception. @@ -116,7 +115,8 @@ Object* DeclareGlobal( RETURN_FAILURE_ON_EXCEPTION( isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); - if (!feedback_vector.is_null()) { + if (!feedback_vector.is_null() && + it.state() != LookupIterator::State::INTERCEPTOR) { DCHECK_EQ(*global, *it.GetHolder<Object>()); // Preinitialize the feedback slot if the global object does not have // named interceptor or the interceptor is not masking. @@ -137,10 +137,11 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, // Traverse the name/value pairs and set the properties. int length = declarations->length(); - FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 3, { + FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 4, { Handle<String> name(String::cast(declarations->get(i)), isolate); - FeedbackVectorSlot slot(Smi::cast(declarations->get(i + 1))->value()); - Handle<Object> initial_value(declarations->get(i + 2), isolate); + FeedbackSlot slot(Smi::cast(declarations->get(i + 1))->value()); + Handle<Object> possibly_literal_slot(declarations->get(i + 2), isolate); + Handle<Object> initial_value(declarations->get(i + 3), isolate); bool is_var = initial_value->IsUndefined(isolate); bool is_function = initial_value->IsSharedFunctionInfo(); @@ -148,12 +149,16 @@ Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> declarations, Handle<Object> value; if (is_function) { + DCHECK(possibly_literal_slot->IsSmi()); // Copy the function and update its context. Use it as value. Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>::cast(initial_value); + FeedbackSlot literals_slot(Smi::cast(*possibly_literal_slot)->value()); + Handle<Cell> literals(Cell::cast(feedback_vector->Get(literals_slot)), + isolate); Handle<JSFunction> function = - isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, - TENURED); + isolate->factory()->NewFunctionFromSharedFunctionInfo( + shared, context, literals, TENURED); value = function; } else { value = isolate->factory()->undefined_value(); @@ -584,12 +589,29 @@ RUNTIME_FUNCTION(Runtime_NewRestParameter) { RUNTIME_FUNCTION(Runtime_NewSloppyArguments) { HandleScope scope(isolate); - DCHECK_EQ(3, args.length()); + DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0); - Object** parameters = reinterpret_cast<Object**>(args[1]); - CONVERT_SMI_ARG_CHECKED(argument_count, 2); + StackFrameIterator iterator(isolate); + + // Stub/interpreter handler frame + iterator.Advance(); + DCHECK(iterator.frame()->type() == StackFrame::STUB); + + // Function frame + iterator.Advance(); + JavaScriptFrame* function_frame = JavaScriptFrame::cast(iterator.frame()); + DCHECK(function_frame->is_java_script()); + int argc = function_frame->GetArgumentsLength(); + Address fp = function_frame->fp(); + if (function_frame->has_adapted_arguments()) { + iterator.Advance(); + fp = iterator.frame()->fp(); + } + + Object** parameters = reinterpret_cast<Object**>( + fp + argc * kPointerSize + StandardFrameConstants::kCallerSPOffset); ParameterArguments argument_getter(parameters); - return *NewSloppyArguments(isolate, callee, argument_getter, argument_count); + return *NewSloppyArguments(isolate, callee, argument_getter, argc); } RUNTIME_FUNCTION(Runtime_NewArgumentsElements) { @@ -612,10 +634,14 @@ RUNTIME_FUNCTION(Runtime_NewClosure) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); + CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1); + CONVERT_SMI_ARG_CHECKED(index, 2); Handle<Context> context(isolate->context(), isolate); + FeedbackSlot slot = FeedbackVector::ToSlot(index); + Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate); Handle<JSFunction> function = - isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, - NOT_TENURED); + isolate->factory()->NewFunctionFromSharedFunctionInfo( + shared, context, vector_cell, NOT_TENURED); return *function; } @@ -624,12 +650,16 @@ RUNTIME_FUNCTION(Runtime_NewClosure_Tenured) { HandleScope scope(isolate); DCHECK_EQ(3, args.length()); CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); + CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1); + CONVERT_SMI_ARG_CHECKED(index, 2); Handle<Context> context(isolate->context(), isolate); + FeedbackSlot slot = FeedbackVector::ToSlot(index); + Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate); // The caller ensures that we pretenure closures that are assigned // directly to properties. Handle<JSFunction> function = - isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, - TENURED); + isolate->factory()->NewFunctionFromSharedFunctionInfo( + shared, context, vector_cell, TENURED); return *function; } diff --git a/deps/v8/src/runtime/runtime-simd.cc b/deps/v8/src/runtime/runtime-simd.cc deleted file mode 100644 index 067e9d680d..0000000000 --- a/deps/v8/src/runtime/runtime-simd.cc +++ /dev/null @@ -1,1016 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/runtime/runtime-utils.h" - -#include "src/arguments.h" -#include "src/base/macros.h" -#include "src/conversions.h" -#include "src/factory.h" -#include "src/objects-inl.h" - -// Implement Single Instruction Multiple Data (SIMD) operations as defined in -// the SIMD.js draft spec: -// http://littledan.github.io/simd.html - -namespace v8 { -namespace internal { - -namespace { - -// Functions to convert Numbers to SIMD component types. - -template <typename T, typename F> -static bool CanCast(F from) { - // A float can't represent 2^31 - 1 or 2^32 - 1 exactly, so promote the limits - // to double. Otherwise, the limit is truncated and numbers like 2^31 or 2^32 - // get through, causing any static_cast to be undefined. - from = trunc(from); - return from >= static_cast<double>(std::numeric_limits<T>::min()) && - from <= static_cast<double>(std::numeric_limits<T>::max()); -} - - -// Explicitly specialize for conversions to float, which always succeed. -template <> -bool CanCast<float>(int32_t from) { - return true; -} - - -template <> -bool CanCast<float>(uint32_t from) { - return true; -} - - -template <typename T> -static T ConvertNumber(double number); - - -template <> -float ConvertNumber<float>(double number) { - return DoubleToFloat32(number); -} - - -template <> -int32_t ConvertNumber<int32_t>(double number) { - return DoubleToInt32(number); -} - - -template <> -uint32_t ConvertNumber<uint32_t>(double number) { - return DoubleToUint32(number); -} - - -template <> -int16_t ConvertNumber<int16_t>(double number) { - return static_cast<int16_t>(DoubleToInt32(number)); -} - - -template <> -uint16_t ConvertNumber<uint16_t>(double number) { - return static_cast<uint16_t>(DoubleToUint32(number)); -} - - -template <> -int8_t ConvertNumber<int8_t>(double number) { - return static_cast<int8_t>(DoubleToInt32(number)); -} - - -template <> -uint8_t ConvertNumber<uint8_t>(double number) { - return static_cast<uint8_t>(DoubleToUint32(number)); -} - - -// TODO(bbudge): Make this consistent with SIMD instruction results. -inline float RecipApprox(float a) { return 1.0f / a; } - - -// TODO(bbudge): Make this consistent with SIMD instruction results. -inline float RecipSqrtApprox(float a) { return 1.0f / std::sqrt(a); } - - -// Saturating addition for int16_t and int8_t. -template <typename T> -inline T AddSaturate(T a, T b) { - const T max = std::numeric_limits<T>::max(); - const T min = std::numeric_limits<T>::min(); - int32_t result = a + b; - if (result > max) return max; - if (result < min) return min; - return result; -} - - -// Saturating subtraction for int16_t and int8_t. -template <typename T> -inline T SubSaturate(T a, T b) { - const T max = std::numeric_limits<T>::max(); - const T min = std::numeric_limits<T>::min(); - int32_t result = a - b; - if (result > max) return max; - if (result < min) return min; - return result; -} - - -inline float Min(float a, float b) { - if (a < b) return a; - if (a > b) return b; - if (a == b) return std::signbit(a) ? a : b; - return std::numeric_limits<float>::quiet_NaN(); -} - - -inline float Max(float a, float b) { - if (a > b) return a; - if (a < b) return b; - if (a == b) return std::signbit(b) ? a : b; - return std::numeric_limits<float>::quiet_NaN(); -} - - -inline float MinNumber(float a, float b) { - if (std::isnan(a)) return b; - if (std::isnan(b)) return a; - return Min(a, b); -} - - -inline float MaxNumber(float a, float b) { - if (std::isnan(a)) return b; - if (std::isnan(b)) return a; - return Max(a, b); -} - -} // namespace - -//------------------------------------------------------------------- - -// SIMD helper functions. - -RUNTIME_FUNCTION(Runtime_IsSimdValue) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - return isolate->heap()->ToBoolean(args[0]->IsSimd128Value()); -} - - -//------------------------------------------------------------------- - -// Utility macros. - -// TODO(gdeepti): Fix to use ToNumber conversion once polyfill is updated. -#define CONVERT_SIMD_LANE_ARG_CHECKED(name, index, lanes) \ - Handle<Object> name_object = args.at(index); \ - if (!name_object->IsNumber()) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewTypeError(MessageTemplate::kInvalidSimdIndex)); \ - } \ - double number = name_object->Number(); \ - if (number < 0 || number >= lanes || !IsInt32Double(number)) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewRangeError(MessageTemplate::kInvalidSimdIndex)); \ - } \ - uint32_t name = static_cast<uint32_t>(number); - -#define CONVERT_SIMD_ARG_HANDLE_THROW(Type, name, index) \ - Handle<Type> name; \ - if (args[index]->Is##Type()) { \ - name = args.at<Type>(index); \ - } else { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ - } - -#define SIMD_UNARY_OP(type, lane_type, lane_count, op, result) \ - static const int kLaneCount = lane_count; \ - DCHECK_EQ(1, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = op(a->get_lane(i)); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); - -#define SIMD_BINARY_OP(type, lane_type, lane_count, op, result) \ - static const int kLaneCount = lane_count; \ - DCHECK_EQ(2, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = op(a->get_lane(i), b->get_lane(i)); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); - -#define SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, op, result) \ - static const int kLaneCount = lane_count; \ - DCHECK_EQ(2, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ - bool lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = a->get_lane(i) op b->get_lane(i); \ - } \ - Handle<bool_type> result = isolate->factory()->New##bool_type(lanes); - -//------------------------------------------------------------------- - -// Common functions. - -#define GET_NUMERIC_ARG(lane_type, name, index) \ - Handle<Object> a; \ - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, a, \ - Object::ToNumber(args.at(index))); \ - name = ConvertNumber<lane_type>(a->Number()); - -#define GET_BOOLEAN_ARG(lane_type, name, index) \ - name = args[index]->BooleanValue(); - -#define SIMD_ALL_TYPES(FUNCTION) \ - FUNCTION(Float32x4, float, 4, NewNumber, GET_NUMERIC_ARG) \ - FUNCTION(Int32x4, int32_t, 4, NewNumber, GET_NUMERIC_ARG) \ - FUNCTION(Uint32x4, uint32_t, 4, NewNumber, GET_NUMERIC_ARG) \ - FUNCTION(Bool32x4, bool, 4, ToBoolean, GET_BOOLEAN_ARG) \ - FUNCTION(Int16x8, int16_t, 8, NewNumber, GET_NUMERIC_ARG) \ - FUNCTION(Uint16x8, uint16_t, 8, NewNumber, GET_NUMERIC_ARG) \ - FUNCTION(Bool16x8, bool, 8, ToBoolean, GET_BOOLEAN_ARG) \ - FUNCTION(Int8x16, int8_t, 16, NewNumber, GET_NUMERIC_ARG) \ - FUNCTION(Uint8x16, uint8_t, 16, NewNumber, GET_NUMERIC_ARG) \ - FUNCTION(Bool8x16, bool, 16, ToBoolean, GET_BOOLEAN_ARG) - -#define SIMD_CREATE_FUNCTION(type, lane_type, lane_count, extract, replace) \ - RUNTIME_FUNCTION(Runtime_Create##type) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK(args.length() == kLaneCount); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - replace(lane_type, lanes[i], i) \ - } \ - return *isolate->factory()->New##type(lanes); \ - } - -#define SIMD_EXTRACT_FUNCTION(type, lane_type, lane_count, extract, replace) \ - RUNTIME_FUNCTION(Runtime_##type##ExtractLane) { \ - HandleScope scope(isolate); \ - DCHECK_EQ(2, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, lane_count); \ - return *isolate->factory()->extract(a->get_lane(lane)); \ - } - -#define SIMD_REPLACE_FUNCTION(type, lane_type, lane_count, extract, replace) \ - RUNTIME_FUNCTION(Runtime_##type##ReplaceLane) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK_EQ(3, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, simd, 0); \ - CONVERT_SIMD_LANE_ARG_CHECKED(lane, 1, kLaneCount); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = simd->get_lane(i); \ - } \ - replace(lane_type, lanes[lane], 2); \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -#define SIMD_CHECK_FUNCTION(type, lane_type, lane_count, extract, replace) \ - RUNTIME_FUNCTION(Runtime_##type##Check) { \ - HandleScope scope(isolate); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - return *a; \ - } - -#define SIMD_SWIZZLE_FUNCTION(type, lane_type, lane_count, extract, replace) \ - RUNTIME_FUNCTION(Runtime_##type##Swizzle) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK(args.length() == 1 + kLaneCount); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - CONVERT_SIMD_LANE_ARG_CHECKED(index, i + 1, kLaneCount); \ - lanes[i] = a->get_lane(index); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -#define SIMD_SHUFFLE_FUNCTION(type, lane_type, lane_count, extract, replace) \ - RUNTIME_FUNCTION(Runtime_##type##Shuffle) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK(args.length() == 2 + kLaneCount); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 1); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - CONVERT_SIMD_LANE_ARG_CHECKED(index, i + 2, kLaneCount * 2); \ - lanes[i] = index < kLaneCount ? a->get_lane(index) \ - : b->get_lane(index - kLaneCount); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -SIMD_ALL_TYPES(SIMD_CREATE_FUNCTION) -SIMD_ALL_TYPES(SIMD_EXTRACT_FUNCTION) -SIMD_ALL_TYPES(SIMD_REPLACE_FUNCTION) -SIMD_ALL_TYPES(SIMD_CHECK_FUNCTION) -SIMD_ALL_TYPES(SIMD_SWIZZLE_FUNCTION) -SIMD_ALL_TYPES(SIMD_SHUFFLE_FUNCTION) - -//------------------------------------------------------------------- - -// Float-only functions. - -#define SIMD_ABS_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Abs) { \ - HandleScope scope(isolate); \ - SIMD_UNARY_OP(type, lane_type, lane_count, std::abs, result); \ - return *result; \ - } - -#define SIMD_SQRT_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Sqrt) { \ - HandleScope scope(isolate); \ - SIMD_UNARY_OP(type, lane_type, lane_count, std::sqrt, result); \ - return *result; \ - } - -#define SIMD_RECIP_APPROX_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##RecipApprox) { \ - HandleScope scope(isolate); \ - SIMD_UNARY_OP(type, lane_type, lane_count, RecipApprox, result); \ - return *result; \ - } - -#define SIMD_RECIP_SQRT_APPROX_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##RecipSqrtApprox) { \ - HandleScope scope(isolate); \ - SIMD_UNARY_OP(type, lane_type, lane_count, RecipSqrtApprox, result); \ - return *result; \ - } - -#define BINARY_DIV(a, b) (a) / (b) -#define SIMD_DIV_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Div) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_DIV, result); \ - return *result; \ - } - -#define SIMD_MINNUM_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##MinNum) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, MinNumber, result); \ - return *result; \ - } - -#define SIMD_MAXNUM_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##MaxNum) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, MaxNumber, result); \ - return *result; \ - } - -SIMD_ABS_FUNCTION(Float32x4, float, 4) -SIMD_SQRT_FUNCTION(Float32x4, float, 4) -SIMD_RECIP_APPROX_FUNCTION(Float32x4, float, 4) -SIMD_RECIP_SQRT_APPROX_FUNCTION(Float32x4, float, 4) -SIMD_DIV_FUNCTION(Float32x4, float, 4) -SIMD_MINNUM_FUNCTION(Float32x4, float, 4) -SIMD_MAXNUM_FUNCTION(Float32x4, float, 4) - -//------------------------------------------------------------------- - -// Int-only functions. - -#define SIMD_INT_TYPES(FUNCTION) \ - FUNCTION(Int32x4, int32_t, 32, 4) \ - FUNCTION(Int16x8, int16_t, 16, 8) \ - FUNCTION(Int8x16, int8_t, 8, 16) - -#define SIMD_UINT_TYPES(FUNCTION) \ - FUNCTION(Uint32x4, uint32_t, 32, 4) \ - FUNCTION(Uint16x8, uint16_t, 16, 8) \ - FUNCTION(Uint8x16, uint8_t, 8, 16) - -#define CONVERT_SHIFT_ARG_CHECKED(name, index) \ - Handle<Object> name_object = args.at(index); \ - if (!name_object->IsNumber()) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewTypeError(MessageTemplate::kInvalidSimdOperation)); \ - } \ - int32_t signed_shift = 0; \ - args[index]->ToInt32(&signed_shift); \ - uint32_t name = bit_cast<uint32_t>(signed_shift); - -#define SIMD_LSL_FUNCTION(type, lane_type, lane_bits, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##ShiftLeftByScalar) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK_EQ(2, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ - lane_type lanes[kLaneCount] = {0}; \ - shift &= lane_bits - 1; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = a->get_lane(i) << shift; \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -#define SIMD_LSR_FUNCTION(type, lane_type, lane_bits, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK_EQ(2, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ - lane_type lanes[kLaneCount] = {0}; \ - shift &= lane_bits - 1; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = static_cast<lane_type>(bit_cast<lane_type>(a->get_lane(i)) >> \ - shift); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -#define SIMD_ASR_FUNCTION(type, lane_type, lane_bits, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##ShiftRightByScalar) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK_EQ(2, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - CONVERT_SHIFT_ARG_CHECKED(shift, 1); \ - shift &= lane_bits - 1; \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - int64_t shifted = static_cast<int64_t>(a->get_lane(i)) >> shift; \ - lanes[i] = static_cast<lane_type>(shifted); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -SIMD_INT_TYPES(SIMD_LSL_FUNCTION) -SIMD_UINT_TYPES(SIMD_LSL_FUNCTION) -SIMD_INT_TYPES(SIMD_ASR_FUNCTION) -SIMD_UINT_TYPES(SIMD_LSR_FUNCTION) - -//------------------------------------------------------------------- - -// Bool-only functions. - -#define SIMD_BOOL_TYPES(FUNCTION) \ - FUNCTION(Bool32x4, 4) \ - FUNCTION(Bool16x8, 8) \ - FUNCTION(Bool8x16, 16) - -#define SIMD_ANY_FUNCTION(type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##AnyTrue) { \ - HandleScope scope(isolate); \ - DCHECK_EQ(1, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - bool result = false; \ - for (int i = 0; i < lane_count; i++) { \ - if (a->get_lane(i)) { \ - result = true; \ - break; \ - } \ - } \ - return isolate->heap()->ToBoolean(result); \ - } - -#define SIMD_ALL_FUNCTION(type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##AllTrue) { \ - HandleScope scope(isolate); \ - DCHECK_EQ(1, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 0); \ - bool result = true; \ - for (int i = 0; i < lane_count; i++) { \ - if (!a->get_lane(i)) { \ - result = false; \ - break; \ - } \ - } \ - return isolate->heap()->ToBoolean(result); \ - } - -SIMD_BOOL_TYPES(SIMD_ANY_FUNCTION) -SIMD_BOOL_TYPES(SIMD_ALL_FUNCTION) - -//------------------------------------------------------------------- - -// Small Int-only functions. - -#define SIMD_SMALL_INT_TYPES(FUNCTION) \ - FUNCTION(Int16x8, int16_t, 8) \ - FUNCTION(Uint16x8, uint16_t, 8) \ - FUNCTION(Int8x16, int8_t, 16) \ - FUNCTION(Uint8x16, uint8_t, 16) - -#define SIMD_ADD_SATURATE_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##AddSaturate) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, AddSaturate, result); \ - return *result; \ - } - -#define BINARY_SUB(a, b) (a) - (b) -#define SIMD_SUB_SATURATE_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##SubSaturate) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, SubSaturate, result); \ - return *result; \ - } - -SIMD_SMALL_INT_TYPES(SIMD_ADD_SATURATE_FUNCTION) -SIMD_SMALL_INT_TYPES(SIMD_SUB_SATURATE_FUNCTION) - -//------------------------------------------------------------------- - -// Numeric functions. - -#define SIMD_NUMERIC_TYPES(FUNCTION) \ - FUNCTION(Float32x4, float, 4) \ - FUNCTION(Int32x4, int32_t, 4) \ - FUNCTION(Uint32x4, uint32_t, 4) \ - FUNCTION(Int16x8, int16_t, 8) \ - FUNCTION(Uint16x8, uint16_t, 8) \ - FUNCTION(Int8x16, int8_t, 16) \ - FUNCTION(Uint8x16, uint8_t, 16) - -#define BINARY_ADD(a, b) (a) + (b) -#define SIMD_ADD_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Add) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_ADD, result); \ - return *result; \ - } - -#define BINARY_SUB(a, b) (a) - (b) -#define SIMD_SUB_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Sub) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_SUB, result); \ - return *result; \ - } - -#define BINARY_MUL(a, b) (a) * (b) -#define SIMD_MUL_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Mul) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_MUL, result); \ - return *result; \ - } - -#define SIMD_MIN_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Min) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, Min, result); \ - return *result; \ - } - -#define SIMD_MAX_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Max) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, Max, result); \ - return *result; \ - } - -SIMD_NUMERIC_TYPES(SIMD_ADD_FUNCTION) -SIMD_NUMERIC_TYPES(SIMD_SUB_FUNCTION) -SIMD_NUMERIC_TYPES(SIMD_MUL_FUNCTION) -SIMD_NUMERIC_TYPES(SIMD_MIN_FUNCTION) -SIMD_NUMERIC_TYPES(SIMD_MAX_FUNCTION) - -//------------------------------------------------------------------- - -// Relational functions. - -#define SIMD_RELATIONAL_TYPES(FUNCTION) \ - FUNCTION(Float32x4, Bool32x4, 4) \ - FUNCTION(Int32x4, Bool32x4, 4) \ - FUNCTION(Uint32x4, Bool32x4, 4) \ - FUNCTION(Int16x8, Bool16x8, 8) \ - FUNCTION(Uint16x8, Bool16x8, 8) \ - FUNCTION(Int8x16, Bool8x16, 16) \ - FUNCTION(Uint8x16, Bool8x16, 16) - -#define SIMD_EQUALITY_TYPES(FUNCTION) \ - SIMD_RELATIONAL_TYPES(FUNCTION) \ - FUNCTION(Bool32x4, Bool32x4, 4) \ - FUNCTION(Bool16x8, Bool16x8, 8) \ - FUNCTION(Bool8x16, Bool8x16, 16) - -#define SIMD_EQUAL_FUNCTION(type, bool_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Equal) { \ - HandleScope scope(isolate); \ - SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, ==, result); \ - return *result; \ - } - -#define SIMD_NOT_EQUAL_FUNCTION(type, bool_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##NotEqual) { \ - HandleScope scope(isolate); \ - SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, !=, result); \ - return *result; \ - } - -SIMD_EQUALITY_TYPES(SIMD_EQUAL_FUNCTION) -SIMD_EQUALITY_TYPES(SIMD_NOT_EQUAL_FUNCTION) - -#define SIMD_LESS_THAN_FUNCTION(type, bool_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##LessThan) { \ - HandleScope scope(isolate); \ - SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, <, result); \ - return *result; \ - } - -#define SIMD_LESS_THAN_OR_EQUAL_FUNCTION(type, bool_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##LessThanOrEqual) { \ - HandleScope scope(isolate); \ - SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, <=, result); \ - return *result; \ - } - -#define SIMD_GREATER_THAN_FUNCTION(type, bool_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##GreaterThan) { \ - HandleScope scope(isolate); \ - SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, >, result); \ - return *result; \ - } - -#define SIMD_GREATER_THAN_OR_EQUAL_FUNCTION(type, bool_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##GreaterThanOrEqual) { \ - HandleScope scope(isolate); \ - SIMD_RELATIONAL_OP(type, bool_type, lane_count, a, b, >=, result); \ - return *result; \ - } - -SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_FUNCTION) -SIMD_RELATIONAL_TYPES(SIMD_LESS_THAN_OR_EQUAL_FUNCTION) -SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_FUNCTION) -SIMD_RELATIONAL_TYPES(SIMD_GREATER_THAN_OR_EQUAL_FUNCTION) - -//------------------------------------------------------------------- - -// Logical functions. - -#define SIMD_LOGICAL_TYPES(FUNCTION) \ - FUNCTION(Int32x4, int32_t, 4, _INT) \ - FUNCTION(Uint32x4, uint32_t, 4, _INT) \ - FUNCTION(Int16x8, int16_t, 8, _INT) \ - FUNCTION(Uint16x8, uint16_t, 8, _INT) \ - FUNCTION(Int8x16, int8_t, 16, _INT) \ - FUNCTION(Uint8x16, uint8_t, 16, _INT) \ - FUNCTION(Bool32x4, bool, 4, _BOOL) \ - FUNCTION(Bool16x8, bool, 8, _BOOL) \ - FUNCTION(Bool8x16, bool, 16, _BOOL) - -#define BINARY_AND_INT(a, b) (a) & (b) -#define BINARY_AND_BOOL(a, b) (a) && (b) -#define SIMD_AND_FUNCTION(type, lane_type, lane_count, op) \ - RUNTIME_FUNCTION(Runtime_##type##And) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_AND##op, result); \ - return *result; \ - } - -#define BINARY_OR_INT(a, b) (a) | (b) -#define BINARY_OR_BOOL(a, b) (a) || (b) -#define SIMD_OR_FUNCTION(type, lane_type, lane_count, op) \ - RUNTIME_FUNCTION(Runtime_##type##Or) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_OR##op, result); \ - return *result; \ - } - -#define BINARY_XOR_INT(a, b) (a) ^ (b) -#define BINARY_XOR_BOOL(a, b) (a) != (b) -#define SIMD_XOR_FUNCTION(type, lane_type, lane_count, op) \ - RUNTIME_FUNCTION(Runtime_##type##Xor) { \ - HandleScope scope(isolate); \ - SIMD_BINARY_OP(type, lane_type, lane_count, BINARY_XOR##op, result); \ - return *result; \ - } - -#define UNARY_NOT_INT ~ -#define UNARY_NOT_BOOL ! -#define SIMD_NOT_FUNCTION(type, lane_type, lane_count, op) \ - RUNTIME_FUNCTION(Runtime_##type##Not) { \ - HandleScope scope(isolate); \ - SIMD_UNARY_OP(type, lane_type, lane_count, UNARY_NOT##op, result); \ - return *result; \ - } - -SIMD_LOGICAL_TYPES(SIMD_AND_FUNCTION) -SIMD_LOGICAL_TYPES(SIMD_OR_FUNCTION) -SIMD_LOGICAL_TYPES(SIMD_XOR_FUNCTION) -SIMD_LOGICAL_TYPES(SIMD_NOT_FUNCTION) - -//------------------------------------------------------------------- - -// Select functions. - -#define SIMD_SELECT_TYPES(FUNCTION) \ - FUNCTION(Float32x4, float, Bool32x4, 4) \ - FUNCTION(Int32x4, int32_t, Bool32x4, 4) \ - FUNCTION(Uint32x4, uint32_t, Bool32x4, 4) \ - FUNCTION(Int16x8, int16_t, Bool16x8, 8) \ - FUNCTION(Uint16x8, uint16_t, Bool16x8, 8) \ - FUNCTION(Int8x16, int8_t, Bool8x16, 16) \ - FUNCTION(Uint8x16, uint8_t, Bool8x16, 16) - -#define SIMD_SELECT_FUNCTION(type, lane_type, bool_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Select) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK_EQ(3, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(bool_type, mask, 0); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 1); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, b, 2); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = mask->get_lane(i) ? a->get_lane(i) : b->get_lane(i); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -SIMD_SELECT_TYPES(SIMD_SELECT_FUNCTION) - -//------------------------------------------------------------------- - -// Signed / unsigned functions. - -#define SIMD_SIGNED_TYPES(FUNCTION) \ - FUNCTION(Float32x4, float, 4) \ - FUNCTION(Int32x4, int32_t, 4) \ - FUNCTION(Int16x8, int16_t, 8) \ - FUNCTION(Int8x16, int8_t, 16) - -#define SIMD_NEG_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Neg) { \ - HandleScope scope(isolate); \ - SIMD_UNARY_OP(type, lane_type, lane_count, -, result); \ - return *result; \ - } - -SIMD_SIGNED_TYPES(SIMD_NEG_FUNCTION) - -//------------------------------------------------------------------- - -// Casting functions. - -#define SIMD_FROM_TYPES(FUNCTION) \ - FUNCTION(Float32x4, float, 4, Int32x4, int32_t) \ - FUNCTION(Float32x4, float, 4, Uint32x4, uint32_t) \ - FUNCTION(Int32x4, int32_t, 4, Float32x4, float) \ - FUNCTION(Int32x4, int32_t, 4, Uint32x4, uint32_t) \ - FUNCTION(Uint32x4, uint32_t, 4, Float32x4, float) \ - FUNCTION(Uint32x4, uint32_t, 4, Int32x4, int32_t) \ - FUNCTION(Int16x8, int16_t, 8, Uint16x8, uint16_t) \ - FUNCTION(Uint16x8, uint16_t, 8, Int16x8, int16_t) \ - FUNCTION(Int8x16, int8_t, 16, Uint8x16, uint8_t) \ - FUNCTION(Uint8x16, uint8_t, 16, Int8x16, int8_t) - -#define SIMD_FROM_FUNCTION(type, lane_type, lane_count, from_type, from_ctype) \ - RUNTIME_FUNCTION(Runtime_##type##From##from_type) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK_EQ(1, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - from_ctype a_value = a->get_lane(i); \ - if (a_value != a_value || !CanCast<lane_type>(a_value)) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewRangeError(MessageTemplate::kInvalidSimdLaneValue)); \ - } \ - lanes[i] = static_cast<lane_type>(a_value); \ - } \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -SIMD_FROM_TYPES(SIMD_FROM_FUNCTION) - -#define SIMD_FROM_BITS_TYPES(FUNCTION) \ - FUNCTION(Float32x4, float, 4, Int32x4) \ - FUNCTION(Float32x4, float, 4, Uint32x4) \ - FUNCTION(Float32x4, float, 4, Int16x8) \ - FUNCTION(Float32x4, float, 4, Uint16x8) \ - FUNCTION(Float32x4, float, 4, Int8x16) \ - FUNCTION(Float32x4, float, 4, Uint8x16) \ - FUNCTION(Int32x4, int32_t, 4, Float32x4) \ - FUNCTION(Int32x4, int32_t, 4, Uint32x4) \ - FUNCTION(Int32x4, int32_t, 4, Int16x8) \ - FUNCTION(Int32x4, int32_t, 4, Uint16x8) \ - FUNCTION(Int32x4, int32_t, 4, Int8x16) \ - FUNCTION(Int32x4, int32_t, 4, Uint8x16) \ - FUNCTION(Uint32x4, uint32_t, 4, Float32x4) \ - FUNCTION(Uint32x4, uint32_t, 4, Int32x4) \ - FUNCTION(Uint32x4, uint32_t, 4, Int16x8) \ - FUNCTION(Uint32x4, uint32_t, 4, Uint16x8) \ - FUNCTION(Uint32x4, uint32_t, 4, Int8x16) \ - FUNCTION(Uint32x4, uint32_t, 4, Uint8x16) \ - FUNCTION(Int16x8, int16_t, 8, Float32x4) \ - FUNCTION(Int16x8, int16_t, 8, Int32x4) \ - FUNCTION(Int16x8, int16_t, 8, Uint32x4) \ - FUNCTION(Int16x8, int16_t, 8, Uint16x8) \ - FUNCTION(Int16x8, int16_t, 8, Int8x16) \ - FUNCTION(Int16x8, int16_t, 8, Uint8x16) \ - FUNCTION(Uint16x8, uint16_t, 8, Float32x4) \ - FUNCTION(Uint16x8, uint16_t, 8, Int32x4) \ - FUNCTION(Uint16x8, uint16_t, 8, Uint32x4) \ - FUNCTION(Uint16x8, uint16_t, 8, Int16x8) \ - FUNCTION(Uint16x8, uint16_t, 8, Int8x16) \ - FUNCTION(Uint16x8, uint16_t, 8, Uint8x16) \ - FUNCTION(Int8x16, int8_t, 16, Float32x4) \ - FUNCTION(Int8x16, int8_t, 16, Int32x4) \ - FUNCTION(Int8x16, int8_t, 16, Uint32x4) \ - FUNCTION(Int8x16, int8_t, 16, Int16x8) \ - FUNCTION(Int8x16, int8_t, 16, Uint16x8) \ - FUNCTION(Int8x16, int8_t, 16, Uint8x16) \ - FUNCTION(Uint8x16, uint8_t, 16, Float32x4) \ - FUNCTION(Uint8x16, uint8_t, 16, Int32x4) \ - FUNCTION(Uint8x16, uint8_t, 16, Uint32x4) \ - FUNCTION(Uint8x16, uint8_t, 16, Int16x8) \ - FUNCTION(Uint8x16, uint8_t, 16, Uint16x8) \ - FUNCTION(Uint8x16, uint8_t, 16, Int8x16) - -#define SIMD_FROM_BITS_FUNCTION(type, lane_type, lane_count, from_type) \ - RUNTIME_FUNCTION(Runtime_##type##From##from_type##Bits) { \ - static const int kLaneCount = lane_count; \ - HandleScope scope(isolate); \ - DCHECK_EQ(1, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(from_type, a, 0); \ - lane_type lanes[kLaneCount]; \ - a->CopyBits(lanes); \ - Handle<type> result = isolate->factory()->New##type(lanes); \ - return *result; \ - } - -SIMD_FROM_BITS_TYPES(SIMD_FROM_BITS_FUNCTION) - - -//------------------------------------------------------------------- - -// Load and Store functions. - -#define SIMD_LOADN_STOREN_TYPES(FUNCTION) \ - FUNCTION(Float32x4, float, 4) \ - FUNCTION(Int32x4, int32_t, 4) \ - FUNCTION(Uint32x4, uint32_t, 4) - -#define SIMD_COERCE_INDEX(name, i) \ - Handle<Object> length_object, number_object; \ - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, length_object, \ - Object::ToLength(isolate, args.at(i))); \ - ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_object, \ - Object::ToNumber(args.at(i))); \ - if (number_object->Number() != length_object->Number()) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewTypeError(MessageTemplate::kInvalidSimdIndex)); \ - } \ - int32_t name = number_object->Number(); - -// Common Load and Store Functions - -#define SIMD_LOAD(type, lane_type, lane_count, count, result) \ - static const int kLaneCount = lane_count; \ - DCHECK_EQ(2, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ - SIMD_COERCE_INDEX(index, 1); \ - size_t bpe = tarray->element_size(); \ - uint32_t bytes = count * sizeof(lane_type); \ - size_t byte_length = NumberToSize(tarray->byte_length()); \ - if (index < 0 || index * bpe + bytes > byte_length) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewRangeError(MessageTemplate::kInvalidSimdIndex)); \ - } \ - size_t tarray_offset = NumberToSize(tarray->byte_offset()); \ - uint8_t* tarray_base = \ - static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ - tarray_offset; \ - lane_type lanes[kLaneCount] = {0}; \ - memcpy(lanes, tarray_base + index * bpe, bytes); \ - Handle<type> result = isolate->factory()->New##type(lanes); - -#define SIMD_STORE(type, lane_type, lane_count, count, a) \ - static const int kLaneCount = lane_count; \ - DCHECK_EQ(3, args.length()); \ - CONVERT_SIMD_ARG_HANDLE_THROW(JSTypedArray, tarray, 0); \ - CONVERT_SIMD_ARG_HANDLE_THROW(type, a, 2); \ - SIMD_COERCE_INDEX(index, 1); \ - size_t bpe = tarray->element_size(); \ - uint32_t bytes = count * sizeof(lane_type); \ - size_t byte_length = NumberToSize(tarray->byte_length()); \ - if (index < 0 || byte_length < index * bpe + bytes) { \ - THROW_NEW_ERROR_RETURN_FAILURE( \ - isolate, NewRangeError(MessageTemplate::kInvalidSimdIndex)); \ - } \ - size_t tarray_offset = NumberToSize(tarray->byte_offset()); \ - uint8_t* tarray_base = \ - static_cast<uint8_t*>(tarray->GetBuffer()->backing_store()) + \ - tarray_offset; \ - lane_type lanes[kLaneCount]; \ - for (int i = 0; i < kLaneCount; i++) { \ - lanes[i] = a->get_lane(i); \ - } \ - memcpy(tarray_base + index * bpe, lanes, bytes); - -#define SIMD_LOAD_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Load) { \ - HandleScope scope(isolate); \ - SIMD_LOAD(type, lane_type, lane_count, lane_count, result); \ - return *result; \ - } - - -#define SIMD_LOAD1_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Load1) { \ - HandleScope scope(isolate); \ - SIMD_LOAD(type, lane_type, lane_count, 1, result); \ - return *result; \ - } - - -#define SIMD_LOAD2_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Load2) { \ - HandleScope scope(isolate); \ - SIMD_LOAD(type, lane_type, lane_count, 2, result); \ - return *result; \ - } - - -#define SIMD_LOAD3_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Load3) { \ - HandleScope scope(isolate); \ - SIMD_LOAD(type, lane_type, lane_count, 3, result); \ - return *result; \ - } - - -#define SIMD_STORE_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Store) { \ - HandleScope scope(isolate); \ - SIMD_STORE(type, lane_type, lane_count, lane_count, a); \ - return *a; \ - } - - -#define SIMD_STORE1_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Store1) { \ - HandleScope scope(isolate); \ - SIMD_STORE(type, lane_type, lane_count, 1, a); \ - return *a; \ - } - - -#define SIMD_STORE2_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Store2) { \ - HandleScope scope(isolate); \ - SIMD_STORE(type, lane_type, lane_count, 2, a); \ - return *a; \ - } - - -#define SIMD_STORE3_FUNCTION(type, lane_type, lane_count) \ - RUNTIME_FUNCTION(Runtime_##type##Store3) { \ - HandleScope scope(isolate); \ - SIMD_STORE(type, lane_type, lane_count, 3, a); \ - return *a; \ - } - - -SIMD_NUMERIC_TYPES(SIMD_LOAD_FUNCTION) -SIMD_LOADN_STOREN_TYPES(SIMD_LOAD1_FUNCTION) -SIMD_LOADN_STOREN_TYPES(SIMD_LOAD2_FUNCTION) -SIMD_LOADN_STOREN_TYPES(SIMD_LOAD3_FUNCTION) -SIMD_NUMERIC_TYPES(SIMD_STORE_FUNCTION) -SIMD_LOADN_STOREN_TYPES(SIMD_STORE1_FUNCTION) -SIMD_LOADN_STOREN_TYPES(SIMD_STORE2_FUNCTION) -SIMD_LOADN_STOREN_TYPES(SIMD_STORE3_FUNCTION) - -//------------------------------------------------------------------- - -} // namespace internal -} // namespace v8 diff --git a/deps/v8/src/runtime/runtime-strings.cc b/deps/v8/src/runtime/runtime-strings.cc index 31d9f1fc6e..3a435913e3 100644 --- a/deps/v8/src/runtime/runtime-strings.cc +++ b/deps/v8/src/runtime/runtime-strings.cc @@ -5,14 +5,54 @@ #include "src/runtime/runtime-utils.h" #include "src/arguments.h" +#include "src/conversions.h" +#include "src/counters.h" +#include "src/objects-inl.h" #include "src/regexp/jsregexp-inl.h" #include "src/string-builder.h" -#include "src/string-case.h" #include "src/string-search.h" namespace v8 { namespace internal { +RUNTIME_FUNCTION(Runtime_GetSubstitution) { + HandleScope scope(isolate); + DCHECK_EQ(4, args.length()); + CONVERT_ARG_HANDLE_CHECKED(String, matched, 0); + CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); + CONVERT_SMI_ARG_CHECKED(position, 2); + CONVERT_ARG_HANDLE_CHECKED(String, replacement, 3); + + // A simple match without captures. + class SimpleMatch : public String::Match { + public: + SimpleMatch(Handle<String> match, Handle<String> prefix, + Handle<String> suffix) + : match_(match), prefix_(prefix), suffix_(suffix) {} + + Handle<String> GetMatch() override { return match_; } + MaybeHandle<String> GetCapture(int i, bool* capture_exists) override { + *capture_exists = false; + return match_; // Return arbitrary string handle. + } + Handle<String> GetPrefix() override { return prefix_; } + Handle<String> GetSuffix() override { return suffix_; } + int CaptureCount() override { return 0; } + + private: + Handle<String> match_, prefix_, suffix_; + }; + + Handle<String> prefix = + isolate->factory()->NewSubString(subject, 0, position); + Handle<String> suffix = isolate->factory()->NewSubString( + subject, position + matched->length(), subject->length()); + SimpleMatch match(matched, prefix, suffix); + + RETURN_RESULT_OR_FAILURE( + isolate, String::GetSubstitution(isolate, &match, replacement)); +} + // This may return an empty MaybeHandle if an exception is thrown or // we abort due to reaching the recursion limit. MaybeHandle<String> StringReplaceOneCharWithString( @@ -263,6 +303,9 @@ RUNTIME_FUNCTION(Runtime_StringBuilderConcat) { if (length == -1) { return isolate->Throw(isolate->heap()->illegal_argument_string()); } + if (length == 0) { + return isolate->heap()->empty_string(); + } if (one_byte) { Handle<SeqOneByteString> answer; @@ -589,182 +632,6 @@ RUNTIME_FUNCTION(Runtime_StringToArray) { } -static inline bool ToUpperOverflows(uc32 character) { - // y with umlauts and the micro sign are the only characters that stop - // fitting into one-byte when converting to uppercase. - static const uc32 yuml_code = 0xff; - static const uc32 micro_code = 0xb5; - return (character == yuml_code || character == micro_code); -} - - -template <class Converter> -MUST_USE_RESULT static Object* ConvertCaseHelper( - Isolate* isolate, String* string, SeqString* result, int result_length, - unibrow::Mapping<Converter, 128>* mapping) { - DisallowHeapAllocation no_gc; - // We try this twice, once with the assumption that the result is no longer - // than the input and, if that assumption breaks, again with the exact - // length. This may not be pretty, but it is nicer than what was here before - // and I hereby claim my vaffel-is. - // - // NOTE: This assumes that the upper/lower case of an ASCII - // character is also ASCII. This is currently the case, but it - // might break in the future if we implement more context and locale - // dependent upper/lower conversions. - bool has_changed_character = false; - - // Convert all characters to upper case, assuming that they will fit - // in the buffer - StringCharacterStream stream(string); - unibrow::uchar chars[Converter::kMaxWidth]; - // We can assume that the string is not empty - uc32 current = stream.GetNext(); - bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString(); - for (int i = 0; i < result_length;) { - bool has_next = stream.HasMore(); - uc32 next = has_next ? stream.GetNext() : 0; - int char_length = mapping->get(current, next, chars); - if (char_length == 0) { - // The case conversion of this character is the character itself. - result->Set(i, current); - i++; - } else if (char_length == 1 && - (ignore_overflow || !ToUpperOverflows(current))) { - // Common case: converting the letter resulted in one character. - DCHECK(static_cast<uc32>(chars[0]) != current); - result->Set(i, chars[0]); - has_changed_character = true; - i++; - } else if (result_length == string->length()) { - bool overflows = ToUpperOverflows(current); - // We've assumed that the result would be as long as the - // input but here is a character that converts to several - // characters. No matter, we calculate the exact length - // of the result and try the whole thing again. - // - // Note that this leaves room for optimization. We could just - // memcpy what we already have to the result string. Also, - // the result string is the last object allocated we could - // "realloc" it and probably, in the vast majority of cases, - // extend the existing string to be able to hold the full - // result. - int next_length = 0; - if (has_next) { - next_length = mapping->get(next, 0, chars); - if (next_length == 0) next_length = 1; - } - int current_length = i + char_length + next_length; - while (stream.HasMore()) { - current = stream.GetNext(); - overflows |= ToUpperOverflows(current); - // NOTE: we use 0 as the next character here because, while - // the next character may affect what a character converts to, - // it does not in any case affect the length of what it convert - // to. - int char_length = mapping->get(current, 0, chars); - if (char_length == 0) char_length = 1; - current_length += char_length; - if (current_length > String::kMaxLength) { - AllowHeapAllocation allocate_error_and_return; - THROW_NEW_ERROR_RETURN_FAILURE(isolate, - NewInvalidStringLengthError()); - } - } - // Try again with the real length. Return signed if we need - // to allocate a two-byte string for to uppercase. - return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length) - : Smi::FromInt(current_length); - } else { - for (int j = 0; j < char_length; j++) { - result->Set(i, chars[j]); - i++; - } - has_changed_character = true; - } - current = next; - } - if (has_changed_character) { - return result; - } else { - // If we didn't actually change anything in doing the conversion - // we simple return the result and let the converted string - // become garbage; there is no reason to keep two identical strings - // alive. - return string; - } -} - -template <class Converter> -MUST_USE_RESULT static Object* ConvertCase( - Handle<String> s, Isolate* isolate, - unibrow::Mapping<Converter, 128>* mapping) { - s = String::Flatten(s); - int length = s->length(); - // Assume that the string is not empty; we need this assumption later - if (length == 0) return *s; - - // Simpler handling of ASCII strings. - // - // NOTE: This assumes that the upper/lower case of an ASCII - // character is also ASCII. This is currently the case, but it - // might break in the future if we implement more context and locale - // dependent upper/lower conversions. - if (s->IsOneByteRepresentationUnderneath()) { - // Same length as input. - Handle<SeqOneByteString> result = - isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); - DisallowHeapAllocation no_gc; - String::FlatContent flat_content = s->GetFlatContent(); - DCHECK(flat_content.IsFlat()); - bool has_changed_character = false; - int index_to_first_unprocessed = FastAsciiConvert<Converter::kIsToLower>( - reinterpret_cast<char*>(result->GetChars()), - reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()), - length, &has_changed_character); - // If not ASCII, we discard the result and take the 2 byte path. - if (index_to_first_unprocessed == length) - return has_changed_character ? *result : *s; - } - - Handle<SeqString> result; // Same length as input. - if (s->IsOneByteRepresentation()) { - result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked(); - } else { - result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked(); - } - - Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping); - if (answer->IsException(isolate) || answer->IsString()) return answer; - - DCHECK(answer->IsSmi()); - length = Smi::cast(answer)->value(); - if (s->IsOneByteRepresentation() && length > 0) { - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, isolate->factory()->NewRawOneByteString(length)); - } else { - if (length < 0) length = -length; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, result, isolate->factory()->NewRawTwoByteString(length)); - } - return ConvertCaseHelper(isolate, *s, *result, length, mapping); -} - - -RUNTIME_FUNCTION(Runtime_StringToLowerCase) { - HandleScope scope(isolate); - DCHECK_EQ(args.length(), 1); - CONVERT_ARG_HANDLE_CHECKED(String, s, 0); - return ConvertCase(s, isolate, isolate->runtime_state()->to_lower_mapping()); -} - -RUNTIME_FUNCTION(Runtime_StringToUpperCase) { - HandleScope scope(isolate); - DCHECK_EQ(args.length(), 1); - CONVERT_ARG_HANDLE_CHECKED(String, s, 0); - return ConvertCase(s, isolate, isolate->runtime_state()->to_upper_mapping()); -} - RUNTIME_FUNCTION(Runtime_StringLessThan) { HandleScope handle_scope(isolate); DCHECK_EQ(2, args.length()); diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc index bea7245c35..c6234fcd85 100644 --- a/deps/v8/src/runtime/runtime-test.cc +++ b/deps/v8/src/runtime/runtime-test.cc @@ -7,6 +7,7 @@ #include <memory> #include "src/arguments.h" +#include "src/assembler-inl.h" #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h" #include "src/compiler.h" #include "src/deoptimizer.h" @@ -275,21 +276,28 @@ RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) { return isolate->heap()->undefined_value(); } - RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { HandleScope scope(isolate); DCHECK(args.length() == 1 || args.length() == 2); + int status = 0; if (!isolate->use_crankshaft()) { - return Smi::FromInt(4); // 4 == "never". + status |= static_cast<int>(OptimizationStatus::kNeverOptimize); + } + if (FLAG_always_opt || FLAG_prepare_always_opt) { + status |= static_cast<int>(OptimizationStatus::kAlwaysOptimize); + } + if (FLAG_deopt_every_n_times) { + status |= static_cast<int>(OptimizationStatus::kMaybeDeopted); } // This function is used by fuzzers to get coverage for optimizations // in compiler. Ignore calls on non-function objects to avoid runtime errors. CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0); if (!function_object->IsJSFunction()) { - return isolate->heap()->undefined_value(); + return Smi::FromInt(status); } Handle<JSFunction> function = Handle<JSFunction>::cast(function_object); + status |= static_cast<int>(OptimizationStatus::kIsFunction); bool sync_with_compiler_thread = true; if (args.length() == 2) { @@ -308,22 +316,16 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) { base::OS::Sleep(base::TimeDelta::FromMilliseconds(50)); } } - if (FLAG_always_opt || FLAG_prepare_always_opt) { - // With --always-opt, optimization status expectations might not - // match up, so just return a sentinel. - return Smi::FromInt(3); // 3 == "always". - } - if (FLAG_deopt_every_n_times) { - return Smi::FromInt(6); // 6 == "maybe deopted". - } - if (function->IsOptimized() && function->code()->is_turbofanned()) { - return Smi::FromInt(7); // 7 == "TurboFan compiler". + if (function->IsOptimized()) { + status |= static_cast<int>(OptimizationStatus::kOptimized); + if (function->code()->is_turbofanned()) { + status |= static_cast<int>(OptimizationStatus::kTurboFanned); + } } if (function->IsInterpreted()) { - return Smi::FromInt(8); // 8 == "Interpreted". + status |= static_cast<int>(OptimizationStatus::kInterpreted); } - return function->IsOptimized() ? Smi::FromInt(1) // 1 == "yes". - : Smi::FromInt(2); // 2 == "no". + return Smi::FromInt(status); } @@ -392,7 +394,7 @@ RUNTIME_FUNCTION(Runtime_GetCallable) { return *Utils::OpenHandle(*instance); } -RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) { +RUNTIME_FUNCTION(Runtime_ClearFunctionFeedback) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); diff --git a/deps/v8/src/runtime/runtime-typedarray.cc b/deps/v8/src/runtime/runtime-typedarray.cc index d5e394c345..4ca7bbb009 100644 --- a/deps/v8/src/runtime/runtime-typedarray.cc +++ b/deps/v8/src/runtime/runtime-typedarray.cc @@ -367,6 +367,67 @@ RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) { } } +namespace { + +template <typename T> +bool CompareNum(T x, T y) { + if (x < y) { + return true; + } else if (x > y) { + return false; + } else if (!std::is_integral<T>::value) { + double _x = x, _y = y; + if (x == 0 && x == y) { + /* -0.0 is less than +0.0 */ + return std::signbit(_x) && !std::signbit(_y); + } else if (!std::isnan(_x) && std::isnan(_y)) { + /* number is less than NaN */ + return true; + } + } + return false; +} + +} // namespace + +RUNTIME_FUNCTION(Runtime_TypedArraySortFast) { + HandleScope scope(isolate); + DCHECK_EQ(1, args.length()); + + CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); + + Handle<JSTypedArray> array; + const char* method = "%TypedArray%.prototype.sort"; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, array, JSTypedArray::Validate(isolate, target_obj, method)); + + // This line can be removed when JSTypedArray::Validate throws + // if array.[[ViewedArrayBuffer]] is neutered(v8:4648) + if (V8_UNLIKELY(array->WasNeutered())) return *array; + + size_t length = array->length_value(); + if (length <= 1) return *array; + + Handle<FixedTypedArrayBase> elements( + FixedTypedArrayBase::cast(array->elements())); + switch (array->type()) { +#define TYPED_ARRAY_SORT(Type, type, TYPE, ctype, size) \ + case kExternal##Type##Array: { \ + ctype* data = static_cast<ctype*>(elements->DataPtr()); \ + if (kExternal##Type##Array == kExternalFloat64Array || \ + kExternal##Type##Array == kExternalFloat32Array) \ + std::sort(data, data + length, CompareNum<ctype>); \ + else \ + std::sort(data, data + length); \ + break; \ + } + + TYPED_ARRAYS(TYPED_ARRAY_SORT) +#undef TYPED_ARRAY_SORT + } + + return *array; +} RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) { DCHECK_EQ(0, args.length()); diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc index 3ae5b92da1..9f125c1345 100644 --- a/deps/v8/src/runtime/runtime-wasm.cc +++ b/deps/v8/src/runtime/runtime-wasm.cc @@ -21,7 +21,7 @@ namespace v8 { namespace internal { namespace { -Handle<WasmInstanceObject> GetWasmInstanceOnStackTop(Isolate* isolate) { +WasmInstanceObject* GetWasmInstanceOnStackTop(Isolate* isolate) { DisallowHeapAllocation no_allocation; const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); Address pc = @@ -30,7 +30,12 @@ Handle<WasmInstanceObject> GetWasmInstanceOnStackTop(Isolate* isolate) { DCHECK_EQ(Code::WASM_FUNCTION, code->kind()); WasmInstanceObject* owning_instance = wasm::GetOwningWasmInstance(code); CHECK_NOT_NULL(owning_instance); - return handle(owning_instance, isolate); + return owning_instance; +} +Context* GetWasmContextOnStackTop(Isolate* isolate) { + return GetWasmInstanceOnStackTop(isolate) + ->compiled_module() + ->ptr_to_native_context(); } } // namespace @@ -38,7 +43,8 @@ RUNTIME_FUNCTION(Runtime_WasmMemorySize) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); - Handle<WasmInstanceObject> instance = GetWasmInstanceOnStackTop(isolate); + Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate), + isolate); return *isolate->factory()->NewNumberFromInt( wasm::GetInstanceMemorySize(isolate, instance)); } @@ -47,7 +53,13 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { HandleScope scope(isolate); DCHECK_EQ(1, args.length()); CONVERT_UINT32_ARG_CHECKED(delta_pages, 0); - Handle<WasmInstanceObject> instance = GetWasmInstanceOnStackTop(isolate); + Handle<WasmInstanceObject> instance(GetWasmInstanceOnStackTop(isolate), + isolate); + + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(instance->compiled_module()->ptr_to_native_context()); + return *isolate->factory()->NewNumberFromInt( wasm::GrowMemory(isolate, instance, delta_pages)); } @@ -55,6 +67,8 @@ RUNTIME_FUNCTION(Runtime_WasmGrowMemory) { Object* ThrowRuntimeError(Isolate* isolate, int message_id, int byte_offset, bool patch_source_position) { 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)); @@ -108,6 +122,12 @@ Object* ThrowRuntimeError(Isolate* isolate, int message_id, int byte_offset, 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); @@ -115,14 +135,6 @@ RUNTIME_FUNCTION(Runtime_ThrowWasmError) { return ThrowRuntimeError(isolate, message_id, byte_offset, true); } -#define DECLARE_ENUM(name) \ - RUNTIME_FUNCTION(Runtime_ThrowWasm##name) { \ - int message_id = wasm::WasmOpcodes::TrapReasonToMessageId(wasm::k##name); \ - return ThrowRuntimeError(isolate, message_id, 0, false); \ - } -FOREACH_WASM_TRAPREASON(DECLARE_ENUM) -#undef DECLARE_ENUM - RUNTIME_FUNCTION(Runtime_WasmThrowTypeError) { HandleScope scope(isolate); DCHECK_EQ(0, args.length()); @@ -138,6 +150,10 @@ RUNTIME_FUNCTION(Runtime_WasmThrow) { const int32_t thrown_value = (upper << 16) | lower; + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(GetWasmContextOnStackTop(isolate)); + return isolate->Throw(*isolate->factory()->NewNumberFromInt(thrown_value)); } @@ -153,12 +169,14 @@ RUNTIME_FUNCTION(Runtime_WasmGetCaughtExceptionValue) { } RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { - DCHECK(args.length() == 3); + DCHECK_EQ(3, args.length()); HandleScope scope(isolate); CONVERT_ARG_HANDLE_CHECKED(JSObject, instance_obj, 0); CONVERT_NUMBER_CHECKED(int32_t, func_index, Int32, args[1]); CONVERT_ARG_HANDLE_CHECKED(Object, arg_buffer_obj, 2); CHECK(WasmInstanceObject::IsWasmInstanceObject(*instance_obj)); + Handle<WasmInstanceObject> instance = + Handle<WasmInstanceObject>::cast(instance_obj); // The arg buffer is the raw pointer to the caller's stack. It looks like a // Smi (lowest bit not set, as checked by IsSmi), but is no valid Smi. We just @@ -167,13 +185,28 @@ RUNTIME_FUNCTION(Runtime_WasmRunInterpreter) { CHECK(arg_buffer_obj->IsSmi()); uint8_t* arg_buffer = reinterpret_cast<uint8_t*>(*arg_buffer_obj); - Handle<WasmInstanceObject> instance = - Handle<WasmInstanceObject>::cast(instance_obj); - Handle<WasmDebugInfo> debug_info = - WasmInstanceObject::GetOrCreateDebugInfo(instance); - WasmDebugInfo::RunInterpreter(debug_info, func_index, arg_buffer); + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(instance->compiled_module()->ptr_to_native_context()); + + instance->debug_info()->RunInterpreter(func_index, arg_buffer); return isolate->heap()->undefined_value(); } +RUNTIME_FUNCTION(Runtime_WasmStackGuard) { + SealHandleScope shs(isolate); + DCHECK_EQ(0, args.length()); + + // Set the current isolate's context. + DCHECK_NULL(isolate->context()); + isolate->set_context(GetWasmContextOnStackTop(isolate)); + + // Check if this is a real stack overflow. + StackLimitCheck check(isolate); + if (check.JsHasOverflowed()) return isolate->StackOverflow(); + + return isolate->stack_guard()->HandleInterrupts(); +} + } // namespace internal } // namespace v8 diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h index 7eadbe2c09..6c5a039d67 100644 --- a/deps/v8/src/runtime/runtime.h +++ b/deps/v8/src/runtime/runtime.h @@ -9,8 +9,8 @@ #include "src/allocation.h" #include "src/base/platform/time.h" +#include "src/elements-kind.h" #include "src/globals.h" -#include "src/objects.h" #include "src/unicode.h" #include "src/zone/zone.h" @@ -56,7 +56,8 @@ namespace internal { F(ArraySpeciesConstructor, 1, 1) \ F(ArrayIncludes_Slow, 3, 1) \ F(ArrayIndexOf, 3, 1) \ - F(SpreadIterablePrepare, 1, 1) + F(SpreadIterablePrepare, 1, 1) \ + F(SpreadIterableFixed, 1, 1) #define FOR_EACH_INTRINSIC_ATOMICS(F) \ F(ThrowNotIntegerSharedTypedArrayError, 1, 1) \ @@ -72,7 +73,8 @@ namespace internal { F(AtomicsIsLockFree, 1, 1) \ F(AtomicsWait, 4, 1) \ F(AtomicsWake, 3, 1) \ - F(AtomicsNumWaitersForTesting, 2, 1) + F(AtomicsNumWaitersForTesting, 2, 1) \ + F(SetAllowAtomicsWait, 1, 1) #define FOR_EACH_INTRINSIC_CLASSES(F) \ F(ThrowUnsupportedSuperError, 0, 1) \ @@ -90,8 +92,7 @@ namespace internal { F(StoreToSuper_Sloppy, 4, 1) \ F(StoreKeyedToSuper_Strict, 4, 1) \ F(StoreKeyedToSuper_Sloppy, 4, 1) \ - F(GetSuperConstructor, 1, 1) \ - F(NewWithSpread, -1, 1) + F(GetSuperConstructor, 1, 1) #define FOR_EACH_INTRINSIC_COLLECTIONS(F) \ F(StringGetRawHashField, 1, 1) \ @@ -170,9 +171,8 @@ namespace internal { F(ChangeBreakOnException, 2, 1) \ F(IsBreakOnException, 1, 1) \ F(PrepareStep, 2, 1) \ - F(PrepareStepFrame, 0, 1) \ F(ClearStepping, 0, 1) \ - F(DebugEvaluate, 4, 1) \ + F(DebugEvaluate, 5, 1) \ F(DebugEvaluateGlobal, 2, 1) \ F(DebugGetLoadedScripts, 0, 1) \ F(DebugReferencedBy, 3, 1) \ @@ -181,7 +181,6 @@ namespace internal { F(DebugSetScriptSource, 2, 1) \ F(FunctionGetInferredName, 1, 1) \ F(FunctionGetDebugName, 1, 1) \ - F(ExecuteInDebugContext, 1, 1) \ F(GetDebugContext, 0, 1) \ F(CollectGarbage, 1, 1) \ F(GetHeapUsage, 0, 1) \ @@ -200,19 +199,19 @@ namespace internal { F(DebugPushPromise, 1, 1) \ F(DebugPopPromise, 0, 1) \ F(DebugPromiseReject, 2, 1) \ - F(DebugNextAsyncTaskId, 1, 1) \ F(DebugAsyncEventEnqueueRecurring, 2, 1) \ F(DebugAsyncFunctionPromiseCreated, 1, 1) \ F(DebugIsActive, 0, 1) \ - F(DebugBreakInOptimizedCode, 0, 1) + F(DebugBreakInOptimizedCode, 0, 1) \ + F(DebugCollectCoverage, 0, 1) \ + F(DebugTogglePreciseCoverage, 1, 1) #define FOR_EACH_INTRINSIC_ERROR(F) F(ErrorToString, 1, 1) #define FOR_EACH_INTRINSIC_FORIN(F) \ F(ForInEnumerate, 1, 1) \ F(ForInFilter, 2, 1) \ - F(ForInHasProperty, 2, 1) \ - F(ForInNext, 4, 1) + F(ForInHasProperty, 2, 1) #define FOR_EACH_INTRINSIC_INTERPRETER(F) \ F(InterpreterNewClosure, 4, 1) \ @@ -290,12 +289,9 @@ namespace internal { F(AllocateSeqOneByteString, 1, 1) \ F(AllocateSeqTwoByteString, 1, 1) \ F(CheckIsBootstrapping, 0, 1) \ + F(CreateAsyncFromSyncIterator, 1, 1) \ F(CreateListFromArrayLike, 1, 1) \ - F(EnqueueMicrotask, 1, 1) \ - F(EnqueuePromiseReactionJob, 3, 1) \ - F(EnqueuePromiseResolveThenableJob, 1, 1) \ F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \ - F(ExportExperimentalFromRuntime, 1, 1) \ F(ExportFromRuntime, 1, 1) \ F(IncrementUseCounter, 1, 1) \ F(InstallToContext, 1, 1) \ @@ -305,17 +301,6 @@ namespace internal { F(NewSyntaxError, 2, 1) \ F(NewTypeError, 2, 1) \ F(OrdinaryHasInstance, 2, 1) \ - F(ReportPromiseReject, 2, 1) \ - F(PromiseHookInit, 2, 1) \ - F(PromiseHookResolve, 1, 1) \ - F(PromiseHookBefore, 1, 1) \ - F(PromiseHookAfter, 1, 1) \ - F(PromiseMarkAsHandled, 1, 1) \ - F(PromiseMarkHandledHint, 1, 1) \ - F(PromiseRejectEventFromStack, 2, 1) \ - F(PromiseRevokeReject, 1, 1) \ - F(PromiseResult, 1, 1) \ - F(PromiseStatus, 1, 1) \ F(PromoteScheduledException, 0, 1) \ F(ReThrow, 1, 1) \ F(RunMicrotasks, 0, 1) \ @@ -334,9 +319,13 @@ namespace internal { F(ThrowInvalidStringLength, 0, 1) \ F(ThrowIteratorResultNotAnObject, 1, 1) \ F(ThrowSymbolIteratorInvalid, 0, 1) \ + F(ThrowNonCallableInInstanceOfCheck, 0, 1) \ + F(ThrowNonObjectInInstanceOfCheck, 0, 1) \ + F(ThrowNotConstructor, 1, 1) \ F(ThrowNotGeneric, 1, 1) \ F(ThrowReferenceError, 1, 1) \ F(ThrowStackOverflow, 0, 1) \ + F(ThrowSymbolAsyncIteratorInvalid, 0, 1) \ F(ThrowTypeError, -1 /* >= 1 */, 1) \ F(ThrowUndefinedOrNullToObject, 1, 1) \ F(Typeof, 1, 1) \ @@ -366,6 +355,7 @@ namespace internal { #define FOR_EACH_INTRINSIC_MATHS(F) F(GenerateRandomNumbers, 0, 1) #define FOR_EACH_INTRINSIC_MODULE(F) \ + F(DynamicImportCall, 1, 1) \ F(GetModuleNamespace, 1, 1) \ F(LoadModuleVariable, 1, 1) \ F(StoreModuleVariable, 2, 1) @@ -385,56 +375,57 @@ namespace internal { F(GetHoleNaNUpper, 0, 1) \ F(GetHoleNaNLower, 0, 1) -#define FOR_EACH_INTRINSIC_OBJECT(F) \ - F(GetPrototype, 1, 1) \ - F(ObjectHasOwnProperty, 2, 1) \ - F(ObjectCreate, 2, 1) \ - F(InternalSetPrototype, 2, 1) \ - F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ - F(GetProperty, 2, 1) \ - F(KeyedGetProperty, 2, 1) \ - F(AddNamedProperty, 4, 1) \ - F(SetProperty, 4, 1) \ - F(AddElement, 3, 1) \ - F(AppendElement, 2, 1) \ - F(DeleteProperty_Sloppy, 2, 1) \ - F(DeleteProperty_Strict, 2, 1) \ - F(HasProperty, 2, 1) \ - F(GetOwnPropertyKeys, 2, 1) \ - F(GetInterceptorInfo, 1, 1) \ - F(ToFastProperties, 1, 1) \ - F(AllocateHeapNumber, 0, 1) \ - F(NewObject, 2, 1) \ - F(FinalizeInstanceSize, 1, 1) \ - F(LoadMutableDouble, 2, 1) \ - F(TryMigrateInstance, 1, 1) \ - F(IsJSGlobalProxy, 1, 1) \ - F(DefineAccessorPropertyUnchecked, 5, 1) \ - F(DefineDataPropertyInLiteral, 6, 1) \ - F(GetDataProperty, 2, 1) \ - F(GetConstructorName, 1, 1) \ - F(HasFastPackedElements, 1, 1) \ - F(ValueOf, 1, 1) \ - F(IsJSReceiver, 1, 1) \ - F(ClassOf, 1, 1) \ - F(CopyDataProperties, 2, 1) \ - F(DefineGetterPropertyUnchecked, 4, 1) \ - F(DefineSetterPropertyUnchecked, 4, 1) \ - F(ToObject, 1, 1) \ - F(ToPrimitive, 1, 1) \ - F(ToPrimitive_Number, 1, 1) \ - F(ToNumber, 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(CreateKeyValueArray, 2, 1) \ - F(IsAccessCheckNeeded, 1, 1) \ +#define FOR_EACH_INTRINSIC_OBJECT(F) \ + F(GetPrototype, 1, 1) \ + F(ObjectHasOwnProperty, 2, 1) \ + F(ObjectCreate, 2, 1) \ + F(InternalSetPrototype, 2, 1) \ + F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ + F(GetProperty, 2, 1) \ + F(KeyedGetProperty, 2, 1) \ + F(AddNamedProperty, 4, 1) \ + F(SetProperty, 4, 1) \ + F(AddElement, 3, 1) \ + F(AppendElement, 2, 1) \ + F(DeleteProperty_Sloppy, 2, 1) \ + F(DeleteProperty_Strict, 2, 1) \ + F(HasProperty, 2, 1) \ + F(GetOwnPropertyKeys, 2, 1) \ + F(GetInterceptorInfo, 1, 1) \ + F(ToFastProperties, 1, 1) \ + F(AllocateHeapNumber, 0, 1) \ + F(NewObject, 2, 1) \ + F(FinalizeInstanceSize, 1, 1) \ + F(LoadMutableDouble, 2, 1) \ + F(TryMigrateInstance, 1, 1) \ + F(IsJSGlobalProxy, 1, 1) \ + F(DefineAccessorPropertyUnchecked, 5, 1) \ + F(DefineDataPropertyInLiteral, 6, 1) \ + F(GetDataProperty, 2, 1) \ + F(GetConstructorName, 1, 1) \ + F(HasFastPackedElements, 1, 1) \ + F(ValueOf, 1, 1) \ + F(IsJSReceiver, 1, 1) \ + F(ClassOf, 1, 1) \ + F(CopyDataProperties, 2, 1) \ + F(CopyDataPropertiesWithExcludedProperties, -1 /* >= 1 */, 1) \ + F(DefineGetterPropertyUnchecked, 4, 1) \ + F(DefineSetterPropertyUnchecked, 4, 1) \ + F(ToObject, 1, 1) \ + F(ToPrimitive, 1, 1) \ + F(ToPrimitive_Number, 1, 1) \ + F(ToNumber, 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(CreateKeyValueArray, 2, 1) \ + F(IsAccessCheckNeeded, 1, 1) \ F(CreateDataProperty, 3, 1) #define FOR_EACH_INTRINSIC_OPERATORS(F) \ @@ -459,6 +450,21 @@ namespace internal { F(GreaterThanOrEqual, 2, 1) \ F(InstanceOf, 2, 1) +#define FOR_EACH_INTRINSIC_PROMISE(F) \ + F(EnqueueMicrotask, 1, 1) \ + F(EnqueuePromiseReactionJob, 1, 1) \ + F(EnqueuePromiseResolveThenableJob, 1, 1) \ + F(PromiseHookInit, 2, 1) \ + F(PromiseHookResolve, 1, 1) \ + F(PromiseHookBefore, 1, 1) \ + F(PromiseHookAfter, 1, 1) \ + F(PromiseMarkAsHandled, 1, 1) \ + F(PromiseRejectEventFromStack, 2, 1) \ + F(PromiseRevokeReject, 1, 1) \ + F(PromiseResult, 1, 1) \ + F(PromiseStatus, 1, 1) \ + F(ReportPromiseReject, 2, 1) + #define FOR_EACH_INTRINSIC_PROXY(F) \ F(IsJSProxy, 1, 1) \ F(JSProxyCall, -1 /* >= 2 */, 1) \ @@ -507,317 +513,8 @@ namespace internal { F(StoreLookupSlot_Sloppy, 2, 1) \ F(StoreLookupSlot_Strict, 2, 1) -#define FOR_EACH_INTRINSIC_SIMD(F) \ - F(IsSimdValue, 1, 1) \ - F(CreateFloat32x4, 4, 1) \ - F(CreateInt32x4, 4, 1) \ - F(CreateUint32x4, 4, 1) \ - F(CreateBool32x4, 4, 1) \ - F(CreateInt16x8, 8, 1) \ - F(CreateUint16x8, 8, 1) \ - F(CreateBool16x8, 8, 1) \ - F(CreateInt8x16, 16, 1) \ - F(CreateUint8x16, 16, 1) \ - F(CreateBool8x16, 16, 1) \ - F(Float32x4Check, 1, 1) \ - F(Float32x4ExtractLane, 2, 1) \ - F(Float32x4ReplaceLane, 3, 1) \ - F(Float32x4Abs, 1, 1) \ - F(Float32x4Neg, 1, 1) \ - F(Float32x4Sqrt, 1, 1) \ - F(Float32x4RecipApprox, 1, 1) \ - F(Float32x4RecipSqrtApprox, 1, 1) \ - F(Float32x4Add, 2, 1) \ - F(Float32x4Sub, 2, 1) \ - F(Float32x4Mul, 2, 1) \ - F(Float32x4Div, 2, 1) \ - F(Float32x4Min, 2, 1) \ - F(Float32x4Max, 2, 1) \ - F(Float32x4MinNum, 2, 1) \ - F(Float32x4MaxNum, 2, 1) \ - F(Float32x4Equal, 2, 1) \ - F(Float32x4NotEqual, 2, 1) \ - F(Float32x4LessThan, 2, 1) \ - F(Float32x4LessThanOrEqual, 2, 1) \ - F(Float32x4GreaterThan, 2, 1) \ - F(Float32x4GreaterThanOrEqual, 2, 1) \ - F(Float32x4Select, 3, 1) \ - F(Float32x4Swizzle, 5, 1) \ - F(Float32x4Shuffle, 6, 1) \ - F(Float32x4FromInt32x4, 1, 1) \ - F(Float32x4FromUint32x4, 1, 1) \ - F(Float32x4FromInt32x4Bits, 1, 1) \ - F(Float32x4FromUint32x4Bits, 1, 1) \ - F(Float32x4FromInt16x8Bits, 1, 1) \ - F(Float32x4FromUint16x8Bits, 1, 1) \ - F(Float32x4FromInt8x16Bits, 1, 1) \ - F(Float32x4FromUint8x16Bits, 1, 1) \ - F(Float32x4Load, 2, 1) \ - F(Float32x4Load1, 2, 1) \ - F(Float32x4Load2, 2, 1) \ - F(Float32x4Load3, 2, 1) \ - F(Float32x4Store, 3, 1) \ - F(Float32x4Store1, 3, 1) \ - F(Float32x4Store2, 3, 1) \ - F(Float32x4Store3, 3, 1) \ - F(Int32x4Check, 1, 1) \ - F(Int32x4ExtractLane, 2, 1) \ - F(Int32x4ReplaceLane, 3, 1) \ - F(Int32x4Neg, 1, 1) \ - F(Int32x4Add, 2, 1) \ - F(Int32x4Sub, 2, 1) \ - F(Int32x4Mul, 2, 1) \ - F(Int32x4Min, 2, 1) \ - F(Int32x4Max, 2, 1) \ - F(Int32x4And, 2, 1) \ - F(Int32x4Or, 2, 1) \ - F(Int32x4Xor, 2, 1) \ - F(Int32x4Not, 1, 1) \ - F(Int32x4ShiftLeftByScalar, 2, 1) \ - F(Int32x4ShiftRightByScalar, 2, 1) \ - F(Int32x4Equal, 2, 1) \ - F(Int32x4NotEqual, 2, 1) \ - F(Int32x4LessThan, 2, 1) \ - F(Int32x4LessThanOrEqual, 2, 1) \ - F(Int32x4GreaterThan, 2, 1) \ - F(Int32x4GreaterThanOrEqual, 2, 1) \ - F(Int32x4Select, 3, 1) \ - F(Int32x4Swizzle, 5, 1) \ - F(Int32x4Shuffle, 6, 1) \ - F(Int32x4FromFloat32x4, 1, 1) \ - F(Int32x4FromUint32x4, 1, 1) \ - F(Int32x4FromFloat32x4Bits, 1, 1) \ - F(Int32x4FromUint32x4Bits, 1, 1) \ - F(Int32x4FromInt16x8Bits, 1, 1) \ - F(Int32x4FromUint16x8Bits, 1, 1) \ - F(Int32x4FromInt8x16Bits, 1, 1) \ - F(Int32x4FromUint8x16Bits, 1, 1) \ - F(Int32x4Load, 2, 1) \ - F(Int32x4Load1, 2, 1) \ - F(Int32x4Load2, 2, 1) \ - F(Int32x4Load3, 2, 1) \ - F(Int32x4Store, 3, 1) \ - F(Int32x4Store1, 3, 1) \ - F(Int32x4Store2, 3, 1) \ - F(Int32x4Store3, 3, 1) \ - F(Uint32x4Check, 1, 1) \ - F(Uint32x4ExtractLane, 2, 1) \ - F(Uint32x4ReplaceLane, 3, 1) \ - F(Uint32x4Add, 2, 1) \ - F(Uint32x4Sub, 2, 1) \ - F(Uint32x4Mul, 2, 1) \ - F(Uint32x4Min, 2, 1) \ - F(Uint32x4Max, 2, 1) \ - F(Uint32x4And, 2, 1) \ - F(Uint32x4Or, 2, 1) \ - F(Uint32x4Xor, 2, 1) \ - F(Uint32x4Not, 1, 1) \ - F(Uint32x4ShiftLeftByScalar, 2, 1) \ - F(Uint32x4ShiftRightByScalar, 2, 1) \ - F(Uint32x4Equal, 2, 1) \ - F(Uint32x4NotEqual, 2, 1) \ - F(Uint32x4LessThan, 2, 1) \ - F(Uint32x4LessThanOrEqual, 2, 1) \ - F(Uint32x4GreaterThan, 2, 1) \ - F(Uint32x4GreaterThanOrEqual, 2, 1) \ - F(Uint32x4Select, 3, 1) \ - F(Uint32x4Swizzle, 5, 1) \ - F(Uint32x4Shuffle, 6, 1) \ - F(Uint32x4FromFloat32x4, 1, 1) \ - F(Uint32x4FromInt32x4, 1, 1) \ - F(Uint32x4FromFloat32x4Bits, 1, 1) \ - F(Uint32x4FromInt32x4Bits, 1, 1) \ - F(Uint32x4FromInt16x8Bits, 1, 1) \ - F(Uint32x4FromUint16x8Bits, 1, 1) \ - F(Uint32x4FromInt8x16Bits, 1, 1) \ - F(Uint32x4FromUint8x16Bits, 1, 1) \ - F(Uint32x4Load, 2, 1) \ - F(Uint32x4Load1, 2, 1) \ - F(Uint32x4Load2, 2, 1) \ - F(Uint32x4Load3, 2, 1) \ - F(Uint32x4Store, 3, 1) \ - F(Uint32x4Store1, 3, 1) \ - F(Uint32x4Store2, 3, 1) \ - F(Uint32x4Store3, 3, 1) \ - F(Bool32x4Check, 1, 1) \ - F(Bool32x4ExtractLane, 2, 1) \ - F(Bool32x4ReplaceLane, 3, 1) \ - F(Bool32x4And, 2, 1) \ - F(Bool32x4Or, 2, 1) \ - F(Bool32x4Xor, 2, 1) \ - F(Bool32x4Not, 1, 1) \ - F(Bool32x4AnyTrue, 1, 1) \ - F(Bool32x4AllTrue, 1, 1) \ - F(Bool32x4Swizzle, 5, 1) \ - F(Bool32x4Shuffle, 6, 1) \ - F(Bool32x4Equal, 2, 1) \ - F(Bool32x4NotEqual, 2, 1) \ - F(Int16x8Check, 1, 1) \ - F(Int16x8ExtractLane, 2, 1) \ - F(Int16x8ReplaceLane, 3, 1) \ - F(Int16x8Neg, 1, 1) \ - F(Int16x8Add, 2, 1) \ - F(Int16x8AddSaturate, 2, 1) \ - F(Int16x8Sub, 2, 1) \ - F(Int16x8SubSaturate, 2, 1) \ - F(Int16x8Mul, 2, 1) \ - F(Int16x8Min, 2, 1) \ - F(Int16x8Max, 2, 1) \ - F(Int16x8And, 2, 1) \ - F(Int16x8Or, 2, 1) \ - F(Int16x8Xor, 2, 1) \ - F(Int16x8Not, 1, 1) \ - F(Int16x8ShiftLeftByScalar, 2, 1) \ - F(Int16x8ShiftRightByScalar, 2, 1) \ - F(Int16x8Equal, 2, 1) \ - F(Int16x8NotEqual, 2, 1) \ - F(Int16x8LessThan, 2, 1) \ - F(Int16x8LessThanOrEqual, 2, 1) \ - F(Int16x8GreaterThan, 2, 1) \ - F(Int16x8GreaterThanOrEqual, 2, 1) \ - F(Int16x8Select, 3, 1) \ - F(Int16x8Swizzle, 9, 1) \ - F(Int16x8Shuffle, 10, 1) \ - F(Int16x8FromUint16x8, 1, 1) \ - F(Int16x8FromFloat32x4Bits, 1, 1) \ - F(Int16x8FromInt32x4Bits, 1, 1) \ - F(Int16x8FromUint32x4Bits, 1, 1) \ - F(Int16x8FromUint16x8Bits, 1, 1) \ - F(Int16x8FromInt8x16Bits, 1, 1) \ - F(Int16x8FromUint8x16Bits, 1, 1) \ - F(Int16x8Load, 2, 1) \ - F(Int16x8Store, 3, 1) \ - F(Uint16x8Check, 1, 1) \ - F(Uint16x8ExtractLane, 2, 1) \ - F(Uint16x8ReplaceLane, 3, 1) \ - F(Uint16x8Add, 2, 1) \ - F(Uint16x8AddSaturate, 2, 1) \ - F(Uint16x8Sub, 2, 1) \ - F(Uint16x8SubSaturate, 2, 1) \ - F(Uint16x8Mul, 2, 1) \ - F(Uint16x8Min, 2, 1) \ - F(Uint16x8Max, 2, 1) \ - F(Uint16x8And, 2, 1) \ - F(Uint16x8Or, 2, 1) \ - F(Uint16x8Xor, 2, 1) \ - F(Uint16x8Not, 1, 1) \ - F(Uint16x8ShiftLeftByScalar, 2, 1) \ - F(Uint16x8ShiftRightByScalar, 2, 1) \ - F(Uint16x8Equal, 2, 1) \ - F(Uint16x8NotEqual, 2, 1) \ - F(Uint16x8LessThan, 2, 1) \ - F(Uint16x8LessThanOrEqual, 2, 1) \ - F(Uint16x8GreaterThan, 2, 1) \ - F(Uint16x8GreaterThanOrEqual, 2, 1) \ - F(Uint16x8Select, 3, 1) \ - F(Uint16x8Swizzle, 9, 1) \ - F(Uint16x8Shuffle, 10, 1) \ - F(Uint16x8FromInt16x8, 1, 1) \ - F(Uint16x8FromFloat32x4Bits, 1, 1) \ - F(Uint16x8FromInt32x4Bits, 1, 1) \ - F(Uint16x8FromUint32x4Bits, 1, 1) \ - F(Uint16x8FromInt16x8Bits, 1, 1) \ - F(Uint16x8FromInt8x16Bits, 1, 1) \ - F(Uint16x8FromUint8x16Bits, 1, 1) \ - F(Uint16x8Load, 2, 1) \ - F(Uint16x8Store, 3, 1) \ - F(Bool16x8Check, 1, 1) \ - F(Bool16x8ExtractLane, 2, 1) \ - F(Bool16x8ReplaceLane, 3, 1) \ - F(Bool16x8And, 2, 1) \ - F(Bool16x8Or, 2, 1) \ - F(Bool16x8Xor, 2, 1) \ - F(Bool16x8Not, 1, 1) \ - F(Bool16x8AnyTrue, 1, 1) \ - F(Bool16x8AllTrue, 1, 1) \ - F(Bool16x8Swizzle, 9, 1) \ - F(Bool16x8Shuffle, 10, 1) \ - F(Bool16x8Equal, 2, 1) \ - F(Bool16x8NotEqual, 2, 1) \ - F(Int8x16Check, 1, 1) \ - F(Int8x16ExtractLane, 2, 1) \ - F(Int8x16ReplaceLane, 3, 1) \ - F(Int8x16Neg, 1, 1) \ - F(Int8x16Add, 2, 1) \ - F(Int8x16AddSaturate, 2, 1) \ - F(Int8x16Sub, 2, 1) \ - F(Int8x16SubSaturate, 2, 1) \ - F(Int8x16Mul, 2, 1) \ - F(Int8x16Min, 2, 1) \ - F(Int8x16Max, 2, 1) \ - F(Int8x16And, 2, 1) \ - F(Int8x16Or, 2, 1) \ - F(Int8x16Xor, 2, 1) \ - F(Int8x16Not, 1, 1) \ - F(Int8x16ShiftLeftByScalar, 2, 1) \ - F(Int8x16ShiftRightByScalar, 2, 1) \ - F(Int8x16Equal, 2, 1) \ - F(Int8x16NotEqual, 2, 1) \ - F(Int8x16LessThan, 2, 1) \ - F(Int8x16LessThanOrEqual, 2, 1) \ - F(Int8x16GreaterThan, 2, 1) \ - F(Int8x16GreaterThanOrEqual, 2, 1) \ - F(Int8x16Select, 3, 1) \ - F(Int8x16Swizzle, 17, 1) \ - F(Int8x16Shuffle, 18, 1) \ - F(Int8x16FromUint8x16, 1, 1) \ - F(Int8x16FromFloat32x4Bits, 1, 1) \ - F(Int8x16FromInt32x4Bits, 1, 1) \ - F(Int8x16FromUint32x4Bits, 1, 1) \ - F(Int8x16FromInt16x8Bits, 1, 1) \ - F(Int8x16FromUint16x8Bits, 1, 1) \ - F(Int8x16FromUint8x16Bits, 1, 1) \ - F(Int8x16Load, 2, 1) \ - F(Int8x16Store, 3, 1) \ - F(Uint8x16Check, 1, 1) \ - F(Uint8x16ExtractLane, 2, 1) \ - F(Uint8x16ReplaceLane, 3, 1) \ - F(Uint8x16Add, 2, 1) \ - F(Uint8x16AddSaturate, 2, 1) \ - F(Uint8x16Sub, 2, 1) \ - F(Uint8x16SubSaturate, 2, 1) \ - F(Uint8x16Mul, 2, 1) \ - F(Uint8x16Min, 2, 1) \ - F(Uint8x16Max, 2, 1) \ - F(Uint8x16And, 2, 1) \ - F(Uint8x16Or, 2, 1) \ - F(Uint8x16Xor, 2, 1) \ - F(Uint8x16Not, 1, 1) \ - F(Uint8x16ShiftLeftByScalar, 2, 1) \ - F(Uint8x16ShiftRightByScalar, 2, 1) \ - F(Uint8x16Equal, 2, 1) \ - F(Uint8x16NotEqual, 2, 1) \ - F(Uint8x16LessThan, 2, 1) \ - F(Uint8x16LessThanOrEqual, 2, 1) \ - F(Uint8x16GreaterThan, 2, 1) \ - F(Uint8x16GreaterThanOrEqual, 2, 1) \ - F(Uint8x16Select, 3, 1) \ - F(Uint8x16Swizzle, 17, 1) \ - F(Uint8x16Shuffle, 18, 1) \ - F(Uint8x16FromInt8x16, 1, 1) \ - F(Uint8x16FromFloat32x4Bits, 1, 1) \ - F(Uint8x16FromInt32x4Bits, 1, 1) \ - F(Uint8x16FromUint32x4Bits, 1, 1) \ - F(Uint8x16FromInt16x8Bits, 1, 1) \ - F(Uint8x16FromUint16x8Bits, 1, 1) \ - F(Uint8x16FromInt8x16Bits, 1, 1) \ - F(Uint8x16Load, 2, 1) \ - F(Uint8x16Store, 3, 1) \ - F(Bool8x16Check, 1, 1) \ - F(Bool8x16ExtractLane, 2, 1) \ - F(Bool8x16ReplaceLane, 3, 1) \ - F(Bool8x16And, 2, 1) \ - F(Bool8x16Or, 2, 1) \ - F(Bool8x16Xor, 2, 1) \ - F(Bool8x16Not, 1, 1) \ - F(Bool8x16AnyTrue, 1, 1) \ - F(Bool8x16AllTrue, 1, 1) \ - F(Bool8x16Swizzle, 17, 1) \ - F(Bool8x16Shuffle, 18, 1) \ - F(Bool8x16Equal, 2, 1) \ - F(Bool8x16NotEqual, 2, 1) - #define FOR_EACH_INTRINSIC_STRINGS(F) \ + F(GetSubstitution, 4, 1) \ F(StringReplaceOneCharWithString, 3, 1) \ F(StringIndexOf, 3, 1) \ F(StringIndexOfUnchecked, 3, 1) \ @@ -831,8 +528,6 @@ namespace internal { F(StringBuilderJoin, 3, 1) \ F(SparseJoinWithSeparator, 3, 1) \ F(StringToArray, 2, 1) \ - F(StringToLowerCase, 1, 1) \ - F(StringToUpperCase, 1, 1) \ F(StringLessThan, 2, 1) \ F(StringLessThanOrEqual, 2, 1) \ F(StringGreaterThan, 2, 1) \ @@ -867,7 +562,7 @@ namespace internal { F(GetOptimizationCount, 1, 1) \ F(GetUndetectable, 0, 1) \ F(GetCallable, 0, 1) \ - F(ClearFunctionTypeFeedback, 1, 1) \ + F(ClearFunctionFeedback, 1, 1) \ F(CheckWasmWrapperElision, 2, 1) \ F(NotifyContextDisposed, 0, 1) \ F(SetAllocationTimeout, -1 /* 2 || 3 */, 1) \ @@ -929,28 +624,23 @@ namespace internal { F(TypedArrayGetLength, 1, 1) \ F(TypedArrayGetBuffer, 1, 1) \ F(TypedArraySetFastCases, 3, 1) \ + F(TypedArraySortFast, 1, 1) \ F(TypedArrayMaxSizeInHeap, 0, 1) \ F(IsTypedArray, 1, 1) \ F(IsSharedTypedArray, 1, 1) \ F(IsSharedIntegerTypedArray, 1, 1) \ F(IsSharedInteger32TypedArray, 1, 1) -#define FOR_EACH_INTRINSIC_WASM(F) \ - F(WasmGrowMemory, 1, 1) \ - F(WasmMemorySize, 0, 1) \ - F(ThrowWasmError, 2, 1) \ - F(WasmThrowTypeError, 0, 1) \ - F(WasmThrow, 2, 1) \ - F(WasmGetCaughtExceptionValue, 1, 1) \ - F(ThrowWasmTrapUnreachable, 0, 1) \ - F(ThrowWasmTrapMemOutOfBounds, 0, 1) \ - F(ThrowWasmTrapDivByZero, 0, 1) \ - F(ThrowWasmTrapDivUnrepresentable, 0, 1) \ - F(ThrowWasmTrapRemByZero, 0, 1) \ - F(ThrowWasmTrapFloatUnrepresentable, 0, 1) \ - F(ThrowWasmTrapFuncInvalid, 0, 1) \ - F(ThrowWasmTrapFuncSigMismatch, 0, 1) \ - F(WasmRunInterpreter, 3, 1) +#define FOR_EACH_INTRINSIC_WASM(F) \ + F(WasmGrowMemory, 1, 1) \ + F(WasmMemorySize, 0, 1) \ + F(ThrowWasmError, 2, 1) \ + F(ThrowWasmErrorFromTrapIf, 1, 1) \ + F(WasmThrowTypeError, 0, 1) \ + F(WasmThrow, 2, 1) \ + F(WasmGetCaughtExceptionValue, 1, 1) \ + F(WasmRunInterpreter, 3, 1) \ + F(WasmStackGuard, 0, 1) #define FOR_EACH_INTRINSIC_RETURN_PAIR(F) \ F(LoadLookupSlotForCall, 1, 2) @@ -963,22 +653,20 @@ namespace internal { #define FOR_EACH_INTRINSIC_IC(F) \ F(BinaryOpIC_Miss, 2, 1) \ F(BinaryOpIC_MissWithAllocationSite, 3, 1) \ - F(CallIC_Miss, 3, 1) \ F(CompareIC_Miss, 3, 1) \ F(ElementsTransitionAndStoreIC_Miss, 6, 1) \ F(KeyedLoadIC_Miss, 4, 1) \ - F(KeyedLoadIC_MissFromStubFailure, 4, 1) \ F(KeyedStoreIC_Miss, 5, 1) \ F(KeyedStoreIC_Slow, 5, 1) \ F(LoadElementWithInterceptor, 2, 1) \ F(LoadGlobalIC_Miss, 3, 1) \ - F(LoadGlobalIC_Slow, 1, 1) \ + F(LoadGlobalIC_Slow, 3, 1) \ F(LoadIC_Miss, 4, 1) \ - F(LoadPropertyWithInterceptor, 3, 1) \ + F(LoadPropertyWithInterceptor, 5, 1) \ F(LoadPropertyWithInterceptorOnly, 3, 1) \ F(StoreCallbackProperty, 6, 1) \ F(StoreIC_Miss, 5, 1) \ - F(StorePropertyWithInterceptor, 3, 1) \ + F(StorePropertyWithInterceptor, 5, 1) \ F(ToBooleanIC_Miss, 1, 1) \ F(Unreachable, 0, 1) @@ -1005,10 +693,10 @@ namespace internal { FOR_EACH_INTRINSIC_NUMBERS(F) \ FOR_EACH_INTRINSIC_OBJECT(F) \ FOR_EACH_INTRINSIC_OPERATORS(F) \ + FOR_EACH_INTRINSIC_PROMISE(F) \ FOR_EACH_INTRINSIC_PROXY(F) \ FOR_EACH_INTRINSIC_REGEXP(F) \ FOR_EACH_INTRINSIC_SCOPES(F) \ - FOR_EACH_INTRINSIC_SIMD(F) \ FOR_EACH_INTRINSIC_STRINGS(F) \ FOR_EACH_INTRINSIC_SYMBOL(F) \ FOR_EACH_INTRINSIC_TEST(F) \ @@ -1157,6 +845,18 @@ class DeclareGlobalsNativeFlag : public BitField<bool, 1, 1> {}; STATIC_ASSERT(LANGUAGE_END == 2); class DeclareGlobalsLanguageMode : public BitField<LanguageMode, 2, 1> {}; +// A set of bits returned by Runtime_GetOptimizationStatus. +// These bits must be in sync with bits defined in test/mjsunit/mjsunit.js +enum class OptimizationStatus { + kIsFunction = 1 << 0, + kNeverOptimize = 1 << 1, + kAlwaysOptimize = 1 << 2, + kMaybeDeopted = 1 << 3, + kOptimized = 1 << 4, + kTurboFanned = 1 << 5, + kInterpreted = 1 << 6, +}; + } // namespace internal } // namespace v8 |