VM: Add dart_precompiled build target, a standalone VM without the JIT compiler.

This removes most of the compiler-related code from dart_precompiled:
x64 stripped binary size 13M -> 9.1M
ARM stripped binary size 12M -> 8.3M

The precompiled build defines the DART_PRECOMPILED macro. This
stubs out the public interface to the compiler/parser with empty
function bodies.

Use gcc options -ffunction-sections and --gc-sections to make the linker remove
unused functions/symbols.

BUG=
R=rmacnak@google.com

Review URL: https://codereview.chromium.org/1459443002 .
This commit is contained in:
Florian Schneider 2015-11-19 10:13:16 +01:00
parent a689bf4180
commit f0a35b3260
14 changed files with 352 additions and 11 deletions

View file

@ -25,6 +25,7 @@
'type': 'none',
'dependencies': [
'runtime/dart-runtime.gyp:dart',
'runtime/dart-runtime.gyp:dart_precompiled',
'runtime/dart-runtime.gyp:dart_no_snapshot',
'runtime/dart-runtime.gyp:run_vm_tests',
'runtime/dart-runtime.gyp:process_test',

View file

@ -625,6 +625,49 @@
},
},
},
{
# dart binary for running precompiled snapshots without the compiler.
'target_name': 'dart_precompiled',
'type': 'executable',
'dependencies': [
'libdart_precompiled',
'libdart_builtin',
'libdart_io',
'build_observatory#host',
'generate_resources_cc_file#host',
'generate_observatory_assets_cc_file#host',
],
'include_dirs': [
'..',
],
'sources': [
'main.cc',
'builtin_common.cc',
'builtin_natives.cc',
'builtin_nolib.cc',
'builtin.h',
'io_natives.h',
'vmservice_impl.cc',
'vmservice_impl.h',
'snapshot_empty.cc',
'<(resources_cc_file)',
'<(observatory_assets_cc_file)',
],
'conditions': [
['OS=="win"', {
'link_settings': {
'libraries': [ '-lws2_32.lib', '-lRpcrt4.lib', '-lwinmm.lib' ],
},
# Generate an import library on Windows, by exporting a function.
# Extensions use this import library to link to the API in dart.exe.
'msvs_settings': {
'VCLinkerTool': {
'AdditionalOptions': [ '/EXPORT:Dart_True' ],
},
},
}],
],
},
{
# dart binary built for the host. It does not use a snapshot
# and does not include Observatory.

View file

@ -54,6 +54,40 @@
],
},
},
{
'target_name': 'libdart_precompiled',
'type': 'static_library',
'dependencies': [
'libdart_lib',
'libdart_vm_precompiled',
'libdouble_conversion',
'generate_version_cc_file#host',
],
'include_dirs': [
'.',
],
'sources': [
'include/dart_api.h',
'include/dart_mirrors_api.h',
'include/dart_native_api.h',
'include/dart_tools_api.h',
'vm/dart_api_impl.cc',
'vm/debugger_api_impl.cc',
'vm/mirrors_api_impl.cc',
'vm/native_api_impl.cc',
'vm/version.h',
'<(version_cc_file)',
],
'defines': [
# The only effect of DART_SHARED_LIB is to export the Dart API entries.
'DART_SHARED_LIB',
],
'direct_dependent_settings': {
'include_dirs': [
'include',
],
},
},
{
'target_name': 'generate_version_cc_file',
'type': 'none',

View file

@ -13,7 +13,6 @@
#include "vm/debugger.h"
#include "vm/deopt_instructions.h"
#include "vm/exceptions.h"
#include "vm/intermediate_language.h"
#include "vm/object_store.h"
#include "vm/message.h"
#include "vm/message_handler.h"

View file

@ -77,6 +77,7 @@ DECLARE_FLAG(bool, trace_irregexp);
bool Compiler::always_optimize_ = false;
bool Compiler::allow_recompilation_ = true;
#ifndef DART_PRECOMPILED
// TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove
// separate helpers functions & `optimizing` args.
@ -1731,9 +1732,7 @@ void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
void BackgroundCompiler::Stop(BackgroundCompiler* task) {
ASSERT(Isolate::Current()->background_compiler() == task);
if (task == NULL) {
return;
}
ASSERT(task != NULL);
BackgroundCompilationQueue* function_queue = task->function_queue();
Monitor* queue_monitor = task->queue_monitor_;
@ -1792,4 +1791,112 @@ void BackgroundCompiler::EnsureInit(Thread* thread) {
}
}
#else // DART_PRECOMPILED
DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
UNREACHABLE();
}
bool Compiler::IsBackgroundCompilation() {
UNREACHABLE();
return false;
}
RawError* Compiler::Compile(const Library& library, const Script& script) {
UNREACHABLE();
return Error::null();
}
RawError* Compiler::CompileClass(const Class& cls) {
UNREACHABLE();
return Error::null();
}
RawError* Compiler::CompileFunction(Thread* thread,
const Function& function) {
UNREACHABLE();
return Error::null();
}
RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
const Function& function) {
UNREACHABLE();
return Error::null();
}
RawError* Compiler::CompileOptimizedFunction(Thread* thread,
const Function& function,
intptr_t osr_id) {
UNREACHABLE();
return Error::null();
}
RawError* Compiler::CompileParsedFunction(
ParsedFunction* parsed_function) {
UNREACHABLE();
return Error::null();
}
void Compiler::ComputeLocalVarDescriptors(const Code& code) {
UNREACHABLE();
}
RawError* Compiler::CompileAllFunctions(const Class& cls) {
UNREACHABLE();
return Error::null();
}
void Compiler::CompileStaticInitializer(const Field& field) {
UNREACHABLE();
}
RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
ASSERT(field.HasPrecompiledInitializer());
const Function& initializer =
Function::Handle(field.PrecompiledInitializer());
return DartEntry::InvokeFunction(initializer, Object::empty_array());
}
RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
UNREACHABLE();
return Object::null();
}
void BackgroundCompiler::CompileOptimized(const Function& function) {
UNREACHABLE();
}
void BackgroundCompiler::VisitPointers(ObjectPointerVisitor* visitor) {
UNREACHABLE();
}
void BackgroundCompiler::Stop(BackgroundCompiler* task) {
UNREACHABLE();
}
void BackgroundCompiler::EnsureInit(Thread* thread) {
UNREACHABLE();
}
#endif // DART_PRECOMPILED
} // namespace dart

