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

Unified Diff: runtime/vm/precompiler.cc

Issue 1275653002: Tree-shaking: use a hash set for tracking live selectors, drop uncompiled functions. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« runtime/vm/precompiler.h ('K') | « 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 52287f3abc2b0e86dcfca35cdedd9115052c1164..2cff2f57df7a36943628035a891a55fd38779509 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -49,11 +49,13 @@ Precompiler::Precompiler(Thread* thread) :
changed_(false),
function_count_(0),
class_count_(0),
+ selector_count_(0),
+ dropped_function_count_(0),
libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
pending_functions_(GrowableObjectArray::Handle(Z,
GrowableObjectArray::New())),
collected_closures_(GrowableObjectArray::Handle(Z, I->collected_closures())),
- sent_selectors_(GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
+ sent_selectors_(Z),
error_(Error::Handle(Z)) {
}
@@ -80,7 +82,9 @@ void Precompiler::DoCompileAll() {
" %" Pd " dynamic selectors\n",
function_count_,
class_count_,
- sent_selectors_.Length());
+ selector_count_);
+ OS::Print("Dropped %" Pd " functions\n",
+ dropped_function_count_);
srdjan 2015/08/05 18:20:08 ISL_Print
Cutch 2015/08/05 18:25:05 DBC: You may also want to put a: LogBlock lb(Thre
rmacnak 2015/08/05 19:51:50 Done.
}
I->set_compilation_allowed(false);
@@ -333,7 +337,9 @@ void Precompiler::Iterate() {
void Precompiler::CleanUp() {
I->set_collected_closures(GrowableObjectArray::Handle(Z));
- // TODO(rmacnak): Drop functions without code, classes without functions, etc.
+ DropUncompiledFunctions();
+
+ // TODO(rmacnak): DropEmptyClasses();
}
@@ -454,36 +460,26 @@ void Precompiler::AddFunction(const Function& function) {
bool Precompiler::IsSent(const String& selector) {
- ASSERT(selector.IsSymbol());
-
- // TODO(rmacnak): Use a proper set.
- for (intptr_t i = 0; i < sent_selectors_.Length(); i++) {
- if (sent_selectors_.At(i) == selector.raw()) {
- return true;
- }
- }
-
- return false;
+ return sent_selectors_.Includes(selector);
}
void Precompiler::AddSelector(const String& selector) {
if (!IsSent(selector)) {
+ sent_selectors_.Add(selector);
+ selector_count_++;
+ changed_ = true;
+
if (FLAG_trace_precompiler) {
OS::Print("Enqueueing selector %" Pd " %s\n",
- sent_selectors_.Length(),
+ selector_count_,
selector.ToCString());
}
- sent_selectors_.Add(selector);
- changed_ = true;
-
if (!Field::IsGetterName(selector) &&
!Field::IsSetterName(selector)) {
// Regular method may be call-through-getter.
- // TODO(rmacnak): Do not create the symbol if it does not already exist.
rmacnak 2015/08/05 18:11:54 Turns out the vast majority of these selectors alr
- String& getter = String::Handle(Field::GetterName(selector));
- getter = Symbols::New(getter);
+ const String& getter = String::Handle(Field::GetterSymbol(selector));
AddSelector(getter);
}
}
@@ -577,10 +573,7 @@ void Precompiler::CheckForNewDynamicFunctions() {
if (function.kind() == RawFunction::kRegularFunction &&
!Field::IsGetterName(selector) &&
!Field::IsSetterName(selector)) {
- // TODO(rmacnak): Do not create the symbol if it does not already
- // exist.
- selector = Field::GetterName(selector);
- selector = Symbols::New(selector);
+ selector = Field::GetterSymbol(selector);
if (IsSent(selector)) {
function = function.ImplicitClosureFunction();
AddFunction(function);
@@ -591,4 +584,55 @@ void Precompiler::CheckForNewDynamicFunctions() {
}
}
+
+void Precompiler::DropUncompiledFunctions() {
+ Library& lib = Library::Handle(Z);
+ Class& cls = Class::Handle(Z);
+ Array& functions = Array::Handle(Z);
+ Function& function = Function::Handle(Z);
+ GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z);
+ GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
+
+ for (intptr_t i = 0; i < libraries_.Length(); i++) {
+ lib ^= libraries_.At(i);
+ ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+ while (it.HasNext()) {
+ cls = it.GetNextClass();
+ if (cls.IsDynamicClass()) {
+ continue; // class 'dynamic' is in the read-only VM isolate.
+ }
+
+ functions = cls.functions();
+ retained_functions = GrowableObjectArray::New();
+ for (intptr_t j = 0; j < functions.Length(); j++) {
+ function ^= functions.At(j);
+ if (function.HasCode()) {
+ retained_functions.Add(function);
+ } else {
+ dropped_function_count_++;
+ if (FLAG_trace_precompiler) {
+ OS::Print("Precompilation dropping %s\n",
srdjan 2015/08/05 18:20:08 ISL_Print
+ function.ToLibNamePrefixedQualifiedCString());
+ }
+ }
+ }
+
+ functions = Array::New(retained_functions.Length(), Heap::kOld);
+ for (intptr_t j = 0; j < retained_functions.Length(); j++) {
+ function ^= retained_functions.At(j);
+ functions.SetAt(j, function);
+ }
+ cls.SetFunctions(functions);
+
+ closures = cls.closures();
+ if (!closures.IsNull()) {
+ for (intptr_t j = 0; j < closures.Length(); j++) {
+ function ^= closures.At(j);
+ ASSERT(function.HasCode());
+ }
+ }
+ }
+ }
+}
+
} // namespace dart
« runtime/vm/precompiler.h ('K') | « runtime/vm/precompiler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698