From 13e4e9f5a8127fdb604fd2445ec82c9d5c7821b6 Mon Sep 17 00:00:00 2001 From: getingke Date: Thu, 9 Sep 2021 17:40:54 +0800 Subject: [PATCH 1/9] rebase with master Signed-off-by: getingke Change-Id: Ib764c465916b0d8b34f298d04e462b81001d359e --- BUILD.gn | 9 +- ecmascript/compiler/BUILD.gn | 40 +- ecmascript/compiler/circuit_builder.cpp | 12 +- ecmascript/compiler/circuit_builder.h | 10 +- ecmascript/compiler/code_generator.h | 43 + ecmascript/compiler/compile_llvm_lib.sh | 46 + ecmascript/compiler/fast_stub.cpp | 655 +++++++++ ecmascript/compiler/fast_stub.h | 106 ++ ecmascript/compiler/fast_stub_define.h | 7 +- ecmascript/compiler/fastpath_optimizer.h | 72 - ...astpath_optimizer.cpp => llvm_codegen.cpp} | 110 +- ecmascript/compiler/llvm_codegen.h | 50 + ecmascript/compiler/llvm_ir_builder.cpp | 121 +- ecmascript/compiler/llvm_ir_builder.h | 64 +- ...jit_compiler.cpp => llvm_mcjit_engine.cpp} | 30 +- ...m_mcjit_compiler.h => llvm_mcjit_engine.h} | 63 +- ecmascript/compiler/scheduler.h | 5 +- .../compiler/{stub_optimizer.cpp => stub.cpp} | 235 ++-- .../compiler/{stub_optimizer.h => stub.h} | 758 ++++++----- ecmascript/compiler/stub_aot_compiler.cpp | 183 +++ ecmascript/compiler/stub_aot_compiler.h | 45 + ecmascript/compiler/stub_descriptor.cpp | 281 ++++ .../{stub_interface.h => stub_descriptor.h} | 125 +- ecmascript/compiler/stub_interface.cpp | 606 --------- ecmascript/compiler/tests/BUILD.gn | 8 +- ...tub_optimizer_tests.cpp => stub_tests.cpp} | 1200 ++++------------- ecmascript/compiler/verifier.cpp | 1 + ecmascript/compiler/verifier.h | 19 +- ecmascript/js_thread.cpp | 13 +- ecmascript/js_thread.h | 18 +- ecmascript/runtime_trampolines.cpp | 24 +- ecmascript/runtime_trampolines.h | 2 + ecmascript/stub_module.cpp | 46 + ecmascript/stub_module.h | 50 + 34 files changed, 2748 insertions(+), 2309 deletions(-) create mode 100644 ecmascript/compiler/code_generator.h create mode 100755 ecmascript/compiler/compile_llvm_lib.sh create mode 100644 ecmascript/compiler/fast_stub.cpp create mode 100644 ecmascript/compiler/fast_stub.h delete mode 100644 ecmascript/compiler/fastpath_optimizer.h rename ecmascript/compiler/{fastpath_optimizer.cpp => llvm_codegen.cpp} (30%) create mode 100644 ecmascript/compiler/llvm_codegen.h rename ecmascript/compiler/{llvm_mcjit_compiler.cpp => llvm_mcjit_engine.cpp} (88%) rename ecmascript/compiler/{llvm_mcjit_compiler.h => llvm_mcjit_engine.h} (75%) rename ecmascript/compiler/{stub_optimizer.cpp => stub.cpp} (71%) rename ecmascript/compiler/{stub_optimizer.h => stub.h} (53%) create mode 100644 ecmascript/compiler/stub_aot_compiler.cpp create mode 100644 ecmascript/compiler/stub_aot_compiler.h create mode 100644 ecmascript/compiler/stub_descriptor.cpp rename ecmascript/compiler/{stub_interface.h => stub_descriptor.h} (51%) delete mode 100644 ecmascript/compiler/stub_interface.cpp rename ecmascript/compiler/tests/{stub_optimizer_tests.cpp => stub_tests.cpp} (51%) create mode 100644 ecmascript/stub_module.cpp create mode 100644 ecmascript/stub_module.h diff --git a/BUILD.gn b/BUILD.gn index 10c1bd16f5..dbc893259b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -33,7 +33,10 @@ group("ark_js_host_linux_tools_packages") { "//ark/js_runtime/ecmascript/js_vm:ark_js_vm(${host_toolchain})", ] if (is_standard_system) { - deps += [ "//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer(${host_toolchain})" ] + deps += [ + "//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer(${host_toolchain})", + "//ark/js_runtime/ecmascript/compiler:ark_stub_opt(${host_toolchain})", + ] } } } @@ -69,6 +72,7 @@ group("ark_js_host_unittest") { "//ark/js_runtime/ecmascript/snapshot/tests:host_unittest", "//ark/js_runtime/ecmascript/tests:host_unittest", "//ark/js_runtime/ecmascript/tooling/test:host_unittest", + "//ark/js_runtime/ecmascript/compiler/tests:host_unittest", ] if (is_standard_system) { deps += [ "//ark/js_runtime/ecmascript/compiler/tests:host_unittest" ] @@ -352,6 +356,7 @@ ecma_source = [ "ecmascript/snapshot/mem/slot_bit.cpp", "ecmascript/snapshot/mem/snapshot.cpp", "ecmascript/snapshot/mem/snapshot_serialize.cpp", + "ecmascript/stub_module.cpp", "ecmascript/tagged_dictionary.cpp", "ecmascript/template_string.cpp", "ecmascript/vmstat/caller_stat.cpp", @@ -380,7 +385,7 @@ ohos_static_library("libark_jsruntime_static") { ] if (is_standard_system) { - cflags_cc = [ "-fvisibility=hidden" ] + # cflags_cc = [ "-fvisibility=hidden" ] deps += [ "$ark_root/runtime:libarkruntime_static" ] } else { deps += [ "$ark_root/runtime:libarkruntime" ] diff --git a/ecmascript/compiler/BUILD.gn b/ecmascript/compiler/BUILD.gn index 4d29631c04..b7b288bd7c 100644 --- a/ecmascript/compiler/BUILD.gn +++ b/ecmascript/compiler/BUILD.gn @@ -15,8 +15,8 @@ import("//ark/js_runtime/js_runtime_config.gni") import("//build/ohos.gni") action("build_llvm_libs") { - script = "build_llvm.sh" - sources = [ "//ark/js_runtime/ecmascript/compiler/build_llvm.sh" ] + script = "compile_llvm_lib.sh" + sources = [ "//ark/js_runtime/ecmascript/compiler/compile_llvm_lib.sh" ] outputs = [ "${root_out_dir}/llvm" ] } @@ -43,14 +43,15 @@ ohos_shared_library("libark_jsoptimizer") { "circuit.cpp", "circuit_builder.cpp", "circuit_visualizer.cpp", - "fastpath_optimizer.cpp", + "fast_stub.cpp", "gate.cpp", + "llvm_codegen.cpp", "llvm_ir_builder.cpp", - "llvm_mcjit_compiler.cpp", + "llvm_mcjit_engine.cpp", "llvm_stackmap_parse.cpp", "scheduler.cpp", - "stub_interface.cpp", - "stub_optimizer.cpp", + "stub_descriptor.cpp", + "stub.cpp", "type.cpp", "verifier.cpp", ] @@ -141,3 +142,30 @@ ohos_shared_library("libark_jsoptimizer") { relative_install_dir = "ark" subsystem_name = "ark" } + +ohos_executable("ark_stub_opt") { + sources = [ "stub_aot_compiler.cpp" ] + + configs = [ + ":include_llvm", + ":ark_jsruntime_compiler_config", + "//ark/js_runtime:ark_jsruntime_public_config", + "$ark_root/runtime:arkruntime_public_config", + ] + + deps = [ + "$ark_root/libpandabase:libarkbase", + "//ark/js_runtime:libark_jsruntime", + "//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer", + ] + + if (!is_standard_system) { + deps += [ "$ark_root/runtime:libarkruntime" ] + } + + part_name = "ark_js_runtime" + install_enable = false + + output_name = "ark_stub_opt" + subsystem_name = "ark" +} \ No newline at end of file diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 307edc8b58..171f51f0da 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -301,7 +301,7 @@ OpCode CircuitBuilder::GetCallOpCodeFromMachineType(MachineType type) } } -AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, +AddrShift CircuitBuilder::NewCallGate(StubDescriptor *descriptor, AddrShift target, std::initializer_list args) { std::vector inputs; @@ -316,7 +316,7 @@ AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, AddrS return circuit_->NewGate(opcode, args.size() + 1, inputs, TypeCode::JS_ANY); } -AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, +AddrShift CircuitBuilder::NewCallGate(StubDescriptor *descriptor, AddrShift target, AddrShift depend, std::initializer_list args) { std::vector inputs; @@ -329,10 +329,10 @@ AddrShift CircuitBuilder::NewCallGate(StubInterfaceDescriptor *descriptor, AddrS return circuit_->NewGate(opcode, args.size() + 1, inputs, TypeCode::JS_ANY); } -AddrShift CircuitBuilder::NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, +AddrShift CircuitBuilder::NewCallRuntimeGate(StubDescriptor *descriptor, AddrShift thread, AddrShift target, std::initializer_list args) { - ASSERT(descriptor->GetStubKind() == StubInterfaceDescriptor::RUNTIME_STUB); + ASSERT(descriptor->GetStubKind() == StubDescriptor::RUNTIME_STUB); std::vector inputs; auto dependEntry = Circuit::GetCircuitRoot(OpCode(OpCode::DEPEND_ENTRY)); inputs.push_back(dependEntry); @@ -346,10 +346,10 @@ AddrShift CircuitBuilder::NewCallRuntimeGate(StubInterfaceDescriptor *descriptor return circuit_->NewGate(opcode, args.size() + 2, inputs, TypeCode::JS_ANY); } -AddrShift CircuitBuilder::NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, +AddrShift CircuitBuilder::NewCallRuntimeGate(StubDescriptor *descriptor, AddrShift thread, AddrShift target, AddrShift depend, std::initializer_list args) { - ASSERT(descriptor->GetStubKind() == StubInterfaceDescriptor::RUNTIME_STUB); + ASSERT(descriptor->GetStubKind() == StubDescriptor::RUNTIME_STUB); std::vector inputs; inputs.push_back(depend); inputs.push_back(target); diff --git a/ecmascript/compiler/circuit_builder.h b/ecmascript/compiler/circuit_builder.h index 35e3c47393..db8fb14063 100644 --- a/ecmascript/compiler/circuit_builder.h +++ b/ecmascript/compiler/circuit_builder.h @@ -19,7 +19,7 @@ #include "ecmascript/compiler/circuit.h" #include "ecmascript/compiler/gate.h" #include "ecmascript/compiler/machine_type.h" -#include "ecmascript/compiler/stub_interface.h" +#include "ecmascript/compiler/stub_descriptor.h" namespace kungfu { class CircuitBuilder { @@ -55,12 +55,12 @@ public: AddrShift NewArithMeticGate(OpCode opcode, AddrShift value); AddrShift NewLogicGate(OpCode opcode, AddrShift left, AddrShift right); AddrShift NewLogicGate(OpCode opcode, AddrShift value); - AddrShift NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, std::initializer_list args); - AddrShift NewCallGate(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, + AddrShift NewCallGate(StubDescriptor *descriptor, AddrShift target, std::initializer_list args); + AddrShift NewCallGate(StubDescriptor *descriptor, AddrShift target, AddrShift depend, std::initializer_list args); - AddrShift NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + AddrShift NewCallRuntimeGate(StubDescriptor *descriptor, AddrShift thread, AddrShift target, std::initializer_list args); - AddrShift NewCallRuntimeGate(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + AddrShift NewCallRuntimeGate(StubDescriptor *descriptor, AddrShift thread, AddrShift target, AddrShift depend, std::initializer_list args); static OpCode GetLoadOpCodeFromMachineType(MachineType type); static OpCode GetStoreOpCodeFromMachineType(MachineType type); diff --git a/ecmascript/compiler/code_generator.h b/ecmascript/compiler/code_generator.h new file mode 100644 index 0000000000..10ffe6f5c5 --- /dev/null +++ b/ecmascript/compiler/code_generator.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_COMPILER_CODE_GENERATOR_H +#define ECMASCRIPT_COMPILER_CODE_GENERATOR_H + +#include "circuit.h" + +namespace kungfu { +using ControlFlowGraph = std::vector>; +class CodeGeneratorImpl { +public: + CodeGeneratorImpl() = default; + virtual ~CodeGeneratorImpl() = default; + virtual void GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, int index) = 0; +}; + +class CodeGenerator { +public: + explicit CodeGenerator(CodeGeneratorImpl *impl) : impl_(impl) {} + ~CodeGenerator() = default; + void Run(Circuit *circuit, const ControlFlowGraph &graph, int index) + { + impl_->GenerateCodeForStub(circuit, graph, index); + } + +private: + CodeGeneratorImpl *impl_; +}; +} // namespace kungfu +#endif // ECMASCRIPT_COMPILER_CODE_GENERATOR_H \ No newline at end of file diff --git a/ecmascript/compiler/compile_llvm_lib.sh b/ecmascript/compiler/compile_llvm_lib.sh new file mode 100755 index 0000000000..58c117ed66 --- /dev/null +++ b/ecmascript/compiler/compile_llvm_lib.sh @@ -0,0 +1,46 @@ +# Copyright (c) 2021 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. + +set -e +echo "++++++++++++++++++++++++++++++++++" +echo "build llvm" +#date +%F ' '%H:%M:%S +#echo $@ + +BIN_PATH=$(cd $(dirname $0);pwd) +JSRUNTIME_HOME=$(dirname $(dirname ${BIN_PATH})) +BASE_HOME=${JSRUNTIME_HOME}/../../ + +echo ${BIN_PATH} +echo ${BASE_HOME} + +if [ ! -d ${BASE_HOME}/third_party/llvm-project ]; then + dd if=/dev/zero of=/tmp/mem.swap bs=1M count=4096 + git clone https://gitee.com/github-repos/llvm-project.git +fi + +cd ${BASE_HOME}/third_party/llvm-project +if [ ! -d "build" ];then + mkdir build && cd build + cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../llvm + ninja +else + cd build + if [ ! -d "lib" ]; then + rm -rf * + cmake -GNinja -DCMAKE_BUILD_TYPE=Release ../llvm + ninja + fi +fi + +echo "++++++++++++++++++++++++++++++++++" \ No newline at end of file diff --git a/ecmascript/compiler/fast_stub.cpp b/ecmascript/compiler/fast_stub.cpp new file mode 100644 index 0000000000..86ac7a8340 --- /dev/null +++ b/ecmascript/compiler/fast_stub.cpp @@ -0,0 +1,655 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "fast_stub.h" +#include "ecmascript/base/number_helper.h" +#include "ecmascript/js_array.h" +#include "ecmascript/message_string.h" +#include "ecmascript/tagged_hash_table-inl.h" +#include "llvm_ir_builder.h" + +namespace kungfu { +using namespace panda::ecmascript; +void FastArrayLoadElementStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift aVal = Int64Argument(0); + AddrShift indexVal = Int32Argument(1); + + // load a.length + AddrShift lengthOffset = GetInteger32Constant(JSArray::GetArrayLengthOffset()); + if (PtrValueCode() == ValueCode::INT64) { + lengthOffset = SExtInt32ToInt64(lengthOffset); + } else if (PtrValueCode() == ValueCode::INT32) { + aVal = TruncInt64ToInt32(aVal); + } + AddrShift taggedLength = Load(MachineType::TAGGED_TYPE, aVal, lengthOffset); + + AddrShift intLength = TaggedCastToInt32(taggedLength); + // if index < length + Label ifTrue(env); + Label ifFalse(env); + Branch(Int32LessThan(indexVal, intLength), &ifTrue, &ifFalse); + Bind(&ifTrue); + Return(LoadFromObject(MachineType::TAGGED_TYPE, aVal, indexVal)); + Bind(&ifFalse); + Return(GetUndefinedConstant()); +} + +void FastAddStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift x = Int64Argument(0); + AddrShift y = Int64Argument(1); + DEFVARIABLE(intX, MachineType::INT32_TYPE, 0); + DEFVARIABLE(intY, MachineType::INT32_TYPE, 0); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); + Label xIsNumber(env); + Label xNotNumberOryNotNumber(env); + Label xIsNumberAndyIsNumber(env); + Label xIsDoubleAndyIsDouble(env); + Branch(TaggedIsNumber(x), &xIsNumber, &xNotNumberOryNotNumber); + Bind(&xIsNumber); + { + Label yIsNumber(env); + // if right.IsNumber() + Branch(TaggedIsNumber(y), &yIsNumber, &xNotNumberOryNotNumber); + Bind(&yIsNumber); + { + Label xIsInt(env); + Label xNotInt(env); + Branch(TaggedIsInt(x), &xIsInt, &xNotInt); + Bind(&xIsInt); + { + intX = TaggedCastToInt32(x); + doubleX = CastInt32ToFloat64(*intX); + Jump(&xIsNumberAndyIsNumber); + } + Bind(&xNotInt); + { + doubleX = TaggedCastToDouble(x); + Jump(&xIsNumberAndyIsNumber); + } + } + } + Bind(&xNotNumberOryNotNumber); + Return(GetHoleConstant()); + Label yIsInt(env); + Label yNotInt(env); + Bind(&xIsNumberAndyIsNumber); + { + Branch(TaggedIsInt(y), &yIsInt, &yNotInt); + Bind(&yIsInt); + { + intY = TaggedCastToInt32(y); + doubleY = CastInt32ToFloat64(*intY); + Jump(&xIsDoubleAndyIsDouble); + } + Bind(&yNotInt); + { + doubleY = TaggedCastToDouble(y); + Jump(&xIsDoubleAndyIsDouble); + } + } + Bind(&xIsDoubleAndyIsDouble); + doubleX = DoubleAdd(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); +} + +void FastSubStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift x = Int64Argument(0); + AddrShift y = Int64Argument(1); + DEFVARIABLE(intX, MachineType::INT32_TYPE, 0); + DEFVARIABLE(intY, MachineType::INT32_TYPE, 0); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); + Label xIsNumber(env); + Label xNotNumberOryNotNumber(env); + Label xNotIntOryNotInt(env); + Label xIsIntAndyIsInt(env); + // if x is number + Branch(TaggedIsNumber(x), &xIsNumber, &xNotNumberOryNotNumber); + Bind(&xIsNumber); + { + Label yIsNumber(env); + // if y is number + Branch(TaggedIsNumber(y), &yIsNumber, &xNotNumberOryNotNumber); + { + Bind(&yIsNumber); + { + Label xIsInt(env); + Label xNotInt(env); + Branch(TaggedIsInt(x), &xIsInt, &xNotInt); + Bind(&xIsInt); + { + intX = TaggedCastToInt32(x); + Label yIsInt(env); + Label yNotInt(env); + Branch(TaggedIsInt(y), &yIsInt, &yNotInt); + Bind(&yIsInt); + { + intY = TaggedCastToInt32(y); + intX = Int32Sub(*intX, *intY); + Jump(&xIsIntAndyIsInt); + } + Bind(&yNotInt); + { + doubleY = TaggedCastToDouble(y); + doubleX = CastInt32ToFloat64(*intX); + Jump(&xNotIntOryNotInt); + } + } + Bind(&xNotInt); + { + Label yIsInt(env); + Label yNotInt(env); + doubleX = TaggedCastToDouble(x); + Branch(TaggedIsInt(y), &yIsInt, &yNotInt); + Bind(&yIsInt); + { + intY = TaggedCastToInt32(y); + doubleY = CastInt32ToFloat64(*intY); + Jump(&xNotIntOryNotInt); + } + Bind(&yNotInt); + { + doubleY = TaggedCastToDouble(y); + Jump(&xNotIntOryNotInt); + } + } + } + } + } + Bind(&xNotNumberOryNotNumber); + Return(GetHoleConstant()); + Bind(&xNotIntOryNotInt); + doubleX = DoubleSub(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); + Bind(&xIsIntAndyIsInt); + Return(IntBuildTagged(*intX)); +} + +void FastMulStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift x = Int64Argument(0); + AddrShift y = Int64Argument(1); + DEFVARIABLE(intX, MachineType::INT32_TYPE, 0); + DEFVARIABLE(intY, MachineType::INT32_TYPE, 0); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); + Label xIsNumber(env); + Label xNotNumberOryNotNumber(env); + Label xIsNumberAndyIsNumber(env); + Label xIsDoubleAndyIsDouble(env); + Branch(TaggedIsNumber(x), &xIsNumber, &xNotNumberOryNotNumber); + Bind(&xIsNumber); + { + Label yIsNumber(env); + // if right.IsNumber() + Branch(TaggedIsNumber(y), &yIsNumber, &xNotNumberOryNotNumber); + Bind(&yIsNumber); + { + Label xIsInt(env); + Label xNotInt(env); + Branch(TaggedIsInt(x), &xIsInt, &xNotInt); + Bind(&xIsInt); + { + intX = TaggedCastToInt32(x); + doubleX = CastInt32ToFloat64(*intX); + Jump(&xIsNumberAndyIsNumber); + } + Bind(&xNotInt); + { + doubleX = TaggedCastToDouble(x); + Jump(&xIsNumberAndyIsNumber); + } + } + } + Bind(&xNotNumberOryNotNumber); + Return(GetHoleConstant()); + Label yIsInt(env); + Label yNotInt(env); + Bind(&xIsNumberAndyIsNumber); + { + Branch(TaggedIsInt(y), &yIsInt, &yNotInt); + Bind(&yIsInt); + { + intY = TaggedCastToInt32(y); + doubleY = CastInt32ToFloat64(*intY); + Jump(&xIsDoubleAndyIsDouble); + } + Bind(&yNotInt); + { + doubleY = TaggedCastToDouble(y); + Jump(&xIsDoubleAndyIsDouble); + } + } + Bind(&xIsDoubleAndyIsDouble); + doubleX = DoubleMul(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); +} + +void FastDivStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift x = Int64Argument(0); + AddrShift y = Int64Argument(1); + DEFVARIABLE(intX, MachineType::INT32_TYPE, 0); + DEFVARIABLE(intY, MachineType::INT32_TYPE, 0); + DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); + DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); + Label xIsNumber(env); + Label xNotNumberOryNotNumber(env); + Label xIsNumberAndyIsNumber(env); + Label xIsDoubleAndyIsDouble(env); + Branch(TaggedIsNumber(x), &xIsNumber, &xNotNumberOryNotNumber); + Bind(&xIsNumber); + { + Label yIsNumber(env); + // if right.IsNumber() + Branch(TaggedIsNumber(y), &yIsNumber, &xNotNumberOryNotNumber); + Bind(&yIsNumber); + { + Label xIsInt(env); + Label xNotInt(env); + Branch(TaggedIsInt(x), &xIsInt, &xNotInt); + Bind(&xIsInt); + { + intX = TaggedCastToInt32(x); + doubleX = CastInt32ToFloat64(*intX); + Jump(&xIsNumberAndyIsNumber); + } + Bind(&xNotInt); + { + doubleX = TaggedCastToDouble(x); + Jump(&xIsNumberAndyIsNumber); + } + } + } + Bind(&xNotNumberOryNotNumber); + Return(GetHoleConstant()); + Label yIsInt(env); + Label yNotInt(env); + Bind(&xIsNumberAndyIsNumber); + Branch(TaggedIsInt(y), &yIsInt, &yNotInt); + Bind(&yIsInt); + { + intY = TaggedCastToInt32(y); + doubleY = CastInt32ToFloat64(*intY); + Jump(&xIsDoubleAndyIsDouble); + } + Bind(&yNotInt); + { + doubleY = TaggedCastToDouble(y); + Jump(&xIsDoubleAndyIsDouble); + } + Bind(&xIsDoubleAndyIsDouble); + { + Label divisorIsZero(env); + Label divisorNotZero(env); + Branch(DoubleEqual(*doubleY, GetDoubleConstant(0.0)), &divisorIsZero, &divisorNotZero); + Bind(&divisorIsZero); + { + Label xIsZeroOrNan(env); + Label xNeiZeroOrNan(env); + Label xIsZero(env); + Label xNotZero(env); + // dLeft == 0.0 || std::isnan(dLeft) + Branch(DoubleEqual(*doubleX, GetDoubleConstant(0.0)), &xIsZero, &xNotZero); + Bind(&xIsZero); + Jump(&xIsZeroOrNan); + Bind(&xNotZero); + { + Label xIsNan(env); + Label xNotNan(env); + Branch(DoubleIsNAN(*doubleX), &xIsNan, &xNotNan); + Bind(&xIsNan); + Jump(&xIsZeroOrNan); + Bind(&xNotNan); + Jump(&xNeiZeroOrNan); + } + Bind(&xIsZeroOrNan); + Return(DoubleBuildTagged(GetDoubleConstant(base::NAN_VALUE))); + Bind(&xNeiZeroOrNan); + { + AddrShift intXTmp = CastDoubleToInt64(*doubleX); + AddrShift intYtmp = CastDoubleToInt64(*doubleY); + intXTmp = Word64And(Word64Xor(intXTmp, intYtmp), GetWord64Constant(base::DOUBLE_SIGN_MASK)); + intXTmp = Word64Xor(intXTmp, CastDoubleToInt64(GetDoubleConstant(base::POSITIVE_INFINITY))); + doubleX = CastInt64ToFloat64(intXTmp); + Return(DoubleBuildTagged(*doubleX)); + } + } + Bind(&divisorNotZero); + { + doubleX = DoubleDiv(*doubleX, *doubleY); + Return(DoubleBuildTagged(*doubleX)); + } + } +} + +void FastFindOwnElementStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift obj = PtrArgument(1); + AddrShift index = Int32Argument(2); // 2: 3rd parameter - index + + Label notDict(env); + Label isDict(env); + Label invalidValue(env); + Label end(env); + AddrShift elements = Load(POINTER_TYPE, obj, GetPtrConstant(JSObject::ELEMENTS_OFFSET)); + + Branch(IsDictionaryMode(elements), &isDict, ¬Dict); + Bind(¬Dict); + { + Label outOfArray(env); + Label notOutOfArray(env); + AddrShift arrayLength = Load(UINT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); + Branch(Int32LessThanOrEqual(arrayLength, index), &outOfArray, ¬OutOfArray); + Bind(&outOfArray); + Jump(&invalidValue); + Bind(¬OutOfArray); + { + AddrShift offset = PtrMul(ChangeInt32ToPointer(index), GetPtrConstant(JSTaggedValue::TaggedTypeSize())); + AddrShift dataIndex = PtrAdd(offset, GetPtrConstant(panda::coretypes::Array::GetDataOffset())); + AddrShift value = Load(TAGGED_TYPE, elements, dataIndex); + Label isHole1(env); + Label notHole1(env); + Branch(TaggedIsHole(value), &isHole1, ¬Hole1); + Bind(&isHole1); + Jump(&invalidValue); + Bind(¬Hole1); + Return(value); + } + Bind(&invalidValue); + Return(GetHoleConstant()); + } + // IsDictionary + Bind(&isDict); + { + AddrShift taggedIndex = IntBuildTagged(index); + AddrShift entry = FindElementFromNumberDictionary(thread, elements, taggedIndex); + Label notNegtiveOne(env); + Label negtiveOne(env); + Branch(Word32NotEqual(entry, GetInteger32Constant(-1)), ¬NegtiveOne, &negtiveOne); + Bind(¬NegtiveOne); + { + Return(GetValueFromDictionary(elements, entry)); + } + Bind(&negtiveOne); + Jump(&end); + } + Bind(&end); + Return(GetHoleConstant()); +} + +void FastGetElementStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift receiver = Int64Argument(1); + AddrShift index = Int64Argument(2); // 2: 3rd parameter - index + Label isHole(env); + Label notHole(env); + Label loopHead(env); + Label loopEnd(env); + Label afterLoop(env); + Label notHeapObj(env); + + Jump(&loopHead); + LoopBegin(&loopHead); + AddrShift objPtr = ChangeInt64ToPointer(receiver); + auto findOwnElementDescriptor = GET_STUBDESCRIPTOR(FindOwnElement); + AddrShift callFindOwnElementVal = + CallStub(findOwnElementDescriptor, GetWord64Constant(FAST_STUB_ID(FindOwnElement)), {thread, objPtr, index}); + Branch(TaggedIsHole(callFindOwnElementVal), &isHole, ¬Hole); + Bind(¬Hole); + Return(callFindOwnElementVal); + Bind(&isHole); + receiver = Load(TAGGED_TYPE, LoadHClass(objPtr), GetPtrConstant(JSHClass::PROTOTYPE_OFFSET)); + Branch(TaggedIsHeapObject(receiver), &loopEnd, ¬HeapObj); + Bind(¬HeapObj); + Return(GetUndefinedConstant()); + Bind(&loopEnd); + LoopEnd(&loopHead); +} + +void FastFindOwnElement2Stub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift elements = PtrArgument(1); + AddrShift index = Int32Argument(2); // 2 : 3rd parameter + AddrShift isDict = Int32Argument(3); // 3 : 4th parameter + AddrShift attr = PtrArgument(4); // 4 : 5th parameter + AddrShift indexOrEntry = PtrArgument(5); // 5 : 6rd parameter + isDict = ZExtInt1ToInt32(isDict); + Label notDictionary(env); + Label isDictionary(env); + Label end(env); + Branch(Word32Equal(isDict, GetInteger32Constant(0)), ¬Dictionary, &isDictionary); + Bind(¬Dictionary); + { + AddrShift elementsLength = + Load(UINT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); + Label outOfElements(env); + Label notOutOfElements(env); + Branch(Int32LessThanOrEqual(elementsLength, index), &outOfElements, ¬OutOfElements); + Bind(&outOfElements); + { + Return(GetHoleConstant()); + } + Bind(¬OutOfElements); + { + AddrShift value = GetValueFromTaggedArray(elements, index); + Label isHole(env); + Label notHole(env); + Branch(TaggedIsHole(value), &isHole, ¬Hole); + Bind(&isHole); + Jump(&end); + Bind(¬Hole); + { + Store(UINT32_TYPE, attr, GetPtrConstant(0), + GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())); + Store(UINT32_TYPE, indexOrEntry, GetPtrConstant(0), index); + Return(value); + } + } + } + Bind(&isDictionary); + { + AddrShift entry = FindElementFromNumberDictionary(thread, elements, IntBuildTagged(index)); + Label notNegtiveOne(env); + Label negtiveOne(env); + Branch(Word32NotEqual(entry, GetInteger32Constant(-1)), ¬NegtiveOne, &negtiveOne); + Bind(¬NegtiveOne); + { + Store(UINT32_TYPE, attr, GetPtrConstant(0), GetAttributesFromDictionary(elements, entry)); + Store(UINT32_TYPE, indexOrEntry, GetPtrConstant(0), entry); + Return(GetValueFromDictionary(elements, entry)); + } + Bind(&negtiveOne); + Jump(&end); + } + Bind(&end); + Return(GetHoleConstant()); +} + +void FastSetElementStub::GenerateCircuit() +{ + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift receiver = PtrArgument(1); + DEFVARIABLE(holder, MachineType::TAGGED_POINTER_TYPE, receiver); + AddrShift index = Int32Argument(2); // 2 : 3rd argument + AddrShift value = Int64Argument(3); // 3 : 4th argument + AddrShift mayThrow = Int32Argument(4); // 4 : 5th argument + DEFVARIABLE(onPrototype, MachineType::BOOL_TYPE, FalseConstant()); + + AddrShift pattr = Alloca(static_cast(MachineRep::K_WORD32)); + AddrShift pindexOrEntry = Alloca(static_cast(MachineRep::K_WORD32)); + Label loopHead(env); + Jump(&loopHead); + LoopBegin(&loopHead); + { + AddrShift elements = GetElements(*holder); + AddrShift isDictionary = IsDictionaryMode(elements); + StubDescriptor *findOwnElemnt2 = GET_STUBDESCRIPTOR(FindOwnElement2); + AddrShift val = CallStub(findOwnElemnt2, GetWord64Constant(FAST_STUB_ID(FindOwnElement2)), + {thread, elements, index, isDictionary, pattr, pindexOrEntry}); + Label notHole(env); + Label isHole(env); + Branch(TaggedIsNotHole(val), ¬Hole, &isHole); + Bind(¬Hole); + { + Label isOnProtoType(env); + Label notOnProtoType(env); + Label afterOnProtoType(env); + Branch(*onPrototype, &isOnProtoType, ¬OnProtoType); + Bind(¬OnProtoType); + Jump(&afterOnProtoType); + Bind(&isOnProtoType); + { + Label isExtensible(env); + Label notExtensible(env); + Label nextExtensible(env); + Branch(IsExtensible(receiver), &isExtensible, ¬Extensible); + Bind(&isExtensible); + Jump(&nextExtensible); + Bind(¬Extensible); + { + Label isThrow(env); + Label notThrow(env); + Branch(Word32NotEqual(mayThrow, GetInteger32Constant(0)), &isThrow, ¬Throw); + Bind(&isThrow); + ThrowTypeAndReturn(thread, GET_MESSAGE_STRING_ID(SetPropertyWhenNotExtensible), FalseConstant()); + Bind(¬Throw); + Return(FalseConstant()); + } + Bind(&nextExtensible); + StubDescriptor *addElementInternal = GET_STUBDESCRIPTOR(AddElementInternal); + Return(CallRuntime(addElementInternal, thread, GetWord64Constant(FAST_STUB_ID(AddElementInternal)), + {thread, receiver, index, value, + GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); + } + Bind(&afterOnProtoType); + { + AddrShift attr = Load(INT32_TYPE, pattr); + Label isAccessor(env); + Label notAccessor(env); + Branch(IsAcesscor(attr), &isAccessor, ¬Accessor); + Bind(¬Accessor); + { + Label isWritable(env); + Label notWritable(env); + Branch(IsWritable(attr), &isWritable, ¬Writable); + Bind(&isWritable); + { + AddrShift elements = GetElements(receiver); + Label isDict(env); + Label notDict(env); + AddrShift indexOrEntry = Load(INT32_TYPE, pindexOrEntry); + Branch(isDictionary, &isDict, ¬Dict); + Bind(¬Dict); + { + StoreElement(elements, indexOrEntry, value); + UpdateRepresention(LoadHClass(receiver), value); + Return(TrueConstant()); + } + Bind(&isDict); + { + UpdateValueAndAttributes(elements, indexOrEntry, value, attr); + Return(TrueConstant()); + } + } + Bind(¬Writable); + { + Label isThrow(env); + Label notThrow(env); + Branch(Word32NotEqual(mayThrow, GetInteger32Constant(0)), &isThrow, ¬Throw); + Bind(&isThrow); + ThrowTypeAndReturn(thread, GET_MESSAGE_STRING_ID(SetReadOnlyProperty), FalseConstant()); + Bind(¬Throw); + Return(FalseConstant()); + } + } + Bind(&isAccessor); + { + StubDescriptor *callsetter = GET_STUBDESCRIPTOR(CallSetter); + AddrShift setter = GetSetterFromAccessor(val); + Return(CallRuntime(callsetter, thread, GetWord64Constant(FAST_STUB_ID(CallSetter)), + {thread, setter, receiver, value, TruncInt32ToInt1(mayThrow)})); + } + } + } + Bind(&isHole); + { + // holder equals to + holder = GetPrototypeFromHClass(LoadHClass(*holder)); + Label isHeapObj(env); + Label notHeapObj(env); + Branch(TaggedIsObject(*holder), &isHeapObj, ¬HeapObj); + Bind(¬HeapObj); + { + Label isExtensible(env); + Label notExtensible(env); + Label nextExtensible(env); + Branch(IsExtensible(receiver), &isExtensible, ¬Extensible); + Bind(&isExtensible); + Jump(&nextExtensible); + Bind(¬Extensible); + { + Label isThrow(env); + Label notThrow(env); + Branch(Word32NotEqual(mayThrow, GetInteger32Constant(0)), &isThrow, ¬Throw); + Bind(&isThrow); + ThrowTypeAndReturn(thread, GET_MESSAGE_STRING_ID(SetPropertyWhenNotExtensible), FalseConstant()); + Bind(¬Throw); + Return(FalseConstant()); + } + Bind(&nextExtensible); + { + StubDescriptor *addElementInternal = GET_STUBDESCRIPTOR(AddElementInternal); + Return(CallRuntime(addElementInternal, thread, GetWord64Constant(FAST_STUB_ID(AddElementInternal)), + {thread, receiver, index, value, + GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); + } + } + Bind(&isHeapObj); + { + Label isJsProxy(env); + Label notJsProxy(env); + Branch(IsJsProxy(*holder), &isJsProxy, ¬JsProxy); + Bind(&isJsProxy); + { + StubDescriptor *setProperty = GET_STUBDESCRIPTOR(JSProxySetProperty); + Return(CallRuntime( + setProperty, thread, GetWord64Constant(FAST_STUB_ID(JSProxySetProperty)), + {thread, *holder, IntBuildTagged(index), value, receiver, TruncInt32ToInt1(mayThrow)})); + } + Bind(¬JsProxy); + onPrototype = TrueConstant(); + } + } + } + LoopEnd(&loopHead); +} +} // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/fast_stub.h b/ecmascript/compiler/fast_stub.h new file mode 100644 index 0000000000..00b4e24048 --- /dev/null +++ b/ecmascript/compiler/fast_stub.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_COMPILER_FASTPATH_STUB_H +#define ECMASCRIPT_COMPILER_FASTPATH_STUB_H + +#include "ecmascript/compiler/fast_stub_define.h" +#include "ecmascript/compiler/stub.h" + +namespace kungfu { +class FastArrayLoadElementStub : public Stub { +public: + // 2 : 2 means argument counts + explicit FastArrayLoadElementStub(Circuit *circuit) : Stub("FastArrayLoadElement", 2, circuit) {} + ~FastArrayLoadElementStub() = default; + NO_MOVE_SEMANTIC(FastArrayLoadElementStub); + NO_COPY_SEMANTIC(FastArrayLoadElementStub); + void GenerateCircuit() override; +}; + +class FastAddStub : public Stub { +public: + // 2 : 2 means argument counts + explicit FastAddStub(Circuit *circuit) : Stub("FastAdd", 2, circuit) {} + ~FastAddStub() = default; + NO_MOVE_SEMANTIC(FastAddStub); + NO_COPY_SEMANTIC(FastAddStub); + void GenerateCircuit() override; +}; + +class FastSubStub : public Stub { +public: + explicit FastSubStub(Circuit *circuit) : Stub("FastSub", 2, circuit) {} + ~FastSubStub() = default; + NO_MOVE_SEMANTIC(FastSubStub); + NO_COPY_SEMANTIC(FastSubStub); + void GenerateCircuit() override; +}; + +class FastMulStub : public Stub { +public: + explicit FastMulStub(Circuit *circuit) : Stub("FastMul", 2, circuit) {} + ~FastMulStub() = default; + NO_MOVE_SEMANTIC(FastMulStub); + NO_COPY_SEMANTIC(FastMulStub); + void GenerateCircuit() override; +}; + +class FastDivStub : public Stub { +public: + explicit FastDivStub(Circuit *circuit) : Stub("FastDiv", 2, circuit) {} + ~FastDivStub() = default; + NO_MOVE_SEMANTIC(FastDivStub); + NO_COPY_SEMANTIC(FastDivStub); + void GenerateCircuit() override; +}; + +class FastFindOwnElementStub : public Stub { +public: + explicit FastFindOwnElementStub(Circuit *circuit) : Stub("FastFindOwnElement", 3, circuit) {} + ~FastFindOwnElementStub() = default; + NO_MOVE_SEMANTIC(FastFindOwnElementStub); + NO_COPY_SEMANTIC(FastFindOwnElementStub); + void GenerateCircuit() override; +}; + +class FastGetElementStub : public Stub { +public: + explicit FastGetElementStub(Circuit *circuit) : Stub("FastGetElement", 3, circuit) {} + ~FastGetElementStub() = default; + NO_MOVE_SEMANTIC(FastGetElementStub); + NO_COPY_SEMANTIC(FastGetElementStub); + void GenerateCircuit() override; +}; + +class FastFindOwnElement2Stub : public Stub { +public: + explicit FastFindOwnElement2Stub(Circuit *circuit) : Stub("FastFindOwnElement2", 6, circuit) {} + ~FastFindOwnElement2Stub() = default; + NO_MOVE_SEMANTIC(FastFindOwnElement2Stub); + NO_COPY_SEMANTIC(FastFindOwnElement2Stub); + void GenerateCircuit() override; +}; + +class FastSetElementStub : public Stub { +public: + explicit FastSetElementStub(Circuit *circuit) : Stub("FastSetElement", 5, circuit) {} + ~FastSetElementStub() = default; + NO_MOVE_SEMANTIC(FastSetElementStub); + NO_COPY_SEMANTIC(FastSetElementStub); + void GenerateCircuit() override; +}; +} // namespace kungfu +#endif // ECMASCRIPT_COMPILER_FASTPATH_STUB_H \ No newline at end of file diff --git a/ecmascript/compiler/fast_stub_define.h b/ecmascript/compiler/fast_stub_define.h index 9dbc8ab846..e56ce3cd0c 100644 --- a/ecmascript/compiler/fast_stub_define.h +++ b/ecmascript/compiler/fast_stub_define.h @@ -20,7 +20,9 @@ namespace kungfu { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define EXTERNAL_RUNTIMESTUB_LIST(V) \ V(AddElementInternal, 5) \ - V(CallSetter, 2) \ + V(CallSetter, 4) \ + V(CallGetter, 4) \ + V(AccessorGetter, 4) \ V(ThrowTypeError, 2) \ V(JSProxySetProperty, 6) \ V(GetHash32, 2) @@ -66,5 +68,8 @@ enum CallStubId { #undef DEF_FAST_STUB CALL_STUB_MAXCOUNT = EXTERN_RUNTIME_STUB_MAXCOUNT, }; + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define FAST_STUB_ID(name) kungfu::CallStubId::NAME_##name } // namespace kungfu #endif // ECMASCRIPT_COMPILER_FASTSTUB_DEFINE_H \ No newline at end of file diff --git a/ecmascript/compiler/fastpath_optimizer.h b/ecmascript/compiler/fastpath_optimizer.h deleted file mode 100644 index bf61207024..0000000000 --- a/ecmascript/compiler/fastpath_optimizer.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H -#define ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H - -#include "ecmascript/compiler/fast_stub_define.h" -#include "ecmascript/compiler/stub_optimizer.h" - -namespace kungfu { -class FastArrayLoadElementOptimizer : public StubOptimizer { -public: - explicit FastArrayLoadElementOptimizer(Environment *env) : StubOptimizer(env) {} - ~FastArrayLoadElementOptimizer() = default; - NO_MOVE_SEMANTIC(FastArrayLoadElementOptimizer); - NO_COPY_SEMANTIC(FastArrayLoadElementOptimizer); - void GenerateCircuit() override; - uint8_t *AllocMachineCode() - { - static constexpr int PROT = PROT_READ | PROT_WRITE | PROT_EXEC; // NOLINT(hicpp-signed-bitwise) - static constexpr int FLAGS = MAP_ANONYMOUS | MAP_SHARED; // NOLINT(hicpp-signed-bitwise) - auto machineCode = static_cast(mmap(nullptr, MAX_MACHINE_CODE_SIZE, PROT, FLAGS, -1, 0)); - return machineCode; - } - void FreeMachineCode(uint8_t *machineCode) - { - munmap(machineCode, MAX_MACHINE_CODE_SIZE); - } - -private: - const size_t MAX_MACHINE_CODE_SIZE = (1U << 20U); -}; - -class FastRuntimeStubs { -public: - static FastRuntimeStubs &GetInstance() - { - static FastRuntimeStubs instance; - return instance; - } - enum FastRuntimeStubId { -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define FAST_RUNTIME_STUB_ID(name, counter) ID_##name, - FAST_RUNTIME_STUB_LIST(FAST_RUNTIME_STUB_ID) -#undef FAST_RUNTIME_STUB_ID - FAST_STUB_MAXNUMBER, - }; - - void GenerateFastRuntimeStubs(); - -private: - FastRuntimeStubs(); - ~FastRuntimeStubs(); - NO_MOVE_SEMANTIC(FastRuntimeStubs); - NO_COPY_SEMANTIC(FastRuntimeStubs); - std::array fastRuntimeEnvs_; - std::array fastRuntimeOptimizers_; -}; -} // namespace kungfu -#endif // ECMASCRIPT_COMPILER_FASTPATH_OPTIMIZER_H \ No newline at end of file diff --git a/ecmascript/compiler/fastpath_optimizer.cpp b/ecmascript/compiler/llvm_codegen.cpp similarity index 30% rename from ecmascript/compiler/fastpath_optimizer.cpp rename to ecmascript/compiler/llvm_codegen.cpp index 65ffd6a449..7ad27f434a 100644 --- a/ecmascript/compiler/fastpath_optimizer.cpp +++ b/ecmascript/compiler/llvm_codegen.cpp @@ -1,56 +1,54 @@ -/* - * Copyright (c) 2021 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. - */ - -#include "ecmascript/compiler/fastpath_optimizer.h" -#include "ecmascript/js_array.h" -#include "ecmascript/tagged_hash_table-inl.h" - -namespace kungfu { -void FastArrayLoadElementOptimizer::GenerateCircuit() -{ - auto env = GetEnvironment(); - AddrShift aVal = Int64Argument(0); - AddrShift indexVal = Int32Argument(1); - - // load a.length - AddrShift lengthOffset = GetInteger32Constant(panda::ecmascript::JSArray::GetArrayLengthOffset()); - if (PtrValueCode() == ValueCode::INT64) { - lengthOffset = SExtInt32ToInt64(lengthOffset); - } else if (PtrValueCode() == ValueCode::INT32) { - aVal = TruncInt64ToInt32(aVal); - } - AddrShift taggegLength = Load(MachineType::TAGGED_TYPE, aVal, lengthOffset); - - AddrShift intLength = TaggedCastToInt32(taggegLength); - // if index < length - StubOptimizerLabel ifTrue(env); - StubOptimizerLabel ifFalse(env); - Branch(Int32LessThan(indexVal, intLength), &ifTrue, &ifFalse); - Bind(&ifTrue); - Return(LoadFromObject(MachineType::TAGGED_TYPE, aVal, indexVal)); - Bind(&ifFalse); - Return(GetUndefinedConstant()); -} - -FastRuntimeStubs::FastRuntimeStubs() - : fastRuntimeEnvs_{ -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define FAST_RUNTIME_STUB_ENV(name, arguments) Environment(#name, arguments), - FAST_RUNTIME_STUB_LIST(FAST_RUNTIME_STUB_ENV) -#undef FAST_RUNTIME_STUB_ENV - }, fastRuntimeOptimizers_{new FastArrayLoadElementOptimizer(&fastRuntimeEnvs_[1])} -{ -} -} // namespace kungfu \ No newline at end of file +/* + * Copyright (c) 2021 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. + */ + +#include "llvm_codegen.h" +#include "ecmascript/object_factory.h" +#include "stub_descriptor.h" + +using namespace panda::ecmascript; +namespace kungfu { +void LLVMCodeGeneratorImpl::GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, int index) +{ + auto function = module_->GetStubFunction(index); + + LLVMIRBuilder builder(&graph, circuit, module_, function); + builder.Build(); +} + +void LLVMModuleAssembler::AssembleModule() +{ + compiler_.Run(); +} + +void LLVMModuleAssembler::CopyAssembleCodeToModule(StubModule *module) +{ + auto codeBuff = reinterpret_cast
(compiler_.GetCodeBuffer()); + auto engine = compiler_.GetEngine(); + for (int i = 0; i < FAST_STUB_MAXCOUNT; i++) { + auto stubfunction = stubmodule_->GetStubFunction(i); + if (stubfunction != nullptr) { + Address stubEntry = reinterpret_cast
(LLVMGetPointerToGlobal(engine, stubfunction)); + module->SetStubEntry(i, stubEntry - codeBuff); + } + } + + auto codeSize = compiler_.GetCodeSize(); + + MachineCode *code = reinterpret_cast(new char(sizeof(MachineCode) + codeSize)); + code->SetInstructionSizeInBytes(nullptr, JSTaggedValue(codeSize), SKIP_BARRIER); + code->SetData(reinterpret_cast(codeBuff), codeSize); + module->SetCode(code); +} +} // namespace kungfu diff --git a/ecmascript/compiler/llvm_codegen.h b/ecmascript/compiler/llvm_codegen.h new file mode 100644 index 0000000000..bdbc4d5c32 --- /dev/null +++ b/ecmascript/compiler/llvm_codegen.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_COMPILER_LLVM_CODEGEN_H +#define ECMASCRIPT_COMPILER_LLVM_CODEGEN_H + +#include "code_generator.h" +#include "ecmascript/compiler/llvm_ir_builder.h" +#include "ecmascript/compiler/llvm_mcjit_engine.h" +#include "ecmascript/js_thread.h" +#include "ecmascript/stub_module.h" +#include "llvm-c/Types.h" +#include "llvm/IR/Instructions.h" +#include "llvm/Support/Host.h" + +namespace kungfu { +class LLVMCodeGeneratorImpl : public CodeGeneratorImpl { +public: + explicit LLVMCodeGeneratorImpl(LLVMStubModule *module) : module_(module) {} + ~LLVMCodeGeneratorImpl() = default; + void GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, int index) override; + +private: + LLVMStubModule *module_; +}; + +class LLVMModuleAssembler { +public: + explicit LLVMModuleAssembler(LLVMStubModule *module) : stubmodule_(module), compiler_(module->GetModule()) {} + void AssembleModule(); + void CopyAssembleCodeToModule(panda::ecmascript::StubModule *module); + +private: + LLVMStubModule *stubmodule_; + LLVMMcJitEngine compiler_; +}; +} // namespace kungfu +#endif // ECMASCRIPT_COMPILER_LLVM_CODEGEN_H \ No newline at end of file diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index 22fa5a9adb..47e98016d9 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -18,14 +18,14 @@ #include #include "ecmascript/compiler/circuit.h" -#include "ecmascript/compiler/fastpath_optimizer.h" +#include "ecmascript/compiler/fast_stub.h" #include "ecmascript/compiler/gate.h" -#include "ecmascript/compiler/stub_interface.h" +#include "ecmascript/compiler/stub_descriptor.h" #include "ecmascript/js_array.h" #include "ecmascript/js_thread.h" #include "llvm/IR/Instructions.h" #include "llvm/Support/Host.h" -#include "llvm_mcjit_compiler.h" +#include "llvm_mcjit_engine.h" #include "securec.h" #include "utils/logger.h" @@ -56,6 +56,17 @@ LLVMIRBuilder::LLVMIRBuilder(const std::vector> *schedule bbIdMapBb_.clear(); } +LLVMIRBuilder::LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit, + LLVMStubModule *module, LLVMValueRef function) + : schedule_(schedule), circuit_(circuit), module_(module->GetModule()), + function_(function), stubModule_(module) +{ + LLVMSetTarget(module_, "x86_64-unknown-linux-gnu"); + builder_ = LLVMCreateBuilder(); + context_ = LLVMGetGlobalContext(); + bbIdMapBb_.clear(); +} + int LLVMIRBuilder::FindBasicBlock(AddrShift gate) const { for (size_t bbIdx = 0; bbIdx < schedule_->size(); bbIdx++) { @@ -360,9 +371,12 @@ void LLVMIRBuilder::Build() VisitStore(gate, MachineRep::K_WORD64, ins[2], ins[1]); // 2:baseAddr gate, 1:data gate break; } - case OpCode::INT32_TO_FLOAT64: // no break, fall through + case OpCode::INT32_TO_FLOAT64: { + VisitCastInt32ToDouble(gate, ins[0]); + break; + } case OpCode::INT64_TO_FLOAT64: { - VisitCastIntToDouble(gate, ins[0]); + VisitCastInt64ToDouble(gate, ins[0]); break; } case OpCode::FLOAT64_TO_INT64: { @@ -554,11 +568,14 @@ void LLVMIRBuilder::VisitCall(AddrShift gate, const std::vector &inLi { int paraStartIndex = 2; int index = circuit_->GetBitField(inList[1]); - LLVMValueRef callee = reinterpret_cast(FastStubs::GetInstance().GetFastStub(index)); - StubInterfaceDescriptor *callee_descriptor = FastStubs::GetInstance().GetStubDescriptor(index); + ASSERT(stubModule_ != nullptr); + LLVMValueRef callee; + StubDescriptor *callee_descriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(index); // runtime case - if (callee_descriptor->GetStubKind() == StubInterfaceDescriptor::RUNTIME_STUB) { - LLVMTypeRef rtfuncType = reinterpret_cast(FastStubs::GetInstance().GetRunTimeLLVMType(index)); + if (callee_descriptor->GetStubKind() == StubDescriptor::RUNTIME_STUB) { + std::cout << "external refrence index " << index << std::endl; + LLVMTypeRef rtfuncType = stubModule_->GetExternalFunctionType(index); + LLVMDumpType(rtfuncType); LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0); LLVMValueRef thread = g_values[inList[2]]; // 2 : 2 means skip two input gates (target thread ) LLVMValueRef rtoffset = LLVMConstInt(LLVMInt64Type(), @@ -575,6 +592,8 @@ void LLVMIRBuilder::VisitCall(AddrShift gate, const std::vector &inLi std::cout << std::endl; LLVMDumpValue(callee); paraStartIndex += 1; + } else { + callee = stubModule_->GetStubFunction(index); } // 16 : params limit LLVMValueRef params[16]; @@ -1031,7 +1050,7 @@ void LLVMIRBuilder::VisitCastIntXToIntY(AddrShift gate, AddrShift e1, MachineRep LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } -void LLVMIRBuilder::VisitCastIntToDouble(AddrShift gate, AddrShift e1) const +void LLVMIRBuilder::VisitCastInt32ToDouble(AddrShift gate, AddrShift e1) const { LOG_ECMA(INFO) << "int cast2 double gate:" << gate; LLVMValueRef e1Value = g_values[e1]; @@ -1041,13 +1060,93 @@ void LLVMIRBuilder::VisitCastIntToDouble(AddrShift gate, AddrShift e1) const LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } +void LLVMIRBuilder::VisitCastInt64ToDouble(AddrShift gate, AddrShift e1) const +{ + LOG_ECMA(INFO) << "int cast2 double gate:" << gate; + LLVMValueRef e1Value = g_values[e1]; + LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); + LLVMValueRef result = LLVMBuildBitCast(builder_, e1Value, LLVMDoubleType(), ""); + g_values[gate] = result; + LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); +} + void LLVMIRBuilder::VisitCastDoubleToInt(AddrShift gate, AddrShift e1) const { LOG_ECMA(INFO) << "double cast2 int gate:" << gate; LLVMValueRef e1Value = g_values[e1]; LOG_ECMA(INFO) << "operand 0: " << LLVMPrintValueToString(e1Value); - LLVMValueRef result = LLVMBuildFPToSI(builder_, e1Value, LLVMInt64Type(), ""); + LLVMValueRef result = LLVMBuildBitCast(builder_, e1Value, LLVMInt64Type(), ""); g_values[gate] = result; LOG_ECMA(INFO) << "result: " << LLVMPrintValueToString(result); } + +LLVMStubModule::LLVMStubModule(const char *name) +{ + module_ = LLVMModuleCreateWithName("fast_stubs"); +#ifdef PANDA_TARGET_AMD64 + LLVMSetTarget(module_, "x86_64-unknown-linux-gnu"); +#endif +} + +void LLVMStubModule::Initialize() +{ + uint32_t i; + for (i = 0; i < FAST_STUB_MAXCOUNT; i++) { + auto stubDescriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(i); + if (!stubDescriptor->GetName().empty()) { + stubFunctions_[i] = GetLLVMFunctionByStubDescriptor(stubDescriptor); + } + } + for (i = 0; i < MAX_EXTERNAL_FUNCTION_COUNT; i++) { + std::cout << "external index " << i + EXTERNAL_FUNCTION_OFFSET << std::endl; + auto externalDescriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(i + EXTERNAL_FUNCTION_OFFSET); + if (!externalDescriptor->GetName().empty()) { + externalFuctionType_[i] = GetLLVMFunctionTypeStubDescriptor(externalDescriptor); + } + } +} + +LLVMValueRef LLVMStubModule::GetLLVMFunctionByStubDescriptor(StubDescriptor *stubDescriptor) +{ + auto funcType = GetLLVMFunctionTypeStubDescriptor(stubDescriptor); + return LLVMAddFunction(module_, stubDescriptor->GetName().c_str(), funcType); +} + +LLVMTypeRef LLVMStubModule::GetLLVMFunctionTypeStubDescriptor(StubDescriptor *stubDescriptor) +{ + LLVMTypeRef returnType = ConvertLLVMTypeFromMachineType(stubDescriptor->GetReturnType()); + LLVMDumpType(returnType); + std::vector paramTys; + auto paramCount = stubDescriptor->GetParametersCount(); + for (int i = 0; i < paramCount; i++) { + auto paramsType = stubDescriptor->GetParametersType(); + paramTys.push_back(ConvertLLVMTypeFromMachineType(paramsType[i])); + } + for(auto type : paramTys) { + LLVMDumpType(type); + } + auto functype = LLVMFunctionType(returnType, paramTys.data(), paramCount, 0); + LLVMDumpType(functype); + return functype; +} + +LLVMTypeRef LLVMStubModule::ConvertLLVMTypeFromMachineType(MachineType type) +{ + static std::map machineTypeMap = { + {MachineType::NONE_TYPE, LLVMVoidType()}, + {MachineType::BOOL_TYPE, LLVMInt1Type()}, + {MachineType::INT8_TYPE, LLVMInt8Type()}, + {MachineType::INT16_TYPE, LLVMInt16Type()}, + {MachineType::INT32_TYPE, LLVMInt32Type()}, + {MachineType::INT64_TYPE, LLVMInt64Type()}, + {MachineType::UINT8_TYPE, LLVMInt8Type()}, + {MachineType::UINT16_TYPE, LLVMInt16Type()}, + {MachineType::UINT32_TYPE, LLVMInt32Type()}, + {MachineType::UINT64_TYPE, LLVMInt64Type()}, + {MachineType::FLOAT32_TYPE, LLVMFloatType()}, + {MachineType::FLOAT64_TYPE, LLVMDoubleType()}, + }; + return machineTypeMap[type]; +} + } // namespace kungfu diff --git a/ecmascript/compiler/llvm_ir_builder.h b/ecmascript/compiler/llvm_ir_builder.h index ca6f1dd085..7d479ba9a4 100644 --- a/ecmascript/compiler/llvm_ir_builder.h +++ b/ecmascript/compiler/llvm_ir_builder.h @@ -22,6 +22,7 @@ #include #include "ecmascript/compiler/circuit.h" +#include "ecmascript/compiler/stub_descriptor.h" #include "ecmascript/compiler/gate.h" #include "llvm-c/Core.h" #include "llvm-c/Types.h" @@ -78,11 +79,12 @@ public: } } ~BasicBlock() = default; + private: - std::vector predecessors_{}; - std::vector successors_{}; - int id_{-1}; - void *impl_{nullptr}; + std::vector predecessors_ {}; + std::vector successors_ {}; + int id_ {-1}; + void *impl_ {nullptr}; }; struct NotMergedPhiDesc { @@ -100,14 +102,52 @@ struct LLVMTFBuilderBasicBlockImpl { std::vector not_merged_phis; }; -class LLVMIRBuilder { +class LLVMStubModule { public: - LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit); - LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit, LLVMModuleRef module, - LLVMValueRef function); + explicit LLVMStubModule(const char *name); + ~LLVMStubModule() = default; + + void Initialize(); + + LLVMModuleRef GetModule() const + { + return module_; + } + + LLVMTypeRef GetExternalFunctionType(int index) const + { + ASSERT(index < MAX_EXTERNAL_FUNCTION_COUNT); + return externalFuctionType_[index - EXTERNAL_FUNCTION_OFFSET]; + } + LLVMValueRef GetStubFunction(int index) + { + ASSERT(index < FAST_STUB_MAXCOUNT); + return stubFunctions_[index]; + } + +private: + LLVMValueRef GetLLVMFunctionByStubDescriptor(StubDescriptor *stubDescriptor); + LLVMTypeRef GetLLVMFunctionTypeStubDescriptor(StubDescriptor *stubDescriptor); + LLVMTypeRef ConvertLLVMTypeFromMachineType(MachineType type); + static constexpr uint32_t MAX_EXTERNAL_FUNCTION_COUNT = + kungfu::EXTERN_RUNTIME_STUB_MAXCOUNT - kungfu::EXTERNAL_RUNTIME_STUB_BEGIN - 1; + static constexpr uint32_t EXTERNAL_FUNCTION_OFFSET = kungfu::EXTERNAL_RUNTIME_STUB_BEGIN + 1; + std::array stubFunctions_ {nullptr}; + std::array externalFuctionType_ {nullptr}; + LLVMModuleRef module_; +}; + +class LLVMIRBuilder { +public: + explicit LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit); + explicit LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit, + LLVMModuleRef module, LLVMValueRef function); + explicit LLVMIRBuilder(const std::vector> *schedule, const Circuit *circuit, + LLVMStubModule *module, LLVMValueRef function); void Build(); ~LLVMIRBuilder() = default; + private: void VisitCall(AddrShift gate, const std::vector &inList); void VisitAlloca(AddrShift gate); @@ -142,7 +182,8 @@ private: void VisitPhi(AddrShift gate, const std::vector &srcGates, MachineRep rep); void VisitReturn(AddrShift gate, AddrShift popCount, const std::vector &operands) const; void VisitCastIntXToIntY(AddrShift gate, AddrShift e1, MachineRep rep) const; - void VisitCastIntToDouble(AddrShift gate, AddrShift e1) const; + void VisitCastInt32ToDouble(AddrShift gate, AddrShift e1) const; + void VisitCastInt64ToDouble(AddrShift gate, AddrShift e1) const; void VisitCastDoubleToInt(AddrShift gate, AddrShift e1) const; void VisitCastInt64ToPointer(AddrShift gate, AddrShift e1) const; @@ -174,6 +215,7 @@ private: BasicBlockMap bbIdMapBb_; std::vector phiRebuildWorklist_; + LLVMStubModule *stubModule_ {nullptr}; }; -#endif -} // namespace kungfu \ No newline at end of file +} // namespace kungfu +#endif // PANDA_RUNTIME_ECMASCRIPT_COMPILER_LLVM_IR_BUILDER_H \ No newline at end of file diff --git a/ecmascript/compiler/llvm_mcjit_compiler.cpp b/ecmascript/compiler/llvm_mcjit_engine.cpp similarity index 88% rename from ecmascript/compiler/llvm_mcjit_compiler.cpp rename to ecmascript/compiler/llvm_mcjit_engine.cpp index 2eaa1f75a3..7792543937 100644 --- a/ecmascript/compiler/llvm_mcjit_compiler.cpp +++ b/ecmascript/compiler/llvm_mcjit_engine.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "ecmascript/compiler/llvm_mcjit_compiler.h" +#include "ecmascript/compiler/llvm_mcjit_engine.h" #include #include "llvm/IR/LegacyPassManager.h" @@ -54,7 +54,7 @@ static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, unsig const char *sectionName) { std::cout << "RoundTripAllocateCodeSection object " << object << " - " << std::endl; - struct CompilerState& state = *static_cast(object); + struct CodeState& state = *static_cast(object); uint8_t *addr = state.AllocaCodeSection(size, sectionName); std::cout << "RoundTripAllocateCodeSection addr:" << std::hex << reinterpret_cast(addr) << addr << " size:0x" << size << " +" << std::endl; @@ -64,7 +64,7 @@ static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, unsig static uint8_t *RoundTripAllocateDataSection(void *object, uintptr_t size, unsigned alignment, unsigned sectionID, const char *sectionName, LLVMBool isReadOnly) { - struct CompilerState& state = *static_cast(object); + struct CodeState& state = *static_cast(object); return state.AllocaDataSection(size, sectionName); } @@ -77,18 +77,18 @@ static LLVMBool RoundTripFinalizeMemory(void *object, char **errMsg) static void RoundTripDestroy(void *object) { std::cout << "RoundTripDestroy object " << object << " - " << std::endl; - delete static_cast(object); + delete static_cast(object); } -void LLVMMCJITCompiler::UseRoundTripSectionMemoryManager() +void LLVMMcJitEngine::UseRoundTripSectionMemoryManager() { auto sectionMemoryManager = std::make_unique(); options_.MCJMM = - LLVMCreateSimpleMCJITMemoryManager(&compilerState_, RoundTripAllocateCodeSection, + LLVMCreateSimpleMCJITMemoryManager(&codeState_, RoundTripAllocateCodeSection, RoundTripAllocateDataSection, RoundTripFinalizeMemory, RoundTripDestroy); } -bool LLVMMCJITCompiler::BuildMCJITEngine() +bool LLVMMcJitEngine::BuildMCJITEngine() { std::cout << " BuildMCJITEngine - " << std::endl; LLVMBool ret = LLVMCreateMCJITCompilerForModule(&engine_, module_, &options_, sizeof(options_), &error_); @@ -101,7 +101,7 @@ bool LLVMMCJITCompiler::BuildMCJITEngine() return true; } -void LLVMMCJITCompiler::BuildAndRunPasses() const +void LLVMMcJitEngine::BuildAndRunPasses() const { std::cout << "BuildAndRunPasses - " << std::endl; LLVMPassManagerRef pass = LLVMCreatePassManager(); @@ -114,14 +114,14 @@ void LLVMMCJITCompiler::BuildAndRunPasses() const std::cout << "BuildAndRunPasses + " << std::endl; } -LLVMMCJITCompiler::LLVMMCJITCompiler(LLVMModuleRef module): module_(module), engine_(nullptr), +LLVMMcJitEngine::LLVMMcJitEngine(LLVMModuleRef module): module_(module), engine_(nullptr), hostTriple_(""), error_(nullptr) { Initialize(); InitMember(); } -LLVMMCJITCompiler::~LLVMMCJITCompiler() +LLVMMcJitEngine::~LLVMMcJitEngine() { module_ = nullptr; engine_ = nullptr; @@ -129,7 +129,7 @@ LLVMMCJITCompiler::~LLVMMCJITCompiler() error_ = nullptr; } -void LLVMMCJITCompiler::Run() +void LLVMMcJitEngine::Run() { UseRoundTripSectionMemoryManager(); if (!BuildMCJITEngine()) { @@ -138,7 +138,7 @@ void LLVMMCJITCompiler::Run() BuildAndRunPasses(); } -void LLVMMCJITCompiler::Initialize() +void LLVMMcJitEngine::Initialize() { #if defined(PANDA_TARGET_AMD64) LLVMInitializeX86TargetInfo(); @@ -163,11 +163,11 @@ static const char *SymbolLookupCallback(void *disInfo, uint64_t referenceValue, return nullptr; } -void LLVMMCJITCompiler::Disassemble(std::map addr2name) const +void LLVMMcJitEngine::Disassemble(std::map addr2name) const { LLVMDisasmContextRef dcr = LLVMCreateDisasm("x86_64-unknown-linux-gnu", nullptr, 0, nullptr, SymbolLookupCallback); std::cout << "========================================================================" << std::endl; - for (auto it : compilerState_.GetCodeInfo()) { + for (auto it : codeState_.GetCodeInfo()) { uint8_t *byteSp; uintptr_t numBytes; byteSp = it.first; @@ -199,7 +199,7 @@ void LLVMMCJITCompiler::Disassemble(std::map addr2name) c std::cout << "========================================================================" << std::endl; } -void LLVMMCJITCompiler::InitMember() +void LLVMMcJitEngine::InitMember() { if (module_ == nullptr) { module_ = LLVMModuleCreateWithName("simple_module"); diff --git a/ecmascript/compiler/llvm_mcjit_compiler.h b/ecmascript/compiler/llvm_mcjit_engine.h similarity index 75% rename from ecmascript/compiler/llvm_mcjit_compiler.h rename to ecmascript/compiler/llvm_mcjit_engine.h index b8c38782c6..594141ed45 100644 --- a/ecmascript/compiler/llvm_mcjit_compiler.h +++ b/ecmascript/compiler/llvm_mcjit_engine.h @@ -13,8 +13,8 @@ * limitations under the License. */ -#ifndef ECMASCRIPT_COMPILER_LLVM_MCJINT_COMPILER_H -#define ECMASCRIPT_COMPILER_LLVM_MCJINT_COMPILER_H +#ifndef ECMASCRIPT_COMPILER_LLVM_MCJINT_ENGINE_H +#define ECMASCRIPT_COMPILER_LLVM_MCJINT_ENGINE_H #include #include @@ -37,39 +37,40 @@ namespace kungfu { using ByteBuffer = std::vector; using BufferList = std::list; using StringList = std::list; -struct CompilerState { - CompilerState(): machineCode(nullptr), codeBufferPos(0), stackMapsSection_(nullptr) +struct CodeState { + CodeState() : machineCode(nullptr), codeBufferPos(0), stackMapsSection_(nullptr) { Reset(); static constexpr int prot = PROT_READ | PROT_WRITE | PROT_EXEC; // NOLINT(hicpp-signed-bitwise) static constexpr int flags = MAP_ANONYMOUS | MAP_SHARED; // NOLINT(hicpp-signed-bitwise) machineCode = static_cast(mmap(nullptr, MAX_MACHINE_CODE_SIZE, prot, flags, -1, 0)); + std::cerr << std::hex << "machineCode : " << reinterpret_cast(machineCode) << std::endl; } - ~CompilerState() + ~CodeState() { Reset(); munmap(machineCode, MAX_MACHINE_CODE_SIZE); } - uint8_t* AllocaCodeSection(uintptr_t size, const char* sectionName) + uint8_t *AllocaCodeSection(uintptr_t size, const char *sectionName) { uint8_t *addr = nullptr; if (codeBufferPos + size > MAX_MACHINE_CODE_SIZE) { - std::cerr << std::hex << "AllocaCodeSection failed alloc codeBufferPos:" << codeBufferPos << " size:" - << size << " larger MAX_MACHINE_CODE_SIZE:" << MAX_MACHINE_CODE_SIZE << std::endl; + std::cerr << std::hex << "AllocaCodeSection failed alloc codeBufferPos:" << codeBufferPos + << " size:" << size << " larger MAX_MACHINE_CODE_SIZE:" << MAX_MACHINE_CODE_SIZE << std::endl; return nullptr; } std::cout << "AllocaCodeSection size:" << size << std::endl; std::vector codeBuffer(machineCode[codeBufferPos], size); std::cout << " codeBuffer size: " << codeBuffer.size() << std::endl; - codeBufferPos += size; codeSectionNames_.push_back(sectionName); addr = machineCode + codeBufferPos; std::cout << "AllocaCodeSection addr:" << std::hex << reinterpret_cast(addr) << std::endl; codeInfo_.push_back({addr, size}); + codeBufferPos += size; return addr; } - uint8_t* AllocaDataSection(uintptr_t size, const char* sectionName) + uint8_t *AllocaDataSection(uintptr_t size, const char *sectionName) { uint8_t *addr = nullptr; dataSectionList_.push_back(std::vector()); @@ -92,30 +93,42 @@ struct CompilerState { codeSectionNames_.clear(); codeBufferPos = 0; } - uint8_t* GetStackMapsSection() const + + uint8_t *GetStackMapsSection() const { return stackMapsSection_; } std::vector> GetCodeInfo() const { - return codeInfo_; + return codeInfo_; } + + int GetCodeSize() const + { + return codeBufferPos; + } + + uint8_t *GetCodeBuff() const + { + return machineCode; + } + private: BufferList dataSectionList_ {}; StringList dataSectionNames_ {}; StringList codeSectionNames_ {}; uint8_t *machineCode; - const size_t MAX_MACHINE_CODE_SIZE = (1 << 20); // 1M + const size_t MAX_MACHINE_CODE_SIZE = (1 << 20); // 1M int codeBufferPos = 0; /* for asssembler */ std::vector> codeInfo_ {}; /* stack map */ - uint8_t* stackMapsSection_ {nullptr}; + uint8_t *stackMapsSection_ {nullptr}; }; -class LLVMMCJITCompiler { +class LLVMMcJitEngine { public: - explicit LLVMMCJITCompiler(LLVMModuleRef module); - virtual ~LLVMMCJITCompiler(); + explicit LLVMMcJitEngine(LLVMModuleRef module); + virtual ~LLVMMcJitEngine(); void Run(); const LLVMExecutionEngineRef &GetEngine() { @@ -124,7 +137,16 @@ public: void Disassemble(std::map addr2name = std::map()) const; uint8_t *GetStackMapsSection() const { - return compilerState_.GetStackMapsSection(); + return codeState_.GetStackMapsSection(); + } + + int GetCodeSize() const + { + return codeState_.GetCodeSize(); + } + uint8_t *GetCodeBuffer() const + { + return codeState_.GetCodeBuff(); } private: @@ -140,8 +162,7 @@ private: LLVMExecutionEngineRef engine_; std::string hostTriple_; char *error_; - struct CompilerState compilerState_; + struct CodeState codeState_; }; - -#endif } // namespace kungfu +#endif // ECMASCRIPT_COMPILER_LLVM_MCJINT_ENGINE_H diff --git a/ecmascript/compiler/scheduler.h b/ecmascript/compiler/scheduler.h index edfa7be124..69f569b91b 100644 --- a/ecmascript/compiler/scheduler.h +++ b/ecmascript/compiler/scheduler.h @@ -25,18 +25,19 @@ #include "ecmascript/compiler/circuit.h" namespace kungfu { +using ControlFlowGraph = std::vector>; class Scheduler { public: static std::tuple, std::unordered_map, std::vector> CalculateDominatorTree(const Circuit *circuit); - static std::vector> Run(const Circuit *circuit); + static ControlFlowGraph Run(const Circuit *circuit); static std::optional> CalculateSchedulingUpperBound(const Circuit *circuit, const std::unordered_map &bbGatesAddrToIdx, const std::function &isAncestor, const std::vector &schedulableGatesList); static std::optional> CalculateSchedulingLowerBound(const Circuit *circuit, const std::unordered_map &bbGatesAddrToIdx, const std::function &lowestCommonAncestor, std::vector *order = nullptr); - static void Print(const std::vector> *cfg, const Circuit *circuit); + static void Print(const ControlFlowGraph *cfg, const Circuit *circuit); }; }; // namespace kungfu diff --git a/ecmascript/compiler/stub_optimizer.cpp b/ecmascript/compiler/stub.cpp similarity index 71% rename from ecmascript/compiler/stub_optimizer.cpp rename to ecmascript/compiler/stub.cpp index 25e344e793..9dad1d308a 100644 --- a/ecmascript/compiler/stub_optimizer.cpp +++ b/ecmascript/compiler/stub.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "ecmascript/compiler/stub_optimizer.h" +#include "ecmascript/compiler/stub.h" #include "ecmascript/compiler/llvm_ir_builder.h" #include "ecmascript/js_object.h" @@ -21,17 +21,17 @@ #include "libpandabase/macros.h" namespace kungfu { -using StubOPtimizerLabelImplement = StubOptimizerLabel::StubOptimizerLabelImplement; +using StubLabelImpl = Stub::StubLabel::StubLabelImpl; -StubOptimizerLabel::StubOptimizerLabel(Environment *env) +Stub::StubLabel::StubLabel(Environment *env) { - impl_ = env->NewStubOptimizerLabel(env); + impl_ = env->NewStubLabel(env); } -AddrShift StubVariable::AddPhiOperand(AddrShift val) +AddrShift Stub::StubVariable::AddPhiOperand(AddrShift val) { ASSERT(IsSelector(val)); - StubOptimizerLabel label = env_->GetLabelFromSelector(val); + StubLabel label = env_->GetLabelFromSelector(val); size_t idx = 0; for (auto pred : label.GetPredecessors()) { idx++; @@ -41,15 +41,15 @@ AddrShift StubVariable::AddPhiOperand(AddrShift val) return TryRemoveTrivialPhi(val); } -AddrShift StubVariable::AddOperandToSelector(AddrShift val, size_t idx, AddrShift in) +AddrShift Stub::StubVariable::AddOperandToSelector(AddrShift val, size_t idx, AddrShift in) { - env_->GetCircuit().NewIn(val, idx, in); + env_->GetCircuit()->NewIn(val, idx, in); return val; } -AddrShift StubVariable::TryRemoveTrivialPhi(AddrShift phiVal) +AddrShift Stub::StubVariable::TryRemoveTrivialPhi(AddrShift phiVal) { - Gate *phi = env_->GetCircuit().LoadGatePtr(phiVal); + Gate *phi = env_->GetCircuit()->LoadGatePtr(phiVal); Gate *same = nullptr; for (size_t i = 1; i < phi->GetNumIns(); ++i) { In *phiIn = phi->GetIn(i); @@ -64,7 +64,7 @@ AddrShift StubVariable::TryRemoveTrivialPhi(AddrShift phiVal) } if (same == nullptr) { // the phi is unreachable or in the start block - same = env_->GetCircuit().LoadGatePtr(env_->GetCircuitBuilder().UndefineConstant()); + same = env_->GetCircuit()->LoadGatePtr(env_->GetCircuitBuilder().UndefineConstant()); } // remove the trivial phi @@ -91,14 +91,14 @@ AddrShift StubVariable::TryRemoveTrivialPhi(AddrShift phiVal) // try to recursiveby remove all phi users, which might have vecome trivial for (auto out : outs) { if (IsSelector(out->GetGate())) { - auto out_addr_shift = env_->GetCircuit().SaveGatePtr(out->GetGate()); + auto out_addr_shift = env_->GetCircuit()->SaveGatePtr(out->GetGate()); TryRemoveTrivialPhi(out_addr_shift); } } - return env_->GetCircuit().SaveGatePtr(same); + return env_->GetCircuit()->SaveGatePtr(same); } -void StubVariable::RerouteOuts(const std::vector &outs, Gate *newGate) +void Stub::StubVariable::RerouteOuts(const std::vector &outs, Gate *newGate) { // reroute all outs to new node for (auto out : outs) { @@ -107,7 +107,7 @@ void StubVariable::RerouteOuts(const std::vector &outs, Gate *newGate) } } -void StubOPtimizerLabelImplement::Seal() +void StubLabelImpl::Seal() { for (auto &[variable, gate] : incompletePhis_) { variable->AddPhiOperand(gate); @@ -115,12 +115,12 @@ void StubOPtimizerLabelImplement::Seal() isSealed_ = true; } -void StubOPtimizerLabelImplement::WriteVariable(StubVariable *var, AddrShift value) +void StubLabelImpl::WriteVariable(StubVariable *var, AddrShift value) { valueMap_[var] = value; } -AddrShift StubOPtimizerLabelImplement::ReadVariable(StubVariable *var) +AddrShift StubLabelImpl::ReadVariable(StubVariable *var) { if (valueMap_.find(var) != valueMap_.end()) { return valueMap_.at(var); @@ -128,7 +128,7 @@ AddrShift StubOPtimizerLabelImplement::ReadVariable(StubVariable *var) return ReadVariableRecursive(var); } -AddrShift StubOPtimizerLabelImplement::ReadVariableRecursive(StubVariable *var) +AddrShift StubLabelImpl::ReadVariableRecursive(StubVariable *var) { AddrShift val; OpCode opcode = CircuitBuilder::GetSelectOpCodeFromMachineType(var->Type()); @@ -137,13 +137,13 @@ AddrShift StubOPtimizerLabelImplement::ReadVariableRecursive(StubVariable *var) int valueCounts = static_cast(this->predecessors.size()) + 1; val = env_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, valueCounts); - env_->AddSelectorToLabel(val, StubOptimizerLabel(this)); + env_->AddSelectorToLabel(val, StubLabel(this)); incompletePhis_[var] = val; } else if (predecessors.size() == 1) { val = predecessors[0]->ReadVariable(var); } else { val = env_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, this->predecessors.size()); - env_->AddSelectorToLabel(val, StubOptimizerLabel(this)); + env_->AddSelectorToLabel(val, StubLabel(this)); WriteVariable(var, val); val = var->AddPhiOperand(val); } @@ -151,7 +151,7 @@ AddrShift StubOPtimizerLabelImplement::ReadVariableRecursive(StubVariable *var) return val; } -void StubOPtimizerLabelImplement::Bind() +void StubLabelImpl::Bind() { ASSERT(!predecessors.empty()); if (IsNeedSeal()) { @@ -160,7 +160,7 @@ void StubOPtimizerLabelImplement::Bind() } } -void StubOPtimizerLabelImplement::MergeAllControl() +void StubLabelImpl::MergeAllControl() { if (predecessors.size() < 2) { // 2 : Loop Head only support two predecessors return; @@ -169,7 +169,7 @@ void StubOPtimizerLabelImplement::MergeAllControl() if (IsLoopHead()) { ASSERT(predecessors.size() == 2); // 2 : Loop Head only support two predecessors ASSERT(otherPredeControls_.size() == 1); - env_->GetCircuit().NewIn(predeControl_, 1, otherPredeControls_[0]); + env_->GetCircuit()->NewIn(predeControl_, 1, otherPredeControls_[0]); return; } @@ -188,139 +188,117 @@ void StubOPtimizerLabelImplement::MergeAllControl() control_ = merge; } -void StubOPtimizerLabelImplement::AppendPredecessor(StubOptimizerLabelImplement *predecessor) +void StubLabelImpl::AppendPredecessor(StubLabelImpl *predecessor) { if (predecessor != nullptr) { predecessors.push_back(predecessor); } } -bool StubOPtimizerLabelImplement::IsNeedSeal() const +bool StubLabelImpl::IsNeedSeal() const { - auto control = env_->GetCircuit().LoadGatePtr(predeControl_); + auto control = env_->GetCircuit()->LoadGatePtr(predeControl_); auto numsInList = control->GetOpCode().GetOpCodeNumInsArray(control->GetBitField()); return predecessors.size() >= numsInList[0]; } -bool StubOPtimizerLabelImplement::IsLoopHead() const +bool StubLabelImpl::IsLoopHead() const { - return env_->GetCircuit().IsLoopHead(predeControl_); + return env_->GetCircuit()->IsLoopHead(predeControl_); } -Environment::Environment(const char *name, size_t arguments) - : builder_(&circuit_), arguments_(arguments), method_name_(name) +Stub::Environment::Environment(size_t arguments, Circuit *circuit) + : circuit_(circuit), builder_(circuit), arguments_(arguments) { for (size_t i = 0; i < arguments; i++) { arguments_[i] = builder_.NewArguments(i); } - entry_ = StubOptimizerLabel(NewStubOptimizerLabel(this, Circuit::GetCircuitRoot(OpCode(OpCode::STATE_ENTRY)))); + entry_ = StubLabel(NewStubLabel(this, Circuit::GetCircuitRoot(OpCode(OpCode::STATE_ENTRY)))); currentLabel_ = &entry_; currentLabel_->Seal(); } -Environment::Environment(Environment const &env) - : circuit_(env.circuit_), builder_(&circuit_), arguments_(env.arguments_), method_name_(env.method_name_) -{ - entry_ = StubOptimizerLabel(NewStubOptimizerLabel(this, Circuit::GetCircuitRoot(OpCode(OpCode::STATE_ENTRY)))); - currentLabel_ = &entry_; - currentLabel_->Seal(); -} - -Environment &Environment::operator=(const Environment &env) -{ - if (&env != this) { - this->circuit_ = env.circuit_; - this->arguments_ = env.arguments_; - this->method_name_ = env.method_name_; - - entry_ = StubOptimizerLabel(NewStubOptimizerLabel(this, Circuit::GetCircuitRoot(OpCode(OpCode::STATE_ENTRY)))); - currentLabel_ = &entry_; - currentLabel_->Seal(); - } - return *this; -} - -Environment::~Environment() +Stub::Environment::~Environment() { for (auto label : rawlabels_) { delete label; } } -void StubOptimizer::Jump(Label *label) +void Stub::Jump(Label *label) { ASSERT(label); - auto currentLabel = env_->GetCurrentLabel(); + auto currentLabel = env_.GetCurrentLabel(); auto currentControl = currentLabel->GetControl(); - auto jump = env_->GetCircuitBuilder().Goto(currentControl); + auto jump = env_.GetCircuitBuilder().Goto(currentControl); currentLabel->SetControl(jump); label->AppendPredecessor(currentLabel); label->MergeControl(currentLabel->GetControl()); - env_->SetCurrentLabel(nullptr); + env_.SetCurrentLabel(nullptr); } -void StubOptimizer::Branch(AddrShift condition, Label *trueLabel, Label *falseLabel) +void Stub::Branch(AddrShift condition, Label *trueLabel, Label *falseLabel) { - auto currentLabel = env_->GetCurrentLabel(); + auto currentLabel = env_.GetCurrentLabel(); auto currentControl = currentLabel->GetControl(); - AddrShift ifBranch = env_->GetCircuitBuilder().Branch(currentControl, condition); + AddrShift ifBranch = env_.GetCircuitBuilder().Branch(currentControl, condition); currentLabel->SetControl(ifBranch); - AddrShift ifTrue = env_->GetCircuitBuilder().NewIfTrue(ifBranch); - trueLabel->AppendPredecessor(env_->GetCurrentLabel()); + AddrShift ifTrue = env_.GetCircuitBuilder().NewIfTrue(ifBranch); + trueLabel->AppendPredecessor(env_.GetCurrentLabel()); trueLabel->MergeControl(ifTrue); - AddrShift ifFalse = env_->GetCircuitBuilder().NewIfFalse(ifBranch); - falseLabel->AppendPredecessor(env_->GetCurrentLabel()); + AddrShift ifFalse = env_.GetCircuitBuilder().NewIfFalse(ifBranch); + falseLabel->AppendPredecessor(env_.GetCurrentLabel()); falseLabel->MergeControl(ifFalse); - env_->SetCurrentLabel(nullptr); + env_.SetCurrentLabel(nullptr); } -void StubOptimizer::Switch(AddrShift index, Label *defaultLabel, int32_t *keysValue, Label *keysLabel, int numberOfKeys) +void Stub::Switch(AddrShift index, Label *defaultLabel, int32_t *keysValue, Label *keysLabel, int numberOfKeys) { - auto currentLabel = env_->GetCurrentLabel(); + auto currentLabel = env_.GetCurrentLabel(); auto currentControl = currentLabel->GetControl(); - AddrShift switchBranch = env_->GetCircuitBuilder().SwitchBranch(currentControl, index, numberOfKeys); + AddrShift switchBranch = env_.GetCircuitBuilder().SwitchBranch(currentControl, index, numberOfKeys); currentLabel->SetControl(switchBranch); for (int i = 0; i < numberOfKeys; i++) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - AddrShift switchCase = env_->GetCircuitBuilder().NewSwitchCase(switchBranch, keysValue[i]); + AddrShift switchCase = env_.GetCircuitBuilder().NewSwitchCase(switchBranch, keysValue[i]); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) keysLabel[i].AppendPredecessor(currentLabel); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) keysLabel[i].MergeControl(switchCase); } - AddrShift defaultCase = env_->GetCircuitBuilder().NewDefaultCase(switchBranch); + AddrShift defaultCase = env_.GetCircuitBuilder().NewDefaultCase(switchBranch); defaultLabel->AppendPredecessor(currentLabel); defaultLabel->MergeControl(defaultCase); - env_->SetCurrentLabel(nullptr); + env_.SetCurrentLabel(nullptr); } -void StubOptimizer::LoopBegin(Label *loopHead) +void Stub::LoopBegin(Label *loopHead) { ASSERT(loopHead); - auto loopControl = env_->GetCircuitBuilder().LoopBegin(loopHead->GetControl()); + auto loopControl = env_.GetCircuitBuilder().LoopBegin(loopHead->GetControl()); loopHead->SetControl(loopControl); loopHead->SetPreControl(loopControl); loopHead->Bind(); - env_->SetCurrentLabel(loopHead); + env_.SetCurrentLabel(loopHead); } -void StubOptimizer::LoopEnd(Label *loopHead) +void Stub::LoopEnd(Label *loopHead) { ASSERT(loopHead); - auto currentLabel = env_->GetCurrentLabel(); + auto currentLabel = env_.GetCurrentLabel(); auto currentControl = currentLabel->GetControl(); - auto loopend = env_->GetCircuitBuilder().LoopEnd(currentControl); + auto loopend = env_.GetCircuitBuilder().LoopEnd(currentControl); currentLabel->SetControl(loopend); loopHead->AppendPredecessor(currentLabel); loopHead->MergeControl(loopend); loopHead->Seal(); loopHead->MergeAllControl(); - env_->SetCurrentLabel(nullptr); + env_.SetCurrentLabel(nullptr); } -AddrShift StubOptimizer::FixLoadType(AddrShift x) +AddrShift Stub::FixLoadType(AddrShift x) { if (PtrValueCode() == ValueCode::INT64) { return SExtInt32ToInt64(x); @@ -331,7 +309,7 @@ AddrShift StubOptimizer::FixLoadType(AddrShift x) UNREACHABLE(); } -AddrShift StubOptimizer::LoadFromObject(MachineType type, AddrShift object, AddrShift offset) +AddrShift Stub::LoadFromObject(MachineType type, AddrShift object, AddrShift offset) { AddrShift elementsOffset = GetInteger32Constant(panda::ecmascript::JSObject::ELEMENTS_OFFSET); if (PtrValueCode() == ValueCode::INT64) { @@ -349,11 +327,13 @@ AddrShift StubOptimizer::LoadFromObject(MachineType type, AddrShift object, Addr return Load(type, ChangeInt64ToPointer(elements), dataOffset); } -AddrShift StubOptimizer::FindElementFromNumberDictionary(AddrShift thread, AddrShift elements, AddrShift key, - Label *next) +AddrShift Stub::FindElementFromNumberDictionary(AddrShift thread, AddrShift elements, AddrShift key) { auto env = GetEnvironment(); + Label subentry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &subentry); DEFVARIABLE(result, INT32_TYPE, GetInteger32Constant(-1)); + Label exit(env); AddrShift capcityoffset = PtrMul(GetPtrConstant(panda::ecmascript::JSTaggedValue::TaggedTypeSize()), GetPtrConstant(panda::ecmascript::TaggedHashTable::SIZE_INDEX)); @@ -363,7 +343,7 @@ AddrShift StubOptimizer::FindElementFromNumberDictionary(AddrShift thread, AddrS AddrShift pKey = Alloca(static_cast(MachineRep::K_WORD32)); AddrShift keyStore = Store(INT32_TYPE, pKey, GetPtrConstant(0), TaggedCastToInt32(key)); - StubInterfaceDescriptor *getHash32Descriptor = GET_STUBDESCRIPTOR(GetHash32); + StubDescriptor *getHash32Descriptor = GET_STUBDESCRIPTOR(GetHash32); AddrShift len = GetInteger32Constant(sizeof(int) / sizeof(uint8_t)); AddrShift hash = CallRuntime(getHash32Descriptor, thread, GetWord64Constant(FAST_STUB_ID(GetHash32)), keyStore, {pKey, len}); @@ -373,8 +353,7 @@ AddrShift StubOptimizer::FindElementFromNumberDictionary(AddrShift thread, AddrS Label afterLoop(env); Jump(&loopHead); LoopBegin(&loopHead); - Label afterGetKey(env); - AddrShift element = GetKeyFromNumberDictionary(elements, *entry, &afterGetKey); + AddrShift element = GetKeyFromNumberDictionary(elements, *entry); Label isHole(env); Label notHole(env); Branch(TaggedIsHole(element), &isHole, ¬Hole); @@ -386,28 +365,30 @@ AddrShift StubOptimizer::FindElementFromNumberDictionary(AddrShift thread, AddrS Branch(TaggedIsUndefined(element), &isUndefined, ¬Undefined); Bind(&isUndefined); result = GetInteger32Constant(-1); - Jump(next); + Jump(&exit); Bind(¬Undefined); - Label afterIsMatch(env); Label isMatch(env); Label notMatch(env); - Branch(IsMatchInNumberDictionary(key, element, &afterIsMatch), &isMatch, ¬Match); + Branch(IsMatchInNumberDictionary(key, element), &isMatch, ¬Match); Bind(&isMatch); result = *entry; - Jump(next); + Jump(&exit); Bind(¬Match); Jump(&loopEnd); Bind(&loopEnd); entry = Word32And(Int32Add(*entry, *count), Int32Sub(capacity, GetInteger32Constant(1))); count = Int32Add(*count, GetInteger32Constant(1)); LoopEnd(&loopHead); - Bind(next); + Bind(&exit); return *result; } -AddrShift StubOptimizer::IsMatchInNumberDictionary(AddrShift key, AddrShift other, Label *next) +AddrShift Stub::IsMatchInNumberDictionary(AddrShift key, AddrShift other) { auto env = GetEnvironment(); + Label entry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &entry); + Label exit(env); DEFVARIABLE(result, BOOL_TYPE, FalseConstant()); Label isHole(env); Label notHole(env); @@ -415,11 +396,11 @@ AddrShift StubOptimizer::IsMatchInNumberDictionary(AddrShift key, AddrShift othe Label notUndefined(env); Branch(TaggedIsHole(key), &isHole, ¬Hole); Bind(&isHole); - Jump(next); + Jump(&exit); Bind(¬Hole); Branch(TaggedIsUndefined(key), &isUndefined, ¬Undefined); Bind(&isUndefined); - Jump(next); + Jump(&exit); Bind(¬Undefined); Label keyIsInt(env); Label keyNotInt(env); @@ -430,18 +411,21 @@ AddrShift StubOptimizer::IsMatchInNumberDictionary(AddrShift key, AddrShift othe Branch(TaggedIsInt(other), &otherIsInt, &otherNotInt); Bind(&otherIsInt); result = Word32Equal(TaggedCastToInt32(key), TaggedCastToInt32(other)); - Jump(next); + Jump(&exit); Bind(&otherNotInt); - Jump(next); + Jump(&exit); Bind(&keyNotInt); - Jump(next); - Bind(next); + Jump(&exit); + Bind(&exit); return *result; } -AddrShift StubOptimizer::GetKeyFromNumberDictionary(AddrShift elements, AddrShift entry, Label *next) +AddrShift Stub::GetKeyFromNumberDictionary(AddrShift elements, AddrShift entry) { auto env = GetEnvironment(); + Label subentry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &subentry); + Label exit(env); DEFVARIABLE(result, TAGGED_TYPE, GetUndefinedConstant()); Label ltZero(env); Label notLtZero(env); @@ -453,29 +437,32 @@ AddrShift StubOptimizer::GetKeyFromNumberDictionary(AddrShift elements, AddrShif Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); Branch(Int32LessThan(arrayIndex, GetInteger32Constant(0)), <Zero, ¬LtZero); Bind(<Zero); - Jump(next); + Jump(&exit); Bind(¬LtZero); Branch(Int32GreaterThan(arrayIndex, dictionaryLength), >Length, ¬GtLength); Bind(>Length); - Jump(next); + Jump(&exit); Bind(¬GtLength); result = GetValueFromTaggedArray(elements, arrayIndex); - Jump(next); - Bind(next); + Jump(&exit); + Bind(&exit); return *result; } -void StubOptimizer::ThrowTypeAndReturn(AddrShift thread, int messageId, AddrShift val) +void Stub::ThrowTypeAndReturn(AddrShift thread, int messageId, AddrShift val) { - StubInterfaceDescriptor *throwTypeError = GET_STUBDESCRIPTOR(ThrowTypeError); + StubDescriptor *throwTypeError = GET_STUBDESCRIPTOR(ThrowTypeError); AddrShift taggedId = IntBuildTagged(GetInteger32Constant(messageId)); CallStub(throwTypeError, GetWord64Constant(FAST_STUB_ID(ThrowTypeError)), {thread, taggedId}); Return(val); } -AddrShift StubOptimizer::TaggedToRepresentation(AddrShift value, Label *next) +AddrShift Stub::TaggedToRepresentation(AddrShift value) { auto env = GetEnvironment(); + Label entry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &entry); + Label exit(env); DEFVARIABLE(resultRep, INT64_TYPE, GetWord64Constant(static_cast(panda::ecmascript::Representation::OBJECT))); Label isInt(env); @@ -485,7 +472,7 @@ AddrShift StubOptimizer::TaggedToRepresentation(AddrShift value, Label *next) Bind(&isInt); { resultRep = GetWord64Constant(static_cast(panda::ecmascript::Representation::INT)); - Jump(next); + Jump(&exit); } Bind(¬Int); { @@ -495,32 +482,34 @@ AddrShift StubOptimizer::TaggedToRepresentation(AddrShift value, Label *next) Bind(&isDouble); { resultRep = GetWord64Constant(static_cast(panda::ecmascript::Representation::DOUBLE)); - Jump(next); + Jump(&exit); } Bind(¬Double); { resultRep = GetWord64Constant(static_cast(panda::ecmascript::Representation::OBJECT)); - Jump(next); + Jump(&exit); } } - Bind(next); + Bind(&exit); return *resultRep; } -AddrShift StubOptimizer::UpdateRepresention(AddrShift oldRep, AddrShift value, Label *next) +AddrShift Stub::UpdateRepresention(AddrShift oldRep, AddrShift value) { auto env = GetEnvironment(); + Label entry(env); + [[maybe_unused]] SubCircuitScope subCircuit(env, &entry); + Label exit(env); DEFVARIABLE(resultRep, INT64_TYPE, oldRep); Label isMixedRep(env); Label notMiexedRep(env); Branch(Word64Equal(oldRep, GetWord64Constant(static_cast(panda::ecmascript::Representation::MIXED))), &isMixedRep, ¬MiexedRep); Bind(&isMixedRep); - Jump(next); + Jump(&exit); Bind(¬MiexedRep); { - Label newRepLabel(env); - AddrShift newRep = TaggedToRepresentation(value, &newRepLabel); + AddrShift newRep = TaggedToRepresentation(value); Label isNoneRep(env); Label notNoneRep(env); Branch(Word64Equal(oldRep, GetWord64Constant(static_cast(panda::ecmascript::Representation::NONE))), @@ -528,7 +517,7 @@ AddrShift StubOptimizer::UpdateRepresention(AddrShift oldRep, AddrShift value, L Bind(&isNoneRep); { resultRep = newRep; - Jump(next); + Jump(&exit); } Bind(¬NoneRep); { @@ -538,7 +527,7 @@ AddrShift StubOptimizer::UpdateRepresention(AddrShift oldRep, AddrShift value, L Bind(&isEqaulNewRep); { resultRep = newRep; - Jump(next); + Jump(&exit); } Bind(¬EqaualNewRep); { @@ -577,31 +566,31 @@ AddrShift StubOptimizer::UpdateRepresention(AddrShift oldRep, AddrShift value, L Bind(¬ObjectNewRep); { resultRep = GetWord64Constant(static_cast(panda::ecmascript::Representation::NUMBER)); - Jump(next); + Jump(&exit); } Bind(&isObjectNewRep); { resultRep = GetWord64Constant(static_cast(panda::ecmascript::Representation::MIXED)); - Jump(next); + Jump(&exit); } } Bind(&objectLabel); { resultRep = GetWord64Constant(static_cast(panda::ecmascript::Representation::MIXED)); - Jump(next); + Jump(&exit); } Bind(&defaultLabel); - Jump(next); + Jump(&exit); } } } - Bind(next); + Bind(&exit); return *resultRep; } -void StubOptimizer::UpdateAndStoreRepresention(AddrShift hclass, AddrShift value, Label *next) +void Stub::UpdateAndStoreRepresention(AddrShift hclass, AddrShift value) { - AddrShift newRep = UpdateRepresention(GetElementRepresentation(hclass), value, next); + AddrShift newRep = UpdateRepresention(GetElementRepresentation(hclass), value); SetElementRepresentation(hclass, newRep); } } // namespace kungfu \ No newline at end of file diff --git a/ecmascript/compiler/stub_optimizer.h b/ecmascript/compiler/stub.h similarity index 53% rename from ecmascript/compiler/stub_optimizer.h rename to ecmascript/compiler/stub.h index cedc09c784..743bac26ed 100644 --- a/ecmascript/compiler/stub_optimizer.h +++ b/ecmascript/compiler/stub.h @@ -13,320 +13,355 @@ * limitations under the License. */ -#ifndef ECMASCRIPT_COMPILER_STUBOPTIMIZER_H -#define ECMASCRIPT_COMPILER_STUBOPTIMIZER_H +#ifndef ECMASCRIPT_COMPILER_Stub_H +#define ECMASCRIPT_COMPILER_Stub_H #include "ecmascript/accessor_data.h" #include "ecmascript/compiler/circuit.h" #include "ecmascript/compiler/circuit_builder.h" #include "ecmascript/compiler/gate.h" -#include "ecmascript/compiler/stub_interface.h" +#include "ecmascript/compiler/stub_descriptor.h" #include "ecmascript/js_object.h" #include "ecmascript/js_tagged_value.h" #include "ecmascript/tagged_dictionary.h" namespace kungfu { -class CompilerOptions; -class Environment; -class StubOptimizerLabel; -class StubVariable; -class CallerDescriptor; + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DEFVARIABLE(varname, type, val) StubVariable varname(GetEnvironment(), type, NextVariableId(), val) +#define DEFVARIABLE(varname, type, val) Stub::StubVariable varname(GetEnvironment(), type, NextVariableId(), val) -class StubOptimizerLabel { +class Stub { public: - class StubOptimizerLabelImplement { + class Environment; + class StubLabel; + class StubVariable; + using Label = StubLabel; + using Variable = StubVariable; + + class StubLabel { public: - StubOptimizerLabelImplement(Environment *env, AddrShift control) - : env_(env), control_(control), predeControl_(-1), isSealed_(false) + class StubLabelImpl { + public: + StubLabelImpl(Environment *env, AddrShift control) + : env_(env), control_(control), predeControl_(-1), isSealed_(false) + { + } + + ~StubLabelImpl() = default; + + NO_MOVE_SEMANTIC(StubLabelImpl); + NO_COPY_SEMANTIC(StubLabelImpl); + using Variable = StubVariable; + void Seal(); + void WriteVariable(Variable *var, AddrShift value); + AddrShift ReadVariable(Variable *var); + void Bind(); + void MergeAllControl(); + void AppendPredecessor(StubLabelImpl *predecessor); + std::vector GetPredecessors() const + { + return predecessors; + } + + void SetControl(AddrShift control) + { + control_ = control; + } + + void SetPreControl(AddrShift control) + { + predeControl_ = control; + } + + void MergeControl(AddrShift control) + { + if (predeControl_ == -1) { + predeControl_ = control; + control_ = predeControl_; + } else { + otherPredeControls_.push_back(control); + } + } + + AddrShift GetControl() const + { + return control_; + } + + private: + bool IsNeedSeal() const; + bool IsSealed() const + { + return isSealed_; + } + bool IsLoopHead() const; + AddrShift ReadVariableRecursive(Variable *var); + Environment *env_; + AddrShift control_; + AddrShift predeControl_; + std::vector otherPredeControls_; + bool isSealed_; + std::map valueMap_; + std::vector phi; + std::vector predecessors; + std::map incompletePhis_; + }; + explicit StubLabel() = default; + explicit StubLabel(Environment *env); + explicit StubLabel(StubLabelImpl *impl) : impl_(impl) {} + ~StubLabel() = default; + using Variable = StubVariable; + StubLabel(StubLabel const &label) = default; + StubLabel &operator=(StubLabel const &label) = default; + StubLabel(StubLabel &&label) = default; + StubLabel &operator=(StubLabel &&label) = default; + + void Seal() { + return impl_->Seal(); } - ~StubOptimizerLabelImplement() = default; + void WriteVariable(Variable *var, AddrShift value) + { + impl_->WriteVariable(var, value); + } - NO_MOVE_SEMANTIC(StubOptimizerLabelImplement); - NO_COPY_SEMANTIC(StubOptimizerLabelImplement); - using Variable = StubVariable; - void Seal(); - void WriteVariable(Variable *var, AddrShift value); - AddrShift ReadVariable(Variable *var); - void Bind(); - void MergeAllControl(); - void AppendPredecessor(StubOptimizerLabelImplement *predecessor); - std::vector GetPredecessors() const + AddrShift ReadVariable(Variable *var) + { + return impl_->ReadVariable(var); + } + + void Bind() { - return predecessors; + impl_->Bind(); + } + + void MergeAllControl() + { + impl_->MergeAllControl(); + } + + void AppendPredecessor(const StubLabel *predecessor) + { + impl_->AppendPredecessor(predecessor->GetRawLabel()); + } + + std::vector GetPredecessors() const + { + std::vector labels; + for (auto rawlabel : impl_->GetPredecessors()) { + labels.emplace_back(StubLabel(rawlabel)); + } + return labels; } void SetControl(AddrShift control) { - control_ = control; + impl_->SetControl(control); } void SetPreControl(AddrShift control) { - predeControl_ = control; + impl_->SetPreControl(control); } void MergeControl(AddrShift control) { - if (predeControl_ == -1) { - predeControl_ = control; - control_ = predeControl_; - } else { - otherPredeControls_.push_back(control); - } + impl_->MergeControl(control); } AddrShift GetControl() const { - return control_; + return impl_->GetControl(); } private: - bool IsNeedSeal() const; - bool IsSealed() const + friend class Environment; + StubLabelImpl *GetRawLabel() const { - return isSealed_; + return impl_; } - bool IsLoopHead() const; - AddrShift ReadVariableRecursive(Variable *var); - Environment *env_; - AddrShift control_; - AddrShift predeControl_; - std::vector otherPredeControls_; - bool isSealed_; - std::map valueMap_; - std::vector phi; - std::vector predecessors; - std::map incompletePhis_; + StubLabelImpl *impl_ {nullptr}; }; - explicit StubOptimizerLabel() = default; - explicit StubOptimizerLabel(Environment *env); - explicit StubOptimizerLabel(StubOptimizerLabelImplement *impl) : impl_(impl) {} - ~StubOptimizerLabel() = default; - using Variable = StubVariable; - StubOptimizerLabel(StubOptimizerLabel const &label) = default; - StubOptimizerLabel &operator=(StubOptimizerLabel const &label) = default; - StubOptimizerLabel(StubOptimizerLabel &&label) = default; - StubOptimizerLabel &operator=(StubOptimizerLabel &&label) = default; - - void Seal() - { - return impl_->Seal(); - } - - void WriteVariable(Variable *var, AddrShift value) - { - impl_->WriteVariable(var, value); - } - - AddrShift ReadVariable(Variable *var) - { - return impl_->ReadVariable(var); - } - void Bind() - { - impl_->Bind(); - } - - void MergeAllControl() - { - impl_->MergeAllControl(); - } - - void AppendPredecessor(const StubOptimizerLabel *predecessor) - { - impl_->AppendPredecessor(predecessor->GetRawLabel()); - } - - std::vector GetPredecessors() const - { - std::vector labels; - for (auto rawlabel : impl_->GetPredecessors()) { - labels.emplace_back(StubOptimizerLabel(rawlabel)); + class Environment { + public: + using StubLabelImpl = StubLabel::StubLabelImpl; + explicit Environment(size_t arguments, Circuit *circuit); + ~Environment(); + NO_COPY_SEMANTIC(Environment); + NO_MOVE_SEMANTIC(Environment); + StubLabel *GetCurrentLabel() const + { + return currentLabel_; + } + void SetCurrentLabel(StubLabel *label) + { + currentLabel_ = label; + } + CircuitBuilder &GetCircuitBuilder() + { + return builder_; + } + AddrShift GetArgument(size_t index) const + { + return arguments_.at(index); + } + Circuit *GetCircuit() + { + return circuit_; } - return labels; - } - - void SetControl(AddrShift control) - { - impl_->SetControl(control); - } - void SetPreControl(AddrShift control) - { - impl_->SetPreControl(control); - } + StubLabel GetLabelFromSelector(AddrShift sel) + { + StubLabelImpl *rawlabel = phi_to_labels[sel]; + return StubLabel(rawlabel); + } - void MergeControl(AddrShift control) - { - impl_->MergeControl(control); - } + void AddSelectorToLabel(AddrShift sel, StubLabel label) + { + phi_to_labels[sel] = label.GetRawLabel(); + } - AddrShift GetControl() const - { - return impl_->GetControl(); - } + StubLabelImpl *NewStubLabel(Environment *env, AddrShift control = -1) + { + auto impl = new StubLabelImpl(env, control); + rawlabels_.push_back(impl); + return impl; + } -private: - friend class Environment; - StubOptimizerLabelImplement *GetRawLabel() const - { - return impl_; - } - StubOptimizerLabelImplement *impl_{nullptr}; -}; + void PushCurrentLabel(StubLabel *entry) + { + AddrShift control = currentLabel_->GetControl(); + if (currentLabel_ != nullptr) { + stack_.push(currentLabel_); + currentLabel_ = entry; + currentLabel_->SetControl(control); + } + } -class Environment { -public: - using StubOptimizerLabelImplement = StubOptimizerLabel::StubOptimizerLabelImplement; - Environment(const char *name, size_t arguments); - ~Environment(); - Environment(Environment const &env); // copy constructor - Environment &operator=(Environment const &env); // copy constructor + void PopCurrentLabel() + { + AddrShift control = currentLabel_->GetControl(); + if (!stack_.empty()) { + currentLabel_ = stack_.top(); + currentLabel_->SetControl(control); + stack_.pop(); + } + } - NO_MOVE_SEMANTIC(Environment); - StubOptimizerLabel *GetCurrentLabel() const - { - return currentLabel_; - } - void SetCurrentLabel(StubOptimizerLabel *label) - { - currentLabel_ = label; - } - CircuitBuilder &GetCircuitBuilder() - { - return builder_; - } - AddrShift GetArgument(size_t index) const - { - return arguments_.at(index); - } - Circuit &GetCircuit() - { - return circuit_; - } + private: + StubLabel *currentLabel_ {nullptr}; + Circuit *circuit_; + CircuitBuilder builder_; + std::unordered_map phi_to_labels; + std::vector arguments_; + StubLabel entry_; + std::vector rawlabels_; + std::stack stack_; + }; - StubOptimizerLabel GetLabelFromSelector(AddrShift sel) - { - StubOptimizerLabelImplement *rawlabel = phi_to_labels[sel]; - return StubOptimizerLabel(rawlabel); - } + class StubVariable { + public: + StubVariable(Environment *env, MachineType type, uint32_t id, AddrShift value) : id_(id), type_(type), env_(env) + { + Bind(value); + env_->GetCurrentLabel()->WriteVariable(this, value); + } + ~StubVariable() = default; + NO_MOVE_SEMANTIC(StubVariable); + NO_COPY_SEMANTIC(StubVariable); + void Bind(AddrShift value) + { + currentValue_ = value; + } + AddrShift Value() const + { + return currentValue_; + } + MachineType Type() const + { + return type_; + } + bool IsBound() const + { + return currentValue_ != 0; + } + StubVariable &operator=(const AddrShift value) + { + env_->GetCurrentLabel()->WriteVariable(this, value); + Bind(value); + return *this; + } - void AddSelectorToLabel(AddrShift sel, StubOptimizerLabel label) - { - phi_to_labels[sel] = label.GetRawLabel(); - } + AddrShift operator*() + { + return env_->GetCurrentLabel()->ReadVariable(this); + } - StubOptimizerLabelImplement *NewStubOptimizerLabel(Environment *env, AddrShift control = -1) - { - auto impl = new StubOptimizerLabelImplement(env, control); - rawlabels_.push_back(impl); - return impl; - } + AddrShift AddPhiOperand(AddrShift val); + AddrShift AddOperandToSelector(AddrShift val, size_t idx, AddrShift in); + AddrShift TryRemoveTrivialPhi(AddrShift phi); + void RerouteOuts(const std::vector &outs, Gate *newGate); -private: - StubOptimizerLabel *currentLabel_{nullptr}; - Circuit circuit_; - CircuitBuilder builder_; - std::map phi_to_labels; - std::vector arguments_; - std::string method_name_; - StubOptimizerLabel entry_; - std::vector rawlabels_; -}; + bool IsSelector(AddrShift gate) const + { + return env_->GetCircuit()->IsSelector(gate); + } -class StubVariable { -public: - StubVariable(Environment *env, MachineType type, uint32_t id, AddrShift value) : id_(id), type_(type), env_(env) - { - Bind(value); - env_->GetCurrentLabel()->WriteVariable(this, value); - } - ~StubVariable() = default; - NO_MOVE_SEMANTIC(StubVariable); - NO_COPY_SEMANTIC(StubVariable); - void Bind(AddrShift value) - { - currentValue_ = value; - } - AddrShift Value() const - { - return currentValue_; - } - MachineType Type() const - { - return type_; - } - bool IsBound() const - { - return currentValue_ != 0; - } - StubVariable &operator=(const AddrShift value) - { - env_->GetCurrentLabel()->WriteVariable(this, value); - Bind(value); - return *this; - } + bool IsSelector(const Gate *gate) const + { + return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS && gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64; + } - AddrShift operator*() - { - return env_->GetCurrentLabel()->ReadVariable(this); - } + uint32_t GetId() const + { + return id_; + } - AddrShift AddPhiOperand(AddrShift val); - AddrShift AddOperandToSelector(AddrShift val, size_t idx, AddrShift in); - AddrShift TryRemoveTrivialPhi(AddrShift phi); - void RerouteOuts(const std::vector &outs, Gate *newGate); + private: + uint32_t id_; + MachineType type_; + AddrShift currentValue_ {0}; + Environment *env_; + }; - bool IsSelector(AddrShift gate) const - { - return env_->GetCircuit().IsSelector(gate); - } + class SubCircuitScope { + public: + explicit SubCircuitScope(Environment *env, StubLabel *entry) : env_(env) + { + env_->PushCurrentLabel(entry); + } + ~SubCircuitScope() + { + env_->PopCurrentLabel(); + } - bool IsSelector(const Gate *gate) const - { - return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS && gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64; - } + private: + Environment *env_; + }; - uint32_t GetId() const + explicit Stub(const char *name, int argCount, Circuit *circuit) + : env_(argCount, circuit), methodName_(name) { - return id_; } - -private: - uint32_t id_; - MachineType type_; - AddrShift currentValue_{0}; - Environment *env_; -}; - -class StubOptimizer { -public: - using Label = StubOptimizerLabel; - using Variable = StubVariable; - - explicit StubOptimizer(Environment *env) : env_(env) {} - virtual ~StubOptimizer() = default; - NO_MOVE_SEMANTIC(StubOptimizer); - NO_COPY_SEMANTIC(StubOptimizer); + virtual ~Stub() = default; + NO_MOVE_SEMANTIC(Stub); + NO_COPY_SEMANTIC(Stub); virtual void GenerateCircuit() = 0; - Environment *GetEnvironment() const + Environment *GetEnvironment() { - return env_; + return &env_; } // constant AddrShift GetInteger32Constant(int32_t value) { - return env_->GetCircuitBuilder().NewIntegerConstant(value); + return env_.GetCircuitBuilder().NewIntegerConstant(value); }; AddrShift GetWord64Constant(uint64_t value) { - return env_->GetCircuitBuilder().NewInteger64Constant(value); + return env_.GetCircuitBuilder().NewInteger64Constant(value); }; AddrShift GetPtrConstant(uint32_t value) @@ -373,47 +408,47 @@ public: AddrShift GetBooleanConstant(bool value) { - return env_->GetCircuitBuilder().NewBooleanConstant(value); + return env_.GetCircuitBuilder().NewBooleanConstant(value); } AddrShift GetDoubleConstant(double value) { - return env_->GetCircuitBuilder().NewDoubleConstant(value); + return env_.GetCircuitBuilder().NewDoubleConstant(value); } AddrShift GetUndefinedConstant() { - return env_->GetCircuitBuilder().UndefineConstant(); + return env_.GetCircuitBuilder().UndefineConstant(); } AddrShift GetHoleConstant() { - return env_->GetCircuitBuilder().HoleConstant(); + return env_.GetCircuitBuilder().HoleConstant(); } // parameter AddrShift Argument(size_t index) { - return env_->GetArgument(index); + return env_.GetArgument(index); } AddrShift Int1Argument(size_t index) { AddrShift argument = Argument(index); - env_->GetCircuit().SetOpCode(argument, OpCode(OpCode::INT1_ARG)); + env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT1_ARG)); return argument; } AddrShift Int32Argument(size_t index) { AddrShift argument = Argument(index); - env_->GetCircuit().SetOpCode(argument, OpCode(OpCode::INT32_ARG)); + env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT32_ARG)); return argument; } AddrShift Int64Argument(size_t index) { AddrShift argument = Argument(index); - env_->GetCircuit().SetOpCode(argument, OpCode(OpCode::INT64_ARG)); + env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT64_ARG)); return argument; } @@ -421,9 +456,9 @@ public: { AddrShift argument = Argument(index); if (PtrValueCode() == INT64) { - env_->GetCircuit().SetOpCode(argument, OpCode(OpCode::INT64_ARG)); + env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT64_ARG)); } else if (PtrValueCode() == INT32) { - env_->GetCircuit().SetOpCode(argument, OpCode(OpCode::INT32_ARG)); + env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::INT32_ARG)); } else { UNREACHABLE(); } @@ -433,33 +468,33 @@ public: AddrShift Float32Argument(size_t index) { AddrShift argument = Argument(index); - env_->GetCircuit().SetOpCode(argument, OpCode(OpCode::FLOAT32_ARG)); + env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::FLOAT32_ARG)); return argument; } AddrShift Float64Argument(size_t index) { AddrShift argument = Argument(index); - env_->GetCircuit().SetOpCode(argument, OpCode(OpCode::FLOAT64_ARG)); + env_.GetCircuit()->SetOpCode(argument, OpCode(OpCode::FLOAT64_ARG)); return argument; } AddrShift Alloca(int size) { - return env_->GetCircuitBuilder().Alloca(size); + return env_.GetCircuitBuilder().Alloca(size); } // control flow AddrShift Return(AddrShift value) { - auto control = env_->GetCurrentLabel()->GetControl(); - return env_->GetCircuitBuilder().Return(control, value); + auto control = env_.GetCurrentLabel()->GetControl(); + return env_.GetCircuitBuilder().Return(control, value); } void Bind(Label *label) { label->Bind(); - env_->SetCurrentLabel(label); + env_.SetCurrentLabel(label); } void Jump(Label *label); void Branch(AddrShift condition, Label *trueLabel, Label *falseLabel); @@ -473,26 +508,26 @@ public: void LoopEnd(Label *loopHead); // call operation - AddrShift CallStub(StubInterfaceDescriptor *descriptor, AddrShift target, std::initializer_list args) + AddrShift CallStub(StubDescriptor *descriptor, AddrShift target, std::initializer_list args) { - return env_->GetCircuitBuilder().NewCallGate(descriptor, target, args); + return env_.GetCircuitBuilder().NewCallGate(descriptor, target, args); } - AddrShift CallStub(StubInterfaceDescriptor *descriptor, AddrShift target, AddrShift depend, + AddrShift CallStub(StubDescriptor *descriptor, AddrShift target, AddrShift depend, std::initializer_list args) { - return env_->GetCircuitBuilder().NewCallGate(descriptor, target, depend, args); + return env_.GetCircuitBuilder().NewCallGate(descriptor, target, depend, args); } - AddrShift CallRuntime(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, + AddrShift CallRuntime(StubDescriptor *descriptor, AddrShift thread, AddrShift target, std::initializer_list args) { - return env_->GetCircuitBuilder().NewCallRuntimeGate(descriptor, thread, target, args); + return env_.GetCircuitBuilder().NewCallRuntimeGate(descriptor, thread, target, args); } - AddrShift CallRuntime(StubInterfaceDescriptor *descriptor, AddrShift thread, AddrShift target, AddrShift depend, + AddrShift CallRuntime(StubDescriptor *descriptor, AddrShift thread, AddrShift target, AddrShift depend, std::initializer_list args) { - return env_->GetCircuitBuilder().NewCallRuntimeGate(descriptor, thread, target, depend, args); + return env_.GetCircuitBuilder().NewCallRuntimeGate(descriptor, thread, target, depend, args); } // memory @@ -500,18 +535,18 @@ public: { if (PtrValueCode() == ValueCode::INT64) { AddrShift val = Int64Add(base, offset); - return env_->GetCircuitBuilder().NewLoadGate(type, val); + return env_.GetCircuitBuilder().NewLoadGate(type, val); } if (PtrValueCode() == ValueCode::INT32) { AddrShift val = Int32Add(base, offset); - return env_->GetCircuitBuilder().NewLoadGate(type, val); + return env_.GetCircuitBuilder().NewLoadGate(type, val); } UNREACHABLE(); } AddrShift Load(MachineType type, AddrShift base) { - return env_->GetCircuitBuilder().NewLoadGate(type, base); + return env_.GetCircuitBuilder().NewLoadGate(type, base); } AddrShift LoadFromObject(MachineType type, AddrShift object, AddrShift offset); @@ -520,11 +555,11 @@ public: { if (PtrValueCode() == ValueCode::INT64) { AddrShift ptr = Int64Add(base, offset); - return env_->GetCircuitBuilder().NewStoreGate(type, ptr, value); + return env_.GetCircuitBuilder().NewStoreGate(type, ptr, value); } if (PtrValueCode() == ValueCode::INT32) { AddrShift ptr = Int32Add(base, offset); - return env_->GetCircuitBuilder().NewStoreGate(type, ptr, value); + return env_.GetCircuitBuilder().NewStoreGate(type, ptr, value); } UNREACHABLE(); } @@ -532,17 +567,17 @@ public: // arithmetic AddrShift Int32Add(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_ADD), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_ADD), x, y); } AddrShift Int64Add(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_ADD), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_ADD), x, y); } AddrShift DoubleAdd(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_ADD), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_ADD), x, y); } AddrShift PtrAdd(AddrShift x, AddrShift y) @@ -563,37 +598,37 @@ public: AddrShift Int32Sub(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_SUB), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_SUB), x, y); } AddrShift Int64Sub(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_SUB), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_SUB), x, y); } AddrShift DoubleSub(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_SUB), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_SUB), x, y); } AddrShift Int32Mul(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_MUL), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_MUL), x, y); } AddrShift Int64Mul(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_MUL), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_MUL), x, y); } AddrShift DoubleMul(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_MUL), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_MUL), x, y); } AddrShift DoubleDiv(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_DIV), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_DIV), x, y); } AddrShift Int32Div(AddrShift x, AddrShift y); AddrShift Int64Div(AddrShift x, AddrShift y); @@ -602,7 +637,7 @@ public: AddrShift Word32Or(AddrShift x, AddrShift y); AddrShift Word32And(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_AND), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_AND), x, y); } AddrShift Word32Xor(AddrShift x, AddrShift y); @@ -610,55 +645,55 @@ public: AddrShift Word64Or(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_OR), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_OR), x, y); } AddrShift Word64And(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_AND), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_AND), x, y); } AddrShift Word64Xor(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_XOR), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_XOR), x, y); } AddrShift Word32Not(AddrShift x); AddrShift Word64Not(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_REV), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_REV), x); } AddrShift WordLogicOr(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_OR), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_OR), x, y); } AddrShift WordLogicAnd(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_AND), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_AND), x, y); } AddrShift WordLogicNot(AddrShift x) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_REV), x); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_REV), x); } AddrShift Word32LSL(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSL), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSL), x, y); } AddrShift Word64LSL(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_LSL), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_LSL), x, y); } AddrShift Word32LSR(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSR), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_LSR), x, y); } AddrShift Word64LSR(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_LSR), x, y); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_LSR), x, y); } AddrShift Word32Sar(AddrShift x, AddrShift y); AddrShift Word64Sar(AddrShift x, AddrShift y); @@ -738,125 +773,125 @@ public: AddrShift CastDoubleToInt64(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_TO_INT64), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::FLOAT64_TO_INT64), x); } // compare operation AddrShift Word32Equal(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_EQ), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_EQ), x, y); } AddrShift Word32NotEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_NE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_NE), x, y); } AddrShift Word64Equal(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_EQ), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_EQ), x, y); } AddrShift DoubleEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::FLOAT64_EQ), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::FLOAT64_EQ), x, y); } AddrShift Word64NotEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_NE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_NE), x, y); } AddrShift Int32GreaterThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SGT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SGT), x, y); } AddrShift Int32LessThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SLT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SLT), x, y); } AddrShift Int32GreaterThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SGE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SGE), x, y); } AddrShift Int32LessThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SLE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_SLE), x, y); } AddrShift Word32GreaterThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_UGT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_UGT), x, y); } AddrShift Word32LessThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_ULT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_ULT), x, y); } AddrShift Word32LessThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_ULE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_ULE), x, y); } AddrShift Word32GreaterThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_UGE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT32_UGE), x, y); } AddrShift Int64GreaterThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SGT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SGT), x, y); } AddrShift Int64LessThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SLT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SLT), x, y); } AddrShift Int64LessThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SLE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SLE), x, y); } AddrShift Int64GreaterThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SGE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_SGE), x, y); } AddrShift Word64GreaterThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_UGT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_UGT), x, y); } AddrShift Word64LessThan(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_ULT), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_ULT), x, y); } AddrShift Word64LessThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_ULE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_ULE), x, y); } AddrShift Word64GreaterThanOrEqual(AddrShift x, AddrShift y) { - return env_->GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_UGE), x, y); + return env_.GetCircuitBuilder().NewLogicGate(OpCode(OpCode::INT64_UGE), x, y); } // cast operation AddrShift ChangeInt64ToInt32(AddrShift val) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), val); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), val); } AddrShift ChangeInt64ToPointer(AddrShift val) { if (PtrValueCode() == ValueCode::INT32) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), val); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), val); } return val; } @@ -888,22 +923,25 @@ public: return Load(MachineType::UINT64_TYPE, object, elementsOffset); } + AddrShift GetLengthofElements(AddrShift elements) + { + return Load(UINT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); + } + // object operation AddrShift LoadHClass(AddrShift object) { return ChangeInt32ToPointer(Load(UINT32_TYPE, object)); } - AddrShift GetObjectType(AddrShift object) + AddrShift GetObjectType(AddrShift hclass) { - AddrShift hclass = LoadHClass(object); AddrShift bitfieldOffset = GetPtrConstant(panda::ecmascript::JSHClass::BIT_FIELD_OFFSET); AddrShift bitfield = Load(INT64_TYPE, hclass, bitfieldOffset); return ChangeInt64ToInt32( - Word64And(Word64LSR(bitfield, GetWord64Constant(panda::ecmascript::JSHClass::ExtensibleBit::START_BIT)), - GetWord64Constant((1LLU << panda::ecmascript::JSHClass::ExtensibleBit::SIZE) - 1))); + Word64And(bitfield, GetWord64Constant((1LLU << panda::ecmascript::JSHClass::ObjectTypeBits::SIZE) - 1))); } AddrShift IsDictionaryMode(AddrShift object) @@ -913,6 +951,19 @@ public: GetInteger32Constant(0)); } + AddrShift IsDictionaryElement(AddrShift hclass) + { + AddrShift bitfieldOffset = GetPtrConstant(panda::ecmascript::JSHClass::BIT_FIELD_OFFSET); + + AddrShift bitfield = Load(INT64_TYPE, hclass, bitfieldOffset); + // decode + return Word64NotEqual( + Word64And( + Word64LSR(bitfield, GetWord64Constant(panda::ecmascript::JSHClass::DictionaryElementBits::START_BIT)), + GetWord64Constant((1LLU << panda::ecmascript::JSHClass::DictionaryElementBits::SIZE) - 1)), + GetWord64Constant(0)); + } + AddrShift IsExtensible(AddrShift object) { AddrShift hclass = LoadHClass(object); @@ -928,7 +979,7 @@ public: AddrShift IsJsProxy(AddrShift obj) { - AddrShift objectType = GetObjectType(obj); + AddrShift objectType = GetObjectType(LoadHClass(obj)); return Word32Equal(objectType, GetInteger32Constant(static_cast(panda::ecmascript::JSType::JS_PROXY))); } @@ -975,7 +1026,7 @@ public: return Load(TAGGED_TYPE, elements, dataOffset); } - AddrShift TaggedToRepresentation(AddrShift value, Label *next); + AddrShift TaggedToRepresentation(AddrShift value); AddrShift GetElementRepresentation(AddrShift hclass) { @@ -997,7 +1048,7 @@ public: panda::ecmascript::JSHClass::ElementRepresentationBits::START_BIT)))); } - void UpdateValueAndDetails(AddrShift elements, AddrShift index, AddrShift value, AddrShift attr) + void UpdateValueAndAttributes(AddrShift elements, AddrShift index, AddrShift value, AddrShift attr) { AddrShift arrayIndex = Int32Add(GetInteger32Constant(panda::ecmascript::NameDictionary::TABLE_HEADER_SIZE), @@ -1010,11 +1061,23 @@ public: StoreElement(elements, attributesIndex, IntBuildTagged(attr)); } - void UpdateAndStoreRepresention(AddrShift hclass, AddrShift value, Label *next); + AddrShift IsSpecialIndexedObj(AddrShift jsType) + { + return Int32GreaterThan(jsType, + GetInteger32Constant(static_cast(panda::ecmascript::JSType::JS_ARRAY))); + } + + AddrShift IsAccessorInternal(AddrShift value) + { + return Word32Equal(GetObjectType(LoadHClass(value)), + GetInteger32Constant(static_cast(panda::ecmascript::JSType::INTERNAL_ACCESSOR))); + } + + void UpdateAndStoreRepresention(AddrShift hclass, AddrShift value); - AddrShift UpdateRepresention(AddrShift oldRep, AddrShift value, Label *next); + AddrShift UpdateRepresention(AddrShift oldRep, AddrShift value); - AddrShift GetDetailsFromDictionary(AddrShift elements, AddrShift entry) + AddrShift GetAttributesFromDictionary(AddrShift elements, AddrShift entry) { AddrShift arrayIndex = Int32Add(GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), @@ -1034,11 +1097,11 @@ public: return GetValueFromTaggedArray(elements, valueIndex); } - AddrShift GetKeyFromNumberDictionary(AddrShift elements, AddrShift entry, Label *next); + AddrShift GetKeyFromNumberDictionary(AddrShift elements, AddrShift entry); - AddrShift IsMatchInNumberDictionary(AddrShift key, AddrShift other, Label *next); + AddrShift IsMatchInNumberDictionary(AddrShift key, AddrShift other); - AddrShift FindElementFromNumberDictionary(AddrShift thread, AddrShift elements, AddrShift key, Label *next); + AddrShift FindElementFromNumberDictionary(AddrShift thread, AddrShift elements, AddrShift key); AddrShift TaggedCastToInt32(AddrShift x) { @@ -1054,67 +1117,68 @@ public: AddrShift CastInt32ToFloat64(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_TO_FLOAT64), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT32_TO_FLOAT64), x); } AddrShift CastInt64ToFloat64(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_TO_FLOAT64), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::INT64_TO_FLOAT64), x); } AddrShift SExtInt32ToInt64(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT32_TO_INT64), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT32_TO_INT64), x); } AddrShift SExtInt1ToInt64(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT1_TO_INT64), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT1_TO_INT64), x); } AddrShift SExtInt1ToInt32(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT1_TO_INT32), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::SEXT_INT1_TO_INT32), x); } AddrShift ZExtInt32ToInt64(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT32_TO_INT64), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT32_TO_INT64), x); } AddrShift ZExtInt1ToInt64(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT64), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT64), x); } AddrShift ZExtInt1ToInt32(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT32), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::ZEXT_INT1_TO_INT32), x); } AddrShift TruncInt64ToInt32(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT32), x); } AddrShift TruncInt64ToInt1(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT1), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT64_TO_INT1), x); } AddrShift TruncInt32ToInt1(AddrShift x) { - return env_->GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT32_TO_INT1), x); + return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT32_TO_INT1), x); } - uint32_t NextVariableId() + int NextVariableId() { - return varibial_id_++; + return nextVariableId_++; } private: - Environment *env_; - uint32_t varibial_id_{0}; + Environment env_; + std::string methodName_; + int nextVariableId_ {0}; }; } // namespace kungfu -#endif // ECMASCRIPT_COMPILER_STUBOPTIMIZER_H +#endif // ECMASCRIPT_COMPILER_Stub_H diff --git a/ecmascript/compiler/stub_aot_compiler.cpp b/ecmascript/compiler/stub_aot_compiler.cpp new file mode 100644 index 0000000000..84dbf75ab3 --- /dev/null +++ b/ecmascript/compiler/stub_aot_compiler.cpp @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "stub_aot_compiler.h" +#include +#include +#include +#include "fast_stub.h" +#include "llvm_codegen.h" +#include "scheduler.h" +#include "stub.h" +#include "verifier.h" + +namespace kungfu { +class PipeLineData { +public: + explicit PipeLineData(Circuit *circuit, LLVMStubModule *module) : circuit_(circuit), module_(module) {} + ~PipeLineData() = default; + const ControlFlowGraph &GetScheduleResult() const + { + return cfg; + } + + void SetScheduleResult(const ControlFlowGraph &result) + { + cfg = result; + } + + Circuit *GetCircuit() const + { + return circuit_; + } + + LLVMStubModule *GetStubModule() const + { + return module_; + } + +private: + Circuit *circuit_; + LLVMStubModule *module_; + ControlFlowGraph cfg; +}; + +class KungfuPipeLine { +public: + explicit KungfuPipeLine(PipeLineData *data) : data_(data) {} + ~KungfuPipeLine() = default; + template + bool RunPass(Args... args) + { + T pass; + return pass.Run(data_, std::forward(args)...); + } + +private: + PipeLineData *data_; +}; + +class VerifierPass { +public: + bool Run(PipeLineData *data) + { + Verifier::Run(data->GetCircuit()); + return true; + } +}; + +class SchedulerPass { +public: + bool Run(PipeLineData *data) + { + data->SetScheduleResult(Scheduler::Run(data->GetCircuit())); + return true; + } +}; + +class LLVMCodegenPass { +public: + bool Run(PipeLineData *data, int index) + { + auto stubModule = data->GetStubModule(); + LLVMCodeGeneratorImpl llvmImpl(stubModule); + CodeGenerator codegen(&llvmImpl); + codegen.Run(data->GetCircuit(), data->GetScheduleResult(), index); + return true; + } +}; + +void StubAotCompiler::BuildStubModule(panda::ecmascript::StubModule *module) +{ + LLVMStubModule stubModule("fast_stubs"); + stubModule.Initialize(); + for (int i = 0; i < FAST_STUB_MAXCOUNT; i++) { + auto Stub = stubs_[i]; + if (Stub != nullptr) { + Stub->GenerateCircuit(); + auto circuit = Stub->GetEnvironment()->GetCircuit(); + PipeLineData data(circuit, &stubModule); + KungfuPipeLine pipeline(&data); + pipeline.RunPass(); + pipeline.RunPass(); + pipeline.RunPass(i); + } + } + + LLVMModuleAssembler assembler(&stubModule); + assembler.AssembleModule(); + assembler.CopyAssembleCodeToModule(module); +} +} // namespace kungfu + +int main(int argc, char *argv[]) +{ + int opt; + // 3 means ark_stub_opt -f stub.m + if (argc != 3) { + std::cerr << "Usage: " << argv[0] << " -f stub.m" << std::endl; + return -1; + } + std::string moduleFilename; + while ((opt = getopt(argc, argv, "f:")) != -1) { + switch (opt) { + case 'f': + moduleFilename += optarg; + break; + default: /* '?' */ + std::cerr << "Usage: " << argv[0] << " -f stub.m" << std::endl; + return -1; + } + } + + kungfu::StubAotCompiler mouldeBuilder; + panda::ecmascript::StubModule stubModule; + /* Set Stub into module */ + kungfu::Circuit fastaddCircuit; + kungfu::FastAddStub fastaddStub(&fastaddCircuit); + mouldeBuilder.SetStub(FAST_STUB_ID(FastAdd), &fastaddStub); + + kungfu::Circuit fastsubCircuit; + kungfu::FastSubStub fastsubStub(&fastsubCircuit); + mouldeBuilder.SetStub(FAST_STUB_ID(FastSub), &fastsubStub); + + kungfu::Circuit fastmulCircuit; + kungfu::FastMulStub fastmulStub(&fastmulCircuit); + mouldeBuilder.SetStub(FAST_STUB_ID(FastMul), &fastmulStub); + + kungfu::Circuit fastdivCircuit; + kungfu::FastDivStub fastdivStub(&fastdivCircuit); + mouldeBuilder.SetStub(FAST_STUB_ID(FastDiv), &fastdivStub); + + kungfu::Circuit fastFindOwnElementCircuit; + kungfu::FastFindOwnElementStub fastFindOwnElementStub(&fastFindOwnElementCircuit); + mouldeBuilder.SetStub(FAST_STUB_ID(FindOwnElement), &fastFindOwnElementStub); + + kungfu::Circuit fastGetElementCircuit; + kungfu::FastGetElementStub fastGetElementStub(&fastGetElementCircuit); + mouldeBuilder.SetStub(FAST_STUB_ID(GetElement), &fastGetElementStub); + + kungfu::Circuit fastFindOwnElement2Circuit; + kungfu::FastFindOwnElement2Stub fastFindOwnElement2Stub(&fastFindOwnElement2Circuit); + mouldeBuilder.SetStub(FAST_STUB_ID(FindOwnElement2), &fastFindOwnElement2Stub); + + kungfu::Circuit fastSetElementCircuit; + kungfu::FastSetElementStub fastSetElementStub(&fastSetElementCircuit); + mouldeBuilder.SetStub(FAST_STUB_ID(SetElement), &fastSetElementStub); + + mouldeBuilder.BuildStubModule(&stubModule); + stubModule.Save(moduleFilename); + exit(0); +} \ No newline at end of file diff --git a/ecmascript/compiler/stub_aot_compiler.h b/ecmascript/compiler/stub_aot_compiler.h new file mode 100644 index 0000000000..736ba00287 --- /dev/null +++ b/ecmascript/compiler/stub_aot_compiler.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_COMPILER_STUB_AOT_COMPILER_H +#define ECMASCRIPT_COMPILER_STUB_AOT_COMPILER_H + +#include "ecmascript/js_thread.h" +#include "ecmascript/stub_module.h" + +namespace kungfu { +class Stub; +class circuit; +using Address = uintptr_t; +class StubAotCompiler { +public: + StubAotCompiler() + { + for (int i = 0; i < FAST_STUB_MAXCOUNT; i++) { + stubs_[i] = nullptr; + } + }; + ~StubAotCompiler() = default; + void BuildStubModule(panda::ecmascript::StubModule *module); + void SetStub(int index, Stub *optimizer) + { + stubs_[index] = optimizer; + } + +private: + std::array stubs_; +}; +} // namespace kungfu +#endif // ECMASCRIPT_COMPILER_STUB_AOT_COMPILER_H diff --git a/ecmascript/compiler/stub_descriptor.cpp b/ecmascript/compiler/stub_descriptor.cpp new file mode 100644 index 0000000000..c4469c5ebb --- /dev/null +++ b/ecmascript/compiler/stub_descriptor.cpp @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "ecmascript/compiler/stub_descriptor.h" + +#include "llvm-c/Core.h" +#include "llvm/Support/Host.h" + +namespace kungfu { +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define CALL_STUB_INIT_DESCRIPTOR(name) \ + class Stub##name##InterfaceDescriptor final { \ + public: \ + static void Initialize(StubDescriptor *descriptor); \ + }; \ + void Stub##name##InterfaceDescriptor::Initialize(StubDescriptor *descriptor) + +CALL_STUB_INIT_DESCRIPTOR(FastAdd) +{ + // 2 : 2 input parameters + static StubDescriptor fastAdd("FastAdd", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + *descriptor = fastAdd; + // 2 : 2 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(FastSub) +{ + // 2 : 2 input parameters + static StubDescriptor fastSub("FastSub", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + *descriptor = fastSub; + // 2 : 2 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(FastMul) +{ + // 2 : 2 input parameters + static StubDescriptor fastMul("FastMul", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + *descriptor = fastMul; + // 2 : 2 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(FastDiv) +{ + // 2 : 2 input parameters + static StubDescriptor fastDiv("FastDiv", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + *descriptor = fastDiv; + // 2 : 2 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(FastMod) {} + +CALL_STUB_INIT_DESCRIPTOR(FastEqual) {} + +CALL_STUB_INIT_DESCRIPTOR(FastTypeOf) {} + +CALL_STUB_INIT_DESCRIPTOR(FastStrictEqual) {} + +CALL_STUB_INIT_DESCRIPTOR(IsSpecialIndexedObjForSet) {} + +CALL_STUB_INIT_DESCRIPTOR(IsSpecialIndexedObjForGet) {} + +CALL_STUB_INIT_DESCRIPTOR(GetElement) +{ + // 3 : 3 input parameters + static StubDescriptor getElement("GetElement", 0, 3, DEFAULT_ORDER, UINT64_TYPE); + *descriptor = getElement; + // 3 : 3 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(SetElement) +{ + // 5 : 5 input parameters + static StubDescriptor setElement("SetElement", 0, 5, DEFAULT_ORDER, BOOL_TYPE); + *descriptor = setElement; + // 5 : 5 input parameters + std::array params = { + MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, MachineType::UINT32_TYPE, + MachineType::UINT64_TYPE, MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(SetPropertyByName) {} + +CALL_STUB_INIT_DESCRIPTOR(GetPropertyByName) {} + +CALL_STUB_INIT_DESCRIPTOR(SetGlobalOwnProperty) {} + +CALL_STUB_INIT_DESCRIPTOR(GetGlobalOwnProperty) {} + +CALL_STUB_INIT_DESCRIPTOR(SetOwnPropertyByName) {} + +CALL_STUB_INIT_DESCRIPTOR(SetOwnElement) {} + +CALL_STUB_INIT_DESCRIPTOR(FastSetProperty) {} + +CALL_STUB_INIT_DESCRIPTOR(FastGetProperty) {} + +CALL_STUB_INIT_DESCRIPTOR(FindOwnProperty) {} + +CALL_STUB_INIT_DESCRIPTOR(FindOwnElement) +{ + // 3 : 3 input parameters + static StubDescriptor findOwnElement("FindOwnElement", 0, 3, DEFAULT_ORDER, UINT64_TYPE); + *descriptor = findOwnElement; + // 3 : 3 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(NewLexicalEnvDyn) {} + +CALL_STUB_INIT_DESCRIPTOR(FindOwnProperty2) {} + +CALL_STUB_INIT_DESCRIPTOR(FindOwnElement2) +{ + // 6 : 6 input parameters + static StubDescriptor findOwnElement2("FindOwnElement2", 0, 6, DEFAULT_ORDER, UINT64_TYPE); + *descriptor = findOwnElement2; + // 6 : 6 input parameters + std::array params = { + MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, MachineType::UINT32_TYPE, + MachineType::BOOL_TYPE, MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); +} + +CALL_STUB_INIT_DESCRIPTOR(AddElementInternal) +{ + // 5 : 5 input parameters + static StubDescriptor addElementInternal("AddElementInternal", 0, 5, DEFAULT_ORDER, BOOL_TYPE); + *descriptor = addElementInternal; + // 5 : 5 input parameters + std::array params = { + MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, MachineType::UINT32_TYPE, + MachineType::UINT64_TYPE, MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); +} + +CALL_STUB_INIT_DESCRIPTOR(CallSetter) +{ + // 5 : 5 input parameters + static StubDescriptor callSetter("CallSetter", 0, 5, DEFAULT_ORDER, NONE_TYPE); + *descriptor = callSetter; + // 5 : 5 input parameters + std::array params = { + MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, MachineType::BOOL_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); +} + +CALL_STUB_INIT_DESCRIPTOR(CallGetter) +{ + // 3 : 3 input parameters + static StubDescriptor callGetter("CallGetter", 0, 3, DEFAULT_ORDER, NONE_TYPE); + *descriptor = callGetter; + // 3 : 3 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); +} + +CALL_STUB_INIT_DESCRIPTOR(AccessorGetter) +{ + // 3 : 3 input parameters + static StubDescriptor accessorGetter("AccessorGetter", 0, 3, DEFAULT_ORDER, NONE_TYPE); + *descriptor = accessorGetter; + // 3 : 3 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); +} + +CALL_STUB_INIT_DESCRIPTOR(ThrowTypeError) +{ + // 2 : 2 input parameters + static StubDescriptor throwTypeError("ThrowTypeError", 0, 2, DEFAULT_ORDER, NONE_TYPE); + *descriptor = throwTypeError; + // 2 : 2 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); +} + +CALL_STUB_INIT_DESCRIPTOR(JSProxySetProperty) +{ + // 6 : 6 input parameters + static StubDescriptor jsproxySetproperty("JSProxySetProperty", 0, 6, DEFAULT_ORDER, BOOL_TYPE); + *descriptor = jsproxySetproperty; + // 6 : 6 input parameters + std::array params = { + MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, + MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, MachineType::BOOL_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); +} + +CALL_STUB_INIT_DESCRIPTOR(GetHash32) +{ + // 2 : 2 input parameters + static StubDescriptor getHash32("GetHash32", 0, 2, DEFAULT_ORDER, UINT32_TYPE); + *descriptor = getHash32; + // 2 : 2 input parameters + std::array params = { + MachineType::UINT64_TYPE, + MachineType::UINT32_TYPE, + }; + descriptor->SetParameters(params.data()); + descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); +} + +void FastStubDescriptors::InitializeStubDescriptors() +{ +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define DEF_CALL_STUB(name) NAME_##name +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define INITIALIZE_CALL_STUB_DESCRIPTOR(name, argcounts) \ + Stub##name##InterfaceDescriptor::Initialize(&callStubsDescriptor_[DEF_CALL_STUB(name)]); + CALL_STUB_LIST(INITIALIZE_CALL_STUB_DESCRIPTOR) +#undef INITIALIZE_CALL_STUB_DESCRIPTOR +#undef DEF_CALL_STUB +} +} // namespace kungfu diff --git a/ecmascript/compiler/stub_interface.h b/ecmascript/compiler/stub_descriptor.h similarity index 51% rename from ecmascript/compiler/stub_interface.h rename to ecmascript/compiler/stub_descriptor.h index 758fb6f1fa..f186dd4d8f 100644 --- a/ecmascript/compiler/stub_interface.h +++ b/ecmascript/compiler/stub_descriptor.h @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef ECMASCRIPT_COMPILER_STUB_INTERFACE_H -#define ECMASCRIPT_COMPILER_STUB_INTERFACE_H +#ifndef ECMASCRIPT_COMPILER_STUB_DESCRIPTOR_H +#define ECMASCRIPT_COMPILER_STUB_DESCRIPTOR_H #include #include @@ -28,20 +28,22 @@ enum ArgumentsOrder { DEFAULT_ORDER, // Push Arguments in stack from right -> left }; -class StubInterfaceDescriptor { +class StubDescriptor { public: enum CallStubKind { CODE_STUB, RUNTIME_STUB, }; - explicit StubInterfaceDescriptor(int flags, int paramCounter, ArgumentsOrder order, MachineType returnType) - : flags_(flags), paramCounter_(paramCounter), order_(order), returnType_(returnType) + explicit StubDescriptor(std::string name, int flags, int paramCounter, ArgumentsOrder order, + MachineType returnType) + : name_(name), flags_(flags), paramCounter_(paramCounter), order_(order), returnType_(returnType) { } - StubInterfaceDescriptor() = default; - ~StubInterfaceDescriptor() = default; - StubInterfaceDescriptor(StubInterfaceDescriptor const &other) + StubDescriptor() = default; + ~StubDescriptor() = default; + StubDescriptor(StubDescriptor const &other) { + name_ = other.name_; flags_ = other.flags_; paramCounter_ = other.paramCounter_; order_ = other.order_; @@ -55,8 +57,9 @@ public: } } - StubInterfaceDescriptor &operator=(StubInterfaceDescriptor const &other) + StubDescriptor &operator=(StubDescriptor const &other) { + name_ = other.name_; flags_ = other.flags_; paramCounter_ = other.paramCounter_; order_ = other.order_; @@ -120,107 +123,49 @@ public: kind_ = kind; } -private: - CallStubKind kind_{CODE_STUB}; - int flags_{0}; - int paramCounter_{0}; - ArgumentsOrder order_{DEFAULT_ORDER}; - - MachineType returnType_{MachineType::NONE_TYPE}; - std::unique_ptr> paramsType_{nullptr}; -}; - -class CallStubsImplement { -public: - CallStubsImplement() = default; - virtual ~CallStubsImplement() = default; - NO_MOVE_SEMANTIC(CallStubsImplement); - NO_COPY_SEMANTIC(CallStubsImplement); - virtual void Initialize() = 0; - virtual void *GetFastStub(int index) = 0; - virtual void SetFastStub(int index, void *code) = 0; - virtual void *GetRunTimeLLVMType(int index) = 0; - virtual void *GetModule() = 0; -}; - -class LLVMStubsImplement : public CallStubsImplement { -public: - LLVMStubsImplement(); - ~LLVMStubsImplement() override = default; - NO_MOVE_SEMANTIC(LLVMStubsImplement); - NO_COPY_SEMANTIC(LLVMStubsImplement); - void Initialize() override; - void *GetFastStub(int index) override; - void SetFastStub(int index, void *code) override; - - void *GetRunTimeLLVMType(int index) override; - void *GetModule() override + const std::string &GetName() { - return reinterpret_cast(stubsModule_); + return name_; } private: - std::array llvmCallStubs_{nullptr}; - std::array llvm_fuction_type_{nullptr}; - LLVMModuleRef stubsModule_{nullptr}; + std::string name_; + CallStubKind kind_ {CODE_STUB}; + int flags_ {0}; + int paramCounter_ {0}; + ArgumentsOrder order_ {DEFAULT_ORDER}; + + MachineType returnType_ {MachineType::NONE_TYPE}; + std::unique_ptr> paramsType_ {nullptr}; }; + // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define FAST_STUB_ID(name) NAME_##name -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define GET_STUBDESCRIPTOR(name) FastStubs::GetInstance().GetStubDescriptor(FAST_STUB_ID(name)) +#define GET_STUBDESCRIPTOR(name) FastStubDescriptors::GetInstance().GetStubDescriptor(FAST_STUB_ID(name)) -class FastStubs { +class FastStubDescriptors { public: - static FastStubs &GetInstance() + static FastStubDescriptors &GetInstance() { - static FastStubs instance; + static FastStubDescriptors instance; return instance; } void InitializeStubDescriptors(); - void InitializeFastStubs() - { - InitializeStubDescriptors(); - stubsImpl_->Initialize(); - } - - void *GetRunTimeLLVMType(int index) - { - return stubsImpl_->GetRunTimeLLVMType(index); - } - - void *GetFastStub(int index) const - { - return stubsImpl_->GetFastStub(index); - } - - void SetFastStub(int index, void *code) - { - return stubsImpl_->SetFastStub(index, code); - } - - void *GetModule() const - { - return stubsImpl_->GetModule(); - } - - StubInterfaceDescriptor *GetStubDescriptor(int index) + StubDescriptor *GetStubDescriptor(int index) { return &callStubsDescriptor_[index]; } private: - FastStubs() + FastStubDescriptors() { - stubsImpl_ = std::make_unique(); - InitializeFastStubs(); + InitializeStubDescriptors(); } - ~FastStubs() {} - NO_MOVE_SEMANTIC(FastStubs); - NO_COPY_SEMANTIC(FastStubs); - std::unique_ptr stubsImpl_{nullptr}; - std::array callStubsDescriptor_{}; + ~FastStubDescriptors() {} + NO_MOVE_SEMANTIC(FastStubDescriptors); + NO_COPY_SEMANTIC(FastStubDescriptors); + std::array callStubsDescriptor_ {}; }; } // namespace kungfu -#endif // ECMASCRIPT_COMPILER_STUB_INTERFACE_H \ No newline at end of file +#endif // ECMASCRIPT_COMPILER_STUB_DESCRIPTOR_H \ No newline at end of file diff --git a/ecmascript/compiler/stub_interface.cpp b/ecmascript/compiler/stub_interface.cpp deleted file mode 100644 index 66908736a1..0000000000 --- a/ecmascript/compiler/stub_interface.cpp +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#include "ecmascript/compiler/stub_interface.h" - -#include "llvm-c/Core.h" -#include "llvm/Support/Host.h" - -namespace kungfu { -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) - -#define LLVM_STUB_GETFUCTION(name) \ - class LLVM##name##Stub final { \ - public: \ - static LLVMValueRef InitializeFunction(LLVMModuleRef module); \ - }; \ - LLVMValueRef LLVM##name##Stub::InitializeFunction(LLVMModuleRef module) - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define LLVM_STUB_GETFUCTION_TYPE(name) \ - class LLVM##name##Stub##Type final { \ - public: \ - static LLVMTypeRef InitializeFunctionType(); \ - }; \ - LLVMTypeRef LLVM##name##Stub##Type::InitializeFunctionType() - -LLVM_STUB_GETFUCTION(FastAdd) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastSub) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastMul) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastDiv) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastMod) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastEqual) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastTypeOf) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastStrictEqual) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(IsSpecialIndexedObjForSet) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(IsSpecialIndexedObjForGet) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(GetElement) -{ - // 2 : 2 input parameters - std::array paramTys = { - LLVMInt64Type(), - LLVMInt32Type(), - }; - // 2 : 2 input parameters - return LLVMAddFunction(module, "GetElement", LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 2, 0)); -} - -LLVM_STUB_GETFUCTION(SetElement) -{ - // 5 : 5 input parameters - std::array paramTys = { - LLVMInt64Type(), LLVMInt64Type(), LLVMInt32Type(), LLVMInt64Type(), LLVMInt32Type(), - }; - // 5 : 5 input parameters - return LLVMAddFunction(module, "SetElement", LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0)); -} - -LLVM_STUB_GETFUCTION(SetPropertyByName) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(GetPropertyByName) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(SetGlobalOwnProperty) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(GetGlobalOwnProperty) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(SetOwnPropertyByName) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(SetOwnElement) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastSetProperty) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FastGetProperty) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FindOwnProperty) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FindOwnElement) -{ - // 2 : 2 input parameters - std::array paramTys = { - LLVMInt64Type(), - LLVMInt32Type(), - }; - // 2 : 2 input parameters - return LLVMAddFunction(module, "FindOwnElement", LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 2, 0)); -} - -LLVM_STUB_GETFUCTION(NewLexicalEnvDyn) -{ - (void)module; - return nullptr; -} - -LLVM_STUB_GETFUCTION(FindOwnProperty2) -{ - // 5 : 5 input parameters - std::array paramTys = { - LLVMInt64Type(), LLVMInt32Type(), LLVMInt1Type(), LLVMInt64Type(), LLVMInt64Type(), - }; - // 5 : 5 input parameters - return LLVMAddFunction(module, "FindOwnProperty2", LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 5, 0)); -} - -LLVM_STUB_GETFUCTION(FindOwnElement2) -{ - // 6 : 6 input parameters - std::array paramTys = { - LLVMInt64Type(), LLVMInt64Type(), LLVMInt32Type(), LLVMInt1Type(), LLVMInt64Type(), LLVMInt64Type(), - }; - // 6 : 6 input parameters - return LLVMAddFunction(module, "FindOwnElement2", LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 6, 0)); -} - -LLVM_STUB_GETFUCTION_TYPE(FastAdd) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastSub) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastMul) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastDiv) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastMod) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastEqual) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastTypeOf) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastStrictEqual) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(IsSpecialIndexedObjForSet) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(IsSpecialIndexedObjForGet) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(GetElement) -{ - // 2 : 2 input parameters - std::array paramTys = { - LLVMInt64Type(), - LLVMInt32Type(), - }; - return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 2, 0); // 2 : 2 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(SetElement) -{ - // 5 : 5 input parameters - std::array paramTys = { - LLVMInt64Type(), LLVMInt64Type(), LLVMInt32Type(), LLVMInt64Type(), LLVMInt32Type(), - }; - return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(SetPropertyByName) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(GetPropertyByName) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(SetGlobalOwnProperty) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(GetGlobalOwnProperty) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(SetOwnPropertyByName) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(SetOwnElement) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastSetProperty) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FastGetProperty) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FindOwnProperty) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FindOwnElement) -{ - // 2 : 2 parameters number - std::array paramTys = { - LLVMInt64Type(), - LLVMInt32Type(), - }; - return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 2, 0); // 2 : 2 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(NewLexicalEnvDyn) -{ - return nullptr; -} - -LLVM_STUB_GETFUCTION_TYPE(FindOwnProperty2) -{ - // 5 : 5 parameters number - std::array paramTys = { - LLVMInt64Type(), LLVMInt32Type(), LLVMInt1Type(), LLVMInt64Type(), LLVMInt64Type(), - }; - return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(FindOwnElement2) -{ - // 5 : 5 parameters number - std::array paramTys = { - LLVMInt64Type(), LLVMInt32Type(), LLVMInt1Type(), LLVMInt64Type(), LLVMInt64Type(), - }; - return LLVMFunctionType(LLVMInt64Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(AddElementInternal) -{ - // 5 : 5 parameters number - std::array paramTys = { - LLVMInt64Type(), LLVMInt64Type(), LLVMInt32Type(), LLVMInt64Type(), LLVMInt32Type(), - }; - return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(CallSetter) -{ - // 5 : 5 parameters number - std::array paramTys = { - LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt1Type(), - }; - return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 5, 0); // 5 : 5 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(ThrowTypeError) -{ - // 2 : 2 parameters number - std::array paramTys = { - LLVMInt64Type(), - LLVMInt32Type(), - }; - return LLVMFunctionType(LLVMVoidType(), paramTys.data(), 2, 0); // 2 : 2 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(JSProxySetProperty) -{ - // 6 : 6 parameters number - std::array paramTys = { - LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt64Type(), LLVMInt1Type(), - }; - return LLVMFunctionType(LLVMInt1Type(), paramTys.data(), 6, 0); // 6 : 6 parameters number -} - -LLVM_STUB_GETFUCTION_TYPE(GetHash32) -{ - // 2 : 2 parameters number - std::array paramTys = {LLVMInt64Type(), LLVMInt32Type()}; - return LLVMFunctionType(LLVMInt32Type(), paramTys.data(), 2, 0); // 2 : 2 parameters number -} - -LLVMStubsImplement::LLVMStubsImplement() -{ - stubsModule_ = LLVMModuleCreateWithName("fast_stubs"); - LLVMSetTarget(stubsModule_, "x86_64-unknown-linux-gnu"); -} - -void LLVMStubsImplement::Initialize() -{ -// Initialize Stubs Function -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DEF_CALL_STUB(name) NAME_##name -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define INITIALIZE_CALL_STUB(name, argcounts) \ - llvmCallStubs_[DEF_CALL_STUB(name)] = LLVM##name##Stub::InitializeFunction(stubsModule_); - FAST_RUNTIME_STUB_LIST(INITIALIZE_CALL_STUB) -#undef INITIALIZE_CALL_STUB -#undef DEF_CALL_STUB - -// Intialize Stubs Function -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DEF_CALL_STUB(name) NAME_##name -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define INITIALIZE_CALL_STUB(name, argcounts) \ - llvm_fuction_type_[DEF_CALL_STUB(name)] = LLVM##name##Stub##Type::InitializeFunctionType(); - CALL_STUB_LIST(INITIALIZE_CALL_STUB) -#undef INITIALIZE_CALL_STUB -#undef DEF_CALL_STUB -} - -void *LLVMStubsImplement::GetFastStub(int index) -{ - ASSERT(index < CALL_STUB_MAXCOUNT && index >= 0); - return reinterpret_cast(llvmCallStubs_[index]); -} - -void LLVMStubsImplement::SetFastStub(int index, void *code) -{ - ASSERT(index < CALL_STUB_MAXCOUNT && index >= 0); - llvmCallStubs_[index] = reinterpret_cast(code); -} - -void *LLVMStubsImplement::GetRunTimeLLVMType(int index) -{ - ASSERT(index < CALL_STUB_MAXCOUNT && index >= 0); - return reinterpret_cast(llvm_fuction_type_[index]); -} - -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define CALL_STUB_INIT_DESCRIPTOR(name) \ - class Stub##name##InterfaceDescriptor final { \ - public: \ - static void Initialize(StubInterfaceDescriptor *descriptor); \ - }; \ - void Stub##name##InterfaceDescriptor::Initialize(StubInterfaceDescriptor *descriptor) - -CALL_STUB_INIT_DESCRIPTOR(FastAdd) {} - -CALL_STUB_INIT_DESCRIPTOR(FastSub) {} - -CALL_STUB_INIT_DESCRIPTOR(FastMul) {} - -CALL_STUB_INIT_DESCRIPTOR(FastDiv) {} - -CALL_STUB_INIT_DESCRIPTOR(FastMod) {} - -CALL_STUB_INIT_DESCRIPTOR(FastEqual) {} - -CALL_STUB_INIT_DESCRIPTOR(FastTypeOf) {} - -CALL_STUB_INIT_DESCRIPTOR(FastStrictEqual) {} - -CALL_STUB_INIT_DESCRIPTOR(IsSpecialIndexedObjForSet) {} - -CALL_STUB_INIT_DESCRIPTOR(IsSpecialIndexedObjForGet) {} - -CALL_STUB_INIT_DESCRIPTOR(GetElement) {} - -CALL_STUB_INIT_DESCRIPTOR(SetElement) {} - -CALL_STUB_INIT_DESCRIPTOR(SetPropertyByName) {} - -CALL_STUB_INIT_DESCRIPTOR(GetPropertyByName) {} - -CALL_STUB_INIT_DESCRIPTOR(SetGlobalOwnProperty) {} - -CALL_STUB_INIT_DESCRIPTOR(GetGlobalOwnProperty) {} - -CALL_STUB_INIT_DESCRIPTOR(SetOwnPropertyByName) {} - -CALL_STUB_INIT_DESCRIPTOR(SetOwnElement) {} - -CALL_STUB_INIT_DESCRIPTOR(FastSetProperty) {} - -CALL_STUB_INIT_DESCRIPTOR(FastGetProperty) {} - -CALL_STUB_INIT_DESCRIPTOR(FindOwnProperty) {} - -CALL_STUB_INIT_DESCRIPTOR(FindOwnElement) {} - -CALL_STUB_INIT_DESCRIPTOR(NewLexicalEnvDyn) {} - -CALL_STUB_INIT_DESCRIPTOR(FindOwnProperty2) {} - -CALL_STUB_INIT_DESCRIPTOR(FindOwnElement2) -{ - // 5 : 5 input parameters - static StubInterfaceDescriptor findOwnElement2(0, 5, DEFAULT_ORDER, UINT64_TYPE); - *descriptor = findOwnElement2; - std::array params = { // 5 : 5 input parameters - MachineType::UINT64_TYPE, - MachineType::UINT32_TYPE, - MachineType::BOOL_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - }; - descriptor->SetParameters(params.data()); -} - -CALL_STUB_INIT_DESCRIPTOR(AddElementInternal) -{ - // 5 : 5 input parameters - static StubInterfaceDescriptor addElementInternal(0, 5, DEFAULT_ORDER, BOOL_TYPE); - *descriptor = addElementInternal; - std::array params = { // 5 : 5 input parameters - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT32_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT32_TYPE, - }; - descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); -} - -CALL_STUB_INIT_DESCRIPTOR(CallSetter) -{ - // 5 : 5 input parameters - static StubInterfaceDescriptor callSetter(0, 5, DEFAULT_ORDER, NONE_TYPE); - *descriptor = callSetter; - std::array params = { // 5 : 5 input parameters - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::BOOL_TYPE, - }; - descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); -} - -CALL_STUB_INIT_DESCRIPTOR(ThrowTypeError) -{ - // 2 : 2 input parameters - static StubInterfaceDescriptor throwTypeError(0, 2, DEFAULT_ORDER, NONE_TYPE); - *descriptor = throwTypeError; - std::array params = { // 2 : 2 input parameters - MachineType::UINT64_TYPE, - MachineType::UINT32_TYPE, - }; - descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); -} - -CALL_STUB_INIT_DESCRIPTOR(JSProxySetProperty) -{ - // 6 : 6 input parameters - static StubInterfaceDescriptor jsproxySetproperty(0, 6, DEFAULT_ORDER, BOOL_TYPE); - *descriptor = jsproxySetproperty; - std::array params = { // 6 : 6 input parameters - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::UINT64_TYPE, - MachineType::BOOL_TYPE, - }; - descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); -} - -CALL_STUB_INIT_DESCRIPTOR(GetHash32) -{ - // 2 : 2 input parameters - static StubInterfaceDescriptor getHash32(0, 2, DEFAULT_ORDER, UINT32_TYPE); - *descriptor = getHash32; - std::array params = { // 2 : 2 input parameters - MachineType::POINTER_TYPE, - MachineType::UINT32_TYPE, - }; - descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubInterfaceDescriptor::RUNTIME_STUB); -} - -void FastStubs::InitializeStubDescriptors() -{ -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DEF_CALL_STUB(name) NAME_##name -// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define INITIALIZE_CALL_STUB_DESCRIPTOR(name, argcounts) \ - Stub##name##InterfaceDescriptor::Initialize(&callStubsDescriptor_[DEF_CALL_STUB(name)]); - CALL_STUB_LIST(INITIALIZE_CALL_STUB_DESCRIPTOR) -#undef INITIALIZE_CALL_STUB_DESCRIPTOR -#undef DEF_CALL_STUB -} -} // namespace kungfu diff --git a/ecmascript/compiler/tests/BUILD.gn b/ecmascript/compiler/tests/BUILD.gn index 0aefde223a..a1cd3e6c94 100644 --- a/ecmascript/compiler/tests/BUILD.gn +++ b/ecmascript/compiler/tests/BUILD.gn @@ -31,12 +31,12 @@ config("include_llvm_config") { module_output_path = "ark/js_runtime" -host_unittest_action("StubOptimizerTest") { +host_unittest_action("StubTest") { module_out_path = module_output_path sources = [ # test file - "stub_optimizer_tests.cpp", + "stub_tests.cpp", ] configs = [ ":include_llvm_config", @@ -108,7 +108,7 @@ host_unittest_action("StubOptimizerTest") { "LLVMTransformUtils", "LLVMAArch64Utils", "LLVMARMUtils", - "LLVMX86Utils", + #"LLVMX86Utils", "LLVMIRReader", ] @@ -125,5 +125,5 @@ group("host_unittest") { testonly = true # deps file - deps = [ ":StubOptimizerTestAction" ] + deps = [ ":StubTestAction(${host_toolchain})" ] } diff --git a/ecmascript/compiler/tests/stub_optimizer_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp similarity index 51% rename from ecmascript/compiler/tests/stub_optimizer_tests.cpp rename to ecmascript/compiler/tests/stub_tests.cpp index 0e56d35c97..515f2a5538 100644 --- a/ecmascript/compiler/tests/stub_optimizer_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -17,18 +17,20 @@ #include #include "gtest/gtest.h" -#include "ecmascript/compiler/fastpath_optimizer.h" +#include "ecmascript/compiler/fast_stub.h" #include "ecmascript/compiler/llvm_ir_builder.h" -#include "ecmascript/compiler/llvm_mcjit_compiler.h" +#include "ecmascript/compiler/llvm_mcjit_engine.h" #include "ecmascript/compiler/llvm_stackmap_parse.h" #include "ecmascript/compiler/scheduler.h" -#include "ecmascript/compiler/stub_interface.h" +#include "ecmascript/compiler/stub_descriptor.h" #include "ecmascript/ecma_vm.h" #include "ecmascript/interpreter/fast_runtime_stub-inl.h" #include "ecmascript/js_array.h" #include "ecmascript/message_string.h" #include "ecmascript/tests/test_helper.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/IR/Instructions.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/Host.h" @@ -39,11 +41,12 @@ using namespace panda::coretypes; using namespace panda::ecmascript; using namespace kungfu; -class StubOptimizerTest : public testing::Test { +class StubTest : public testing::Test { public: void SetUp() override { TestHelper::CreateEcmaVMWithScope(instance, thread, scope); + stubModule.Initialize(); } void TearDown() override @@ -51,12 +54,18 @@ public: TestHelper::DestroyEcmaVMWithScope(instance, scope); } - PandaVM *instance{nullptr}; - EcmaHandleScope *scope{nullptr}; - JSThread *thread{nullptr}; + JSTaggedValue FastMul2(JSTaggedValue x, JSTaggedValue y) + { + return FastRuntimeStub::FastMul(x, y); + } + + PandaVM *instance {nullptr}; + EcmaHandleScope *scope {nullptr}; + JSThread *thread {nullptr}; + LLVMStubModule stubModule{"fast_stub"}; }; -HWTEST_F_L0(StubOptimizerTest, FastLoadElement) +HWTEST_F_L0(StubTest, FastLoadElement) { auto *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory(); LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); @@ -69,10 +78,9 @@ HWTEST_F_L0(StubOptimizerTest, FastLoadElement) // 2 : parameter number LLVMAddFunction(module, "FastLoadElement", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); LLVMDumpModule(module); - Environment fastEnv("FastLoadElement", 2); // 2 : parameter count - FastArrayLoadElementOptimizer optimizer(&fastEnv); + Circuit netOfGates; + FastArrayLoadElementStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = fastEnv.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -84,7 +92,7 @@ HWTEST_F_L0(StubOptimizerTest, FastLoadElement) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); /* exec function */ @@ -106,20 +114,20 @@ HWTEST_F_L0(StubOptimizerTest, FastLoadElement) std::cerr << "valUndefine = " << std::hex << valUndefine << std::endl; } -class StubPhiOptimizer : public StubOptimizer { +class PhiStub : public Stub { public: - explicit StubPhiOptimizer(Environment *env) : StubOptimizer(env) {} - ~StubPhiOptimizer() = default; - NO_MOVE_SEMANTIC(StubPhiOptimizer); - NO_COPY_SEMANTIC(StubPhiOptimizer); + explicit PhiStub(Circuit *circuit) : Stub("Phi", 1, circuit) {} + ~PhiStub() = default; + NO_MOVE_SEMANTIC(PhiStub); + NO_COPY_SEMANTIC(PhiStub); void GenerateCircuit() override { auto env = GetEnvironment(); DEFVARIABLE(z, MachineType::INT32_TYPE, GetInteger32Constant(0)); DEFVARIABLE(x, MachineType::INT32_TYPE, Int32Argument(0)); - StubOptimizerLabel ifTrue(env); - StubOptimizerLabel ifFalse(env); - StubOptimizerLabel next(env); + StubLabel ifTrue(env); + StubLabel ifFalse(env); + StubLabel next(env); Branch(Word32Equal(*x, GetInteger32Constant(10)), &ifTrue, &ifFalse); // 10 : size of entry Bind(&ifTrue); @@ -133,7 +141,7 @@ public: } }; -HWTEST_F_L0(StubOptimizerTest, PhiGateTest) +HWTEST_F_L0(StubTest, PhiGateTest) { std::cout << "---------------------PhiGateTest-----------------------------------------------------" << std::endl; LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); @@ -142,10 +150,9 @@ HWTEST_F_L0(StubOptimizerTest, PhiGateTest) LLVMInt32Type(), }; LLVMValueRef function = LLVMAddFunction(module, "PhiGateTest", LLVMFunctionType(LLVMInt32Type(), paramTys, 1, 0)); - Environment env("PhiGateTest", 1); - StubPhiOptimizer optimizer(&env); + Circuit netOfGates; + PhiStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -157,7 +164,7 @@ HWTEST_F_L0(StubOptimizerTest, PhiGateTest) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); /* exec function */ @@ -169,18 +176,18 @@ HWTEST_F_L0(StubOptimizerTest, PhiGateTest) std::cout << "+++++++++++++++++++++PhiGateTest+++++++++++++++++++++++++++++++++++++++++++++++++++++" << std::endl; } -class StubCallPhiOptimizer : public StubOptimizer { +class CallPhiStub : public Stub { public: - explicit StubCallPhiOptimizer(Environment *env) - : StubOptimizer(env), phi_descriptor_(0, 1, DEFAULT_ORDER, MachineType::INT32_TYPE) + explicit CallPhiStub(Circuit *circuit) + : Stub("CallPhi", 1, circuit), phi_descriptor_("phi", 0, 1, DEFAULT_ORDER, MachineType::INT32_TYPE) { std::array *params = new std::array(); (*params)[0] = MachineType::INT32_TYPE; phi_descriptor_.SetParameters(params->data()); } - ~StubCallPhiOptimizer() = default; - NO_MOVE_SEMANTIC(StubCallPhiOptimizer); - NO_COPY_SEMANTIC(StubCallPhiOptimizer); + ~CallPhiStub() = default; + NO_MOVE_SEMANTIC(CallPhiStub); + NO_COPY_SEMANTIC(CallPhiStub); void GenerateCircuit() override { DEFVARIABLE(x, MachineType::INT32_TYPE, Int32Argument(0)); @@ -190,68 +197,15 @@ public: } private: - StubInterfaceDescriptor phi_descriptor_; + StubDescriptor phi_descriptor_; }; -HWTEST_F_L0(StubOptimizerTest, CallPhiGateTest) -{ - LLVMModuleRef module = static_cast(FastStubs::GetInstance().GetModule()); - LLVMTypeRef fooParamTys[] = { - LLVMInt32Type(), - }; - LLVMValueRef function = LLVMAddFunction(module, "PhiTest", LLVMFunctionType(LLVMInt32Type(), fooParamTys, 1, 0)); - LLVMTypeRef barParamTys[] = { - LLVMInt32Type(), - }; - FastStubs::GetInstance().SetFastStub(0, reinterpret_cast(function)); - LLVMValueRef barfunction = - LLVMAddFunction(module, "CallPhiGateTest_bar", LLVMFunctionType(LLVMInt32Type(), barParamTys, 1, 0)); - Environment env("PhiTest", 1); - StubPhiOptimizer optimizer(&env); - optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); - netOfGates.PrintAllGates(); - auto cfg = Scheduler::Run(&netOfGates); - LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); - llvmBuilder.Build(); - Environment barEnv("CallPhiGateTest_bar", 1); - StubCallPhiOptimizer callphiOptimizer(&barEnv); - callphiOptimizer.GenerateCircuit(); - auto callNetOfGates = barEnv.GetCircuit(); - callNetOfGates.PrintAllGates(); - auto callCfg = Scheduler::Run(&callNetOfGates); - for (size_t bbIdx = 0; bbIdx < callCfg.size(); bbIdx++) { - std::cout << (callNetOfGates.GetOpCode(callCfg[bbIdx].front()).IsCFGMerge() ? "MERGE_" : "BB_") << bbIdx << ":" - << std::endl; - for (size_t instIdx = callCfg[bbIdx].size(); instIdx > 0; instIdx--) { - callNetOfGates.Print(callCfg[bbIdx][instIdx - 1]); - } - } - LLVMIRBuilder barllvmBuilder(&callCfg, &callNetOfGates, module, barfunction); - barllvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); - compiler.Run(); - auto engine = compiler.GetEngine(); - auto *phiTestPointer = - reinterpret_cast(reinterpret_cast(LLVMGetPointerToGlobal(engine, function))); - LLVMAddGlobalMapping(engine, function, reinterpret_cast(phiTestPointer)); - auto *barPointerbar = - reinterpret_cast(reinterpret_cast(LLVMGetPointerToGlobal(engine, barfunction))); - std::cout << std::hex << "phiTestPointer:" << reinterpret_cast(phiTestPointer) - << " barPointerbar:" << reinterpret_cast(barPointerbar) << std::endl; - compiler.Disassemble(); - int result = barPointerbar(9); - EXPECT_EQ(result, 21); - result = barPointerbar(10); - EXPECT_EQ(result, 112); -} - -class LoopOptimizer : public StubOptimizer { +class LoopStub : public Stub { public: - explicit LoopOptimizer(Environment *env) : StubOptimizer(env) {} - ~LoopOptimizer() = default; - NO_MOVE_SEMANTIC(LoopOptimizer); - NO_COPY_SEMANTIC(LoopOptimizer); + explicit LoopStub(Circuit *circuit) : Stub("loop", 1, circuit) {} + ~LoopStub() = default; + NO_MOVE_SEMANTIC(LoopStub); + NO_COPY_SEMANTIC(LoopStub); void GenerateCircuit() override { auto env = GetEnvironment(); @@ -283,7 +237,7 @@ public: } }; -HWTEST_F_L0(StubOptimizerTest, LoopTest) +HWTEST_F_L0(StubTest, LoopTest) { LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); @@ -291,10 +245,9 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest) LLVMInt32Type(), }; LLVMValueRef function = LLVMAddFunction(module, "LoopTest", LLVMFunctionType(LLVMInt32Type(), paramTys, 1, 0)); - Environment env("loop", 1); - LoopOptimizer optimizer(&env); + Circuit netOfGates; + LoopStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -306,7 +259,7 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); @@ -320,12 +273,12 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest) std::cout << "res for loop(11) = " << std::dec << resInvalid << std::endl; } -class LoopOptimizer1 : public StubOptimizer { +class LoopStub1 : public Stub { public: - explicit LoopOptimizer1(Environment *env) : StubOptimizer(env) {} - ~LoopOptimizer1() = default; - NO_MOVE_SEMANTIC(LoopOptimizer1); - NO_COPY_SEMANTIC(LoopOptimizer1); + explicit LoopStub1(Circuit *circuit) : Stub("loop1", 1, circuit) {} + ~LoopStub1() = default; + NO_MOVE_SEMANTIC(LoopStub1); + NO_COPY_SEMANTIC(LoopStub1); void GenerateCircuit() override { auto env = GetEnvironment(); @@ -355,7 +308,7 @@ public: } }; -HWTEST_F_L0(StubOptimizerTest, LoopTest1) +HWTEST_F_L0(StubTest, LoopTest1) { LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); @@ -363,10 +316,9 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest1) LLVMInt32Type(), }; LLVMValueRef function = LLVMAddFunction(module, "LoopTest1", LLVMFunctionType(LLVMInt32Type(), paramTys, 1, 0)); - Environment env("loop1", 1); - LoopOptimizer1 optimizer(&env); + Circuit netOfGates; + LoopStub1 optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -377,7 +329,7 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest1) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); /* exec function */ @@ -390,75 +342,7 @@ HWTEST_F_L0(StubOptimizerTest, LoopTest1) std::cout << "res for loop1(11) = " << std::dec << resInvalid << std::endl; } -class FastAddOptimizer : public StubOptimizer { -public: - explicit FastAddOptimizer(Environment *env) : StubOptimizer(env) {} - ~FastAddOptimizer() = default; - NO_MOVE_SEMANTIC(FastAddOptimizer); - NO_COPY_SEMANTIC(FastAddOptimizer); - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift x = Int64Argument(0); - AddrShift y = Int64Argument(1); - DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); - DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); - StubOptimizerLabel ifTrue1(env); - StubOptimizerLabel ifTrue2(env); - StubOptimizerLabel ifFalse1(env); - StubOptimizerLabel ifFalse2(env); - StubOptimizerLabel ifTrue3(env); - StubOptimizerLabel ifTrue4(env); - StubOptimizerLabel ifTrue5(env); - StubOptimizerLabel ifFalse3(env); - StubOptimizerLabel ifFalse4(env); - StubOptimizerLabel ifFalse5(env); - StubOptimizerLabel next1(env); - StubOptimizerLabel next2(env); - StubOptimizerLabel next3(env); - // if x is number - Branch(TaggedIsNumber(x), &ifTrue1, &ifFalse1); - Bind(&ifTrue1); - // if y is number - Branch(TaggedIsNumber(y), &ifTrue2, &ifFalse2); - Bind(&ifTrue2); - Branch(TaggedIsInt(x), &ifTrue3, &ifFalse3); - Bind(&ifTrue3); - AddrShift intX = TaggedCastToInt32(x); - Branch(TaggedIsInt(y), &ifTrue4, &ifFalse4); - Bind(&ifTrue4); - AddrShift intY = TaggedCastToInt32(y); - intX = Int32Add(intX, intY); - Jump(&next3); - Bind(&ifFalse4); - doubleY = TaggedCastToDouble(y); - doubleX = CastInt32ToFloat64(intX); - Jump(&next2); - Bind(&ifFalse3); - doubleX = TaggedCastToDouble(x); - Branch(TaggedIsInt(y), &ifTrue5, &ifFalse5); - Bind(&ifTrue5); - intY = TaggedCastToInt32(y); - doubleY = CastInt32ToFloat64(intY); - Jump(&next2); - Bind(&ifFalse5); - doubleY = TaggedCastToDouble(y); - Jump(&next2); - Bind(&ifFalse2); - Jump(&next1); - Bind(&ifFalse1); - Jump(&next1); - Bind(&next1); - Return(GetHoleConstant()); - Bind(&next2); - doubleX = DoubleAdd(*doubleX, *doubleY); - Return(DoubleBuildTagged(*doubleX)); - Bind(&next3); - Return(IntBuildTagged(intX)); - } -}; - -HWTEST_F_L0(StubOptimizerTest, FastAddTest) +HWTEST_F_L0(StubTest, FastAddTest) { LLVMModuleRef module = LLVMModuleCreateWithName("fast_add_module"); LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); @@ -468,10 +352,9 @@ HWTEST_F_L0(StubOptimizerTest, FastAddTest) }; LLVMValueRef function = LLVMAddFunction(module, "FastAddTest", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); LLVMDumpModule(module); - Environment env("FastAdd", 2); // 2 : parameter count - FastAddOptimizer optimizer(&env); + Circuit netOfGates; + FastAddStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -483,7 +366,7 @@ HWTEST_F_L0(StubOptimizerTest, FastAddTest) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); /* exec function */ @@ -494,77 +377,14 @@ HWTEST_F_L0(StubOptimizerTest, FastAddTest) std::cout << "res for FastAdd(1, 1) = " << std::dec << resValid.GetNumber() << std::endl; std::cout << "res for FastAdd(2, 2) = " << std::dec << resValid2.GetNumber() << std::endl; std::cout << "res for FastAdd(11, 11) = " << std::dec << resInvalid.GetNumber() << std::endl; + int x1 = 2147483647; + int y1 = 15; + auto resG = fn(JSTaggedValue(x1).GetRawData(), JSTaggedValue(y1).GetRawData()); + auto expectedG = FastRuntimeStub::FastAdd(JSTaggedValue(x1), JSTaggedValue(y1)); + EXPECT_EQ(resG, expectedG); } -class FastSubOptimizer : public StubOptimizer { -public: - explicit FastSubOptimizer(Environment *env) : StubOptimizer(env) {} - ~FastSubOptimizer() = default; - NO_MOVE_SEMANTIC(FastSubOptimizer); - NO_COPY_SEMANTIC(FastSubOptimizer); - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift x = Int64Argument(0); - AddrShift y = Int64Argument(1); - DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); - DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); - StubOptimizerLabel ifTrue1(env); - StubOptimizerLabel ifTrue2(env); - StubOptimizerLabel ifFalse1(env); - StubOptimizerLabel ifFalse2(env); - StubOptimizerLabel ifTrue3(env); - StubOptimizerLabel ifTrue4(env); - StubOptimizerLabel ifTrue5(env); - StubOptimizerLabel ifFalse3(env); - StubOptimizerLabel ifFalse4(env); - StubOptimizerLabel ifFalse5(env); - StubOptimizerLabel next1(env); - StubOptimizerLabel next2(env); - StubOptimizerLabel next3(env); - // if x is number - Branch(TaggedIsNumber(x), &ifTrue1, &ifFalse1); - Bind(&ifTrue1); - // if y is number - Branch(TaggedIsNumber(y), &ifTrue2, &ifFalse2); - Bind(&ifTrue2); - Branch(TaggedIsInt(x), &ifTrue3, &ifFalse3); - Bind(&ifTrue3); - AddrShift intX = TaggedCastToInt32(x); - Branch(TaggedIsInt(y), &ifTrue4, &ifFalse4); - Bind(&ifTrue4); - AddrShift intY = TaggedCastToInt32(y); - intX = Int32Sub(intX, intY); - Jump(&next3); - Bind(&ifFalse4); - doubleY = TaggedCastToDouble(y); - doubleX = CastInt32ToFloat64(intX); - Jump(&next2); - Bind(&ifFalse3); - doubleX = TaggedCastToDouble(x); - Branch(TaggedIsInt(y), &ifTrue5, &ifFalse5); - Bind(&ifTrue5); - intY = TaggedCastToInt32(y); - doubleY = CastInt32ToFloat64(intY); - Jump(&next2); - Bind(&ifFalse5); - doubleY = TaggedCastToDouble(y); - Jump(&next2); - Bind(&ifFalse2); - Jump(&next1); - Bind(&ifFalse1); - Jump(&next1); - Bind(&next1); - Return(GetHoleConstant()); - Bind(&next2); - doubleX = DoubleSub(*doubleX, *doubleY); - Return(DoubleBuildTagged(*doubleX)); - Bind(&next3); - Return(IntBuildTagged(intX)); - } -}; - -HWTEST_F_L0(StubOptimizerTest, FastSubTest) +HWTEST_F_L0(StubTest, FastSubTest) { LLVMModuleRef module = LLVMModuleCreateWithName("fast_sub_module"); LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); @@ -574,10 +394,9 @@ HWTEST_F_L0(StubOptimizerTest, FastSubTest) }; LLVMValueRef function = LLVMAddFunction(module, "FastSubTest", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); LLVMDumpModule(module); - Environment env("FastSub", 2); // 2 : parameter - FastSubOptimizer optimizer(&env); + Circuit netOfGates; + FastSubStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -589,7 +408,7 @@ HWTEST_F_L0(StubOptimizerTest, FastSubTest) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); /* exec function */ @@ -602,75 +421,7 @@ HWTEST_F_L0(StubOptimizerTest, FastSubTest) std::cout << "res for FastSub(11, 11) = " << std::dec << resC.GetNumber() << std::endl; } -class FastMulOptimizer : public StubOptimizer { -public: - explicit FastMulOptimizer(Environment *env) : StubOptimizer(env) {} - ~FastMulOptimizer() = default; - NO_MOVE_SEMANTIC(FastMulOptimizer); - NO_COPY_SEMANTIC(FastMulOptimizer); - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift x = Int64Argument(0); - AddrShift y = Int64Argument(1); - DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); - DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); - StubOptimizerLabel ifTrue1(env); - StubOptimizerLabel ifTrue2(env); - StubOptimizerLabel ifFalse1(env); - StubOptimizerLabel ifFalse2(env); - StubOptimizerLabel ifTrue3(env); - StubOptimizerLabel ifTrue4(env); - StubOptimizerLabel ifTrue5(env); - StubOptimizerLabel ifFalse3(env); - StubOptimizerLabel ifFalse4(env); - StubOptimizerLabel ifFalse5(env); - StubOptimizerLabel next1(env); - StubOptimizerLabel next2(env); - StubOptimizerLabel next3(env); - // if x is number - Branch(TaggedIsNumber(x), &ifTrue1, &ifFalse1); - Bind(&ifTrue1); - // if y is number - Branch(TaggedIsNumber(y), &ifTrue2, &ifFalse2); - Bind(&ifTrue2); - Branch(TaggedIsInt(x), &ifTrue3, &ifFalse3); - Bind(&ifTrue3); - AddrShift intX = TaggedCastToInt32(x); - Branch(TaggedIsInt(y), &ifTrue4, &ifFalse4); - Bind(&ifTrue4); - AddrShift intY = TaggedCastToInt32(y); - intX = Int32Mul(intX, intY); - Jump(&next3); - Bind(&ifFalse4); - doubleY = TaggedCastToDouble(y); - doubleX = CastInt32ToFloat64(intX); - Jump(&next2); - Bind(&ifFalse3); - doubleX = TaggedCastToDouble(x); - Branch(TaggedIsInt(y), &ifTrue5, &ifFalse5); - Bind(&ifTrue5); - intY = TaggedCastToInt32(y); - doubleY = CastInt32ToFloat64(intY); - Jump(&next2); - Bind(&ifFalse5); - doubleY = TaggedCastToDouble(y); - Jump(&next2); - Bind(&ifFalse2); - Jump(&next1); - Bind(&ifFalse1); - Jump(&next1); - Bind(&next1); - Return(GetHoleConstant()); - Bind(&next2); - doubleX = DoubleMul(*doubleX, *doubleY); - Return(DoubleBuildTagged(*doubleX)); - Bind(&next3); - Return(IntBuildTagged(intX)); - } -}; - -HWTEST_F_L0(StubOptimizerTest, FastMulTest) +HWTEST_F_L0(StubTest, FastMulTest) { LLVMModuleRef module = LLVMModuleCreateWithName("fast_mul_module"); LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); @@ -680,10 +431,9 @@ HWTEST_F_L0(StubOptimizerTest, FastMulTest) }; LLVMValueRef function = LLVMAddFunction(module, "FastMulTest", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); LLVMDumpModule(module); - Environment env("FastMul", 2); // 2 : parameter count - FastMulOptimizer optimizer(&env); + Circuit netOfGates; + FastMulStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -695,7 +445,7 @@ HWTEST_F_L0(StubOptimizerTest, FastMulTest) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); @@ -707,90 +457,29 @@ HWTEST_F_L0(StubOptimizerTest, FastMulTest) std::cout << "res for FastMul(-2, 1) = " << std::dec << resA.GetNumber() << std::endl; std::cout << "res for FastMul(-7, -2) = " << std::dec << resB.GetNumber() << std::endl; std::cout << "res for FastMul(11, 11) = " << std::dec << resC.GetNumber() << std::endl; + int x = 7; + double y = 1125899906842624; + auto resD = fn(JSTaggedValue(x).GetRawData(), JSTaggedValue(y).GetRawData()); + JSTaggedValue expectedD = FastRuntimeStub::FastMul(JSTaggedValue(x), JSTaggedValue(y)); + EXPECT_EQ(resD, expectedD); + x = -1; + y = 1.7976931348623157e+308; + auto resE = fn(JSTaggedValue(x).GetRawData(), JSTaggedValue(y).GetRawData()); + JSTaggedValue expectedE = FastRuntimeStub::FastMul(JSTaggedValue(x), JSTaggedValue(y)); + EXPECT_EQ(resE, expectedE); + x = -1; + y = -1 * std::numeric_limits::infinity(); + auto resF = fn(JSTaggedValue(x).GetRawData(), JSTaggedValue(y).GetRawData()); + JSTaggedValue expectedF = FastRuntimeStub::FastMul(JSTaggedValue(x), JSTaggedValue(y)); + EXPECT_EQ(resF, expectedF); + int x1 = 2147483647; + int y1 = 15; + auto resG = fn(JSTaggedValue(x1).GetRawData(), JSTaggedValue(y1).GetRawData()); + auto expectedG = FastRuntimeStub::FastMul(JSTaggedValue(x1), JSTaggedValue(y1)); + EXPECT_EQ(resG, expectedG); } -class FastDivOptimizer : public StubOptimizer { -public: - explicit FastDivOptimizer(Environment *env) : StubOptimizer(env) {} - ~FastDivOptimizer() = default; - NO_MOVE_SEMANTIC(FastDivOptimizer); - NO_COPY_SEMANTIC(FastDivOptimizer); - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift x = Int64Argument(0); - AddrShift y = Int64Argument(1); - DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0); - DEFVARIABLE(doubleY, MachineType::FLOAT64_TYPE, 0); - StubOptimizerLabel ifTrue1(env); - StubOptimizerLabel ifTrue2(env); - StubOptimizerLabel ifFalse1(env); - StubOptimizerLabel ifFalse2(env); - StubOptimizerLabel ifTrue3(env); - StubOptimizerLabel ifTrue4(env); - StubOptimizerLabel ifTrue5(env); - StubOptimizerLabel ifTrue6(env); - StubOptimizerLabel ifFalse3(env); - StubOptimizerLabel ifFalse4(env); - StubOptimizerLabel ifFalse5(env); - StubOptimizerLabel ifFalse6(env); - StubOptimizerLabel next1(env); - StubOptimizerLabel next2(env); - StubOptimizerLabel next3(env); - StubOptimizerLabel next4(env); - Branch(TaggedIsNumber(x), &ifTrue1, &ifFalse1); - Bind(&ifTrue1); - // if right.IsNumber() - Branch(TaggedIsNumber(y), &ifTrue2, &ifFalse2); - Bind(&ifTrue2); - Branch(TaggedIsInt(x), &ifTrue3, &ifFalse3); - Bind(&ifTrue3); - AddrShift intX = TaggedCastToInt32(x); - doubleX = CastInt32ToFloat64(intX); - Jump(&next2); - Bind(&ifFalse3); - doubleX = TaggedCastToDouble(x); - Jump(&next2); - Bind(&ifFalse2); - Jump(&next1); - Bind(&ifFalse1); - Jump(&next1); - Bind(&next1); - Return(GetHoleConstant()); - Bind(&next2); - Branch(TaggedIsInt(y), &ifTrue4, &ifFalse4); - Bind(&ifTrue4); - AddrShift intY = TaggedCastToInt32(y); - doubleY = CastInt32ToFloat64(intY); - Jump(&next3); - Bind(&ifFalse4); - doubleY = TaggedCastToDouble(y); - Jump(&next3); - Bind(&next3); - Branch(DoubleEqual(*doubleY, GetDoubleConstant(0.0)), &ifTrue5, &ifFalse5); - Bind(&ifTrue5); - // dLeft == 0.0 || std::isnan(dLeft) - Branch(TruncInt64ToInt1(Word64Or(SExtInt1ToInt64(DoubleEqual(*doubleX, GetDoubleConstant(0.0))), - SExtInt32ToInt64(DoubleIsNAN(*doubleX)))), - &ifTrue6, &ifFalse6); - Bind(&ifTrue6); - Return(DoubleBuildTagged(GetDoubleConstant(base::NAN_VALUE))); - Bind(&ifFalse6); - Jump(&next4); - Bind(&next4); - AddrShift intXTmp = CastDoubleToInt64(*doubleX); - AddrShift intYtmp = CastDoubleToInt64(*doubleY); - intXTmp = Word64And(Word64Xor(intXTmp, intYtmp), GetWord64Constant(base::DOUBLE_SIGN_MASK)); - intXTmp = Word64Xor(intXTmp, CastDoubleToInt64(GetDoubleConstant(base::POSITIVE_INFINITY))); - doubleX = CastInt64ToFloat64(intXTmp); - Return(DoubleBuildTagged(*doubleX)); - Bind(&ifFalse5); - doubleX = DoubleDiv(*doubleX, *doubleY); - Return(DoubleBuildTagged(*doubleX)); - } -}; - -HWTEST_F_L0(StubOptimizerTest, FastDivTest) +HWTEST_F_L0(StubTest, FastDivTest) { LLVMModuleRef module = LLVMModuleCreateWithName("fast_div_module"); LLVMSetTarget(module, "x86_64-unknown-linux-gnu"); @@ -799,10 +488,9 @@ HWTEST_F_L0(StubOptimizerTest, FastDivTest) LLVMInt64Type(), }; LLVMValueRef function = LLVMAddFunction(module, "FastDiv", LLVMFunctionType(LLVMInt64Type(), paramTys, 2, 0)); - Environment env("FastDiv", 2); - FastDivOptimizer optimizer(&env); + Circuit netOfGates; + FastDivStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -814,7 +502,7 @@ HWTEST_F_L0(StubOptimizerTest, FastDivTest) } LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); auto fn = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); @@ -825,165 +513,13 @@ HWTEST_F_L0(StubOptimizerTest, FastDivTest) std::cout << "res for FastDiv(50, 25) = " << res.GetRawData() << std::endl; } -class FastFindOwnElementStub : public StubOptimizer { -public: - explicit FastFindOwnElementStub(Environment *env) : StubOptimizer(env) {} - ~FastFindOwnElementStub() = default; - NO_MOVE_SEMANTIC(FastFindOwnElementStub); - NO_COPY_SEMANTIC(FastFindOwnElementStub); - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift obj = PtrArgument(0); - AddrShift index = Int32Argument(1); - - StubOptimizerLabel notDict(env); - StubOptimizerLabel lessOrEqual1(env); - StubOptimizerLabel greaterThan1(env); - StubOptimizerLabel isHole1(env); - StubOptimizerLabel isHole2(env); - StubOptimizerLabel isHole3(env); - StubOptimizerLabel notHole1(env); - StubOptimizerLabel notHole2(env); - StubOptimizerLabel notHole3(env); - StubOptimizerLabel isDict(env); - StubOptimizerLabel lessThan(env); - StubOptimizerLabel greaterOrEqual(env); - StubOptimizerLabel greaterThan2(env); - StubOptimizerLabel lessOrEqual2(env); - StubOptimizerLabel isUndef1(env); - StubOptimizerLabel isUndef2(env); - StubOptimizerLabel notUndef1(env); - StubOptimizerLabel notUndef2(env); - StubOptimizerLabel indexIsInt(env); - StubOptimizerLabel indexIsNotInt(env); - StubOptimizerLabel equal1(env); - StubOptimizerLabel equal2(env); - StubOptimizerLabel notEqual1(env); - StubOptimizerLabel notEqual2(env); - StubOptimizerLabel lessThanZero(env); - StubOptimizerLabel greaterOrEqualZero(env); - StubOptimizerLabel greaterThanLength(env); - StubOptimizerLabel elelmentIsInt(env); - StubOptimizerLabel elelmentIsNotInt(env); - StubOptimizerLabel notGreaterThanLength(env); - StubOptimizerLabel next1(env); - AddrShift elements = Load(POINTER_TYPE, obj, GetPtrConstant(JSObject::ELEMENTS_OFFSET)); - - Branch(IsDictionaryMode(elements), &isDict, ¬Dict); - Bind(¬Dict); - AddrShift arrayLength = Load(UINT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); - - Branch(Int32LessThanOrEqual(arrayLength, index), &lessOrEqual1, &greaterThan1); - Bind(&lessOrEqual1); - Jump(&next1); - Bind(&greaterThan1); - AddrShift offset = PtrMul(ChangeInt32ToPointer(index), GetPtrConstant(JSTaggedValue::TaggedTypeSize())); - AddrShift dataIndex = PtrAdd(offset, GetPtrConstant(panda::coretypes::Array::GetDataOffset())); - AddrShift value = Load(TAGGED_TYPE, elements, dataIndex); - - Branch(TaggedIsHole(value), &isHole1, ¬Hole1); - Bind(&isHole1); - Jump(&next1); - Bind(¬Hole1); - Return(value); - Bind(&next1); - Return(GetHoleConstant()); - // IsDictionary - Bind(&isDict); - offset = PtrMul(GetPtrConstant(JSTaggedValue::TaggedTypeSize()), - GetPtrConstant(GetInteger32Constant(panda::ecmascript::NumberDictionary::SIZE_INDEX))); - AddrShift data = Load(POINTER_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetDataOffset())); - AddrShift capacity = TaggedCastToInt32(Load(TAGGED_TYPE, data, offset)); - AddrShift count = GetInteger32Constant(1); - AddrShift taggedIndex = IntBuildTagged(index); - // 15 : size of entry - AddrShift entry = Word32And(GetInteger32Constant(15), Int32Sub(capacity, GetInteger32Constant(1))); - AddrShift dictionaryLength = - Load(INT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); - Label loopHead(env); - Label loopEnd(env); - Label afterLoop(env); - Jump(&loopHead); - LoopBegin(&loopHead); - AddrShift arrayIndex = - Int32Add(GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), - Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE))); - - Branch(Int32LessThan(arrayIndex, GetInteger32Constant(0)), &lessThan, &greaterOrEqual); - Bind(&lessThan); - Return(GetHoleConstant()); - Bind(&greaterOrEqual); - Branch(Int32GreaterThan(arrayIndex, dictionaryLength), &greaterThan2, &lessOrEqual2); - Bind(&greaterThan2); - Return(GetHoleConstant()); - Bind(&lessOrEqual2); - offset = PtrMul(ChangeInt32ToPointer(arrayIndex), GetPtrConstant(JSTaggedValue::TaggedTypeSize())); - data = Load(POINTER_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetDataOffset())); - AddrShift element = Load(TAGGED_TYPE, data, offset); - Branch(TaggedIsHole(element), &isHole2, ¬Hole2); - Bind(&isHole2); - Jump(&loopEnd); - // if element is undefined - Bind(¬Hole2); - Branch(TaggedIsUndefined(element), &isUndef1, ¬Undef1); - Bind(&isUndef1); - Return(GetHoleConstant()); - Bind(¬Undef1); - Branch(TaggedIsHole(taggedIndex), &isHole3, ¬Hole3); - Bind(&isHole3); - Jump(&loopEnd); - Bind(¬Hole3); - Branch(TaggedIsUndefined(taggedIndex), &isUndef2, ¬Undef2); - Bind(&isUndef2); - Jump(&loopEnd); - Bind(¬Undef2); - Branch(TaggedIsInt(taggedIndex), &indexIsInt, &indexIsNotInt); - Bind(&indexIsNotInt); - Jump(&loopEnd); - Bind(&indexIsInt); - Branch(TaggedIsInt(element), &elelmentIsInt, &elelmentIsNotInt); - Bind(&elelmentIsNotInt); - Jump(&loopEnd); - Bind(&elelmentIsInt); - Branch(Word32Equal(TaggedCastToInt32(taggedIndex), TaggedCastToInt32(element)), &equal1, ¬Equal1); - Bind(¬Equal1); - Jump(&loopEnd); - Bind(&equal1); - Branch(Word32Equal(entry, GetInteger32Constant(-1)), &equal2, ¬Equal2); - Bind(&equal2); - Return(GetHoleConstant()); - Bind(¬Equal2); - entry = - Int32Add(GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_VALUE_INDEX), - Int32Add(GetInteger32Constant(panda::ecmascript::NumberDictionary::TABLE_HEADER_SIZE), - Int32Mul(entry, GetInteger32Constant(panda::ecmascript::NumberDictionary::ENTRY_SIZE)))); - Branch(Int32LessThan(entry, GetInteger32Constant(0)), &lessThanZero, &greaterOrEqualZero); - Bind(&lessThanZero); - Return(GetUndefinedConstant()); - Bind(&greaterOrEqualZero); - Branch(Int32GreaterThan(entry, dictionaryLength), &greaterThanLength, ¬GreaterThanLength); - Bind(&greaterThanLength); - Return(GetUndefinedConstant()); - Bind(¬GreaterThanLength); - offset = PtrMul(ChangeInt32ToPointer(arrayIndex), GetPtrConstant(JSTaggedValue::TaggedTypeSize())); - data = Load(POINTER_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetDataOffset())); - Return(Load(TAGGED_TYPE, data, offset)); - Bind(&loopEnd); - entry = Word32And(Int32Add(entry, count), Int32Sub(capacity, GetInteger32Constant(1))); - count = Int32Add(count, GetInteger32Constant(1)); - LoopEnd(&loopHead); - } -}; - -HWTEST_F_L0(StubOptimizerTest, FastFindOwnElementStub) +HWTEST_F_L0(StubTest, FastFindOwnElementStub) { - LLVMModuleRef module = static_cast(FastStubs::GetInstance().GetModule()); + auto module = stubModule.GetModule(); LLVMValueRef findFunction = LLVMGetNamedFunction(module, "FindOwnElement"); - Environment env("FastFindOwnElementStub", 2); - FastFindOwnElementStub optimizer(&env); + Circuit netOfGates; + FastFindOwnElementStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -993,67 +529,19 @@ HWTEST_F_L0(StubOptimizerTest, FastFindOwnElementStub) netOfGates.Print(cfg[bbIdx][instIdx - 1]); } } - LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, findFunction); + LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, &stubModule, findFunction); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); } -class FastGetElementStub : public StubOptimizer { -public: - explicit FastGetElementStub(Environment *env) - // 2 : parameter number - : StubOptimizer(env), findOwnElementDescriptor(0, 2, DEFAULT_ORDER, MachineType::TAGGED_TYPE) - { - // 2 : 2 means that there are 2 cases in total. - std::array *params = new std::array(); - (*params)[0] = MachineType::POINTER_TYPE; - (*params)[1] = MachineType::UINT32_TYPE; - findOwnElementDescriptor.SetParameters(params->data()); - } - ~FastGetElementStub() = default; - NO_MOVE_SEMANTIC(FastGetElementStub); - NO_COPY_SEMANTIC(FastGetElementStub); - - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift receiver = Int64Argument(0); - AddrShift index = Int64Argument(1); - StubOptimizerLabel isHole(env); - StubOptimizerLabel notHole(env); - Label loopHead(env); - Label loopEnd(env); - Label afterLoop(env); - Label notHeapObj(env); - - Jump(&loopHead); - LoopBegin(&loopHead); - AddrShift objPtr = ChangeInt64ToPointer(receiver); - AddrShift callFindOwnElementVal = - CallStub(&findOwnElementDescriptor, GetWord64Constant(FAST_STUB_ID(FindOwnElement)), {objPtr, index}); - Branch(TaggedIsHole(callFindOwnElementVal), &isHole, ¬Hole); - Bind(¬Hole); - Return(callFindOwnElementVal); - Bind(&isHole); - receiver = Load(TAGGED_TYPE, LoadHClass(objPtr), GetPtrConstant(JSHClass::PROTOTYPE_OFFSET)); - Branch(TaggedIsHeapObject(receiver), &loopEnd, ¬HeapObj); - Bind(¬HeapObj); - Return(GetUndefinedConstant()); - Bind(&loopEnd); - LoopEnd(&loopHead); - } - StubInterfaceDescriptor findOwnElementDescriptor; -}; - -HWTEST_F_L0(StubOptimizerTest, FastGetElementStub) +HWTEST_F_L0(StubTest, FastGetElementStub) { - LLVMModuleRef module = static_cast(FastStubs::GetInstance().GetModule()); + auto module = stubModule.GetModule(); LLVMValueRef findFunction = LLVMGetNamedFunction(module, "FindOwnElement"); - Environment findFuncEnv("FastFindOwnElement_Foo", 2); - FastFindOwnElementStub findOptimizer(&findFuncEnv); + Circuit netOfGates; + FastFindOwnElementStub findOptimizer(&netOfGates); findOptimizer.GenerateCircuit(); - auto netOfGates = findFuncEnv.GetCircuit(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { std::cout << (netOfGates.GetOpCode(cfg[bbIdx].front()).IsCFGMerge() ? "MERGE_" : "BB_") << bbIdx << ":" @@ -1062,12 +550,11 @@ HWTEST_F_L0(StubOptimizerTest, FastGetElementStub) netOfGates.Print(cfg[bbIdx][instIdx - 1]); } } - LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, findFunction); + LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, &stubModule, findFunction); llvmBuilder.Build(); - Environment getFuncEnv("FastGetElement", 2); - FastGetElementStub getOptimizer(&getFuncEnv); + Circuit getNetOfGates; + FastGetElementStub getOptimizer(&getNetOfGates); getOptimizer.GenerateCircuit(); - auto getNetOfGates = getFuncEnv.GetCircuit(); getNetOfGates.PrintAllGates(); auto getCfg = Scheduler::Run(&getNetOfGates); for (size_t bbIdx = 0; bbIdx < getCfg.size(); bbIdx++) { @@ -1078,260 +565,18 @@ HWTEST_F_L0(StubOptimizerTest, FastGetElementStub) } } llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); } -class FastFindOwnElement2Stub : public StubOptimizer { -public: - explicit FastFindOwnElement2Stub(Environment *env) : StubOptimizer(env) {} - ~FastFindOwnElement2Stub() = default; - NO_MOVE_SEMANTIC(FastFindOwnElement2Stub); - NO_COPY_SEMANTIC(FastFindOwnElement2Stub); - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift thread = PtrArgument(0); // 0 : 1st para - AddrShift elements = PtrArgument(1); // 1 : 2nd para - AddrShift index = Int32Argument(2); // 2 : 3rd para - AddrShift isDict = Int32Argument(3); // 3 : 4th para - AddrShift attr = PtrArgument(4); // 4: 5th para - AddrShift indexOrEntry = PtrArgument(5); // 5: 6th para - isDict = ZExtInt1ToInt32(isDict); - Label notDictionary(env); - Label isDictionary(env); - Label end(env); - Branch(Word32Equal(isDict, GetInteger32Constant(0)), ¬Dictionary, &isDictionary); - Bind(¬Dictionary); - { - AddrShift elementsLength = - Load(UINT32_TYPE, elements, GetPtrConstant(panda::coretypes::Array::GetLengthOffset())); - Label outOfElements(env); - Label notOutOfElements(env); - Branch(Int32LessThanOrEqual(elementsLength, index), &outOfElements, ¬OutOfElements); - Bind(&outOfElements); - { - Return(GetHoleConstant()); - } - Bind(¬OutOfElements); - { - AddrShift value = GetValueFromTaggedArray(elements, index); - Label isHole(env); - Label notHole(env); - Branch(TaggedIsHole(value), &isHole, ¬Hole); - Bind(&isHole); - Jump(&end); - Bind(¬Hole); - { - Store(UINT32_TYPE, attr, GetPtrConstant(0), - GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())); - Store(UINT32_TYPE, indexOrEntry, GetPtrConstant(0), index); - Return(value); - } - } - } - Bind(&isDictionary); - { - Label afterFindElement(env); - AddrShift entry = - FindElementFromNumberDictionary(thread, elements, IntBuildTagged(index), &afterFindElement); - Label notNegtiveOne(env); - Label negtiveOne(env); - Branch(Word32NotEqual(entry, GetInteger32Constant(-1)), ¬NegtiveOne, &negtiveOne); - Bind(¬NegtiveOne); - { - Store(UINT32_TYPE, attr, GetPtrConstant(0), GetDetailsFromDictionary(elements, entry)); - Store(UINT32_TYPE, indexOrEntry, GetPtrConstant(0), entry); - Return(GetValueFromDictionary(elements, entry)); - } - Bind(&negtiveOne); - Jump(&end); - } - Bind(&end); - Return(GetHoleConstant()); - } -}; - -class SetElementStub : public StubOptimizer { -public: - explicit SetElementStub(Environment *env) : StubOptimizer(env) {} - ~SetElementStub() = default; - NO_MOVE_SEMANTIC(SetElementStub); - NO_COPY_SEMANTIC(SetElementStub); - void GenerateCircuit() override - { - auto env = GetEnvironment(); - AddrShift thread = PtrArgument(0); - AddrShift receiver = PtrArgument(1); - DEFVARIABLE(holder, MachineType::TAGGED_POINTER_TYPE, receiver); - AddrShift index = Int32Argument(2); // 2 : 3rd argument - AddrShift value = Int64Argument(3); // 3 : 4th argument - AddrShift mayThrow = Int32Argument(4); // 4 : 5th argument - DEFVARIABLE(onPrototype, MachineType::BOOL_TYPE, FalseConstant()); - - AddrShift pattr = Alloca(static_cast(MachineRep::K_WORD32)); - AddrShift pindexOrEntry = Alloca(static_cast(MachineRep::K_WORD32)); - Label loopHead(env); - Jump(&loopHead); - LoopBegin(&loopHead); - { - AddrShift elements = GetElements(*holder); - AddrShift isDictionary = IsDictionaryMode(elements); - StubInterfaceDescriptor *findOwnElemnt2 = GET_STUBDESCRIPTOR(FindOwnElement2); - AddrShift val = CallStub(findOwnElemnt2, GetWord64Constant(FAST_STUB_ID(FindOwnElement2)), - {thread, elements, index, isDictionary, pattr, pindexOrEntry}); - Label notHole(env); - Label isHole(env); - Branch(TaggedIsNotHole(val), ¬Hole, &isHole); - Bind(¬Hole); - { - Label isOnProtoType(env); - Label notOnProtoType(env); - Label afterOnProtoType(env); - Branch(*onPrototype, &isOnProtoType, ¬OnProtoType); - Bind(¬OnProtoType); - Jump(&afterOnProtoType); - Bind(&isOnProtoType); - { - Label isExtensible(env); - Label notExtensible(env); - Label nextExtensible(env); - Branch(IsExtensible(receiver), &isExtensible, ¬Extensible); - Bind(&isExtensible); - Jump(&nextExtensible); - Bind(¬Extensible); - { - Label isThrow(env); - Label notThrow(env); - Branch(Word32NotEqual(mayThrow, GetInteger32Constant(0)), &isThrow, ¬Throw); - Bind(&isThrow); - ThrowTypeAndReturn(thread, GET_MESSAGE_STRING_ID(SetPropertyWhenNotExtensible), - FalseConstant()); - Bind(¬Throw); - Return(FalseConstant()); - } - Bind(&nextExtensible); - StubInterfaceDescriptor *addElementInternal = GET_STUBDESCRIPTOR(AddElementInternal); - Return(CallRuntime(addElementInternal, thread, GetWord64Constant(FAST_STUB_ID(AddElementInternal)), - {thread, receiver, index, value, - GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); - } - Bind(&afterOnProtoType); - { - AddrShift attr = Load(INT32_TYPE, pattr); - Label isAccessor(env); - Label notAccessor(env); - Branch(IsAcesscor(attr), &isAccessor, ¬Accessor); - Bind(¬Accessor); - { - Label isWritable(env); - Label notWritable(env); - Branch(IsWritable(attr), &isWritable, ¬Writable); - Bind(&isWritable); - { - AddrShift elements = GetElements(receiver); - Label isDict(env); - Label notDict(env); - AddrShift indexOrEntry = Load(INT32_TYPE, pindexOrEntry); - Branch(isDictionary, &isDict, ¬Dict); - Bind(¬Dict); - { - StoreElement(elements, indexOrEntry, value); - Label updateRepLabel(env); - UpdateRepresention(LoadHClass(receiver), value, &updateRepLabel); - Return(TrueConstant()); - } - Bind(&isDict); - { - UpdateValueAndDetails(elements, indexOrEntry, value, attr); - Return(TrueConstant()); - } - } - Bind(¬Writable); - { - Label isThrow(env); - Label notThrow(env); - Branch(Word32NotEqual(mayThrow, GetInteger32Constant(0)), &isThrow, ¬Throw); - Bind(&isThrow); - ThrowTypeAndReturn(thread, GET_MESSAGE_STRING_ID(SetReadOnlyProperty), FalseConstant()); - Bind(¬Throw); - Return(FalseConstant()); - } - } - Bind(&isAccessor); - { - StubInterfaceDescriptor *callsetter = GET_STUBDESCRIPTOR(CallSetter); - AddrShift setter = GetSetterFromAccessor(val); - Return(CallRuntime(callsetter, thread, GetWord64Constant(FAST_STUB_ID(CallSetter)), - {thread, setter, receiver, value, TruncInt32ToInt1(mayThrow)})); - } - } - } - Bind(&isHole); - { - // holder equals to JSObject::Cast(holder)->GetJSHClass()->GetPrototype(); - holder = GetPrototypeFromHClass(LoadHClass(*holder)); - Label isHeapObj(env); - Label notHeapObj(env); - Branch(TaggedIsObject(*holder), &isHeapObj, ¬HeapObj); - Bind(¬HeapObj); - { - Label isExtensible(env); - Label notExtensible(env); - Label nextExtensible(env); - Branch(IsExtensible(receiver), &isExtensible, ¬Extensible); - Bind(&isExtensible); - Jump(&nextExtensible); - Bind(¬Extensible); - { - Label isThrow(env); - Label notThrow(env); - Branch(Word32NotEqual(mayThrow, GetInteger32Constant(0)), &isThrow, ¬Throw); - Bind(&isThrow); - ThrowTypeAndReturn(thread, GET_MESSAGE_STRING_ID(SetPropertyWhenNotExtensible), - FalseConstant()); - Bind(¬Throw); - Return(FalseConstant()); - } - Bind(&nextExtensible); - { - StubInterfaceDescriptor *addElementInternal = GET_STUBDESCRIPTOR(AddElementInternal); - Return(CallRuntime(addElementInternal, thread, - GetWord64Constant(FAST_STUB_ID(AddElementInternal)), - {thread, receiver, index, value, - GetInteger32Constant(PropertyAttributes::GetDefaultAttributes())})); - } - } - Bind(&isHeapObj); - { - Label isJsProxy(env); - Label notJsProxy(env); - Branch(IsJsProxy(*holder), &isJsProxy, ¬JsProxy); - Bind(&isJsProxy); - { - StubInterfaceDescriptor *setProperty = GET_STUBDESCRIPTOR(JSProxySetProperty); - Return(CallRuntime( - setProperty, thread, GetWord64Constant(FAST_STUB_ID(JSProxySetProperty)), - {thread, *holder, IntBuildTagged(index), value, receiver, TruncInt32ToInt1(mayThrow)})); - } - Bind(¬JsProxy); - onPrototype = TrueConstant(); - } - } - } - LoopEnd(&loopHead); - } -}; - -HWTEST_F_L0(StubOptimizerTest, FastFindOwnElement2Stub) +HWTEST_F_L0(StubTest, FastFindOwnElement2Stub) { std::cout << " ------------------------FastFindOwnElement2Stub ---------------------" << std::endl; - LLVMModuleRef module = static_cast(FastStubs::GetInstance().GetModule()); + auto module = stubModule.GetModule(); LLVMValueRef function = LLVMGetNamedFunction(module, "FindOwnElement2"); - Environment env("FindOwnElement2", 6); - FastFindOwnElement2Stub optimizer(&env); + Circuit netOfGates; + FastFindOwnElement2Stub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -1341,9 +586,9 @@ HWTEST_F_L0(StubOptimizerTest, FastFindOwnElement2Stub) netOfGates.Print(cfg[bbIdx][instIdx - 1]); } } - LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); + LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, &stubModule, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); auto *findOwnElement2Ptr = reinterpret_cast(FastStubs::GetInstance().GetModule()); + auto module = stubModule.GetModule(); LLVMValueRef function = LLVMGetNamedFunction(module, "SetElement"); - Environment env("SetElementStub", 5); - SetElementStub optimizer(&env); + Circuit netOfGates; + FastSetElementStub optimizer(&netOfGates); optimizer.GenerateCircuit(); - auto netOfGates = env.GetCircuit(); netOfGates.PrintAllGates(); auto cfg = Scheduler::Run(&netOfGates); for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { @@ -1384,30 +628,30 @@ HWTEST_F_L0(StubOptimizerTest, SetElementStub) netOfGates.Print(cfg[bbIdx][instIdx - 1]); } } - LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, module, function); + LLVMIRBuilder llvmBuilder(&cfg, &netOfGates, &stubModule, function); llvmBuilder.Build(); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); } struct ThreadTy { - intptr_t magic; // 0x11223344 + intptr_t magic; // 0x11223344 intptr_t fp; }; class StubCallRunTimeThreadFpLock { public: - StubCallRunTimeThreadFpLock(struct ThreadTy *thread, intptr_t newFp): oldRbp_(thread->fp), - thread_(thread) + StubCallRunTimeThreadFpLock(struct ThreadTy *thread, intptr_t newFp) : oldRbp_(thread->fp), thread_(thread) { thread_->fp = *(reinterpret_cast(newFp)); std::cout << "StubCallRunTimeThreadFpLock newFp: " << newFp << " oldRbp_ : " << oldRbp_ - << " thread_->fp:" << thread_->fp <fp:" << thread_->fp << std::endl; } ~StubCallRunTimeThreadFpLock() { std::cout << "~StubCallRunTimeThreadFpLock oldRbp_: " << oldRbp_ << " thread_->fp:" << thread_->fp << std::endl; thread_->fp = oldRbp_; } + private: intptr_t oldRbp_; struct ThreadTy *thread_; @@ -1487,7 +731,7 @@ frameType :1 gcFp:0 #4 0x00007fffebf7b1ab in stub2 () #5 0x0000555555610afe in RuntimeFunc1 () #6 0x00007fffebf7b14e in stub1 () -#7 0x000055555561197c in panda::test::StubOptimizerTest_JSEntryTest_Test::TestBody() () +#7 0x000055555561197c in panda::test::StubTest_JSEntryTest_Test::TestBody() () */ LLVMValueRef LLVMCallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder) @@ -1504,7 +748,8 @@ LLVMValueRef LLVMCallingFp(LLVMModuleRef &module, LLVMBuilderRef &builder) return frameAddr; } -HWTEST_F_L0(StubOptimizerTest, JSEntryTest) +#ifdef LLVM_SUPPORT_GC +HWTEST_F_L0(StubTest, JSEntryTest) { std::cout << " ---------- JSEntryTest ------------- " << std::endl; LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); @@ -1526,9 +771,7 @@ HWTEST_F_L0(StubOptimizerTest, JSEntryTest) std::vector elements_t {llvmI64, llvmI64}; LLVMTypeRef threadTy = LLVMStructTypeInContext(context, elements_t.data(), elements_t.size(), 0); LLVMTypeRef threadTyPtr = LLVMPointerType(threadTy, 0); - LLVMTypeRef paramTys0[] = { - threadTyPtr - }; + LLVMTypeRef paramTys0[] = {threadTyPtr}; /* implement stub1 */ LLVMValueRef stub1 = LLVMAddFunction(module, "stub1", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0)); LLVMAddTargetDependentFunctionAttr(stub1, "frame-pointer", "all"); @@ -1623,18 +866,16 @@ HWTEST_F_L0(StubOptimizerTest, JSEntryTest) retVal = LLVMConstInt(LLVMInt64Type(), 3, false); LLVMBuildRet(builder, retVal); LLVMDumpModule(module); - char* error = nullptr; + char *error = nullptr; LLVMVerifyModule(module, LLVMAbortProcessAction, &error); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); uint64_t stub1Code = LLVMGetFunctionAddress(engine, "stub1"); uint64_t stub2Code = LLVMGetFunctionAddress(engine, "stub2"); uint64_t stub3Code = LLVMGetFunctionAddress(engine, "stub3"); - std::map addr2name = { - {stub1Code, "stub1"}, {stub2Code, "stub2"}, {stub3Code, "stub3"} - }; + std::map addr2name = {{stub1Code, "stub1"}, {stub2Code, "stub2"}, {stub3Code, "stub3"}}; std::cout << std::endl << " stub1Code : " << stub1Code << std::endl; std::cout << std::endl << " stub2Code : " << stub2Code << std::endl; std::cout << std::endl << " stub3Code : " << stub3Code << std::endl; @@ -1643,8 +884,8 @@ HWTEST_F_L0(StubOptimizerTest, JSEntryTest) auto stub1Func = reinterpret_cast(stub1Code); g_stub2Func = reinterpret_cast(stub2Code); int64_t result = stub1Func(¶meters); - std::cout << std::endl << "parameters magic:" << parameters.magic - << " parameters.fp " << parameters.fp << std::endl; + std::cout << std::endl + << "parameters magic:" << parameters.magic << " parameters.fp " << parameters.fp << std::endl; EXPECT_EQ(parameters.fp, 0x0); EXPECT_EQ(result, 1); std::cout << " ++++++++++ JSEntryTest +++++++++++++ " << std::endl; @@ -1660,7 +901,7 @@ main push rbp push rbp push type */ -HWTEST_F_L0(StubOptimizerTest, Prologue) +HWTEST_F_L0(StubTest, Prologue) { std::cout << " ---------- Prologue ------------- " << std::endl; LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); @@ -1699,10 +940,10 @@ HWTEST_F_L0(StubOptimizerTest, Prologue) LLVMBuildRet(builder, retVal); LLVMDumpModule(module); - char* error = nullptr; + char *error = nullptr; LLVMVerifyModule(module, LLVMAbortProcessAction, &error); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); uint64_t mainCode = LLVMGetFunctionAddress(engine, "main"); @@ -1719,7 +960,7 @@ test: js(stub):main call RuntimeFunc */ -HWTEST_F_L0(StubOptimizerTest, CEntryFp) +HWTEST_F_L0(StubTest, CEntryFp) { std::cout << " ---------- CEntryFp ------------- " << std::endl; LLVMModuleRef module = LLVMModuleCreateWithName("simple_module"); @@ -1732,9 +973,7 @@ HWTEST_F_L0(StubOptimizerTest, CEntryFp) std::vector elements_t {llvmI64, llvmI64}; LLVMTypeRef threadTy = LLVMStructTypeInContext(context, elements_t.data(), elements_t.size(), 0); LLVMTypeRef threadTyPtr = LLVMPointerType(threadTy, 0); - LLVMTypeRef paramTys0[] = { - threadTyPtr - }; + LLVMTypeRef paramTys0[] = {threadTyPtr}; /* implement main call RuntimeFunc */ LLVMValueRef func = LLVMAddFunction(module, "main", LLVMFunctionType(LLVMInt64Type(), paramTys0, 1, 0)); LLVMAddTargetDependentFunctionAttr(func, "frame-pointer", "all"); @@ -1780,10 +1019,10 @@ HWTEST_F_L0(StubOptimizerTest, CEntryFp) LLVMBuildRet(builder, retVal); LLVMDumpModule(module); - char* error = nullptr; + char *error = nullptr; LLVMVerifyModule(module, LLVMAbortProcessAction, &error); - LLVMMCJITCompiler compiler(module); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); uint64_t nativeCode = LLVMGetFunctionAddress(engine, "main"); @@ -1797,7 +1036,7 @@ HWTEST_F_L0(StubOptimizerTest, CEntryFp) std::cout << " ++++++++++ CEntryFp +++++++++++++ " << std::endl; } -HWTEST_F_L0(StubOptimizerTest, LoadGCIRTest) +HWTEST_F_L0(StubTest, LoadGCIRTest) { std::cout << "--------------LoadGCIRTest--------------------" << std::endl; char *path = get_current_dir_name(); @@ -1814,18 +1053,16 @@ HWTEST_F_L0(StubOptimizerTest, LoadGCIRTest) llvm::LLVMContext context; llvm::StringRef inputFilename(resolvedPath); // Load the input module... - std::unique_ptr rawModule = - parseIRFile(inputFilename, err, context); + std::unique_ptr rawModule = parseIRFile(inputFilename, err, context); if (!rawModule) { std::cout << "parseIRFile :" << inputFilename.data() << " failed !" << std::endl; return; } - LLVMModuleRef module = LLVMCloneModule(wrap(rawModule.get())); - LLVMMCJITCompiler compiler(module); + LLVMModuleRef module = LLVMCloneModule(wrap(rawModule.get())); + LLVMMcJitEngine compiler(module); compiler.Run(); auto engine = compiler.GetEngine(); - LLVMValueRef function = - LLVMGetNamedFunction(module, "main"); + LLVMValueRef function = LLVMGetNamedFunction(module, "main"); LLVMDumpValue(function); auto *mainPtr = reinterpret_cast(LLVMGetPointerToGlobal(engine, function)); @@ -1838,6 +1075,8 @@ HWTEST_F_L0(StubOptimizerTest, LoadGCIRTest) int value = reinterpret_cast(mainPtr)(); std::cout << " value:" << value << std::endl; } +#endif + extern "C" { void DoSafepoint() { @@ -1863,9 +1102,144 @@ void DoSafepoint() } std::cout << std::endl << std::endl; std::cout << std::hex << "+++++++++++++++++++ returnAddr : 0x" << returnAddr << " rbp:" << rbp - << " rsp: " << rsp << std::endl; + << " rsp: " << rsp << std::endl; } std::cout << "do_safepoint +++ " << std::endl; } } + +class FastGetPropertyByIndexStub : public Stub { +public: + explicit FastGetPropertyByIndexStub(Circuit *circuit) : Stub("FastGetPropertyByIndex", 3, circuit) {} + ~FastGetPropertyByIndexStub() = default; + NO_MOVE_SEMANTIC(FastGetPropertyByIndexStub); + NO_COPY_SEMANTIC(FastGetPropertyByIndexStub); + void GenerateCircuit() override + { + auto env = GetEnvironment(); + AddrShift thread = PtrArgument(0); + AddrShift receiver = PtrArgument(1); + AddrShift index = Int32Argument(2); /* 2 : 3rd paramter is index */ + + DEFVARIABLE(holder, MachineType::TAGGED_POINTER_TYPE, receiver); + Label loopHead(env); + Label loopEnd(env); + Label loopExit(env); + Label afterLoop(env); + Jump(&loopHead); + LoopBegin(&loopHead); + { + AddrShift hclass = LoadHClass(*holder); + AddrShift jsType = GetObjectType(hclass); + Label isSpecialIndexed(env); + Label notSpecialIndexed(env); + Label loopEnd(env); + Branch(IsSpecialIndexedObj(jsType), &isSpecialIndexed, ¬SpecialIndexed); + Bind(&isSpecialIndexed); + { + Return(GetHoleConstant()); + } + Bind(¬SpecialIndexed); + { + AddrShift elements = GetElements(*holder); + Label isDictionaryElement(env); + Label notDictionaryElement(env); + Branch(IsDictionaryElement(hclass), &isDictionaryElement, ¬DictionaryElement); + Bind(¬DictionaryElement); + { + Label lessThanLength(env); + Label notLessThanLength(env); + Branch(Word32LessThan(index, GetLengthofElements(elements)), &lessThanLength, ¬LessThanLength); + Bind(&lessThanLength); + { + Label notHole(env); + Label isHole(env); + AddrShift value = GetValueFromTaggedArray(elements, index); + Branch(TaggedIsNotHole(value), ¬Hole, &isHole); + Bind(¬Hole); + { + Return(value); + } + Bind(&isHole); + { + Jump(&loopExit); + } + } + Bind(¬LessThanLength); + { + Return(GetHoleConstant()); + } + } + Bind(&isDictionaryElement); + { + AddrShift entry = + FindElementFromNumberDictionary(thread, elements, IntBuildTagged(index)); + Label notNegtiveOne(env); + Label negtiveOne(env); + Branch(Word32NotEqual(entry, GetInteger32Constant(-1)), ¬NegtiveOne, &negtiveOne); + Bind(¬NegtiveOne); + { + AddrShift attr = GetAttributesFromDictionary(elements, entry); + AddrShift value = GetValueFromDictionary(elements, entry); + Label isAccessor(env); + Label notAccessor(env); + Branch(IsAcesscor(attr), &isAccessor, ¬Accessor); + Bind(&isAccessor); + { + Label isInternal(env); + Label notInternal(env); + Branch(IsAccessorInternal(value), &isInternal, ¬Internal); + Bind(&isInternal); + { + StubDescriptor *callAccessorGetter = GET_STUBDESCRIPTOR(AccessorGetter); + Return(CallRuntime(callAccessorGetter, thread, + GetWord64Constant(FAST_STUB_ID(AccessorGetter)), + {thread, *holder, value})); + } + Bind(¬Internal); + { + StubDescriptor *callGetter = GET_STUBDESCRIPTOR(CallGetter); + Return(CallRuntime(callGetter, thread, GetWord64Constant(FAST_STUB_ID(CallGetter)), + {thread, receiver, value})); + } + } + Bind(¬Accessor); + { + Return(value); + } + } + Bind(&negtiveOne); + Jump(&loopExit); + } + Bind(&loopExit); + { + holder = GetPrototypeFromHClass(LoadHClass(*holder)); + Branch(TaggedIsHeapObject(*holder), &loopEnd, &afterLoop); + } + } + Bind(&loopEnd); + LoopEnd(&loopHead); + Bind(&afterLoop); + { + Return(GetUndefinedConstant()); + } + } + } +}; + +HWTEST_F_L0(StubTest, FastGetPropertyByIndexStub) +{ + Circuit netOfGates; + FastGetPropertyByIndexStub optimizer(&netOfGates); + optimizer.GenerateCircuit(); + netOfGates.PrintAllGates(); + auto cfg = Scheduler::Run(&netOfGates); + for (size_t bbIdx = 0; bbIdx < cfg.size(); bbIdx++) { + std::cout << (netOfGates.GetOpCode(cfg[bbIdx].front()).IsCFGMerge() ? "MERGE_" : "BB_") << bbIdx << ":" + << std::endl; + for (size_t instIdx = cfg[bbIdx].size(); instIdx > 0; instIdx--) { + netOfGates.Print(cfg[bbIdx][instIdx - 1]); + } + } +} } // namespace panda::test diff --git a/ecmascript/compiler/verifier.cpp b/ecmascript/compiler/verifier.cpp index 66749c8bee..96fb1b882a 100644 --- a/ecmascript/compiler/verifier.cpp +++ b/ecmascript/compiler/verifier.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "ecmascript/compiler/scheduler.h" diff --git a/ecmascript/compiler/verifier.h b/ecmascript/compiler/verifier.h index 2c23be63cf..ca8036ce22 100644 --- a/ecmascript/compiler/verifier.h +++ b/ecmascript/compiler/verifier.h @@ -30,23 +30,24 @@ public: static bool RunDataIntegrityCheck(const Circuit *circuit); static bool RunStateGatesCheck(const Circuit *circuit, const std::vector &bbGatesList); static bool RunCFGSoundnessCheck(const Circuit *circuit, const std::vector &bbGatesList, - const std::unordered_map &bbGatesAddrToIdx); + const std::unordered_map &bbGatesAddrToIdx); static bool RunCFGIsDAGCheck(const Circuit *circuit); static bool RunCFGReducibilityCheck(const Circuit *circuit, const std::vector &bbGatesList, - const std::unordered_map &bbGatesAddrToIdx, - const std::function &isAncestor); + const std::unordered_map &bbGatesAddrToIdx, + const std::function &isAncestor); static bool RunFixedGatesCheck(const Circuit *circuit, const std::vector &fixedGatesList); static bool RunFixedGatesRelationsCheck(const Circuit *circuit, const std::vector &fixedGatesList, - const std::unordered_map &bbGatesAddrToIdx, - const std::function &isAncestor); + const std::unordered_map &bbGatesAddrToIdx, + const std::function &isAncestor); static bool RunFlowCyclesFind(const Circuit *circuit, std::vector *schedulableGatesListPtr, - const std::vector &bbGatesList, const std::vector &fixedGatesList); + const std::vector &bbGatesList, + const std::vector &fixedGatesList); static bool RunSchedulableGatesCheck(const Circuit *circuit, const std::vector &schedulableGatesList); static bool RunPrologGatesCheck(const Circuit *circuit, const std::vector &schedulableGatesList); static bool RunSchedulingBoundsCheck(const Circuit *circuit, const std::vector &schedulableGatesList, - const std::unordered_map &bbGatesAddrToIdx, - const std::function &isAncestor, - const std::function &lowestCommonAncestor); + const std::unordered_map &bbGatesAddrToIdx, + const std::function &isAncestor, + const std::function &lowestCommonAncestor); static std::vector FindFixedGates(const Circuit *circuit, const std::vector &bbGatesList); static bool Run(const Circuit *circuit); }; diff --git a/ecmascript/js_thread.cpp b/ecmascript/js_thread.cpp index f2352867b9..93e94e2c00 100644 --- a/ecmascript/js_thread.cpp +++ b/ecmascript/js_thread.cpp @@ -17,6 +17,7 @@ #include "ecmascript/internal_call_params.h" #include "ecmascript/interpreter/interpreter-inl.h" #include "ecmascript/js_thread.h" +#include "ecmascript/stub_module.h" #include "include/panda_vm.h" namespace panda::ecmascript { @@ -31,7 +32,6 @@ JSThread *JSThread::Create(Runtime *runtime, PandaVM *vm) jsThread->currentFrame_ = jsThread->frameBase_ + MAX_STACK_SIZE; JSThread::SetCurrent(jsThread); EcmaInterpreter::InitStackFrame(jsThread); - return jsThread; } @@ -211,4 +211,15 @@ void JSThread::ResetGuardians() { stableArrayElementsGuardians_ = true; } + +void JSThread::LoadFastStubModule(const char *moduleFile) +{ + StubModule stubModule; + std::string fileName(moduleFile); + stubModule.Load(this, fileName); + for (int i = 0; i < kungfu::FAST_STUB_MAXCOUNT; i++) { + fastStubEntires_[i] = stubModule.GetStubEntry(i); + } + stubCode_ = stubModule.GetCode(); +} } // namespace panda::ecmascript diff --git a/ecmascript/js_thread.h b/ecmascript/js_thread.h index eef175a525..4cdc049d84 100644 --- a/ecmascript/js_thread.h +++ b/ecmascript/js_thread.h @@ -157,15 +157,23 @@ public: JSTaggedValue GetCurrentLexenv() const; - void SetRuntimeFunction(uint32_t id, uintptr_t functionAddress) + void SetRuntimeFunction(uint32_t id, Address functionAddress) { ASSERT(id < MAX_RUNTIME_FUNCTIONS); - runtimeFunctions[id] = functionAddress; + runtimeFunctions_[id] = functionAddress; } + Address GetFastStubEntry(uint32_t id) + { + ASSERT(id < kungfu::FAST_STUB_MAXCOUNT); + return fastStubEntires_[id]; + } + + void LoadFastStubModule(const char *moduleFile); + static uint32_t GetRuntimeFunctionsOffset() { - return MEMBER_OFFSET(JSThread, runtimeFunctions); + return MEMBER_OFFSET(JSThread, runtimeFunctions_); } static uint64_t GetCurrentFrameOffset() @@ -193,6 +201,9 @@ private: static constexpr uint32_t MAX_RUNTIME_FUNCTIONS = kungfu::EXTERN_RUNTIME_STUB_MAXCOUNT - kungfu::EXTERNAL_RUNTIME_STUB_BEGIN - 1; + Address runtimeFunctions_[MAX_RUNTIME_FUNCTIONS]; + Address fastStubEntires_[kungfu::FAST_STUB_MAXCOUNT]; + JSTaggedValue stubCode_ {JSTaggedValue::Hole()}; EcmaGlobalStorage *globalStorage_ {nullptr}; os::memory::ConditionVariable initializationVar_ GUARDED_BY(initializationLock_); @@ -210,7 +221,6 @@ private: JSTaggedValue exception_ {JSTaggedValue::Hole()}; bool stableArrayElementsGuardians_ {true}; GlobalEnvConstants globalConst_; // Place-Holder - Address runtimeFunctions[MAX_RUNTIME_FUNCTIONS]; InternalCallParams *internalCallParams_ {nullptr}; friend class EcmaHandleScope; diff --git a/ecmascript/runtime_trampolines.cpp b/ecmascript/runtime_trampolines.cpp index 1df5a19818..3608d39e5a 100644 --- a/ecmascript/runtime_trampolines.cpp +++ b/ecmascript/runtime_trampolines.cpp @@ -33,8 +33,8 @@ bool RuntimeTrampolines::AddElementInternal(uint64_t argThread, uint64_t argRece return JSObject::AddElementInternal(thread, receiver, argIndex, value, attr); } -bool RuntimeTrampolines::CallSetter(uint64_t argThread, uint64_t argSetter, uint64_t argReceiver, - uint64_t argValue, bool argMayThrow) +bool RuntimeTrampolines::CallSetter(uint64_t argThread, uint64_t argSetter, uint64_t argReceiver, uint64_t argValue, + bool argMayThrow) { auto thread = reinterpret_cast(argThread); [[maybe_unused]] EcmaHandleScope handleScope(thread); @@ -54,8 +54,8 @@ void RuntimeTrampolines::ThrowTypeError(uint64_t argThread, int argMessageString THROW_NEW_ERROR_AND_RETURN(thread, error.GetTaggedValue()); } -bool RuntimeTrampolines::JSProxySetProperty(uint64_t argThread, uint64_t argProxy, uint64_t argKey, - uint64_t argValue, uint64_t argReceiver, bool argMayThrow) +bool RuntimeTrampolines::JSProxySetProperty(uint64_t argThread, uint64_t argProxy, uint64_t argKey, uint64_t argValue, + uint64_t argReceiver, bool argMayThrow) { auto thread = reinterpret_cast(argThread); [[maybe_unused]] EcmaHandleScope handleScope(thread); @@ -72,4 +72,20 @@ uint32_t RuntimeTrampolines::GetHash32(uint64_t key, uint64_t len) auto pkey = reinterpret_cast(key); return panda::GetHash32(pkey, static_cast(len)); } + +uint64_t RuntimeTrampolines::CallGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver) +{ + auto thread = reinterpret_cast(argThread); + auto accessor = AccessorData::Cast(reinterpret_cast(argGetter)); + JSHandle objHandle(thread, JSTaggedValue(reinterpret_cast(argReceiver))); + return JSObject::CallGetter(thread, accessor, objHandle).GetRawData(); +} + +uint64_t RuntimeTrampolines::AccessorGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver) +{ + auto thread = reinterpret_cast(argThread); + auto accessor = AccessorData::Cast(reinterpret_cast(argGetter)); + JSHandle objHandle(thread, JSTaggedValue(reinterpret_cast(argReceiver))); + return accessor->CallInternalGet(thread, objHandle).GetRawData(); +} } // namespace panda::ecmascript diff --git a/ecmascript/runtime_trampolines.h b/ecmascript/runtime_trampolines.h index e63f3469ad..0881006e5b 100644 --- a/ecmascript/runtime_trampolines.h +++ b/ecmascript/runtime_trampolines.h @@ -40,6 +40,8 @@ public: uint64_t argValue, uint32_t argAttr); static bool CallSetter(uint64_t argThread, uint64_t argSetter, uint64_t argReceiver, uint64_t argValue, bool argMayThrow); + static uint64_t CallGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver); + static uint64_t AccessorGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver); static void ThrowTypeError(uint64_t argThread, int argMessageStringId); static bool JSProxySetProperty(uint64_t argThread, uint64_t argProxy, uint64_t argKey, uint64_t argValue, uint64_t argReceiver, bool argMayThrow); diff --git a/ecmascript/stub_module.cpp b/ecmascript/stub_module.cpp new file mode 100644 index 0000000000..4dee898c4d --- /dev/null +++ b/ecmascript/stub_module.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "stub_module.h" + +namespace panda::ecmascript { +void StubModule::Save(const std::string &filename) +{ + if (code_ != nullptr) { + std::ofstream modulefile(filename.c_str(), std::ofstream::binary); + /* write stub entries offset */ + modulefile.write(reinterpret_cast(fastStubEntries_.data()), + sizeof(uintptr_t) * kungfu::FAST_STUB_MAXCOUNT); + /* write code length & code buff */ + int codeSize = code_->GetInstructionSizeInBytes().GetInt(); + modulefile.write(reinterpret_cast(&codeSize), sizeof(codeSize)); + modulefile.write(reinterpret_cast(code_->GetDataOffsetAddress()), codeSize); + modulefile.close(); + } +} + +void StubModule::Load(JSThread *thread, const std::string &filename) +{ + std::ifstream modulefile(filename.c_str(), std::ofstream::binary); + modulefile.read(reinterpret_cast(fastStubEntries_.data()), sizeof(uintptr_t) * kungfu::FAST_STUB_MAXCOUNT); + int codeSize = 0; + modulefile.read(reinterpret_cast(&codeSize), sizeof(codeSize)); + auto factory = thread->GetEcmaVM()->GetFactory(); + auto codeHandle = factory->NewMachineCodeObject(codeSize, nullptr); + modulefile.read(reinterpret_cast(codeHandle->GetDataOffsetAddress()), codeSize); + SetCode(*codeHandle); + modulefile.close(); +} +} // namespace panda::ecmascript \ No newline at end of file diff --git a/ecmascript/stub_module.h b/ecmascript/stub_module.h new file mode 100644 index 0000000000..f2a81c8797 --- /dev/null +++ b/ecmascript/stub_module.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 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. + */ + +#ifndef ECMASCRIPT_STUB_MODULE_H +#define ECMASCRIPT_STUB_MODULE_H + +#include "ecmascript/js_thread.h" +#include "ecmascript/mem/machine_code.h" + +namespace panda::ecmascript { +using Address = uintptr_t; +class StubModule { +public: + Address GetStubEntry(int index) + { + return code_->GetDataOffsetAddress() + fastStubEntries_[index]; + } + void Save(const std::string &filename); + void Load(JSThread *thread, const std::string &filename); + void SetCode(MachineCode *code)\ + { + code_ = code; + } + void SetStubEntry(int index, Address offset) + { + fastStubEntries_[index] = offset; + } + JSTaggedValue GetCode() + { + return JSTaggedValue(code_); + } + +private: + std::array fastStubEntries_ {-1}; + MachineCode *code_ {nullptr}; +}; +} // namespace panda::ecmascript +#endif // ECMASCRIPT_STUB_MODULE_H \ No newline at end of file -- Gitee From 57a7a5071a47a22d9faa30d4b3bd569bc86cac45 Mon Sep 17 00:00:00 2001 From: getingke Date: Mon, 13 Sep 2021 15:18:13 +0800 Subject: [PATCH 2/9] change StubModule to public api Change-Id: I869bc1fc9b71afc6c99825580017e60272d0c493 Signed-off-by: getingke --- BUILD.gn | 2 +- ecmascript/stub_module.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index dbc893259b..1032661a7a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -385,7 +385,7 @@ ohos_static_library("libark_jsruntime_static") { ] if (is_standard_system) { - # cflags_cc = [ "-fvisibility=hidden" ] + cflags_cc = [ "-fvisibility=hidden" ] deps += [ "$ark_root/runtime:libarkruntime_static" ] } else { deps += [ "$ark_root/runtime:libarkruntime" ] diff --git a/ecmascript/stub_module.h b/ecmascript/stub_module.h index f2a81c8797..cc0c666692 100644 --- a/ecmascript/stub_module.h +++ b/ecmascript/stub_module.h @@ -16,12 +16,14 @@ #ifndef ECMASCRIPT_STUB_MODULE_H #define ECMASCRIPT_STUB_MODULE_H +#include "ecmascript/common.h" #include "ecmascript/js_thread.h" #include "ecmascript/mem/machine_code.h" +#include "libpandabase/macros.h" namespace panda::ecmascript { using Address = uintptr_t; -class StubModule { +class PUBLIC_API StubModule { public: Address GetStubEntry(int index) { -- Gitee From ccf9cd39c5776eb53f764d1cd60bab018b5603b6 Mon Sep 17 00:00:00 2001 From: getingke Date: Wed, 22 Sep 2021 21:52:06 +0800 Subject: [PATCH 3/9] fixed for gn format Signed-off-by: getingke Change-Id: Id1dbd7eb333a2a252b7c6670156c647ca042f6d1 --- BUILD.gn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 1032661a7a..ae8a7ba665 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -34,8 +34,8 @@ group("ark_js_host_linux_tools_packages") { ] if (is_standard_system) { deps += [ - "//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer(${host_toolchain})", "//ark/js_runtime/ecmascript/compiler:ark_stub_opt(${host_toolchain})", + "//ark/js_runtime/ecmascript/compiler:libark_jsoptimizer(${host_toolchain})", ] } } @@ -65,6 +65,7 @@ group("ark_js_host_unittest") { deps += [ "//ark/js_runtime:libark_jsruntime(${host_toolchain})", "//ark/js_runtime/ecmascript/builtins/tests:host_unittest", + "//ark/js_runtime/ecmascript/compiler/tests:host_unittest", "//ark/js_runtime/ecmascript/hprof/tests:host_unittest", "//ark/js_runtime/ecmascript/js_vm:ark_js_vm(${host_toolchain})", "//ark/js_runtime/ecmascript/napi/test:host_unittest", @@ -72,7 +73,6 @@ group("ark_js_host_unittest") { "//ark/js_runtime/ecmascript/snapshot/tests:host_unittest", "//ark/js_runtime/ecmascript/tests:host_unittest", "//ark/js_runtime/ecmascript/tooling/test:host_unittest", - "//ark/js_runtime/ecmascript/compiler/tests:host_unittest", ] if (is_standard_system) { deps += [ "//ark/js_runtime/ecmascript/compiler/tests:host_unittest" ] -- Gitee From 2c3adbfbfe970375b856dc953a628748abf3b5a4 Mon Sep 17 00:00:00 2001 From: getingke Date: Thu, 23 Sep 2021 11:26:35 +0800 Subject: [PATCH 4/9] fixed for codestyle check Signed-off-by: getingke Change-Id: If2d8a0734b4c67151468c86854b0299171e4b617 --- ecmascript/compiler/fast_stub.h | 7 ++++ ecmascript/compiler/llvm_ir_builder.cpp | 12 ++----- ecmascript/compiler/llvm_mcjit_engine.cpp | 18 +++++----- ecmascript/compiler/stub.cpp | 4 +-- ecmascript/compiler/stub.h | 19 +++++----- ecmascript/compiler/stub_aot_compiler.cpp | 2 +- ecmascript/compiler/stub_descriptor.cpp | 44 +++++++++++------------ ecmascript/compiler/stub_descriptor.h | 8 ++--- ecmascript/compiler/tests/stub_tests.cpp | 3 +- ecmascript/stub_module.h | 2 +- 10 files changed, 61 insertions(+), 58 deletions(-) diff --git a/ecmascript/compiler/fast_stub.h b/ecmascript/compiler/fast_stub.h index 00b4e24048..7982183207 100644 --- a/ecmascript/compiler/fast_stub.h +++ b/ecmascript/compiler/fast_stub.h @@ -42,6 +42,7 @@ public: class FastSubStub : public Stub { public: + // 2 : 2 means argument counts explicit FastSubStub(Circuit *circuit) : Stub("FastSub", 2, circuit) {} ~FastSubStub() = default; NO_MOVE_SEMANTIC(FastSubStub); @@ -51,6 +52,7 @@ public: class FastMulStub : public Stub { public: + // 2 : 2 means argument counts explicit FastMulStub(Circuit *circuit) : Stub("FastMul", 2, circuit) {} ~FastMulStub() = default; NO_MOVE_SEMANTIC(FastMulStub); @@ -60,6 +62,7 @@ public: class FastDivStub : public Stub { public: + // 2 : 2 means argument counts explicit FastDivStub(Circuit *circuit) : Stub("FastDiv", 2, circuit) {} ~FastDivStub() = default; NO_MOVE_SEMANTIC(FastDivStub); @@ -69,6 +72,7 @@ public: class FastFindOwnElementStub : public Stub { public: + // 3 : 3 means argument counts explicit FastFindOwnElementStub(Circuit *circuit) : Stub("FastFindOwnElement", 3, circuit) {} ~FastFindOwnElementStub() = default; NO_MOVE_SEMANTIC(FastFindOwnElementStub); @@ -78,6 +82,7 @@ public: class FastGetElementStub : public Stub { public: + // 3 : 3 means argument counts explicit FastGetElementStub(Circuit *circuit) : Stub("FastGetElement", 3, circuit) {} ~FastGetElementStub() = default; NO_MOVE_SEMANTIC(FastGetElementStub); @@ -87,6 +92,7 @@ public: class FastFindOwnElement2Stub : public Stub { public: + // 6 : 6 means argument counts explicit FastFindOwnElement2Stub(Circuit *circuit) : Stub("FastFindOwnElement2", 6, circuit) {} ~FastFindOwnElement2Stub() = default; NO_MOVE_SEMANTIC(FastFindOwnElement2Stub); @@ -96,6 +102,7 @@ public: class FastSetElementStub : public Stub { public: + // 5 : 5 means argument counts explicit FastSetElementStub(Circuit *circuit) : Stub("FastSetElement", 5, circuit) {} ~FastSetElementStub() = default; NO_MOVE_SEMANTIC(FastSetElementStub); diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index 47e98016d9..204494a9e8 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -572,8 +572,7 @@ void LLVMIRBuilder::VisitCall(AddrShift gate, const std::vector &inLi LLVMValueRef callee; StubDescriptor *callee_descriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(index); // runtime case - if (callee_descriptor->GetStubKind() == StubDescriptor::RUNTIME_STUB) { - std::cout << "external refrence index " << index << std::endl; + if (callee_descriptor->GetStubKind() == StubDescriptor::CallStubKind::RUNTIME_STUB) { LLVMTypeRef rtfuncType = stubModule_->GetExternalFunctionType(index); LLVMDumpType(rtfuncType); LLVMTypeRef rtfuncTypePtr = LLVMPointerType(rtfuncType, 0); @@ -1082,9 +1081,9 @@ void LLVMIRBuilder::VisitCastDoubleToInt(AddrShift gate, AddrShift e1) const LLVMStubModule::LLVMStubModule(const char *name) { - module_ = LLVMModuleCreateWithName("fast_stubs"); + module_ = LLVMModuleCreateWithName("fast_stubs"); #ifdef PANDA_TARGET_AMD64 - LLVMSetTarget(module_, "x86_64-unknown-linux-gnu"); + LLVMSetTarget(module_, "x86_64-unknown-linux-gnu"); #endif } @@ -1098,7 +1097,6 @@ void LLVMStubModule::Initialize() } } for (i = 0; i < MAX_EXTERNAL_FUNCTION_COUNT; i++) { - std::cout << "external index " << i + EXTERNAL_FUNCTION_OFFSET << std::endl; auto externalDescriptor = FastStubDescriptors::GetInstance().GetStubDescriptor(i + EXTERNAL_FUNCTION_OFFSET); if (!externalDescriptor->GetName().empty()) { externalFuctionType_[i] = GetLLVMFunctionTypeStubDescriptor(externalDescriptor); @@ -1115,16 +1113,12 @@ LLVMValueRef LLVMStubModule::GetLLVMFunctionByStubDescriptor(StubDescriptor *stu LLVMTypeRef LLVMStubModule::GetLLVMFunctionTypeStubDescriptor(StubDescriptor *stubDescriptor) { LLVMTypeRef returnType = ConvertLLVMTypeFromMachineType(stubDescriptor->GetReturnType()); - LLVMDumpType(returnType); std::vector paramTys; auto paramCount = stubDescriptor->GetParametersCount(); for (int i = 0; i < paramCount; i++) { auto paramsType = stubDescriptor->GetParametersType(); paramTys.push_back(ConvertLLVMTypeFromMachineType(paramsType[i])); } - for(auto type : paramTys) { - LLVMDumpType(type); - } auto functype = LLVMFunctionType(returnType, paramTys.data(), paramCount, 0); LLVMDumpType(functype); return functype; diff --git a/ecmascript/compiler/llvm_mcjit_engine.cpp b/ecmascript/compiler/llvm_mcjit_engine.cpp index 7792543937..abcc8df721 100644 --- a/ecmascript/compiler/llvm_mcjit_engine.cpp +++ b/ecmascript/compiler/llvm_mcjit_engine.cpp @@ -50,8 +50,8 @@ namespace kungfu { -static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, unsigned alignment, unsigned sectionID, - const char *sectionName) +static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, [[maybe_unused]] unsigned alignment, + [[maybe_unused]] unsigned sectionID, const char *sectionName) { std::cout << "RoundTripAllocateCodeSection object " << object << " - " << std::endl; struct CodeState& state = *static_cast(object); @@ -61,14 +61,15 @@ static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, unsig return addr; } -static uint8_t *RoundTripAllocateDataSection(void *object, uintptr_t size, unsigned alignment, unsigned sectionID, - const char *sectionName, LLVMBool isReadOnly) +static uint8_t *RoundTripAllocateDataSection(void *object, uintptr_t size, [[maybe_unused]] unsigned alignment, + [[maybe_unused]] unsigned sectionID, const char *sectionName, + [[maybe_unused]] LLVMBool isReadOnly) { struct CodeState& state = *static_cast(object); return state.AllocaDataSection(size, sectionName); } -static LLVMBool RoundTripFinalizeMemory(void *object, char **errMsg) +static LLVMBool RoundTripFinalizeMemory(void *object, [[maybe_unused]] char **errMsg) { std::cout << "RoundTripFinalizeMemory object " << object << " - " << std::endl; return 0; @@ -156,8 +157,9 @@ void LLVMMcJitEngine::Initialize() options_.NoFramePointerElim = true; } -static const char *SymbolLookupCallback(void *disInfo, uint64_t referenceValue, uint64_t *referenceType, - uint64_t referencePC, const char **referenceName) +static const char *SymbolLookupCallback([[maybe_unused]] void *disInfo, [[maybe_unused]] uint64_t referenceValue, + uint64_t *referenceType, [[maybe_unused]]uint64_t referencePC, + [[maybe_unused]] const char **referenceName) { *referenceType = LLVMDisassembler_ReferenceType_InOut_None; return nullptr; @@ -190,7 +192,7 @@ void LLVMMcJitEngine::Disassemble(std::map addr2name) con if (addr2name.find(addr) != addr2name.end()) { std::cout << addr2name[addr].c_str() << ":" << std::endl; } - fprintf(stderr, "%08x: %08x %s\n", pc, *reinterpret_cast(byteSp), outString); + (void)fprintf(stderr, "%08x: %08x %s\n", pc, *reinterpret_cast(byteSp), outString); pc += InstSize; byteSp += InstSize; numBytes -= InstSize; diff --git a/ecmascript/compiler/stub.cpp b/ecmascript/compiler/stub.cpp index 9dad1d308a..28f0537814 100644 --- a/ecmascript/compiler/stub.cpp +++ b/ecmascript/compiler/stub.cpp @@ -561,8 +561,8 @@ AddrShift Stub::UpdateRepresention(AddrShift oldRep, AddrShift value) Label isObjectNewRep(env); Label notObjectNewRep(env); Branch(Word64NotEqual(newRep, GetWord64Constant( - static_cast(panda::ecmascript::Representation::OBJECT))), - ¬ObjectNewRep, &isObjectNewRep); + static_cast(panda::ecmascript::Representation::OBJECT))), + ¬ObjectNewRep, &isObjectNewRep); Bind(¬ObjectNewRep); { resultRep = GetWord64Constant(static_cast(panda::ecmascript::Representation::NUMBER)); diff --git a/ecmascript/compiler/stub.h b/ecmascript/compiler/stub.h index 743bac26ed..00a0785d35 100644 --- a/ecmascript/compiler/stub.h +++ b/ecmascript/compiler/stub.h @@ -26,7 +26,6 @@ #include "ecmascript/tagged_dictionary.h" namespace kungfu { - // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define DEFVARIABLE(varname, type, val) Stub::StubVariable varname(GetEnvironment(), type, NextVariableId(), val) @@ -311,7 +310,8 @@ public: bool IsSelector(const Gate *gate) const { - return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS && gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64; + return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS && + gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64; } uint32_t GetId() const @@ -740,11 +740,10 @@ public: return TruncInt32ToInt1(WordLogicAnd( SExtInt1ToInt32( Word64Equal(Word64And(x, GetWord64Constant(~panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), - GetWord64Constant(0))), - WordLogicOr(SExtInt1ToInt32(Word64NotEqual( - Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), GetWord64Constant(0))), - SExtInt1ToInt32(TaggedIsHole(x))))); + WordLogicOr(SExtInt1ToInt32(Word64NotEqual( + Word64And(x, GetWord64Constant(panda::ecmascript::JSTaggedValue::TAG_SPECIAL_MASK)), + GetWord64Constant(0))), SExtInt1ToInt32(TaggedIsHole(x))))); } AddrShift TaggedIsHeapObject(AddrShift x) @@ -1042,10 +1041,10 @@ public: AddrShift bitfieldOffset = GetPtrConstant(panda::ecmascript::JSHClass::BIT_FIELD_OFFSET); AddrShift oldValue = Load(INT64_TYPE, hclass, bitfieldOffset); Store(INT64_TYPE, hclass, bitfieldOffset, - Word64Or(Word64And(oldValue, - GetWord64Constant(~panda::ecmascript::JSHClass::ElementRepresentationBits::Mask())), - Word64LSR(value, GetWord64Constant( - panda::ecmascript::JSHClass::ElementRepresentationBits::START_BIT)))); + Word64Or(Word64And(oldValue, + GetWord64Constant(~panda::ecmascript::JSHClass::ElementRepresentationBits::Mask())), + Word64LSR(value, GetWord64Constant( + panda::ecmascript::JSHClass::ElementRepresentationBits::START_BIT)))); } void UpdateValueAndAttributes(AddrShift elements, AddrShift index, AddrShift value, AddrShift attr) diff --git a/ecmascript/compiler/stub_aot_compiler.cpp b/ecmascript/compiler/stub_aot_compiler.cpp index 84dbf75ab3..768cac749a 100644 --- a/ecmascript/compiler/stub_aot_compiler.cpp +++ b/ecmascript/compiler/stub_aot_compiler.cpp @@ -115,7 +115,7 @@ void StubAotCompiler::BuildStubModule(panda::ecmascript::StubModule *module) pipeline.RunPass(i); } } - + LLVMModuleAssembler assembler(&stubModule); assembler.AssembleModule(); assembler.CopyAssembleCodeToModule(module); diff --git a/ecmascript/compiler/stub_descriptor.cpp b/ecmascript/compiler/stub_descriptor.cpp index c4469c5ebb..0d627b897d 100644 --- a/ecmascript/compiler/stub_descriptor.cpp +++ b/ecmascript/compiler/stub_descriptor.cpp @@ -30,7 +30,7 @@ namespace kungfu { CALL_STUB_INIT_DESCRIPTOR(FastAdd) { // 2 : 2 input parameters - static StubDescriptor fastAdd("FastAdd", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + static StubDescriptor fastAdd("FastAdd", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); *descriptor = fastAdd; // 2 : 2 input parameters std::array params = { @@ -43,7 +43,7 @@ CALL_STUB_INIT_DESCRIPTOR(FastAdd) CALL_STUB_INIT_DESCRIPTOR(FastSub) { // 2 : 2 input parameters - static StubDescriptor fastSub("FastSub", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + static StubDescriptor fastSub("FastSub", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); *descriptor = fastSub; // 2 : 2 input parameters std::array params = { @@ -56,7 +56,7 @@ CALL_STUB_INIT_DESCRIPTOR(FastSub) CALL_STUB_INIT_DESCRIPTOR(FastMul) { // 2 : 2 input parameters - static StubDescriptor fastMul("FastMul", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + static StubDescriptor fastMul("FastMul", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); *descriptor = fastMul; // 2 : 2 input parameters std::array params = { @@ -69,7 +69,7 @@ CALL_STUB_INIT_DESCRIPTOR(FastMul) CALL_STUB_INIT_DESCRIPTOR(FastDiv) { // 2 : 2 input parameters - static StubDescriptor fastDiv("FastDiv", 0, 2, DEFAULT_ORDER, UINT64_TYPE); + static StubDescriptor fastDiv("FastDiv", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); *descriptor = fastDiv; // 2 : 2 input parameters std::array params = { @@ -94,7 +94,7 @@ CALL_STUB_INIT_DESCRIPTOR(IsSpecialIndexedObjForGet) {} CALL_STUB_INIT_DESCRIPTOR(GetElement) { // 3 : 3 input parameters - static StubDescriptor getElement("GetElement", 0, 3, DEFAULT_ORDER, UINT64_TYPE); + static StubDescriptor getElement("GetElement", 0, 3, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); *descriptor = getElement; // 3 : 3 input parameters std::array params = { @@ -108,7 +108,7 @@ CALL_STUB_INIT_DESCRIPTOR(GetElement) CALL_STUB_INIT_DESCRIPTOR(SetElement) { // 5 : 5 input parameters - static StubDescriptor setElement("SetElement", 0, 5, DEFAULT_ORDER, BOOL_TYPE); + static StubDescriptor setElement("SetElement", 0, 5, ArgumentsOrder::DEFAULT_ORDER, BOOL_TYPE); *descriptor = setElement; // 5 : 5 input parameters std::array params = { @@ -139,7 +139,7 @@ CALL_STUB_INIT_DESCRIPTOR(FindOwnProperty) {} CALL_STUB_INIT_DESCRIPTOR(FindOwnElement) { // 3 : 3 input parameters - static StubDescriptor findOwnElement("FindOwnElement", 0, 3, DEFAULT_ORDER, UINT64_TYPE); + static StubDescriptor findOwnElement("FindOwnElement", 0, 3, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); *descriptor = findOwnElement; // 3 : 3 input parameters std::array params = { @@ -157,7 +157,7 @@ CALL_STUB_INIT_DESCRIPTOR(FindOwnProperty2) {} CALL_STUB_INIT_DESCRIPTOR(FindOwnElement2) { // 6 : 6 input parameters - static StubDescriptor findOwnElement2("FindOwnElement2", 0, 6, DEFAULT_ORDER, UINT64_TYPE); + static StubDescriptor findOwnElement2("FindOwnElement2", 0, 6, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE); *descriptor = findOwnElement2; // 6 : 6 input parameters std::array params = { @@ -170,7 +170,7 @@ CALL_STUB_INIT_DESCRIPTOR(FindOwnElement2) CALL_STUB_INIT_DESCRIPTOR(AddElementInternal) { // 5 : 5 input parameters - static StubDescriptor addElementInternal("AddElementInternal", 0, 5, DEFAULT_ORDER, BOOL_TYPE); + static StubDescriptor addElementInternal("AddElementInternal", 0, 5, ArgumentsOrder::DEFAULT_ORDER, BOOL_TYPE); *descriptor = addElementInternal; // 5 : 5 input parameters std::array params = { @@ -178,13 +178,13 @@ CALL_STUB_INIT_DESCRIPTOR(AddElementInternal) MachineType::UINT64_TYPE, MachineType::UINT32_TYPE, }; descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(CallSetter) { // 5 : 5 input parameters - static StubDescriptor callSetter("CallSetter", 0, 5, DEFAULT_ORDER, NONE_TYPE); + static StubDescriptor callSetter("CallSetter", 0, 5, ArgumentsOrder::DEFAULT_ORDER, NONE_TYPE); *descriptor = callSetter; // 5 : 5 input parameters std::array params = { @@ -192,13 +192,13 @@ CALL_STUB_INIT_DESCRIPTOR(CallSetter) MachineType::UINT64_TYPE, MachineType::BOOL_TYPE, }; descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(CallGetter) { // 3 : 3 input parameters - static StubDescriptor callGetter("CallGetter", 0, 3, DEFAULT_ORDER, NONE_TYPE); + static StubDescriptor callGetter("CallGetter", 0, 3, ArgumentsOrder::DEFAULT_ORDER, NONE_TYPE); *descriptor = callGetter; // 3 : 3 input parameters std::array params = { @@ -207,13 +207,13 @@ CALL_STUB_INIT_DESCRIPTOR(CallGetter) MachineType::UINT64_TYPE, }; descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(AccessorGetter) { // 3 : 3 input parameters - static StubDescriptor accessorGetter("AccessorGetter", 0, 3, DEFAULT_ORDER, NONE_TYPE); + static StubDescriptor accessorGetter("AccessorGetter", 0, 3, ArgumentsOrder::DEFAULT_ORDER, NONE_TYPE); *descriptor = accessorGetter; // 3 : 3 input parameters std::array params = { @@ -222,13 +222,13 @@ CALL_STUB_INIT_DESCRIPTOR(AccessorGetter) MachineType::UINT64_TYPE, }; descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(ThrowTypeError) { // 2 : 2 input parameters - static StubDescriptor throwTypeError("ThrowTypeError", 0, 2, DEFAULT_ORDER, NONE_TYPE); + static StubDescriptor throwTypeError("ThrowTypeError", 0, 2, ArgumentsOrder::DEFAULT_ORDER, NONE_TYPE); *descriptor = throwTypeError; // 2 : 2 input parameters std::array params = { @@ -236,13 +236,13 @@ CALL_STUB_INIT_DESCRIPTOR(ThrowTypeError) MachineType::UINT32_TYPE, }; descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(JSProxySetProperty) { // 6 : 6 input parameters - static StubDescriptor jsproxySetproperty("JSProxySetProperty", 0, 6, DEFAULT_ORDER, BOOL_TYPE); + static StubDescriptor jsproxySetproperty("JSProxySetProperty", 0, 6, ArgumentsOrder::DEFAULT_ORDER, BOOL_TYPE); *descriptor = jsproxySetproperty; // 6 : 6 input parameters std::array params = { @@ -250,13 +250,13 @@ CALL_STUB_INIT_DESCRIPTOR(JSProxySetProperty) MachineType::UINT64_TYPE, MachineType::UINT64_TYPE, MachineType::BOOL_TYPE, }; descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } CALL_STUB_INIT_DESCRIPTOR(GetHash32) { // 2 : 2 input parameters - static StubDescriptor getHash32("GetHash32", 0, 2, DEFAULT_ORDER, UINT32_TYPE); + static StubDescriptor getHash32("GetHash32", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT32_TYPE); *descriptor = getHash32; // 2 : 2 input parameters std::array params = { @@ -264,7 +264,7 @@ CALL_STUB_INIT_DESCRIPTOR(GetHash32) MachineType::UINT32_TYPE, }; descriptor->SetParameters(params.data()); - descriptor->SetStubKind(StubDescriptor::RUNTIME_STUB); + descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB); } void FastStubDescriptors::InitializeStubDescriptors() diff --git a/ecmascript/compiler/stub_descriptor.h b/ecmascript/compiler/stub_descriptor.h index f186dd4d8f..c921dac73b 100644 --- a/ecmascript/compiler/stub_descriptor.h +++ b/ecmascript/compiler/stub_descriptor.h @@ -24,13 +24,13 @@ #include "llvm-c/Types.h" namespace kungfu { -enum ArgumentsOrder { +enum class ArgumentsOrder { DEFAULT_ORDER, // Push Arguments in stack from right -> left }; class StubDescriptor { public: - enum CallStubKind { + enum class CallStubKind { CODE_STUB, RUNTIME_STUB, }; @@ -130,10 +130,10 @@ public: private: std::string name_; - CallStubKind kind_ {CODE_STUB}; + CallStubKind kind_ {CallStubKind::CODE_STUB}; int flags_ {0}; int paramCounter_ {0}; - ArgumentsOrder order_ {DEFAULT_ORDER}; + ArgumentsOrder order_ {ArgumentsOrder::DEFAULT_ORDER}; MachineType returnType_ {MachineType::NONE_TYPE}; std::unique_ptr> paramsType_ {nullptr}; diff --git a/ecmascript/compiler/tests/stub_tests.cpp b/ecmascript/compiler/tests/stub_tests.cpp index 515f2a5538..ef1cff2c84 100644 --- a/ecmascript/compiler/tests/stub_tests.cpp +++ b/ecmascript/compiler/tests/stub_tests.cpp @@ -179,7 +179,8 @@ HWTEST_F_L0(StubTest, PhiGateTest) class CallPhiStub : public Stub { public: explicit CallPhiStub(Circuit *circuit) - : Stub("CallPhi", 1, circuit), phi_descriptor_("phi", 0, 1, DEFAULT_ORDER, MachineType::INT32_TYPE) + : Stub("CallPhi", 1, circuit), + phi_descriptor_("phi", 0, 1, ArgumentsOrder::DEFAULT_ORDER, MachineType::INT32_TYPE) { std::array *params = new std::array(); (*params)[0] = MachineType::INT32_TYPE; diff --git a/ecmascript/stub_module.h b/ecmascript/stub_module.h index cc0c666692..a48b841ece 100644 --- a/ecmascript/stub_module.h +++ b/ecmascript/stub_module.h @@ -31,7 +31,7 @@ public: } void Save(const std::string &filename); void Load(JSThread *thread, const std::string &filename); - void SetCode(MachineCode *code)\ + void SetCode(MachineCode *code) { code_ = code; } -- Gitee From f8833efd426b1e8fde08bfbad1b8357cbfcf9e33 Mon Sep 17 00:00:00 2001 From: getingke Date: Thu, 23 Sep 2021 16:35:10 +0800 Subject: [PATCH 5/9] remove circuit_visualizer.cpp Signed-off-by: getingke Change-Id: Ia5cc583a0b68ef739730f562c44caf8429a5511d --- ecmascript/compiler/BUILD.gn | 1 - ecmascript/compiler/circuit_visualizer.cpp | 63 ---------------------- ecmascript/compiler/circuit_visualizer.h | 50 ----------------- ecmascript/compiler/llvm_mcjit_engine.cpp | 16 +++--- 4 files changed, 8 insertions(+), 122 deletions(-) delete mode 100644 ecmascript/compiler/circuit_visualizer.cpp delete mode 100644 ecmascript/compiler/circuit_visualizer.h diff --git a/ecmascript/compiler/BUILD.gn b/ecmascript/compiler/BUILD.gn index b7b288bd7c..1975391b3d 100644 --- a/ecmascript/compiler/BUILD.gn +++ b/ecmascript/compiler/BUILD.gn @@ -42,7 +42,6 @@ ohos_shared_library("libark_jsoptimizer") { sources = [ "circuit.cpp", "circuit_builder.cpp", - "circuit_visualizer.cpp", "fast_stub.cpp", "gate.cpp", "llvm_codegen.cpp", diff --git a/ecmascript/compiler/circuit_visualizer.cpp b/ecmascript/compiler/circuit_visualizer.cpp deleted file mode 100644 index b533cc01cc..0000000000 --- a/ecmascript/compiler/circuit_visualizer.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ -#include "ecmascript/compiler/circuit_visualizer.h" -#include "ecmascript/compiler/circuit.h" -#include "ecmascript/compiler/gate.h" - -namespace kungfu { -#ifndef NDEBUG -void CircuitVisualizer::DumpDFG() {} - -void CircuitVisualizer::PrintGateVisit(Gate *node, std::ostream &os, int depth, int indentation) -{ - for (int i = 0; i < indentation; ++i) { - os << "---"; - } - if (node != nullptr) { - PrintSingleGate(node, os); - } else { - os << "(NULL)"; - return; - } - os << std::endl; - if (depth <= 0) { - return; - } - - if (!node->IsFirstOutNull()) { - Out *curOut = node->GetFirstOut(); - PrintGateVisit(curOut->GetGate(), os, depth - 1, indentation + 1); - while (!curOut->IsNextOutNull()) { - curOut = curOut->GetNextOut(); - PrintGateVisit(curOut->GetGate(), os, depth - 1, indentation + 1); - } - } -} - -void CircuitVisualizer::PrintGate(Gate *node, int depth) -{ - PrintGateVisit(node, std::cout, depth, 0); - std::flush(std::cout); -} - -void CircuitVisualizer::PrintSingleGate(Gate *node, std::ostream &os) -{ - ASSERT(node != nullptr); - (void)os; - node->Print(); -} - -#endif -} // namespace kungfu diff --git a/ecmascript/compiler/circuit_visualizer.h b/ecmascript/compiler/circuit_visualizer.h deleted file mode 100644 index b968082360..0000000000 --- a/ecmascript/compiler/circuit_visualizer.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021 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. - */ - -#ifndef ECMASCRIPT_COMPILER_CIRCUIT_VISUALIZER_H -#define ECMASCRIPT_COMPILER_CIRCUIT_VISUALIZER_H - -#include -#include -#include -#include -#include "circuit.h" -#include "gate.h" - -namespace kungfu { -#ifndef NDEBUG -// This class dump graph in graphviz format -// Option: --compiler-graph-visualizer - -class CircuitVisualizer { -public: - explicit CircuitVisualizer(Circuit *graph) : graph_(graph) {} - - void CreateDumpFile(const char *file_name); - void DumpDFG(); - void PrintGate(Gate *node, int depth); - ~CircuitVisualizer() = default; -private: - void PrintGateVisit(Gate *node, std::ostream &os, int depth, int indentation = 0); - void PrintSingleGate(Gate *node, std::ostream &os); - Circuit *graph_; - std::ofstream dump_output_{nullptr}; - const char *pass_name_{nullptr}; - std::map node_info_; -}; -#endif -} // namespace kungfu - -#endif \ No newline at end of file diff --git a/ecmascript/compiler/llvm_mcjit_engine.cpp b/ecmascript/compiler/llvm_mcjit_engine.cpp index abcc8df721..002a781636 100644 --- a/ecmascript/compiler/llvm_mcjit_engine.cpp +++ b/ecmascript/compiler/llvm_mcjit_engine.cpp @@ -13,12 +13,13 @@ * limitations under the License. */ -#include "ecmascript/compiler/llvm_mcjit_engine.h" +#include "llvm_mcjit_engine.h" #include #include "llvm/IR/LegacyPassManager.h" #include "llvm/ADT/APInt.h" -#include "llvm/IR/Verifier.h" +#include "llvm/CodeGen/BuiltinGCs.h" +#include "llvm/CodeGen/BuiltinGCs.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/IR/Argument.h" @@ -31,22 +32,21 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" -#include "llvm/CodeGen/BuiltinGCs.h" +#include "llvm/IR/Verifier.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Host.h" #include "llvm/Support/TargetSelect.h" #include "llvm-c/Analysis.h" #include "llvm-c/Core.h" #include "llvm-c/Target.h" #include "llvm-c/Transforms/PassManagerBuilder.h" #include "llvm-c/Transforms/Scalar.h" -#include "llvm/CodeGen/BuiltinGCs.h" - #include "llvm/Transforms/Scalar.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/Host.h" #include "llvm-c/Disassembler.h" #include "llvm-c/DisassemblerTypes.h" -#include "llvm/IRReader/IRReader.h" + namespace kungfu { -- Gitee From 1d1a9cffe18e22208e897a6950b59657d0907a0d Mon Sep 17 00:00:00 2001 From: getingke Date: Thu, 23 Sep 2021 18:28:05 +0800 Subject: [PATCH 6/9] fixed for gn format Signed-off-by: getingke Change-Id: I29c7ce9fa6808bab29ee8e23c2207315d01b892b Signed-off-by: getingke --- ecmascript/compiler/BUILD.gn | 4 ++-- ecmascript/compiler/tests/BUILD.gn | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ecmascript/compiler/BUILD.gn b/ecmascript/compiler/BUILD.gn index 1975391b3d..8b32d8264e 100644 --- a/ecmascript/compiler/BUILD.gn +++ b/ecmascript/compiler/BUILD.gn @@ -49,8 +49,8 @@ ohos_shared_library("libark_jsoptimizer") { "llvm_mcjit_engine.cpp", "llvm_stackmap_parse.cpp", "scheduler.cpp", - "stub_descriptor.cpp", "stub.cpp", + "stub_descriptor.cpp", "type.cpp", "verifier.cpp", ] @@ -167,4 +167,4 @@ ohos_executable("ark_stub_opt") { output_name = "ark_stub_opt" subsystem_name = "ark" -} \ No newline at end of file +} diff --git a/ecmascript/compiler/tests/BUILD.gn b/ecmascript/compiler/tests/BUILD.gn index a1cd3e6c94..9d0952fd26 100644 --- a/ecmascript/compiler/tests/BUILD.gn +++ b/ecmascript/compiler/tests/BUILD.gn @@ -108,7 +108,6 @@ host_unittest_action("StubTest") { "LLVMTransformUtils", "LLVMAArch64Utils", "LLVMARMUtils", - #"LLVMX86Utils", "LLVMIRReader", ] -- Gitee From ff82e151542f4a1f888f9056eb282d7f8059db74 Mon Sep 17 00:00:00 2001 From: getingke Date: Thu, 23 Sep 2021 19:32:53 +0800 Subject: [PATCH 7/9] fixed for codestyle check Signed-off-by: getingke Change-Id: I3a6a7536a7f079726fd79a4d10d906632eb21644 --- ecmascript/compiler/llvm_ir_builder.cpp | 1 - ecmascript/compiler/llvm_mcjit_engine.cpp | 9 +++------ ecmascript/compiler/stub.h | 18 +++++++++--------- ecmascript/compiler/verifier.cpp | 1 - 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/ecmascript/compiler/llvm_ir_builder.cpp b/ecmascript/compiler/llvm_ir_builder.cpp index 204494a9e8..4d9d7489de 100644 --- a/ecmascript/compiler/llvm_ir_builder.cpp +++ b/ecmascript/compiler/llvm_ir_builder.cpp @@ -1142,5 +1142,4 @@ LLVMTypeRef LLVMStubModule::ConvertLLVMTypeFromMachineType(MachineType type) }; return machineTypeMap[type]; } - } // namespace kungfu diff --git a/ecmascript/compiler/llvm_mcjit_engine.cpp b/ecmascript/compiler/llvm_mcjit_engine.cpp index 002a781636..1ced16e1dd 100644 --- a/ecmascript/compiler/llvm_mcjit_engine.cpp +++ b/ecmascript/compiler/llvm_mcjit_engine.cpp @@ -19,7 +19,6 @@ #include "llvm/IR/LegacyPassManager.h" #include "llvm/ADT/APInt.h" #include "llvm/CodeGen/BuiltinGCs.h" -#include "llvm/CodeGen/BuiltinGCs.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/GenericValue.h" #include "llvm/IR/Argument.h" @@ -34,20 +33,18 @@ #include "llvm/IR/Type.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Host.h" #include "llvm/Support/TargetSelect.h" #include "llvm-c/Analysis.h" #include "llvm-c/Core.h" +#include "llvm-c/Disassembler.h" +#include "llvm-c/DisassemblerTypes.h" #include "llvm-c/Target.h" #include "llvm-c/Transforms/PassManagerBuilder.h" #include "llvm-c/Transforms/Scalar.h" -#include "llvm/Transforms/Scalar.h" -#include "llvm-c/Disassembler.h" -#include "llvm-c/DisassemblerTypes.h" - - namespace kungfu { static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, [[maybe_unused]] unsigned alignment, diff --git a/ecmascript/compiler/stub.h b/ecmascript/compiler/stub.h index 00a0785d35..7d5b54785a 100644 --- a/ecmascript/compiler/stub.h +++ b/ecmascript/compiler/stub.h @@ -310,8 +310,8 @@ public: bool IsSelector(const Gate *gate) const { - return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS && - gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64; + return gate->GetOpCode() >= OpCode::VALUE_SELECTOR_JS + && gate->GetOpCode() <= OpCode::VALUE_SELECTOR_FLOAT64; } uint32_t GetId() const @@ -341,7 +341,7 @@ public: Environment *env_; }; - explicit Stub(const char *name, int argCount, Circuit *circuit) + explicit Stub(const char *name, int argCount, Circuit *circuit) : env_(argCount, circuit), methodName_(name) { } @@ -1040,11 +1040,11 @@ public: { AddrShift bitfieldOffset = GetPtrConstant(panda::ecmascript::JSHClass::BIT_FIELD_OFFSET); AddrShift oldValue = Load(INT64_TYPE, hclass, bitfieldOffset); - Store(INT64_TYPE, hclass, bitfieldOffset, - Word64Or(Word64And(oldValue, - GetWord64Constant(~panda::ecmascript::JSHClass::ElementRepresentationBits::Mask())), - Word64LSR(value, GetWord64Constant( - panda::ecmascript::JSHClass::ElementRepresentationBits::START_BIT)))); + AddrShift oldWithMask = Word64And(oldValue, + GetWord64Constant(~panda::ecmascript::JSHClass::ElementRepresentationBits::Mask())); + AddrShift newValue = Word64LSR(value, GetWord64Constant( + panda::ecmascript::JSHClass::ElementRepresentationBits::START_BIT)); + Store(INT64_TYPE, hclass, bitfieldOffset, Word64Or(oldWithMask, newValue)); } void UpdateValueAndAttributes(AddrShift elements, AddrShift index, AddrShift value, AddrShift attr) @@ -1169,7 +1169,7 @@ public: return env_.GetCircuitBuilder().NewArithMeticGate(OpCode(OpCode::TRUNC_INT32_TO_INT1), x); } - int NextVariableId() + int NextVariableId() { return nextVariableId_++; } diff --git a/ecmascript/compiler/verifier.cpp b/ecmascript/compiler/verifier.cpp index 96fb1b882a..66749c8bee 100644 --- a/ecmascript/compiler/verifier.cpp +++ b/ecmascript/compiler/verifier.cpp @@ -17,7 +17,6 @@ #include #include -#include #include "ecmascript/compiler/scheduler.h" -- Gitee From b4d1cc291ce6cd74feeee8fc2de13cd5dbe583ed Mon Sep 17 00:00:00 2001 From: getingke Date: Thu, 23 Sep 2021 20:52:33 +0800 Subject: [PATCH 8/9] fixed for remove stub tests Signed-off-by: getingke Change-Id: I154ae02982a98606bc111082b15d4a6d24d71b22 --- BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/BUILD.gn b/BUILD.gn index ae8a7ba665..fbbfe4760b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -65,7 +65,6 @@ group("ark_js_host_unittest") { deps += [ "//ark/js_runtime:libark_jsruntime(${host_toolchain})", "//ark/js_runtime/ecmascript/builtins/tests:host_unittest", - "//ark/js_runtime/ecmascript/compiler/tests:host_unittest", "//ark/js_runtime/ecmascript/hprof/tests:host_unittest", "//ark/js_runtime/ecmascript/js_vm:ark_js_vm(${host_toolchain})", "//ark/js_runtime/ecmascript/napi/test:host_unittest", -- Gitee From 7ff677936cd8b3e0030e36b469b20706c5e7b033 Mon Sep 17 00:00:00 2001 From: getingke Date: Fri, 24 Sep 2021 11:47:27 +0800 Subject: [PATCH 9/9] fixed for review comments by wuzhefeng Signed-off-by: getingke Change-Id: I5debcfcc4450fc22e33549911d8c557b2a671a35 --- ecmascript/compiler/llvm_codegen.cpp | 8 +- ecmascript/compiler/llvm_codegen.h | 4 +- ecmascript/compiler/llvm_mcjit_engine.cpp | 28 +++--- ecmascript/compiler/llvm_mcjit_engine.h | 26 +++--- ecmascript/compiler/stub.cpp | 40 ++++----- ecmascript/compiler/stub.h | 104 +++++++++++----------- ecmascript/compiler/stub_aot_compiler.cpp | 30 +++---- ecmascript/compiler/tests/stub_tests.cpp | 38 ++++---- 8 files changed, 137 insertions(+), 141 deletions(-) diff --git a/ecmascript/compiler/llvm_codegen.cpp b/ecmascript/compiler/llvm_codegen.cpp index 7ad27f434a..f58bef33ab 100644 --- a/ecmascript/compiler/llvm_codegen.cpp +++ b/ecmascript/compiler/llvm_codegen.cpp @@ -29,13 +29,13 @@ void LLVMCodeGeneratorImpl::GenerateCodeForStub(Circuit *circuit, const ControlF void LLVMModuleAssembler::AssembleModule() { - compiler_.Run(); + assembler_.Run(); } void LLVMModuleAssembler::CopyAssembleCodeToModule(StubModule *module) { - auto codeBuff = reinterpret_cast
(compiler_.GetCodeBuffer()); - auto engine = compiler_.GetEngine(); + auto codeBuff = reinterpret_cast
(assembler_.GetCodeBuffer()); + auto engine = assembler_.GetEngine(); for (int i = 0; i < FAST_STUB_MAXCOUNT; i++) { auto stubfunction = stubmodule_->GetStubFunction(i); if (stubfunction != nullptr) { @@ -44,7 +44,7 @@ void LLVMModuleAssembler::CopyAssembleCodeToModule(StubModule *module) } } - auto codeSize = compiler_.GetCodeSize(); + auto codeSize = assembler_.GetCodeSize(); MachineCode *code = reinterpret_cast(new char(sizeof(MachineCode) + codeSize)); code->SetInstructionSizeInBytes(nullptr, JSTaggedValue(codeSize), SKIP_BARRIER); diff --git a/ecmascript/compiler/llvm_codegen.h b/ecmascript/compiler/llvm_codegen.h index bdbc4d5c32..f55463005b 100644 --- a/ecmascript/compiler/llvm_codegen.h +++ b/ecmascript/compiler/llvm_codegen.h @@ -38,13 +38,13 @@ private: class LLVMModuleAssembler { public: - explicit LLVMModuleAssembler(LLVMStubModule *module) : stubmodule_(module), compiler_(module->GetModule()) {} + explicit LLVMModuleAssembler(LLVMStubModule *module) : stubmodule_(module), assembler_(module->GetModule()) {} void AssembleModule(); void CopyAssembleCodeToModule(panda::ecmascript::StubModule *module); private: LLVMStubModule *stubmodule_; - LLVMMcJitEngine compiler_; + LLVMAssembler assembler_; }; } // namespace kungfu #endif // ECMASCRIPT_COMPILER_LLVM_CODEGEN_H \ No newline at end of file diff --git a/ecmascript/compiler/llvm_mcjit_engine.cpp b/ecmascript/compiler/llvm_mcjit_engine.cpp index 1ced16e1dd..cacc2213e4 100644 --- a/ecmascript/compiler/llvm_mcjit_engine.cpp +++ b/ecmascript/compiler/llvm_mcjit_engine.cpp @@ -51,7 +51,7 @@ static uint8_t *RoundTripAllocateCodeSection(void *object, uintptr_t size, [[may [[maybe_unused]] unsigned sectionID, const char *sectionName) { std::cout << "RoundTripAllocateCodeSection object " << object << " - " << std::endl; - struct CodeState& state = *static_cast(object); + struct CodeInfo& state = *static_cast(object); uint8_t *addr = state.AllocaCodeSection(size, sectionName); std::cout << "RoundTripAllocateCodeSection addr:" << std::hex << reinterpret_cast(addr) << addr << " size:0x" << size << " +" << std::endl; @@ -62,7 +62,7 @@ static uint8_t *RoundTripAllocateDataSection(void *object, uintptr_t size, [[may [[maybe_unused]] unsigned sectionID, const char *sectionName, [[maybe_unused]] LLVMBool isReadOnly) { - struct CodeState& state = *static_cast(object); + struct CodeInfo& state = *static_cast(object); return state.AllocaDataSection(size, sectionName); } @@ -75,18 +75,18 @@ static LLVMBool RoundTripFinalizeMemory(void *object, [[maybe_unused]] char **er static void RoundTripDestroy(void *object) { std::cout << "RoundTripDestroy object " << object << " - " << std::endl; - delete static_cast(object); + delete static_cast(object); } -void LLVMMcJitEngine::UseRoundTripSectionMemoryManager() +void LLVMAssembler::UseRoundTripSectionMemoryManager() { auto sectionMemoryManager = std::make_unique(); options_.MCJMM = - LLVMCreateSimpleMCJITMemoryManager(&codeState_, RoundTripAllocateCodeSection, + LLVMCreateSimpleMCJITMemoryManager(&codeInfo_, RoundTripAllocateCodeSection, RoundTripAllocateDataSection, RoundTripFinalizeMemory, RoundTripDestroy); } -bool LLVMMcJitEngine::BuildMCJITEngine() +bool LLVMAssembler::BuildMCJITEngine() { std::cout << " BuildMCJITEngine - " << std::endl; LLVMBool ret = LLVMCreateMCJITCompilerForModule(&engine_, module_, &options_, sizeof(options_), &error_); @@ -99,7 +99,7 @@ bool LLVMMcJitEngine::BuildMCJITEngine() return true; } -void LLVMMcJitEngine::BuildAndRunPasses() const +void LLVMAssembler::BuildAndRunPasses() const { std::cout << "BuildAndRunPasses - " << std::endl; LLVMPassManagerRef pass = LLVMCreatePassManager(); @@ -112,14 +112,14 @@ void LLVMMcJitEngine::BuildAndRunPasses() const std::cout << "BuildAndRunPasses + " << std::endl; } -LLVMMcJitEngine::LLVMMcJitEngine(LLVMModuleRef module): module_(module), engine_(nullptr), +LLVMAssembler::LLVMAssembler(LLVMModuleRef module): module_(module), engine_(nullptr), hostTriple_(""), error_(nullptr) { Initialize(); InitMember(); } -LLVMMcJitEngine::~LLVMMcJitEngine() +LLVMAssembler::~LLVMAssembler() { module_ = nullptr; engine_ = nullptr; @@ -127,7 +127,7 @@ LLVMMcJitEngine::~LLVMMcJitEngine() error_ = nullptr; } -void LLVMMcJitEngine::Run() +void LLVMAssembler::Run() { UseRoundTripSectionMemoryManager(); if (!BuildMCJITEngine()) { @@ -136,7 +136,7 @@ void LLVMMcJitEngine::Run() BuildAndRunPasses(); } -void LLVMMcJitEngine::Initialize() +void LLVMAssembler::Initialize() { #if defined(PANDA_TARGET_AMD64) LLVMInitializeX86TargetInfo(); @@ -162,11 +162,11 @@ static const char *SymbolLookupCallback([[maybe_unused]] void *disInfo, [[maybe_ return nullptr; } -void LLVMMcJitEngine::Disassemble(std::map addr2name) const +void LLVMAssembler::Disassemble(std::map addr2name) const { LLVMDisasmContextRef dcr = LLVMCreateDisasm("x86_64-unknown-linux-gnu", nullptr, 0, nullptr, SymbolLookupCallback); std::cout << "========================================================================" << std::endl; - for (auto it : codeState_.GetCodeInfo()) { + for (auto it : codeInfo_.GetCodeInfo()) { uint8_t *byteSp; uintptr_t numBytes; byteSp = it.first; @@ -198,7 +198,7 @@ void LLVMMcJitEngine::Disassemble(std::map addr2name) con std::cout << "========================================================================" << std::endl; } -void LLVMMcJitEngine::InitMember() +void LLVMAssembler::InitMember() { if (module_ == nullptr) { module_ = LLVMModuleCreateWithName("simple_module"); diff --git a/ecmascript/compiler/llvm_mcjit_engine.h b/ecmascript/compiler/llvm_mcjit_engine.h index 594141ed45..3eaafb206b 100644 --- a/ecmascript/compiler/llvm_mcjit_engine.h +++ b/ecmascript/compiler/llvm_mcjit_engine.h @@ -34,11 +34,11 @@ #include "llvm-c/Transforms/Scalar.h" namespace kungfu { -using ByteBuffer = std::vector; -using BufferList = std::list; -using StringList = std::list; -struct CodeState { - CodeState() : machineCode(nullptr), codeBufferPos(0), stackMapsSection_(nullptr) +struct CodeInfo { + using ByteBuffer = std::vector; + using BufferList = std::list; + using StringList = std::list; + CodeInfo() : machineCode(nullptr), codeBufferPos(0), stackMapsSection_(nullptr) { Reset(); static constexpr int prot = PROT_READ | PROT_WRITE | PROT_EXEC; // NOLINT(hicpp-signed-bitwise) @@ -46,7 +46,7 @@ struct CodeState { machineCode = static_cast(mmap(nullptr, MAX_MACHINE_CODE_SIZE, prot, flags, -1, 0)); std::cerr << std::hex << "machineCode : " << reinterpret_cast(machineCode) << std::endl; } - ~CodeState() + ~CodeInfo() { Reset(); munmap(machineCode, MAX_MACHINE_CODE_SIZE); @@ -125,10 +125,10 @@ private: /* stack map */ uint8_t *stackMapsSection_ {nullptr}; }; -class LLVMMcJitEngine { +class LLVMAssembler { public: - explicit LLVMMcJitEngine(LLVMModuleRef module); - virtual ~LLVMMcJitEngine(); + explicit LLVMAssembler(LLVMModuleRef module); + virtual ~LLVMAssembler(); void Run(); const LLVMExecutionEngineRef &GetEngine() { @@ -137,16 +137,16 @@ public: void Disassemble(std::map addr2name = std::map()) const; uint8_t *GetStackMapsSection() const { - return codeState_.GetStackMapsSection(); + return codeInfo_.GetStackMapsSection(); } int GetCodeSize() const { - return codeState_.GetCodeSize(); + return codeInfo_.GetCodeSize(); } uint8_t *GetCodeBuffer() const { - return codeState_.GetCodeBuff(); + return codeInfo_.GetCodeBuff(); } private: @@ -162,7 +162,7 @@ private: LLVMExecutionEngineRef engine_; std::string hostTriple_; char *error_; - struct CodeState codeState_; + struct CodeInfo codeInfo_; }; } // namespace kungfu #endif // ECMASCRIPT_COMPILER_LLVM_MCJINT_ENGINE_H diff --git a/ecmascript/compiler/stub.cpp b/ecmascript/compiler/stub.cpp index 28f0537814..a3b0d94513 100644 --- a/ecmascript/compiler/stub.cpp +++ b/ecmascript/compiler/stub.cpp @@ -21,17 +21,17 @@ #include "libpandabase/macros.h" namespace kungfu { -using StubLabelImpl = Stub::StubLabel::StubLabelImpl; +using LabelImpl = Stub::Label::LabelImpl; -Stub::StubLabel::StubLabel(Environment *env) +Stub::Label::Label(Environment *env) { - impl_ = env->NewStubLabel(env); + impl_ = env->NewLabel(env); } -AddrShift Stub::StubVariable::AddPhiOperand(AddrShift val) +AddrShift Stub::Variable::AddPhiOperand(AddrShift val) { ASSERT(IsSelector(val)); - StubLabel label = env_->GetLabelFromSelector(val); + Label label = env_->GetLabelFromSelector(val); size_t idx = 0; for (auto pred : label.GetPredecessors()) { idx++; @@ -41,13 +41,13 @@ AddrShift Stub::StubVariable::AddPhiOperand(AddrShift val) return TryRemoveTrivialPhi(val); } -AddrShift Stub::StubVariable::AddOperandToSelector(AddrShift val, size_t idx, AddrShift in) +AddrShift Stub::Variable::AddOperandToSelector(AddrShift val, size_t idx, AddrShift in) { env_->GetCircuit()->NewIn(val, idx, in); return val; } -AddrShift Stub::StubVariable::TryRemoveTrivialPhi(AddrShift phiVal) +AddrShift Stub::Variable::TryRemoveTrivialPhi(AddrShift phiVal) { Gate *phi = env_->GetCircuit()->LoadGatePtr(phiVal); Gate *same = nullptr; @@ -98,7 +98,7 @@ AddrShift Stub::StubVariable::TryRemoveTrivialPhi(AddrShift phiVal) return env_->GetCircuit()->SaveGatePtr(same); } -void Stub::StubVariable::RerouteOuts(const std::vector &outs, Gate *newGate) +void Stub::Variable::RerouteOuts(const std::vector &outs, Gate *newGate) { // reroute all outs to new node for (auto out : outs) { @@ -107,7 +107,7 @@ void Stub::StubVariable::RerouteOuts(const std::vector &outs, Gate *newGa } } -void StubLabelImpl::Seal() +void LabelImpl::Seal() { for (auto &[variable, gate] : incompletePhis_) { variable->AddPhiOperand(gate); @@ -115,12 +115,12 @@ void StubLabelImpl::Seal() isSealed_ = true; } -void StubLabelImpl::WriteVariable(StubVariable *var, AddrShift value) +void LabelImpl::WriteVariable(Variable *var, AddrShift value) { valueMap_[var] = value; } -AddrShift StubLabelImpl::ReadVariable(StubVariable *var) +AddrShift LabelImpl::ReadVariable(Variable *var) { if (valueMap_.find(var) != valueMap_.end()) { return valueMap_.at(var); @@ -128,7 +128,7 @@ AddrShift StubLabelImpl::ReadVariable(StubVariable *var) return ReadVariableRecursive(var); } -AddrShift StubLabelImpl::ReadVariableRecursive(StubVariable *var) +AddrShift LabelImpl::ReadVariableRecursive(Variable *var) { AddrShift val; OpCode opcode = CircuitBuilder::GetSelectOpCodeFromMachineType(var->Type()); @@ -137,13 +137,13 @@ AddrShift StubLabelImpl::ReadVariableRecursive(StubVariable *var) int valueCounts = static_cast(this->predecessors.size()) + 1; val = env_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, valueCounts); - env_->AddSelectorToLabel(val, StubLabel(this)); + env_->AddSelectorToLabel(val, Label(this)); incompletePhis_[var] = val; } else if (predecessors.size() == 1) { val = predecessors[0]->ReadVariable(var); } else { val = env_->GetCircuitBuilder().NewSelectorGate(opcode, predeControl_, this->predecessors.size()); - env_->AddSelectorToLabel(val, StubLabel(this)); + env_->AddSelectorToLabel(val, Label(this)); WriteVariable(var, val); val = var->AddPhiOperand(val); } @@ -151,7 +151,7 @@ AddrShift StubLabelImpl::ReadVariableRecursive(StubVariable *var) return val; } -void StubLabelImpl::Bind() +void LabelImpl::Bind() { ASSERT(!predecessors.empty()); if (IsNeedSeal()) { @@ -160,7 +160,7 @@ void StubLabelImpl::Bind() } } -void StubLabelImpl::MergeAllControl() +void LabelImpl::MergeAllControl() { if (predecessors.size() < 2) { // 2 : Loop Head only support two predecessors return; @@ -188,21 +188,21 @@ void StubLabelImpl::MergeAllControl() control_ = merge; } -void StubLabelImpl::AppendPredecessor(StubLabelImpl *predecessor) +void LabelImpl::AppendPredecessor(LabelImpl *predecessor) { if (predecessor != nullptr) { predecessors.push_back(predecessor); } } -bool StubLabelImpl::IsNeedSeal() const +bool LabelImpl::IsNeedSeal() const { auto control = env_->GetCircuit()->LoadGatePtr(predeControl_); auto numsInList = control->GetOpCode().GetOpCodeNumInsArray(control->GetBitField()); return predecessors.size() >= numsInList[0]; } -bool StubLabelImpl::IsLoopHead() const +bool LabelImpl::IsLoopHead() const { return env_->GetCircuit()->IsLoopHead(predeControl_); } @@ -213,7 +213,7 @@ Stub::Environment::Environment(size_t arguments, Circuit *circuit) for (size_t i = 0; i < arguments; i++) { arguments_[i] = builder_.NewArguments(i); } - entry_ = StubLabel(NewStubLabel(this, Circuit::GetCircuitRoot(OpCode(OpCode::STATE_ENTRY)))); + entry_ = Label(NewLabel(this, Circuit::GetCircuitRoot(OpCode(OpCode::STATE_ENTRY)))); currentLabel_ = &entry_; currentLabel_->Seal(); } diff --git a/ecmascript/compiler/stub.h b/ecmascript/compiler/stub.h index 7d5b54785a..93bf7bac0b 100644 --- a/ecmascript/compiler/stub.h +++ b/ecmascript/compiler/stub.h @@ -27,37 +27,34 @@ namespace kungfu { // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) -#define DEFVARIABLE(varname, type, val) Stub::StubVariable varname(GetEnvironment(), type, NextVariableId(), val) +#define DEFVARIABLE(varname, type, val) Stub::Variable varname(GetEnvironment(), type, NextVariableId(), val) class Stub { public: class Environment; - class StubLabel; - class StubVariable; - using Label = StubLabel; - using Variable = StubVariable; + class Label; + class Variable; - class StubLabel { + class Label { public: - class StubLabelImpl { + class LabelImpl { public: - StubLabelImpl(Environment *env, AddrShift control) + LabelImpl(Environment *env, AddrShift control) : env_(env), control_(control), predeControl_(-1), isSealed_(false) { } - ~StubLabelImpl() = default; + ~LabelImpl() = default; - NO_MOVE_SEMANTIC(StubLabelImpl); - NO_COPY_SEMANTIC(StubLabelImpl); - using Variable = StubVariable; + NO_MOVE_SEMANTIC(LabelImpl); + NO_COPY_SEMANTIC(LabelImpl); void Seal(); void WriteVariable(Variable *var, AddrShift value); AddrShift ReadVariable(Variable *var); void Bind(); void MergeAllControl(); - void AppendPredecessor(StubLabelImpl *predecessor); - std::vector GetPredecessors() const + void AppendPredecessor(LabelImpl *predecessor); + std::vector GetPredecessors() const { return predecessors; } @@ -100,20 +97,19 @@ public: AddrShift predeControl_; std::vector otherPredeControls_; bool isSealed_; - std::map valueMap_; + std::map valueMap_; std::vector phi; - std::vector predecessors; - std::map incompletePhis_; + std::vector predecessors; + std::map incompletePhis_; }; - explicit StubLabel() = default; - explicit StubLabel(Environment *env); - explicit StubLabel(StubLabelImpl *impl) : impl_(impl) {} - ~StubLabel() = default; - using Variable = StubVariable; - StubLabel(StubLabel const &label) = default; - StubLabel &operator=(StubLabel const &label) = default; - StubLabel(StubLabel &&label) = default; - StubLabel &operator=(StubLabel &&label) = default; + explicit Label() = default; + explicit Label(Environment *env); + explicit Label(LabelImpl *impl) : impl_(impl) {} + ~Label() = default; + Label(Label const &label) = default; + Label &operator=(Label const &label) = default; + Label(Label &&label) = default; + Label &operator=(Label &&label) = default; void Seal() { @@ -140,16 +136,16 @@ public: impl_->MergeAllControl(); } - void AppendPredecessor(const StubLabel *predecessor) + void AppendPredecessor(const Label *predecessor) { impl_->AppendPredecessor(predecessor->GetRawLabel()); } - std::vector GetPredecessors() const + std::vector