Add Option Enable Force IC

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAPV03

Decription: Add Option for enable force ic
Test: All stable and performance teset suite

Change-Id: I7f4f6a99f1e4198a2f5426ad221e4d1bb5ce7d7c
Signed-off-by: zhuangkudecha <fuhao71@huawei.com>
This commit is contained in:
zhuangkudecha 2024-09-07 14:38:12 +08:00
parent 4023ece63b
commit 68de2d91d0
19 changed files with 205 additions and 7 deletions

View File

@ -17,9 +17,12 @@
#include "ecmascript/base/number_helper.h"
#include "ecmascript/compiler/circuit_builder_helper.h"
#include "ecmascript/compiler/rt_call_signature.h"
#include "ecmascript/compiler/share_gate_meta_data.h"
#include "ecmascript/compiler/interpreter_stub-inl.h"
#include "ecmascript/compiler/stub_builder.h"
#include "ecmascript/compiler/stub_builder-inl.h"
#include "ecmascript/compiler/variable_type.h"
#include "ecmascript/ic/profile_type_info.h"
namespace panda::ecmascript::kungfu {
@ -245,12 +248,17 @@ void ProfilerStubBuilder::ProfileCall(
Label targetIsNotHot(env);
Label targetIsHot(env);
Label currentIsHot(env);
Label updateTargetIC(env);
BRANCH(IsProfileTypeInfoHotAndValid(targetProfileInfo), &targetIsHot, &targetIsNotHot);
Bind(&targetIsNotHot);
BRANCH(IsEnableForceIC(glue), &updateTargetIC, &targetIsHot);
Bind(&updateTargetIC);
{
CallRuntime(glue, RTSTUB_ID(UpdateHotnessCounterWithProf), { target });
Jump(&targetIsHot);
BRANCH(IsProfileTypeInfoHotAndValid(targetProfileInfo), &targetIsHot, &targetIsNotHot);
Bind(&targetIsNotHot);
{
CallRuntime(glue, RTSTUB_ID(UpdateHotnessCounterWithProf), { target });
Jump(&targetIsHot);
}
}
Bind(&targetIsHot);
{
@ -851,6 +859,13 @@ GateRef ProfilerStubBuilder::IsProfileTypeInfoHotAndValid(GateRef profileTypeInf
return ret;
}
GateRef ProfilerStubBuilder::IsEnableForceIC(GateRef glue)
{
auto env = GetEnvironment();
GateRef offset = IntPtr(JSThread::GlueData::GetIsEnableForceICOffSet(env->Is32Bit()));
return Load(VariableType::BOOL(), glue, offset);
}
void ProfilerStubBuilder::SetDumpPeriodIndex(GateRef glue, GateRef profileTypeInfo)
{
GateRef periodCounterOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);

View File

@ -137,6 +137,7 @@ private:
GateRef IsProfileTypeInfoPreDumped(GateRef profileTypeInfo);
GateRef IsProfileTypeInfoWithBigMethod(GateRef profileTypeInfo);
GateRef IsProfileTypeInfoHotAndValid(GateRef profileTypeInfo);
GateRef IsEnableForceIC(GateRef glue);
void SetDumpPeriodIndex(GateRef glue, GateRef profileTypeInfo);
void SetPreDumpPeriodIndex(GateRef glue, GateRef profileTypeInfo);
GateRef TaggedToTrackType(GateRef value);

View File

@ -16,6 +16,7 @@
#include "ecmascript/ecma_vm.h"
#include "ecmascript/builtins/builtins_ark_tools.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#ifdef ARK_SUPPORT_INTL
#include "ecmascript/builtins/builtins_collator.h"
#include "ecmascript/builtins/builtins_date_time_format.h"
@ -208,6 +209,7 @@ void EcmaVM::ResetPGOProfiler()
PGOProfilerManager::GetInstance()->Reset(pgoProfiler_, isEnablePGOProfiler);
thread_->SetPGOProfilerEnable(isEnablePGOProfiler);
thread_->CheckOrSwitchPGOStubs();
thread_->SetEnableForceIC(ecmascript::pgo::PGOProfilerManager::GetInstance()->IsEnableForceIC());
}
}

View File

@ -164,6 +164,9 @@ public:
bool PUBLIC_API IsEnablePGOProfiler() const;
bool PUBLIC_API IsEnableElementsKind() const;
bool PUBLIC_API IsEnableForceIC() const;
void SetEnableForceIC(bool isEnableForceIC);
bool Initialize();
void InitializeForJit(JitThread *thread);

View File

@ -135,6 +135,7 @@ const std::string PUBLIC_API HELP_OPTION_MSG =
"--enable-pgo-profiler: Enable pgo profiler to sample jsfunction call and output to file. "
"Default: 'false'\n"
"--enable-elements-kind: Enable elementsKind sampling and usage. Default: 'false'\n"
"--enable-force-ic: Enable force ic for pgo. Default: 'true'\n"
"--compiler-pgo-hotness-threshold: Set hotness threshold for pgo in aot compiler. Default: '2'\n"
"--compiler-pgo-profiler-path: The pgo file output dir or the pgo file dir of AOT compiler. Default: ''\n"
"--compiler-pgo-save-min-interval: Set the minimum time interval for automatically saving profile, "
@ -276,6 +277,7 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
{"enable-print-execute-time", required_argument, nullptr, OPTION_PRINT_EXECUTE_TIME},
{"enable-pgo-profiler", required_argument, nullptr, OPTION_ENABLE_PGO_PROFILER},
{"enable-elements-kind", required_argument, nullptr, OPTION_ENABLE_ELEMENTSKIND},
{"enable-force-ic", required_argument, nullptr, OPTION_ENABLE_FORCE_IC},
{"compiler-pgo-profiler-path", required_argument, nullptr, OPTION_COMPILER_PGO_PROFILER_PATH},
{"compiler-pgo-hotness-threshold", required_argument, nullptr, OPTION_COMPILER_PGO_HOTNESS_THRESHOLD},
{"compiler-pgo-save-min-interval", required_argument, nullptr, OPTION_COMPILER_PGO_SAVE_MIN_INTERVAL},
@ -733,6 +735,14 @@ bool JSRuntimeOptions::ParseCommand(const int argc, const char **argv)
return false;
}
break;
case OPTION_ENABLE_FORCE_IC:
ret = ParseBoolParam(&argBool);
if (ret) {
SetEnableForceIC(argBool);
} else {
return false;
}
break;
case OPTION_COMPILER_PGO_PROFILER_PATH:
if (*optarg == '\0') {
return false;

View File

@ -214,7 +214,8 @@ enum CommandValues {
OPTION_COMPILER_OPT_STRING,
OPTION_OPEN_ARK_TOOLS,
OPTION_COMPILER_OPT_FRAME_STATE_ELIMINATION,
OPTION_COMPILER_EMPTY_CATCH_FUNCTION
OPTION_COMPILER_EMPTY_CATCH_FUNCTION,
OPTION_ENABLE_FORCE_IC,
};
static_assert(OPTION_SPLIT_ONE == 64); // add new option at the bottom, DO NOT modify this value
static_assert(OPTION_SPLIT_TWO == 128); // add new option at the bottom, DO NOT modify this value
@ -1074,6 +1075,16 @@ public:
return enableElementsKind_;
}
void SetEnableForceIC(bool value)
{
enableForceIC_ = value;
}
bool IsEnableForceIC() const
{
return enableForceIC_;
}
void SetEnablePGOProfiler(bool value)
{
enablePGOProfiler_ = value;
@ -2049,6 +2060,7 @@ private:
bool enableValueNumbering_ {true};
bool enableOptString_ {true};
bool enableElementsKind_ {false};
bool enableForceIC_ {true};
bool enableInstrcutionCombine {true};
bool enableNewValueNumbering_ {true};
bool enableOptInlining_ {true};

View File

@ -20,6 +20,7 @@
#include "ecmascript/js_object-inl.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/runtime_call_id.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS) && !defined(PANDA_TARGET_IOS)
#include <sys/resource.h>
@ -96,6 +97,7 @@ JSThread *JSThread::Create(EcmaVM *vm)
jsThread->glueData_.stackLimit_ = GetAsmStackLimit();
jsThread->glueData_.stackStart_ = GetCurrentStackPosition();
jsThread->glueData_.isEnableElementsKind_ = vm->IsEnableElementsKind();
jsThread->glueData_.isEnableForceIC_ = ecmascript::pgo::PGOProfilerManager::GetInstance()->IsEnableForceIC();
jsThread->SetThreadId();
RegisterThread(jsThread);
@ -204,6 +206,16 @@ void JSThread::ClearException()
glueData_.exception_ = JSTaggedValue::Hole();
}
void JSThread::SetEnableForceIC(bool isEnableForceIC)
{
glueData_.isEnableForceIC_ = isEnableForceIC;
}
bool JSThread::IsEnableForceIC() const
{
return glueData_.isEnableForceIC_;
}
JSTaggedValue JSThread::GetCurrentLexenv() const
{
FrameHandler frameHandler(this);

View File

@ -290,6 +290,10 @@ public:
void ClearException();
void SetEnableForceIC(bool isEnableForceIC);
bool IsEnableForceIC() const;
void SetGlobalObject(JSTaggedValue globalObject)
{
glueData_.globalObject_ = globalObject;
@ -952,6 +956,7 @@ public:
base::AlignedPointer,
base::AlignedPointer,
base::AlignedUint32,
base::AlignedBool,
base::AlignedBool> {
enum class Index : size_t {
BcStubEntriesIndex = 0,
@ -995,6 +1000,7 @@ public:
StateAndFlagsIndex,
TaskInfoIndex,
IsEnableElementsKindIndex,
IsEnableForceIC,
NumOfMembers
};
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
@ -1225,6 +1231,11 @@ public:
return GetOffset<static_cast<size_t>(Index::IsEnableElementsKindIndex)>(isArch32);
}
static size_t GetIsEnableForceICOffSet(bool isArch32)
{
return GetOffset<static_cast<size_t>(Index::IsEnableForceIC)>(isArch32);
}
alignas(EAS) BCStubEntries bcStubEntries_ {};
alignas(EAS) JSTaggedValue exception_ {JSTaggedValue::Hole()};
alignas(EAS) JSTaggedValue globalObject_ {JSTaggedValue::Hole()};
@ -1266,6 +1277,7 @@ public:
alignas(EAS) ThreadStateAndFlags stateAndFlags_ {};
alignas(EAS) uintptr_t taskInfo_ {0};
alignas(EAS) bool isEnableElementsKind_ {false};
alignas(EAS) bool isEnableForceIC_ {true};
};
STATIC_ASSERT_EQ_ARCH(sizeof(GlueData), GlueData::SizeArch32, GlueData::SizeArch64);

View File

@ -20,6 +20,7 @@
#include "ecmascript/base/json_stringifier.h"
#include "ecmascript/base/typed_array_helper-inl.h"
#include "ecmascript/builtins/builtins_object.h"
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
#include "ecmascript/dfx/cpu_profiler/cpu_profiler.h"
#endif
@ -5234,8 +5235,10 @@ void JSNApi::PostFork(EcmaVM *vm, const RuntimeOption &option)
jsOption.SetEnableJIT(option.GetEnableJIT());
jsOption.SetEnableBaselineJIT(option.GetEnableBaselineJIT());
jsOption.SetMaxAotMethodSize(JSRuntimeOptions::MAX_APP_COMPILE_METHOD_SIZE);
jsOption.SetEnableForceIC(false);
ecmascript::pgo::PGOProfilerManager::GetInstance()->SetBundleName(option.GetBundleName());
ecmascript::pgo::PGOProfilerManager::GetInstance()->SetMaxAotMethodSize(jsOption.GetMaxAotMethodSize());
ecmascript::pgo::PGOProfilerManager::GetInstance()->SetEnableForceIC(jsOption.IsEnableForceIC());
JSRuntimeOptions runtimeOptions;
runtimeOptions.SetLogLevel(Log::LevelToString(Log::ConvertFromRuntime(option.GetLogLevel())));
Log::Initialize(runtimeOptions);

View File

@ -279,6 +279,16 @@ public:
return maxAotMethodSize_ != 0 && methodSize > maxAotMethodSize_;
}
bool IsEnableForceIC() const
{
return isEnableForceIC_;
}
void SetEnableForceIC(bool isEnableForceIC)
{
isEnableForceIC_ = isEnableForceIC;
}
private:
bool InitializeData()
{
@ -300,6 +310,7 @@ private:
os::memory::Mutex *mutex_ = new os::memory::Mutex();
std::set<std::shared_ptr<PGOProfiler>> profilers_;
bool isApFileCompatible_ {true};
bool isEnableForceIC_ {true};
uint32_t maxAotMethodSize_ {0};
};
} // namespace panda::ecmascript::pgo

