From 2e2687fff9752eab9ca6faca12f3cf6fb695200b Mon Sep 17 00:00:00 2001 From: Ishin Pavel Date: Mon, 29 May 2023 16:03:07 +0300 Subject: [PATCH] Replace intrinsics without profiling on Deoptimize instruction Signed-off-by: Ishin Pavel --- compiler/ecma_compiler.yaml | 6 ++++++ compiler/templates/ecmascript_inst_builder_gen.cpp.erb | 7 ++++++- runtime/compiler/ecmascript_runtime_interface.cpp | 8 +++++++- runtime/ecma_language_context.cpp | 4 ++++ tests/checked/string_equals.js | 4 ++-- 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/compiler/ecma_compiler.yaml b/compiler/ecma_compiler.yaml index dac6af4c6..042e401cb 100644 --- a/compiler/ecma_compiler.yaml +++ b/compiler/ecma_compiler.yaml @@ -29,4 +29,10 @@ options: type: bool default: true description: Use profiling data when expanding newobj intrinsic + tags: [perf] + +- name: compiler-ecma-replace-intrinsics-to-deopt + type: bool + default: true + description: Replace intrinsics without profiling on deoptimize instruction tags: [perf] \ No newline at end of file diff --git a/compiler/templates/ecmascript_inst_builder_gen.cpp.erb b/compiler/templates/ecmascript_inst_builder_gen.cpp.erb index ad0498f06..e8d76012d 100644 --- a/compiler/templates/ecmascript_inst_builder_gen.cpp.erb +++ b/compiler/templates/ecmascript_inst_builder_gen.cpp.erb @@ -173,6 +173,9 @@ void InstBuilder::BuildEcmaAsIntrinsics(const BytecodeInstruction* bc_inst) // N bool is_type_profiled = false; auto operand_type = GetRuntime()->GetProfilingAnyType(profile, bc_inst, <%= input_index %>, &allowed_input_type, &is_type_profiled); input = BuildAnyTypeCheckInst(GetPc(bc_inst->GetAddress()), input, inst_save_state, operand_type, is_type_profiled, allowed_input_type); + if (OPTIONS.IsCompilerEcmaReplaceIntrinsicsToDeopt() && !is_type_profiled) { + inst->SetReplaceOnDeoptimize(); + } } % end inst->AppendInput(input); @@ -235,7 +238,9 @@ void InstBuilder::BuildEcmaAsIntrinsics(const BytecodeInstruction* bc_inst) // N % idx = inst.profile.properties.include?('operand_types_2') ? 1 : 0 auto operand_type = GetRuntime()->GetProfilingAnyType(profile, bc_inst, <%= idx %>, &allowed_input_type, &is_type_profiled); input = BuildAnyTypeCheckInst(GetPc(bc_inst->GetAddress()), input, inst_save_state, operand_type, is_type_profiled, allowed_input_type); - + if (OPTIONS.IsCompilerEcmaReplaceIntrinsicsToDeopt() && !is_type_profiled) { + inst->SetReplaceOnDeoptimize(); + } } % end inst->AppendInput(input); diff --git a/runtime/compiler/ecmascript_runtime_interface.cpp b/runtime/compiler/ecmascript_runtime_interface.cpp index d7c613467..6871d4ec3 100644 --- a/runtime/compiler/ecmascript_runtime_interface.cpp +++ b/runtime/compiler/ecmascript_runtime_interface.cpp @@ -230,6 +230,10 @@ compiler::AnyBaseType EcmaRuntimeInterface::GetProfilingAnyType(RuntimeInterface case profiling::ProfilingKind::UNARY_ARITH: { UnaryOperationProfile p(ecma_prof); type = p.GetOperandType(index).GetType(); + if (type != ProfilingTypeBits::NONE) { + *is_type_profiled = true; + } + if (type == ProfilingTypeBits::STRING) { return compiler::AnyBaseType::ECMASCRIPT_STRING_TYPE; } @@ -241,6 +245,9 @@ compiler::AnyBaseType EcmaRuntimeInterface::GetProfilingAnyType(RuntimeInterface case profiling::ProfilingKind::BINARY_ARITH: { BinaryOperationProfile p(ecma_prof); type = p.GetOperandType(index).GetType(); + if (type != ProfilingTypeBits::NONE) { + *is_type_profiled = true; + } auto other_operand_type = p.GetOperandType(1 - index).GetType(); if (type == ProfilingTypeBits::STRING && other_operand_type == ProfilingTypeBits::STRING) { return compiler::AnyBaseType::ECMASCRIPT_STRING_TYPE; @@ -264,7 +271,6 @@ compiler::AnyBaseType EcmaRuntimeInterface::GetProfilingAnyType(RuntimeInterface return compiler::AnyBaseType::UNDEFINED_TYPE; } - *is_type_profiled = true; if (type == ProfilingTypeBits::BOOLEAN) { return compiler::AnyBaseType::ECMASCRIPT_BOOLEAN_TYPE; } diff --git a/runtime/ecma_language_context.cpp b/runtime/ecma_language_context.cpp index 3cc6d5a60..5c03d5986 100644 --- a/runtime/ecma_language_context.cpp +++ b/runtime/ecma_language_context.cpp @@ -113,6 +113,10 @@ void EcmaLanguageContext::RestoreEnv(Frame *current_iframe, const StackWalker::E ecmascript::JSFunction::Cast(ecmascript::JSTaggedValue(env_data[VRegType::THIS_FUNC]).GetHeapObject())); iframe_env->SetConstantPool(ecmascript::ConstantPool::Cast(env_data[VRegType::CONST_POOL])); iframe_env->SetLexicalEnv(ecmascript::LexicalEnv::Cast(env_data[VRegType::LEX_ENV])); + // restore func parameter + auto num_vregs = current_iframe->GetMethod()->GetNumVregs(); + DynamicFrameHandler frame_handler(current_iframe); + frame_handler.GetVReg(num_vregs + ecmascript::js_method_args::FUNC_IDX).SetValue(env_data[VRegType::THIS_FUNC]); } void EcmaLanguageContext::InitializeOsrCframeSlots(Span param_slots) const diff --git a/tests/checked/string_equals.js b/tests/checked/string_equals.js index e01ae9d2f..2fc7186d7 100644 --- a/tests/checked/string_equals.js +++ b/tests/checked/string_equals.js @@ -14,7 +14,7 @@ */ //! CHECKER String equals with profiled type - call fastpath EcmaStringEquals -//! RUN options: "--no-async-jit --compiler-hotness-threshold=1 --compiler-regex _GLOBAL::test_.*", entry: "_GLOBAL::func_main_0" +//! RUN options: "--no-async-jit --compiler-hotness-threshold=1 --compiler-ecma-replace-intrinsics-to-deopt=false --compiler-regex _GLOBAL::test_.*", entry: "_GLOBAL::func_main_0" //! EVENT_NOT /Deoptimization.*/ //! METHOD "test_eq" //! PASS_BEFORE "TypesResolving" @@ -29,7 +29,7 @@ //! INST_COUNT "Intrinsic.EcmaStringEquals", 1 //! CHECKER String equals without profiled type - call fastpath StrictEq/StrictNotEq -//! RUN options: "--no-async-jit --compiler-hotness-threshold=0 --compiler-regex _GLOBAL::test_.*", entry: "_GLOBAL::func_main_0" +//! RUN options: "--no-async-jit --compiler-hotness-threshold=0 --compiler-ecma-replace-intrinsics-to-deopt=false --compiler-regex _GLOBAL::test_.*", entry: "_GLOBAL::func_main_0" //! METHOD "test_eq" //! PASS_AFTER "Codegen" //! INST_NOT "Intrinsic.EcmaStringEquals" -- Gitee