Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(862)

Unified Diff: runtime/vm/precompiler.cc

Issue 2300873002: VM: Compute static guarded cid for final instance fields. (Closed)
Patch Set: address comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/precompiler.cc
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 11a7b3ba8bb4ede5b7c18c23155962d9f28fd269..7977f78b30fc07e5eddff38ace656c96ce4cc950 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -78,9 +78,54 @@ DECLARE_FLAG(bool, trace_irregexp);
class DartPrecompilationPipeline : public DartCompilationPipeline {
public:
- DartPrecompilationPipeline() : result_type_(CompileType::None()) { }
+ explicit DartPrecompilationPipeline(Zone* zone,
+ FieldTypeMap* field_map = NULL)
+ : zone_(zone),
+ result_type_(CompileType::None()),
+ field_map_(field_map) { }
virtual void FinalizeCompilation(FlowGraph* flow_graph) {
+ if ((field_map_ != NULL )&&
+ flow_graph->function().IsGenerativeConstructor()) {
+ for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
+ !block_it.Done();
+ block_it.Advance()) {
+ ForwardInstructionIterator it(block_it.Current());
+ for (; !it.Done(); it.Advance()) {
+ StoreInstanceFieldInstr* store = it.Current()->AsStoreInstanceField();
+ if (store != NULL) {
+ if (!store->field().IsNull() && store->field().is_final()) {
+ if (FLAG_trace_precompiler) {
+ THR_Print("Found store to %s <- %s\n",
+ store->field().ToCString(),
+ store->value()->Type()->ToCString());
+ }
+ FieldTypePair* entry = field_map_->Lookup(&store->field());
+ if (entry == NULL) {
+ field_map_->Insert(FieldTypePair(
+ &Field::Handle(zone_, store->field().raw()), // Re-wrap.
+ store->value()->Type()->ToCid()));
+ if (FLAG_trace_precompiler) {
+ THR_Print(" initial type = %s\n",
+ store->value()->Type()->ToCString());
+ }
+ continue;
+ }
+ CompileType type = CompileType::FromCid(entry->cid_);
+ if (FLAG_trace_precompiler) {
+ THR_Print(" old type = %s\n", type.ToCString());
+ }
+ type.Union(store->value()->Type());
+ if (FLAG_trace_precompiler) {
+ THR_Print(" new type = %s\n", type.ToCString());
+ }
+ entry->cid_ = type.ToCid();
+ }
+ }
+ }
+ }
+ }
+
CompileType result_type = CompileType::None();
for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
!block_it.Done();
@@ -99,7 +144,9 @@ class DartPrecompilationPipeline : public DartCompilationPipeline {
CompileType result_type() { return result_type_; }
private:
+ Zone* zone_;
CompileType result_type_;
+ FieldTypeMap* field_map_;
};
@@ -180,6 +227,7 @@ Precompiler::Precompiler(Thread* thread, bool reset_fields) :
typeargs_to_retain_(),
types_to_retain_(),
consts_to_retain_(),
+ field_type_map_(),
error_(Error::Handle()) {
}
@@ -203,6 +251,10 @@ void Precompiler::DoCompileAll(
// Precompile static initializers to compute result type information.
PrecompileStaticInitializers();
+ // Precompile constructors to compute type information for final fields.
+ ClearAllCode();
+ PrecompileConstructors();
+
for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
if (FLAG_trace_precompiler) {
THR_Print("Precompiler round %" Pd "\n", round);
@@ -339,6 +391,52 @@ void Precompiler::PrecompileStaticInitializers() {
}
+void Precompiler::PrecompileConstructors() {
+ class ConstructorVisitor : public FunctionVisitor {
+ public:
+ explicit ConstructorVisitor(Zone* zone, FieldTypeMap* map)
+ : zone_(zone), field_type_map_(map) {
+ ASSERT(map != NULL);
+ }
+ void Visit(const Function& function) {
+ if (!function.IsGenerativeConstructor()) return;
+ if (function.HasCode()) {
+ // Const constructors may have been visited before. Recompile them here
+ // to collect type information for final fields for them as well.
+ function.ClearCode();
+ }
+ if (FLAG_trace_precompiler) {
+ THR_Print("Precompiling constructor %s\n", function.ToCString());
+ }
+ CompileFunction(Thread::Current(),
+ zone_,
+ function,
+ field_type_map_);
+ }
+ private:
+ Zone* zone_;
+ FieldTypeMap* field_type_map_;
+ };
+
+ HANDLESCOPE(T);
+ ConstructorVisitor visitor(zone_, &field_type_map_);
+ VisitFunctions(&visitor);
+
+ FieldTypeMap::Iterator it(field_type_map_.GetIterator());
+ for (FieldTypePair* current = it.Next();
+ current != NULL;
+ current = it.Next()) {
+ const intptr_t cid = current->cid_;
+ current->field_->set_guarded_cid(cid);
+ current->field_->set_is_nullable(cid == kNullCid || cid == kDynamicCid);
+ if (FLAG_trace_precompiler) {
+ THR_Print("Field %s <- Type %s\n", current->field_->ToCString(),
+ Class::Handle(T->isolate()->class_table()->At(cid)).ToCString());
+ }
+ }
+}
+
+
void Precompiler::ClearAllCode() {
class ClearCodeFunctionVisitor : public FunctionVisitor {
void Visit(const Function& function) {
@@ -609,7 +707,7 @@ void Precompiler::ProcessFunction(const Function& function) {
ASSERT(!function.is_abstract());
ASSERT(!function.IsRedirectingFactory());
- error_ = CompileFunction(thread_, function);
+ error_ = CompileFunction(thread_, zone_, function);
if (!error_.IsNull()) {
Jump(error_);
}
@@ -946,7 +1044,7 @@ RawFunction* Precompiler::CompileStaticInitializer(const Field& field,
ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field);
parsed_function->AllocateVariables();
- DartPrecompilationPipeline pipeline;
+ DartPrecompilationPipeline pipeline(zone.GetZone());
PrecompileParsedFunctionHelper helper(parsed_function,
/* optimized = */ true);
bool success = helper.Compile(&pipeline);
@@ -1046,7 +1144,7 @@ RawObject* Precompiler::ExecuteOnce(SequenceNode* fragment) {
parsed_function->AllocateVariables();
// Non-optimized code generator.
- DartPrecompilationPipeline pipeline;
+ DartPrecompilationPipeline pipeline(Thread::Current()->zone());
PrecompileParsedFunctionHelper helper(parsed_function,
/* optimized = */ false);
helper.Compile(&pipeline);
@@ -3073,16 +3171,16 @@ static RawError* PrecompileFunctionHelper(CompilationPipeline* pipeline,
RawError* Precompiler::CompileFunction(Thread* thread,
- const Function& function) {
+ Zone* zone,
+ const Function& function,
+ FieldTypeMap* field_type_map) {
VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function);
- CompilationPipeline* pipeline =
- CompilationPipeline::New(thread->zone(), function);
-
ASSERT(FLAG_precompiled_mode);
const bool optimized = function.IsOptimizable(); // False for natives.
- return PrecompileFunctionHelper(pipeline, function, optimized);
+ DartPrecompilationPipeline pipeline(zone, field_type_map);
+ return PrecompileFunctionHelper(&pipeline, function, optimized);
}
#endif // DART_PRECOMPILER
« no previous file with comments | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698