View File

@ -51,6 +51,7 @@
#include "ecmascript/pgo_profiler/tests/pgo_context_mock.h"
#include "ecmascript/pgo_profiler/tests/pgo_encoder_mock.h"
#include "ecmascript/tests/test_helper.h"
#include "ecmascript/napi/include/jsnapi_expo.h"
using namespace panda;
using namespace panda::ecmascript;
@ -1422,4 +1423,22 @@ HWTEST_F_L0(PGOProfilerTest, PGODisableUnderAOTFailTest)
}
}
HWTEST_F_L0(PGOProfilerTest, EnableForceICTest)
{
RuntimeOption option;
EcmaVM* ecmaVM = JSNApi::CreateJSVM(option);
JSThread* jsThread = ecmaVM->GetJSThread();
JSRuntimeOptions& jsOption = ecmaVM->GetJSOptions();
EXPECT_TRUE(jsThread->IsEnableForceIC());
EXPECT_TRUE(jsOption.IsEnableForceIC());
EXPECT_TRUE(ecmascript::pgo::PGOProfilerManager::GetInstance()->IsEnableForceIC());
JSNApi::PreFork(ecmaVM);
JSNApi::PostFork(ecmaVM, option);
EXPECT_FALSE(jsThread->IsEnableForceIC());
EXPECT_FALSE(jsOption.IsEnableForceIC());
EXPECT_FALSE(ecmascript::pgo::PGOProfilerManager::GetInstance()->IsEnableForceIC());
JSNApi::DestroyJSVM(ecmaVM);
}
} // namespace panda::test