View file

@ -4,7 +4,6 @@
#include "vm/dart_api_impl.h"
#include "vm/dart_api_state.h"
#include "vm/intermediate_language.h"
#include "vm/object.h"
#include "vm/unit_test.h"

View file

@ -1695,7 +1695,9 @@ void Isolate::LowLevelShutdown() {
void Isolate::Shutdown() {
ASSERT(this == Isolate::Current());
// Wait until all background compilation has finished.
BackgroundCompiler::Stop(background_compiler_);
if (background_compiler_ != NULL) {
BackgroundCompiler::Stop(background_compiler_);
}
#if defined(DEBUG)
if (heap_ != NULL) {

View file

@ -6,8 +6,6 @@
#include "vm/assembler.h"
#include "vm/il_printer.h"
#include "vm/intermediate_language.h"
#include "vm/flow_graph_compiler.h"
#include "vm/log.h"
#include "vm/stack_frame.h"

View file

@ -3,6 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
#include "vm/parser.h"
#include "vm/flags.h"
#ifndef DART_PRECOMPILED
#include "lib/invocation_mirror.h"
#include "platform/utils.h"
@ -13,7 +16,6 @@
#include "vm/compiler_stats.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/handles.h"
#include "vm/hash_table.h"
@ -14339,3 +14341,90 @@ void Parser::SkipQualIdent() {
}
} // namespace dart
#else // DART_PRECOMPILED
namespace dart {
DEFINE_FLAG(bool, enable_mirrors, true,
"Disable to make importing dart:mirrors an error.");
DEFINE_FLAG(bool, load_deferred_eagerly, false,
"Load deferred libraries eagerly.");
DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily");
LocalVariable* ParsedFunction::EnsureExpressionTemp() {
UNREACHABLE();
return NULL;
}
void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) {
UNREACHABLE();
}
void ParsedFunction::SetRegExpCompileData(
RegExpCompileData* regexp_compile_data) {
UNREACHABLE();
}
void ParsedFunction::AllocateVariables() {
UNREACHABLE();
}
void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) {
UNREACHABLE();
}
void Parser::ParseCompilationUnit(const Library& library,
const Script& script) {
UNREACHABLE();
}
void Parser::ParseClass(const Class& cls) {
UNREACHABLE();
}
RawObject* Parser::ParseFunctionParameters(const Function& func) {
UNREACHABLE();
return Object::null();
}
void Parser::ParseFunction(ParsedFunction* parsed_function) {
UNREACHABLE();
}
RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) {
UNREACHABLE();
return Object::null();
}
ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) {
UNREACHABLE();
return NULL;
}
ArgumentListNode* Parser::BuildNoSuchMethodArguments(
intptr_t call_pos,
const String& function_name,
const ArgumentListNode& function_args,
const LocalVariable* temp_for_last_arg,
bool is_super_invocation) {
UNREACHABLE();
return NULL;
}
} // namespace dart
#endif // DART_PRECOMPILED

