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

Unified Diff: runtime/vm/compiler.cc

Issue 1386503002: Initial design for background compilation (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Address Comments Created 5 years, 2 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/compiler.h ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/compiler.cc
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index fbf9974fc9da27ca02ce8cb3782d15a067139118..666a47b2739cbf04310e8b40bf2bac9009ef8dc6 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1402,4 +1402,164 @@ RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
return Object::null();
}
+
+// A simple work queue containing functions to be optimized. Use
+// PushFront and PopBack to add and read from queue.
+// TODO(srdjan): Write a more efficient implementation.
+class CompilationWorkQueue : public ValueObject {
+ public:
+ explicit CompilationWorkQueue(Isolate* isolate) :
+ data_(GrowableObjectArray::Handle()) {
+ data_ = isolate->background_compilation_queue();
+ }
+
+ intptr_t IsEmpty() const { return data_.Length() == 0; }
+
+ // Adds to the queue only if 'function' is not already in there.
+ void PushFront(const Function& function) {
+ for (intptr_t i = 0; i < data_.Length(); i++) {
+ if (data_.At(i) == function.raw()) {
+ return;
+ }
+ }
+ // Insert new element in front.
+ Object& f = Object::Handle();
+ data_.Add(f);
+ for (intptr_t i = data_.Length() - 1; i > 0; i--) {
+ f = data_.At(i - 1);
+ data_.SetAt(i, f);
+ }
+ data_.SetAt(0, function);
+ }
+
+ RawFunction* PopBack() {
+ ASSERT(!IsEmpty());
+ Object& result = Object::Handle();
+ result = data_.At(data_.Length() - 1);
+ data_.SetLength(data_.Length() - 1);
+ return Function::Cast(result).raw();
+ }
+
+ private:
+ GrowableObjectArray& data_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
+};
+
+
+BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
+ : isolate_(isolate), running_(true), done_(new bool()),
+ monitor_(new Monitor()), done_monitor_(new Monitor()) {
+ *done_ = false;
+}
+
+
+void BackgroundCompiler::Run() {
+ while (running_) {
+ {
+ // Wait to be notified when the work queue is not empty.
+ MonitorLocker ml(monitor_);
+ ml.Wait();
+ }
+
+ Thread::EnterIsolateAsHelper(isolate_);
+ {
+ Thread* thread = Thread::Current();
+ StackZone stack_zone(thread);
+ HANDLESCOPE(thread);
+ Function& function = Function::Handle();
+ function = RemoveOrNull();
+ while (!function.IsNull()) {
+ if (true) {
+ // Debugging printing
+ THR_Print("Background compilation: %s\n",
+ function.ToQualifiedCString());
+ } else {
+ const Error& error = Error::Handle(
+ Compiler::CompileOptimizedFunction(thread, function));
+ // TODO(srdjan): We do not expect errors while compiling optimized
+ // code, any errors should have been caught when compiling
+ // unotpimized code.
+ // If it still happens mark function as not optimizable.
+ ASSERT(error.IsNull());
+ }
+ function = RemoveOrNull();
+ }
+ }
+ Thread::ExitIsolateAsHelper();
+ }
+ {
+ // Notify that the thread is done.
+ MonitorLocker ml_done(done_monitor_);
+ *done_ = true;
+ ml_done.Notify();
+ }
+}
+
+
+void BackgroundCompiler::CompileOptimized(const Function& function) {
+ Add(function);
+}
+
+
+void BackgroundCompiler::Add(const Function& f) const {
+ MonitorLocker ml(monitor_);
+ CompilationWorkQueue queue(isolate_);
+ queue.PushFront(f);
+ ml.Notify();
+}
+
+
+RawFunction* BackgroundCompiler::RemoveOrNull() const {
+ MonitorLocker ml(monitor_);
+ CompilationWorkQueue queue(isolate_);
+ return queue.IsEmpty() ? Function::null() : queue.PopBack();
+}
+
+
+void BackgroundCompiler::Stop(BackgroundCompiler* task) {
+ if (task == NULL) {
+ return;
+ }
+ Monitor* monitor = task->monitor_;
+ Monitor* done_monitor = task->done_monitor_;
+ bool* task_done = task->done_;
+ // Wake up compiler task and stop it.
+ {
+ MonitorLocker ml(task->monitor_);
+ task->running_ = false;
+ // 'task' will be deleted by thread pool.
+ task = NULL;
+ ml.Notify();
+ }
+
+ {
+ MonitorLocker ml_done(done_monitor);
+ while (!(*task_done)) {
+ ml_done.Wait();
+ }
+ }
+ delete task_done;
+ delete done_monitor;
+ delete monitor;
+}
+
+
+void BackgroundCompiler::EnsureInit(Isolate* isolate) {
+ bool start_task = false;
+ {
+ MutexLocker ml(isolate->mutex());
+ if (isolate->background_compiler() == NULL) {
+ BackgroundCompiler* task = new BackgroundCompiler(isolate);
+ isolate->set_background_compiler(task);
+ isolate->set_background_compilation_queue(
+ GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()));
+ start_task = true;
+ }
+ }
+ if (start_task) {
+ Dart::thread_pool()->Run(isolate->background_compiler());
+ }
+}
+
} // namespace dart
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698