From b4004f64764b833c93eb2c85d2a953b3f149c75f Mon Sep 17 00:00:00 2001 From: Zach Anderson Date: Fri, 7 Sep 2018 19:25:31 +0000 Subject: [PATCH] [vm] Reland: Move the interpreter under a flag. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After this CL, the interpreter is included by default in the JIT VM under the flag --enable-interpreter. Reland with fix to NativeArgument setup in simulator_arm.cc Change-Id: Ib9b4df6eb4d997dfbe361188b8a127828c1d9c6f Reviewed-on: https://dart-review.googlesource.com/74003 Reviewed-by: Siva Annamalai Reviewed-by: RĂ©gis Crelier Commit-Queue: Zach Anderson --- runtime/BUILD.gn | 11 -- runtime/bin/BUILD.gn | 63 ------ runtime/configs.gni | 84 +------- runtime/runtime_args.gni | 7 +- runtime/vm/BUILD.gn | 9 +- runtime/vm/code_patcher.h | 3 - runtime/vm/code_patcher_kbc.cc | 5 - .../vm/compiler/assembler/disassembler_kbc.cc | 4 +- .../vm/compiler/assembler/disassembler_kbc.h | 4 +- .../vm/compiler/frontend/bytecode_reader.cc | 2 - .../vm/compiler/frontend/bytecode_reader.h | 2 - .../frontend/kernel_binary_flowgraph.cc | 7 +- .../frontend/kernel_binary_flowgraph.h | 4 - .../frontend/kernel_translation_helper.h | 5 +- runtime/vm/compiler/jit/compiler.cc | 45 ++--- runtime/vm/dart.cc | 22 ++- runtime/vm/dart_entry.cc | 26 +-- runtime/vm/debugger.cc | 7 +- runtime/vm/exceptions.cc | 20 +- runtime/vm/flag_list.h | 14 +- runtime/vm/instructions_kbc.cc | 5 - runtime/vm/interpreter.cc | 4 +- runtime/vm/interpreter.h | 4 +- runtime/vm/interpreter_unsupported.cc | 185 ++++++++++++++++++ runtime/vm/isolate.cc | 8 +- runtime/vm/isolate.h | 6 + runtime/vm/kernel_isolate.cc | 3 +- runtime/vm/native_arguments.h | 2 - runtime/vm/native_entry.cc | 12 +- runtime/vm/native_entry.h | 2 - runtime/vm/object.cc | 51 ++--- runtime/vm/object.h | 6 +- runtime/vm/raw_object.h | 10 +- runtime/vm/runtime_entry.cc | 64 +++--- runtime/vm/simulator_arm.cc | 2 +- runtime/vm/stack_frame.cc | 41 ++-- runtime/vm/stack_frame.h | 21 -- runtime/vm/stub_code.cc | 33 ++-- runtime/vm/stub_code.h | 4 +- runtime/vm/stub_code_arm64.cc | 25 ++- runtime/vm/stub_code_dbc.cc | 8 + runtime/vm/stub_code_x64.cc | 25 ++- runtime/vm/thread_test.cc | 8 +- runtime/vm/vm_sources.gni | 1 + tools/build.py | 11 +- tools/gn.py | 19 +- tools/testing/dart/configuration.dart | 5 +- tools/testing/dart/runtime_configuration.dart | 6 +- tools/utils.py | 15 +- 49 files changed, 470 insertions(+), 460 deletions(-) create mode 100644 runtime/vm/interpreter_unsupported.cc diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index ed7631b2756..bc08e005e79 100644 --- a/runtime/BUILD.gn +++ b/runtime/BUILD.gn @@ -124,17 +124,6 @@ config("dart_arch_config") { } } -config("dart_interpreter_config") { - defines = [ "DART_USE_INTERPRETER" ] -} - -config("dart_maybe_interpreter_config") { - defines = [] - if (dart_use_interpreter) { - defines += [ "DART_USE_INTERPRETER" ] - } -} - config("dart_config") { defines = [] diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn index 96351e9a1da..86847438cab 100644 --- a/runtime/bin/BUILD.gn +++ b/runtime/bin/BUILD.gn @@ -247,7 +247,6 @@ template("build_libdart_builtin") { static_library(target_name) { configs += [ "..:dart_arch_config", - "..:dart_maybe_interpreter_config", "..:dart_config", ] + extra_configs if (is_fuchsia) { @@ -408,7 +407,6 @@ template("build_gen_snapshot") { build_gen_snapshot("gen_snapshot") { extra_configs = [ - "..:dart_maybe_interpreter_config", "..:dart_maybe_product_config", "..:dart_os_config", ] @@ -421,7 +419,6 @@ build_gen_snapshot("gen_snapshot") { build_gen_snapshot("gen_snapshot_product") { extra_configs = [ - "..:dart_maybe_interpreter_config", "..:dart_product_config", "..:dart_os_config", ] @@ -434,7 +431,6 @@ build_gen_snapshot("gen_snapshot_product") { build_gen_snapshot("gen_snapshot_fuchsia") { extra_configs = [ - "..:dart_maybe_interpreter_config", "..:dart_maybe_product_config", "..:dart_os_fuchsia_config", ] @@ -447,7 +443,6 @@ build_gen_snapshot("gen_snapshot_fuchsia") { build_gen_snapshot("gen_snapshot_product_fuchsia") { extra_configs = [ - "..:dart_maybe_interpreter_config", "..:dart_product_config", "..:dart_os_fuchsia_config", ] @@ -458,60 +453,6 @@ build_gen_snapshot("gen_snapshot_product_fuchsia") { ] } -if (!is_win) { - build_gen_snapshot("gen_snapshot_interpreter") { - extra_configs = [ - "..:dart_interpreter_config", - "..:dart_maybe_product_config", - "..:dart_os_config", - ] - extra_deps = [ - ":gen_snapshot_dart_io", - ":libdart_builtin", - "..:libdart_nosnapshot_with_precompiler_interpreter", - ] - } - - build_gen_snapshot("gen_snapshot_product_interpreter") { - extra_configs = [ - "..:dart_interpreter_config", - "..:dart_product_config", - "..:dart_os_config", - ] - extra_deps = [ - ":gen_snapshot_dart_io", - ":libdart_builtin", - "..:libdart_nosnapshot_with_precompiler_interpreter", - ] - } - - build_gen_snapshot("gen_snapshot_interpreter_fuchsia") { - extra_configs = [ - "..:dart_interpreter_config", - "..:dart_maybe_product_config", - "..:dart_os_fuchsia_config", - ] - extra_deps = [ - ":gen_snapshot_dart_io_fuchsia", - ":libdart_builtin_fuchsia", - "..:libdart_nosnapshot_with_precompiler_interpreter_fuchsia", - ] - } - - build_gen_snapshot("gen_snapshot_product_interpreter_fuchsia") { - extra_configs = [ - "..:dart_interpreter_config", - "..:dart_product_config", - "..:dart_os_fuchsia_config", - ] - extra_deps = [ - ":gen_snapshot_dart_io_product_fuchsia", - ":libdart_builtin_product_fuchsia", - "..:libdart_nosnapshot_with_precompiler_product_interpreter_fuchsia", - ] - } -} - # A source set for the implementation of 'dart:io' library # (without secure sockets) suitable for linking with gen_snapshot. template("build_gen_snapshot_dart_io") { @@ -523,7 +464,6 @@ template("build_gen_snapshot_dart_io") { configs += [ "..:dart_arch_config", "..:dart_config", - "..:dart_maybe_interpreter_config", "..:dart_precompiler_config", ] + extra_configs deps = [] @@ -611,7 +551,6 @@ template("dart_io") { configs += [ "..:dart_arch_config", "..:dart_config", - "..:dart_maybe_interpreter_config", "..:dart_os_config", ] + extra_configs if (is_fuchsia) { @@ -940,7 +879,6 @@ template("dart_executable") { "..:dart_arch_config", "..:dart_config", "..:dart_os_config", - "..:dart_maybe_interpreter_config", "..:dart_maybe_product_config", ] + extra_configs if (is_fuchsia) { @@ -1186,7 +1124,6 @@ executable("run_vm_tests") { "..:dart_arch_config", "..:dart_config", "..:dart_os_config", - "..:dart_maybe_interpreter_config", "..:dart_maybe_product_config", ] if (is_fuchsia) { diff --git a/runtime/configs.gni b/runtime/configs.gni index fa5658fa751..b678f175759 100644 --- a/runtime/configs.gni +++ b/runtime/configs.gni @@ -16,33 +16,13 @@ _base_fuchsia_config = [ "$_dart_runtime:dart_os_fuchsia_config", ] -_maybe_interpreter_maybe_product = [ - "$_dart_runtime:dart_maybe_interpreter_config", - "$_dart_runtime:dart_maybe_product_config", -] +_maybe_product = [ "$_dart_runtime:dart_maybe_product_config" ] -_maybe_interpreter_product = [ - "$_dart_runtime:dart_maybe_interpreter_config", - "$_dart_runtime:dart_product_config", -] +_product = [ "$_dart_runtime:dart_product_config" ] -_interpreter_maybe_product = [ - "$_dart_runtime:dart_interpreter_config", - "$_dart_runtime:dart_maybe_product_config", -] +_jit_config = _base_config + _maybe_product -_interpreter_product = [ - "$_dart_runtime:dart_interpreter_config", - "$_dart_runtime:dart_product_config", -] - -_jit_config = _base_config + _maybe_interpreter_maybe_product - -_jit_product_config = _base_config + _maybe_interpreter_product - -_jit_interpreter_config = _base_config + _interpreter_maybe_product - -_jit_product_interpreter_config = _base_config + _interpreter_product +_jit_product_config = _base_config + _product _precompiled_runtime_config = _base_config + [ @@ -72,28 +52,16 @@ _nosnapshot_precompiler_base = [ ] _nosnapshot_with_precompiler_config = - _base_config + _nosnapshot_precompiler_base + _maybe_interpreter_maybe_product - -_nosnapshot_with_precompiler_interpreter_config = - _base_config + _nosnapshot_precompiler_base + _interpreter_maybe_product - -_nosnapshot_with_precompiler_product_interpreter_config = - _base_config + _nosnapshot_precompiler_base + _interpreter_product + _base_config + _nosnapshot_precompiler_base + _maybe_product _nosnapshot_with_precompiler_product_config = - _base_config + _nosnapshot_precompiler_base + _maybe_interpreter_product + _base_config + _nosnapshot_precompiler_base + _product _nosnapshot_with_precompiler_fuchsia_config = - _base_fuchsia_config + _nosnapshot_precompiler_base + _maybe_interpreter_maybe_product + _base_fuchsia_config + _nosnapshot_precompiler_base + _maybe_product _nosnapshot_with_precompiler_product_fuchsia_config = - _base_fuchsia_config + _nosnapshot_precompiler_base + _maybe_interpreter_product - -_nosnapshot_with_precompiler_interpreter_fuchsia_config = - _base_fuchsia_config + _nosnapshot_precompiler_base + _interpreter_maybe_product - -_nosnapshot_with_precompiler_product_interpreter_fuchsia_config = - _base_fuchsia_config + _nosnapshot_precompiler_base + _interpreter_product + _base_fuchsia_config + _nosnapshot_precompiler_base + _product _all_configs = [ { @@ -148,42 +116,6 @@ _all_configs = [ }, ] -# The interpreter is not currently needed on Windows. -if (!is_win) { - _all_configs += [ - { - suffix = "_jit_interpreter" - configs = _jit_interpreter_config - snapshot = true - }, - { - suffix = "_jit_product_interpreter" - configs = _jit_product_interpreter_config - snapshot = true - }, - { - suffix = "_nosnapshot_with_precompiler_interpreter" - configs = _nosnapshot_with_precompiler_interpreter_config - snapshot = false - }, - { - suffix = "_nosnapshot_with_precompiler_product_interpreter" - configs = _nosnapshot_with_precompiler_product_interpreter_config - snapshot = false - }, - { - suffix = "_nosnapshot_with_precompiler_interpreter_fuchsia" - configs = _nosnapshot_with_precompiler_interpreter_fuchsia_config - snapshot = false - }, - { - suffix = "_nosnapshot_with_precompiler_product_interpreter_fuchsia" - configs = _nosnapshot_with_precompiler_product_interpreter_fuchsia_config - snapshot = false - }, - ] -} - # This template creates a target for each of the configurations listed above. # For example: # diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni index ba24461ebf7..325d95161c9 100644 --- a/runtime/runtime_args.gni +++ b/runtime/runtime_args.gni @@ -78,9 +78,8 @@ declare_args() { dart_component_kind = "static_library" } - # Whether the runtime should interpret called functions for which bytecode - # is provided by kernel, rather than compile them before execution. - dart_use_interpreter = false + # Whether the VM's platform dill file contains bytecode. + dart_platform_bytecode = false # Whether the VM includes the kernel service in all modes (debug, release, # product). @@ -91,7 +90,7 @@ declare_args() { # We create a kernel service app-jit snapshot only for when the target # architecture is x64 for other cases we will use the '.dill' file # which is already linked in the VM. - if (dart_target_arch == "x64" && !dart_use_interpreter) { + if (dart_target_arch == "x64") { create_kernel_service_snapshot = true } else { create_kernel_service_snapshot = false diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn index b47ed541ee7..ebb800a6e54 100644 --- a/runtime/vm/BUILD.gn +++ b/runtime/vm/BUILD.gn @@ -328,13 +328,14 @@ compile_platform("vm_platform") { "$root_out_dir/vm_outline_strong.dill", ] - args = [ "--strong-mode" ] + args = [ + "--strong-mode", + "dart:core", + ] - if (dart_use_interpreter) { + if (dart_platform_bytecode) { args += [ "--bytecode" ] } - - args += [ "dart:core" ] } group("kernel_platform_files") { diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h index 595f5129f93..fb3716c7a82 100644 --- a/runtime/vm/code_patcher.h +++ b/runtime/vm/code_patcher.h @@ -7,7 +7,6 @@ #define RUNTIME_VM_CODE_PATCHER_H_ #include "vm/allocation.h" -#include "vm/globals.h" // Needed here to get DART_USE_INTERPRETER. #include "vm/native_entry.h" namespace dart { @@ -113,7 +112,6 @@ class CodePatcher : public AllStatic { // Example pattern: `[0x3d, 0x8b, -1, -1]`. bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size); -#if defined(DART_USE_INTERPRETER) class KBCPatcher : public AllStatic { public: static NativeFunctionWrapper GetNativeCallAt(uword return_address, @@ -125,7 +123,6 @@ class KBCPatcher : public AllStatic { NativeFunction function, NativeFunctionWrapper trampoline); }; -#endif // defined DART_USE_INTERPRETER } // namespace dart diff --git a/runtime/vm/code_patcher_kbc.cc b/runtime/vm/code_patcher_kbc.cc index 6f8665b1e25..1df082b3280 100644 --- a/runtime/vm/code_patcher_kbc.cc +++ b/runtime/vm/code_patcher_kbc.cc @@ -2,9 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -#include "vm/globals.h" // Needed here to get DART_USE_INTERPRETER. -#if defined(DART_USE_INTERPRETER) - #include "vm/code_patcher.h" #include "vm/instructions_kbc.h" @@ -34,5 +31,3 @@ NativeFunctionWrapper KBCPatcher::GetNativeCallAt(uword return_address, } } // namespace dart - -#endif // defined DART_USE_INTERPRETER diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc index 69d47366f7e..a1da9ee6f9c 100644 --- a/runtime/vm/compiler/assembler/disassembler_kbc.cc +++ b/runtime/vm/compiler/assembler/disassembler_kbc.cc @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. #include "vm/globals.h" -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) #include "vm/compiler/assembler/disassembler_kbc.h" @@ -370,4 +370,4 @@ void KernelBytecodeDisassembler::Disassemble(const Function& function) { } // namespace dart -#endif // defined(DART_USE_INTERPRETER) +#endif // !defined(DART_PRECOMPILED_RUNTIME) diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.h b/runtime/vm/compiler/assembler/disassembler_kbc.h index b3e2408f503..35127796e3e 100644 --- a/runtime/vm/compiler/assembler/disassembler_kbc.h +++ b/runtime/vm/compiler/assembler/disassembler_kbc.h @@ -6,7 +6,7 @@ #define RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_KBC_H_ #include "vm/globals.h" -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) #include "vm/compiler/assembler/disassembler.h" @@ -84,6 +84,6 @@ class KernelBytecodeDisassembler : public AllStatic { } // namespace dart -#endif // defined(DART_USE_INTERPRETER) +#endif // !defined(DART_PRECOMPILED_RUNTIME) #endif // RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_KBC_H_ diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc index fa861455d65..e5d88c98fff 100644 --- a/runtime/vm/compiler/frontend/bytecode_reader.cc +++ b/runtime/vm/compiler/frontend/bytecode_reader.cc @@ -13,7 +13,6 @@ #include "vm/timeline.h" #if !defined(DART_PRECOMPILED_RUNTIME) -#if defined(DART_USE_INTERPRETER) #define Z (zone_) #define H (translation_helper_) @@ -682,5 +681,4 @@ RawNativeEntryData* BytecodeMetadataHelper::NativeEntry( } // namespace kernel } // namespace dart -#endif // defined(DART_USE_INTERPRETER) #endif // !defined(DART_PRECOMPILED_RUNTIME) diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h index 6d3ed1ffb30..f1a81a5299a 100644 --- a/runtime/vm/compiler/frontend/bytecode_reader.h +++ b/runtime/vm/compiler/frontend/bytecode_reader.h @@ -9,7 +9,6 @@ #include "vm/object.h" #if !defined(DART_PRECOMPILED_RUNTIME) -#if defined(DART_USE_INTERPRETER) namespace dart { namespace kernel { @@ -45,6 +44,5 @@ class BytecodeMetadataHelper : public MetadataHelper { } // namespace kernel } // namespace dart -#endif // defined(DART_USE_INTERPRETER) #endif // !defined(DART_PRECOMPILED_RUNTIME) #endif // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_ diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index 8abc8bda134..777e05c8f9d 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -14,6 +14,9 @@ #if !defined(DART_PRECOMPILED_RUNTIME) namespace dart { + +DECLARE_FLAG(bool, enable_interpreter); + namespace kernel { #define Z (zone_) @@ -1903,10 +1906,9 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraph() { SetOffset(kernel_offset); -#if defined(DART_USE_INTERPRETER) // TODO(regis): Clean up this logic of when to compile. // If the bytecode was previously loaded, we really want to compile. - if (!function.HasBytecode()) { + if (FLAG_enable_interpreter && !function.HasBytecode()) { // TODO(regis): For now, we skip bytecode loading for functions that were // synthesized and that do not have bytecode. Since they inherited the // kernel offset of a concrete function, the wrong bytecode would be loaded. @@ -1927,7 +1929,6 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraph() { } } } -#endif // Mark forwarding stubs. switch (function.kind()) { diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h index 399216318a1..c5449d6d782 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h @@ -39,9 +39,7 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper { &type_translator_, active_class_, flow_graph_builder), -#if defined(DART_USE_INTERPRETER) bytecode_metadata_helper_(this, &type_translator_, active_class_), -#endif // defined(DART_USE_INTERPRETER) direct_call_metadata_helper_(this), inferred_type_metadata_helper_(this), procedure_attributes_metadata_helper_(this), @@ -419,9 +417,7 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper { ActiveClass* const active_class_; TypeTranslator type_translator_; ConstantEvaluator constant_evaluator_; -#if defined(DART_USE_INTERPRETER) BytecodeMetadataHelper bytecode_metadata_helper_; -#endif // defined(DART_USE_INTERPRETER) DirectCallMetadataHelper direct_call_metadata_helper_; InferredTypeMetadataHelper inferred_type_metadata_helper_; ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_; diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h index 3dd63b854b4..0d1e40d4da9 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.h +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h @@ -1042,6 +1042,7 @@ class KernelReaderHelper { // kernel program. intptr_t data_program_offset_; + friend class BytecodeMetadataHelper; friend class ClassHelper; friend class CallSiteAttributesMetadataHelper; friend class ConstantEvaluator; @@ -1064,10 +1065,6 @@ class KernelReaderHelper { friend class VariableDeclarationHelper; friend bool NeedsDynamicInvocationForwarder(const Function& function); -#if defined(DART_USE_INTERPRETER) - friend class BytecodeMetadataHelper; -#endif // defined(DART_USE_INTERPRETER) - private: DISALLOW_COPY_AND_ASSIGN(KernelReaderHelper); }; diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc index 371fafa31ea..6304e1987f9 100644 --- a/runtime/vm/compiler/jit/compiler.cc +++ b/runtime/vm/compiler/jit/compiler.cc @@ -89,6 +89,7 @@ DEFINE_FLAG(bool, false, "Enable compiler verification assertions"); +DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); DECLARE_FLAG(bool, trace_failed_optimization_attempts); DECLARE_FLAG(bool, unbox_numeric_fields); @@ -162,11 +163,8 @@ FlowGraph* DartCompilationPipeline::BuildFlowGraph( /* not inlining */ NULL, optimized, osr_id); FlowGraph* graph = builder.BuildGraph(); -#if defined(DART_USE_INTERPRETER) - ASSERT((graph != NULL) || parsed_function->function().HasBytecode()); -#else - ASSERT(graph != NULL); -#endif + ASSERT((graph != NULL) || (FLAG_enable_interpreter && + parsed_function->function().HasBytecode())); return graph; } FlowGraphBuilder builder(*parsed_function, ic_data_array, @@ -260,14 +258,13 @@ DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { } Exceptions::PropagateError(Error::Cast(result)); } -#if defined(DART_USE_INTERPRETER) // TODO(regis): Revisit. - if (!function.HasCode() && function.HasBytecode()) { + if (FLAG_enable_interpreter && !function.HasCode() && + function.HasBytecode()) { // Function was not actually compiled, but its bytecode was loaded. // Verify that InterpretCall stub code was installed. ASSERT(function.CurrentCode() == StubCode::InterpretCall_entry()->code()); } -#endif } bool Compiler::CanOptimizeFunction(Thread* thread, const Function& function) { @@ -832,12 +829,11 @@ RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) { zone, parsed_function(), *ic_data_array, osr_id(), optimized()); } -#if defined(DART_USE_INTERPRETER) // TODO(regis): Revisit. - if (flow_graph == NULL && function.HasBytecode()) { + if (FLAG_enable_interpreter && (flow_graph == NULL) && + function.HasBytecode()) { return Code::null(); } -#endif const bool print_flow_graph = (FLAG_print_flow_graph || @@ -1022,12 +1018,10 @@ static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline, const Code& result = Code::Handle(helper.Compile(pipeline)); -#if defined(DART_USE_INTERPRETER) // TODO(regis): Revisit. - if (result.IsNull() && function.HasBytecode()) { + if (FLAG_enable_interpreter && result.IsNull() && function.HasBytecode()) { return Object::null(); } -#endif if (!result.IsNull()) { if (!optimized) { @@ -1403,11 +1397,9 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) { func ^= functions.At(i); ASSERT(!func.IsNull()); if (!func.HasCode() && -#if defined(DART_USE_INTERPRETER) // TODO(regis): Revisit. // Do not compile function if its bytecode is already loaded. - !func.HasBytecode() && -#endif + (!FLAG_enable_interpreter || !func.HasBytecode()) && !func.is_abstract() && !func.IsRedirectingFactory()) { if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) && func.HasOptionalParameters()) { @@ -1418,13 +1410,10 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) { if (result.IsError()) { return Error::Cast(result).raw(); } -#if defined(DART_USE_INTERPRETER) // TODO(regis): Revisit. // The compiler may load bytecode and return Code::null(). - ASSERT(!result.IsNull() || func.HasBytecode()); -#else - ASSERT(!result.IsNull()); -#endif + ASSERT(!result.IsNull() || + (FLAG_enable_interpreter && func.HasBytecode())); } } return Error::null(); @@ -1511,15 +1500,13 @@ RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); const Code& code = Code::Handle(helper.Compile(&pipeline)); const Function& initializer = parsed_function->function(); + if (!code.IsNull()) { code.set_var_descriptors(Object::empty_var_descriptors()); -#if defined(DART_USE_INTERPRETER) - } - // In case the initializer has bytecode, the compilation step above only - // loaded the bytecode without generating code. - if (!code.IsNull() || initializer.HasBytecode()) { -#endif - // Invoke the function to evaluate the expression. + return DartEntry::InvokeFunction(initializer, Object::empty_array()); + } else if (FLAG_enable_interpreter && initializer.HasBytecode()) { + // In case the initializer has bytecode, the compilation step above only + // loaded the bytecode without generating code. return DartEntry::InvokeFunction(initializer, Object::empty_array()); } } diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc index a1330855b12..d78ff5cc14b 100644 --- a/runtime/vm/dart.cc +++ b/runtime/vm/dart.cc @@ -135,6 +135,24 @@ char* Dart::InitOnce(const uint8_t* vm_isolate_snapshot, FLAG_verify_gc_contains = true; } #endif + + if (FLAG_enable_interpreter) { +#if defined(USING_SIMULATOR) || defined(TARGET_ARCH_DBC) + return strdup( + "--enable-interpreter is not supported when targeting " + "a sim* architecture."); +#endif // defined(USING_SIMULATOR) || defined(TARGET_ARCH_DBC) + +#if defined(TARGET_OS_WINDOWS) + // TODO(34393): The interpreter currently relies on computed gotos, which + // aren't supported on Windows. + return strdup("--enable-interpreter is not supported on Windows."); +#endif // defined(TARGET_OS_WINDOWS) + + FLAG_use_field_guards = false; + FLAG_optimization_counter_threshold = -1; + } + FrameLayout::InitOnce(); set_thread_exit_callback(thread_exit); @@ -716,10 +734,6 @@ const char* Dart::FeaturesString(Isolate* isolate, buffer.AddString(" x64-sysv"); #endif -#if defined(DART_USE_INTERPRETER) - buffer.AddString(" kbc"); -#endif - #elif defined(TARGET_ARCH_DBC) #if defined(ARCH_IS_32_BIT) buffer.AddString(" dbc32"); diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc index 8fca5262615..e9827361ed3 100644 --- a/runtime/vm/dart_entry.cc +++ b/runtime/vm/dart_entry.cc @@ -19,6 +19,8 @@ namespace dart { +DECLARE_FLAG(bool, enable_interpreter); + // A cache of VM heap allocated arguments descriptors. RawArray* ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount]; @@ -126,17 +128,24 @@ RawObject* DartEntry::InvokeFunction(const Function& function, Zone* zone = thread->zone(); ASSERT(thread->IsMutatorThread()); ScopedIsolateStackLimits stack_limit(thread, current_sp); +#if !defined(DART_PRECOMPILED_RUNTIME) if (!function.HasCode()) { -#if defined(DART_USE_INTERPRETER) - // The function is not compiled yet. Interpret it if it has bytecode. - // The bytecode is loaded as part as an aborted compilation step. - if (!function.HasBytecode()) { + // There's no native code. If we're not using the interpreter, then we + // compile to native code. If we are using the interpreter, but there's no + // native code and no bytecode, then we invoke the compiler to extract the + // bytecode. + if (!FLAG_enable_interpreter || !function.HasBytecode()) { const Object& result = Object::Handle(zone, Compiler::CompileFunction(thread, function)); if (result.IsError()) { return Error::Cast(result).raw(); } } + + // At this point we should have either native code or bytecode. + ASSERT(function.HasCode() || function.HasBytecode()); + + // If we have bytecode but no native code then invoke the interpreter. if (!function.HasCode() && function.HasBytecode()) { ASSERT(thread->no_callback_scope_depth() == 0); SuspendLongJumpScope suspend_long_jump_scope(thread); @@ -144,14 +153,9 @@ RawObject* DartEntry::InvokeFunction(const Function& function, return Interpreter::Current()->Call(function, arguments_descriptor, arguments, thread); } -#else - const Object& result = - Object::Handle(zone, Compiler::CompileFunction(thread, function)); - if (result.IsError()) { - return Error::Cast(result).raw(); - } -#endif } +#endif // !defined(DART_PRECOMPILED_RUNTIME) + // Now Call the invoke stub which will invoke the dart function. #if !defined(TARGET_ARCH_DBC) invokestub entrypoint = reinterpret_cast( diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc index 306cf6faf23..302df62f8c1 100644 --- a/runtime/vm/debugger.cc +++ b/runtime/vm/debugger.cc @@ -57,6 +57,7 @@ DEFINE_FLAG(bool, "handler instead. This handler dispatches breakpoints to " "the VM service."); +DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(bool, warn_on_pause_with_no_debugger); #ifndef PRODUCT @@ -261,14 +262,14 @@ ActivationFrame::ActivationFrame(uword pc, var_descriptors_(LocalVarDescriptors::ZoneHandle()), desc_indices_(8), pc_desc_(PcDescriptors::ZoneHandle()) { +#if !defined(DART_PRECOMPILED_RUNTIME) // TODO(regis): If debugging of interpreted code is required, recognize an // interpreted activation frame and respect alternate frame layout. // For now, punt. -#if defined(DART_USE_INTERPRETER) - if (function_.Bytecode() == code_.raw()) { + if (FLAG_enable_interpreter && function_.Bytecode() == code_.raw()) { UNIMPLEMENTED(); } -#endif +#endif // !defined(DART_PRECOMPILED_RUNTIME) } ActivationFrame::ActivationFrame(Kind kind) diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc index 28520f99ce0..811c0b2d19c 100644 --- a/runtime/vm/exceptions.cc +++ b/runtime/vm/exceptions.cc @@ -25,6 +25,7 @@ namespace dart { +DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(bool, trace_deoptimization); DEFINE_FLAG(bool, print_stacktrace_at_throw, @@ -463,15 +464,20 @@ void Exceptions::JumpToFrame(Thread* thread, Simulator::Current()->JumpToFrame(program_counter, stack_pointer, frame_pointer, thread); #else -#if defined(DART_USE_INTERPRETER) - Interpreter* interpreter = thread->isolate()->interpreter(); - if ((interpreter != NULL) && interpreter->HasFrame(frame_pointer)) { - interpreter->JumpToFrame(program_counter, stack_pointer, frame_pointer, - thread); - } + +#if !defined(DART_PRECOMPILED_RUNTIME) // TODO(regis): We still possibly need to unwind interpreter frames if they // are callee frames of the C++ frame handling the exception. -#endif + if (FLAG_enable_interpreter) { + Interpreter* interpreter = thread->isolate()->interpreter(); + ASSERT(interpreter != NULL); + if (interpreter->HasFrame(frame_pointer)) { + interpreter->JumpToFrame(program_counter, stack_pointer, frame_pointer, + thread); + } + } +#endif // !defined(DART_PRECOMPILED_RUNTIME) + // Prepare for unwinding frames by destroying all the stack resources // in the previous frames. StackResource::Unwind(thread); diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h index 2f3600b84c6..54ee710685d 100644 --- a/runtime/vm/flag_list.h +++ b/runtime/vm/flag_list.h @@ -12,13 +12,6 @@ #define USING_DBC false #endif -// Don't use USING_KBC outside of this file. -#if defined(DART_USE_INTERPRETER) -#define USING_KBC true -#else -#define USING_KBC false -#endif - // Don't use USING_MULTICORE outside of this file. #if defined(ARCH_IS_MULTI_CORE) #define USING_MULTICORE true @@ -132,7 +125,7 @@ constexpr bool kDartPrecompiledRuntime = false; "Max size of new gen semi space in MB") \ P(new_gen_semi_initial_size, int, (kWordSize <= 4) ? 1 : 2, \ "Initial size of new gen semi space in MB") \ - P(optimization_counter_threshold, int, USING_KBC ? -1 : 30000, \ + P(optimization_counter_threshold, int, 30000, \ "Function's usage-counter value before it is optimized, -1 means never") \ P(old_gen_heap_size, int, kDefaultMaxOldGenHeapSize, \ "Max size of old gen heap size in MB, or 0 for unlimited," \ @@ -195,7 +188,7 @@ constexpr bool kDartPrecompiledRuntime = false; P(use_compactor, bool, false, "Compact the heap during old-space GC.") \ P(use_cha_deopt, bool, true, \ "Use class hierarchy analysis even if it can cause deoptimization.") \ - P(use_field_guards, bool, !USING_DBC && !USING_KBC, \ + P(use_field_guards, bool, !USING_DBC, \ "Use field guards and track field types") \ C(use_osr, false, true, bool, true, "Use OSR") \ P(use_strong_mode_types, bool, true, "Optimize based on strong mode types.") \ @@ -216,6 +209,7 @@ constexpr bool kDartPrecompiledRuntime = false; R(enable_testing_pragmas, false, bool, false, \ "Enable magical pragmas for testing purposes. Use at your own risk!") \ R(eliminate_type_checks, true, bool, true, \ - "Eliminate type checks when allowed by static type analysis.") + "Eliminate type checks when allowed by static type analysis.") \ + P(enable_interpreter, bool, false, "Enable interpreting kernel bytecode.") #endif // RUNTIME_VM_FLAG_LIST_H_ diff --git a/runtime/vm/instructions_kbc.cc b/runtime/vm/instructions_kbc.cc index edb71a8a28a..ce3d46a0292 100644 --- a/runtime/vm/instructions_kbc.cc +++ b/runtime/vm/instructions_kbc.cc @@ -2,9 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -#include "vm/globals.h" // Needed here to get DART_USE_INTERPRETER. -#if defined(DART_USE_INTERPRETER) - #include "vm/instructions.h" #include "vm/instructions_kbc.h" @@ -31,5 +28,3 @@ RawNativeEntryData* KBCNativeCallPattern::GetNativeEntryDataAt( } } // namespace dart - -#endif // defined DART_USE_INTERPRETER diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc index 18723db1e9e..88e76f27d53 100644 --- a/runtime/vm/interpreter.cc +++ b/runtime/vm/interpreter.cc @@ -6,7 +6,7 @@ #include #include "vm/globals.h" -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_OS_WINDOWS) #include "vm/interpreter.h" @@ -4852,4 +4852,4 @@ void Interpreter::VisitObjectPointers(ObjectPointerVisitor* visitor) { } // namespace dart -#endif // defined(DART_USE_INTERPRETER) +#endif // !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_OS_WINDOWS) diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h index d8322050b0e..c49c3b5badc 100644 --- a/runtime/vm/interpreter.h +++ b/runtime/vm/interpreter.h @@ -6,7 +6,7 @@ #define RUNTIME_VM_INTERPRETER_H_ #include "vm/globals.h" -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) #include "vm/compiler/method_recognizer.h" #include "vm/constants_kbc.h" @@ -221,6 +221,6 @@ class Interpreter { } // namespace dart -#endif // defined(DART_USE_INTERPRETER) +#endif // !defined(DART_PRECOMPILED_RUNTIME) #endif // RUNTIME_VM_INTERPRETER_H_ diff --git a/runtime/vm/interpreter_unsupported.cc b/runtime/vm/interpreter_unsupported.cc new file mode 100644 index 00000000000..b12ba4e7db4 --- /dev/null +++ b/runtime/vm/interpreter_unsupported.cc @@ -0,0 +1,185 @@ +// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +#include "vm/globals.h" +#if !defined(DART_PRECOMPILED_RUNTIME) && defined(TARGET_OS_WINDOWS) + +#include "vm/interpreter.h" + +#include "platform/assert.h" +#include "vm/object.h" + +namespace dart { + +IntrinsicHandler Interpreter::intrinsics_[Interpreter::kIntrinsicCount]; + +void Interpreter::InitOnce() { + UNIMPLEMENTED(); +} + +Interpreter::Interpreter() { + UNIMPLEMENTED(); +} + +Interpreter::~Interpreter() { + UNIMPLEMENTED(); +} + +Interpreter* Interpreter::Current() { + UNIMPLEMENTED(); + return NULL; +} + +#if defined(DEBUG) +bool Interpreter::IsTracingExecution() const { + UNIMPLEMENTED(); + return false; +} + +void Interpreter::TraceInstruction(uint32_t* pc) const { + UNIMPLEMENTED(); +} +#endif // defined(DEBUG) + +void Interpreter::Exit(Thread* thread, + RawObject** base, + RawObject** frame, + uint32_t* pc) { + UNIMPLEMENTED(); +} + +void Interpreter::CallRuntime(Thread* thread, + RawObject** base, + RawObject** exit_frame, + uint32_t* pc, + intptr_t argc_tag, + RawObject** args, + RawObject** result, + uword target) { + UNIMPLEMENTED(); +} + +bool Interpreter::InvokeCompiled(Thread* thread, + RawFunction* function, + RawObject** call_base, + RawObject** call_top, + uint32_t** pc, + RawObject*** FP, + RawObject*** SP) { + UNIMPLEMENTED(); + return false; +} + +bool Interpreter::ProcessInvocation(bool* invoked, + Thread* thread, + RawFunction* function, + RawObject** call_base, + RawObject** call_top, + uint32_t** pc, + RawObject*** FP, + RawObject*** SP) { + UNIMPLEMENTED(); + return false; +} + +bool Interpreter::Invoke(Thread* thread, + RawObject** call_base, + RawObject** call_top, + uint32_t** pc, + RawObject*** FP, + RawObject*** SP) { + UNIMPLEMENTED(); + return false; +} + +void Interpreter::InlineCacheMiss(int checked_args, + Thread* thread, + RawICData* icdata, + RawObject** args, + RawObject** top, + uint32_t* pc, + RawObject** FP, + RawObject** SP) { + UNIMPLEMENTED(); +} + +bool Interpreter::InstanceCall1(Thread* thread, + RawICData* icdata, + RawObject** call_base, + RawObject** top, + uint32_t** pc, + RawObject*** FP, + RawObject*** SP, + bool optimized) { + UNIMPLEMENTED(); + return false; +} + +bool Interpreter::InstanceCall2(Thread* thread, + RawICData* icdata, + RawObject** call_base, + RawObject** top, + uint32_t** pc, + RawObject*** FP, + RawObject*** SP, + bool optimized) { + UNIMPLEMENTED(); + return false; +} + +void Interpreter::PrepareForTailCall(RawCode* code, + RawImmutableArray* args_desc, + RawObject** FP, + RawObject*** SP, + uint32_t** pc) { + UNIMPLEMENTED(); +} + +bool Interpreter::Deoptimize(Thread* thread, + uint32_t** pc, + RawObject*** FP, + RawObject*** SP, + bool is_lazy) { + UNIMPLEMENTED(); + return false; +} + +bool Interpreter::AssertAssignable(Thread* thread, + uint32_t* pc, + RawObject** FP, + RawObject** call_top, + RawObject** args, + RawSubtypeTestCache* cache) { + UNIMPLEMENTED(); + return false; +} + +RawObject* Interpreter::Call(const Function& function, + const Array& arguments_descriptor, + const Array& arguments, + Thread* thread) { + UNIMPLEMENTED(); + return NULL; +} + +RawObject* Interpreter::Call(RawFunction* function, + RawArray* argdesc, + intptr_t argc, + RawObject* const* argv, + Thread* thread) { + UNIMPLEMENTED(); + return NULL; +} + +void Interpreter::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { + UNIMPLEMENTED(); +} + +void Interpreter::VisitObjectPointers(ObjectPointerVisitor* visitor) { + UNIMPLEMENTED(); +} + +} // namespace dart + +#endif // !defined(DART_PRECOMPILED_RUNTIME) && defined(TARGET_OS_WINDOWS) diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc index e31589f4916..00996d2a75d 100644 --- a/runtime/vm/isolate.cc +++ b/runtime/vm/isolate.cc @@ -911,7 +911,9 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags) library_tag_handler_(NULL), api_state_(NULL), random_(), +#if !defined(DART_PRECOMPILED_RUNTIME) interpreter_(NULL), +#endif simulator_(NULL), mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::mutex_"))), symbols_mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::symbols_mutex_"))), @@ -988,7 +990,7 @@ Isolate::~Isolate() { delete heap_; delete object_store_; delete api_state_; -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) delete interpreter_; #endif #if defined(USING_SIMULATOR) @@ -1980,11 +1982,11 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, } #endif // !defined(DART_PRECOMPILED_RUNTIME) -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) if (interpreter() != NULL) { interpreter()->VisitObjectPointers(visitor); } -#endif // defined(DART_USE_INTERPRETER) +#endif #if defined(TARGET_ARCH_DBC) if (simulator() != NULL) { diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h index f8f78353347..dfd3422b3c5 100644 --- a/runtime/vm/isolate.h +++ b/runtime/vm/isolate.h @@ -39,7 +39,9 @@ class HandleScope; class HandleVisitor; class Heap; class ICData; +#if !defined(DART_PRECOMPILED_RUNTIME) class Interpreter; +#endif class IsolateProfilerData; class IsolateReloadContext; class IsolateSpawnState; @@ -409,8 +411,10 @@ class Isolate : public BaseIsolate { Random* random() { return &random_; } +#if !defined(DART_PRECOMPILED_RUNTIME) Interpreter* interpreter() const { return interpreter_; } void set_interpreter(Interpreter* value) { interpreter_ = value; } +#endif Simulator* simulator() const { return simulator_; } void set_simulator(Simulator* value) { simulator_ = value; } @@ -973,7 +977,9 @@ class Isolate : public BaseIsolate { Dart_LibraryTagHandler library_tag_handler_; ApiState* api_state_; Random random_; +#if !defined(DART_PRECOMPILED_RUNTIME) Interpreter* interpreter_; +#endif Simulator* simulator_; Mutex* mutex_; // Protects compiler stats. Mutex* symbols_mutex_; // Protects concurrent access to the symbol table. diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc index 5a8517878d9..863f5ed4463 100644 --- a/runtime/vm/kernel_isolate.cc +++ b/runtime/vm/kernel_isolate.cc @@ -97,8 +97,7 @@ class RunKernelTask : public ThreadPool::Task { api_flags.strong = true; api_flags.unsafe_trust_strong_mode_types = false; api_flags.sync_async = true; -#if !defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) && \ - !defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) api_flags.use_field_guards = true; #endif #if !defined(DART_PRECOMPILER) diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h index 782fc6e510f..38fac512ea2 100644 --- a/runtime/vm/native_arguments.h +++ b/runtime/vm/native_arguments.h @@ -216,7 +216,6 @@ class NativeArguments { friend class NativeEntryData; friend class Simulator; -#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER) // Allow simulator and interpreter to create NativeArguments in reverse order // on the stack. NativeArguments(Thread* thread, @@ -227,7 +226,6 @@ class NativeArguments { argc_tag_(ReverseArgOrderBit::update(true, argc_tag)), argv_(argv), retval_(retval) {} -#endif // Since this function is passed a RawObject directly, we need to be // exceedingly careful when we use it. If there are any other side diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc index 5597b0ea35d..1fbbf79e916 100644 --- a/runtime/vm/native_entry.cc +++ b/runtime/vm/native_entry.cc @@ -103,7 +103,6 @@ void NativeEntry::PropagateErrors(NativeArguments* arguments) { UNREACHABLE(); } -#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER) uword NativeEntry::BootstrapNativeCallWrapperEntry() { uword entry = reinterpret_cast(NativeEntry::BootstrapNativeCallWrapper); @@ -114,7 +113,6 @@ void NativeEntry::BootstrapNativeCallWrapper(Dart_NativeArguments args, Dart_NativeFunction func) { func(args); } -#endif uword NativeEntry::NoScopeNativeCallWrapperEntry() { uword entry = reinterpret_cast(NativeEntry::NoScopeNativeCallWrapper); @@ -285,7 +283,7 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { #if defined(DEBUG) && !defined(TARGET_ARCH_DBC) NativeFunction current_function = NULL; if (caller_frame->is_interpreted()) { -#if defined(DART_USE_INTERPRETER) + ASSERT(FLAG_enable_interpreter); NativeFunctionWrapper current_trampoline = KBCPatcher::GetNativeCallAt( caller_frame->pc(), code, ¤t_function); ASSERT(current_function == @@ -293,9 +291,6 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { ASSERT(current_trampoline == &BootstrapNativeCallWrapper || current_trampoline == &AutoScopeNativeCallWrapper || current_trampoline == &NoScopeNativeCallWrapper); -#else - UNREACHABLE(); -#endif // defined DART_USE_INTERPRETER } else { const Code& current_trampoline = Code::Handle(zone, CodePatcher::GetNativeCallAt( @@ -329,7 +324,7 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { patch_target_function, trampoline); #else if (caller_frame->is_interpreted()) { -#if defined(DART_USE_INTERPRETER) + ASSERT(FLAG_enable_interpreter); NativeFunctionWrapper trampoline; if (is_bootstrap_native) { trampoline = &BootstrapNativeCallWrapper; @@ -340,9 +335,6 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { } KBCPatcher::PatchNativeCallAt(caller_frame->pc(), code, patch_target_function, trampoline); -#else - UNREACHABLE(); -#endif // defined DART_USE_INTERPRETER } else { Code& trampoline = Code::Handle(zone); if (is_bootstrap_native) { diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h index 6c1e5ef099f..2f718c26f1a 100644 --- a/runtime/vm/native_entry.h +++ b/runtime/vm/native_entry.h @@ -129,11 +129,9 @@ class NativeEntry : public AllStatic { uword pc); static const uint8_t* ResolveSymbol(uword pc); -#if defined(TARGET_ARCH_DBC) || defined(DART_USE_INTERPRETER) static uword BootstrapNativeCallWrapperEntry(); static void BootstrapNativeCallWrapper(Dart_NativeArguments args, Dart_NativeFunction func); -#endif static uword NoScopeNativeCallWrapperEntry(); static void NoScopeNativeCallWrapper(Dart_NativeArguments args, diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 11084b734d6..ac1b716a354 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -5959,15 +5959,19 @@ void Function::AttachCode(const Code& value) const { bool Function::HasCode() const { NoSafepointScope no_safepoint; ASSERT(raw_ptr()->code_ != Code::null()); -#if defined(DART_USE_INTERPRETER) - return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code() && - raw_ptr()->code_ != StubCode::InterpretCall_entry()->code(); -#else +#if defined(DART_PRECOMPILED_RUNTIME) return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code(); -#endif +#else + if (FLAG_enable_interpreter) { + return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code() && + raw_ptr()->code_ != StubCode::InterpretCall_entry()->code(); + } else { + return raw_ptr()->code_ != StubCode::LazyCompile_entry()->code(); + } +#endif // defined(DART_PRECOMPILED_RUNTIME) } -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) void Function::AttachBytecode(const Code& value) const { DEBUG_ASSERT(IsMutatorOrAtSafepoint()); // Finish setting up code before activating it. @@ -5985,18 +5989,21 @@ bool Function::HasBytecode() const { return raw_ptr()->bytecode_ != Code::null(); } -bool Function::HasCode(RawFunction* function) { - NoSafepointScope no_safepoint; - ASSERT(function->ptr()->code_ != Code::null()); - return function->ptr()->code_ != StubCode::LazyCompile_entry()->code() && - function->ptr()->code_ != StubCode::InterpretCall_entry()->code(); -} - bool Function::HasBytecode(RawFunction* function) { return function->ptr()->bytecode_ != Code::null(); } +#endif // !defined(DART_PRECOMPILED_RUNTIME) -#endif +bool Function::HasCode(RawFunction* function) { + NoSafepointScope no_safepoint; + ASSERT(function->ptr()->code_ != Code::null()); +#if defined(DART_PRECOMPILED_RUNTIME) + return function->ptr()->code_ != StubCode::LazyCompile_entry()->code(); +#else + return function->ptr()->code_ != StubCode::LazyCompile_entry()->code() && + function->ptr()->code_ != StubCode::InterpretCall_entry()->code(); +#endif // !defined(DART_PRECOMPILED_RUNTIME) +} void Function::ClearCode() const { #if defined(DART_PRECOMPILED_RUNTIME) @@ -6005,9 +6012,9 @@ void Function::ClearCode() const { ASSERT(Thread::Current()->IsMutatorThread()); StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); -#if defined(DART_USE_INTERPRETER) - StorePointer(&raw_ptr()->bytecode_, Code::null()); -#endif // defined(DART_USE_INTERPRETER) + if (FLAG_enable_interpreter) { + StorePointer(&raw_ptr()->bytecode_, Code::null()); + } SetInstructions(Code::Handle(StubCode::LazyCompile_entry()->code())); #endif // defined(DART_PRECOMPILED_RUNTIME) @@ -8510,7 +8517,8 @@ RawNativeEntryData* NativeEntryData::New() { } const char* NativeEntryData::ToCString() const { -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) + ASSERT(FLAG_enable_interpreter); if (IsNull()) { return "NativeEntryData: null"; } @@ -8530,7 +8538,7 @@ const char* NativeEntryData::ToCString() const { reinterpret_cast(native_function())); #else UNREACHABLE(); -#endif // defined(DART_USE_INTERPRETER) +#endif // !defined(DART_PRECOMPILED_RUNTIME) } RawField* Field::CloneFromOriginal() const { @@ -15820,9 +15828,7 @@ RawCode* Code::FinalizeCode(const Function& function, #endif // !PRODUCT return FinalizeCode("", compiler, assembler, optimized, stats); } -#endif // !defined(DART_PRECOMPILED_RUNTIME) -#if defined(DART_USE_INTERPRETER) RawCode* Code::FinalizeBytecode(const void* bytecode_data, intptr_t bytecode_size, const ObjectPool& object_pool, @@ -15880,7 +15886,8 @@ RawCode* Code::FinalizeBytecode(const void* bytecode_data, code.comments().comments_.Length()); return code.raw(); } -#endif // defined(DART_USE_INTERPRETER) + +#endif // !defined(DART_PRECOMPILED_RUNTIME) bool Code::SlowFindRawCodeVisitor::FindObject(RawObject* raw_obj) const { return RawCode::ContainsPC(raw_obj, pc_); diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 6fbd389c542..959070ce5d5 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -2364,8 +2364,8 @@ class Function : public Object { } void set_unoptimized_code(const Code& value) const; bool HasCode() const; -#if defined(DART_USE_INTERPRETER) static bool HasCode(RawFunction* function); +#if !defined(DART_PRECOMPILED_RUNTIME) static bool HasBytecode(RawFunction* function); #endif @@ -2379,7 +2379,7 @@ class Function : public Object { return OFFSET_OF(RawFunction, unchecked_entry_point_); } -#if defined(DART_USE_INTERPRETER) +#if !defined(DART_PRECOMPILED_RUNTIME) void AttachBytecode(const Code& bytecode) const; RawCode* Bytecode() const { return raw_ptr()->bytecode_; } bool HasBytecode() const; @@ -5263,12 +5263,10 @@ class Code : public Object { Assembler* assembler, bool optimized, CodeStatistics* stats = nullptr); -#if defined(DART_USE_INTERPRETER) static RawCode* FinalizeBytecode(const void* bytecode_data, intptr_t bytecode_size, const ObjectPool& object_pool, CodeStatistics* stats = nullptr); -#endif #endif static RawCode* LookupCode(uword pc); static RawCode* LookupCodeInVmIsolate(uword pc); diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index c6e36691431..b00a212027e 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -983,10 +983,8 @@ class RawFunction : public RawObject { RawObject** to_no_code() { return reinterpret_cast(&ptr()->ic_data_array_); } -#if defined(DART_USE_INTERPRETER) - RawCode* bytecode_; -#endif RawCode* code_; // Currently active code. Accessed from generated code. + NOT_IN_PRECOMPILED(RawCode* bytecode_); NOT_IN_PRECOMPILED(RawCode* unoptimized_code_); // Unoptimized code, keep it // after optimization. #if defined(DART_PRECOMPILED_RUNTIME) @@ -1133,11 +1131,11 @@ class RawField : public RawObject { UNREACHABLE(); return NULL; } -#if defined(DART_USE_INTERPRETER) +#if defined(DART_PRECOMPILED_RUNTIME) + VISIT_TO(RawObject*, dependent_code_); +#else RawSubtypeTestCache* type_test_cache_; // For type test in implicit setter. VISIT_TO(RawObject*, type_test_cache_); -#else - VISIT_TO(RawObject*, dependent_code_); #endif TokenPosition token_pos_; TokenPosition end_token_pos_; diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc index 3731a08da16..9a758deeb03 100644 --- a/runtime/vm/runtime_entry.cc +++ b/runtime/vm/runtime_entry.cc @@ -63,6 +63,7 @@ DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks."); +DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(int, max_deoptimization_counter_threshold); DECLARE_FLAG(bool, enable_inlining_annotations); DECLARE_FLAG(bool, trace_compiler); @@ -391,13 +392,9 @@ DEFINE_RUNTIME_ENTRY(InstantiateTypeArguments, 3) { instantiator_type_arguments.IsInstantiated()); ASSERT(function_type_arguments.IsNull() || function_type_arguments.IsInstantiated()); -#if !defined(DART_USE_INTERPRETER) // Code inlined in the caller should have optimized the case where the // instantiator can be reused as type argument vector. - // However, it is non-trivial for the bytecode generator to implement this - // optimization, so we do not require it when the interpreter is used. ASSERT(!type_arguments.IsUninstantiatedIdentity()); -#endif if (isolate->type_checks()) { Error& bound_error = Error::Handle(zone); type_arguments = type_arguments.InstantiateAndCanonicalizeFrom( @@ -462,11 +459,8 @@ DEFINE_RUNTIME_ENTRY(SubtypeCheck, 5) { // Allocate a new SubtypeTestCache for use in interpreted implicit setters. // Return value: newly allocated SubtypeTestCache. DEFINE_RUNTIME_ENTRY(AllocateSubtypeTestCache, 0) { -#if defined(DART_USE_INTERPRETER) + ASSERT(FLAG_enable_interpreter); arguments.SetReturn(SubtypeTestCache::Handle(zone, SubtypeTestCache::New())); -#else - UNREACHABLE(); -#endif // defined(DART_USE_INTERPRETER) } // Allocate a new context large enough to hold the given number of variables. @@ -504,7 +498,7 @@ DEFINE_RUNTIME_ENTRY(CloneContext, 1) { // Arg1: method. // Return value: newly allocated Closure. DEFINE_RUNTIME_ENTRY(ExtractMethod, 2) { -#if defined(DART_USE_INTERPRETER) + ASSERT(FLAG_enable_interpreter); const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); const Function& method = Function::CheckedHandle(zone, arguments.ArgAt(1)); const TypeArguments& instantiator_type_arguments = @@ -519,9 +513,6 @@ DEFINE_RUNTIME_ENTRY(ExtractMethod, 2) { Closure::New(instantiator_type_arguments, Object::null_type_arguments(), Object::empty_type_arguments(), method, context)); arguments.SetReturn(closure); -#else - UNREACHABLE(); -#endif // defined(DART_USE_INTERPRETER) } // Result of an invoke may be an unhandled exception, in which case we @@ -537,7 +528,7 @@ static void CheckResultError(const Object& result) { // Arg1: field name. // Return value: field value. DEFINE_RUNTIME_ENTRY(GetFieldForDispatch, 2) { -#if defined(DART_USE_INTERPRETER) + ASSERT(FLAG_enable_interpreter); const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); const String& name = String::CheckedHandle(zone, arguments.ArgAt(1)); const Class& receiver_class = Class::Handle(zone, receiver.clazz()); @@ -556,16 +547,13 @@ DEFINE_RUNTIME_ENTRY(GetFieldForDispatch, 2) { Object::Handle(zone, DartEntry::InvokeFunction(getter, args)); CheckResultError(result); arguments.SetReturn(result); -#else - UNREACHABLE(); -#endif // defined(DART_USE_INTERPRETER) } // Resolve 'call' function of receiver. // Arg0: receiver (not a closure). // Return value: 'call' function'. DEFINE_RUNTIME_ENTRY(ResolveCallFunction, 1) { -#if defined(DART_USE_INTERPRETER) + ASSERT(FLAG_enable_interpreter); const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); ASSERT(!receiver.IsClosure()); // Interpreter tests for closure. Class& cls = Class::Handle(zone, receiver.clazz()); @@ -578,9 +566,6 @@ DEFINE_RUNTIME_ENTRY(ResolveCallFunction, 1) { cls = cls.SuperClass(); } while (!cls.IsNull()); arguments.SetReturn(call_function); -#else - UNREACHABLE(); -#endif // defined(DART_USE_INTERPRETER) } // Helper routine for tracing a type check. @@ -918,14 +903,14 @@ DEFINE_RUNTIME_ENTRY(TypeCheck, 7) { if (should_update_cache) { if (cache.IsNull()) { -#if defined(DART_USE_INTERPRETER) - // TODO(regis): Remove this workaround once the interpreter can provide a - // non-null cache for the type test in an implicit setter. - if (mode == kTypeCheckFromInline) { - arguments.SetReturn(src_instance); - return; + if (FLAG_enable_interpreter) { + // TODO(regis): Remove this workaround once the interpreter can provide + // a non-null cache for the type test in an implicit setter. + if (mode == kTypeCheckFromInline) { + arguments.SetReturn(src_instance); + return; + } } -#endif // defined(DART_USE_INTERPRETER) #if !defined(TARGET_ARCH_DBC) && !defined(TARGET_ARCH_IA32) ASSERT(mode == kTypeCheckFromSlowStub); @@ -2090,14 +2075,16 @@ DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { } bool interpreter_stack_overflow = false; -#if defined(DART_USE_INTERPRETER) - // Do not allocate an interpreter, if none is allocated yet. - Interpreter* interpreter = Isolate::Current()->interpreter(); - if (interpreter != NULL) { - interpreter_stack_overflow = - interpreter->get_sp() >= interpreter->stack_limit(); +#if !defined(DART_PRECOMPILED_RUNTIME) + if (FLAG_enable_interpreter) { + // Do not allocate an interpreter, if none is allocated yet. + Interpreter* interpreter = Isolate::Current()->interpreter(); + if (interpreter != NULL) { + interpreter_stack_overflow = + interpreter->get_sp() >= interpreter->stack_limit(); + } } -#endif +#endif // !defined(DART_PRECOMPILED_RUNTIME) // If an interrupt happens at the same time as a stack overflow, we // process the stack overflow now and leave the interrupt for next @@ -2731,7 +2718,10 @@ RawObject* RuntimeEntry::InterpretCall(RawFunction* function, intptr_t argc, RawObject** argv, Thread* thread) { -#if defined(DART_USE_INTERPRETER) +#if defined(DART_PRECOMPILED_RUNTIME) + UNREACHABLE(); +#else + ASSERT(FLAG_enable_interpreter); Interpreter* interpreter = Interpreter::Current(); #if defined(DEBUG) uword exit_fp = thread->top_exit_frame_info(); @@ -2754,9 +2744,7 @@ RawObject* RuntimeEntry::InterpretCall(RawFunction* function, Exceptions::PropagateError(Error::Cast(result)); } return result.raw(); -#else - UNREACHABLE(); -#endif // defined(DART_USE_INTERPRETER) +#endif // defined(DART_PRECOMPILED_RUNTIME) } } // namespace dart diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc index 1fb6ddb52dc..8951295d6d1 100644 --- a/runtime/vm/simulator_arm.cc +++ b/runtime/vm/simulator_arm.cc @@ -1386,7 +1386,7 @@ void Simulator::SupervisorCall(Instr* instr) { THR_Print("Call to host function at 0x%" Pd "\n", external); } if (redirection->call_kind() == kRuntimeCall) { - NativeArguments arguments; + NativeArguments arguments(NULL, 0, NULL, NULL); ASSERT(sizeof(NativeArguments) == 4 * kWordSize); arguments.thread_ = reinterpret_cast(get_register(R0)); arguments.argc_tag_ = get_register(R1); diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc index 8535bcded94..2104353edb9 100644 --- a/runtime/vm/stack_frame.cc +++ b/runtime/vm/stack_frame.cc @@ -21,6 +21,8 @@ namespace dart { +DECLARE_FLAG(bool, enable_interpreter); + const FrameLayout invalid_frame_layout = { /*.first_object_from_fp = */ -1, /*.last_fixed_object_from_fp = */ -1, @@ -428,9 +430,9 @@ void StackFrameIterator::SetupLastExitFrameData() { ASSERT(thread_ != NULL); uword exit_marker = thread_->top_exit_frame_info(); frames_.fp_ = exit_marker; -#if defined(DART_USE_INTERPRETER) - frames_.CheckIfInterpreted(exit_marker); -#endif + if (FLAG_enable_interpreter) { + frames_.CheckIfInterpreted(exit_marker); + } } void StackFrameIterator::SetupNextExitFrameData() { @@ -442,9 +444,9 @@ void StackFrameIterator::SetupNextExitFrameData() { frames_.fp_ = exit_marker; frames_.sp_ = 0; frames_.pc_ = 0; -#if defined(DART_USE_INTERPRETER) - frames_.CheckIfInterpreted(exit_marker); -#endif + if (FLAG_enable_interpreter) { + frames_.CheckIfInterpreted(exit_marker); + } } // Tell MemorySanitizer that generated code initializes part of the stack. @@ -484,9 +486,9 @@ StackFrameIterator::StackFrameIterator(uword last_fp, frames_.fp_ = last_fp; frames_.sp_ = 0; frames_.pc_ = 0; -#if defined(DART_USE_INTERPRETER) - frames_.CheckIfInterpreted(last_fp); -#endif + if (FLAG_enable_interpreter) { + frames_.CheckIfInterpreted(last_fp); + } } #if !defined(TARGET_ARCH_DBC) @@ -507,9 +509,9 @@ StackFrameIterator::StackFrameIterator(uword fp, frames_.fp_ = fp; frames_.sp_ = sp; frames_.pc_ = pc; -#if defined(DART_USE_INTERPRETER) - frames_.CheckIfInterpreted(fp); -#endif + if (FLAG_enable_interpreter) { + frames_.CheckIfInterpreted(fp); + } } #endif @@ -575,16 +577,17 @@ StackFrame* StackFrameIterator::NextFrame() { return current_frame_; } -#if defined(DART_USE_INTERPRETER) void StackFrameIterator::FrameSetIterator::CheckIfInterpreted( uword exit_marker) { +#if !defined(DART_PRECOMPILED_RUNTIME) // TODO(regis): We should rely on a new thread vm_tag to identify an // interpreter frame and not need the HasFrame() method. + ASSERT(FLAG_enable_interpreter); Isolate* isolate = thread_->isolate(); Interpreter* interpreter = isolate != NULL ? isolate->interpreter() : NULL; is_interpreted_ = (interpreter != NULL) && interpreter->HasFrame(exit_marker); +#endif // !defined(DART_PRECOMPILED_RUNTIME) } -#endif StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) { StackFrame* frame; @@ -593,15 +596,11 @@ StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) { frame->sp_ = sp_; frame->fp_ = fp_; frame->pc_ = pc_; -#if defined(DART_USE_INTERPRETER) frame->is_interpreted_ = is_interpreted_; -#endif sp_ = frame->GetCallerSp(); fp_ = frame->GetCallerFp(); pc_ = frame->GetCallerPc(); -#if defined(DART_USE_INTERPRETER) ASSERT(is_interpreted_ == frame->is_interpreted_); -#endif ASSERT(!validate || frame->IsValid()); return frame; } @@ -610,15 +609,11 @@ ExitFrame* StackFrameIterator::NextExitFrame() { exit_.sp_ = frames_.sp_; exit_.fp_ = frames_.fp_; exit_.pc_ = frames_.pc_; -#if defined(DART_USE_INTERPRETER) exit_.is_interpreted_ = frames_.is_interpreted_; -#endif frames_.sp_ = exit_.GetCallerSp(); frames_.fp_ = exit_.GetCallerFp(); frames_.pc_ = exit_.GetCallerPc(); -#if defined(DART_USE_INTERPRETER) ASSERT(frames_.is_interpreted_ == exit_.is_interpreted_); -#endif ASSERT(!validate_ || exit_.IsValid()); return &exit_; } @@ -628,9 +623,7 @@ EntryFrame* StackFrameIterator::NextEntryFrame() { entry_.sp_ = frames_.sp_; entry_.fp_ = frames_.fp_; entry_.pc_ = frames_.pc_; -#if defined(DART_USE_INTERPRETER) entry_.is_interpreted_ = frames_.is_interpreted_; -#endif SetupNextExitFrameData(); // Setup data for next exit frame in chain. ASSERT(!validate_ || entry_.IsValid()); return &entry_; diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h index 92ceedbb08f..58dcc56faf2 100644 --- a/runtime/vm/stack_frame.h +++ b/runtime/vm/stack_frame.h @@ -161,11 +161,7 @@ class StackFrame : public ValueObject { virtual bool IsStubFrame() const; virtual bool IsEntryFrame() const { return false; } virtual bool IsExitFrame() const { return false; } -#if defined(DART_USE_INTERPRETER) virtual bool is_interpreted() const { return is_interpreted_; } -#else - virtual bool is_interpreted() const { return false; } -#endif RawFunction* LookupDartFunction() const; RawCode* LookupDartCode() const; @@ -179,13 +175,8 @@ class StackFrame : public ValueObject { protected: explicit StackFrame(Thread* thread) -#if defined(DART_USE_INTERPRETER) : fp_(0), sp_(0), pc_(0), thread_(thread), is_interpreted_(false) { } -#else - : fp_(0), sp_(0), pc_(0), thread_(thread) { - } -#endif // Name of the frame, used for generic frame printing functionality. virtual const char* GetName() const { @@ -229,9 +220,7 @@ class StackFrame : public ValueObject { uword sp_; uword pc_; Thread* thread_; -#if defined(DART_USE_INTERPRETER) bool is_interpreted_; -#endif // The iterators FrameSetIterator and StackFrameIterator set the private // fields fp_ and sp_ when they return the respective frame objects. @@ -349,7 +338,6 @@ class StackFrameIterator : public ValueObject { StackFrame* NextFrame(bool validate); private: -#if defined(DART_USE_INTERPRETER) explicit FrameSetIterator(Thread* thread) : fp_(0), sp_(0), @@ -359,20 +347,13 @@ class StackFrameIterator : public ValueObject { is_interpreted_(false) {} bool is_interpreted() const { return is_interpreted_; } void CheckIfInterpreted(uword exit_marker); -#else - explicit FrameSetIterator(Thread* thread) - : fp_(0), sp_(0), pc_(0), stack_frame_(thread), thread_(thread) {} - bool is_interpreted() const { return false; } -#endif uword fp_; uword sp_; uword pc_; StackFrame stack_frame_; // Singleton frame returned by NextFrame(). Thread* thread_; -#if defined(DART_USE_INTERPRETER) bool is_interpreted_; -#endif friend class StackFrameIterator; DISALLOW_COPY_AND_ASSIGN(FrameSetIterator); @@ -393,9 +374,7 @@ class StackFrameIterator : public ValueObject { void SetupLastExitFrameData(); void SetupNextExitFrameData(); -#if defined(DART_USE_INTERPRETER) void CheckInterpreterExitFrame(uword exit_marker); -#endif bool validate_; // Validate each frame as we traverse the frames. EntryFrame entry_; // Singleton entry frame returned by NextEntryFrame(). diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc index 8b1a357f1ea..759469aa073 100644 --- a/runtime/vm/stub_code.cc +++ b/runtime/vm/stub_code.cc @@ -20,6 +20,8 @@ namespace dart { DEFINE_FLAG(bool, disassemble_stubs, false, "Disassemble generated stubs."); +DECLARE_FLAG(bool, enable_interpreter); + StubEntry* StubCode::entries_[kNumStubEntries] = { #define STUB_CODE_DECLARE(name) NULL, VM_STUB_CODE_LIST(STUB_CODE_DECLARE) @@ -90,25 +92,30 @@ bool StubCode::HasBeenInitialized() { bool StubCode::InInvocationStub(uword pc, bool is_interpreted_frame) { #if !defined(TARGET_ARCH_DBC) ASSERT(HasBeenInitialized()); -#if defined(DART_USE_INTERPRETER) - if (is_interpreted_frame) { - // Recognize special marker set up by interpreter in entry frame. - return (pc & 2) != 0; - } - { - uword entry = StubCode::InvokeDartCodeFromBytecode_entry()->EntryPoint(); - uword size = StubCode::InvokeDartCodeFromBytecodeSize(); - if ((pc >= entry) && (pc < (entry + size))) { - return true; +#if !defined(DART_PRECOMPILED_RUNTIME) + if (FLAG_enable_interpreter) { + if (is_interpreted_frame) { + // Recognize special marker set up by interpreter in entry frame. + return (pc & 2) != 0; + } + { + uword entry = StubCode::InvokeDartCodeFromBytecode_entry()->EntryPoint(); + uword size = StubCode::InvokeDartCodeFromBytecodeSize(); + if ((pc >= entry) && (pc < (entry + size))) { + return true; + } } } -#endif +#endif // !defined(DART_PRECOMPILED_RUNTIME) uword entry = StubCode::InvokeDartCode_entry()->EntryPoint(); uword size = StubCode::InvokeDartCodeSize(); return (pc >= entry) && (pc < (entry + size)); -#elif defined(DART_USE_INTERPRETER) -#error "Simultaneous usage of DBC simulator and interpreter not yet supported." #else + if (FLAG_enable_interpreter) { + FATAL( + "Simultaneous usage of DBC simulator " + "and interpreter not yet supported."); + } // On DBC we use a special marker PC to signify entry frame because there is // no such thing as invocation stub. return (pc & 2) != 0; diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h index 5dc798be64e..1dceaa9a4e9 100644 --- a/runtime/vm/stub_code.h +++ b/runtime/vm/stub_code.h @@ -116,7 +116,9 @@ class SnapshotWriter; V(SlowTypeTest) \ V(LazySpecializeTypeTest) \ V(FrameAwaitingMaterialization) \ - V(AsynchronousGapMarker) + V(AsynchronousGapMarker) \ + V(InvokeDartCodeFromBytecode) \ + V(InterpretCall) #endif // !defined(TARGET_ARCH_DBC) diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc index 306900ecc0f..4441956250a 100644 --- a/runtime/vm/stub_code_arm64.cc +++ b/runtime/vm/stub_code_arm64.cc @@ -28,6 +28,7 @@ DEFINE_FLAG(bool, false, "Set to true for debugging & verifying the slow paths."); DECLARE_FLAG(bool, trace_optimized_ic_calls); +DECLARE_FLAG(bool, enable_interpreter); // Input parameters: // LR : return address. @@ -1051,7 +1052,13 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { // R2 : address of first argument. // R3 : current thread. void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) { -#if defined(DART_USE_INTERPRETER) +#if defined(DART_PRECOMPILED_RUNTIME) + __ Stop("Not using interpreter"); +#else + if (!FLAG_enable_interpreter) { + __ Stop("Not using interpreter"); + return; + } // Copy the C stack pointer (R31) into the stack pointer we'll actually use // to access the stack. __ SetupDartSP(); @@ -1172,9 +1179,7 @@ void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) { __ LeaveFrame(); __ RestoreCSP(); __ ret(); -#else - __ Stop("Not using interpreter"); -#endif // defined(DART_USE_INTERPRETER) +#endif // defined(DART_PRECOMPILED_RUNTIME) } // Called for inline allocation of contexts. @@ -1989,7 +1994,13 @@ void StubCode::GenerateLazyCompileStub(Assembler* assembler) { // R4: Arguments descriptor. // R0: Function. void StubCode::GenerateInterpretCallStub(Assembler* assembler) { -#if defined(DART_USE_INTERPRETER) +#if defined(DART_PRECOMPILED_RUNTIME) + __ Stop("Not using interpreter") +#else + if (!FLAG_enable_interpreter) { + __ Stop("Not using interpreter"); + return; + } __ SetPrologueOffset(); __ EnterStubFrame(); @@ -2060,9 +2071,7 @@ void StubCode::GenerateInterpretCallStub(Assembler* assembler) { __ LeaveStubFrame(); __ ret(); -#else - __ Stop("Not using interpreter"); -#endif // defined(DART_USE_INTERPRETER) +#endif // defined(DART_PRECOMPILED_RUNTIME) } // R5: Contains an ICData. diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc index a6e6a767d25..c1fbc5ea4fb 100644 --- a/runtime/vm/stub_code_dbc.cc +++ b/runtime/vm/stub_code_dbc.cc @@ -121,6 +121,14 @@ void StubCode::GenerateAsynchronousGapMarkerStub(Assembler* assembler) { __ Trap(); } +void StubCode::GenerateInterpretCallStub(Assembler* assembler) { + __ Trap(); +} + +void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) { + __ Trap(); +} + } // namespace dart #endif // defined TARGET_ARCH_DBC diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc index 115811774c0..59fd88dfc02 100644 --- a/runtime/vm/stub_code_x64.cc +++ b/runtime/vm/stub_code_x64.cc @@ -33,6 +33,7 @@ DEFINE_FLAG(bool, false, "Set to true for debugging & verifying the slow paths."); DECLARE_FLAG(bool, trace_optimized_ic_calls); +DECLARE_FLAG(bool, enable_interpreter); // Input parameters: // RSP : points to return address. @@ -975,7 +976,13 @@ void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { // RDX : address of first argument. // RCX : current thread. void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) { -#if defined(DART_USE_INTERPRETER) +#if defined(DART_PRECOMPILED_RUNTIME) + __ Stop("Not using interpreter"); +#else + if (!FLAG_enable_interpreter) { + __ Stop("Not using interpreter"); + return; + } // Save frame pointer coming in. __ EnterFrame(0); @@ -1103,9 +1110,7 @@ void StubCode::GenerateInvokeDartCodeFromBytecodeStub(Assembler* assembler) { __ LeaveFrame(); __ ret(); -#else - __ Stop("Not using interpreter"); -#endif // defined(DART_USE_INTERPRETER) +#endif // defined(DART_PRECOMPILED_RUNTIME) } // Called for inline allocation of contexts. @@ -1985,7 +1990,13 @@ void StubCode::GenerateLazyCompileStub(Assembler* assembler) { // R10: Arguments descriptor. // RAX: Function. void StubCode::GenerateInterpretCallStub(Assembler* assembler) { -#if defined(DART_USE_INTERPRETER) +#if defined(DART_PRECOMPILED_RUNTIME) + __ Stop("Not using interpreter"); +#else + if (!FLAG_enable_interpreter) { + __ Stop("Not using interpreter"); + return; + } __ EnterStubFrame(); #if defined(DEBUG) @@ -2050,9 +2061,7 @@ void StubCode::GenerateInterpretCallStub(Assembler* assembler) { __ LeaveStubFrame(); __ ret(); -#else - __ Stop("Not using interpreter"); -#endif // defined(DART_USE_INTERPRETER) +#endif // defined(DART_PRECOMPILED_RUNTIME) } // RBX: Contains an ICData. diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc index 561db06be87..b0687de01e9 100644 --- a/runtime/vm/thread_test.cc +++ b/runtime/vm/thread_test.cc @@ -13,6 +13,8 @@ namespace dart { +DECLARE_FLAG(bool, enable_interpreter); + VM_UNIT_TEST_CASE(Mutex) { // This unit test case needs a running isolate. TestCase::CreateTestIsolate(); @@ -496,11 +498,11 @@ TEST_CASE(SafepointTestDart) { // to get their verification done and exit. Use a specific UserTag // to enable the helpers to verify that the main thread is // successfully interrupted in the pure Dart loop. -#if defined(USING_SIMULATOR) || defined(DART_USE_INTERPRETER) +#if defined(USING_SIMULATOR) const intptr_t kLoopCount = 12345678; #else - const intptr_t kLoopCount = 1234567890; -#endif // defined(USING_SIMULATOR) || defined(DART_USE_INTERPRETER) + const intptr_t kLoopCount = FLAG_enable_interpreter ? 12345678 : 1234567890; +#endif // defined(USING_SIMULATOR) char buffer[1024]; Utils::SNPrint(buffer, sizeof(buffer), "import 'dart:developer';\n" diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni index 5f8dfff563a..23f0402cc43 100644 --- a/runtime/vm/vm_sources.gni +++ b/runtime/vm/vm_sources.gni @@ -126,6 +126,7 @@ vm_sources = [ "instructions_x64.h", "interpreter.cc", "interpreter.h", + "interpreter_unsupported.cc", "isolate.cc", "isolate.h", "isolate_reload.cc", diff --git a/tools/build.py b/tools/build.py index abb1e1dc18e..efeff211735 100755 --- a/tools/build.py +++ b/tools/build.py @@ -32,7 +32,7 @@ def BuildOptions(): 'simarm64,arm64,simdbc,armsimdbc]', default=utils.GuessArchitecture()) result.add_option("-b", "--bytecode", - help='Build with the kernel bytecode interpreter', + help='Build with the kernel bytecode interpreter. DEPRECATED.', default=False, action='store_true') result.add_option("-j", @@ -228,9 +228,9 @@ def EnsureGomaStarted(out_dir): # Returns a tuple (build_config, command to run, whether goma is used) -def BuildOneConfig(options, targets, target_os, mode, arch, kbc): - build_config = utils.GetBuildConf(mode, arch, target_os, kbc=kbc) - out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os, kbc=kbc) +def BuildOneConfig(options, targets, target_os, mode, arch): + build_config = utils.GetBuildConf(mode, arch, target_os) + out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os) using_goma = False # TODO(zra): Remove auto-run of gn, replace with prompt for user to run # gn.py manually. @@ -295,8 +295,7 @@ def Main(): for target_os in options.os: for mode in options.mode: for arch in options.arch: - configs.append(BuildOneConfig(options, targets, target_os, mode, arch, - options.bytecode)) + configs.append(BuildOneConfig(options, targets, target_os, mode, arch)) # Build regular configs. goma_builds = [] diff --git a/tools/gn.py b/tools/gn.py index 005ecc04fd0..9c24ee30793 100755 --- a/tools/gn.py +++ b/tools/gn.py @@ -64,8 +64,8 @@ def GetGNArgs(args): return args.split() -def GetOutDir(mode, arch, target_os, kbc): - return utils.GetBuildRoot(HOST_OS, mode, arch, target_os, kbc=kbc) +def GetOutDir(mode, arch, target_os): + return utils.GetBuildRoot(HOST_OS, mode, arch, target_os) def ToCommandLine(gn_args): @@ -174,9 +174,6 @@ def ToGnArgs(args, mode, arch, target_os): gn_args['target_cpu'] = TargetCpuForArch(arch, target_os) gn_args['dart_target_arch'] = DartTargetCpuForArch(arch) - if args.bytecode: - gn_args['dart_use_interpreter'] = True - if arch != HostCpuForArch(arch): # Training an app-jit snapshot under a simulator is slow. Use script # snapshots instead. @@ -189,6 +186,8 @@ def ToGnArgs(args, mode, arch, target_os): if gn_args['target_os'] in ['linux', 'win']: gn_args['dart_use_fallback_root_certificates'] = True + gn_args['dart_platform_bytecode'] = args.bytecode + gn_args['dart_zlib_path'] = "//runtime/bin/zlib" # Use tcmalloc only when targeting Linux and when not using ASAN. @@ -345,10 +344,6 @@ def parse_args(args): metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,' 'simarm64,arm64,simdbc,armsimdbc]', default='x64') - common_group.add_argument('--bytecode', '-b', - help='Configure with the kernel bytecode interpreter', - default=False, - action="store_true") common_group.add_argument('--mode', '-m', type=str, help='Build variants (comma-separated).', @@ -377,6 +372,10 @@ def parse_args(args): help='Disable ASAN', dest='asan', action='store_false') + other_group.add_argument('--bytecode', '-b', + help='Include bytecode in the VMs platform dill', + default=False, + action="store_true") other_group.add_argument('--clang', help='Use Clang', default=True, @@ -488,7 +487,7 @@ def Main(argv): for target_os in args.os: for mode in args.mode: for arch in args.arch: - out_dir = GetOutDir(mode, arch, target_os, args.bytecode) + out_dir = GetOutDir(mode, arch, target_os) # TODO(infra): Re-enable --check. Many targets fail to use # public_deps to re-expose header files to their dependents. # See dartbug.com/32364 diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart index ef7a85c660b..bd538292f93 100644 --- a/tools/testing/dart/configuration.dart +++ b/tools/testing/dart/configuration.dart @@ -419,10 +419,9 @@ class TestConfiguration { var os = ''; if (system == System.android) os = "Android"; - var kbc = useKernelBytecode ? 'KBC' : ''; var arch = architecture.name.toUpperCase(); - var normal = '$modeName$os$arch$kbc'; - var cross = '$modeName${os}X$arch$kbc'; + var normal = '$modeName$os$arch'; + var cross = '$modeName${os}X$arch'; var outDir = system.outputDirectory; var normalDir = new Directory(new Path('$outDir$normal').toNativePath()); var crossDir = new Directory(new Path('$outDir$cross').toNativePath()); diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart index c8c92278564..a7561037ac8 100644 --- a/tools/testing/dart/runtime_configuration.dart +++ b/tools/testing/dart/runtime_configuration.dart @@ -219,11 +219,7 @@ class StandaloneDartRuntimeConfiguration extends DartVmRuntimeConfiguration { List args = arguments; if (suite.configuration.compiler == Compiler.dartkb) { - args.removeWhere( - (String arg) => arg.startsWith('--optimization-counter-threshold')); - args.removeWhere( - (String arg) => arg.startsWith('--optimization_counter_threshold')); - args = ['--optimization-counter-threshold=-1']..addAll(args); + args.add('--enable_interpreter'); } String executable = suite.dartVmBinaryFileName; diff --git a/tools/utils.py b/tools/utils.py index a6b7578fa5b..38c1244e82a 100644 --- a/tools/utils.py +++ b/tools/utils.py @@ -293,32 +293,27 @@ def IsCrossBuild(target_os, arch): (target_os != GuessOS())) -def GetBuildConf(mode, arch, conf_os=None, kbc=False): - kbc_suffix = '' - if kbc: - kbc_suffix = 'KBC' +def GetBuildConf(mode, arch, conf_os=None): if conf_os == 'android': - return '%s%s%s%s' % (GetBuildMode(mode), conf_os.title(), arch.upper(), - kbc_suffix) + return '%s%s%s' % (GetBuildMode(mode), conf_os.title(), arch.upper()) else: # Ask for a cross build if the host and target architectures don't match. host_arch = ARCH_GUESS cross_build = '' if GetArchFamily(host_arch) != GetArchFamily(arch): cross_build = 'X' - return '%s%s%s%s' % (GetBuildMode(mode), cross_build, arch.upper(), - kbc_suffix) + return '%s%s%s' % (GetBuildMode(mode), cross_build, arch.upper()) def GetBuildDir(host_os): return BUILD_ROOT[host_os] -def GetBuildRoot(host_os, mode=None, arch=None, target_os=None, kbc=False): +def GetBuildRoot(host_os, mode=None, arch=None, target_os=None): build_root = GetBuildDir(host_os) if mode: build_root = os.path.join(build_root, - GetBuildConf(mode, arch, target_os, kbc)) + GetBuildConf(mode, arch, target_os)) return build_root