diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore index 8088214daa951b..48f1071fe8424f 100644 --- a/deps/v8/.gitignore +++ b/deps/v8/.gitignore @@ -1,3 +1,5 @@ +#*# +*.Makefile *.a *.exe *.idb @@ -18,9 +20,9 @@ *.vcxproj *.vcxproj.filters *.xcodeproj -#*# *~ .#* +.*.sw? .cpplint-cache .cproject .d8_history @@ -30,26 +32,23 @@ .project .pydevproject .settings -.*.sw? -bsuite -compile_commands.json -d8 -d8_g -gccauses -gcsuspects -shell -shell_g /_* /build -/gypfiles/win_toolchain.json /buildtools +/gypfiles/win_toolchain.json /hydrogen.cfg /obj /out /out.gn /perf.data /perf.data.old +/src/inspector/build/closure-compiler +/src/inspector/build/closure-compiler.tar.gz /test/benchmarks/data +/test/fuzzer/wasm +/test/fuzzer/wasm.tar.gz +/test/fuzzer/wasm_asmjs +/test/fuzzer/wasm_asmjs.tar.gz /test/mozilla/data /test/promises-aplus/promises-tests /test/promises-aplus/promises-tests.tar.gz @@ -57,6 +56,7 @@ shell_g /test/test262/data /test/test262/data.tar /test/test262/harness +/test/wasm-js /testing/gmock /testing/gtest/* !/testing/gtest/include @@ -67,6 +67,8 @@ shell_g /third_party/* !/third_party/binutils !/third_party/inspector_protocol +!/third_party/jinja2 +!/third_party/markupsafe /tools/clang /tools/gcmole/gcmole-tools /tools/gcmole/gcmole-tools.tar.gz @@ -81,26 +83,24 @@ shell_g /tools/swarming_client /tools/visual_studio/Debug /tools/visual_studio/Release -/test/fuzzer/wasm -/test/fuzzer/wasm_asmjs /v8.log.ll /xcodebuild -TAGS -*.Makefile -GTAGS +GPATH GRTAGS GSYMS -GPATH -tags +GTAGS +TAGS +bsuite +compile_commands.json +d8 +d8_g +gccauses +gcsuspects gtags.files +shell +shell_g +tags turbo*.cfg turbo*.dot turbo*.json v8.ignition_dispatches_table.json -/test/fuzzer/wasm.tar.gz -/test/fuzzer/wasm_asmjs.tar.gz -/src/inspector/build/closure-compiler.tar.gz -/src/inspector/build/closure-compiler -/test/wasm-js -!/third_party/jinja2 -!/third_party/markupsafe diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index ad339290d292b4..256c2c008e164d 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -1889,6 +1889,7 @@ v8_source_set("v8_base") { "src/ia32/macro-assembler-ia32.h", "src/ia32/simulator-ia32.cc", "src/ia32/simulator-ia32.h", + "src/ia32/sse-instr.h", "src/ic/ia32/access-compiler-ia32.cc", "src/ic/ia32/handler-compiler-ia32.cc", "src/ic/ia32/ic-ia32.cc", diff --git a/deps/v8/DEPS b/deps/v8/DEPS index 6fd1ddb49ae900..03db66aa11cdd3 100644 --- a/deps/v8/DEPS +++ b/deps/v8/DEPS @@ -8,13 +8,13 @@ vars = { deps = { "v8/build": - Var("chromium_url") + "/chromium/src/build.git" + "@" + "5f4c2a0a2b8f11a8381c665daa09eb575239db06", + Var("chromium_url") + "/chromium/src/build.git" + "@" + "1748b434c77f774e6046d6cd721e7534a9643163", "v8/tools/gyp": Var("chromium_url") + "/external/gyp.git" + "@" + "e7079f0e0e14108ab0dba58728ff219637458563", "v8/third_party/icu": Var("chromium_url") + "/chromium/deps/icu.git" + "@" + "450be73c9ee8ae29d43d4fdc82febb2a5f62bfb5", "v8/third_party/instrumented_libraries": - Var("chromium_url") + "/chromium/src/third_party/instrumented_libraries.git" + "@" + "e905e0fd5933c224ea54701efb79e6f585c6c586", + Var("chromium_url") + "/chromium/src/third_party/instrumented_libraries.git" + "@" + "62275386c19e927797e8ae6b0c6e57a76c9c6f3c", "v8/buildtools": Var("chromium_url") + "/chromium/buildtools.git" + "@" + "b3771b1935ea74c388b6fb1750e83f5d83b39dec", "v8/base/trace_event/common": @@ -38,7 +38,7 @@ deps = { "v8/test/test262/harness": Var("chromium_url") + "/external/github.com/test262-utils/test262-harness-py.git" + "@" + "0f2acdd882c84cff43b9d60df7574a1901e2cdcd", "v8/tools/clang": - Var("chromium_url") + "/chromium/src/tools/clang.git" + "@" + "e96a7b48d35ab6a268c8372048781cdec903a794", + Var("chromium_url") + "/chromium/src/tools/clang.git" + "@" + "49cece5b02431a848652c7f60dd7b06d94e8d625", "v8/test/wasm-js": Var("chromium_url") + "/external/github.com/WebAssembly/spec.git" + "@" + "002e57c86ccf5c80db0de6e40246665340350c43", } @@ -48,7 +48,7 @@ deps_os = { "v8/third_party/android_tools": Var("chromium_url") + "/android_tools.git" + "@" + "b43a6a289a7588b1769814f04dd6c7d7176974cc", "v8/third_party/catapult": - Var('chromium_url') + "/external/github.com/catapult-project/catapult.git" + "@" + "299d02a80d4158fc98d2a3bfe1a04c355286aec2", + Var('chromium_url') + "/external/github.com/catapult-project/catapult.git" + "@" + "4550ebce30c0593fb85be7890b84b942e8b7af57", }, "win": { "v8/third_party/cygwin": diff --git a/deps/v8/include/v8-debug.h b/deps/v8/include/v8-debug.h index 797d23314e2fd4..54c0f216aa6cc1 100644 --- a/deps/v8/include/v8-debug.h +++ b/deps/v8/include/v8-debug.h @@ -8,7 +8,9 @@ #include "v8.h" // NOLINT(build/include) /** - * Debugger support for the V8 JavaScript engine. + * ATTENTION: The debugger API exposed by this file is deprecated and will be + * removed by the end of 2017. Please use the V8 inspector declared + * in include/v8-inspector.h instead. */ namespace v8 { @@ -140,21 +142,19 @@ class V8_EXPORT Debug { */ typedef void (*MessageHandler)(const Message& message); - /** - * This is now a no-op. - */ - typedef void (*DebugMessageDispatchHandler)(); - - static bool SetDebugEventListener(Isolate* isolate, EventCallback that, - Local data = Local()); + V8_DEPRECATED("No longer supported", static bool SetDebugEventListener( + Isolate* isolate, EventCallback that, + Local data = Local())); // Schedule a debugger break to happen when JavaScript code is run // in the given isolate. - static void DebugBreak(Isolate* isolate); + V8_DEPRECATED("No longer supported", + static void DebugBreak(Isolate* isolate)); // Remove scheduled debugger break in given isolate if it has not // happened yet. - static void CancelDebugBreak(Isolate* isolate); + V8_DEPRECATED("No longer supported", + static void CancelDebugBreak(Isolate* isolate)); // Check if a debugger break is scheduled in the given isolate. V8_DEPRECATED("No longer supported", @@ -189,10 +189,10 @@ class V8_EXPORT Debug { * } * \endcode */ - // TODO(dcarney): data arg should be a MaybeLocal - static MaybeLocal Call(Local context, - v8::Local fun, - Local data = Local()); + V8_DEPRECATED("No longer supported", + static MaybeLocal Call( + Local context, v8::Local fun, + Local data = Local())); // This is now a no-op. V8_DEPRECATED("No longer supported", @@ -221,23 +221,28 @@ class V8_EXPORT Debug { * (default Isolate if not provided). V8 will abort if LiveEdit is * unexpectedly used. LiveEdit is enabled by default. */ - static void SetLiveEditEnabled(Isolate* isolate, bool enable); + V8_DEPRECATED("No longer supported", + static void SetLiveEditEnabled(Isolate* isolate, bool enable)); /** * Returns array of internal properties specific to the value type. Result has * the following format: [, ,...,, ]. Result array * will be allocated in the current context. */ - static MaybeLocal GetInternalProperties(Isolate* isolate, - Local value); + V8_DEPRECATED("No longer supported", + static MaybeLocal GetInternalProperties( + Isolate* isolate, Local value)); /** * Defines if the ES2015 tail call elimination feature is enabled or not. * The change of this flag triggers deoptimization of all functions that * contain calls at tail position. */ - static bool IsTailCallEliminationEnabled(Isolate* isolate); - static void SetTailCallEliminationEnabled(Isolate* isolate, bool enabled); + V8_DEPRECATED("No longer supported", + static bool IsTailCallEliminationEnabled(Isolate* isolate)); + V8_DEPRECATED("No longer supported", + static void SetTailCallEliminationEnabled(Isolate* isolate, + bool enabled)); }; diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index ead6efa42c8dd2..f012b3bdd1a613 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -6638,6 +6638,12 @@ class V8_EXPORT Isolate { */ void Dispose(); + /** + * Dumps activated low-level V8 internal stats. This can be used instead + * of performing a full isolate disposal. + */ + void DumpAndResetStats(); + /** * Discards all V8 thread-specific data for the Isolate. Should be used * if a thread is terminating and it has used an Isolate that will outlive diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 84bc171d2eddec..38668efba1c616 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -6367,9 +6367,7 @@ Local NewContext( isolate, extensions, global_template, global_object, context_snapshot_index, internal_fields_deserializer); if (env.is_null()) { - if (isolate->has_pending_exception()) { - isolate->OptionalRescheduleException(true); - } + if (isolate->has_pending_exception()) isolate->clear_pending_exception(); return Local(); } return Utils::ToLocal(scope.CloseAndEscape(env)); @@ -6420,9 +6418,7 @@ MaybeLocal v8::Context::NewRemoteContext( global_object, 0, DeserializeInternalFieldsCallback()); if (global_proxy.is_null()) { - if (isolate->has_pending_exception()) { - isolate->OptionalRescheduleException(true); - } + if (isolate->has_pending_exception()) isolate->clear_pending_exception(); return MaybeLocal(); } return Utils::ToLocal( @@ -8205,6 +8201,10 @@ void Isolate::Dispose() { isolate->TearDown(); } +void Isolate::DumpAndResetStats() { + i::Isolate* isolate = reinterpret_cast(this); + isolate->DumpAndResetStats(); +} void Isolate::DiscardThreadSpecificMetadata() { i::Isolate* isolate = reinterpret_cast(this); @@ -8961,17 +8961,12 @@ bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that, return true; } -void Debug::DebugBreak(Isolate* isolate) { - reinterpret_cast(isolate)->stack_guard()->RequestDebugBreak(); -} - +void Debug::DebugBreak(Isolate* isolate) { debug::DebugBreak(isolate); } void Debug::CancelDebugBreak(Isolate* isolate) { - i::Isolate* internal_isolate = reinterpret_cast(isolate); - internal_isolate->stack_guard()->ClearDebugBreak(); + debug::CancelDebugBreak(isolate); } - bool Debug::CheckDebugBreak(Isolate* isolate) { i::Isolate* internal_isolate = reinterpret_cast(isolate); return internal_isolate->stack_guard()->CheckDebugBreak(); @@ -8986,29 +8981,15 @@ void Debug::SendCommand(Isolate* isolate, const uint16_t* command, int length, MaybeLocal Debug::Call(Local context, v8::Local fun, v8::Local data) { - PREPARE_FOR_EXECUTION(context, Debug, Call, Value); - i::Handle data_obj; - if (data.IsEmpty()) { - data_obj = isolate->factory()->undefined_value(); - } else { - data_obj = Utils::OpenHandle(*data); - } - Local result; - has_pending_exception = - !ToLocal(isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj), - &result); - RETURN_ON_FAILED_EXECUTION(Value); - RETURN_ESCAPED(result); + return debug::Call(context, fun, data); } - void Debug::ProcessDebugMessages(Isolate* isolate) {} Local Debug::GetDebugContext(Isolate* isolate) { return debug::GetDebugContext(isolate); } - MaybeLocal Debug::GetDebuggedContext(Isolate* isolate) { i::Isolate* i_isolate = reinterpret_cast(isolate); ENTER_V8(i_isolate); @@ -9019,8 +9000,7 @@ MaybeLocal Debug::GetDebuggedContext(Isolate* isolate) { } void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) { - i::Isolate* internal_isolate = reinterpret_cast(isolate); - internal_isolate->debug()->set_live_edit_enabled(enable); + debug::SetLiveEditEnabled(isolate, enable); } bool Debug::IsTailCallEliminationEnabled(Isolate* isolate) { @@ -9035,13 +9015,7 @@ void Debug::SetTailCallEliminationEnabled(Isolate* isolate, bool enabled) { MaybeLocal Debug::GetInternalProperties(Isolate* v8_isolate, Local value) { - i::Isolate* isolate = reinterpret_cast(v8_isolate); - ENTER_V8(isolate); - i::Handle val = Utils::OpenHandle(*value); - i::Handle result; - if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result)) - return MaybeLocal(); - return Utils::ToLocal(result); + return debug::GetInternalProperties(v8_isolate, value); } Local debug::GetDebugContext(Isolate* isolate) { @@ -9053,22 +9027,43 @@ Local debug::GetDebugContext(Isolate* isolate) { MaybeLocal debug::Call(Local context, v8::Local fun, v8::Local data) { - return Debug::Call(context, fun, data); + PREPARE_FOR_EXECUTION(context, Debug, Call, Value); + i::Handle data_obj; + if (data.IsEmpty()) { + data_obj = isolate->factory()->undefined_value(); + } else { + data_obj = Utils::OpenHandle(*data); + } + Local result; + has_pending_exception = !ToLocal( + isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj), &result); + RETURN_ON_FAILED_EXECUTION(Value); + RETURN_ESCAPED(result); } void debug::SetLiveEditEnabled(Isolate* isolate, bool enable) { - Debug::SetLiveEditEnabled(isolate, enable); + i::Isolate* internal_isolate = reinterpret_cast(isolate); + internal_isolate->debug()->set_live_edit_enabled(enable); } -void debug::DebugBreak(Isolate* isolate) { Debug::DebugBreak(isolate); } +void debug::DebugBreak(Isolate* isolate) { + reinterpret_cast(isolate)->stack_guard()->RequestDebugBreak(); +} void debug::CancelDebugBreak(Isolate* isolate) { - Debug::CancelDebugBreak(isolate); + i::Isolate* internal_isolate = reinterpret_cast(isolate); + internal_isolate->stack_guard()->ClearDebugBreak(); } -MaybeLocal debug::GetInternalProperties(Isolate* isolate, +MaybeLocal debug::GetInternalProperties(Isolate* v8_isolate, Local value) { - return Debug::GetInternalProperties(isolate, value); + i::Isolate* isolate = reinterpret_cast(v8_isolate); + ENTER_V8(isolate); + i::Handle val = Utils::OpenHandle(*value); + i::Handle result; + if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result)) + return MaybeLocal(); + return Utils::ToLocal(result); } void debug::ChangeBreakOnException(Isolate* isolate, ExceptionBreakState type) { diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index c88f1f4840e485..1756b965ed3686 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -2282,19 +2282,12 @@ void Assembler::stop(const char* msg, Condition cond, int32_t code) { #ifndef __arm__ DCHECK(code >= kDefaultStopCode); { - // The Simulator will handle the stop instruction and get the message - // address. It expects to find the address just after the svc instruction. BlockConstPoolScope block_const_pool(this); if (code >= 0) { svc(kStopCode + code, cond); } else { svc(kStopCode + kMaxStopCode, cond); } - // Do not embed the message string address! We used to do this, but that - // made snapshots created from position-independent executable builds - // non-deterministic. - // TODO(yangguo): remove this field entirely. - nop(); } #else // def __arm__ if (cond != al) { diff --git a/deps/v8/src/arm/disasm-arm.cc b/deps/v8/src/arm/disasm-arm.cc index 761192f59d795f..2cd97a357215c9 100644 --- a/deps/v8/src/arm/disasm-arm.cc +++ b/deps/v8/src/arm/disasm-arm.cc @@ -1364,12 +1364,6 @@ int Decoder::DecodeType7(Instruction* instr) { if (instr->Bit(24) == 1) { if (instr->SvcValue() >= kStopCode) { Format(instr, "stop'cond 'svc"); - out_buffer_pos_ += SNPrintF( - out_buffer_ + out_buffer_pos_, "\n %p %08x", - reinterpret_cast(instr + Instruction::kInstrSize), - *reinterpret_cast(instr + Instruction::kInstrSize)); - // We have decoded 2 * Instruction::kInstrSize bytes. - return 2 * Instruction::kInstrSize; } else { Format(instr, "svc'cond 'svc"); } diff --git a/deps/v8/src/arm/simulator-arm.cc b/deps/v8/src/arm/simulator-arm.cc index e2bcd952a6c08d..6a478d5701bd81 100644 --- a/deps/v8/src/arm/simulator-arm.cc +++ b/deps/v8/src/arm/simulator-arm.cc @@ -432,15 +432,12 @@ void ArmDebugger::Debug() { PrintF("INEXACT flag: %d;\n", sim_->inexact_vfp_flag_); } else if (strcmp(cmd, "stop") == 0) { int32_t value; - intptr_t stop_pc = sim_->get_pc() - 2 * Instruction::kInstrSize; + intptr_t stop_pc = sim_->get_pc() - Instruction::kInstrSize; Instruction* stop_instr = reinterpret_cast(stop_pc); - Instruction* msg_address = - reinterpret_cast(stop_pc + Instruction::kInstrSize); if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) { // Remove the current stop. if (sim_->isStopInstruction(stop_instr)) { stop_instr->SetInstructionBits(kNopInstr); - msg_address->SetInstructionBits(kNopInstr); } else { PrintF("Not at debugger stop.\n"); } @@ -5671,10 +5668,6 @@ void Simulator::InstructionDecode(Instruction* instr) { break; } } - // If the instruction is a non taken conditional stop, we need to skip the - // inlined message address. - } else if (instr->IsStop()) { - set_pc(get_pc() + 2 * Instruction::kInstrSize); } if (!pc_modified_) { set_register(pc, reinterpret_cast(instr) diff --git a/deps/v8/src/bootstrapper.cc b/deps/v8/src/bootstrapper.cc index 8e7c0fc0ae0b3a..ac3ca994b41838 100644 --- a/deps/v8/src/bootstrapper.cc +++ b/deps/v8/src/bootstrapper.cc @@ -2040,6 +2040,7 @@ void Genesis::InitializeGlobal(Handle global_object, SimpleInstallFunction(promise_fun, "resolve", Builtins::kPromiseResolve, 1, true, DONT_ENUM); + isolate->builtins()->PromiseResolve()->set_is_promise_rejection(true); SimpleInstallFunction(promise_fun, "reject", Builtins::kPromiseReject, 1, true, DONT_ENUM); @@ -2075,6 +2076,7 @@ void Genesis::InitializeGlobal(Handle global_object, function->shared()->set_native(false); InstallWithIntrinsicDefaultProto(isolate, function, Context::PROMISE_RESOLVE_INDEX); + isolate->builtins()->ResolvePromise()->set_is_promise_rejection(true); } { // Internal: PromiseHandle @@ -2111,6 +2113,7 @@ void Genesis::InitializeGlobal(Handle global_object, Handle code = handle(isolate->builtins()->builtin(Builtins::kPromiseResolveClosure), isolate); + code->set_is_promise_rejection(true); Handle info = factory->NewSharedFunctionInfo(factory->empty_string(), code, false); info->set_internal_formal_parameter_count(1); @@ -3132,7 +3135,7 @@ bool Bootstrapper::CompileNative(Isolate* isolate, Vector name, // environment has been at least partially initialized. Add a stack check // before entering JS code to catch overflow early. StackLimitCheck check(isolate); - if (check.JsHasOverflowed(1 * KB)) { + if (check.JsHasOverflowed(4 * KB)) { isolate->StackOverflow(); return false; } @@ -3537,6 +3540,8 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate, Handle function = SimpleCreateFunction(isolate, factory->empty_string(), Builtins::kAsyncFunctionAwaitCaught, 3, false); + isolate->builtins()->AsyncFunctionAwaitCaught()->set_is_promise_rejection( + true); InstallWithIntrinsicDefaultProto( isolate, function, Context::ASYNC_FUNCTION_AWAIT_CAUGHT_INDEX); } @@ -3545,6 +3550,9 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate, Handle function = SimpleCreateFunction(isolate, factory->empty_string(), Builtins::kAsyncFunctionAwaitUncaught, 3, false); + isolate->builtins() + ->AsyncFunctionAwaitUncaught() + ->set_is_promise_rejection(true); InstallWithIntrinsicDefaultProto( isolate, function, Context::ASYNC_FUNCTION_AWAIT_UNCAUGHT_INDEX); } diff --git a/deps/v8/src/builtins/builtins-array.cc b/deps/v8/src/builtins/builtins-array.cc index 5d3d4c1c730505..85a49284b72953 100644 --- a/deps/v8/src/builtins/builtins-array.cc +++ b/deps/v8/src/builtins/builtins-array.cc @@ -188,76 +188,63 @@ BUILTIN(ArrayPush) { return Smi::FromInt(new_length); } -void Builtins::Generate_FastArrayPush(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef CodeStubAssembler::Label Label; - typedef CodeStubAssembler::Variable Variable; - CodeStubAssembler assembler(state); - Variable arg_index(&assembler, MachineType::PointerRepresentation()); - Label default_label(&assembler, &arg_index); - Label smi_transition(&assembler); - Label object_push_pre(&assembler); - Label object_push(&assembler, &arg_index); - Label double_push(&assembler, &arg_index); - Label double_transition(&assembler); - Label runtime(&assembler, Label::kDeferred); - - Node* argc = assembler.Parameter(BuiltinDescriptor::kArgumentsCount); - Node* context = assembler.Parameter(BuiltinDescriptor::kContext); - Node* new_target = assembler.Parameter(BuiltinDescriptor::kNewTarget); - - CodeStubArguments args(&assembler, assembler.ChangeInt32ToIntPtr(argc)); +TF_BUILTIN(FastArrayPush, CodeStubAssembler) { + Variable arg_index(this, MachineType::PointerRepresentation()); + Label default_label(this, &arg_index); + Label smi_transition(this); + Label object_push_pre(this); + Label object_push(this, &arg_index); + Label double_push(this, &arg_index); + Label double_transition(this); + Label runtime(this, Label::kDeferred); + + Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount); + Node* context = Parameter(BuiltinDescriptor::kContext); + Node* new_target = Parameter(BuiltinDescriptor::kNewTarget); + + CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); Node* receiver = args.GetReceiver(); Node* kind = nullptr; - Label fast(&assembler); - { - assembler.BranchIfFastJSArray( - receiver, context, CodeStubAssembler::FastJSArrayAccessMode::ANY_ACCESS, - &fast, &runtime); - } + Label fast(this); + BranchIfFastJSArray(receiver, context, FastJSArrayAccessMode::ANY_ACCESS, + &fast, &runtime); - assembler.Bind(&fast); + Bind(&fast); { // Disallow pushing onto prototypes. It might be the JSArray prototype. // Disallow pushing onto non-extensible objects. - assembler.Comment("Disallow pushing onto prototypes"); - Node* map = assembler.LoadMap(receiver); - Node* bit_field2 = assembler.LoadMapBitField2(map); + Comment("Disallow pushing onto prototypes"); + Node* map = LoadMap(receiver); + Node* bit_field2 = LoadMapBitField2(map); int mask = static_cast(Map::IsPrototypeMapBits::kMask) | (1 << Map::kIsExtensible); - Node* test = assembler.Word32And(bit_field2, assembler.Int32Constant(mask)); - assembler.GotoIf( - assembler.Word32NotEqual( - test, assembler.Int32Constant(1 << Map::kIsExtensible)), - &runtime); + Node* test = Word32And(bit_field2, Int32Constant(mask)); + GotoIf(Word32NotEqual(test, Int32Constant(1 << Map::kIsExtensible)), + &runtime); // Disallow pushing onto arrays in dictionary named property mode. We need // to figure out whether the length property is still writable. - assembler.Comment( - "Disallow pushing onto arrays in dictionary named property mode"); - assembler.GotoIf(assembler.IsDictionaryMap(map), &runtime); + Comment("Disallow pushing onto arrays in dictionary named property mode"); + GotoIf(IsDictionaryMap(map), &runtime); // Check whether the length property is writable. The length property is the // only default named property on arrays. It's nonconfigurable, hence is // guaranteed to stay the first property. - Node* descriptors = assembler.LoadMapDescriptors(map); - Node* details = assembler.LoadFixedArrayElement( - descriptors, DescriptorArray::ToDetailsIndex(0)); - assembler.GotoIf( - assembler.IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask), - &runtime); - - arg_index.Bind(assembler.IntPtrConstant(0)); - kind = assembler.DecodeWord32(bit_field2); - - assembler.GotoIf( - assembler.Int32GreaterThan( - kind, assembler.Int32Constant(FAST_HOLEY_SMI_ELEMENTS)), - &object_push_pre); - - Node* new_length = assembler.BuildAppendJSArray( - FAST_SMI_ELEMENTS, context, receiver, args, arg_index, &smi_transition); + Node* descriptors = LoadMapDescriptors(map); + Node* details = + LoadFixedArrayElement(descriptors, DescriptorArray::ToDetailsIndex(0)); + GotoIf(IsSetSmi(details, PropertyDetails::kAttributesReadOnlyMask), + &runtime); + + arg_index.Bind(IntPtrConstant(0)); + kind = DecodeWord32(bit_field2); + + GotoIf(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_SMI_ELEMENTS)), + &object_push_pre); + + Node* new_length = BuildAppendJSArray(FAST_SMI_ELEMENTS, context, receiver, + args, arg_index, &smi_transition); args.PopAndReturn(new_length); } @@ -265,48 +252,46 @@ void Builtins::Generate_FastArrayPush(compiler::CodeAssemblerState* state) { // transition the array for only the single next element. If the argument is // a smi, the failure is due to some other reason and we should fall back on // the most generic implementation for the rest of the array. - assembler.Bind(&smi_transition); + Bind(&smi_transition); { Node* arg = args.AtIndex(arg_index.value()); - assembler.GotoIf(assembler.TaggedIsSmi(arg), &default_label); - Node* length = assembler.LoadJSArrayLength(receiver); + GotoIf(TaggedIsSmi(arg), &default_label); + Node* length = LoadJSArrayLength(receiver); // TODO(danno): Use the KeyedStoreGeneric stub here when possible, // calling into the runtime to do the elements transition is overkill. - assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, - assembler.SmiConstant(STRICT)); - assembler.Increment(arg_index); + CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, + SmiConstant(STRICT)); + Increment(arg_index); // The runtime SetProperty call could have converted the array to dictionary // mode, which must be detected to abort the fast-path. - Node* map = assembler.LoadMap(receiver); - Node* bit_field2 = assembler.LoadMapBitField2(map); - Node* kind = assembler.DecodeWord32(bit_field2); - assembler.GotoIf(assembler.Word32Equal( - kind, assembler.Int32Constant(DICTIONARY_ELEMENTS)), - &default_label); + Node* map = LoadMap(receiver); + Node* bit_field2 = LoadMapBitField2(map); + Node* kind = DecodeWord32(bit_field2); + GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)), + &default_label); - assembler.GotoIfNotNumber(arg, &object_push); - assembler.Goto(&double_push); + GotoIfNotNumber(arg, &object_push); + Goto(&double_push); } - assembler.Bind(&object_push_pre); + Bind(&object_push_pre); { - assembler.Branch(assembler.Int32GreaterThan( - kind, assembler.Int32Constant(FAST_HOLEY_ELEMENTS)), - &double_push, &object_push); + Branch(Int32GreaterThan(kind, Int32Constant(FAST_HOLEY_ELEMENTS)), + &double_push, &object_push); } - assembler.Bind(&object_push); + Bind(&object_push); { - Node* new_length = assembler.BuildAppendJSArray( - FAST_ELEMENTS, context, receiver, args, arg_index, &default_label); + Node* new_length = BuildAppendJSArray(FAST_ELEMENTS, context, receiver, + args, arg_index, &default_label); args.PopAndReturn(new_length); } - assembler.Bind(&double_push); + Bind(&double_push); { Node* new_length = - assembler.BuildAppendJSArray(FAST_DOUBLE_ELEMENTS, context, receiver, - args, arg_index, &double_transition); + BuildAppendJSArray(FAST_DOUBLE_ELEMENTS, context, receiver, args, + arg_index, &double_transition); args.PopAndReturn(new_length); } @@ -314,47 +299,46 @@ void Builtins::Generate_FastArrayPush(compiler::CodeAssemblerState* state) { // transition the array for only the single next element. If the argument is // a double, the failure is due to some other reason and we should fall back // on the most generic implementation for the rest of the array. - assembler.Bind(&double_transition); + Bind(&double_transition); { Node* arg = args.AtIndex(arg_index.value()); - assembler.GotoIfNumber(arg, &default_label); - Node* length = assembler.LoadJSArrayLength(receiver); + GotoIfNumber(arg, &default_label); + Node* length = LoadJSArrayLength(receiver); // TODO(danno): Use the KeyedStoreGeneric stub here when possible, // calling into the runtime to do the elements transition is overkill. - assembler.CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, - assembler.SmiConstant(STRICT)); - assembler.Increment(arg_index); + CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, + SmiConstant(STRICT)); + Increment(arg_index); // The runtime SetProperty call could have converted the array to dictionary // mode, which must be detected to abort the fast-path. - Node* map = assembler.LoadMap(receiver); - Node* bit_field2 = assembler.LoadMapBitField2(map); - Node* kind = assembler.DecodeWord32(bit_field2); - assembler.GotoIf(assembler.Word32Equal( - kind, assembler.Int32Constant(DICTIONARY_ELEMENTS)), - &default_label); - assembler.Goto(&object_push); + Node* map = LoadMap(receiver); + Node* bit_field2 = LoadMapBitField2(map); + Node* kind = DecodeWord32(bit_field2); + GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)), + &default_label); + Goto(&object_push); } // Fallback that stores un-processed arguments using the full, heavyweight // SetProperty machinery. - assembler.Bind(&default_label); + Bind(&default_label); { args.ForEach( - [&assembler, receiver, context](Node* arg) { - Node* length = assembler.LoadJSArrayLength(receiver); - assembler.CallRuntime(Runtime::kSetProperty, context, receiver, - length, arg, assembler.SmiConstant(STRICT)); + [this, receiver, context](Node* arg) { + Node* length = LoadJSArrayLength(receiver); + CallRuntime(Runtime::kSetProperty, context, receiver, length, arg, + SmiConstant(STRICT)); }, arg_index.value()); - args.PopAndReturn(assembler.LoadJSArrayLength(receiver)); + args.PopAndReturn(LoadJSArrayLength(receiver)); } - assembler.Bind(&runtime); + Bind(&runtime); { - Node* target = assembler.LoadFromFrame( - StandardFrameConstants::kFunctionOffset, MachineType::TaggedPointer()); - assembler.TailCallStub(CodeFactory::ArrayPush(assembler.isolate()), context, - target, new_target, argc); + Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, + MachineType::TaggedPointer()); + TailCallStub(CodeFactory::ArrayPush(isolate()), context, target, new_target, + argc); } } @@ -1645,38 +1629,30 @@ BUILTIN(ArrayConcat) { return Slow_ArrayConcat(&args, species, isolate); } -void Builtins::Generate_ArrayIsArray(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef CodeStubAssembler::Label Label; - CodeStubAssembler assembler(state); - - Node* object = assembler.Parameter(1); - Node* context = assembler.Parameter(4); +TF_BUILTIN(ArrayIsArray, CodeStubAssembler) { + Node* object = Parameter(1); + Node* context = Parameter(4); - Label call_runtime(&assembler), return_true(&assembler), - return_false(&assembler); + Label call_runtime(this), return_true(this), return_false(this); - assembler.GotoIf(assembler.TaggedIsSmi(object), &return_false); - Node* instance_type = assembler.LoadInstanceType(object); + GotoIf(TaggedIsSmi(object), &return_false); + Node* instance_type = LoadInstanceType(object); - assembler.GotoIf(assembler.Word32Equal( - instance_type, assembler.Int32Constant(JS_ARRAY_TYPE)), - &return_true); + GotoIf(Word32Equal(instance_type, Int32Constant(JS_ARRAY_TYPE)), + &return_true); // TODO(verwaest): Handle proxies in-place. - assembler.Branch(assembler.Word32Equal( - instance_type, assembler.Int32Constant(JS_PROXY_TYPE)), - &call_runtime, &return_false); + Branch(Word32Equal(instance_type, Int32Constant(JS_PROXY_TYPE)), + &call_runtime, &return_false); - assembler.Bind(&return_true); - assembler.Return(assembler.BooleanConstant(true)); + Bind(&return_true); + Return(BooleanConstant(true)); - assembler.Bind(&return_false); - assembler.Return(assembler.BooleanConstant(false)); + Bind(&return_false); + Return(BooleanConstant(false)); - assembler.Bind(&call_runtime); - assembler.Return( - assembler.CallRuntime(Runtime::kArrayIsArray, context, object)); + Bind(&call_runtime); + Return(CallRuntime(Runtime::kArrayIsArray, context, object)); } TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { @@ -1694,8 +1670,7 @@ TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { // Take slow path if not a JSArray, if retrieving elements requires // traversing prototype, or if access checks are required. - BranchIfFastJSArray(array, context, - CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, + BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ, &init_len, &call_runtime); Bind(&init_len); @@ -1917,7 +1892,7 @@ TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { // Load double value or continue if it contains a double hole. Node* element_k = LoadFixedDoubleArrayElement( elements, index_var.value(), MachineType::Float64(), 0, - CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); + INTPTR_PARAMETERS, &continue_loop); Branch(Float64Equal(element_k, search_num.value()), &return_true, &continue_loop); @@ -1935,7 +1910,7 @@ TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { // Load double value or continue if it contains a double hole. Node* element_k = LoadFixedDoubleArrayElement( elements, index_var.value(), MachineType::Float64(), 0, - CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); + INTPTR_PARAMETERS, &continue_loop); BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); Bind(&continue_loop); @@ -1949,9 +1924,9 @@ TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { GotoIfNot(UintPtrLessThan(index_var.value(), len), &return_false); // Check if the element is a double hole, but don't load it. - LoadFixedDoubleArrayElement( - elements, index_var.value(), MachineType::None(), 0, - CodeStubAssembler::INTPTR_PARAMETERS, &return_true); + LoadFixedDoubleArrayElement(elements, index_var.value(), + MachineType::None(), 0, INTPTR_PARAMETERS, + &return_true); index_var.Bind(IntPtrAdd(index_var.value(), IntPtrConstant(1))); Goto(&hole_loop); @@ -1969,116 +1944,100 @@ TF_BUILTIN(ArrayIncludes, CodeStubAssembler) { search_element, start_from)); } -void Builtins::Generate_ArrayIndexOf(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef CodeStubAssembler::Label Label; - typedef CodeStubAssembler::Variable Variable; - CodeStubAssembler assembler(state); - - Node* array = assembler.Parameter(0); - Node* search_element = assembler.Parameter(1); - Node* start_from = assembler.Parameter(2); - Node* context = assembler.Parameter(3 + 2); - - Node* intptr_zero = assembler.IntPtrConstant(0); - Node* intptr_one = assembler.IntPtrConstant(1); +TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) { + Node* array = Parameter(0); + Node* search_element = Parameter(1); + Node* start_from = Parameter(2); + Node* context = Parameter(3 + 2); - Node* undefined = assembler.UndefinedConstant(); + Node* intptr_zero = IntPtrConstant(0); + Node* intptr_one = IntPtrConstant(1); - Variable len_var(&assembler, MachineType::PointerRepresentation()), - index_var(&assembler, MachineType::PointerRepresentation()), - start_from_var(&assembler, MachineType::PointerRepresentation()); + Variable len_var(this, MachineType::PointerRepresentation()), + index_var(this, MachineType::PointerRepresentation()), + start_from_var(this, MachineType::PointerRepresentation()); - Label init_k(&assembler), return_found(&assembler), - return_not_found(&assembler), call_runtime(&assembler); + Label init_k(this), return_found(this), return_not_found(this), + call_runtime(this); - Label init_len(&assembler); + Label init_len(this); index_var.Bind(intptr_zero); len_var.Bind(intptr_zero); // Take slow path if not a JSArray, if retrieving elements requires // traversing prototype, or if access checks are required. - assembler.BranchIfFastJSArray( - array, context, CodeStubAssembler::FastJSArrayAccessMode::INBOUNDS_READ, - &init_len, &call_runtime); + BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ, + &init_len, &call_runtime); - assembler.Bind(&init_len); + Bind(&init_len); { // JSArray length is always an Smi for fast arrays. - CSA_ASSERT(&assembler, assembler.TaggedIsSmi(assembler.LoadObjectField( - array, JSArray::kLengthOffset))); - Node* len = - assembler.LoadAndUntagObjectField(array, JSArray::kLengthOffset); + CSA_ASSERT(this, + TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset))); + Node* len = LoadAndUntagObjectField(array, JSArray::kLengthOffset); len_var.Bind(len); - assembler.Branch(assembler.WordEqual(len_var.value(), intptr_zero), - &return_not_found, &init_k); + Branch(WordEqual(len_var.value(), intptr_zero), &return_not_found, &init_k); } - assembler.Bind(&init_k); + Bind(&init_k); { - Label done(&assembler), init_k_smi(&assembler), init_k_heap_num(&assembler), - init_k_zero(&assembler), init_k_n(&assembler); - Node* tagged_n = assembler.ToInteger(context, start_from); + Label done(this), init_k_smi(this), init_k_heap_num(this), + init_k_zero(this), init_k_n(this); + Node* tagged_n = ToInteger(context, start_from); - assembler.Branch(assembler.TaggedIsSmi(tagged_n), &init_k_smi, - &init_k_heap_num); + Branch(TaggedIsSmi(tagged_n), &init_k_smi, &init_k_heap_num); - assembler.Bind(&init_k_smi); + Bind(&init_k_smi); { - start_from_var.Bind(assembler.SmiUntag(tagged_n)); - assembler.Goto(&init_k_n); + start_from_var.Bind(SmiUntag(tagged_n)); + Goto(&init_k_n); } - assembler.Bind(&init_k_heap_num); + Bind(&init_k_heap_num); { - Label do_return_not_found(&assembler); + Label do_return_not_found(this); // This round is lossless for all valid lengths. - Node* fp_len = assembler.RoundIntPtrToFloat64(len_var.value()); - Node* fp_n = assembler.LoadHeapNumberValue(tagged_n); - assembler.GotoIf(assembler.Float64GreaterThanOrEqual(fp_n, fp_len), - &do_return_not_found); - start_from_var.Bind(assembler.ChangeInt32ToIntPtr( - assembler.TruncateFloat64ToWord32(fp_n))); - assembler.Goto(&init_k_n); - - assembler.Bind(&do_return_not_found); + Node* fp_len = RoundIntPtrToFloat64(len_var.value()); + Node* fp_n = LoadHeapNumberValue(tagged_n); + GotoIf(Float64GreaterThanOrEqual(fp_n, fp_len), &do_return_not_found); + start_from_var.Bind(ChangeInt32ToIntPtr(TruncateFloat64ToWord32(fp_n))); + Goto(&init_k_n); + + Bind(&do_return_not_found); { index_var.Bind(intptr_zero); - assembler.Goto(&return_not_found); + Goto(&return_not_found); } } - assembler.Bind(&init_k_n); + Bind(&init_k_n); { - Label if_positive(&assembler), if_negative(&assembler), done(&assembler); - assembler.Branch( - assembler.IntPtrLessThan(start_from_var.value(), intptr_zero), - &if_negative, &if_positive); + Label if_positive(this), if_negative(this), done(this); + Branch(IntPtrLessThan(start_from_var.value(), intptr_zero), &if_negative, + &if_positive); - assembler.Bind(&if_positive); + Bind(&if_positive); { index_var.Bind(start_from_var.value()); - assembler.Goto(&done); + Goto(&done); } - assembler.Bind(&if_negative); + Bind(&if_negative); { - index_var.Bind( - assembler.IntPtrAdd(len_var.value(), start_from_var.value())); - assembler.Branch( - assembler.IntPtrLessThan(index_var.value(), intptr_zero), - &init_k_zero, &done); + index_var.Bind(IntPtrAdd(len_var.value(), start_from_var.value())); + Branch(IntPtrLessThan(index_var.value(), intptr_zero), &init_k_zero, + &done); } - assembler.Bind(&init_k_zero); + Bind(&init_k_zero); { index_var.Bind(intptr_zero); - assembler.Goto(&done); + Goto(&done); } - assembler.Bind(&done); + Bind(&done); } } @@ -2087,357 +2046,291 @@ void Builtins::Generate_ArrayIndexOf(compiler::CodeAssemblerState* state) { FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, }; - Label if_smiorobjects(&assembler), if_packed_doubles(&assembler), - if_holey_doubles(&assembler); + Label if_smiorobjects(this), if_packed_doubles(this), if_holey_doubles(this); Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects, &if_smiorobjects, &if_smiorobjects, &if_packed_doubles, &if_holey_doubles}; - Node* map = assembler.LoadMap(array); - Node* elements_kind = assembler.LoadMapElementsKind(map); - Node* elements = assembler.LoadElements(array); - assembler.Switch(elements_kind, &return_not_found, kElementsKind, - element_kind_handlers, arraysize(kElementsKind)); + Node* map = LoadMap(array); + Node* elements_kind = LoadMapElementsKind(map); + Node* elements = LoadElements(array); + Switch(elements_kind, &return_not_found, kElementsKind, element_kind_handlers, + arraysize(kElementsKind)); - assembler.Bind(&if_smiorobjects); + Bind(&if_smiorobjects); { - Variable search_num(&assembler, MachineRepresentation::kFloat64); - Label ident_loop(&assembler, &index_var), - heap_num_loop(&assembler, &search_num), - string_loop(&assembler, &index_var), undef_loop(&assembler, &index_var), - not_smi(&assembler), not_heap_num(&assembler); - - assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), ¬_smi); - search_num.Bind(assembler.SmiToFloat64(search_element)); - assembler.Goto(&heap_num_loop); - - assembler.Bind(¬_smi); - assembler.GotoIf(assembler.WordEqual(search_element, undefined), - &undef_loop); - Node* map = assembler.LoadMap(search_element); - assembler.GotoIfNot(assembler.IsHeapNumberMap(map), ¬_heap_num); - search_num.Bind(assembler.LoadHeapNumberValue(search_element)); - assembler.Goto(&heap_num_loop); - - assembler.Bind(¬_heap_num); - Node* search_type = assembler.LoadMapInstanceType(map); - assembler.GotoIf(assembler.IsStringInstanceType(search_type), &string_loop); - assembler.Goto(&ident_loop); - - assembler.Bind(&ident_loop); - { - assembler.GotoIfNot( - assembler.UintPtrLessThan(index_var.value(), len_var.value()), - &return_not_found); - Node* element_k = - assembler.LoadFixedArrayElement(elements, index_var.value()); - assembler.GotoIf(assembler.WordEqual(element_k, search_element), - &return_found); - - index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); - assembler.Goto(&ident_loop); - } + Variable search_num(this, MachineRepresentation::kFloat64); + Label ident_loop(this, &index_var), heap_num_loop(this, &search_num), + string_loop(this, &index_var), not_smi(this), not_heap_num(this); - assembler.Bind(&undef_loop); + GotoIfNot(TaggedIsSmi(search_element), ¬_smi); + search_num.Bind(SmiToFloat64(search_element)); + Goto(&heap_num_loop); + + Bind(¬_smi); + Node* map = LoadMap(search_element); + GotoIfNot(IsHeapNumberMap(map), ¬_heap_num); + search_num.Bind(LoadHeapNumberValue(search_element)); + Goto(&heap_num_loop); + + Bind(¬_heap_num); + Node* search_type = LoadMapInstanceType(map); + GotoIf(IsStringInstanceType(search_type), &string_loop); + Goto(&ident_loop); + + Bind(&ident_loop); { - assembler.GotoIfNot( - assembler.UintPtrLessThan(index_var.value(), len_var.value()), - &return_not_found); - Node* element_k = - assembler.LoadFixedArrayElement(elements, index_var.value()); - assembler.GotoIf(assembler.WordEqual(element_k, undefined), - &return_found); - - index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); - assembler.Goto(&undef_loop); + GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), + &return_not_found); + Node* element_k = LoadFixedArrayElement(elements, index_var.value()); + GotoIf(WordEqual(element_k, search_element), &return_found); + + index_var.Bind(IntPtrAdd(index_var.value(), intptr_one)); + Goto(&ident_loop); } - assembler.Bind(&heap_num_loop); + Bind(&heap_num_loop); { - Label not_nan_loop(&assembler, &index_var); - assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, - ¬_nan_loop); + Label not_nan_loop(this, &index_var); + BranchIfFloat64IsNaN(search_num.value(), &return_not_found, + ¬_nan_loop); - assembler.Bind(¬_nan_loop); + Bind(¬_nan_loop); { - Label continue_loop(&assembler), not_smi(&assembler); - assembler.GotoIfNot( - assembler.UintPtrLessThan(index_var.value(), len_var.value()), - &return_not_found); - Node* element_k = - assembler.LoadFixedArrayElement(elements, index_var.value()); - assembler.GotoIfNot(assembler.TaggedIsSmi(element_k), ¬_smi); - assembler.Branch( - assembler.Float64Equal(search_num.value(), - assembler.SmiToFloat64(element_k)), - &return_found, &continue_loop); - - assembler.Bind(¬_smi); - assembler.GotoIfNot( - assembler.IsHeapNumberMap(assembler.LoadMap(element_k)), - &continue_loop); - assembler.Branch( - assembler.Float64Equal(search_num.value(), - assembler.LoadHeapNumberValue(element_k)), - &return_found, &continue_loop); - - assembler.Bind(&continue_loop); - index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); - assembler.Goto(¬_nan_loop); + Label continue_loop(this), not_smi(this); + GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), + &return_not_found); + Node* element_k = LoadFixedArrayElement(elements, index_var.value()); + GotoIfNot(TaggedIsSmi(element_k), ¬_smi); + Branch(Float64Equal(search_num.value(), SmiToFloat64(element_k)), + &return_found, &continue_loop); + + Bind(¬_smi); + GotoIfNot(IsHeapNumber(element_k), &continue_loop); + Branch(Float64Equal(search_num.value(), LoadHeapNumberValue(element_k)), + &return_found, &continue_loop); + + Bind(&continue_loop); + index_var.Bind(IntPtrAdd(index_var.value(), intptr_one)); + Goto(¬_nan_loop); } } - assembler.Bind(&string_loop); + Bind(&string_loop); { - Label continue_loop(&assembler); - assembler.GotoIfNot( - assembler.UintPtrLessThan(index_var.value(), len_var.value()), - &return_not_found); - Node* element_k = - assembler.LoadFixedArrayElement(elements, index_var.value()); - assembler.GotoIf(assembler.TaggedIsSmi(element_k), &continue_loop); - assembler.GotoIfNot( - assembler.IsStringInstanceType(assembler.LoadInstanceType(element_k)), - &continue_loop); + Label continue_loop(this); + GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), + &return_not_found); + Node* element_k = LoadFixedArrayElement(elements, index_var.value()); + GotoIf(TaggedIsSmi(element_k), &continue_loop); + GotoIfNot(IsString(element_k), &continue_loop); // TODO(bmeurer): Consider inlining the StringEqual logic here. - Callable callable = CodeFactory::StringEqual(assembler.isolate()); - Node* result = - assembler.CallStub(callable, context, search_element, element_k); - assembler.Branch( - assembler.WordEqual(assembler.BooleanConstant(true), result), - &return_found, &continue_loop); - - assembler.Bind(&continue_loop); - index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); - assembler.Goto(&string_loop); + Callable callable = CodeFactory::StringEqual(isolate()); + Node* result = CallStub(callable, context, search_element, element_k); + Branch(WordEqual(BooleanConstant(true), result), &return_found, + &continue_loop); + + Bind(&continue_loop); + index_var.Bind(IntPtrAdd(index_var.value(), intptr_one)); + Goto(&string_loop); } } - assembler.Bind(&if_packed_doubles); + Bind(&if_packed_doubles); { - Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); - Variable search_num(&assembler, MachineRepresentation::kFloat64); + Label not_nan_loop(this, &index_var), search_notnan(this); + Variable search_num(this, MachineRepresentation::kFloat64); - assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &search_notnan); - search_num.Bind(assembler.SmiToFloat64(search_element)); - assembler.Goto(¬_nan_loop); + GotoIfNot(TaggedIsSmi(search_element), &search_notnan); + search_num.Bind(SmiToFloat64(search_element)); + Goto(¬_nan_loop); - assembler.Bind(&search_notnan); - assembler.GotoIfNot( - assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), - &return_not_found); + Bind(&search_notnan); + GotoIfNot(IsHeapNumber(search_element), &return_not_found); - search_num.Bind(assembler.LoadHeapNumberValue(search_element)); + search_num.Bind(LoadHeapNumberValue(search_element)); - assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, - ¬_nan_loop); + BranchIfFloat64IsNaN(search_num.value(), &return_not_found, ¬_nan_loop); // Search for HeapNumber - assembler.Bind(¬_nan_loop); + Bind(¬_nan_loop); { - Label continue_loop(&assembler); - assembler.GotoIfNot( - assembler.UintPtrLessThan(index_var.value(), len_var.value()), - &return_not_found); - Node* element_k = assembler.LoadFixedDoubleArrayElement( - elements, index_var.value(), MachineType::Float64()); - assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), - &return_found, &continue_loop); - assembler.Bind(&continue_loop); - index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); - assembler.Goto(¬_nan_loop); + GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), + &return_not_found); + Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(), + MachineType::Float64()); + GotoIf(Float64Equal(element_k, search_num.value()), &return_found); + + index_var.Bind(IntPtrAdd(index_var.value(), intptr_one)); + Goto(¬_nan_loop); } } - assembler.Bind(&if_holey_doubles); + Bind(&if_holey_doubles); { - Label not_nan_loop(&assembler, &index_var), search_notnan(&assembler); - Variable search_num(&assembler, MachineRepresentation::kFloat64); + Label not_nan_loop(this, &index_var), search_notnan(this); + Variable search_num(this, MachineRepresentation::kFloat64); - assembler.GotoIfNot(assembler.TaggedIsSmi(search_element), &search_notnan); - search_num.Bind(assembler.SmiToFloat64(search_element)); - assembler.Goto(¬_nan_loop); + GotoIfNot(TaggedIsSmi(search_element), &search_notnan); + search_num.Bind(SmiToFloat64(search_element)); + Goto(¬_nan_loop); - assembler.Bind(&search_notnan); - assembler.GotoIfNot( - assembler.IsHeapNumberMap(assembler.LoadMap(search_element)), - &return_not_found); + Bind(&search_notnan); + GotoIfNot(IsHeapNumber(search_element), &return_not_found); - search_num.Bind(assembler.LoadHeapNumberValue(search_element)); + search_num.Bind(LoadHeapNumberValue(search_element)); - assembler.BranchIfFloat64IsNaN(search_num.value(), &return_not_found, - ¬_nan_loop); + BranchIfFloat64IsNaN(search_num.value(), &return_not_found, ¬_nan_loop); // Search for HeapNumber - assembler.Bind(¬_nan_loop); + Bind(¬_nan_loop); { - Label continue_loop(&assembler); - assembler.GotoIfNot( - assembler.UintPtrLessThan(index_var.value(), len_var.value()), - &return_not_found); + Label continue_loop(this); + GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()), + &return_not_found); // Load double value or continue if it contains a double hole. - Node* element_k = assembler.LoadFixedDoubleArrayElement( + Node* element_k = LoadFixedDoubleArrayElement( elements, index_var.value(), MachineType::Float64(), 0, - CodeStubAssembler::INTPTR_PARAMETERS, &continue_loop); + INTPTR_PARAMETERS, &continue_loop); - assembler.Branch(assembler.Float64Equal(element_k, search_num.value()), - &return_found, &continue_loop); - assembler.Bind(&continue_loop); - index_var.Bind(assembler.IntPtrAdd(index_var.value(), intptr_one)); - assembler.Goto(¬_nan_loop); + Branch(Float64Equal(element_k, search_num.value()), &return_found, + &continue_loop); + Bind(&continue_loop); + index_var.Bind(IntPtrAdd(index_var.value(), intptr_one)); + Goto(¬_nan_loop); } } - assembler.Bind(&return_found); - assembler.Return(assembler.SmiTag(index_var.value())); + Bind(&return_found); + Return(SmiTag(index_var.value())); - assembler.Bind(&return_not_found); - assembler.Return(assembler.NumberConstant(-1)); + Bind(&return_not_found); + Return(NumberConstant(-1)); - assembler.Bind(&call_runtime); - assembler.Return(assembler.CallRuntime(Runtime::kArrayIndexOf, context, array, - search_element, start_from)); + Bind(&call_runtime); + Return(CallRuntime(Runtime::kArrayIndexOf, context, array, search_element, + start_from)); } -namespace { - -template -void Generate_ArrayPrototypeIterationMethod( - compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef CodeStubAssembler::Label Label; - typedef CodeStubAssembler::Variable Variable; - CodeStubAssembler assembler(state); +class ArrayPrototypeIterationAssembler : public CodeStubAssembler { + public: + explicit ArrayPrototypeIterationAssembler(compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} - Node* receiver = assembler.Parameter(0); - Node* context = assembler.Parameter(3); + protected: + void Generate_ArrayPrototypeIterationMethod(IterationKind iteration_kind) { + Node* receiver = Parameter(0); + Node* context = Parameter(3); - Variable var_array(&assembler, MachineRepresentation::kTagged); - Variable var_map(&assembler, MachineRepresentation::kTagged); - Variable var_type(&assembler, MachineRepresentation::kWord32); + Variable var_array(this, MachineRepresentation::kTagged); + Variable var_map(this, MachineRepresentation::kTagged); + Variable var_type(this, MachineRepresentation::kWord32); - Label if_isnotobject(&assembler, Label::kDeferred); - Label create_array_iterator(&assembler); + Label if_isnotobject(this, Label::kDeferred); + Label create_array_iterator(this); - assembler.GotoIf(assembler.TaggedIsSmi(receiver), &if_isnotobject); - var_array.Bind(receiver); - var_map.Bind(assembler.LoadMap(receiver)); - var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); - assembler.Branch(assembler.IsJSReceiverInstanceType(var_type.value()), - &create_array_iterator, &if_isnotobject); + GotoIf(TaggedIsSmi(receiver), &if_isnotobject); + var_array.Bind(receiver); + var_map.Bind(LoadMap(receiver)); + var_type.Bind(LoadMapInstanceType(var_map.value())); + Branch(IsJSReceiverInstanceType(var_type.value()), &create_array_iterator, + &if_isnotobject); - assembler.Bind(&if_isnotobject); - { - Callable callable = CodeFactory::ToObject(assembler.isolate()); - Node* result = assembler.CallStub(callable, context, receiver); - var_array.Bind(result); - var_map.Bind(assembler.LoadMap(result)); - var_type.Bind(assembler.LoadMapInstanceType(var_map.value())); - assembler.Goto(&create_array_iterator); - } - - assembler.Bind(&create_array_iterator); - assembler.Return( - assembler.CreateArrayIterator(var_array.value(), var_map.value(), - var_type.value(), context, kIterationKind)); -} + Bind(&if_isnotobject); + { + Callable callable = CodeFactory::ToObject(isolate()); + Node* result = CallStub(callable, context, receiver); + var_array.Bind(result); + var_map.Bind(LoadMap(result)); + var_type.Bind(LoadMapInstanceType(var_map.value())); + Goto(&create_array_iterator); + } -} // namespace + Bind(&create_array_iterator); + Return(CreateArrayIterator(var_array.value(), var_map.value(), + var_type.value(), context, iteration_kind)); + } +}; -void Builtins::Generate_ArrayPrototypeValues( - compiler::CodeAssemblerState* state) { - Generate_ArrayPrototypeIterationMethod(state); +TF_BUILTIN(ArrayPrototypeValues, ArrayPrototypeIterationAssembler) { + Generate_ArrayPrototypeIterationMethod(IterationKind::kValues); } -void Builtins::Generate_ArrayPrototypeEntries( - compiler::CodeAssemblerState* state) { - Generate_ArrayPrototypeIterationMethod(state); +TF_BUILTIN(ArrayPrototypeEntries, ArrayPrototypeIterationAssembler) { + Generate_ArrayPrototypeIterationMethod(IterationKind::kEntries); } -void Builtins::Generate_ArrayPrototypeKeys( - compiler::CodeAssemblerState* state) { - Generate_ArrayPrototypeIterationMethod(state); +TF_BUILTIN(ArrayPrototypeKeys, ArrayPrototypeIterationAssembler) { + Generate_ArrayPrototypeIterationMethod(IterationKind::kKeys); } -void Builtins::Generate_ArrayIteratorPrototypeNext( - compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef CodeStubAssembler::Label Label; - typedef CodeStubAssembler::Variable Variable; - CodeStubAssembler assembler(state); - - Handle operation = assembler.factory()->NewStringFromAsciiChecked( +TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) { + Handle operation = factory()->NewStringFromAsciiChecked( "Array Iterator.prototype.next", TENURED); - Node* iterator = assembler.Parameter(0); - Node* context = assembler.Parameter(3); + Node* iterator = Parameter(0); + Node* context = Parameter(3); - Variable var_value(&assembler, MachineRepresentation::kTagged); - Variable var_done(&assembler, MachineRepresentation::kTagged); + Variable var_value(this, MachineRepresentation::kTagged); + Variable var_done(this, MachineRepresentation::kTagged); // Required, or else `throw_bad_receiver` fails a DCHECK due to these // variables not being bound along all paths, despite not being used. - var_done.Bind(assembler.TrueConstant()); - var_value.Bind(assembler.UndefinedConstant()); + var_done.Bind(TrueConstant()); + var_value.Bind(UndefinedConstant()); - Label throw_bad_receiver(&assembler, Label::kDeferred); - Label set_done(&assembler); - Label allocate_key_result(&assembler); - Label allocate_entry_if_needed(&assembler); - Label allocate_iterator_result(&assembler); - Label generic_values(&assembler); + Label throw_bad_receiver(this, Label::kDeferred); + Label set_done(this); + Label allocate_key_result(this); + Label allocate_entry_if_needed(this); + Label allocate_iterator_result(this); + Label generic_values(this); // If O does not have all of the internal slots of an Array Iterator Instance // (22.1.5.3), throw a TypeError exception - assembler.GotoIf(assembler.TaggedIsSmi(iterator), &throw_bad_receiver); - Node* instance_type = assembler.LoadInstanceType(iterator); - assembler.GotoIf( - assembler.Uint32LessThan( - assembler.Int32Constant(LAST_ARRAY_ITERATOR_TYPE - - FIRST_ARRAY_ITERATOR_TYPE), - assembler.Int32Sub(instance_type, assembler.Int32Constant( - FIRST_ARRAY_ITERATOR_TYPE))), + GotoIf(TaggedIsSmi(iterator), &throw_bad_receiver); + Node* instance_type = LoadInstanceType(iterator); + GotoIf( + Uint32LessThan( + Int32Constant(LAST_ARRAY_ITERATOR_TYPE - FIRST_ARRAY_ITERATOR_TYPE), + Int32Sub(instance_type, Int32Constant(FIRST_ARRAY_ITERATOR_TYPE))), &throw_bad_receiver); // Let a be O.[[IteratedObject]]. - Node* array = assembler.LoadObjectField( - iterator, JSArrayIterator::kIteratedObjectOffset); + Node* array = + LoadObjectField(iterator, JSArrayIterator::kIteratedObjectOffset); // Let index be O.[[ArrayIteratorNextIndex]]. - Node* index = - assembler.LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); - Node* orig_map = assembler.LoadObjectField( - iterator, JSArrayIterator::kIteratedObjectMapOffset); - Node* array_map = assembler.LoadMap(array); + Node* index = LoadObjectField(iterator, JSArrayIterator::kNextIndexOffset); + Node* orig_map = + LoadObjectField(iterator, JSArrayIterator::kIteratedObjectMapOffset); + Node* array_map = LoadMap(array); - Label if_isfastarray(&assembler), if_isnotfastarray(&assembler), - if_isdetached(&assembler, Label::kDeferred); + Label if_isfastarray(this), if_isnotfastarray(this), + if_isdetached(this, Label::kDeferred); - assembler.Branch(assembler.WordEqual(orig_map, array_map), &if_isfastarray, - &if_isnotfastarray); + Branch(WordEqual(orig_map, array_map), &if_isfastarray, &if_isnotfastarray); - assembler.Bind(&if_isfastarray); + Bind(&if_isfastarray); { - CSA_ASSERT(&assembler, - assembler.Word32Equal(assembler.LoadMapInstanceType(array_map), - assembler.Int32Constant(JS_ARRAY_TYPE))); + CSA_ASSERT(this, Word32Equal(LoadMapInstanceType(array_map), + Int32Constant(JS_ARRAY_TYPE))); - Node* length = assembler.LoadObjectField(array, JSArray::kLengthOffset); + Node* length = LoadObjectField(array, JSArray::kLengthOffset); - CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); - CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); + CSA_ASSERT(this, TaggedIsSmi(length)); + CSA_ASSERT(this, TaggedIsSmi(index)); - assembler.GotoIfNot(assembler.SmiBelow(index, length), &set_done); + GotoIfNot(SmiBelow(index, length), &set_done); - Node* one = assembler.SmiConstant(Smi::FromInt(1)); - assembler.StoreObjectFieldNoWriteBarrier(iterator, - JSArrayIterator::kNextIndexOffset, - assembler.SmiAdd(index, one)); + Node* one = SmiConstant(Smi::FromInt(1)); + StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset, + SmiAdd(index, one)); - var_done.Bind(assembler.FalseConstant()); - Node* elements = assembler.LoadElements(array); + var_done.Bind(FalseConstant()); + Node* elements = LoadElements(array); static int32_t kInstanceType[] = { JS_FAST_ARRAY_KEY_ITERATOR_TYPE, @@ -2455,8 +2348,8 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE, }; - Label packed_object_values(&assembler), holey_object_values(&assembler), - packed_double_values(&assembler), holey_double_values(&assembler); + Label packed_object_values(this), holey_object_values(this), + packed_double_values(this), holey_double_values(this); Label* kInstanceTypeHandlers[] = { &allocate_key_result, &packed_object_values, &holey_object_values, &packed_object_values, &holey_object_values, &packed_double_values, @@ -2464,192 +2357,164 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( &packed_object_values, &holey_object_values, &packed_double_values, &holey_double_values}; - assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, - kInstanceTypeHandlers, arraysize(kInstanceType)); + Switch(instance_type, &throw_bad_receiver, kInstanceType, + kInstanceTypeHandlers, arraysize(kInstanceType)); - assembler.Bind(&packed_object_values); + Bind(&packed_object_values); { - var_value.Bind(assembler.LoadFixedArrayElement( - elements, index, 0, CodeStubAssembler::SMI_PARAMETERS)); - assembler.Goto(&allocate_entry_if_needed); + var_value.Bind(LoadFixedArrayElement(elements, index, 0, SMI_PARAMETERS)); + Goto(&allocate_entry_if_needed); } - assembler.Bind(&packed_double_values); + Bind(&packed_double_values); { - Node* value = assembler.LoadFixedDoubleArrayElement( - elements, index, MachineType::Float64(), 0, - CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); - assembler.Goto(&allocate_entry_if_needed); + Node* value = LoadFixedDoubleArrayElement( + elements, index, MachineType::Float64(), 0, SMI_PARAMETERS); + var_value.Bind(AllocateHeapNumberWithValue(value)); + Goto(&allocate_entry_if_needed); } - assembler.Bind(&holey_object_values); + Bind(&holey_object_values); { // Check the array_protector cell, and take the slow path if it's invalid. - Node* invalid = - assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); - Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); - Node* cell_value = - assembler.LoadObjectField(cell, PropertyCell::kValueOffset); - assembler.GotoIf(assembler.WordEqual(cell_value, invalid), - &generic_values); - - var_value.Bind(assembler.UndefinedConstant()); - Node* value = assembler.LoadFixedArrayElement( - elements, index, 0, CodeStubAssembler::SMI_PARAMETERS); - assembler.GotoIf(assembler.WordEqual(value, assembler.TheHoleConstant()), - &allocate_entry_if_needed); + Node* invalid = SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); + Node* cell = LoadRoot(Heap::kArrayProtectorRootIndex); + Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); + GotoIf(WordEqual(cell_value, invalid), &generic_values); + + var_value.Bind(UndefinedConstant()); + Node* value = LoadFixedArrayElement(elements, index, 0, SMI_PARAMETERS); + GotoIf(WordEqual(value, TheHoleConstant()), &allocate_entry_if_needed); var_value.Bind(value); - assembler.Goto(&allocate_entry_if_needed); + Goto(&allocate_entry_if_needed); } - assembler.Bind(&holey_double_values); + Bind(&holey_double_values); { // Check the array_protector cell, and take the slow path if it's invalid. - Node* invalid = - assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); - Node* cell = assembler.LoadRoot(Heap::kArrayProtectorRootIndex); - Node* cell_value = - assembler.LoadObjectField(cell, PropertyCell::kValueOffset); - assembler.GotoIf(assembler.WordEqual(cell_value, invalid), - &generic_values); - - var_value.Bind(assembler.UndefinedConstant()); - Node* value = assembler.LoadFixedDoubleArrayElement( - elements, index, MachineType::Float64(), 0, - CodeStubAssembler::SMI_PARAMETERS, &allocate_entry_if_needed); - var_value.Bind(assembler.AllocateHeapNumberWithValue(value)); - assembler.Goto(&allocate_entry_if_needed); + Node* invalid = SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); + Node* cell = LoadRoot(Heap::kArrayProtectorRootIndex); + Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset); + GotoIf(WordEqual(cell_value, invalid), &generic_values); + + var_value.Bind(UndefinedConstant()); + Node* value = LoadFixedDoubleArrayElement( + elements, index, MachineType::Float64(), 0, SMI_PARAMETERS, + &allocate_entry_if_needed); + var_value.Bind(AllocateHeapNumberWithValue(value)); + Goto(&allocate_entry_if_needed); } } - assembler.Bind(&if_isnotfastarray); + Bind(&if_isnotfastarray); { - Label if_istypedarray(&assembler), if_isgeneric(&assembler); + Label if_istypedarray(this), if_isgeneric(this); // If a is undefined, return CreateIterResultObject(undefined, true) - assembler.GotoIf(assembler.WordEqual(array, assembler.UndefinedConstant()), - &allocate_iterator_result); + GotoIf(WordEqual(array, UndefinedConstant()), &allocate_iterator_result); - Node* array_type = assembler.LoadInstanceType(array); - assembler.Branch( - assembler.Word32Equal(array_type, - assembler.Int32Constant(JS_TYPED_ARRAY_TYPE)), - &if_istypedarray, &if_isgeneric); + Node* array_type = LoadInstanceType(array); + Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), + &if_istypedarray, &if_isgeneric); - assembler.Bind(&if_isgeneric); + Bind(&if_isgeneric); { - Label if_wasfastarray(&assembler); + Label if_wasfastarray(this); Node* length = nullptr; { - Variable var_length(&assembler, MachineRepresentation::kTagged); - Label if_isarray(&assembler), if_isnotarray(&assembler), - done(&assembler); - assembler.Branch( - assembler.Word32Equal(array_type, - assembler.Int32Constant(JS_ARRAY_TYPE)), - &if_isarray, &if_isnotarray); - - assembler.Bind(&if_isarray); + Variable var_length(this, MachineRepresentation::kTagged); + Label if_isarray(this), if_isnotarray(this), done(this); + Branch(Word32Equal(array_type, Int32Constant(JS_ARRAY_TYPE)), + &if_isarray, &if_isnotarray); + + Bind(&if_isarray); { - var_length.Bind( - assembler.LoadObjectField(array, JSArray::kLengthOffset)); + var_length.Bind(LoadObjectField(array, JSArray::kLengthOffset)); // Invalidate protector cell if needed - assembler.Branch( - assembler.WordNotEqual(orig_map, assembler.UndefinedConstant()), - &if_wasfastarray, &done); + Branch(WordNotEqual(orig_map, UndefinedConstant()), &if_wasfastarray, + &done); - assembler.Bind(&if_wasfastarray); + Bind(&if_wasfastarray); { - Label if_invalid(&assembler, Label::kDeferred); + Label if_invalid(this, Label::kDeferred); // A fast array iterator transitioned to a slow iterator during // iteration. Invalidate fast_array_iteration_prtoector cell to // prevent potential deopt loops. - assembler.StoreObjectFieldNoWriteBarrier( + StoreObjectFieldNoWriteBarrier( iterator, JSArrayIterator::kIteratedObjectMapOffset, - assembler.UndefinedConstant()); - assembler.GotoIf( - assembler.Uint32LessThanOrEqual( - instance_type, assembler.Int32Constant( - JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), - &done); + UndefinedConstant()); + GotoIf(Uint32LessThanOrEqual( + instance_type, + Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), + &done); Node* invalid = - assembler.SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); - Node* cell = - assembler.LoadRoot(Heap::kFastArrayIterationProtectorRootIndex); - assembler.StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, - invalid); - assembler.Goto(&done); + SmiConstant(Smi::FromInt(Isolate::kProtectorInvalid)); + Node* cell = LoadRoot(Heap::kFastArrayIterationProtectorRootIndex); + StoreObjectFieldNoWriteBarrier(cell, Cell::kValueOffset, invalid); + Goto(&done); } } - assembler.Bind(&if_isnotarray); + Bind(&if_isnotarray); { - Node* length_string = assembler.HeapConstant( - assembler.isolate()->factory()->length_string()); - Callable get_property = CodeFactory::GetProperty(assembler.isolate()); - Node* length = - assembler.CallStub(get_property, context, array, length_string); - Callable to_length = CodeFactory::ToLength(assembler.isolate()); - var_length.Bind(assembler.CallStub(to_length, context, length)); - assembler.Goto(&done); + Node* length_string = HeapConstant(factory()->length_string()); + Callable get_property = CodeFactory::GetProperty(isolate()); + Node* length = CallStub(get_property, context, array, length_string); + Callable to_length = CodeFactory::ToLength(isolate()); + var_length.Bind(CallStub(to_length, context, length)); + Goto(&done); } - assembler.Bind(&done); + Bind(&done); length = var_length.value(); } - assembler.GotoUnlessNumberLessThan(index, length, &set_done); + GotoUnlessNumberLessThan(index, length, &set_done); - assembler.StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, - assembler.NumberInc(index)); - var_done.Bind(assembler.FalseConstant()); + StoreObjectField(iterator, JSArrayIterator::kNextIndexOffset, + NumberInc(index)); + var_done.Bind(FalseConstant()); - assembler.Branch( - assembler.Uint32LessThanOrEqual( - instance_type, - assembler.Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), + Branch( + Uint32LessThanOrEqual( + instance_type, Int32Constant(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE)), &allocate_key_result, &generic_values); - assembler.Bind(&generic_values); + Bind(&generic_values); { - Callable get_property = CodeFactory::GetProperty(assembler.isolate()); - var_value.Bind(assembler.CallStub(get_property, context, array, index)); - assembler.Goto(&allocate_entry_if_needed); + Callable get_property = CodeFactory::GetProperty(isolate()); + var_value.Bind(CallStub(get_property, context, array, index)); + Goto(&allocate_entry_if_needed); } } - assembler.Bind(&if_istypedarray); + Bind(&if_istypedarray); { - Node* buffer = - assembler.LoadObjectField(array, JSTypedArray::kBufferOffset); - assembler.GotoIf(assembler.IsDetachedBuffer(buffer), &if_isdetached); + Node* buffer = LoadObjectField(array, JSTypedArray::kBufferOffset); + GotoIf(IsDetachedBuffer(buffer), &if_isdetached); - Node* length = - assembler.LoadObjectField(array, JSTypedArray::kLengthOffset); + Node* length = LoadObjectField(array, JSTypedArray::kLengthOffset); - CSA_ASSERT(&assembler, assembler.TaggedIsSmi(length)); - CSA_ASSERT(&assembler, assembler.TaggedIsSmi(index)); + CSA_ASSERT(this, TaggedIsSmi(length)); + CSA_ASSERT(this, TaggedIsSmi(index)); - assembler.GotoIfNot(assembler.SmiBelow(index, length), &set_done); + GotoIfNot(SmiBelow(index, length), &set_done); - Node* one = assembler.SmiConstant(1); - assembler.StoreObjectFieldNoWriteBarrier( - iterator, JSArrayIterator::kNextIndexOffset, - assembler.SmiAdd(index, one)); - var_done.Bind(assembler.FalseConstant()); + Node* one = SmiConstant(1); + StoreObjectFieldNoWriteBarrier( + iterator, JSArrayIterator::kNextIndexOffset, SmiAdd(index, one)); + var_done.Bind(FalseConstant()); - Node* elements = assembler.LoadElements(array); - Node* base_ptr = assembler.LoadObjectField( - elements, FixedTypedArrayBase::kBasePointerOffset); - Node* external_ptr = assembler.LoadObjectField( - elements, FixedTypedArrayBase::kExternalPointerOffset, - MachineType::Pointer()); - Node* data_ptr = assembler.IntPtrAdd( - assembler.BitcastTaggedToWord(base_ptr), external_ptr); + Node* elements = LoadElements(array); + Node* base_ptr = + LoadObjectField(elements, FixedTypedArrayBase::kBasePointerOffset); + Node* external_ptr = + LoadObjectField(elements, FixedTypedArrayBase::kExternalPointerOffset, + MachineType::Pointer()); + Node* data_ptr = IntPtrAdd(BitcastTaggedToWord(base_ptr), external_ptr); static int32_t kInstanceType[] = { JS_TYPED_ARRAY_KEY_ITERATOR_TYPE, @@ -2673,10 +2538,9 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE, }; - Label uint8_values(&assembler), int8_values(&assembler), - uint16_values(&assembler), int16_values(&assembler), - uint32_values(&assembler), int32_values(&assembler), - float32_values(&assembler), float64_values(&assembler); + Label uint8_values(this), int8_values(this), uint16_values(this), + int16_values(this), uint32_values(this), int32_values(this), + float32_values(this), float64_values(this); Label* kInstanceTypeHandlers[] = { &allocate_key_result, &uint8_values, &uint8_values, &int8_values, &uint16_values, &int16_values, @@ -2687,156 +2551,140 @@ void Builtins::Generate_ArrayIteratorPrototypeNext( &float64_values, }; - var_done.Bind(assembler.FalseConstant()); - assembler.Switch(instance_type, &throw_bad_receiver, kInstanceType, - kInstanceTypeHandlers, arraysize(kInstanceType)); + var_done.Bind(FalseConstant()); + Switch(instance_type, &throw_bad_receiver, kInstanceType, + kInstanceTypeHandlers, arraysize(kInstanceType)); - assembler.Bind(&uint8_values); + Bind(&uint8_values); { - Node* value_uint8 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, UINT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.SmiFromWord32(value_uint8)); - assembler.Goto(&allocate_entry_if_needed); + Node* value_uint8 = LoadFixedTypedArrayElement( + data_ptr, index, UINT8_ELEMENTS, SMI_PARAMETERS); + var_value.Bind(SmiFromWord32(value_uint8)); + Goto(&allocate_entry_if_needed); } - - assembler.Bind(&int8_values); + Bind(&int8_values); { - Node* value_int8 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, INT8_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.SmiFromWord32(value_int8)); - assembler.Goto(&allocate_entry_if_needed); + Node* value_int8 = LoadFixedTypedArrayElement( + data_ptr, index, INT8_ELEMENTS, SMI_PARAMETERS); + var_value.Bind(SmiFromWord32(value_int8)); + Goto(&allocate_entry_if_needed); } - - assembler.Bind(&uint16_values); + Bind(&uint16_values); { - Node* value_uint16 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, UINT16_ELEMENTS, - CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.SmiFromWord32(value_uint16)); - assembler.Goto(&allocate_entry_if_needed); + Node* value_uint16 = LoadFixedTypedArrayElement( + data_ptr, index, UINT16_ELEMENTS, SMI_PARAMETERS); + var_value.Bind(SmiFromWord32(value_uint16)); + Goto(&allocate_entry_if_needed); } - - assembler.Bind(&int16_values); + Bind(&int16_values); { - Node* value_int16 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, INT16_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.SmiFromWord32(value_int16)); - assembler.Goto(&allocate_entry_if_needed); + Node* value_int16 = LoadFixedTypedArrayElement( + data_ptr, index, INT16_ELEMENTS, SMI_PARAMETERS); + var_value.Bind(SmiFromWord32(value_int16)); + Goto(&allocate_entry_if_needed); } - - assembler.Bind(&uint32_values); + Bind(&uint32_values); { - Node* value_uint32 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, UINT32_ELEMENTS, - CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.ChangeUint32ToTagged(value_uint32)); - assembler.Goto(&allocate_entry_if_needed); + Node* value_uint32 = LoadFixedTypedArrayElement( + data_ptr, index, UINT32_ELEMENTS, SMI_PARAMETERS); + var_value.Bind(ChangeUint32ToTagged(value_uint32)); + Goto(&allocate_entry_if_needed); } - assembler.Bind(&int32_values); + Bind(&int32_values); { - Node* value_int32 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, INT32_ELEMENTS, CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.ChangeInt32ToTagged(value_int32)); - assembler.Goto(&allocate_entry_if_needed); + Node* value_int32 = LoadFixedTypedArrayElement( + data_ptr, index, INT32_ELEMENTS, SMI_PARAMETERS); + var_value.Bind(ChangeInt32ToTagged(value_int32)); + Goto(&allocate_entry_if_needed); } - assembler.Bind(&float32_values); + Bind(&float32_values); { - Node* value_float32 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, FLOAT32_ELEMENTS, - CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.AllocateHeapNumberWithValue( - assembler.ChangeFloat32ToFloat64(value_float32))); - assembler.Goto(&allocate_entry_if_needed); + Node* value_float32 = LoadFixedTypedArrayElement( + data_ptr, index, FLOAT32_ELEMENTS, SMI_PARAMETERS); + var_value.Bind( + AllocateHeapNumberWithValue(ChangeFloat32ToFloat64(value_float32))); + Goto(&allocate_entry_if_needed); } - assembler.Bind(&float64_values); + Bind(&float64_values); { - Node* value_float64 = assembler.LoadFixedTypedArrayElement( - data_ptr, index, FLOAT64_ELEMENTS, - CodeStubAssembler::SMI_PARAMETERS); - var_value.Bind(assembler.AllocateHeapNumberWithValue(value_float64)); - assembler.Goto(&allocate_entry_if_needed); + Node* value_float64 = LoadFixedTypedArrayElement( + data_ptr, index, FLOAT64_ELEMENTS, SMI_PARAMETERS); + var_value.Bind(AllocateHeapNumberWithValue(value_float64)); + Goto(&allocate_entry_if_needed); } } } - assembler.Bind(&set_done); + Bind(&set_done); { - assembler.StoreObjectFieldNoWriteBarrier( - iterator, JSArrayIterator::kIteratedObjectOffset, - assembler.UndefinedConstant()); - assembler.Goto(&allocate_iterator_result); + StoreObjectFieldNoWriteBarrier( + iterator, JSArrayIterator::kIteratedObjectOffset, UndefinedConstant()); + Goto(&allocate_iterator_result); } - assembler.Bind(&allocate_key_result); + Bind(&allocate_key_result); { var_value.Bind(index); - var_done.Bind(assembler.FalseConstant()); - assembler.Goto(&allocate_iterator_result); + var_done.Bind(FalseConstant()); + Goto(&allocate_iterator_result); } - assembler.Bind(&allocate_entry_if_needed); + Bind(&allocate_entry_if_needed); { - assembler.GotoIf( - assembler.Int32GreaterThan( - instance_type, - assembler.Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), - &allocate_iterator_result); - - Node* elements = assembler.AllocateFixedArray(FAST_ELEMENTS, - assembler.IntPtrConstant(2)); - assembler.StoreFixedArrayElement(elements, 0, index, SKIP_WRITE_BARRIER); - assembler.StoreFixedArrayElement(elements, 1, var_value.value(), - SKIP_WRITE_BARRIER); - - Node* entry = assembler.Allocate(JSArray::kSize); - Node* map = - assembler.LoadContextElement(assembler.LoadNativeContext(context), - Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); - - assembler.StoreMapNoWriteBarrier(entry, map); - assembler.StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler.StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, - elements); - assembler.StoreObjectFieldNoWriteBarrier( - entry, JSArray::kLengthOffset, assembler.SmiConstant(Smi::FromInt(2))); + GotoIf(Int32GreaterThan(instance_type, + Int32Constant(LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE)), + &allocate_iterator_result); + + Node* elements = AllocateFixedArray(FAST_ELEMENTS, IntPtrConstant(2)); + StoreFixedArrayElement(elements, 0, index, SKIP_WRITE_BARRIER); + StoreFixedArrayElement(elements, 1, var_value.value(), SKIP_WRITE_BARRIER); + + Node* entry = Allocate(JSArray::kSize); + Node* map = LoadContextElement(LoadNativeContext(context), + Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX); + + StoreMapNoWriteBarrier(entry, map); + StoreObjectFieldRoot(entry, JSArray::kPropertiesOffset, + Heap::kEmptyFixedArrayRootIndex); + StoreObjectFieldNoWriteBarrier(entry, JSArray::kElementsOffset, elements); + StoreObjectFieldNoWriteBarrier(entry, JSArray::kLengthOffset, + SmiConstant(Smi::FromInt(2))); var_value.Bind(entry); - assembler.Goto(&allocate_iterator_result); + Goto(&allocate_iterator_result); } - assembler.Bind(&allocate_iterator_result); + Bind(&allocate_iterator_result); { - Node* result = assembler.Allocate(JSIteratorResult::kSize); - Node* map = - assembler.LoadContextElement(assembler.LoadNativeContext(context), - Context::ITERATOR_RESULT_MAP_INDEX); - assembler.StoreMapNoWriteBarrier(result, map); - assembler.StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler.StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler.StoreObjectFieldNoWriteBarrier( - result, JSIteratorResult::kValueOffset, var_value.value()); - assembler.StoreObjectFieldNoWriteBarrier( - result, JSIteratorResult::kDoneOffset, var_done.value()); - assembler.Return(result); - } - - assembler.Bind(&throw_bad_receiver); + Node* result = Allocate(JSIteratorResult::kSize); + Node* map = LoadContextElement(LoadNativeContext(context), + Context::ITERATOR_RESULT_MAP_INDEX); + StoreMapNoWriteBarrier(result, map); + StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset, + Heap::kEmptyFixedArrayRootIndex); + StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset, + Heap::kEmptyFixedArrayRootIndex); + StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset, + var_value.value()); + StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset, + var_done.value()); + Return(result); + } + + Bind(&throw_bad_receiver); { // The {receiver} is not a valid JSArrayIterator. - assembler.CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, - assembler.HeapConstant(operation), iterator); - assembler.Unreachable(); + CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, + HeapConstant(operation), iterator); + Unreachable(); } - assembler.Bind(&if_isdetached); + Bind(&if_isdetached); { - Node* message = assembler.SmiConstant(MessageTemplate::kDetachedOperation); - assembler.CallRuntime(Runtime::kThrowTypeError, context, message, - assembler.HeapConstant(operation)); - assembler.Unreachable(); + Node* message = SmiConstant(MessageTemplate::kDetachedOperation); + CallRuntime(Runtime::kThrowTypeError, context, message, + HeapConstant(operation)); + Unreachable(); } } diff --git a/deps/v8/src/builtins/builtins-conversion.cc b/deps/v8/src/builtins/builtins-conversion.cc index 2aff1c5f070dfa..37da457d382588 100644 --- a/deps/v8/src/builtins/builtins-conversion.cc +++ b/deps/v8/src/builtins/builtins-conversion.cc @@ -11,6 +11,17 @@ namespace v8 { namespace internal { +class ConversionBuiltinsAssembler : public CodeStubAssembler { + public: + explicit ConversionBuiltinsAssembler(compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} + + protected: + void Generate_NonPrimitiveToPrimitive(ToPrimitiveHint hint); + + void Generate_OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint); +}; + Handle Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) { switch (hint) { case ToPrimitiveHint::kDefault: @@ -24,192 +35,140 @@ Handle Builtins::NonPrimitiveToPrimitive(ToPrimitiveHint hint) { return Handle::null(); } -namespace { - // ES6 section 7.1.1 ToPrimitive ( input [ , PreferredType ] ) -void Generate_NonPrimitiveToPrimitive(CodeStubAssembler* assembler, - ToPrimitiveHint hint) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - typedef TypeConversionDescriptor Descriptor; - - Node* input = assembler->Parameter(Descriptor::kArgument); - Node* context = assembler->Parameter(Descriptor::kContext); +void ConversionBuiltinsAssembler::Generate_NonPrimitiveToPrimitive( + ToPrimitiveHint hint) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); // Lookup the @@toPrimitive property on the {input}. - Callable callable = CodeFactory::GetProperty(assembler->isolate()); - Node* to_primitive_symbol = - assembler->HeapConstant(assembler->factory()->to_primitive_symbol()); + Callable callable = CodeFactory::GetProperty(isolate()); + Node* to_primitive_symbol = HeapConstant(factory()->to_primitive_symbol()); Node* exotic_to_prim = - assembler->CallStub(callable, context, input, to_primitive_symbol); + CallStub(callable, context, input, to_primitive_symbol); // Check if {exotic_to_prim} is neither null nor undefined. - Label ordinary_to_primitive(assembler); - assembler->GotoIf( - assembler->WordEqual(exotic_to_prim, assembler->NullConstant()), - &ordinary_to_primitive); - assembler->GotoIf( - assembler->WordEqual(exotic_to_prim, assembler->UndefinedConstant()), - &ordinary_to_primitive); + Label ordinary_to_primitive(this); + GotoIf(WordEqual(exotic_to_prim, NullConstant()), &ordinary_to_primitive); + GotoIf(WordEqual(exotic_to_prim, UndefinedConstant()), + &ordinary_to_primitive); { // Invoke the {exotic_to_prim} method on the {input} with a string // representation of the {hint}. - Callable callable = CodeFactory::Call( - assembler->isolate(), ConvertReceiverMode::kNotNullOrUndefined); - Node* hint_string = assembler->HeapConstant( - assembler->factory()->ToPrimitiveHintString(hint)); - Node* result = assembler->CallJS(callable, context, exotic_to_prim, input, - hint_string); + Callable callable = + CodeFactory::Call(isolate(), ConvertReceiverMode::kNotNullOrUndefined); + Node* hint_string = HeapConstant(factory()->ToPrimitiveHintString(hint)); + Node* result = + CallJS(callable, context, exotic_to_prim, input, hint_string); // Verify that the {result} is actually a primitive. - Label if_resultisprimitive(assembler), - if_resultisnotprimitive(assembler, Label::kDeferred); - assembler->GotoIf(assembler->TaggedIsSmi(result), &if_resultisprimitive); - Node* result_instance_type = assembler->LoadInstanceType(result); + Label if_resultisprimitive(this), + if_resultisnotprimitive(this, Label::kDeferred); + GotoIf(TaggedIsSmi(result), &if_resultisprimitive); + Node* result_instance_type = LoadInstanceType(result); STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); - assembler->Branch(assembler->Int32LessThanOrEqual( - result_instance_type, - assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), - &if_resultisprimitive, &if_resultisnotprimitive); + Branch(Int32LessThanOrEqual(result_instance_type, + Int32Constant(LAST_PRIMITIVE_TYPE)), + &if_resultisprimitive, &if_resultisnotprimitive); - assembler->Bind(&if_resultisprimitive); + Bind(&if_resultisprimitive); { // Just return the {result}. - assembler->Return(result); + Return(result); } - assembler->Bind(&if_resultisnotprimitive); + Bind(&if_resultisnotprimitive); { // Somehow the @@toPrimitive method on {input} didn't yield a primitive. - assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, - context); + TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context); } } // Convert using the OrdinaryToPrimitive algorithm instead. - assembler->Bind(&ordinary_to_primitive); + Bind(&ordinary_to_primitive); { Callable callable = CodeFactory::OrdinaryToPrimitive( - assembler->isolate(), (hint == ToPrimitiveHint::kString) - ? OrdinaryToPrimitiveHint::kString - : OrdinaryToPrimitiveHint::kNumber); - assembler->TailCallStub(callable, context, input); + isolate(), (hint == ToPrimitiveHint::kString) + ? OrdinaryToPrimitiveHint::kString + : OrdinaryToPrimitiveHint::kNumber); + TailCallStub(callable, context, input); } } -} // namespace - -void Builtins::Generate_NonPrimitiveToPrimitive_Default( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_NonPrimitiveToPrimitive(&assembler, ToPrimitiveHint::kDefault); +TF_BUILTIN(NonPrimitiveToPrimitive_Default, ConversionBuiltinsAssembler) { + Generate_NonPrimitiveToPrimitive(ToPrimitiveHint::kDefault); } -void Builtins::Generate_NonPrimitiveToPrimitive_Number( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_NonPrimitiveToPrimitive(&assembler, ToPrimitiveHint::kNumber); +TF_BUILTIN(NonPrimitiveToPrimitive_Number, ConversionBuiltinsAssembler) { + Generate_NonPrimitiveToPrimitive(ToPrimitiveHint::kNumber); } -void Builtins::Generate_NonPrimitiveToPrimitive_String( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_NonPrimitiveToPrimitive(&assembler, ToPrimitiveHint::kString); +TF_BUILTIN(NonPrimitiveToPrimitive_String, ConversionBuiltinsAssembler) { + Generate_NonPrimitiveToPrimitive(ToPrimitiveHint::kString); } -void Builtins::Generate_StringToNumber(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); +TF_BUILTIN(StringToNumber, CodeStubAssembler) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - Node* input = assembler.Parameter(Descriptor::kArgument); - Node* context = assembler.Parameter(Descriptor::kContext); - - assembler.Return(assembler.StringToNumber(context, input)); + Return(StringToNumber(context, input)); } -void Builtins::Generate_ToName(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); - - Node* input = assembler.Parameter(Descriptor::kArgument); - Node* context = assembler.Parameter(Descriptor::kContext); +TF_BUILTIN(ToName, CodeStubAssembler) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - assembler.Return(assembler.ToName(context, input)); + Return(ToName(context, input)); } -// static -void Builtins::Generate_NonNumberToNumber(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); - - Node* input = assembler.Parameter(Descriptor::kArgument); - Node* context = assembler.Parameter(Descriptor::kContext); +TF_BUILTIN(NonNumberToNumber, CodeStubAssembler) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - assembler.Return(assembler.NonNumberToNumber(context, input)); + Return(NonNumberToNumber(context, input)); } // ES6 section 7.1.3 ToNumber ( argument ) -void Builtins::Generate_ToNumber(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); +TF_BUILTIN(ToNumber, CodeStubAssembler) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - Node* input = assembler.Parameter(Descriptor::kArgument); - Node* context = assembler.Parameter(Descriptor::kContext); - - assembler.Return(assembler.ToNumber(context, input)); + Return(ToNumber(context, input)); } -void Builtins::Generate_ToString(compiler::CodeAssemblerState* state) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); - - Node* input = assembler.Parameter(Descriptor::kArgument); - Node* context = assembler.Parameter(Descriptor::kContext); +TF_BUILTIN(ToString, CodeStubAssembler) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - Label is_number(&assembler); - Label runtime(&assembler); + Label is_number(this); + Label runtime(this); - assembler.GotoIf(assembler.TaggedIsSmi(input), &is_number); + GotoIf(TaggedIsSmi(input), &is_number); - Node* input_map = assembler.LoadMap(input); - Node* input_instance_type = assembler.LoadMapInstanceType(input_map); + Node* input_map = LoadMap(input); + Node* input_instance_type = LoadMapInstanceType(input_map); - Label not_string(&assembler); - assembler.GotoIfNot(assembler.IsStringInstanceType(input_instance_type), - ¬_string); - assembler.Return(input); + Label not_string(this); + GotoIfNot(IsStringInstanceType(input_instance_type), ¬_string); + Return(input); - Label not_heap_number(&assembler); + Label not_heap_number(this); - assembler.Bind(¬_string); - { - assembler.GotoIfNot(assembler.IsHeapNumberMap(input_map), ¬_heap_number); - assembler.Goto(&is_number); - } + Bind(¬_string); + { Branch(IsHeapNumberMap(input_map), &is_number, ¬_heap_number); } - assembler.Bind(&is_number); - { assembler.Return(assembler.NumberToString(context, input)); } + Bind(&is_number); + { Return(NumberToString(context, input)); } - assembler.Bind(¬_heap_number); + Bind(¬_heap_number); { - assembler.GotoIf( - assembler.Word32NotEqual(input_instance_type, - assembler.Int32Constant(ODDBALL_TYPE)), - &runtime); - assembler.Return( - assembler.LoadObjectField(input, Oddball::kToStringOffset)); + GotoIf(Word32NotEqual(input_instance_type, Int32Constant(ODDBALL_TYPE)), + &runtime); + Return(LoadObjectField(input, Oddball::kToStringOffset)); } - assembler.Bind(&runtime); - { - assembler.Return(assembler.CallRuntime(Runtime::kToString, context, input)); - } + Bind(&runtime); + { Return(CallRuntime(Runtime::kToString, context, input)); } } Handle Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) { @@ -223,284 +182,233 @@ Handle Builtins::OrdinaryToPrimitive(OrdinaryToPrimitiveHint hint) { return Handle::null(); } -namespace { - // 7.1.1.1 OrdinaryToPrimitive ( O, hint ) -void Generate_OrdinaryToPrimitive(CodeStubAssembler* assembler, - OrdinaryToPrimitiveHint hint) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - typedef CodeStubAssembler::Variable Variable; - typedef TypeConversionDescriptor Descriptor; - - Node* input = assembler->Parameter(Descriptor::kArgument); - Node* context = assembler->Parameter(Descriptor::kContext); +void ConversionBuiltinsAssembler::Generate_OrdinaryToPrimitive( + OrdinaryToPrimitiveHint hint) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - Variable var_result(assembler, MachineRepresentation::kTagged); - Label return_result(assembler, &var_result); + Variable var_result(this, MachineRepresentation::kTagged); + Label return_result(this, &var_result); Handle method_names[2]; switch (hint) { case OrdinaryToPrimitiveHint::kNumber: - method_names[0] = assembler->factory()->valueOf_string(); - method_names[1] = assembler->factory()->toString_string(); + method_names[0] = factory()->valueOf_string(); + method_names[1] = factory()->toString_string(); break; case OrdinaryToPrimitiveHint::kString: - method_names[0] = assembler->factory()->toString_string(); - method_names[1] = assembler->factory()->valueOf_string(); + method_names[0] = factory()->toString_string(); + method_names[1] = factory()->valueOf_string(); break; } for (Handle name : method_names) { // Lookup the {name} on the {input}. - Callable callable = CodeFactory::GetProperty(assembler->isolate()); - Node* name_string = assembler->HeapConstant(name); - Node* method = assembler->CallStub(callable, context, input, name_string); + Callable callable = CodeFactory::GetProperty(isolate()); + Node* name_string = HeapConstant(name); + Node* method = CallStub(callable, context, input, name_string); // Check if the {method} is callable. - Label if_methodiscallable(assembler), - if_methodisnotcallable(assembler, Label::kDeferred); - assembler->GotoIf(assembler->TaggedIsSmi(method), &if_methodisnotcallable); - Node* method_map = assembler->LoadMap(method); - assembler->Branch(assembler->IsCallableMap(method_map), - &if_methodiscallable, &if_methodisnotcallable); - - assembler->Bind(&if_methodiscallable); + Label if_methodiscallable(this), + if_methodisnotcallable(this, Label::kDeferred); + GotoIf(TaggedIsSmi(method), &if_methodisnotcallable); + Node* method_map = LoadMap(method); + Branch(IsCallableMap(method_map), &if_methodiscallable, + &if_methodisnotcallable); + + Bind(&if_methodiscallable); { // Call the {method} on the {input}. Callable callable = CodeFactory::Call( - assembler->isolate(), ConvertReceiverMode::kNotNullOrUndefined); - Node* result = assembler->CallJS(callable, context, method, input); + isolate(), ConvertReceiverMode::kNotNullOrUndefined); + Node* result = CallJS(callable, context, method, input); var_result.Bind(result); // Return the {result} if it is a primitive. - assembler->GotoIf(assembler->TaggedIsSmi(result), &return_result); - Node* result_instance_type = assembler->LoadInstanceType(result); + GotoIf(TaggedIsSmi(result), &return_result); + Node* result_instance_type = LoadInstanceType(result); STATIC_ASSERT(FIRST_PRIMITIVE_TYPE == FIRST_TYPE); - assembler->GotoIf(assembler->Int32LessThanOrEqual( - result_instance_type, - assembler->Int32Constant(LAST_PRIMITIVE_TYPE)), - &return_result); + GotoIf(Int32LessThanOrEqual(result_instance_type, + Int32Constant(LAST_PRIMITIVE_TYPE)), + &return_result); } // Just continue with the next {name} if the {method} is not callable. - assembler->Goto(&if_methodisnotcallable); - assembler->Bind(&if_methodisnotcallable); + Goto(&if_methodisnotcallable); + Bind(&if_methodisnotcallable); } - assembler->TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context); + TailCallRuntime(Runtime::kThrowCannotConvertToPrimitive, context); - assembler->Bind(&return_result); - assembler->Return(var_result.value()); + Bind(&return_result); + Return(var_result.value()); } -} // namespace - -void Builtins::Generate_OrdinaryToPrimitive_Number( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_OrdinaryToPrimitive(&assembler, OrdinaryToPrimitiveHint::kNumber); +TF_BUILTIN(OrdinaryToPrimitive_Number, ConversionBuiltinsAssembler) { + Generate_OrdinaryToPrimitive(OrdinaryToPrimitiveHint::kNumber); } -void Builtins::Generate_OrdinaryToPrimitive_String( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_OrdinaryToPrimitive(&assembler, OrdinaryToPrimitiveHint::kString); +TF_BUILTIN(OrdinaryToPrimitive_String, ConversionBuiltinsAssembler) { + Generate_OrdinaryToPrimitive(OrdinaryToPrimitiveHint::kString); } // ES6 section 7.1.2 ToBoolean ( argument ) -void Builtins::Generate_ToBoolean(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef CodeStubAssembler::Label Label; - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); +TF_BUILTIN(ToBoolean, CodeStubAssembler) { + Node* value = Parameter(TypeConversionDescriptor::kArgument); - Node* value = assembler.Parameter(Descriptor::kArgument); + Label return_true(this), return_false(this); + BranchIfToBooleanIsTrue(value, &return_true, &return_false); - Label return_true(&assembler), return_false(&assembler); - assembler.BranchIfToBooleanIsTrue(value, &return_true, &return_false); + Bind(&return_true); + Return(BooleanConstant(true)); - assembler.Bind(&return_true); - assembler.Return(assembler.BooleanConstant(true)); - - assembler.Bind(&return_false); - assembler.Return(assembler.BooleanConstant(false)); + Bind(&return_false); + Return(BooleanConstant(false)); } -void Builtins::Generate_ToLength(compiler::CodeAssemblerState* state) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - typedef CodeStubAssembler::Variable Variable; - CodeStubAssembler assembler(state); - - Node* context = assembler.Parameter(1); +TF_BUILTIN(ToLength, CodeStubAssembler) { + Node* context = Parameter(1); // We might need to loop once for ToNumber conversion. - Variable var_len(&assembler, MachineRepresentation::kTagged); - Label loop(&assembler, &var_len); - var_len.Bind(assembler.Parameter(0)); - assembler.Goto(&loop); - assembler.Bind(&loop); + Variable var_len(this, MachineRepresentation::kTagged, Parameter(0)); + Label loop(this, &var_len); + Goto(&loop); + Bind(&loop); { // Shared entry points. - Label return_len(&assembler), - return_two53minus1(&assembler, Label::kDeferred), - return_zero(&assembler, Label::kDeferred); + Label return_len(this), return_two53minus1(this, Label::kDeferred), + return_zero(this, Label::kDeferred); // Load the current {len} value. Node* len = var_len.value(); // Check if {len} is a positive Smi. - assembler.GotoIf(assembler.TaggedIsPositiveSmi(len), &return_len); + GotoIf(TaggedIsPositiveSmi(len), &return_len); // Check if {len} is a (negative) Smi. - assembler.GotoIf(assembler.TaggedIsSmi(len), &return_zero); + GotoIf(TaggedIsSmi(len), &return_zero); // Check if {len} is a HeapNumber. - Label if_lenisheapnumber(&assembler), - if_lenisnotheapnumber(&assembler, Label::kDeferred); - assembler.Branch(assembler.IsHeapNumberMap(assembler.LoadMap(len)), - &if_lenisheapnumber, &if_lenisnotheapnumber); + Label if_lenisheapnumber(this), + if_lenisnotheapnumber(this, Label::kDeferred); + Branch(IsHeapNumberMap(LoadMap(len)), &if_lenisheapnumber, + &if_lenisnotheapnumber); - assembler.Bind(&if_lenisheapnumber); + Bind(&if_lenisheapnumber); { // Load the floating-point value of {len}. - Node* len_value = assembler.LoadHeapNumberValue(len); + Node* len_value = LoadHeapNumberValue(len); // Check if {len} is not greater than zero. - assembler.GotoIfNot(assembler.Float64GreaterThan( - len_value, assembler.Float64Constant(0.0)), - &return_zero); + GotoIfNot(Float64GreaterThan(len_value, Float64Constant(0.0)), + &return_zero); // Check if {len} is greater than or equal to 2^53-1. - assembler.GotoIf( - assembler.Float64GreaterThanOrEqual( - len_value, assembler.Float64Constant(kMaxSafeInteger)), - &return_two53minus1); + GotoIf(Float64GreaterThanOrEqual(len_value, + Float64Constant(kMaxSafeInteger)), + &return_two53minus1); // Round the {len} towards -Infinity. - Node* value = assembler.Float64Floor(len_value); - Node* result = assembler.ChangeFloat64ToTagged(value); - assembler.Return(result); + Node* value = Float64Floor(len_value); + Node* result = ChangeFloat64ToTagged(value); + Return(result); } - assembler.Bind(&if_lenisnotheapnumber); + Bind(&if_lenisnotheapnumber); { // Need to convert {len} to a Number first. - Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); - var_len.Bind(assembler.CallStub(callable, context, len)); - assembler.Goto(&loop); + Callable callable = CodeFactory::NonNumberToNumber(isolate()); + var_len.Bind(CallStub(callable, context, len)); + Goto(&loop); } - assembler.Bind(&return_len); - assembler.Return(var_len.value()); + Bind(&return_len); + Return(var_len.value()); - assembler.Bind(&return_two53minus1); - assembler.Return(assembler.NumberConstant(kMaxSafeInteger)); + Bind(&return_two53minus1); + Return(NumberConstant(kMaxSafeInteger)); - assembler.Bind(&return_zero); - assembler.Return(assembler.SmiConstant(Smi::kZero)); + Bind(&return_zero); + Return(SmiConstant(Smi::kZero)); } } -void Builtins::Generate_ToInteger(compiler::CodeAssemblerState* state) { - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); - - compiler::Node* input = assembler.Parameter(Descriptor::kArgument); - compiler::Node* context = assembler.Parameter(Descriptor::kContext); +TF_BUILTIN(ToInteger, CodeStubAssembler) { + Node* input = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - assembler.Return(assembler.ToInteger(context, input)); + Return(ToInteger(context, input)); } // ES6 section 7.1.13 ToObject (argument) -void Builtins::Generate_ToObject(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef CodeStubAssembler::Label Label; - typedef CodeStubAssembler::Variable Variable; - typedef TypeConversionDescriptor Descriptor; - CodeStubAssembler assembler(state); +TF_BUILTIN(ToObject, CodeStubAssembler) { + Label if_number(this, Label::kDeferred), if_notsmi(this), if_jsreceiver(this), + if_noconstructor(this, Label::kDeferred), if_wrapjsvalue(this); - Label if_number(&assembler, Label::kDeferred), if_notsmi(&assembler), - if_jsreceiver(&assembler), if_noconstructor(&assembler, Label::kDeferred), - if_wrapjsvalue(&assembler); + Node* object = Parameter(TypeConversionDescriptor::kArgument); + Node* context = Parameter(TypeConversionDescriptor::kContext); - Node* object = assembler.Parameter(Descriptor::kArgument); - Node* context = assembler.Parameter(Descriptor::kContext); - - Variable constructor_function_index_var(&assembler, + Variable constructor_function_index_var(this, MachineType::PointerRepresentation()); - assembler.Branch(assembler.TaggedIsSmi(object), &if_number, &if_notsmi); + Branch(TaggedIsSmi(object), &if_number, &if_notsmi); - assembler.Bind(&if_notsmi); - Node* map = assembler.LoadMap(object); + Bind(&if_notsmi); + Node* map = LoadMap(object); - assembler.GotoIf(assembler.IsHeapNumberMap(map), &if_number); + GotoIf(IsHeapNumberMap(map), &if_number); - Node* instance_type = assembler.LoadMapInstanceType(map); - assembler.GotoIf(assembler.IsJSReceiverInstanceType(instance_type), - &if_jsreceiver); + Node* instance_type = LoadMapInstanceType(map); + GotoIf(IsJSReceiverInstanceType(instance_type), &if_jsreceiver); - Node* constructor_function_index = - assembler.LoadMapConstructorFunctionIndex(map); - assembler.GotoIf(assembler.WordEqual(constructor_function_index, - assembler.IntPtrConstant( - Map::kNoConstructorFunctionIndex)), - &if_noconstructor); + Node* constructor_function_index = LoadMapConstructorFunctionIndex(map); + GotoIf(WordEqual(constructor_function_index, + IntPtrConstant(Map::kNoConstructorFunctionIndex)), + &if_noconstructor); constructor_function_index_var.Bind(constructor_function_index); - assembler.Goto(&if_wrapjsvalue); + Goto(&if_wrapjsvalue); - assembler.Bind(&if_number); + Bind(&if_number); constructor_function_index_var.Bind( - assembler.IntPtrConstant(Context::NUMBER_FUNCTION_INDEX)); - assembler.Goto(&if_wrapjsvalue); + IntPtrConstant(Context::NUMBER_FUNCTION_INDEX)); + Goto(&if_wrapjsvalue); - assembler.Bind(&if_wrapjsvalue); - Node* native_context = assembler.LoadNativeContext(context); - Node* constructor = assembler.LoadFixedArrayElement( + Bind(&if_wrapjsvalue); + Node* native_context = LoadNativeContext(context); + Node* constructor = LoadFixedArrayElement( native_context, constructor_function_index_var.value()); - Node* initial_map = assembler.LoadObjectField( - constructor, JSFunction::kPrototypeOrInitialMapOffset); - Node* js_value = assembler.Allocate(JSValue::kSize); - assembler.StoreMapNoWriteBarrier(js_value, initial_map); - assembler.StoreObjectFieldRoot(js_value, JSValue::kPropertiesOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler.StoreObjectFieldRoot(js_value, JSObject::kElementsOffset, - Heap::kEmptyFixedArrayRootIndex); - assembler.StoreObjectField(js_value, JSValue::kValueOffset, object); - assembler.Return(js_value); - - assembler.Bind(&if_noconstructor); - assembler.TailCallRuntime( + Node* initial_map = + LoadObjectField(constructor, JSFunction::kPrototypeOrInitialMapOffset); + Node* js_value = Allocate(JSValue::kSize); + StoreMapNoWriteBarrier(js_value, initial_map); + StoreObjectFieldRoot(js_value, JSValue::kPropertiesOffset, + Heap::kEmptyFixedArrayRootIndex); + StoreObjectFieldRoot(js_value, JSObject::kElementsOffset, + Heap::kEmptyFixedArrayRootIndex); + StoreObjectField(js_value, JSValue::kValueOffset, object); + Return(js_value); + + Bind(&if_noconstructor); + TailCallRuntime( Runtime::kThrowUndefinedOrNullToObject, context, - assembler.HeapConstant( - assembler.factory()->NewStringFromAsciiChecked("ToObject", TENURED))); + HeapConstant(factory()->NewStringFromAsciiChecked("ToObject", TENURED))); - assembler.Bind(&if_jsreceiver); - assembler.Return(object); + Bind(&if_jsreceiver); + Return(object); } // Deprecated ES5 [[Class]] internal property (used to implement %_ClassOf). -void Builtins::Generate_ClassOf(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef TypeofDescriptor Descriptor; - CodeStubAssembler assembler(state); - - Node* object = assembler.Parameter(Descriptor::kObject); +TF_BUILTIN(ClassOf, CodeStubAssembler) { + Node* object = Parameter(TypeofDescriptor::kObject); - assembler.Return(assembler.ClassOf(object)); + Return(ClassOf(object)); } // ES6 section 12.5.5 typeof operator -void Builtins::Generate_Typeof(compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef TypeofDescriptor Descriptor; - CodeStubAssembler assembler(state); - - Node* object = assembler.Parameter(Descriptor::kObject); - Node* context = assembler.Parameter(Descriptor::kContext); +TF_BUILTIN(Typeof, CodeStubAssembler) { + Node* object = Parameter(TypeofDescriptor::kObject); - assembler.Return(assembler.Typeof(object, context)); + Return(Typeof(object)); } } // namespace internal diff --git a/deps/v8/src/builtins/builtins-date.cc b/deps/v8/src/builtins/builtins-date.cc index 1bc1dfa03614b7..4c44bbc65a98ed 100644 --- a/deps/v8/src/builtins/builtins-date.cc +++ b/deps/v8/src/builtins/builtins-date.cc @@ -17,6 +17,15 @@ namespace internal { // ----------------------------------------------------------------------------- // ES6 section 20.3 Date Objects +class DateBuiltinsAssembler : public CodeStubAssembler { + public: + explicit DateBuiltinsAssembler(compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} + + protected: + void Generate_DatePrototype_GetField(int field_index); +}; + namespace { // ES6 section 20.3.1.1 Time Values and Time Range @@ -895,279 +904,198 @@ BUILTIN(DatePrototypeToJson) { } } -namespace { - -void Generate_DatePrototype_GetField(CodeStubAssembler* assembler, - int field_index) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - - Node* receiver = assembler->Parameter(0); - Node* context = assembler->Parameter(3); +void DateBuiltinsAssembler::Generate_DatePrototype_GetField(int field_index) { + Node* receiver = Parameter(0); + Node* context = Parameter(3); - Label receiver_not_date(assembler, Label::kDeferred); + Label receiver_not_date(this, Label::kDeferred); - assembler->GotoIf(assembler->TaggedIsSmi(receiver), &receiver_not_date); - Node* receiver_instance_type = assembler->LoadInstanceType(receiver); - assembler->GotoIf( - assembler->Word32NotEqual(receiver_instance_type, - assembler->Int32Constant(JS_DATE_TYPE)), - &receiver_not_date); + GotoIf(TaggedIsSmi(receiver), &receiver_not_date); + Node* receiver_instance_type = LoadInstanceType(receiver); + GotoIf(Word32NotEqual(receiver_instance_type, Int32Constant(JS_DATE_TYPE)), + &receiver_not_date); // Load the specified date field, falling back to the runtime as necessary. if (field_index == JSDate::kDateValue) { - assembler->Return( - assembler->LoadObjectField(receiver, JSDate::kValueOffset)); + Return(LoadObjectField(receiver, JSDate::kValueOffset)); } else { if (field_index < JSDate::kFirstUncachedField) { - Label stamp_mismatch(assembler, Label::kDeferred); - Node* date_cache_stamp = assembler->Load( + Label stamp_mismatch(this, Label::kDeferred); + Node* date_cache_stamp = Load( MachineType::AnyTagged(), - assembler->ExternalConstant( - ExternalReference::date_cache_stamp(assembler->isolate()))); - - Node* cache_stamp = - assembler->LoadObjectField(receiver, JSDate::kCacheStampOffset); - assembler->GotoIf(assembler->WordNotEqual(date_cache_stamp, cache_stamp), - &stamp_mismatch); - assembler->Return(assembler->LoadObjectField( + ExternalConstant(ExternalReference::date_cache_stamp(isolate()))); + + Node* cache_stamp = LoadObjectField(receiver, JSDate::kCacheStampOffset); + GotoIf(WordNotEqual(date_cache_stamp, cache_stamp), &stamp_mismatch); + Return(LoadObjectField( receiver, JSDate::kValueOffset + field_index * kPointerSize)); - assembler->Bind(&stamp_mismatch); + Bind(&stamp_mismatch); } - Node* field_index_smi = assembler->SmiConstant(Smi::FromInt(field_index)); - Node* function = assembler->ExternalConstant( - ExternalReference::get_date_field_function(assembler->isolate())); - Node* result = assembler->CallCFunction2( + Node* field_index_smi = SmiConstant(Smi::FromInt(field_index)); + Node* function = + ExternalConstant(ExternalReference::get_date_field_function(isolate())); + Node* result = CallCFunction2( MachineType::AnyTagged(), MachineType::AnyTagged(), MachineType::AnyTagged(), function, receiver, field_index_smi); - assembler->Return(result); + Return(result); } // Raise a TypeError if the receiver is not a date. - assembler->Bind(&receiver_not_date); + Bind(&receiver_not_date); { - assembler->CallRuntime(Runtime::kThrowNotDateError, context); - assembler->Unreachable(); + CallRuntime(Runtime::kThrowNotDateError, context); + Unreachable(); } } -} // namespace - -// static -void Builtins::Generate_DatePrototypeGetDate( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kDay); +TF_BUILTIN(DatePrototypeGetDate, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kDay); } -// static -void Builtins::Generate_DatePrototypeGetDay( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kWeekday); +TF_BUILTIN(DatePrototypeGetDay, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kWeekday); } -// static -void Builtins::Generate_DatePrototypeGetFullYear( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kYear); +TF_BUILTIN(DatePrototypeGetFullYear, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kYear); } -// static -void Builtins::Generate_DatePrototypeGetHours( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kHour); +TF_BUILTIN(DatePrototypeGetHours, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kHour); } -// static -void Builtins::Generate_DatePrototypeGetMilliseconds( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kMillisecond); +TF_BUILTIN(DatePrototypeGetMilliseconds, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kMillisecond); } -// static -void Builtins::Generate_DatePrototypeGetMinutes( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kMinute); +TF_BUILTIN(DatePrototypeGetMinutes, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kMinute); } -// static -void Builtins::Generate_DatePrototypeGetMonth( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kMonth); +TF_BUILTIN(DatePrototypeGetMonth, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kMonth); } -// static -void Builtins::Generate_DatePrototypeGetSeconds( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kSecond); +TF_BUILTIN(DatePrototypeGetSeconds, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kSecond); } -// static -void Builtins::Generate_DatePrototypeGetTime( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kDateValue); +TF_BUILTIN(DatePrototypeGetTime, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kDateValue); } -// static -void Builtins::Generate_DatePrototypeGetTimezoneOffset( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kTimezoneOffset); +TF_BUILTIN(DatePrototypeGetTimezoneOffset, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kTimezoneOffset); } -// static -void Builtins::Generate_DatePrototypeGetUTCDate( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kDayUTC); +TF_BUILTIN(DatePrototypeGetUTCDate, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kDayUTC); } -// static -void Builtins::Generate_DatePrototypeGetUTCDay( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kWeekdayUTC); +TF_BUILTIN(DatePrototypeGetUTCDay, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kWeekdayUTC); } -// static -void Builtins::Generate_DatePrototypeGetUTCFullYear( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kYearUTC); +TF_BUILTIN(DatePrototypeGetUTCFullYear, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kYearUTC); } -// static -void Builtins::Generate_DatePrototypeGetUTCHours( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kHourUTC); +TF_BUILTIN(DatePrototypeGetUTCHours, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kHourUTC); } -// static -void Builtins::Generate_DatePrototypeGetUTCMilliseconds( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kMillisecondUTC); +TF_BUILTIN(DatePrototypeGetUTCMilliseconds, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kMillisecondUTC); } -// static -void Builtins::Generate_DatePrototypeGetUTCMinutes( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kMinuteUTC); +TF_BUILTIN(DatePrototypeGetUTCMinutes, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kMinuteUTC); } -// static -void Builtins::Generate_DatePrototypeGetUTCMonth( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kMonthUTC); +TF_BUILTIN(DatePrototypeGetUTCMonth, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kMonthUTC); } -// static -void Builtins::Generate_DatePrototypeGetUTCSeconds( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kSecondUTC); +TF_BUILTIN(DatePrototypeGetUTCSeconds, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kSecondUTC); } -// static -void Builtins::Generate_DatePrototypeValueOf( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - Generate_DatePrototype_GetField(&assembler, JSDate::kDateValue); +TF_BUILTIN(DatePrototypeValueOf, DateBuiltinsAssembler) { + Generate_DatePrototype_GetField(JSDate::kDateValue); } -// static -void Builtins::Generate_DatePrototypeToPrimitive( - compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - - Node* receiver = assembler.Parameter(0); - Node* hint = assembler.Parameter(1); - Node* context = assembler.Parameter(4); +TF_BUILTIN(DatePrototypeToPrimitive, CodeStubAssembler) { + Node* receiver = Parameter(0); + Node* hint = Parameter(1); + Node* context = Parameter(4); // Check if the {receiver} is actually a JSReceiver. - Label receiver_is_invalid(&assembler, Label::kDeferred); - assembler.GotoIf(assembler.TaggedIsSmi(receiver), &receiver_is_invalid); - assembler.GotoIfNot(assembler.IsJSReceiver(receiver), &receiver_is_invalid); + Label receiver_is_invalid(this, Label::kDeferred); + GotoIf(TaggedIsSmi(receiver), &receiver_is_invalid); + GotoIfNot(IsJSReceiver(receiver), &receiver_is_invalid); // Dispatch to the appropriate OrdinaryToPrimitive builtin. - Label hint_is_number(&assembler), hint_is_string(&assembler), - hint_is_invalid(&assembler, Label::kDeferred); + Label hint_is_number(this), hint_is_string(this), + hint_is_invalid(this, Label::kDeferred); // Fast cases for internalized strings. - Node* number_string = assembler.LoadRoot(Heap::knumber_stringRootIndex); - assembler.GotoIf(assembler.WordEqual(hint, number_string), &hint_is_number); - Node* default_string = assembler.LoadRoot(Heap::kdefault_stringRootIndex); - assembler.GotoIf(assembler.WordEqual(hint, default_string), &hint_is_string); - Node* string_string = assembler.LoadRoot(Heap::kstring_stringRootIndex); - assembler.GotoIf(assembler.WordEqual(hint, string_string), &hint_is_string); + Node* number_string = LoadRoot(Heap::knumber_stringRootIndex); + GotoIf(WordEqual(hint, number_string), &hint_is_number); + Node* default_string = LoadRoot(Heap::kdefault_stringRootIndex); + GotoIf(WordEqual(hint, default_string), &hint_is_string); + Node* string_string = LoadRoot(Heap::kstring_stringRootIndex); + GotoIf(WordEqual(hint, string_string), &hint_is_string); // Slow-case with actual string comparisons. - Callable string_equal = CodeFactory::StringEqual(assembler.isolate()); - assembler.GotoIf(assembler.TaggedIsSmi(hint), &hint_is_invalid); - assembler.GotoIfNot(assembler.IsString(hint), &hint_is_invalid); - assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context, - hint, number_string), - assembler.TrueConstant()), - &hint_is_number); - assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context, - hint, default_string), - assembler.TrueConstant()), - &hint_is_string); - assembler.GotoIf(assembler.WordEqual(assembler.CallStub(string_equal, context, - hint, string_string), - assembler.TrueConstant()), - &hint_is_string); - assembler.Goto(&hint_is_invalid); + Callable string_equal = CodeFactory::StringEqual(isolate()); + GotoIf(TaggedIsSmi(hint), &hint_is_invalid); + GotoIfNot(IsString(hint), &hint_is_invalid); + GotoIf(WordEqual(CallStub(string_equal, context, hint, number_string), + TrueConstant()), + &hint_is_number); + GotoIf(WordEqual(CallStub(string_equal, context, hint, default_string), + TrueConstant()), + &hint_is_string); + GotoIf(WordEqual(CallStub(string_equal, context, hint, string_string), + TrueConstant()), + &hint_is_string); + Goto(&hint_is_invalid); // Use the OrdinaryToPrimitive builtin to convert to a Number. - assembler.Bind(&hint_is_number); + Bind(&hint_is_number); { Callable callable = CodeFactory::OrdinaryToPrimitive( - assembler.isolate(), OrdinaryToPrimitiveHint::kNumber); - Node* result = assembler.CallStub(callable, context, receiver); - assembler.Return(result); + isolate(), OrdinaryToPrimitiveHint::kNumber); + Node* result = CallStub(callable, context, receiver); + Return(result); } // Use the OrdinaryToPrimitive builtin to convert to a String. - assembler.Bind(&hint_is_string); + Bind(&hint_is_string); { Callable callable = CodeFactory::OrdinaryToPrimitive( - assembler.isolate(), OrdinaryToPrimitiveHint::kString); - Node* result = assembler.CallStub(callable, context, receiver); - assembler.Return(result); + isolate(), OrdinaryToPrimitiveHint::kString); + Node* result = CallStub(callable, context, receiver); + Return(result); } // Raise a TypeError if the {hint} is invalid. - assembler.Bind(&hint_is_invalid); + Bind(&hint_is_invalid); { - assembler.CallRuntime(Runtime::kThrowInvalidHint, context, hint); - assembler.Unreachable(); + CallRuntime(Runtime::kThrowInvalidHint, context, hint); + Unreachable(); } // Raise a TypeError if the {receiver} is not a JSReceiver instance. - assembler.Bind(&receiver_is_invalid); + Bind(&receiver_is_invalid); { - assembler.CallRuntime( - Runtime::kThrowIncompatibleMethodReceiver, context, - assembler.HeapConstant(assembler.factory()->NewStringFromAsciiChecked( - "Date.prototype [ @@toPrimitive ]", TENURED)), - receiver); - assembler.Unreachable(); + CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, + HeapConstant(factory()->NewStringFromAsciiChecked( + "Date.prototype [ @@toPrimitive ]", TENURED)), + receiver); + Unreachable(); } } diff --git a/deps/v8/src/builtins/builtins-function.cc b/deps/v8/src/builtins/builtins-function.cc index e58cad30d8b451..d08b109d112a4c 100644 --- a/deps/v8/src/builtins/builtins-function.cc +++ b/deps/v8/src/builtins/builtins-function.cc @@ -272,182 +272,160 @@ Object* DoFunctionBind(Isolate* isolate, BuiltinArguments args) { // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); } -void Builtins::Generate_FastFunctionPrototypeBind( - compiler::CodeAssemblerState* state) { - using compiler::Node; - typedef CodeStubAssembler::Label Label; - typedef CodeStubAssembler::Variable Variable; +TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) { + Label slow(this); - CodeStubAssembler assembler(state); - Label slow(&assembler); + Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount); + Node* context = Parameter(BuiltinDescriptor::kContext); + Node* new_target = Parameter(BuiltinDescriptor::kNewTarget); - Node* argc = assembler.Parameter(BuiltinDescriptor::kArgumentsCount); - Node* context = assembler.Parameter(BuiltinDescriptor::kContext); - Node* new_target = assembler.Parameter(BuiltinDescriptor::kNewTarget); - - CodeStubArguments args(&assembler, assembler.ChangeInt32ToIntPtr(argc)); + CodeStubArguments args(this, ChangeInt32ToIntPtr(argc)); // Check that receiver has instance type of JS_FUNCTION_TYPE Node* receiver = args.GetReceiver(); - assembler.GotoIf(assembler.TaggedIsSmi(receiver), &slow); + GotoIf(TaggedIsSmi(receiver), &slow); - Node* receiver_map = assembler.LoadMap(receiver); - Node* instance_type = assembler.LoadMapInstanceType(receiver_map); - assembler.GotoIf( - assembler.Word32NotEqual(instance_type, - assembler.Int32Constant(JS_FUNCTION_TYPE)), - &slow); + Node* receiver_map = LoadMap(receiver); + Node* instance_type = LoadMapInstanceType(receiver_map); + GotoIf(Word32NotEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)), &slow); // Disallow binding of slow-mode functions. We need to figure out whether the // length and name property are in the original state. - assembler.Comment("Disallow binding of slow-mode functions"); - assembler.GotoIf(assembler.IsDictionaryMap(receiver_map), &slow); + Comment("Disallow binding of slow-mode functions"); + GotoIf(IsDictionaryMap(receiver_map), &slow); // Check whether the length and name properties are still present as // AccessorInfo objects. In that case, their value can be recomputed even if // the actual value on the object changes. - assembler.Comment("Check descriptor array length"); - Node* descriptors = assembler.LoadMapDescriptors(receiver_map); - Node* descriptors_length = assembler.LoadFixedArrayBaseLength(descriptors); - assembler.GotoIf(assembler.SmiLessThanOrEqual(descriptors_length, - assembler.SmiConstant(1)), - &slow); + Comment("Check descriptor array length"); + Node* descriptors = LoadMapDescriptors(receiver_map); + Node* descriptors_length = LoadFixedArrayBaseLength(descriptors); + GotoIf(SmiLessThanOrEqual(descriptors_length, SmiConstant(1)), &slow); // Check whether the length and name properties are still present as // AccessorInfo objects. In that case, their value can be recomputed even if // the actual value on the object changes. - assembler.Comment("Check name and length properties"); + Comment("Check name and length properties"); const int length_index = JSFunction::kLengthDescriptorIndex; - Node* maybe_length = assembler.LoadFixedArrayElement( + Node* maybe_length = LoadFixedArrayElement( descriptors, DescriptorArray::ToKeyIndex(length_index)); - assembler.GotoIf( - assembler.WordNotEqual(maybe_length, - assembler.LoadRoot(Heap::klength_stringRootIndex)), - &slow); + GotoIf(WordNotEqual(maybe_length, LoadRoot(Heap::klength_stringRootIndex)), + &slow); - Node* maybe_length_accessor = assembler.LoadFixedArrayElement( + Node* maybe_length_accessor = LoadFixedArrayElement( descriptors, DescriptorArray::ToValueIndex(length_index)); - assembler.GotoIf(assembler.TaggedIsSmi(maybe_length_accessor), &slow); - Node* length_value_map = assembler.LoadMap(maybe_length_accessor); - assembler.GotoIfNot(assembler.IsAccessorInfoMap(length_value_map), &slow); + GotoIf(TaggedIsSmi(maybe_length_accessor), &slow); + Node* length_value_map = LoadMap(maybe_length_accessor); + GotoIfNot(IsAccessorInfoMap(length_value_map), &slow); const int name_index = JSFunction::kNameDescriptorIndex; - Node* maybe_name = assembler.LoadFixedArrayElement( + Node* maybe_name = LoadFixedArrayElement( descriptors, DescriptorArray::ToKeyIndex(name_index)); - assembler.GotoIf( - assembler.WordNotEqual(maybe_name, - assembler.LoadRoot(Heap::kname_stringRootIndex)), - &slow); + GotoIf(WordNotEqual(maybe_name, LoadRoot(Heap::kname_stringRootIndex)), + &slow); - Node* maybe_name_accessor = assembler.LoadFixedArrayElement( + Node* maybe_name_accessor = LoadFixedArrayElement( descriptors, DescriptorArray::ToValueIndex(name_index)); - assembler.GotoIf(assembler.TaggedIsSmi(maybe_name_accessor), &slow); - Node* name_value_map = assembler.LoadMap(maybe_name_accessor); - assembler.GotoIfNot(assembler.IsAccessorInfoMap(name_value_map), &slow); + GotoIf(TaggedIsSmi(maybe_name_accessor), &slow); + Node* name_value_map = LoadMap(maybe_name_accessor); + GotoIfNot(IsAccessorInfoMap(name_value_map), &slow); // Choose the right bound function map based on whether the target is // constructable. - assembler.Comment("Choose the right bound function map"); - Variable bound_function_map(&assembler, MachineRepresentation::kTagged); - Label with_constructor(&assembler); - CodeStubAssembler::VariableList vars({&bound_function_map}, assembler.zone()); - Node* native_context = assembler.LoadNativeContext(context); - - Label map_done(&assembler, vars); - Node* bit_field = assembler.LoadMapBitField(receiver_map); + Comment("Choose the right bound function map"); + Variable bound_function_map(this, MachineRepresentation::kTagged); + Label with_constructor(this); + VariableList vars({&bound_function_map}, zone()); + Node* native_context = LoadNativeContext(context); + + Label map_done(this, vars); + Node* bit_field = LoadMapBitField(receiver_map); int mask = static_cast(1 << Map::kIsConstructor); - assembler.GotoIf(assembler.IsSetWord32(bit_field, mask), &with_constructor); + GotoIf(IsSetWord32(bit_field, mask), &with_constructor); - bound_function_map.Bind(assembler.LoadContextElement( + bound_function_map.Bind(LoadContextElement( native_context, Context::BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX)); - assembler.Goto(&map_done); + Goto(&map_done); - assembler.Bind(&with_constructor); - bound_function_map.Bind(assembler.LoadContextElement( + Bind(&with_constructor); + bound_function_map.Bind(LoadContextElement( native_context, Context::BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX)); - assembler.Goto(&map_done); + Goto(&map_done); - assembler.Bind(&map_done); + Bind(&map_done); // Verify that __proto__ matches that of a the target bound function. - assembler.Comment("Verify that __proto__ matches target bound function"); - Node* prototype = assembler.LoadMapPrototype(receiver_map); - Node* expected_prototype = - assembler.LoadMapPrototype(bound_function_map.value()); - assembler.GotoIf(assembler.WordNotEqual(prototype, expected_prototype), - &slow); + Comment("Verify that __proto__ matches target bound function"); + Node* prototype = LoadMapPrototype(receiver_map); + Node* expected_prototype = LoadMapPrototype(bound_function_map.value()); + GotoIf(WordNotEqual(prototype, expected_prototype), &slow); // Allocate the arguments array. - assembler.Comment("Allocate the arguments array"); - Variable argument_array(&assembler, MachineRepresentation::kTagged); - Label empty_arguments(&assembler); - Label arguments_done(&assembler, &argument_array); - assembler.GotoIf( - assembler.Uint32LessThanOrEqual(argc, assembler.Int32Constant(1)), - &empty_arguments); - Node* elements_length = assembler.ChangeUint32ToWord( - assembler.Int32Sub(argc, assembler.Int32Constant(1))); - Node* elements = assembler.AllocateFixedArray(FAST_ELEMENTS, elements_length); - Variable index(&assembler, MachineType::PointerRepresentation()); - index.Bind(assembler.IntPtrConstant(0)); - CodeStubAssembler::VariableList foreach_vars({&index}, assembler.zone()); + Comment("Allocate the arguments array"); + Variable argument_array(this, MachineRepresentation::kTagged); + Label empty_arguments(this); + Label arguments_done(this, &argument_array); + GotoIf(Uint32LessThanOrEqual(argc, Int32Constant(1)), &empty_arguments); + Node* elements_length = ChangeUint32ToWord(Int32Sub(argc, Int32Constant(1))); + Node* elements = AllocateFixedArray(FAST_ELEMENTS, elements_length); + Variable index(this, MachineType::PointerRepresentation()); + index.Bind(IntPtrConstant(0)); + VariableList foreach_vars({&index}, zone()); args.ForEach(foreach_vars, - [&assembler, elements, &index](compiler::Node* arg) { - assembler.StoreFixedArrayElement(elements, index.value(), arg); - assembler.Increment(index); + [this, elements, &index](Node* arg) { + StoreFixedArrayElement(elements, index.value(), arg); + Increment(index); }, - assembler.IntPtrConstant(1)); + IntPtrConstant(1)); argument_array.Bind(elements); - assembler.Goto(&arguments_done); + Goto(&arguments_done); - assembler.Bind(&empty_arguments); - argument_array.Bind(assembler.EmptyFixedArrayConstant()); - assembler.Goto(&arguments_done); + Bind(&empty_arguments); + argument_array.Bind(EmptyFixedArrayConstant()); + Goto(&arguments_done); - assembler.Bind(&arguments_done); + Bind(&arguments_done); // Determine bound receiver. - assembler.Comment("Determine bound receiver"); - Variable bound_receiver(&assembler, MachineRepresentation::kTagged); - Label has_receiver(&assembler); - Label receiver_done(&assembler, &bound_receiver); - assembler.GotoIf(assembler.Word32NotEqual(argc, assembler.Int32Constant(0)), - &has_receiver); - bound_receiver.Bind(assembler.UndefinedConstant()); - assembler.Goto(&receiver_done); - - assembler.Bind(&has_receiver); + Comment("Determine bound receiver"); + Variable bound_receiver(this, MachineRepresentation::kTagged); + Label has_receiver(this); + Label receiver_done(this, &bound_receiver); + GotoIf(Word32NotEqual(argc, Int32Constant(0)), &has_receiver); + bound_receiver.Bind(UndefinedConstant()); + Goto(&receiver_done); + + Bind(&has_receiver); bound_receiver.Bind(args.AtIndex(0)); - assembler.Goto(&receiver_done); + Goto(&receiver_done); - assembler.Bind(&receiver_done); + Bind(&receiver_done); // Allocate the resulting bound function. - assembler.Comment("Allocate the resulting bound function"); - Node* bound_function = assembler.Allocate(JSBoundFunction::kSize); - assembler.StoreMapNoWriteBarrier(bound_function, bound_function_map.value()); - assembler.StoreObjectFieldNoWriteBarrier( + Comment("Allocate the resulting bound function"); + Node* bound_function = Allocate(JSBoundFunction::kSize); + StoreMapNoWriteBarrier(bound_function, bound_function_map.value()); + StoreObjectFieldNoWriteBarrier( bound_function, JSBoundFunction::kBoundTargetFunctionOffset, receiver); - assembler.StoreObjectFieldNoWriteBarrier(bound_function, - JSBoundFunction::kBoundThisOffset, - bound_receiver.value()); - assembler.StoreObjectFieldNoWriteBarrier( - bound_function, JSBoundFunction::kBoundArgumentsOffset, - argument_array.value()); - Node* empty_fixed_array = assembler.EmptyFixedArrayConstant(); - assembler.StoreObjectFieldNoWriteBarrier( - bound_function, JSObject::kPropertiesOffset, empty_fixed_array); - assembler.StoreObjectFieldNoWriteBarrier( - bound_function, JSObject::kElementsOffset, empty_fixed_array); + StoreObjectFieldNoWriteBarrier(bound_function, + JSBoundFunction::kBoundThisOffset, + bound_receiver.value()); + StoreObjectFieldNoWriteBarrier(bound_function, + JSBoundFunction::kBoundArgumentsOffset, + argument_array.value()); + Node* empty_fixed_array = EmptyFixedArrayConstant(); + StoreObjectFieldNoWriteBarrier(bound_function, JSObject::kPropertiesOffset, + empty_fixed_array); + StoreObjectFieldNoWriteBarrier(bound_function, JSObject::kElementsOffset, + empty_fixed_array); args.PopAndReturn(bound_function); - assembler.Bind(&slow); + Bind(&slow); - Node* target = assembler.LoadFromFrame( - StandardFrameConstants::kFunctionOffset, MachineType::TaggedPointer()); - assembler.TailCallStub( - CodeFactory::FunctionPrototypeBind(assembler.isolate()), context, target, - new_target, argc); + Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset, + MachineType::TaggedPointer()); + TailCallStub(CodeFactory::FunctionPrototypeBind(isolate()), context, target, + new_target, argc); } // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub @@ -477,16 +455,12 @@ BUILTIN(FunctionPrototypeToString) { } // ES6 section 19.2.3.6 Function.prototype [ @@hasInstance ] ( V ) -void Builtins::Generate_FunctionPrototypeHasInstance( - compiler::CodeAssemblerState* state) { - using compiler::Node; - CodeStubAssembler assembler(state); - - Node* f = assembler.Parameter(0); - Node* v = assembler.Parameter(1); - Node* context = assembler.Parameter(4); - Node* result = assembler.OrdinaryHasInstance(context, f, v); - assembler.Return(result); +TF_BUILTIN(FunctionPrototypeHasInstance, CodeStubAssembler) { + Node* f = Parameter(0); + Node* v = Parameter(1); + Node* context = Parameter(4); + Node* result = OrdinaryHasInstance(context, f, v); + Return(result); } } // namespace internal diff --git a/deps/v8/src/builtins/builtins-global.cc b/deps/v8/src/builtins/builtins-global.cc index 2af6e99730a630..2bbd7c78b557d7 100644 --- a/deps/v8/src/builtins/builtins-global.cc +++ b/deps/v8/src/builtins/builtins-global.cc @@ -104,110 +104,98 @@ BUILTIN(GlobalEval) { } // ES6 section 18.2.2 isFinite ( number ) -void Builtins::Generate_GlobalIsFinite(compiler::CodeAssemblerState* state) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - typedef CodeStubAssembler::Variable Variable; - CodeStubAssembler assembler(state); +TF_BUILTIN(GlobalIsFinite, CodeStubAssembler) { + Node* context = Parameter(4); - Node* context = assembler.Parameter(4); - - Label return_true(&assembler), return_false(&assembler); + Label return_true(this), return_false(this); // We might need to loop once for ToNumber conversion. - Variable var_num(&assembler, MachineRepresentation::kTagged); - Label loop(&assembler, &var_num); - var_num.Bind(assembler.Parameter(1)); - assembler.Goto(&loop); - assembler.Bind(&loop); + Variable var_num(this, MachineRepresentation::kTagged); + Label loop(this, &var_num); + var_num.Bind(Parameter(1)); + Goto(&loop); + Bind(&loop); { - // Load the current {num} value. Node* num = var_num.value(); // Check if {num} is a Smi or a HeapObject. - assembler.GotoIf(assembler.TaggedIsSmi(num), &return_true); + GotoIf(TaggedIsSmi(num), &return_true); // Check if {num} is a HeapNumber. - Label if_numisheapnumber(&assembler), - if_numisnotheapnumber(&assembler, Label::kDeferred); - assembler.Branch(assembler.IsHeapNumberMap(assembler.LoadMap(num)), - &if_numisheapnumber, &if_numisnotheapnumber); + Label if_numisheapnumber(this), + if_numisnotheapnumber(this, Label::kDeferred); + Branch(IsHeapNumberMap(LoadMap(num)), &if_numisheapnumber, + &if_numisnotheapnumber); - assembler.Bind(&if_numisheapnumber); + Bind(&if_numisheapnumber); { // Check if {num} contains a finite, non-NaN value. - Node* num_value = assembler.LoadHeapNumberValue(num); - assembler.BranchIfFloat64IsNaN(assembler.Float64Sub(num_value, num_value), - &return_false, &return_true); + Node* num_value = LoadHeapNumberValue(num); + BranchIfFloat64IsNaN(Float64Sub(num_value, num_value), &return_false, + &return_true); } - assembler.Bind(&if_numisnotheapnumber); + Bind(&if_numisnotheapnumber); { // Need to convert {num} to a Number first. - Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); - var_num.Bind(assembler.CallStub(callable, context, num)); - assembler.Goto(&loop); + Callable callable = CodeFactory::NonNumberToNumber(isolate()); + var_num.Bind(CallStub(callable, context, num)); + Goto(&loop); } } - assembler.Bind(&return_true); - assembler.Return(assembler.BooleanConstant(true)); + Bind(&return_true); + Return(BooleanConstant(true)); - assembler.Bind(&return_false); - assembler.Return(assembler.BooleanConstant(false)); + Bind(&return_false); + Return(BooleanConstant(false)); } // ES6 section 18.2.3 isNaN ( number ) -void Builtins::Generate_GlobalIsNaN(compiler::CodeAssemblerState* state) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; - typedef CodeStubAssembler::Variable Variable; - CodeStubAssembler assembler(state); - - Node* context = assembler.Parameter(4); +TF_BUILTIN(GlobalIsNaN, CodeStubAssembler) { + Node* context = Parameter(4); - Label return_true(&assembler), return_false(&assembler); + Label return_true(this), return_false(this); // We might need to loop once for ToNumber conversion. - Variable var_num(&assembler, MachineRepresentation::kTagged); - Label loop(&assembler, &var_num); - var_num.Bind(assembler.Parameter(1)); - assembler.Goto(&loop); - assembler.Bind(&loop); + Variable var_num(this, MachineRepresentation::kTagged); + Label loop(this, &var_num); + var_num.Bind(Parameter(1)); + Goto(&loop); + Bind(&loop); { - // Load the current {num} value. Node* num = var_num.value(); // Check if {num} is a Smi or a HeapObject. - assembler.GotoIf(assembler.TaggedIsSmi(num), &return_false); + GotoIf(TaggedIsSmi(num), &return_false); // Check if {num} is a HeapNumber. - Label if_numisheapnumber(&assembler), - if_numisnotheapnumber(&assembler, Label::kDeferred); - assembler.Branch(assembler.IsHeapNumberMap(assembler.LoadMap(num)), - &if_numisheapnumber, &if_numisnotheapnumber); + Label if_numisheapnumber(this), + if_numisnotheapnumber(this, Label::kDeferred); + Branch(IsHeapNumberMap(LoadMap(num)), &if_numisheapnumber, + &if_numisnotheapnumber); - assembler.Bind(&if_numisheapnumber); + Bind(&if_numisheapnumber); { // Check if {num} contains a NaN. - Node* num_value = assembler.LoadHeapNumberValue(num); - assembler.BranchIfFloat64IsNaN(num_value, &return_true, &return_false); + Node* num_value = LoadHeapNumberValue(num); + BranchIfFloat64IsNaN(num_value, &return_true, &return_false); } - assembler.Bind(&if_numisnotheapnumber); + Bind(&if_numisnotheapnumber); { // Need to convert {num} to a Number first. - Callable callable = CodeFactory::NonNumberToNumber(assembler.isolate()); - var_num.Bind(assembler.CallStub(callable, context, num)); - assembler.Goto(&loop); + Callable callable = CodeFactory::NonNumberToNumber(isolate()); + var_num.Bind(CallStub(callable, context, num)); + Goto(&loop); } } - assembler.Bind(&return_true); - assembler.Return(assembler.BooleanConstant(true)); + Bind(&return_true); + Return(BooleanConstant(true)); - assembler.Bind(&return_false); - assembler.Return(assembler.BooleanConstant(false)); + Bind(&return_false); + Return(BooleanConstant(false)); } } // namespace internal diff --git a/deps/v8/src/builtins/builtins-internal.cc b/deps/v8/src/builtins/builtins-internal.cc index 324f1a310b9946..7f81e8c086b774 100644 --- a/deps/v8/src/builtins/builtins-internal.cc +++ b/deps/v8/src/builtins/builtins-internal.cc @@ -56,190 +56,150 @@ void Builtins::Generate_StackCheck(MacroAssembler* masm) { // ----------------------------------------------------------------------------- // TurboFan support builtins. -void Builtins::Generate_CopyFastSmiOrObjectElements( - compiler::CodeAssemblerState* state) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; +TF_BUILTIN(CopyFastSmiOrObjectElements, CodeStubAssembler) { typedef CopyFastSmiOrObjectElementsDescriptor Descriptor; - CodeStubAssembler assembler(state); - Node* object = assembler.Parameter(Descriptor::kObject); + Node* object = Parameter(Descriptor::kObject); // Load the {object}s elements. - Node* source = assembler.LoadObjectField(object, JSObject::kElementsOffset); + Node* source = LoadObjectField(object, JSObject::kElementsOffset); - CodeStubAssembler::ParameterMode mode = assembler.OptimalParameterMode(); - Node* length = assembler.TaggedToParameter( - assembler.LoadFixedArrayBaseLength(source), mode); + ParameterMode mode = OptimalParameterMode(); + Node* length = TaggedToParameter(LoadFixedArrayBaseLength(source), mode); // Check if we can allocate in new space. ElementsKind kind = FAST_ELEMENTS; int max_elements = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind); - Label if_newspace(&assembler), if_oldspace(&assembler); - assembler.Branch( - assembler.UintPtrOrSmiLessThan( - length, assembler.IntPtrOrSmiConstant(max_elements, mode), mode), - &if_newspace, &if_oldspace); + Label if_newspace(this), if_oldspace(this); + Branch(UintPtrOrSmiLessThan(length, IntPtrOrSmiConstant(max_elements, mode), + mode), + &if_newspace, &if_oldspace); - assembler.Bind(&if_newspace); + Bind(&if_newspace); { - Node* target = assembler.AllocateFixedArray(kind, length, mode); - assembler.CopyFixedArrayElements(kind, source, target, length, - SKIP_WRITE_BARRIER, mode); - assembler.StoreObjectField(object, JSObject::kElementsOffset, target); - assembler.Return(target); + Node* target = AllocateFixedArray(kind, length, mode); + CopyFixedArrayElements(kind, source, target, length, SKIP_WRITE_BARRIER, + mode); + StoreObjectField(object, JSObject::kElementsOffset, target); + Return(target); } - assembler.Bind(&if_oldspace); + Bind(&if_oldspace); { - Node* target = assembler.AllocateFixedArray(kind, length, mode, - CodeStubAssembler::kPretenured); - assembler.CopyFixedArrayElements(kind, source, target, length, - UPDATE_WRITE_BARRIER, mode); - assembler.StoreObjectField(object, JSObject::kElementsOffset, target); - assembler.Return(target); + Node* target = AllocateFixedArray(kind, length, mode, kPretenured); + CopyFixedArrayElements(kind, source, target, length, UPDATE_WRITE_BARRIER, + mode); + StoreObjectField(object, JSObject::kElementsOffset, target); + Return(target); } } -void Builtins::Generate_GrowFastDoubleElements( - compiler::CodeAssemblerState* state) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; +TF_BUILTIN(GrowFastDoubleElements, CodeStubAssembler) { typedef GrowArrayElementsDescriptor Descriptor; - CodeStubAssembler assembler(state); - Node* object = assembler.Parameter(Descriptor::kObject); - Node* key = assembler.Parameter(Descriptor::kKey); - Node* context = assembler.Parameter(Descriptor::kContext); + Node* object = Parameter(Descriptor::kObject); + Node* key = Parameter(Descriptor::kKey); + Node* context = Parameter(Descriptor::kContext); - Label runtime(&assembler, CodeStubAssembler::Label::kDeferred); - Node* elements = assembler.LoadElements(object); - elements = assembler.TryGrowElementsCapacity( - object, elements, FAST_DOUBLE_ELEMENTS, key, &runtime); - assembler.Return(elements); + Label runtime(this, Label::kDeferred); + Node* elements = LoadElements(object); + elements = TryGrowElementsCapacity(object, elements, FAST_DOUBLE_ELEMENTS, + key, &runtime); + Return(elements); - assembler.Bind(&runtime); - assembler.TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); + Bind(&runtime); + TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); } -void Builtins::Generate_GrowFastSmiOrObjectElements( - compiler::CodeAssemblerState* state) { - typedef CodeStubAssembler::Label Label; - typedef compiler::Node Node; +TF_BUILTIN(GrowFastSmiOrObjectElements, CodeStubAssembler) { typedef GrowArrayElementsDescriptor Descriptor; - CodeStubAssembler assembler(state); - Node* object = assembler.Parameter(Descriptor::kObject); - Node* key = assembler.Parameter(Descriptor::kKey); - Node* context = assembler.Parameter(Descriptor::kContext); + Node* object = Parameter(Descriptor::kObject); + Node* key = Parameter(Descriptor::kKey); + Node* context = Parameter(Descriptor::kContext); - Label runtime(&assembler, CodeStubAssembler::Label::kDeferred); - Node* elements = assembler.LoadElements(object); - elements = assembler.TryGrowElementsCapacity(object, elements, FAST_ELEMENTS, - key, &runtime); - assembler.Return(elements); + Label runtime(this, Label::kDeferred); + Node* elements = LoadElements(object); + elements = + TryGrowElementsCapacity(object, elements, FAST_ELEMENTS, key, &runtime); + Return(elements); - assembler.Bind(&runtime); - assembler.TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); + Bind(&runtime); + TailCallRuntime(Runtime::kGrowArrayElements, context, object, key); } -namespace { +TF_BUILTIN(NewUnmappedArgumentsElements, CodeStubAssembler) { + typedef NewArgumentsElementsDescriptor Descriptor; -void Generate_NewArgumentsElements(CodeStubAssembler* assembler, - compiler::Node* frame, - compiler::Node* length) { - typedef CodeStubAssembler::Label Label; - typedef CodeStubAssembler::Variable Variable; - typedef compiler::Node Node; + Node* frame = Parameter(Descriptor::kFrame); + Node* length = SmiToWord(Parameter(Descriptor::kLength)); // Check if we can allocate in new space. ElementsKind kind = FAST_ELEMENTS; int max_elements = FixedArray::GetMaxLengthForNewSpaceAllocation(kind); - Label if_newspace(assembler), if_oldspace(assembler, Label::kDeferred); - assembler->Branch(assembler->IntPtrLessThan( - length, assembler->IntPtrConstant(max_elements)), - &if_newspace, &if_oldspace); + Label if_newspace(this), if_oldspace(this, Label::kDeferred); + Branch(IntPtrLessThan(length, IntPtrConstant(max_elements)), &if_newspace, + &if_oldspace); - assembler->Bind(&if_newspace); + Bind(&if_newspace); { // Prefer EmptyFixedArray in case of non-positive {length} (the {length} // can be negative here for rest parameters). - Label if_empty(assembler), if_notempty(assembler); - assembler->Branch( - assembler->IntPtrLessThanOrEqual(length, assembler->IntPtrConstant(0)), - &if_empty, &if_notempty); + Label if_empty(this), if_notempty(this); + Branch(IntPtrLessThanOrEqual(length, IntPtrConstant(0)), &if_empty, + &if_notempty); - assembler->Bind(&if_empty); - assembler->Return(assembler->EmptyFixedArrayConstant()); + Bind(&if_empty); + Return(EmptyFixedArrayConstant()); - assembler->Bind(&if_notempty); + Bind(&if_notempty); { // Allocate a FixedArray in new space. - Node* result = assembler->AllocateFixedArray(kind, length); + Node* result = AllocateFixedArray(kind, length); // Compute the effective {offset} into the {frame}. - Node* offset = assembler->IntPtrAdd(length, assembler->IntPtrConstant(1)); + Node* offset = IntPtrAdd(length, IntPtrConstant(1)); // Copy the parameters from {frame} (starting at {offset}) to {result}. - Variable var_index(assembler, MachineType::PointerRepresentation()); - Label loop(assembler, &var_index), done_loop(assembler); - var_index.Bind(assembler->IntPtrConstant(0)); - assembler->Goto(&loop); - assembler->Bind(&loop); + Variable var_index(this, MachineType::PointerRepresentation()); + Label loop(this, &var_index), done_loop(this); + var_index.Bind(IntPtrConstant(0)); + Goto(&loop); + Bind(&loop); { // Load the current {index}. Node* index = var_index.value(); // Check if we are done. - assembler->GotoIf(assembler->WordEqual(index, length), &done_loop); + GotoIf(WordEqual(index, length), &done_loop); // Load the parameter at the given {index}. - Node* value = assembler->Load( - MachineType::AnyTagged(), frame, - assembler->WordShl(assembler->IntPtrSub(offset, index), - assembler->IntPtrConstant(kPointerSizeLog2))); + Node* value = Load(MachineType::AnyTagged(), frame, + WordShl(IntPtrSub(offset, index), + IntPtrConstant(kPointerSizeLog2))); // Store the {value} into the {result}. - assembler->StoreFixedArrayElement(result, index, value, - SKIP_WRITE_BARRIER); + StoreFixedArrayElement(result, index, value, SKIP_WRITE_BARRIER); // Continue with next {index}. - var_index.Bind( - assembler->IntPtrAdd(index, assembler->IntPtrConstant(1))); - assembler->Goto(&loop); + var_index.Bind(IntPtrAdd(index, IntPtrConstant(1))); + Goto(&loop); } - assembler->Bind(&done_loop); - assembler->Return(result); + Bind(&done_loop); + Return(result); } } - assembler->Bind(&if_oldspace); + Bind(&if_oldspace); { // Allocate in old space (or large object space). - assembler->TailCallRuntime( - Runtime::kNewArgumentsElements, assembler->NoContextConstant(), - assembler->BitcastWordToTagged(frame), assembler->SmiFromWord(length)); + TailCallRuntime(Runtime::kNewArgumentsElements, NoContextConstant(), + BitcastWordToTagged(frame), SmiFromWord(length)); } } -} // namespace - -void Builtins::Generate_NewUnmappedArgumentsElements( - compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - typedef NewArgumentsElementsDescriptor Descriptor; - CodeStubAssembler assembler(state); - - Node* frame = assembler.Parameter(Descriptor::kFrame); - Node* length = assembler.Parameter(Descriptor::kLength); - Generate_NewArgumentsElements(&assembler, frame, assembler.SmiToWord(length)); -} - -void Builtins::Generate_ReturnReceiver(compiler::CodeAssemblerState* state) { - CodeStubAssembler assembler(state); - assembler.Return(assembler.Parameter(0)); -} +TF_BUILTIN(ReturnReceiver, CodeStubAssembler) { Return(Parameter(0)); } } // namespace internal } // namespace v8 diff --git a/deps/v8/src/builtins/builtins-number.cc b/deps/v8/src/builtins/builtins-number.cc index 56a115ac0c17ab..0b1afe1b09ea4b 100644 --- a/deps/v8/src/builtins/builtins-number.cc +++ b/deps/v8/src/builtins/builtins-number.cc @@ -1593,9 +1593,8 @@ TF_BUILTIN(Equal, CodeStubAssembler) { TF_BUILTIN(StrictEqual, CodeStubAssembler) { Node* lhs = Parameter(0); Node* rhs = Parameter(1); - Node* context = Parameter(2); - Return(StrictEqual(lhs, rhs, context)); + Return(StrictEqual(lhs, rhs)); } } // namespace internal diff --git a/deps/v8/src/builtins/builtins-promise.cc b/deps/v8/src/builtins/builtins-promise.cc index 1e97bd034e8c47..a1a556dc99a154 100644 --- a/deps/v8/src/builtins/builtins-promise.cc +++ b/deps/v8/src/builtins/builtins-promise.cc @@ -13,10 +13,6 @@ namespace v8 { namespace internal { -typedef compiler::Node Node; -typedef CodeStubAssembler::ParameterMode ParameterMode; -typedef compiler::CodeAssemblerState CodeAssemblerState; - Node* PromiseBuiltinsAssembler::AllocateJSPromise(Node* context) { Node* const native_context = LoadNativeContext(context); Node* const promise_fun = @@ -685,7 +681,7 @@ void PromiseBuiltinsAssembler::InternalResolvePromise(Node* context, Bind(&cycle_check); // 6. If SameValue(resolution, promise) is true, then - GotoIf(SameValue(promise, result, context), &if_cycle); + GotoIf(SameValue(promise, result), &if_cycle); // 7. If Type(resolution) is not Object, then GotoIf(TaggedIsSmi(result), &fulfill); @@ -746,7 +742,7 @@ void PromiseBuiltinsAssembler::InternalResolvePromise(Node* context, Goto(&reject); Bind(&reject); - // Don't cause a debug event as this case is forwarding a rejection + // Don't cause a debug event as this case is forwarding a rejection. InternalPromiseReject(context, promise, thenable_value, false); PromiseSetHasHandler(result); Goto(&out); @@ -829,7 +825,8 @@ void PromiseBuiltinsAssembler::InternalResolvePromise(Node* context, // 9.a Return RejectPromise(promise, then.[[Value]]). Bind(&if_rejectpromise); { - InternalPromiseReject(context, promise, var_reason.value(), true); + // Don't cause a debug event as this case is forwarding a rejection. + InternalPromiseReject(context, promise, var_reason.value(), false); Goto(&out); } @@ -1430,7 +1427,7 @@ TF_BUILTIN(PromiseResolve, PromiseBuiltinsAssembler) { CallStub(getproperty_callable, context, value, constructor_str); // 3.b If SameValue(xConstructor, C) is true, return x. - GotoIfNot(SameValue(constructor, receiver, context), &if_valueisnotpromise); + GotoIfNot(SameValue(constructor, receiver), &if_valueisnotpromise); Return(value); } diff --git a/deps/v8/src/builtins/builtins-regexp.cc b/deps/v8/src/builtins/builtins-regexp.cc index 93cb55899b449f..baf163fd456e07 100644 --- a/deps/v8/src/builtins/builtins-regexp.cc +++ b/deps/v8/src/builtins/builtins-regexp.cc @@ -1723,7 +1723,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow( // Ensure last index is 0. { Label next(this); - GotoIf(SameValue(previous_last_index, smi_zero, context), &next); + GotoIf(SameValue(previous_last_index, smi_zero), &next); SlowStoreLastIndex(context, regexp, smi_zero); Goto(&next); @@ -1738,7 +1738,7 @@ void RegExpBuiltinsAssembler::RegExpPrototypeSearchBodySlow( Label next(this); Node* const current_last_index = SlowLoadLastIndex(context, regexp); - GotoIf(SameValue(current_last_index, previous_last_index, context), &next); + GotoIf(SameValue(current_last_index, previous_last_index), &next); SlowStoreLastIndex(context, regexp, previous_last_index); Goto(&next); diff --git a/deps/v8/src/builtins/builtins-sharedarraybuffer.cc b/deps/v8/src/builtins/builtins-sharedarraybuffer.cc index b4cb78f20a75d2..d2b9f1efa96b4b 100644 --- a/deps/v8/src/builtins/builtins-sharedarraybuffer.cc +++ b/deps/v8/src/builtins/builtins-sharedarraybuffer.cc @@ -10,6 +10,24 @@ namespace v8 { namespace internal { +using compiler::Node; + +class SharedArrayBufferBuiltinsAssembler : public CodeStubAssembler { + public: + explicit SharedArrayBufferBuiltinsAssembler( + compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} + + protected: + void ValidateSharedTypedArray(Node* tagged, Node* context, + Node** out_instance_type, + Node** out_backing_store); + Node* ConvertTaggedAtomicIndexToWord32(Node* tagged, Node* context, + Node** number_index); + void ValidateAtomicIndex(Node* index_word, Node* array_length_word, + Node* context); +}; + // ES7 sharedmem 6.3.4.1 get SharedArrayBuffer.prototype.byteLength BUILTIN(SharedArrayBufferPrototypeGetByteLength) { HandleScope scope(isolate); @@ -25,325 +43,298 @@ BUILTIN(SharedArrayBufferPrototypeGetByteLength) { return array_buffer->byte_length(); } -namespace { - -void ValidateSharedTypedArray(CodeStubAssembler* a, compiler::Node* tagged, - compiler::Node* context, - compiler::Node** out_instance_type, - compiler::Node** out_backing_store) { - using compiler::Node; - CodeStubAssembler::Label is_smi(a), not_smi(a), is_typed_array(a), - not_typed_array(a), is_shared(a), not_shared(a), is_float_or_clamped(a), - not_float_or_clamped(a), invalid(a); +void SharedArrayBufferBuiltinsAssembler::ValidateSharedTypedArray( + Node* tagged, Node* context, Node** out_instance_type, + Node** out_backing_store) { + Label not_float_or_clamped(this), invalid(this); // Fail if it is not a heap object. - a->Branch(a->TaggedIsSmi(tagged), &is_smi, ¬_smi); - a->Bind(&is_smi); - a->Goto(&invalid); + GotoIf(TaggedIsSmi(tagged), &invalid); // Fail if the array's instance type is not JSTypedArray. - a->Bind(¬_smi); - a->Branch(a->Word32Equal(a->LoadInstanceType(tagged), - a->Int32Constant(JS_TYPED_ARRAY_TYPE)), - &is_typed_array, ¬_typed_array); - a->Bind(¬_typed_array); - a->Goto(&invalid); + GotoIf(Word32NotEqual(LoadInstanceType(tagged), + Int32Constant(JS_TYPED_ARRAY_TYPE)), + &invalid); // Fail if the array's JSArrayBuffer is not shared. - a->Bind(&is_typed_array); - Node* array_buffer = a->LoadObjectField(tagged, JSTypedArray::kBufferOffset); - Node* is_buffer_shared = - a->IsSetWord32(a->LoadObjectField( - array_buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32())); - a->Branch(is_buffer_shared, &is_shared, ¬_shared); - a->Bind(¬_shared); - a->Goto(&invalid); + Node* array_buffer = LoadObjectField(tagged, JSTypedArray::kBufferOffset); + Node* bitfield = LoadObjectField(array_buffer, JSArrayBuffer::kBitFieldOffset, + MachineType::Uint32()); + GotoIfNot(IsSetWord32(bitfield), &invalid); // Fail if the array's element type is float32, float64 or clamped. - a->Bind(&is_shared); - Node* elements_instance_type = a->LoadInstanceType( - a->LoadObjectField(tagged, JSObject::kElementsOffset)); + Node* elements_instance_type = + LoadInstanceType(LoadObjectField(tagged, JSObject::kElementsOffset)); STATIC_ASSERT(FIXED_INT8_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE); STATIC_ASSERT(FIXED_INT16_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE); STATIC_ASSERT(FIXED_INT32_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE); STATIC_ASSERT(FIXED_UINT8_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE); STATIC_ASSERT(FIXED_UINT16_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE); STATIC_ASSERT(FIXED_UINT32_ARRAY_TYPE < FIXED_FLOAT32_ARRAY_TYPE); - a->Branch(a->Int32LessThan(elements_instance_type, - a->Int32Constant(FIXED_FLOAT32_ARRAY_TYPE)), - ¬_float_or_clamped, &is_float_or_clamped); - a->Bind(&is_float_or_clamped); - a->Goto(&invalid); - - a->Bind(&invalid); - a->CallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, context, - tagged); - a->Unreachable(); - - a->Bind(¬_float_or_clamped); + Branch(Int32LessThan(elements_instance_type, + Int32Constant(FIXED_FLOAT32_ARRAY_TYPE)), + ¬_float_or_clamped, &invalid); + + Bind(&invalid); + { + CallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, context, + tagged); + Unreachable(); + } + + Bind(¬_float_or_clamped); *out_instance_type = elements_instance_type; Node* backing_store = - a->LoadObjectField(array_buffer, JSArrayBuffer::kBackingStoreOffset); - Node* byte_offset = a->ChangeUint32ToWord(a->TruncateTaggedToWord32( - context, - a->LoadObjectField(tagged, JSArrayBufferView::kByteOffsetOffset))); + LoadObjectField(array_buffer, JSArrayBuffer::kBackingStoreOffset); + Node* byte_offset = ChangeUint32ToWord(TruncateTaggedToWord32( + context, LoadObjectField(tagged, JSArrayBufferView::kByteOffsetOffset))); *out_backing_store = - a->IntPtrAdd(a->BitcastTaggedToWord(backing_store), byte_offset); + IntPtrAdd(BitcastTaggedToWord(backing_store), byte_offset); } // https://tc39.github.io/ecmascript_sharedmem/shmem.html#Atomics.ValidateAtomicAccess -compiler::Node* ConvertTaggedAtomicIndexToWord32( - CodeStubAssembler* a, compiler::Node* tagged, compiler::Node* context, - compiler::Node** number_index) { - using compiler::Node; - CodeStubAssembler::Variable var_result(a, MachineRepresentation::kWord32); - - Callable to_number = CodeFactory::ToNumber(a->isolate()); - *number_index = a->CallStub(to_number, context, tagged); - CodeStubAssembler::Label done(a, &var_result); - - CodeStubAssembler::Label if_numberissmi(a), if_numberisnotsmi(a); - a->Branch(a->TaggedIsSmi(*number_index), &if_numberissmi, &if_numberisnotsmi); - - a->Bind(&if_numberissmi); +Node* SharedArrayBufferBuiltinsAssembler::ConvertTaggedAtomicIndexToWord32( + Node* tagged, Node* context, Node** number_index) { + Variable var_result(this, MachineRepresentation::kWord32); + + // TODO(jkummerow): Skip ToNumber call when |tagged| is a number already. + // Maybe this can be unified with other tagged-to-index conversions? + // Why does this return an int32, and not an intptr? + // Why is there the additional |number_index| output parameter? + Callable to_number = CodeFactory::ToNumber(isolate()); + *number_index = CallStub(to_number, context, tagged); + Label done(this, &var_result); + + Label if_numberissmi(this), if_numberisnotsmi(this); + Branch(TaggedIsSmi(*number_index), &if_numberissmi, &if_numberisnotsmi); + + Bind(&if_numberissmi); { - var_result.Bind(a->SmiToWord32(*number_index)); - a->Goto(&done); + var_result.Bind(SmiToWord32(*number_index)); + Goto(&done); } - a->Bind(&if_numberisnotsmi); + Bind(&if_numberisnotsmi); { - Node* number_index_value = a->LoadHeapNumberValue(*number_index); - Node* access_index = a->TruncateFloat64ToWord32(number_index_value); - Node* test_index = a->ChangeInt32ToFloat64(access_index); + Node* number_index_value = LoadHeapNumberValue(*number_index); + Node* access_index = TruncateFloat64ToWord32(number_index_value); + Node* test_index = ChangeInt32ToFloat64(access_index); - CodeStubAssembler::Label if_indexesareequal(a), if_indexesarenotequal(a); - a->Branch(a->Float64Equal(number_index_value, test_index), - &if_indexesareequal, &if_indexesarenotequal); + Label if_indexesareequal(this), if_indexesarenotequal(this); + Branch(Float64Equal(number_index_value, test_index), &if_indexesareequal, + &if_indexesarenotequal); - a->Bind(&if_indexesareequal); + Bind(&if_indexesareequal); { var_result.Bind(access_index); - a->Goto(&done); + Goto(&done); } - a->Bind(&if_indexesarenotequal); - a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context); - a->Unreachable(); + Bind(&if_indexesarenotequal); + { + CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context); + Unreachable(); + } } - a->Bind(&done); + Bind(&done); return var_result.value(); } -void ValidateAtomicIndex(CodeStubAssembler* a, compiler::Node* index_word, - compiler::Node* array_length_word, - compiler::Node* context) { - using compiler::Node; +void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex( + Node* index_word, Node* array_length_word, Node* context) { // Check if the index is in bounds. If not, throw RangeError. - CodeStubAssembler::Label if_inbounds(a), if_notinbounds(a); - // TODO(jkummerow): Use unsigned comparison instead of "i<0 || i>length". - a->Branch( - a->Word32Or(a->Int32LessThan(index_word, a->Int32Constant(0)), - a->Int32GreaterThanOrEqual(index_word, array_length_word)), - &if_notinbounds, &if_inbounds); - a->Bind(&if_notinbounds); - a->CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context); - a->Unreachable(); - a->Bind(&if_inbounds); -} + Label check_passed(this); + GotoIf(Uint32LessThan(index_word, array_length_word), &check_passed); -} // anonymous namespace + CallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context); + Unreachable(); -void Builtins::Generate_AtomicsLoad(compiler::CodeAssemblerState* state) { - using compiler::Node; - CodeStubAssembler a(state); - Node* array = a.Parameter(1); - Node* index = a.Parameter(2); - Node* context = a.Parameter(3 + 2); + Bind(&check_passed); +} + +TF_BUILTIN(AtomicsLoad, SharedArrayBufferBuiltinsAssembler) { + Node* array = Parameter(1); + Node* index = Parameter(2); + Node* context = Parameter(3 + 2); Node* instance_type; Node* backing_store; - ValidateSharedTypedArray(&a, array, context, &instance_type, &backing_store); + ValidateSharedTypedArray(array, context, &instance_type, &backing_store); Node* index_integer; Node* index_word32 = - ConvertTaggedAtomicIndexToWord32(&a, index, context, &index_integer); - Node* array_length_word32 = a.TruncateTaggedToWord32( - context, a.LoadObjectField(array, JSTypedArray::kLengthOffset)); - ValidateAtomicIndex(&a, index_word32, array_length_word32, context); - Node* index_word = a.ChangeUint32ToWord(index_word32); - - CodeStubAssembler::Label i8(&a), u8(&a), i16(&a), u16(&a), i32(&a), u32(&a), - other(&a); + ConvertTaggedAtomicIndexToWord32(index, context, &index_integer); + Node* array_length_word32 = TruncateTaggedToWord32( + context, LoadObjectField(array, JSTypedArray::kLengthOffset)); + ValidateAtomicIndex(index_word32, array_length_word32, context); + Node* index_word = ChangeUint32ToWord(index_word32); + + Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this), + other(this); int32_t case_values[] = { FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE, FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE, }; - CodeStubAssembler::Label* case_labels[] = { + Label* case_labels[] = { &i8, &u8, &i16, &u16, &i32, &u32, }; - a.Switch(instance_type, &other, case_values, case_labels, - arraysize(case_labels)); + Switch(instance_type, &other, case_values, case_labels, + arraysize(case_labels)); - a.Bind(&i8); - a.Return(a.SmiFromWord32( - a.AtomicLoad(MachineType::Int8(), backing_store, index_word))); + Bind(&i8); + Return(SmiFromWord32( + AtomicLoad(MachineType::Int8(), backing_store, index_word))); - a.Bind(&u8); - a.Return(a.SmiFromWord32( - a.AtomicLoad(MachineType::Uint8(), backing_store, index_word))); + Bind(&u8); + Return(SmiFromWord32( + AtomicLoad(MachineType::Uint8(), backing_store, index_word))); - a.Bind(&i16); - a.Return(a.SmiFromWord32(a.AtomicLoad(MachineType::Int16(), backing_store, - a.WordShl(index_word, 1)))); + Bind(&i16); + Return(SmiFromWord32( + AtomicLoad(MachineType::Int16(), backing_store, WordShl(index_word, 1)))); - a.Bind(&u16); - a.Return(a.SmiFromWord32(a.AtomicLoad(MachineType::Uint16(), backing_store, - a.WordShl(index_word, 1)))); + Bind(&u16); + Return(SmiFromWord32(AtomicLoad(MachineType::Uint16(), backing_store, + WordShl(index_word, 1)))); - a.Bind(&i32); - a.Return(a.ChangeInt32ToTagged(a.AtomicLoad( - MachineType::Int32(), backing_store, a.WordShl(index_word, 2)))); + Bind(&i32); + Return(ChangeInt32ToTagged( + AtomicLoad(MachineType::Int32(), backing_store, WordShl(index_word, 2)))); - a.Bind(&u32); - a.Return(a.ChangeUint32ToTagged(a.AtomicLoad( - MachineType::Uint32(), backing_store, a.WordShl(index_word, 2)))); + Bind(&u32); + Return(ChangeUint32ToTagged(AtomicLoad(MachineType::Uint32(), backing_store, + WordShl(index_word, 2)))); // This shouldn't happen, we've already validated the type. - a.Bind(&other); - a.Return(a.SmiConstant(0)); + Bind(&other); + Unreachable(); } -void Builtins::Generate_AtomicsStore(compiler::CodeAssemblerState* state) { - using compiler::Node; - CodeStubAssembler a(state); - Node* array = a.Parameter(1); - Node* index = a.Parameter(2); - Node* value = a.Parameter(3); - Node* context = a.Parameter(4 + 2); +TF_BUILTIN(AtomicsStore, SharedArrayBufferBuiltinsAssembler) { + Node* array = Parameter(1); + Node* index = Parameter(2); + Node* value = Parameter(3); + Node* context = Parameter(4 + 2); Node* instance_type; Node* backing_store; - ValidateSharedTypedArray(&a, array, context, &instance_type, &backing_store); + ValidateSharedTypedArray(array, context, &instance_type, &backing_store); Node* index_integer; Node* index_word32 = - ConvertTaggedAtomicIndexToWord32(&a, index, context, &index_integer); - Node* array_length_word32 = a.TruncateTaggedToWord32( - context, a.LoadObjectField(array, JSTypedArray::kLengthOffset)); - ValidateAtomicIndex(&a, index_word32, array_length_word32, context); - Node* index_word = a.ChangeUint32ToWord(index_word32); + ConvertTaggedAtomicIndexToWord32(index, context, &index_integer); + Node* array_length_word32 = TruncateTaggedToWord32( + context, LoadObjectField(array, JSTypedArray::kLengthOffset)); + ValidateAtomicIndex(index_word32, array_length_word32, context); + Node* index_word = ChangeUint32ToWord(index_word32); - Node* value_integer = a.ToInteger(context, value); - Node* value_word32 = a.TruncateTaggedToWord32(context, value_integer); + Node* value_integer = ToInteger(context, value); + Node* value_word32 = TruncateTaggedToWord32(context, value_integer); - CodeStubAssembler::Label u8(&a), u16(&a), u32(&a), other(&a); + Label u8(this), u16(this), u32(this), other(this); int32_t case_values[] = { FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE, FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE, }; - CodeStubAssembler::Label* case_labels[] = { + Label* case_labels[] = { &u8, &u8, &u16, &u16, &u32, &u32, }; - a.Switch(instance_type, &other, case_values, case_labels, - arraysize(case_labels)); + Switch(instance_type, &other, case_values, case_labels, + arraysize(case_labels)); - a.Bind(&u8); - a.AtomicStore(MachineRepresentation::kWord8, backing_store, index_word, - value_word32); - a.Return(value_integer); + Bind(&u8); + AtomicStore(MachineRepresentation::kWord8, backing_store, index_word, + value_word32); + Return(value_integer); - a.Bind(&u16); - a.AtomicStore(MachineRepresentation::kWord16, backing_store, - a.WordShl(index_word, 1), value_word32); - a.Return(value_integer); + Bind(&u16); + AtomicStore(MachineRepresentation::kWord16, backing_store, + WordShl(index_word, 1), value_word32); + Return(value_integer); - a.Bind(&u32); - a.AtomicStore(MachineRepresentation::kWord32, backing_store, - a.WordShl(index_word, 2), value_word32); - a.Return(value_integer); + Bind(&u32); + AtomicStore(MachineRepresentation::kWord32, backing_store, + WordShl(index_word, 2), value_word32); + Return(value_integer); // This shouldn't happen, we've already validated the type. - a.Bind(&other); - a.Return(a.SmiConstant(0)); + Bind(&other); + Unreachable(); } -void Builtins::Generate_AtomicsExchange(compiler::CodeAssemblerState* state) { - using compiler::Node; - CodeStubAssembler a(state); - Node* array = a.Parameter(1); - Node* index = a.Parameter(2); - Node* value = a.Parameter(3); - Node* context = a.Parameter(4 + 2); +TF_BUILTIN(AtomicsExchange, SharedArrayBufferBuiltinsAssembler) { + Node* array = Parameter(1); + Node* index = Parameter(2); + Node* value = Parameter(3); + Node* context = Parameter(4 + 2); Node* instance_type; Node* backing_store; - ValidateSharedTypedArray(&a, array, context, &instance_type, &backing_store); + ValidateSharedTypedArray(array, context, &instance_type, &backing_store); Node* index_integer; Node* index_word32 = - ConvertTaggedAtomicIndexToWord32(&a, index, context, &index_integer); - Node* array_length_word32 = a.TruncateTaggedToWord32( - context, a.LoadObjectField(array, JSTypedArray::kLengthOffset)); - ValidateAtomicIndex(&a, index_word32, array_length_word32, context); + ConvertTaggedAtomicIndexToWord32(index, context, &index_integer); + Node* array_length_word32 = TruncateTaggedToWord32( + context, LoadObjectField(array, JSTypedArray::kLengthOffset)); + ValidateAtomicIndex(index_word32, array_length_word32, context); - Node* value_integer = a.ToInteger(context, value); + Node* value_integer = ToInteger(context, value); -#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 - // Node* index_integer = a.ToInteger(context, index); - a.Return(a.CallRuntime(Runtime::kAtomicsExchange, context, array, - index_integer, value_integer)); +#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || \ + V8_TARGET_ARCH_PPC + Return(CallRuntime(Runtime::kAtomicsExchange, context, array, index_integer, + value_integer)); #else - Node* index_word = a.ChangeUint32ToWord(index_word32); + Node* index_word = ChangeUint32ToWord(index_word32); - Node* value_word32 = a.TruncateTaggedToWord32(context, value_integer); + Node* value_word32 = TruncateTaggedToWord32(context, value_integer); - CodeStubAssembler::Label i8(&a), u8(&a), i16(&a), u16(&a), i32(&a), u32(&a), - other(&a); + Label i8(this), u8(this), i16(this), u16(this), i32(this), u32(this), + other(this); int32_t case_values[] = { FIXED_INT8_ARRAY_TYPE, FIXED_UINT8_ARRAY_TYPE, FIXED_INT16_ARRAY_TYPE, FIXED_UINT16_ARRAY_TYPE, FIXED_INT32_ARRAY_TYPE, FIXED_UINT32_ARRAY_TYPE, }; - CodeStubAssembler::Label* case_labels[] = { + Label* case_labels[] = { &i8, &u8, &i16, &u16, &i32, &u32, }; - a.Switch(instance_type, &other, case_values, case_labels, - arraysize(case_labels)); + Switch(instance_type, &other, case_values, case_labels, + arraysize(case_labels)); - a.Bind(&i8); - a.Return(a.SmiFromWord32(a.AtomicExchange(MachineType::Int8(), backing_store, - index_word, value_word32))); + Bind(&i8); + Return(SmiFromWord32(AtomicExchange(MachineType::Int8(), backing_store, + index_word, value_word32))); - a.Bind(&u8); - a.Return(a.SmiFromWord32(a.AtomicExchange(MachineType::Uint8(), backing_store, - index_word, value_word32))); + Bind(&u8); + Return(SmiFromWord32(AtomicExchange(MachineType::Uint8(), backing_store, + index_word, value_word32))); - a.Bind(&i16); - a.Return(a.SmiFromWord32(a.AtomicExchange(MachineType::Int16(), backing_store, - a.WordShl(index_word, 1), - value_word32))); + Bind(&i16); + Return(SmiFromWord32(AtomicExchange(MachineType::Int16(), backing_store, + WordShl(index_word, 1), value_word32))); - a.Bind(&u16); - a.Return(a.SmiFromWord32( - a.AtomicExchange(MachineType::Uint16(), backing_store, - a.WordShl(index_word, 1), value_word32))); + Bind(&u16); + Return(SmiFromWord32(AtomicExchange(MachineType::Uint16(), backing_store, + WordShl(index_word, 1), value_word32))); - a.Bind(&i32); - a.Return(a.ChangeInt32ToTagged( - a.AtomicExchange(MachineType::Int32(), backing_store, - a.WordShl(index_word, 2), value_word32))); + Bind(&i32); + Return(ChangeInt32ToTagged(AtomicExchange(MachineType::Int32(), backing_store, + WordShl(index_word, 2), + value_word32))); - a.Bind(&u32); - a.Return(a.ChangeUint32ToTagged( - a.AtomicExchange(MachineType::Uint32(), backing_store, - a.WordShl(index_word, 2), value_word32))); + Bind(&u32); + Return(ChangeUint32ToTagged( + AtomicExchange(MachineType::Uint32(), backing_store, + WordShl(index_word, 2), value_word32))); // This shouldn't happen, we've already validated the type. - a.Bind(&other); - a.Return(a.SmiConstant(0)); -#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 + Bind(&other); + Unreachable(); +#endif // V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 + // || V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X } } // namespace internal diff --git a/deps/v8/src/builtins/builtins-symbol.cc b/deps/v8/src/builtins/builtins-symbol.cc index f57d0bffd9f9fd..43cb8c89a90a29 100644 --- a/deps/v8/src/builtins/builtins-symbol.cc +++ b/deps/v8/src/builtins/builtins-symbol.cc @@ -68,48 +68,34 @@ BUILTIN(SymbolKeyFor) { } // ES6 section 19.4.3.4 Symbol.prototype [ @@toPrimitive ] ( hint ) -void Builtins::Generate_SymbolPrototypeToPrimitive( - compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - CodeStubAssembler assembler(state); +TF_BUILTIN(SymbolPrototypeToPrimitive, CodeStubAssembler) { + Node* receiver = Parameter(0); + Node* context = Parameter(4); - Node* receiver = assembler.Parameter(0); - Node* context = assembler.Parameter(4); - - Node* result = - assembler.ToThisValue(context, receiver, PrimitiveType::kSymbol, - "Symbol.prototype [ @@toPrimitive ]"); - assembler.Return(result); + Node* result = ToThisValue(context, receiver, PrimitiveType::kSymbol, + "Symbol.prototype [ @@toPrimitive ]"); + Return(result); } // ES6 section 19.4.3.2 Symbol.prototype.toString ( ) -void Builtins::Generate_SymbolPrototypeToString( - compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - CodeStubAssembler assembler(state); - - Node* receiver = assembler.Parameter(0); - Node* context = assembler.Parameter(3); - - Node* value = assembler.ToThisValue(context, receiver, PrimitiveType::kSymbol, - "Symbol.prototype.toString"); - Node* result = - assembler.CallRuntime(Runtime::kSymbolDescriptiveString, context, value); - assembler.Return(result); +TF_BUILTIN(SymbolPrototypeToString, CodeStubAssembler) { + Node* receiver = Parameter(0); + Node* context = Parameter(3); + + Node* value = ToThisValue(context, receiver, PrimitiveType::kSymbol, + "Symbol.prototype.toString"); + Node* result = CallRuntime(Runtime::kSymbolDescriptiveString, context, value); + Return(result); } // ES6 section 19.4.3.3 Symbol.prototype.valueOf ( ) -void Builtins::Generate_SymbolPrototypeValueOf( - compiler::CodeAssemblerState* state) { - typedef compiler::Node Node; - CodeStubAssembler assembler(state); - - Node* receiver = assembler.Parameter(0); - Node* context = assembler.Parameter(3); +TF_BUILTIN(SymbolPrototypeValueOf, CodeStubAssembler) { + Node* receiver = Parameter(0); + Node* context = Parameter(3); - Node* result = assembler.ToThisValue( - context, receiver, PrimitiveType::kSymbol, "Symbol.prototype.valueOf"); - assembler.Return(result); + Node* result = ToThisValue(context, receiver, PrimitiveType::kSymbol, + "Symbol.prototype.valueOf"); + Return(result); } } // namespace internal diff --git a/deps/v8/src/code-stub-assembler.cc b/deps/v8/src/code-stub-assembler.cc index dc97e704b75d55..879de1120e4848 100644 --- a/deps/v8/src/code-stub-assembler.cc +++ b/deps/v8/src/code-stub-assembler.cc @@ -747,33 +747,28 @@ Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes, Node* top_address, Node* limit_address) { Node* top = Load(MachineType::Pointer(), top_address); - Node* limit = Load(MachineType::Pointer(), limit_address); Variable adjusted_size(this, MachineType::PointerRepresentation(), size_in_bytes); if (flags & kDoubleAlignment) { - Label aligned(this), not_aligned(this), merge(this, &adjusted_size); + Label not_aligned(this), done_alignment(this, &adjusted_size); Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), ¬_aligned, - &aligned); + &done_alignment); Bind(¬_aligned); Node* not_aligned_size = IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize)); adjusted_size.Bind(not_aligned_size); - Goto(&merge); - - Bind(&aligned); - Goto(&merge); + Goto(&done_alignment); - Bind(&merge); + Bind(&done_alignment); } - Variable address( - this, MachineRepresentation::kTagged, - AllocateRawUnaligned(adjusted_size.value(), kNone, top, limit)); + Variable address(this, MachineRepresentation::kTagged, + AllocateRawUnaligned(adjusted_size.value(), kNone, + top_address, limit_address)); - Label needs_filler(this), doesnt_need_filler(this), - merge_address(this, &address); - Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &doesnt_need_filler, + Label needs_filler(this), done_filling(this, &address); + Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &done_filling, &needs_filler); Bind(&needs_filler); @@ -782,12 +777,9 @@ Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes, LoadRoot(Heap::kOnePointerFillerMapRootIndex)); address.Bind(BitcastWordToTagged( IntPtrAdd(address.value(), IntPtrConstant(kPointerSize)))); - Goto(&merge_address); + Goto(&done_filling); - Bind(&doesnt_need_filler); - Goto(&merge_address); - - Bind(&merge_address); + Bind(&done_filling); // Update the top. StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address, IntPtrAdd(top, adjusted_size.value())); @@ -7258,7 +7250,7 @@ Node* CodeStubAssembler::Equal(Node* lhs, Node* rhs, Node* context) { return result.value(); } -Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs, Node* context) { +Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs) { // Here's pseudo-code for the algorithm below in case of kDontNegateResult // mode; for kNegateResult mode we properly negate the result. // @@ -7408,7 +7400,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs, Node* context) { Bind(&if_rhsisstring); { Callable callable = CodeFactory::StringEqual(isolate()); - result.Bind(CallStub(callable, context, lhs, rhs)); + result.Bind(CallStub(callable, NoContextConstant(), lhs, rhs)); Goto(&end); } @@ -7479,7 +7471,7 @@ Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs, Node* context) { // ECMA#sec-samevalue // This algorithm differs from the Strict Equality Comparison Algorithm in its // treatment of signed zeroes and NaNs. -Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) { +Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs) { Variable var_result(this, MachineRepresentation::kWord32); Label strict_equal(this), out(this); @@ -7553,7 +7545,7 @@ Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) { Bind(&strict_equal); { - Node* const is_equal = StrictEqual(lhs, rhs, context); + Node* const is_equal = StrictEqual(lhs, rhs); Node* const result = WordEqual(is_equal, TrueConstant()); var_result.Bind(result); Goto(&out); @@ -7664,7 +7656,7 @@ Node* CodeStubAssembler::ClassOf(Node* value) { return var_result.value(); } -Node* CodeStubAssembler::Typeof(Node* value, Node* context) { +Node* CodeStubAssembler::Typeof(Node* value) { Variable result_var(this, MachineRepresentation::kTagged); Label return_number(this, Label::kDeferred), if_oddball(this), diff --git a/deps/v8/src/code-stub-assembler.h b/deps/v8/src/code-stub-assembler.h index efb95546833ef3..471fb26b5fc632 100644 --- a/deps/v8/src/code-stub-assembler.h +++ b/deps/v8/src/code-stub-assembler.h @@ -1204,14 +1204,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { Node* Equal(Node* lhs, Node* rhs, Node* context); - Node* StrictEqual(Node* lhs, Node* rhs, Node* context); + Node* StrictEqual(Node* lhs, Node* rhs); // ECMA#sec-samevalue // Similar to StrictEqual except that NaNs are treated as equal and minus zero // differs from positive zero. // Unlike Equal and StrictEqual, returns a value suitable for use in Branch // instructions, e.g. Branch(SameValue(...), &label). - Node* SameValue(Node* lhs, Node* rhs, Node* context); + Node* SameValue(Node* lhs, Node* rhs); Node* HasProperty( Node* object, Node* key, Node* context, @@ -1219,7 +1219,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { Node* ClassOf(Node* object); - Node* Typeof(Node* value, Node* context); + Node* Typeof(Node* value); Node* GetSuperConstructor(Node* value, Node* context); diff --git a/deps/v8/src/compiler/bytecode-graph-builder.cc b/deps/v8/src/compiler/bytecode-graph-builder.cc index 10ded107ed7180..c0fcc87b449d88 100644 --- a/deps/v8/src/compiler/bytecode-graph-builder.cc +++ b/deps/v8/src/compiler/bytecode-graph-builder.cc @@ -1293,10 +1293,8 @@ void BytecodeGraphBuilder::VisitCreateObjectLiteral() { literal, Environment::kAttachFrameState); } -Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, - Node* callee, - interpreter::Register receiver, - size_t arity) { +Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister( + Node* callee, interpreter::Register receiver, size_t arity) { Node** all = local_zone()->NewArray(static_cast(arity)); all[0] = callee; all[1] = environment()->LookupRegister(receiver); @@ -1305,34 +1303,133 @@ Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, all[i] = environment()->LookupRegister( interpreter::Register(receiver_index + i - 1)); } - Node* value = MakeNode(call_op, static_cast(arity), all, false); - return value; + return all; +} + +Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, + Node* const* args, + size_t arg_count) { + return MakeNode(call_op, static_cast(arg_count), args, false); +} + +Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op, + Node* callee, + interpreter::Register receiver, + size_t arg_count) { + return ProcessCallArguments( + call_op, GetCallArgumentsFromRegister(callee, receiver, arg_count), + arg_count); } void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode, - ConvertReceiverMode receiver_hint) { + ConvertReceiverMode receiver_hint, + Node* const* args, size_t arg_count, + int slot_id) { PrepareEagerCheckpoint(); - Node* callee = - environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); - interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); - size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); - // Slot index of 0 is used indicate no feedback slot is available. Assert // the assumption that slot index 0 is never a valid feedback slot. STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0); - int const slot_id = bytecode_iterator().GetIndexOperand(3); VectorSlotPair feedback = CreateVectorSlotPair(slot_id); float const frequency = ComputeCallFrequency(slot_id); - const Operator* call = javascript()->Call(arg_count + 1, frequency, feedback, + const Operator* call = javascript()->Call(arg_count, frequency, feedback, receiver_hint, tail_call_mode); - Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1); + Node* value = ProcessCallArguments(call, args, arg_count); environment()->BindAccumulator(value, Environment::kAttachFrameState); } +void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode, + ConvertReceiverMode receiver_hint) { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1); + size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2); + int const slot_id = bytecode_iterator().GetIndexOperand(3); + BuildCall(tail_call_mode, receiver_hint, + GetCallArgumentsFromRegister(callee, receiver, arg_count + 1), + arg_count + 1, slot_id); +} + void BytecodeGraphBuilder::VisitCall() { - BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny); + BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kAny); +} + +void BytecodeGraphBuilder::VisitCall0() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + int const slot_id = bytecode_iterator().GetIndexOperand(2); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, + {callee, receiver}, slot_id); +} + +void BytecodeGraphBuilder::VisitCall1() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + Node* arg0 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); + int const slot_id = bytecode_iterator().GetIndexOperand(3); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, + {callee, receiver, arg0}, slot_id); +} + +void BytecodeGraphBuilder::VisitCall2() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + Node* arg0 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); + Node* arg1 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); + int const slot_id = bytecode_iterator().GetIndexOperand(4); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kAny, + {callee, receiver, arg0, arg1}, slot_id); +} + +void BytecodeGraphBuilder::VisitCallProperty() { + BuildCallVarArgs(TailCallMode::kDisallow, + ConvertReceiverMode::kNotNullOrUndefined); +} + +void BytecodeGraphBuilder::VisitCallProperty0() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + int const slot_id = bytecode_iterator().GetIndexOperand(2); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, + {callee, receiver}, slot_id); +} + +void BytecodeGraphBuilder::VisitCallProperty1() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + Node* arg0 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); + int const slot_id = bytecode_iterator().GetIndexOperand(3); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, + {callee, receiver, arg0}, slot_id); +} + +void BytecodeGraphBuilder::VisitCallProperty2() { + Node* callee = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0)); + Node* receiver = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1)); + Node* arg0 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2)); + Node* arg1 = + environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3)); + int const slot_id = bytecode_iterator().GetIndexOperand(4); + BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined, + {callee, receiver, arg0, arg1}, slot_id); } void BytecodeGraphBuilder::VisitCallWithSpread() { @@ -1348,16 +1445,12 @@ void BytecodeGraphBuilder::VisitCallWithSpread() { environment()->BindAccumulator(value, Environment::kAttachFrameState); } -void BytecodeGraphBuilder::VisitCallProperty() { - BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined); -} - void BytecodeGraphBuilder::VisitTailCall() { TailCallMode tail_call_mode = bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled() ? TailCallMode::kAllow : TailCallMode::kDisallow; - BuildCall(tail_call_mode, ConvertReceiverMode::kAny); + BuildCallVarArgs(tail_call_mode, ConvertReceiverMode::kAny); } void BytecodeGraphBuilder::VisitCallJSRuntime() { @@ -2265,7 +2358,8 @@ void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) { } Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count, - Node** value_inputs, bool incomplete) { + Node* const* value_inputs, + bool incomplete) { DCHECK_EQ(op->ValueInputCount(), value_input_count); bool has_context = OperatorProperties::HasContextInput(op); diff --git a/deps/v8/src/compiler/bytecode-graph-builder.h b/deps/v8/src/compiler/bytecode-graph-builder.h index 057bfe17ec5913..3e73e030709dc4 100644 --- a/deps/v8/src/compiler/bytecode-graph-builder.h +++ b/deps/v8/src/compiler/bytecode-graph-builder.h @@ -104,11 +104,16 @@ class BytecodeGraphBuilder { // The main node creation chokepoint. Adds context, frame state, effect, // and control dependencies depending on the operator. - Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs, - bool incomplete); + Node* MakeNode(const Operator* op, int value_input_count, + Node* const* value_inputs, bool incomplete); Node** EnsureInputBufferSize(int size); + Node* const* GetCallArgumentsFromRegister(Node* callee, + interpreter::Register first_arg, + size_t arity); + Node* ProcessCallArguments(const Operator* call_op, Node* const* args, + size_t arg_count); Node* ProcessCallArguments(const Operator* call_op, Node* callee, interpreter::Register receiver, size_t arity); Node* ProcessConstructArguments(const Operator* call_new_op, Node* callee, @@ -150,8 +155,16 @@ class BytecodeGraphBuilder { void BuildLdaLookupContextSlot(TypeofMode typeof_mode); void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode); void BuildStaLookupSlot(LanguageMode language_mode); - void BuildCall(TailCallMode tail_call_mode, - ConvertReceiverMode receiver_hint); + void BuildCallVarArgs(TailCallMode tail_call_mode, + ConvertReceiverMode receiver_hint); + void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_hint, + Node* const* args, size_t arg_count, int slot_id); + void BuildCall(TailCallMode tail_call_mode, ConvertReceiverMode receiver_hint, + std::initializer_list args, int slot_id) { + BuildCall(tail_call_mode, receiver_hint, args.begin(), args.size(), + slot_id); + } + void BuildThrow(); void BuildBinaryOp(const Operator* op); void BuildBinaryOpWithImmediate(const Operator* op); void BuildCompareOp(const Operator* op); diff --git a/deps/v8/src/compiler/ia32/code-generator-ia32.cc b/deps/v8/src/compiler/ia32/code-generator-ia32.cc index 0f6d1c3a4a8ff7..7243d621c3d210 100644 --- a/deps/v8/src/compiler/ia32/code-generator-ia32.cc +++ b/deps/v8/src/compiler/ia32/code-generator-ia32.cc @@ -1614,10 +1614,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } break; case kSSEFloat64InsertLowWord32: - __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0); + __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 0, true); break; case kSSEFloat64InsertHighWord32: - __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1); + __ Pinsrd(i.OutputDoubleRegister(), i.InputOperand(1), 1, true); break; case kSSEFloat64LoadLowWord32: __ movd(i.OutputDoubleRegister(), i.InputOperand(0)); @@ -1888,6 +1888,40 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( } break; } + case kIA32Int32x4Splat: { + XMMRegister dst = i.OutputSimd128Register(); + __ movd(dst, i.InputOperand(0)); + __ pshufd(dst, dst, 0x0); + break; + } + case kIA32Int32x4ExtractLane: { + __ Pextrd(i.OutputRegister(), i.InputSimd128Register(0), i.InputInt8(1)); + break; + } + case kIA32Int32x4ReplaceLane: { + __ Pinsrd(i.OutputSimd128Register(), i.InputOperand(2), i.InputInt8(1)); + break; + } + case kSSEInt32x4Add: { + __ paddd(i.OutputSimd128Register(), i.InputOperand(1)); + break; + } + case kSSEInt32x4Sub: { + __ psubd(i.OutputSimd128Register(), i.InputOperand(1)); + break; + } + case kAVXInt32x4Add: { + CpuFeatureScope avx_scope(masm(), AVX); + __ vpaddd(i.OutputSimd128Register(), i.InputSimd128Register(0), + i.InputOperand(1)); + break; + } + case kAVXInt32x4Sub: { + CpuFeatureScope avx_scope(masm(), AVX); + __ vpsubd(i.OutputSimd128Register(), i.InputSimd128Register(0), + i.InputOperand(1)); + break; + } case kCheckedLoadInt8: ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b); break; diff --git a/deps/v8/src/compiler/ia32/instruction-codes-ia32.h b/deps/v8/src/compiler/ia32/instruction-codes-ia32.h index b4d40e0962620e..7566c2b0fcb24f 100644 --- a/deps/v8/src/compiler/ia32/instruction-codes-ia32.h +++ b/deps/v8/src/compiler/ia32/instruction-codes-ia32.h @@ -110,7 +110,14 @@ namespace compiler { V(IA32PushFloat32) \ V(IA32PushFloat64) \ V(IA32Poke) \ - V(IA32StackCheck) + V(IA32StackCheck) \ + V(IA32Int32x4Splat) \ + V(IA32Int32x4ExtractLane) \ + V(IA32Int32x4ReplaceLane) \ + V(SSEInt32x4Add) \ + V(SSEInt32x4Sub) \ + V(AVXInt32x4Add) \ + V(AVXInt32x4Sub) // Addressing modes represent the "shape" of inputs to an instruction. // Many instructions support multiple addressing modes. Addressing modes diff --git a/deps/v8/src/compiler/ia32/instruction-scheduler-ia32.cc b/deps/v8/src/compiler/ia32/instruction-scheduler-ia32.cc index efd5065bda552f..a30ebfccd4a70e 100644 --- a/deps/v8/src/compiler/ia32/instruction-scheduler-ia32.cc +++ b/deps/v8/src/compiler/ia32/instruction-scheduler-ia32.cc @@ -97,6 +97,13 @@ int InstructionScheduler::GetTargetInstructionFlags( case kAVXFloat32Neg: case kIA32BitcastFI: case kIA32BitcastIF: + case kIA32Int32x4Splat: + case kIA32Int32x4ExtractLane: + case kIA32Int32x4ReplaceLane: + case kSSEInt32x4Add: + case kSSEInt32x4Sub: + case kAVXInt32x4Add: + case kAVXInt32x4Sub: return (instr->addressing_mode() == kMode_None) ? kNoOpcodeFlags : kIsLoadOperation | kHasSideEffect; diff --git a/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc b/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc index fcb0b484faa181..b2476cec5d8bd7 100644 --- a/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc +++ b/deps/v8/src/compiler/ia32/instruction-selector-ia32.cc @@ -873,7 +873,9 @@ void InstructionSelector::VisitWord32Ror(Node* node) { V(Float32Mul, kAVXFloat32Mul, kSSEFloat32Mul) \ V(Float64Mul, kAVXFloat64Mul, kSSEFloat64Mul) \ V(Float32Div, kAVXFloat32Div, kSSEFloat32Div) \ - V(Float64Div, kAVXFloat64Div, kSSEFloat64Div) + V(Float64Div, kAVXFloat64Div, kSSEFloat64Div) \ + V(Int32x4Add, kAVXInt32x4Add, kSSEInt32x4Add) \ + V(Int32x4Sub, kAVXInt32x4Sub, kSSEInt32x4Sub) #define FLOAT_UNOP_LIST(V) \ V(Float32Abs, kAVXFloat32Abs, kSSEFloat32Abs) \ @@ -1756,6 +1758,25 @@ void InstructionSelector::VisitAtomicExchange(Node* node) { Emit(code, 1, outputs, input_count, inputs); } +void InstructionSelector::VisitInt32x4Splat(Node* node) { + VisitRO(this, node, kIA32Int32x4Splat); +} + +void InstructionSelector::VisitInt32x4ExtractLane(Node* node) { + IA32OperandGenerator g(this); + int32_t lane = OpParameter(node); + Emit(kIA32Int32x4ExtractLane, g.DefineAsRegister(node), + g.UseRegister(node->InputAt(0)), g.UseImmediate(lane)); +} + +void InstructionSelector::VisitInt32x4ReplaceLane(Node* node) { + IA32OperandGenerator g(this); + int32_t lane = OpParameter(node); + Emit(kIA32Int32x4ReplaceLane, g.DefineSameAsFirst(node), + g.UseRegister(node->InputAt(0)), g.UseImmediate(lane), + g.Use(node->InputAt(1))); +} + // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { diff --git a/deps/v8/src/compiler/instruction-selector.cc b/deps/v8/src/compiler/instruction-selector.cc index 11839ba0e211eb..5e48c51652ff5f 100644 --- a/deps/v8/src/compiler/instruction-selector.cc +++ b/deps/v8/src/compiler/instruction-selector.cc @@ -2031,7 +2031,7 @@ void InstructionSelector::VisitWord32PairShr(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitWord32PairSar(Node* node) { UNIMPLEMENTED(); } #endif // V8_TARGET_ARCH_64_BIT -#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM +#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 void InstructionSelector::VisitInt32x4Splat(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitInt32x4ExtractLane(Node* node) { @@ -2045,7 +2045,9 @@ void InstructionSelector::VisitInt32x4ReplaceLane(Node* node) { void InstructionSelector::VisitInt32x4Add(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitInt32x4Sub(Node* node) { UNIMPLEMENTED(); } +#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 +#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM void InstructionSelector::VisitSimd128Zero(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitSimd1x4Zero(Node* node) { UNIMPLEMENTED(); } diff --git a/deps/v8/src/compiler/js-builtin-reducer.cc b/deps/v8/src/compiler/js-builtin-reducer.cc index 66c212dfcb71a3..40aaef91f9b5ac 100644 --- a/deps/v8/src/compiler/js-builtin-reducer.cc +++ b/deps/v8/src/compiler/js-builtin-reducer.cc @@ -1513,6 +1513,11 @@ Reduction JSBuiltinReducer::ReduceNumberIsInteger(Node* node) { // ES6 section 20.1.2.4 Number.isNaN ( number ) Reduction JSBuiltinReducer::ReduceNumberIsNaN(Node* node) { JSCallReduction r(node); + if (r.InputsMatchZero()) { + // Number.isNaN() -> #false + Node* value = jsgraph()->FalseConstant(); + return Replace(value); + } // Number.isNaN(a:number) -> ObjectIsNaN(a) Node* input = r.GetJSCallInput(0); Node* value = graph()->NewNode(simplified()->ObjectIsNaN(), input); diff --git a/deps/v8/src/compiler/js-native-context-specialization.cc b/deps/v8/src/compiler/js-native-context-specialization.cc index 0b7b2913b85d50..a2fe6c18295766 100644 --- a/deps/v8/src/compiler/js-native-context-specialization.cc +++ b/deps/v8/src/compiler/js-native-context-specialization.cc @@ -570,9 +570,12 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess( if (receiver_maps.length() == 1) { Handle receiver_map = receiver_maps.first(); if (receiver_map->IsJSGlobalProxyMap()) { - Context* receiver_context = - JSFunction::cast(receiver_map->GetConstructor())->native_context(); - if (receiver_context == *native_context()) { + Object* maybe_constructor = receiver_map->GetConstructor(); + // Detached global proxies have |null| as their constructor. + if (maybe_constructor->IsJSFunction() && + JSFunction::cast(maybe_constructor)->has_context() && + JSFunction::cast(maybe_constructor)->native_context() == + *native_context()) { return ReduceGlobalAccess(node, receiver, value, name, access_mode, index); } @@ -797,17 +800,6 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccessFromNexus( } } - // Check if the {nexus} reports type feedback for the IC. - if (nexus.IsUninitialized()) { - if ((flags() & kDeoptimizationEnabled) && - (flags() & kBailoutOnUninitialized)) { - return ReduceSoftDeoptimize( - node, - DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); - } - return NoChange(); - } - // Extract receiver maps from the IC using the {nexus}. MapHandleList receiver_maps; if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { @@ -1192,17 +1184,6 @@ Reduction JSNativeContextSpecialization::ReduceKeyedAccess( } } - // Check if the {nexus} reports type feedback for the IC. - if (nexus.IsUninitialized()) { - if ((flags() & kDeoptimizationEnabled) && - (flags() & kBailoutOnUninitialized)) { - return ReduceSoftDeoptimize( - node, - DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess); - } - return NoChange(); - } - // Extract receiver maps from the {nexus}. MapHandleList receiver_maps; if (!ExtractReceiverMaps(receiver, effect, nexus, &receiver_maps)) { @@ -2248,7 +2229,10 @@ bool JSNativeContextSpecialization::ExtractReceiverMaps( } return true; } - return false; + // Check if the {nexus} actually reports feedback for the IC. We return + // true if the IC is still uninitialized, which translates to a SOFT + // deoptimization exit in the callers. + return nexus.IsUninitialized(); } bool JSNativeContextSpecialization::InferReceiverMaps( diff --git a/deps/v8/src/compiler/machine-operator.cc b/deps/v8/src/compiler/machine-operator.cc index 2ea55779440cdc..a07e0596876d79 100644 --- a/deps/v8/src/compiler/machine-operator.cc +++ b/deps/v8/src/compiler/machine-operator.cc @@ -135,7 +135,6 @@ MachineType AtomicExchangeRepresentationOf(Operator const* op) { V(Word32Clz, Operator::kNoProperties, 1, 0, 1) \ V(Word64Clz, Operator::kNoProperties, 1, 0, 1) \ V(BitcastTaggedToWord, Operator::kNoProperties, 1, 0, 1) \ - V(BitcastWordToTagged, Operator::kNoProperties, 1, 0, 1) \ V(BitcastWordToTaggedSigned, Operator::kNoProperties, 1, 0, 1) \ V(TruncateFloat64ToWord32, Operator::kNoProperties, 1, 0, 1) \ V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1) \ @@ -607,6 +606,19 @@ struct MachineOperatorGlobalCache { ATOMIC_TYPE_LIST(ATOMIC_EXCHANGE) #undef ATOMIC_EXCHANGE + // The {BitcastWordToTagged} operator must not be marked as pure (especially + // not idempotent), because otherwise the splitting logic in the Scheduler + // might decide to split these operators, thus potentially creating live + // ranges of allocation top across calls or other things that might allocate. + // See https://bugs.chromium.org/p/v8/issues/detail?id=6059 for more details. + struct BitcastWordToTaggedOperator : public Operator { + BitcastWordToTaggedOperator() + : Operator(IrOpcode::kBitcastWordToTagged, + Operator::kEliminatable | Operator::kNoWrite, + "BitcastWordToTagged", 1, 0, 0, 1, 0, 0) {} + }; + BitcastWordToTaggedOperator kBitcastWordToTagged; + struct DebugBreakOperator : public Operator { DebugBreakOperator() : Operator(IrOpcode::kDebugBreak, Operator::kNoThrow, "DebugBreak", 0, @@ -784,6 +796,10 @@ const Operator* MachineOperatorBuilder::UnsafePointerAdd() { return &cache_.kUnsafePointerAdd; } +const Operator* MachineOperatorBuilder::BitcastWordToTagged() { + return &cache_.kBitcastWordToTagged; +} + const Operator* MachineOperatorBuilder::DebugBreak() { return &cache_.kDebugBreak; } diff --git a/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc b/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc index 4a25c2cd658320..ab3c3bc587c72c 100644 --- a/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc +++ b/deps/v8/src/compiler/mips64/instruction-selector-mips64.cc @@ -686,7 +686,7 @@ void InstructionSelector::VisitWord32Shr(Node* node) { if (m.left().IsWord32And() && m.right().HasValue()) { uint32_t lsb = m.right().Value() & 0x1f; Int32BinopMatcher mleft(m.left().node()); - if (mleft.right().HasValue()) { + if (mleft.right().HasValue() && mleft.right().Value() != 0) { // Select Ext for Shr(And(x, mask), imm) where the result of the mask is // shifted into the least-significant bits. uint32_t mask = (mleft.right().Value() >> lsb) << lsb; @@ -779,7 +779,7 @@ void InstructionSelector::VisitWord64Shr(Node* node) { if (m.left().IsWord64And() && m.right().HasValue()) { uint32_t lsb = m.right().Value() & 0x3f; Int64BinopMatcher mleft(m.left().node()); - if (mleft.right().HasValue()) { + if (mleft.right().HasValue() && mleft.right().Value() != 0) { // Select Dext for Shr(And(x, mask), imm) where the result of the mask is // shifted into the least-significant bits. uint64_t mask = (mleft.right().Value() >> lsb) << lsb; diff --git a/deps/v8/src/compiler/ppc/code-generator-ppc.cc b/deps/v8/src/compiler/ppc/code-generator-ppc.cc index 455b0ae97e8c50..80b407c6ecfa83 100644 --- a/deps/v8/src/compiler/ppc/code-generator-ppc.cc +++ b/deps/v8/src/compiler/ppc/code-generator-ppc.cc @@ -1978,6 +1978,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kAtomicStoreWord32: ASSEMBLE_ATOMIC_STORE_INTEGER(stw, stwx); break; + case kAtomicExchangeInt8: + case kAtomicExchangeUint8: + case kAtomicExchangeInt16: + case kAtomicExchangeUint16: + case kAtomicExchangeWord32: + UNREACHABLE(); + break; default: UNREACHABLE(); break; diff --git a/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc b/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc index c2770b3ce8539c..7127472361bdd0 100644 --- a/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc +++ b/deps/v8/src/compiler/ppc/instruction-selector-ppc.cc @@ -2113,6 +2113,8 @@ void InstructionSelector::VisitAtomicStore(Node* node) { 0, nullptr, input_count, inputs); } +void InstructionSelector::VisitAtomicExchange(Node* node) { UNIMPLEMENTED(); } + // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { diff --git a/deps/v8/src/compiler/s390/code-generator-s390.cc b/deps/v8/src/compiler/s390/code-generator-s390.cc index ddf68562b861e7..916323b22c7406 100644 --- a/deps/v8/src/compiler/s390/code-generator-s390.cc +++ b/deps/v8/src/compiler/s390/code-generator-s390.cc @@ -2260,6 +2260,138 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( case kAtomicStoreWord32: __ StoreW(i.InputRegister(0), i.MemoryOperand(NULL, 1)); break; +// 0x aa bb cc dd +// index = 3..2..1..0 +#define ATOMIC_EXCHANGE(start, end, shift_amount, offset) \ + { \ + Label do_cs; \ + __ LoadlW(output, MemOperand(r1)); \ + __ bind(&do_cs); \ + __ llgfr(r0, output); \ + __ risbg(r0, value, Operand(start), Operand(end), Operand(shift_amount), \ + false); \ + __ csy(output, r0, MemOperand(r1, offset)); \ + __ bne(&do_cs, Label::kNear); \ + __ srl(output, Operand(shift_amount)); \ + } +#ifdef V8_TARGET_BIG_ENDIAN +#define ATOMIC_EXCHANGE_BYTE(i) \ + { \ + constexpr int idx = (i); \ + static_assert(idx <= 3 && idx >= 0, "idx is out of range!"); \ + constexpr int start = 32 + 8 * idx; \ + constexpr int end = start + 7; \ + constexpr int shift_amount = (3 - idx) * 8; \ + ATOMIC_EXCHANGE(start, end, shift_amount, -idx); \ + } +#define ATOMIC_EXCHANGE_HALFWORD(i) \ + { \ + constexpr int idx = (i); \ + static_assert(idx <= 1 && idx >= 0, "idx is out of range!"); \ + constexpr int start = 32 + 16 * idx; \ + constexpr int end = start + 15; \ + constexpr int shift_amount = (1 - idx) * 16; \ + ATOMIC_EXCHANGE(start, end, shift_amount, -idx * 2); \ + } +#else +#define ATOMIC_EXCHANGE_BYTE(i) \ + { \ + constexpr int idx = (i); \ + static_assert(idx <= 3 && idx >= 0, "idx is out of range!"); \ + constexpr int start = 32 + 8 * (3 - idx); \ + constexpr int end = start + 7; \ + constexpr int shift_amount = idx * 8; \ + ATOMIC_EXCHANGE(start, end, shift_amount, -idx); \ + } +#define ATOMIC_EXCHANGE_HALFWORD(i) \ + { \ + constexpr int idx = (i); \ + static_assert(idx <= 1 && idx >= 0, "idx is out of range!"); \ + constexpr int start = 32 + 16 * (1 - idx); \ + constexpr int end = start + 15; \ + constexpr int shift_amount = idx * 16; \ + ATOMIC_EXCHANGE(start, end, shift_amount, -idx * 2); \ + } +#endif + case kAtomicExchangeInt8: + case kAtomicExchangeUint8: { + Register base = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register output = i.OutputRegister(); + Label three, two, one, done; + __ la(r1, MemOperand(base, index)); + __ tmll(r1, Operand(3)); + __ b(Condition(1), &three); + __ b(Condition(2), &two); + __ b(Condition(4), &one); + + // end with 0b00 + ATOMIC_EXCHANGE_BYTE(0); + __ b(&done); + + // ending with 0b01 + __ bind(&one); + ATOMIC_EXCHANGE_BYTE(1); + __ b(&done); + + // ending with 0b10 + __ bind(&two); + ATOMIC_EXCHANGE_BYTE(2); + __ b(&done); + + // ending with 0b11 + __ bind(&three); + ATOMIC_EXCHANGE_BYTE(3); + + __ bind(&done); + if (opcode == kAtomicExchangeInt8) { + __ lbr(output, output); + } else { + __ llcr(output, output); + } + break; + } + case kAtomicExchangeInt16: + case kAtomicExchangeUint16: { + Register base = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register output = i.OutputRegister(); + Label two, unaligned, done; + __ la(r1, MemOperand(base, index)); + __ tmll(r1, Operand(3)); + __ b(Condition(2), &two); + + // end with 0b00 + ATOMIC_EXCHANGE_HALFWORD(0); + __ b(&done); + + // ending with 0b10 + __ bind(&two); + ATOMIC_EXCHANGE_HALFWORD(1); + + __ bind(&done); + if (opcode == kAtomicExchangeInt8) { + __ lhr(output, output); + } else { + __ llhr(output, output); + } + break; + } + case kAtomicExchangeWord32: { + Register base = i.InputRegister(0); + Register index = i.InputRegister(1); + Register value = i.InputRegister(2); + Register output = i.OutputRegister(); + Label do_cs; + __ lay(r1, MemOperand(base, index)); + __ LoadlW(output, MemOperand(r1)); + __ bind(&do_cs); + __ cs(output, value, MemOperand(r1)); + __ bne(&do_cs, Label::kNear); + break; + } default: UNREACHABLE(); break; diff --git a/deps/v8/src/compiler/s390/instruction-selector-s390.cc b/deps/v8/src/compiler/s390/instruction-selector-s390.cc index 3a27f191af6695..3476f1a5c58d54 100644 --- a/deps/v8/src/compiler/s390/instruction-selector-s390.cc +++ b/deps/v8/src/compiler/s390/instruction-selector-s390.cc @@ -2517,6 +2517,40 @@ void InstructionSelector::VisitAtomicStore(Node* node) { inputs); } +void InstructionSelector::VisitAtomicExchange(Node* node) { + S390OperandGenerator g(this); + Node* base = node->InputAt(0); + Node* index = node->InputAt(1); + Node* value = node->InputAt(2); + ArchOpcode opcode = kArchNop; + MachineType type = AtomicExchangeRepresentationOf(node->op()); + if (type == MachineType::Int8()) { + opcode = kAtomicExchangeInt8; + } else if (type == MachineType::Uint8()) { + opcode = kAtomicExchangeUint8; + } else if (type == MachineType::Int16()) { + opcode = kAtomicExchangeInt16; + } else if (type == MachineType::Uint16()) { + opcode = kAtomicExchangeUint16; + } else if (type == MachineType::Int32() || type == MachineType::Uint32()) { + opcode = kAtomicExchangeWord32; + } else { + UNREACHABLE(); + return; + } + + AddressingMode addressing_mode = kMode_MRR; + InstructionOperand inputs[3]; + size_t input_count = 0; + inputs[input_count++] = g.UseUniqueRegister(base); + inputs[input_count++] = g.UseUniqueRegister(index); + inputs[input_count++] = g.UseUniqueRegister(value); + InstructionOperand outputs[1]; + outputs[0] = g.UseUniqueRegister(node); + InstructionCode code = opcode | AddressingModeField::encode(addressing_mode); + Emit(code, 1, outputs, input_count, inputs); +} + // static MachineOperatorBuilder::Flags InstructionSelector::SupportedMachineOperatorFlags() { diff --git a/deps/v8/src/compiler/typed-optimization.cc b/deps/v8/src/compiler/typed-optimization.cc index bc0d80ade0aeaf..76ae9d48ec1b71 100644 --- a/deps/v8/src/compiler/typed-optimization.cc +++ b/deps/v8/src/compiler/typed-optimization.cc @@ -219,11 +219,6 @@ Reduction TypedOptimization::ReduceNumberFloor(Node* node) { NodeProperties::SetType(node, lhs_type); return Changed(node); } - if (lhs_type->Is(Type::Signed32()) && rhs_type->Is(Type::Unsigned32())) { - NodeProperties::ChangeOp(node, simplified()->NumberToInt32()); - NodeProperties::SetType(node, lhs_type); - return Changed(node); - } } return NoChange(); } diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc index 9cf30fba3967ce..731fdb37352876 100644 --- a/deps/v8/src/d8.cc +++ b/deps/v8/src/d8.cc @@ -881,11 +881,8 @@ MaybeLocal Shell::CreateRealm( Local global_template = CreateGlobalTemplate(isolate); Local context = Context::New(isolate, NULL, global_template, global_object); - if (context.IsEmpty()) { - DCHECK(try_catch.HasCaught()); - try_catch.ReThrow(); - return MaybeLocal(); - } + DCHECK(!try_catch.HasCaught()); + if (context.IsEmpty()) return MaybeLocal(); InitializeModuleEmbedderData(context); data->realms_[index].Reset(isolate, context); args.GetReturnValue().Set(index); @@ -2033,6 +2030,8 @@ class InspectorClient : public v8_inspector::V8InspectorClient { .ToLocalChecked(); CHECK(context->Global()->Set(context, function_name, function).FromJust()); + v8::debug::SetLiveEditEnabled(isolate_, true); + context_.Reset(isolate_, context); } diff --git a/deps/v8/src/date.cc b/deps/v8/src/date.cc index d0ff192b6ad16b..6471bdb00af507 100644 --- a/deps/v8/src/date.cc +++ b/deps/v8/src/date.cc @@ -39,6 +39,8 @@ void DateCache::ResetDateCache() { local_offset_ms_ = kInvalidLocalOffsetInMs; ymd_valid_ = false; tz_cache_->Clear(); + tz_name_ = nullptr; + dst_tz_name_ = nullptr; } diff --git a/deps/v8/src/date.h b/deps/v8/src/date.h index 1a3b65638ce951..5de2b84408634e 100644 --- a/deps/v8/src/date.h +++ b/deps/v8/src/date.h @@ -93,7 +93,12 @@ class DateCache { if (time_ms < 0 || time_ms > kMaxEpochTimeInMs) { time_ms = EquivalentTime(time_ms); } - return tz_cache_->LocalTimezone(static_cast(time_ms)); + bool is_dst = DaylightSavingsOffsetInMs(time_ms) != 0; + const char** name = is_dst ? &dst_tz_name_ : &tz_name_; + if (*name == nullptr) { + *name = tz_cache_->LocalTimezone(static_cast(time_ms)); + } + return *name; } // ECMA 262 - 15.9.5.26 @@ -276,6 +281,10 @@ class DateCache { int ymd_month_; int ymd_day_; + // Timezone name cache + const char* tz_name_; + const char* dst_tz_name_; + base::TimezoneCache* tz_cache_; }; diff --git a/deps/v8/src/debug/arm64/debug-arm64.cc b/deps/v8/src/debug/arm64/debug-arm64.cc index 06929c63b6ce6d..c6c43d647d8011 100644 --- a/deps/v8/src/debug/arm64/debug-arm64.cc +++ b/deps/v8/src/debug/arm64/debug-arm64.cc @@ -84,7 +84,6 @@ bool DebugCodegen::DebugBreakSlotIsPatched(Address pc) { void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, DebugBreakCallHelperMode mode) { __ RecordComment("Debug break"); - Register scratch = x10; { FrameScope scope(masm, StackFrame::INTERNAL); diff --git a/deps/v8/src/debug/debug-evaluate.cc b/deps/v8/src/debug/debug-evaluate.cc index eca0b360d976df..bb3e85baafdb1a 100644 --- a/deps/v8/src/debug/debug-evaluate.cc +++ b/deps/v8/src/debug/debug-evaluate.cc @@ -210,7 +210,6 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate, void DebugEvaluate::ContextBuilder::UpdateValues() { - // TODO(yangguo): remove updating values. for (int i = 0; i < context_chain_.length(); i++) { ContextChainElement element = context_chain_[i]; if (!element.materialized_object.is_null()) { diff --git a/deps/v8/src/debug/debug-interface.h b/deps/v8/src/debug/debug-interface.h index bbd6f6ac7f1c9e..21dd0f08c1802c 100644 --- a/deps/v8/src/debug/debug-interface.h +++ b/deps/v8/src/debug/debug-interface.h @@ -61,7 +61,7 @@ MaybeLocal Call(Local context, v8::Local fun, * (default Isolate if not provided). V8 will abort if LiveEdit is * unexpectedly used. LiveEdit is enabled by default. */ -void SetLiveEditEnabled(Isolate* isolate, bool enable); +V8_EXPORT_PRIVATE void SetLiveEditEnabled(Isolate* isolate, bool enable); // Schedule a debugger break to happen when JavaScript code is run // in the given isolate. diff --git a/deps/v8/src/debug/debug.cc b/deps/v8/src/debug/debug.cc index 0bdc22596c1cf0..5cff7f4a347fd7 100644 --- a/deps/v8/src/debug/debug.cc +++ b/deps/v8/src/debug/debug.cc @@ -42,7 +42,7 @@ Debug::Debug(Isolate* isolate) is_active_(false), hook_on_function_call_(false), is_suppressed_(false), - live_edit_enabled_(true), // TODO(yangguo): set to false by default. + live_edit_enabled_(false), break_disabled_(false), break_points_active_(true), break_on_exception_(false), @@ -815,7 +815,7 @@ void Debug::ClearAllBreakPoints() { } void Debug::FloodWithOneShot(Handle shared) { - if (!shared->IsSubjectToDebugging() || IsBlackboxed(shared)) return; + if (IsBlackboxed(shared)) return; // Make sure the function is compiled and has set up the debug info. if (!EnsureDebugInfo(shared)) return; Handle debug_info(shared->GetDebugInfo()); @@ -960,7 +960,7 @@ void Debug::PrepareStepOnThrow() { } Handle info( summaries[i].AsJavaScript().function()->shared()); - if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue; + if (IsBlackboxed(info)) continue; FloodWithOneShot(info); return; } @@ -1055,7 +1055,7 @@ void Debug::PrepareStep(StepAction step_action) { in_current_frame = false; continue; } - if (!info->IsSubjectToDebugging() || IsBlackboxed(info)) continue; + if (IsBlackboxed(info)) continue; FloodWithOneShot(info); thread_local_.target_frame_count_ = current_frame_count; return; @@ -1732,25 +1732,23 @@ v8::Local GetDebugEventContext(Isolate* isolate) { } // anonymous namespace bool Debug::IsExceptionBlackboxed(bool uncaught) { - JavaScriptFrameIterator it(isolate_); - if (it.done()) return false; // Uncaught exception is blackboxed if all current frames are blackboxed, // caught exception if top frame is blackboxed. - bool is_top_frame_blackboxed = IsFrameBlackboxed(it.frame()); + StackTraceFrameIterator it(isolate_); + while (!it.done() && it.is_wasm()) it.Advance(); + bool is_top_frame_blackboxed = + !it.done() ? IsFrameBlackboxed(it.javascript_frame()) : true; if (!uncaught || !is_top_frame_blackboxed) return is_top_frame_blackboxed; return AllFramesOnStackAreBlackboxed(); } bool Debug::IsFrameBlackboxed(JavaScriptFrame* frame) { HandleScope scope(isolate_); - if (!frame->HasInlinedFrames()) { - Handle shared(frame->function()->shared(), isolate_); - return IsBlackboxed(shared); - } List> infos; frame->GetFunctions(&infos); - for (const auto& info : infos) + for (const auto& info : infos) { if (!IsBlackboxed(info)) return false; + } return true; } @@ -1970,22 +1968,23 @@ debug::Location GetDebugLocation(Handle