diff --git a/plugins/ets/tests/ets_test_suite/gc/CMakeLists.txt b/plugins/ets/tests/ets_test_suite/gc/CMakeLists.txt index cd959586e47a26c7e6db662da19689f03a82cbae..3bd182546cbbb6568be85d0b5e7d559f60209a3b 100644 --- a/plugins/ets/tests/ets_test_suite/gc/CMakeLists.txt +++ b/plugins/ets/tests/ets_test_suite/gc/CMakeLists.txt @@ -49,6 +49,40 @@ function(add_ets_gc_test) endif() endfunction() +set(OUTPUT_ABC ${CMAKE_CURRENT_BINARY_DIR}/test_heap.abc) +compile_ets_code( + ${CMAKE_CURRENT_SOURCE_DIR}/test_heap.ets + ${OUTPUT_ABC} + test_heap_abc +) + +panda_add_gtest( + NO_CORES + NAME test_heap + SOURCES + test_heap.cpp + LIBRARIES + arkruntime + arkbase + DEPS_TARGETS + test_heap_abc + etsstdlib + SANITIZERS + ${PANDA_SANITIZERS_LIST} +) + +target_compile_definitions(test_heap + PUBLIC STDLIB_ABC=${PANDA_BINARY_ROOT}/plugins/ets/etsstdlib.abc + PUBLIC PATH_ABC=${OUTPUT_ABC} +) +target_include_directories(test_heap + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + PUBLIC ${PANDA_ROOT} + PRIVATE ${PANDA_BINARY_ROOT}/libpandabase/panda_gen_options/generated +) +target_compile_options(test_heap PUBLIC "-Wno-ignored-attributes") +add_dependencies(ets_test_suite_gc test_heap) + add_ets_gc_test(FILE pin_object.ets OPTIONS "--gc-type=g1-gc" "--gc-trigger-type=debug-never" MODE "INT") add_ets_gc_test(FILE space_type_test.ets OPTIONS "--gc-type=g1-gc" "--gc-trigger-type=debug-never" MODE "INT") add_ets_gc_test(FILE weak_ref_test.ets OPTIONS "--gc-type=g1-gc" "--gc-trigger-type=debug-never" MODE "INT") diff --git a/plugins/ets/tests/ets_test_suite/gc/test_heap.cpp b/plugins/ets/tests/ets_test_suite/gc/test_heap.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1271d21aa39b29587e3fbe7e19a29e757a4a6ce --- /dev/null +++ b/plugins/ets/tests/ets_test_suite/gc/test_heap.cpp @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "base_options.h" +#include "plugins/ets/runtime/ets_vm.h" +#include "plugins/ets/runtime/napi/ets_napi.h" +#include "plugins/ets/runtime/napi/ets_napi_native_interface.h" +#include "plugins/ets/runtime/napi/ets_scoped_objects_fix.h" + +static std::vector sMemPtrVector; + +namespace panda::ets::test { + +// NOLINTBEGIN(google-runtime-int) +extern "C" ets_long GetBuffer([[maybe_unused]] EtsEnv *env, [[maybe_unused]] ets_class klass) +{ + auto panda_env = PandaEtsNapiEnv::ToPandaEtsEnv(env); + panda::ets::napi::ScopedManagedCodeFix s(panda_env); + + auto vm = panda_env->GetEtsVM(); + auto ptr = vm->GetHeapManager()->GetInternalAllocator()->Alloc(10000000 * 4); + + if(ptr != nullptr) { + sMemPtrVector.push_back(ptr); + return 1; + } + else { + vm->GetHeapManager()->GetInternalAllocator()->Free(*sMemPtrVector.end()); + sMemPtrVector.pop_back(); + return 0; + } +} +// NOLINTEND(google-runtime-int) + +class EtsVMConfingNapi : public testing::Test { +public: + bool CreateRuntime(const std::string &stdlib_abc, const std::string &path_abc, bool enable_jit, + const std::string &path_an = "") + { + std::vector options = {{EtsOptionType::EtsLogLevel, "info"}, + {EtsOptionType::EtsBootFile, stdlib_abc.c_str()}, + {EtsOptionType::EtsBootFile, path_abc.c_str()}, + {EtsOptionType::EtsArkFile, path_abc.c_str()}, + {EtsOptionType::EtsGcTriggerType, "heap-trigger"}, + {enable_jit ? EtsOptionType::EtsJit : EtsOptionType::EtsNoJit, nullptr}}; + if (!path_an.empty()) { + options.emplace_back(EtsVMOption {EtsOptionType::EtsAot, nullptr}); + options.emplace_back(EtsVMOption {EtsOptionType::EtsAotFile, path_an.c_str()}); + } + + EtsVMInitArgs args = {ETS_NAPI_VERSION_1_0, static_cast(options.size()), options.data()}; + return ETS_CreateVM(&vm_, &env_, &args) == ETS_OK; + } + + bool InitExports() + { + const std::array impls = { + {"_getBuffer", nullptr, reinterpret_cast(GetBuffer)}}; + + auto global_class = env_->FindClass("ETSGLOBAL"); + if (global_class == nullptr) { + return false; + } + + return env_->RegisterNatives(global_class, impls.data(), impls.size()) == ETS_OK; + } + + bool DestroyRuntime() const + { + auto panda_env = PandaEtsNapiEnv::ToPandaEtsEnv(env_); + panda::ets::napi::ScopedManagedCodeFix s(panda_env); + + auto vm = panda_env->GetEtsVM(); + for(auto n : sMemPtrVector) { + vm->GetHeapManager()->GetInternalAllocator()->Free(n); + } + sMemPtrVector.clear(); + return vm_->DestroyEtsVM() == ETS_OK; + } + + int ExecuteMain() const + { + auto klass = env_->FindClass("ETSGLOBAL"); + auto method = env_->GetStaticp_method(klass, "main", ":I"); + return env_->CallStaticIntMethod(klass, method); // NOLINT(cppcoreguidelines-pro-type-vararg) + } + +private: + EtsVM *vm_ {}; + EtsEnv *env_ {}; +}; + +// NOLINTBEGIN(cppcoreguidelines-macro-usage) +TEST_F(EtsVMConfingNapi, TestHeap) +{ + std::string stdlib_abc; + std::string path_abc; + +#if defined(STDLIB_ABC) && defined(PATH_ABC) +#define ETS_UNIT_STRING_STEP(s) #s +#define ETS_UNIT_STRING(s) ETS_UNIT_STRING_STEP(s) + stdlib_abc = ETS_UNIT_STRING(STDLIB_ABC); + path_abc = ETS_UNIT_STRING(PATH_ABC); +#undef ETS_UNIT_STRING +#undef ETS_UNIT_STRING_STEP +#endif + + ASSERT_FALSE(stdlib_abc.empty()); + ASSERT_FALSE(path_abc.empty()); + + ASSERT_TRUE(CreateRuntime(stdlib_abc, path_abc, false)); + EXPECT_TRUE(InitExports()); + EXPECT_TRUE(ExecuteMain() == 0); + ASSERT_TRUE(DestroyRuntime()); +} +// NOLINTEND(cppcoreguidelines-macro-usage) + +} // namespace panda::ets::test diff --git a/plugins/ets/tests/ets_test_suite/gc/test_heap.ets b/plugins/ets/tests/ets_test_suite/gc/test_heap.ets new file mode 100644 index 0000000000000000000000000000000000000000..fda7ba97e7e4ed0e3038535b2bb16ca4efc2a4d7 --- /dev/null +++ b/plugins/ets/tests/ets_test_suite/gc/test_heap.ets @@ -0,0 +1,9 @@ +native function _getBuffer() : long; + +function main(): int +{ + for(let i: int = 0; i < 200; i++) { + console.println("Cycle: " + i + " Is Allocated: " + _getBuffer()); + } + return 0; +} \ No newline at end of file