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

Unified Diff: runtime/vm/precompiler.cc

Issue 2699853002: Sort class IDs before training AppJIT snapshots (Closed)
Patch Set: Add DeleteAllCode Created 3 years, 10 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 a053603d4dbec6a7e7fa61da145c8fe3d921ddfa..f3b5822ec4a73c024e8f59ff59839252eff2df0a 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -9,6 +9,7 @@
#include "vm/ast_printer.h"
#include "vm/branch_optimizer.h"
#include "vm/cha.h"
+#include "vm/class_finalizer.h"
#include "vm/code_generator.h"
#include "vm/code_patcher.h"
#include "vm/compiler.h"
@@ -427,7 +428,7 @@ void Precompiler::DoCompileAll(
// because their class hasn't been finalized yet.
FinalizeAllClasses();
- SortClasses();
+ ClassFinalizer::SortClasses();
TypeRangeCache trc(this, T, I->class_table()->NumCids());
VerifyJITFeedback();
@@ -435,7 +436,7 @@ void Precompiler::DoCompileAll(
PrecompileStaticInitializers();
// Precompile constructors to compute type information for final fields.
- ClearAllCode();
+ ClassFinalizer::ClearAllCode();
PrecompileConstructors();
for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
@@ -455,7 +456,7 @@ void Precompiler::DoCompileAll(
// - method-extractors
// that are needed in early iterations but optimized away in later
// iterations.
- ClearAllCode();
+ ClassFinalizer::ClearAllCode();
CollectDynamicFunctionNames();
@@ -619,24 +620,6 @@ void Precompiler::PrecompileConstructors() {
}
-void Precompiler::ClearAllCode() {
- class ClearCodeFunctionVisitor : public FunctionVisitor {
- void Visit(const Function& function) {
- function.ClearCode();
- function.ClearICDataArray();
- }
- };
- ClearCodeFunctionVisitor function_visitor;
- ProgramVisitor::VisitFunctions(&function_visitor);
-
- class ClearCodeClassVisitor : public ClassVisitor {
- void Visit(const Class& cls) { cls.DisableAllocationStub(); }
- };
- ClearCodeClassVisitor class_visitor;
- ProgramVisitor::VisitClasses(&class_visitor);
-}
-
-
void Precompiler::AddRoots(Dart_QualifiedFunctionName embedder_entry_points[]) {
// Note that <rootlibrary>.main is not a root. The appropriate main will be
// discovered through _getMainClosure.
@@ -2543,242 +2526,6 @@ void Precompiler::FinalizeAllClasses() {
}
-void Precompiler::SortClasses() {
- ClassTable* table = I->class_table();
- intptr_t num_cids = table->NumCids();
- intptr_t* old_to_new_cid = new intptr_t[num_cids];
- for (intptr_t cid = 0; cid < kNumPredefinedCids; cid++) {
- old_to_new_cid[cid] = cid; // The predefined classes cannot change cids.
- }
- for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
- old_to_new_cid[cid] = -1;
- }
-
- intptr_t next_new_cid = kNumPredefinedCids;
- GrowableArray<intptr_t> dfs_stack;
- Class& cls = Class::Handle(Z);
- GrowableObjectArray& subclasses = GrowableObjectArray::Handle(Z);
-
- // Object doesn't use its subclasses list.
- for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
- if (!table->HasValidClassAt(cid)) {
- continue;
- }
- cls = table->At(cid);
- if (cls.is_patch()) {
- continue;
- }
- if (cls.SuperClass() == I->object_store()->object_class()) {
- dfs_stack.Add(cid);
- }
- }
-
- while (dfs_stack.length() > 0) {
- intptr_t cid = dfs_stack.RemoveLast();
- ASSERT(table->HasValidClassAt(cid));
- cls = table->At(cid);
- ASSERT(!cls.IsNull());
- if (old_to_new_cid[cid] == -1) {
- old_to_new_cid[cid] = next_new_cid++;
- if (FLAG_trace_precompiler) {
- THR_Print("%" Pd ": %s, was %" Pd "\n", old_to_new_cid[cid],
- cls.ToCString(), cid);
- }
- }
- subclasses = cls.direct_subclasses();
- if (!subclasses.IsNull()) {
- for (intptr_t i = 0; i < subclasses.Length(); i++) {
- cls ^= subclasses.At(i);
- ASSERT(!cls.IsNull());
- dfs_stack.Add(cls.id());
- }
- }
- }
-
- // Top-level classes, typedefs, patch classes, etc.
- for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
- if (old_to_new_cid[cid] == -1) {
- old_to_new_cid[cid] = next_new_cid++;
- if (FLAG_trace_precompiler && table->HasValidClassAt(cid)) {
- cls = table->At(cid);
- THR_Print("%" Pd ": %s, was %" Pd "\n", old_to_new_cid[cid],
- cls.ToCString(), cid);
- }
- }
- }
- ASSERT(next_new_cid == num_cids);
-
- RemapClassIds(old_to_new_cid);
- delete[] old_to_new_cid;
- RehashTypes(); // Types use cid's as part of their hashes.
-}
-
-
-class CidRewriteVisitor : public ObjectVisitor {
- public:
- explicit CidRewriteVisitor(intptr_t* old_to_new_cids)
- : old_to_new_cids_(old_to_new_cids) {}
-
- intptr_t Map(intptr_t cid) {
- ASSERT(cid != -1);
- return old_to_new_cids_[cid];
- }
-
- void VisitObject(RawObject* obj) {
- if (obj->IsClass()) {
- RawClass* cls = Class::RawCast(obj);
- cls->ptr()->id_ = Map(cls->ptr()->id_);
- } else if (obj->IsField()) {
- RawField* field = Field::RawCast(obj);
- field->ptr()->guarded_cid_ = Map(field->ptr()->guarded_cid_);
- field->ptr()->is_nullable_ = Map(field->ptr()->is_nullable_);
- } else if (obj->IsTypeParameter()) {
- RawTypeParameter* param = TypeParameter::RawCast(obj);
- param->ptr()->parameterized_class_id_ =
- Map(param->ptr()->parameterized_class_id_);
- } else if (obj->IsType()) {
- RawType* type = Type::RawCast(obj);
- RawObject* id = type->ptr()->type_class_id_;
- if (!id->IsHeapObject()) {
- type->ptr()->type_class_id_ =
- Smi::New(Map(Smi::Value(Smi::RawCast(id))));
- }
- } else {
- intptr_t old_cid = obj->GetClassId();
- intptr_t new_cid = Map(old_cid);
- if (old_cid != new_cid) {
- // Don't touch objects that are unchanged. In particular, Instructions,
- // which are write-protected.
- obj->SetClassId(new_cid);
- }
- }
- }
-
- private:
- intptr_t* old_to_new_cids_;
-};
-
-
-void Precompiler::RemapClassIds(intptr_t* old_to_new_cid) {
- // Code, ICData, allocation stubs have now-invalid cids.
- ClearAllCode();
-
- {
- HeapIterationScope his;
-
- // Update the class table. Do it before rewriting cids in headers, as the
- // heap walkers load an object's size *after* calling the visitor.
- I->class_table()->Remap(old_to_new_cid);
-
- // Rewrite cids in headers and cids in Classes, Fields, Types and
- // TypeParameters.
- {
- CidRewriteVisitor visitor(old_to_new_cid);
- I->heap()->VisitObjects(&visitor);
- }
- }
-
-#if defined(DEBUG)
- I->class_table()->Validate();
- I->heap()->Verify();
-#endif
-}
-
-
-class ClearTypeHashVisitor : public ObjectVisitor {
- public:
- explicit ClearTypeHashVisitor(Zone* zone)
- : type_param_(TypeParameter::Handle(zone)),
- type_(Type::Handle(zone)),
- type_args_(TypeArguments::Handle(zone)),
- bounded_type_(BoundedType::Handle(zone)) {}
-
- void VisitObject(RawObject* obj) {
- if (obj->IsTypeParameter()) {
- type_param_ ^= obj;
- type_param_.SetHash(0);
- } else if (obj->IsType()) {
- type_ ^= obj;
- type_.SetHash(0);
- } else if (obj->IsBoundedType()) {
- bounded_type_ ^= obj;
- bounded_type_.SetHash(0);
- } else if (obj->IsTypeArguments()) {
- type_args_ ^= obj;
- type_args_.SetHash(0);
- }
- }
-
- private:
- TypeParameter& type_param_;
- Type& type_;
- TypeArguments& type_args_;
- BoundedType& bounded_type_;
-};
-
-
-void Precompiler::RehashTypes() {
- // Clear all cached hash values.
- {
- HeapIterationScope his;
- ClearTypeHashVisitor visitor(Z);
- I->heap()->VisitObjects(&visitor);
- }
-
- // Rehash the canonical Types table.
- ObjectStore* object_store = I->object_store();
- GrowableObjectArray& types =
- GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
- Array& types_array = Array::Handle(Z);
- Type& type = Type::Handle(Z);
- {
- CanonicalTypeSet types_table(Z, object_store->canonical_types());
- types_array = HashTables::ToArray(types_table, false);
- for (intptr_t i = 0; i < types_array.Length(); i++) {
- type ^= types_array.At(i);
- types.Add(type);
- }
- types_table.Release();
- }
-
- intptr_t dict_size = Utils::RoundUpToPowerOfTwo(types.Length() * 4 / 3);
- types_array = HashTables::New<CanonicalTypeSet>(dict_size, Heap::kOld);
- CanonicalTypeSet types_table(Z, types_array.raw());
- for (intptr_t i = 0; i < types.Length(); i++) {
- type ^= types.At(i);
- bool present = types_table.Insert(type);
- ASSERT(!present || type.IsRecursive());
- }
- object_store->set_canonical_types(types_table.Release());
-
- // Rehash the canonical TypeArguments table.
- Array& typeargs_array = Array::Handle(Z);
- GrowableObjectArray& typeargs =
- GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
- TypeArguments& typearg = TypeArguments::Handle(Z);
- {
- CanonicalTypeArgumentsSet typeargs_table(
- Z, object_store->canonical_type_arguments());
- typeargs_array = HashTables::ToArray(typeargs_table, false);
- for (intptr_t i = 0; i < typeargs_array.Length(); i++) {
- typearg ^= typeargs_array.At(i);
- typeargs.Add(typearg);
- }
- typeargs_table.Release();
- }
-
- dict_size = Utils::RoundUpToPowerOfTwo(typeargs.Length() * 4 / 3);
- typeargs_array =
- HashTables::New<CanonicalTypeArgumentsSet>(dict_size, Heap::kOld);
- CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw());
- for (intptr_t i = 0; i < typeargs.Length(); i++) {
- typearg ^= typeargs.At(i);
- bool present = typeargs_table.Insert(typearg);
- ASSERT(!present || typearg.IsRecursive());
- }
- object_store->set_canonical_type_arguments(typeargs_table.Release());
-}
-
void Precompiler::VerifyJITFeedback() {
if (jit_feedback_ == NULL) return;
« 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