[vm/compiler] Don't serialize precompiled constructors.

The code from these precompiled constructors is thrown away,
and if we are adding constants to the LLVM constant pool, then
we may add constants that will not actually appear in the final
program which may cause issues for tree shaking.

If these constructors are actually used, then they will be
recompiled normally.

In addition, we also do not add unreferenced constants to the
constant pool. That is, these constant definitions will not have
an `llvm_index` value in their serialized form when the LLVM
constant pool is populated.

Bug: https://github.com/dart-lang/sdk/issues/38661
Change-Id: I2a3702fd3f174504a5f01458064306cd687d7949
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/119339
Commit-Queue: Teagan Strickland <sstrickl@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
This commit is contained in:
Teagan Strickland 2019-10-02 10:07:29 +00:00 committed by commit-bot@chromium.org
parent f0b2a46734
commit 0e24c2e6e5
3 changed files with 54 additions and 22 deletions

View file

@ -0,0 +1,27 @@
// Copyright (c) 2019, 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.
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --populate_llvm_constant_pool
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --verbose_flow_graph_serialization
// VMOptions=--serialize_flow_graphs_to=il_tmp.txt --no_serialize_flow_graph_types --verbose_flow_graph_serialization
class A {
const A();
}
class B {
Object a = const A();
}
foo(int i) {
if (i == 3) {
new B();
}
}
main(args) {
foo(4);
}

View file

@ -200,26 +200,6 @@ void Precompiler::DoCompileAll() {
StackZone stack_zone(T);
zone_ = stack_zone.GetZone();
// Check that both the file open and write callbacks are available, though
// we only use the latter during IL processing.
if (FLAG_serialize_flow_graphs_to != nullptr &&
Dart::file_write_callback() != nullptr) {
if (auto file_open = Dart::file_open_callback()) {
auto file = file_open(FLAG_serialize_flow_graphs_to, /*write=*/true);
set_il_serialization_stream(file);
}
if (FLAG_populate_llvm_constant_pool) {
auto const object_store = I->object_store();
auto& llvm_constants = GrowableObjectArray::Handle(
zone_, GrowableObjectArray::New(16, Heap::kOld));
auto& llvm_constants_hash_table = Array::Handle(
zone_, HashTables::New<FlowGraphSerializer::LLVMConstantsMap>(
16, Heap::kOld));
object_store->set_llvm_constant_pool(llvm_constants);
object_store->set_llvm_constant_hash_table(llvm_constants_hash_table);
}
}
if (FLAG_use_bare_instructions) {
// Since we keep the object pool until the end of AOT compilation, it
// will hang on to its entries until the very end. Therefore we have
@ -255,6 +235,29 @@ void Precompiler::DoCompileAll() {
ClassFinalizer::ClearAllCode(
/*including_nonchanging_cids=*/FLAG_use_bare_instructions);
// After this point, it should be safe to serialize flow graphs produced
// during compilation and add constants to the LLVM constant pool.
//
// Check that both the file open and write callbacks are available, though
// we only use the latter during IL processing.
if (FLAG_serialize_flow_graphs_to != nullptr &&
Dart::file_write_callback() != nullptr) {
if (auto file_open = Dart::file_open_callback()) {
auto file = file_open(FLAG_serialize_flow_graphs_to, /*write=*/true);
set_il_serialization_stream(file);
}
if (FLAG_populate_llvm_constant_pool) {
auto const object_store = I->object_store();
auto& llvm_constants = GrowableObjectArray::Handle(
Z, GrowableObjectArray::New(16, Heap::kOld));
auto& llvm_constants_hash_table = Array::Handle(
Z, HashTables::New<FlowGraphSerializer::LLVMConstantsMap>(
16, Heap::kOld));
object_store->set_llvm_constant_pool(llvm_constants);
object_store->set_llvm_constant_hash_table(llvm_constants_hash_table);
}
}
// All stubs have already been generated, all of them share the same pool.
// We use that pool to initialize our global object pool, to guarantee
// stubs as well as code compiled from here on will have the same pool.
@ -346,8 +349,8 @@ void Precompiler::DoCompileAll() {
Dart::file_write_callback() != nullptr) {
if (auto file_close = Dart::file_close_callback()) {
file_close(il_serialization_stream());
set_il_serialization_stream(nullptr);
}
set_il_serialization_stream(nullptr);
if (FLAG_populate_llvm_constant_pool) {
// We don't want the Array backing for the map from constants to
// indices in the snapshot, only the constant pool itself.

View file

@ -745,7 +745,9 @@ SExpression* FlowGraphSerializer::ConstantPoolToSExp(GraphEntryInstr* start) {
elem->AddExtra("type", type->ToSExpression(this));
}
}
if (FLAG_populate_llvm_constant_pool) {
// Only add constants to the LLVM constant pool that are actually used in
// the flow graph.
if (FLAG_populate_llvm_constant_pool && definition->HasUses()) {
auto const pool_len = llvm_pool_.Length();
llvm_index_ = Smi::New(pool_len);
llvm_index_ =