mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-08 00:24:00 +00:00
!3020 Adapt to Hot Patch and Add Testcases
Merge pull request !3020 from lijiamin/master
This commit is contained in:
commit
0875afa157
@ -101,7 +101,12 @@ bool QuickFixLoader::LoadPatchInternal(JSThread *thread, const JSPandaFile *base
|
||||
}
|
||||
|
||||
if (!ReplaceMethod(thread, baseFile, patchFile, baseConstpoolValues.value())) {
|
||||
LOG_ECMA(ERROR) << "replace method failed";
|
||||
LOG_ECMA(ERROR) << "Replace method failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isHotPatch_ && !ExecutePatchMain(thread, patchPrograms, patchFile)) {
|
||||
LOG_ECMA(ERROR) << "Execute patch main failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -138,6 +143,13 @@ CVector<JSHandle<Program>> QuickFixLoader::ParseAllConstpoolWithMerge(JSThread *
|
||||
|
||||
uint32_t mainMethodIndex = jsPandaFile->GetMainMethodIndex(recordName);
|
||||
ASSERT(mainMethodIndex != 0);
|
||||
|
||||
const char *mainMethodName =
|
||||
MethodLiteral::GetMethodName(jsPandaFile, panda_file::File::EntityId(mainMethodIndex));
|
||||
if (!isHotPatch_ && std::strcmp(mainMethodName, JSPandaFile::PATCH_FUNCTION_NAME_0) == 0) {
|
||||
isHotPatch_ = true;
|
||||
}
|
||||
|
||||
if (!isNewVersion) {
|
||||
PandaFileTranslator::ParseFuncAndLiteralConstPool(vm, jsPandaFile, recordName, constpool);
|
||||
} else {
|
||||
@ -404,49 +416,48 @@ bool QuickFixLoader::UnloadPatch(JSThread *thread, const CString &patchFileName)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto &iter : baseConstpoolValues.value().get()) {
|
||||
uint32_t index = iter.first;
|
||||
ConstantPool *baseConstpool = ConstantPool::Cast((iter.second).GetTaggedObject());
|
||||
for (const auto &item : reservedBaseNormalMethodInfo_) {
|
||||
NormalMethodIndex normalMethodIndex = item.first;
|
||||
if (index == normalMethodIndex.constpoolNum) {
|
||||
uint32_t constpoolIndex = normalMethodIndex.constpoolIndex;
|
||||
MethodLiteral *base = item.second;
|
||||
|
||||
JSTaggedValue value = baseConstpool->GetObjectFromCache(constpoolIndex);
|
||||
ASSERT(value.IsMethod());
|
||||
Method *method = Method::Cast(value.GetTaggedObject());
|
||||
|
||||
JSTaggedValue baseConstpoolValue = FindConstpoolVal(thread, baseFile, base->GetMethodId());
|
||||
ReplaceMethodInner(thread, method, base, baseConstpoolValue);
|
||||
LOG_ECMA(INFO) << "Replace normal method: " << method->GetMethodName();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &item : reservedBaseClassMethodInfo_) {
|
||||
ClassMethodIndex classMethodIndex = item.first;
|
||||
if (index == classMethodIndex.constpoolNum) {
|
||||
uint32_t constpoolIndex = classMethodIndex.constpoolIndex;
|
||||
MethodLiteral *base = item.second;
|
||||
|
||||
TaggedArray *classLiteral = TaggedArray::Cast(baseConstpool->GetObjectFromCache(constpoolIndex));
|
||||
JSTaggedValue value = classLiteral->Get(thread, classMethodIndex.literalIndex);
|
||||
ASSERT(value.IsJSFunctionBase());
|
||||
JSFunctionBase *func = JSFunctionBase::Cast(value.GetTaggedObject());
|
||||
Method *method = Method::Cast(func->GetMethod().GetTaggedObject());
|
||||
for (const auto &item : reservedBaseNormalMethodInfo_) {
|
||||
NormalMethodIndex normalMethodIndex = item.first;
|
||||
ConstantPool *baseConstpool = ConstantPool::Cast(
|
||||
(baseConstpoolValues.value().get()[normalMethodIndex.constpoolNum]).GetTaggedObject());
|
||||
|
||||
JSTaggedValue baseConstpoolValue = FindConstpoolVal(thread, baseFile, base->GetMethodId());
|
||||
ReplaceMethodInner(thread, method, base, baseConstpoolValue);
|
||||
LOG_ECMA(INFO) << "Replace class method: " << method->GetMethodName();
|
||||
}
|
||||
}
|
||||
uint32_t constpoolIndex = normalMethodIndex.constpoolIndex;
|
||||
MethodLiteral *base = item.second;
|
||||
|
||||
JSTaggedValue value = baseConstpool->GetObjectFromCache(constpoolIndex);
|
||||
ASSERT(value.IsMethod());
|
||||
Method *method = Method::Cast(value.GetTaggedObject());
|
||||
|
||||
JSTaggedValue baseConstpoolValue = FindConstpoolVal(thread, baseFile, base->GetMethodId());
|
||||
ReplaceMethodInner(thread, method, base, baseConstpoolValue);
|
||||
LOG_ECMA(INFO) << "Replace normal method: " << method->GetMethodName();
|
||||
}
|
||||
|
||||
for (auto &item : reservedBaseClassMethodInfo_) {
|
||||
ClassMethodIndex classMethodIndex = item.first;
|
||||
ConstantPool *baseConstpool = ConstantPool::Cast(
|
||||
(baseConstpoolValues.value().get()[classMethodIndex.constpoolNum]).GetTaggedObject());
|
||||
|
||||
uint32_t constpoolIndex = classMethodIndex.constpoolIndex;
|
||||
MethodLiteral *base = item.second;
|
||||
|
||||
TaggedArray *classLiteral = TaggedArray::Cast(baseConstpool->GetObjectFromCache(constpoolIndex));
|
||||
JSTaggedValue value = classLiteral->Get(thread, classMethodIndex.literalIndex);
|
||||
ASSERT(value.IsJSFunctionBase());
|
||||
JSFunctionBase *func = JSFunctionBase::Cast(value.GetTaggedObject());
|
||||
Method *method = Method::Cast(func->GetMethod().GetTaggedObject());
|
||||
|
||||
JSTaggedValue baseConstpoolValue = FindConstpoolVal(thread, baseFile, base->GetMethodId());
|
||||
ReplaceMethodInner(thread, method, base, baseConstpoolValue);
|
||||
LOG_ECMA(INFO) << "Replace class method: " << method->GetMethodName();
|
||||
}
|
||||
|
||||
vm->GetJsDebuggerManager()->GetHotReloadManager()->NotifyPatchUnloaded(patchFile);
|
||||
|
||||
ClearReservedInfo();
|
||||
ClearPatchInfo(thread, patchFileName);
|
||||
|
||||
isHotPatch_ = false;
|
||||
|
||||
LOG_ECMA(INFO) << "UnloadPatch success!";
|
||||
return true;
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ private:
|
||||
static bool CheckStarExportEntryMismatch(StarExportEntry *patch, StarExportEntry *base);
|
||||
|
||||
CString baseFileName_;
|
||||
bool isHotPatch_ {false}; // true: HotPatch; false: HotReload.
|
||||
|
||||
struct NormalMethodIndex {
|
||||
uint32_t constpoolNum {UINT32_MAX};
|
||||
|
@ -105,7 +105,7 @@ int Main(const int argc, const char **argv)
|
||||
#endif
|
||||
uint32_t len = fileNames.size();
|
||||
if (len < 4) { // 4: four abc file
|
||||
std::cout << "Must include base.abc, patch.abc, test1.abc, test2.abc absolute path" << std::endl;
|
||||
std::cout << "Must include base.abc, patch.abc, test.abc, retest.abc absolute path" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::string baseFileName = fileNames[0];
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
test_list = [
|
||||
hot_reload_test_list = [
|
||||
"check_import",
|
||||
"class_inheritance",
|
||||
"class_mem_func",
|
||||
@ -28,7 +28,7 @@ test_list = [
|
||||
]
|
||||
|
||||
if (!is_debug) {
|
||||
test_list += [
|
||||
hot_reload_test_list += [
|
||||
"multi_classconstpool",
|
||||
"multi_closureconstpool",
|
||||
"multi_constructorconstpool",
|
||||
@ -37,6 +37,8 @@ if (!is_debug) {
|
||||
]
|
||||
}
|
||||
|
||||
hot_patch_test_list = [ "add_callfunction" ]
|
||||
|
||||
host_quickfix_test_action("multi_patch") {
|
||||
extra_patches = [
|
||||
"patch1",
|
||||
@ -45,17 +47,28 @@ host_quickfix_test_action("multi_patch") {
|
||||
entry_point = "--entry-point=base"
|
||||
}
|
||||
|
||||
foreach(testcase, test_list) {
|
||||
foreach(testcase, hot_reload_test_list) {
|
||||
host_quickfix_test_action("${testcase}") {
|
||||
entry_point = "--entry-point=base"
|
||||
}
|
||||
}
|
||||
|
||||
foreach(testcase, hot_patch_test_list) {
|
||||
host_quickfix_test_action("${testcase}") {
|
||||
entry_point = "--entry-point=base"
|
||||
is_hotpatch = true
|
||||
}
|
||||
}
|
||||
|
||||
group("ark_quickfix_test") {
|
||||
testonly = true
|
||||
|
||||
deps = []
|
||||
foreach(testcase, test_list) {
|
||||
foreach(testcase, hot_reload_test_list) {
|
||||
deps += [ ":${testcase}QuickfixAction" ]
|
||||
}
|
||||
|
||||
foreach(testcase, hot_patch_test_list) {
|
||||
deps += [ ":${testcase}QuickfixAction" ]
|
||||
}
|
||||
|
||||
|
25
test/quickfix/add_callfunction/base.js
Normal file
25
test/quickfix/add_callfunction/base.js
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 A() {
|
||||
print("base A()");
|
||||
B();
|
||||
}
|
||||
|
||||
function B() {
|
||||
print("base B()");
|
||||
}
|
||||
|
||||
globalThis.A = A;
|
||||
globalThis.B = B;
|
2
test/quickfix/add_callfunction/base.txt
Normal file
2
test/quickfix/add_callfunction/base.txt
Normal file
@ -0,0 +1,2 @@
|
||||
base.js;base;module;base.js
|
||||
module.js;module;module;module.js
|
29
test/quickfix/add_callfunction/base_modify.js
Normal file
29
test/quickfix/add_callfunction/base_modify.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 A() {
|
||||
print("patch A()");
|
||||
B();
|
||||
C();
|
||||
}
|
||||
|
||||
function B() {
|
||||
print("patch B()");
|
||||
}
|
||||
|
||||
function C() {
|
||||
print("patch C()");
|
||||
}
|
||||
|
||||
globalThis.C = C;
|
26
test/quickfix/add_callfunction/expect_output.txt
Normal file
26
test/quickfix/add_callfunction/expect_output.txt
Normal file
@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2022 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.
|
||||
|
||||
QuickFix Execute start
|
||||
QuickFix start load patch
|
||||
QuickFix load patch success
|
||||
patch A()
|
||||
patch B()
|
||||
patch C()
|
||||
QuickFix start check exception
|
||||
QuickFix have no exception
|
||||
QuickFix start unload patch
|
||||
QuickFix unload patch success
|
||||
base A()
|
||||
base B()
|
||||
QuickFix Execute end
|
16
test/quickfix/add_callfunction/module.js
Normal file
16
test/quickfix/add_callfunction/module.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
export var nop = undefined
|
16
test/quickfix/add_callfunction/module_modify.js
Normal file
16
test/quickfix/add_callfunction/module_modify.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
|
||||
export var nop = undefined
|
2
test/quickfix/add_callfunction/patch.txt
Normal file
2
test/quickfix/add_callfunction/patch.txt
Normal file
@ -0,0 +1,2 @@
|
||||
base_modify.js;base;module;base.js
|
||||
module_modify.js;module;module;module.js
|
15
test/quickfix/add_callfunction/test.js
Normal file
15
test/quickfix/add_callfunction/test.js
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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.
|
||||
*/
|
||||
A()
|
@ -663,6 +663,10 @@ template("host_quickfix_test_action") {
|
||||
_script_args_ = invoker.entry_point + " "
|
||||
}
|
||||
|
||||
if (defined(invoker.is_hotpatch) && invoker.is_hotpatch) {
|
||||
_test_map_path_ = "$target_out_dir/${_target_name_}/base.map"
|
||||
}
|
||||
|
||||
foreach(filename, _test_file_name_) {
|
||||
merge_file_raw = "//arkcompiler/ets_runtime/test/quickfix/"
|
||||
if (filename == "test" || filename == "retest") {
|
||||
@ -703,10 +707,23 @@ template("host_quickfix_test_action") {
|
||||
"--merge-abc",
|
||||
]
|
||||
|
||||
if (defined(invoker.is_hotpatch) && filename == "patch") {
|
||||
extra_args += [ "--generate-patch" ]
|
||||
}
|
||||
|
||||
if (defined(invoker.is_hotpatch) && filename == "base") {
|
||||
dump_symbol_table = rebase_path(_test_map_path_)
|
||||
}
|
||||
|
||||
if (defined(invoker.is_hotpatch) && filename == "patch") {
|
||||
input_symbol_table = rebase_path(_test_map_path_)
|
||||
}
|
||||
|
||||
in_puts = [
|
||||
_test_expect_path_,
|
||||
merge_file,
|
||||
]
|
||||
|
||||
out_puts = [ abc_path ]
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user