View File

@ -59,6 +59,7 @@ void Runtime::CreateIfFirstVm(const JSRuntimeOptions &options)
MemMapAllocator::GetInstance()->Initialize(ecmascript::DEFAULT_REGION_SIZE);
PGOProfilerManager::GetInstance()->Initialize(options.GetPGOProfilerPath(),
options.GetPGOHotnessThreshold());
PGOProfilerManager::GetInstance()->SetEnableForceIC(options.IsEnableForceIC());
ASSERT(instance_ == nullptr);
instance_ = new Runtime();
SharedHeap::CreateNewInstance();

View File

@ -233,6 +233,7 @@ group("ark_aot_ts_test") {
"pgo_forof_set",
"pgo_forof_string",
"pgo_forof_typed_array",
"pgo_force_ic",
"pgo_function_prototype",
"pgo_gettersetter",
"pgo_extrainfomap_expand",

View File

@ -0,0 +1,22 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//arkcompiler/ets_runtime/test/test_helper.gni")
host_aot_test_action("pgo_force_ic") {
deps = []
is_enable_pgo = true
is_enable_force_ic = false
log_option = " --log-info=trace"
use_distinct_slowpath_expect_path = true
}

View File

@ -0,0 +1,15 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
hello
false

View File

@ -0,0 +1,15 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
hello
false

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function forceIC() {
print("hello");
}
forceIC()
print(ArkTools.isAOTCompiled(forceIC)) // pgo:false, aot:false

View File

@ -0,0 +1,15 @@
# Copyright (c) 2024 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
hello
true

View File

@ -2383,6 +2383,7 @@ template("host_aot_test_action") {
_test_aot_arg_slowpath_ = "$target_out_dir/slowpath/${_target_name_}"
_test_aot_log_level = "info"
_test_expect_path_ = "${_src_dir_}/expect_output.txt"
_test_slowpath_expect_path_ = _test_expect_path_
_test_pgo_expect_path_ = "${_src_dir_}/pgo_expect_output.txt"
_is_test_llvm_only_ = TEST_LLVM_ONLY
if (!TEST_LLVM_ONLY && defined(invoker.is_test_llvm_only) &&
@ -2392,6 +2393,10 @@ template("host_aot_test_action") {
if (defined(invoker.use_one_expect_path) && invoker.use_one_expect_path) {
_test_pgo_expect_path_ = _test_expect_path_
}
if (defined(invoker.use_distinct_slowpath_expect_path) &&
invoker.use_distinct_slowpath_expect_path) {
_test_slowpath_expect_path_ = "${_src_dir_}/slowpath_expect_output.txt"
}
if (target_cpu == "x64" ||
(ark_standalone_build && run_with_qemu && host_os == "linux" &&
target_os == "ohos" && target_cpu == "arm64")) {
@ -2410,6 +2415,7 @@ template("host_aot_test_action") {
if (defined(invoker.gen_expect_output) && invoker.gen_expect_output) {
_test_expect_path_ = "$target_out_dir/expect_output.txt"
_test_pgo_expect_path_ = "$target_out_dir/pgo_expect_output.txt"
_test_slowpath_expect_path_ = _test_expect_path_
action("${_target_name_}GenExpectOutput") {
script = "$js_root/script/gen_expect_output.sh"
@ -2503,6 +2509,9 @@ template("host_aot_test_action") {
if (defined(invoker.log_option)) {
_aot_run_options_ += invoker.log_option
}
if (defined(invoker.is_enable_force_ic) && !invoker.is_enable_force_ic) {
_aot_run_options_ += " --enable-force-ic=false"
}
_aot_run_options_ += common_options
args = [
"--script-file",
@ -2940,7 +2949,7 @@ template("host_aot_test_action") {
"--timeout-limit",
"${_timeout_}",
"--expect-file",
rebase_path(_test_expect_path_),
rebase_path(_test_slowpath_expect_path_),
"--env-path",
rebase_path(_root_out_dir_) + "/arkcompiler/ets_runtime:" +
rebase_path(_root_out_dir_) + "/${_icu_path_}:" +
@ -3359,7 +3368,7 @@ template("host_aot_test_action") {
"--timeout-limit",
"${_timeout_}",
"--expect-file",
rebase_path(_test_expect_path_),
rebase_path(_test_slowpath_expect_path_),
"--env-path",
rebase_path(_root_out_dir_) + "/arkcompiler/ets_runtime:" +
rebase_path(_root_out_dir_) + "/${_icu_path_}:" +