diff --git a/libpandabase/BUILD.gn b/libpandabase/BUILD.gn index 7ed37053a3e75bc02e22effdb641ae7404434eca..d5404d9b59b82d80b7f4497b478a1c7dba25f1e0 100644 --- a/libpandabase/BUILD.gn +++ b/libpandabase/BUILD.gn @@ -21,6 +21,13 @@ config("arkbase_public_config") { ] } +ark_gen_file("base_options_h") { + template_file = "../templates/options/options.h.erb" + data_file = "options.yaml" + requires = [ "../templates/common.rb" ] + output_file = "$target_gen_dir/generated/base_options.h" +} + ark_gen_file("events_gen") { template_file = "events/events_gen.h.erb" data_file = "events/events.yaml" @@ -110,6 +117,7 @@ libarkbase_configs = [ ] libarkbase_deps = [ + ":base_options_h", ":events_gen", sdk_libc_secshared_dep, ] diff --git a/libpandabase/CMakeLists.txt b/libpandabase/CMakeLists.txt index bca1e6368db6bac60e64f7e27f865194e9ec0644..2003b24449d29942454dc7f05c5f54e3791580a4 100644 --- a/libpandabase/CMakeLists.txt +++ b/libpandabase/CMakeLists.txt @@ -248,6 +248,8 @@ if(PANDA_TARGET_32) ) endif() +panda_gen_options(TARGET arkbase YAML_FILE options.yaml GENERATED_HEADER base_options.h) + panda_add_sanitizers(TARGET arkbase SANITIZERS ${PANDA_SANITIZERS_LIST}) if (PANDA_ENABLE_AFL) diff --git a/libpandabase/options.yaml b/libpandabase/options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..df5812a024f8b677c3471718527b151486ceb5b7 --- /dev/null +++ b/libpandabase/options.yaml @@ -0,0 +1,80 @@ +# 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. + +module: + name: arkbase + # It is better to name this namespace simply "panda::base", but there is already namespace "ecmascript::base", which + # is used just as "base", hence it conflicts with this namespace. I fixed it by renaming base->ecmascript::base in + # this repository, but there is the external repository ark_js_runtime, which uses us as an external library and has + # the same problem with "ecmascript::base". So, I've gave up and renamed it to "base_options". + namespace: panda::base_options + +options: +- name: log-level + type: std::string + default: error + possible_values: + - debug + - info + - warning + - error + - fatal + description: Log level + +- name: log-stream + type: std::string + default: std + possible_values: + - std + - file + - fast-file + - dummy + description: Log level + +- name: log-file + type: std::string + default: "" + description: File name for file-logger + +- name: log-components + type: arg_list_t + default: + - all + possible_values: + - all + - alloc + - alloc-obj + - classlinker + - common + - core + - gc + - gc_trigger + - reference_processor + - interpreter + - compiler + - pandafile + - memorypool + - runtime + - trace + - debugger + - interop + - jni + - verifier + - compilation_queue + - jvmti + - aot + - events + - ecmascript + - scheduler + description: Enable logs from specified components + delimiter: ":" diff --git a/libpandabase/utils/logger.cpp b/libpandabase/utils/logger.cpp index fac151ff21ee936420eda9fe652d31745c1d394a..54835dc48dc03a88e652ba001c459bc9f49d4bf8 100644 --- a/libpandabase/utils/logger.cpp +++ b/libpandabase/utils/logger.cpp @@ -16,6 +16,7 @@ #include "logger.h" #include "os/thread.h" #include "string_helpers.h" +#include "generated/base_options.h" #include #include @@ -31,6 +32,25 @@ Logger *Logger::logger = nullptr; os::memory::Mutex Logger::mutex; // NOLINT(fuchsia-statically-constructed-objects) FUNC_MOBILE_LOG_PRINT mlog_buf_print = nullptr; +void Logger::Initialize(const base_options::Options &options) +{ + panda::Logger::ComponentMask component_mask; + for (const auto &s : options.GetLogComponents()) { + component_mask |= Logger::ComponentMaskFromString(s); + } + + if (options.GetLogStream() == "std") { + Logger::InitializeStdLogging(Logger::LevelFromString(options.GetLogLevel()), component_mask); + } else if (options.GetLogStream() == "file" || options.GetLogStream() == "fast-file") { + const std::string &file_name = options.GetLogFile(); + Logger::InitializeFileLogging(file_name, Logger::LevelFromString(options.GetLogLevel()), component_mask); + } else if (options.GetLogStream() == "dummy") { + Logger::InitializeDummyLogging(Logger::LevelFromString(options.GetLogLevel()), component_mask); + } else { + UNREACHABLE(); + } +} + Logger::Message::~Message() { if (print_system_error_) { diff --git a/libpandabase/utils/logger.h b/libpandabase/utils/logger.h index 64c2ad6252c5331e8071b2ea42badaf1e75047d0..d22baae45c4d52b1d883d706151d400c44e6a7ed 100644 --- a/libpandabase/utils/logger.h +++ b/libpandabase/utils/logger.h @@ -80,6 +80,10 @@ extern FUNC_MOBILE_LOG_PRINT mlog_buf_print; D(COMMON, 0x00, "common") \ D(SIGNAL, 0x01, "signal") +namespace base_options { +class Options; +} // namespace base_options + class Logger { public: enum Component : uint32_t { @@ -142,11 +146,13 @@ public: NO_MOVE_SEMANTIC(Message); }; + static void Initialize(const base_options::Options &options); + static void InitializeFileLogging(const std::string &log_file, Level level, ComponentMask component_mask); static void InitializeStdLogging(Level level, ComponentMask component_mask); - static void InitializeDummyLogging(Level level, ComponentMask component_mask); + static void InitializeDummyLogging(Level level = Level::DEBUG, ComponentMask component_mask = 0); static void Destroy(); @@ -241,6 +247,12 @@ public: logger->level_ = level; } + static Level GetLevel() + { + ASSERT(IsInitialized()); + return logger->level_; + } + static void EnableComponent(Component component) { ASSERT(IsInitialized()); @@ -279,12 +291,12 @@ public: static void ProcessLogComponentsFromString(std::string_view s); -protected: static bool IsInitialized() { return logger != nullptr; } +protected: Logger(Level level, ComponentMask component_mask) : level_(level), component_mask_(component_mask) {} virtual void LogLineInternal(Level level, Component component, const std::string &str) = 0; diff --git a/panda/panda.cpp b/panda/panda.cpp index c110316991c165bb7a805bc099f9ccb6ad45b5d5..adbeef209a28a4ec320d63a9338c4e6bd1f893e0 100644 --- a/panda/panda.cpp +++ b/panda/panda.cpp @@ -26,6 +26,7 @@ #include "libpandabase/os/mutex.h" #include "libpandabase/os/native_stack.h" +#include "generated/base_options.h" #include "mem/mem_stats.h" @@ -176,6 +177,7 @@ int Main(const int argc, const char **argv) BlockSignals(); Span sp(argv, argc); RuntimeOptions runtime_options(sp[0]); + base_options::Options base_options(sp[0]); panda::PandArg help("help", false, "Print this message and exit"); panda::PandArg options("options", false, "Print compiler and runtime options"); @@ -185,6 +187,7 @@ int Main(const int argc, const char **argv) panda::PandArgParser pa_parser; runtime_options.AddOptions(&pa_parser); + base_options.AddOptions(&pa_parser); pa_parser.Add(&help); pa_parser.Add(&options); @@ -204,6 +207,8 @@ int Main(const int argc, const char **argv) return 1; } + Logger::Initialize(base_options); + arg_list_t arguments = pa_parser.GetRemainder(); if (runtime_options.IsStartupTime()) { diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index 9f090f11e929f4465ad667b7724c98ebba32efdc..eef472101927ba6bfe6dcaad262d677f542829c5 100644 --- a/runtime/BUILD.gn +++ b/runtime/BUILD.gn @@ -53,6 +53,7 @@ group("arkruntime_header_deps") { ":isa_gen_libarkruntime_unimplemented_handlers-inl_h", ":libarkruntime_options_gen_h", ":libarkruntime_shorty_values_h", + "$ark_root/libpandabase:base_options_h", "$ark_root/verification/gen:isa_gen_verification_gen_abs_int_inl_gen_h", "$ark_root/verification/gen:isa_gen_verification_gen_cflow_iterate_inl_gen_h", "$ark_root/verification/gen:isa_gen_verification_gen_job_fill_gen_h", diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index d23d71407aff44b84c24ce8a2c64c2f9d5fc457a..ad8b7a4f099735c3bbfeb7dd221f6cb6e5acfa34 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -306,6 +306,8 @@ panda_gen_options( GENERATED_HEADER runtime_options_gen.h ) +add_dependencies(arkruntime_static_options arkbase_options) + panda_add_to_clang_tidy(TARGET arkruntime_static) add_subdirectory(asm_defines) diff --git a/runtime/include/runtime.h b/runtime/include/runtime.h index de029861558c1cd41484c839e13a9de0179d98a9..a1c35cf3186c7aa0cf1b6c22a535d6666f005ad4 100644 --- a/runtime/include/runtime.h +++ b/runtime/include/runtime.h @@ -81,8 +81,6 @@ public: LanguageContext GetLanguageContext(panda_file::ClassDataAccessor *cda); LanguageContext GetLanguageContext(panda_file::SourceLang lang); - static void InitializeLogger(const RuntimeOptions &options); - static bool CreateInstance(const RuntimeOptions &options, mem::InternalAllocatorPtr internal_allocator, const std::vector &ctxs); diff --git a/runtime/options.yaml b/runtime/options.yaml index 44a03eba719a5cf7da142dd717d53ae312256f64..7625641802849daccfc2a8d4d29653dd53c44afa 100644 --- a/runtime/options.yaml +++ b/runtime/options.yaml @@ -131,8 +131,9 @@ options: - events - ecmascript - scheduler - description: Enable logs from specified components + description: '[DEPRECATED] Option was moved to libpandabase/options.yaml, use base_options::Options instead of runtime options.' delimiter: ":" + deprecated: true - name: reference-dump type: uint64_t @@ -271,7 +272,8 @@ options: - info - error - fatal - description: Log level + description: '[DEPRECATED] Option was moved to libpandabase/options.yaml, use base_options::Options instead of runtime options.' + deprecated: true - name: log-stream type: std::string @@ -280,12 +282,14 @@ options: - std - file - dummy - description: Log level + description: '[DEPRECATED] Option was moved to libpandabase/options.yaml, use base_options::Options instead of runtime options.' + deprecated: true - name: log-file type: std::string default: "" - description: File name for file-logger + description: '[DEPRECATED] Option was moved to libpandabase/options.yaml, use base_options::Options instead of runtime options.' + deprecated: true - name: gc-enable-tracing diff --git a/runtime/runtime.cpp b/runtime/runtime.cpp index e0e1a673a17bd7e610b42ac6a81a6a17a9b3ddfd..95385690d55ed28628c573b2bcc6d615d8369b41 100644 --- a/runtime/runtime.cpp +++ b/runtime/runtime.cpp @@ -196,26 +196,6 @@ LanguageContext Runtime::GetLanguageContext(const std::string &runtime_type) UNREACHABLE(); } -/* static */ -void Runtime::InitializeLogger(const RuntimeOptions &options) -{ - panda::Logger::ComponentMask component_mask; - for (const auto &s : options.GetLogComponents()) { - component_mask |= Logger::ComponentMaskFromString(s); - } - - if (options.GetLogStream() == "std") { - Logger::InitializeStdLogging(Logger::LevelFromString(options.GetLogLevel()), component_mask); - } else if (options.GetLogStream() == "file") { - const std::string &file_name = options.GetLogFile(); - Logger::InitializeFileLogging(file_name, Logger::LevelFromString(options.GetLogLevel()), component_mask); - } else if (options.GetLogStream() == "dummy") { - Logger::InitializeDummyLogging(Logger::LevelFromString(options.GetLogLevel()), component_mask); - } else { - UNREACHABLE(); - } -} - /* static */ bool Runtime::CreateInstance(const RuntimeOptions &options, mem::InternalAllocatorPtr internal_allocator, const std::vector &ctxs) @@ -262,8 +242,6 @@ bool Runtime::Create(const RuntimeOptions &options, const std::vectorInitialize()) { @@ -485,8 +463,9 @@ Runtime::~Runtime() bool Runtime::IsEnableMemoryHooks() const { - auto log_level = options_.GetLogLevel(); - return options_.IsLimitStandardAlloc() && (log_level == "fatal" || log_level == "error") && + auto log_level = Logger::IsInitialized() ? Logger::GetLevel() : Logger::Level::DEBUG; + return options_.IsLimitStandardAlloc() && + (log_level == Logger::Level::FATAL || log_level == Logger::Level::ERROR) && (!options_.UseMallocForInternalAllocations()); } diff --git a/runtime/tests/options_test.cpp b/runtime/tests/options_test.cpp index 2afd5100fc83511391278e52f7163ed2f75fc80f..f749df29a387648e19dd75d4f0cbf7bd7d466c72 100644 --- a/runtime/tests/options_test.cpp +++ b/runtime/tests/options_test.cpp @@ -66,7 +66,6 @@ void RuntimeOptionsTest::LoadCorrectOptionsList() AddTestingOption("sigquit-flag", "1234"); AddTestingOption("dfx-log", "1234"); AddTestingOption("gc-dump-heap", "true"); - AddTestingOption("log-file", "string"); AddTestingOption("start-as-zygote", "true"); AddTestingOption("verification-enabled", "true"); AddTestingOption("pre-gc-heap-verify-enabled", "true"); diff --git a/templates/common.rb b/templates/common.rb index 016db88839c4fa19a12466d4a970144895f1b091..46066d388db8f6ac04a9dd15e0109811eb34225a 100755 --- a/templates/common.rb +++ b/templates/common.rb @@ -28,6 +28,10 @@ class Option < SimpleDelegator 'Set' + name.split(Regexp.union(['-', '.'])).map(&:capitalize).join end + def deprecated? + respond_to?(:deprecated) && deprecated + end + def default_value return default_constant_name if need_default_constant return '{' + default.map { |e| expand_string(e) }.join(', ') + '}' if type == 'arg_list_t' @@ -37,6 +41,7 @@ class Option < SimpleDelegator def full_description full_desc = description + full_desc.prepend("[DEPRECATED] ") if deprecated? if defined? possible_values full_desc += '. Possible values: ' + possible_values.inspect end diff --git a/templates/options/options.h.erb b/templates/options/options.h.erb index e11d86fb292c3683f1ef292fbbfcabb0cde17f7f..c7abf85a366048ed204202c34ec642efb4a13776 100644 --- a/templates/options/options.h.erb +++ b/templates/options/options.h.erb @@ -44,20 +44,30 @@ public: void AddOptions(PandArgParser *parser) { % Common::options.each do |op| +% next if op.deprecated? parser->Add(&<%= op.field_name %>); % end } % Common::options.each do |op| <%= op.type %> <%= op.getter_name %>() const { +% if op.deprecated? + std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; +% end return <%= op.field_name %>.GetValue(); } void <%= op.setter_name %>(<%= op.type %> value) { +% if op.deprecated? + std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; +% end <%= op.field_name %>.SetValue(<%= op.type == 'std::string' || op.type == 'arg_list_t' ? 'std::move(value)' : 'value' %>); } bool WasSet<%= op.name.split(Regexp.union(['-','.'])).map(&:capitalize).join %>() const { +% if op.deprecated? + std::cerr << "WARNING: Option '<%= op.name %>' is deprecated and should not be used\n"; +% end return <%= op.field_name %>.WasSet(); } diff --git a/verification/util/tests/verifier_test.h b/verification/util/tests/verifier_test.h index c1e1fa79a1fd601284ea9f7116d3f94da9a08765..9315b29302cbe21086c78caa1a6c8ed8f8408194 100644 --- a/verification/util/tests/verifier_test.h +++ b/verification/util/tests/verifier_test.h @@ -26,6 +26,7 @@ public: VerifierTest() { RuntimeOptions options; + Logger::InitializeDummyLogging(); options.SetShouldLoadBootPandaFiles(false); options.SetShouldInitializeIntrinsics(false); options.SetHeapSizeLimit(64_MB); diff --git a/verification/verifier/verifier.cpp b/verification/verifier/verifier.cpp index 2fb285c5228e9077c1a600e3563883e9c1fcc6bf..b34b945ad0c254afdf3f9849e9a2220de054a45f 100644 --- a/verification/verifier/verifier.cpp +++ b/verification/verifier/verifier.cpp @@ -27,6 +27,7 @@ #include "verification/job_queue/job_queue.h" #include "verification/cache/results_cache.h" +#include "generated/base_options.h" #include "utils/span.h"