View file

@ -588,6 +588,7 @@ void Precompiler::AddInstantiatedClass(const Class& cls) {
class_count_++;
cls.set_is_allocated(true);
cls.EnsureIsFinalized(T);
changed_ = true;
if (FLAG_trace_precompiler) {

View file

@ -95,6 +95,69 @@
},
}]],
},
{
'target_name': 'libdart_vm_precompiled',
'type': 'static_library',
'toolsets':['host', 'target'],
'includes': [
'vm_sources.gypi',
'../platform/platform_headers.gypi',
'../platform/platform_sources.gypi',
],
'sources/': [
# Exclude all _test.[cc|h] files.
['exclude', '_test\\.(cc|h)$'],
],
'include_dirs': [
'..',
],
'defines': [
'DART_PRECOMPILED',
],
'conditions': [
['OS=="linux"', {
'link_settings': {
'libraries': [
'-lpthread',
'-lrt',
'-ldl',
],
},
}],
['OS=="android" and _toolset=="host"', {
'link_settings': {
'libraries': [
'-lpthread',
'-lrt',
'-ldl',
],
},
}],
['OS=="win"', {
'sources/' : [
['exclude', 'gdbjit.cc'],
],
}],
['dart_vtune_support==0', {
'sources/' : [
['exclude', 'vtune\\.(cc|h)$'],
],
}],
['dart_vtune_support==1', {
'include_dirs': ['<(dart_vtune_root)/include'],
'defines': ['DART_VTUNE_SUPPORT'],
'link_settings': {
'conditions': [
['OS=="linux"', {
'libraries': ['-ljitprofiling'],
}],
['OS=="win"', {
'libraries': ['-ljitprofiling.lib'],
}],
],
},
}]],
},
{
'target_name': 'libdart_vm_nosnapshot',
'type': 'static_library',

View file

@ -87,7 +87,7 @@ main(List args) {
var ld_library_path = new String.fromEnvironment("LD_LIBRARY_PATH");
ld_library_path = "${ld_library_path}:${tmp.path}";
exec = "${dart_executable}";
exec = "${dart_executable}_precompiled";
args = ["--run-precompiled-snapshot", "ignored_script", "--version"];
print("LD_LIBRARY_PATH=$ld_library_path $exec ${args.join(' ')}");
result = Process.runSync(exec, args,

View file

@ -86,7 +86,7 @@ main(List args) {
ld_library_path = "${ld_library_path}:${tmp.path}";
result = Process.runSync(
"${dart_executable}",
"${dart_executable}_precompiled",
["--run-precompiled-snapshot", "ignored_script", "--hello"],
workingDirectory: tmp.path,
environment: {"LD_LIBRARY_PATH": ld_library_path});

View file

@ -236,6 +236,11 @@
],
'cflags': [
'-O3',
'-fdata-sections',
'-ffunction-sections',
],
'ldflags': [
'-Wl,--gc-sections',
],
},
},