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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/compiler.h" 5 #include "vm/compiler.h"
6 6
7 #include "vm/assembler.h" 7 #include "vm/assembler.h"
8 8
9 #include "vm/ast_printer.h" 9 #include "vm/ast_printer.h"
10 #include "vm/block_scheduler.h" 10 #include "vm/block_scheduler.h"
(...skipping 17 matching lines...) Expand all
28 #include "vm/longjump.h" 28 #include "vm/longjump.h"
29 #include "vm/object.h" 29 #include "vm/object.h"
30 #include "vm/object_store.h" 30 #include "vm/object_store.h"
31 #include "vm/os.h" 31 #include "vm/os.h"
32 #include "vm/parser.h" 32 #include "vm/parser.h"
33 #include "vm/regexp_parser.h" 33 #include "vm/regexp_parser.h"
34 #include "vm/regexp_assembler.h" 34 #include "vm/regexp_assembler.h"
35 #include "vm/scanner.h" 35 #include "vm/scanner.h"
36 #include "vm/symbols.h" 36 #include "vm/symbols.h"
37 #include "vm/tags.h" 37 #include "vm/tags.h"
38 #include "vm/thread_registry.h"
38 #include "vm/timer.h" 39 #include "vm/timer.h"
39 40
40 namespace dart { 41 namespace dart {
41 42
42 DEFINE_FLAG(bool, allocation_sinking, true, 43 DEFINE_FLAG(bool, allocation_sinking, true,
43 "Attempt to sink temporary allocations to side exits"); 44 "Attempt to sink temporary allocations to side exits");
44 DEFINE_FLAG(bool, common_subexpression_elimination, true, 45 DEFINE_FLAG(bool, common_subexpression_elimination, true,
45 "Do common subexpression elimination."); 46 "Do common subexpression elimination.");
46 DEFINE_FLAG(bool, constant_propagation, true, 47 DEFINE_FLAG(bool, constant_propagation, true,
47 "Do conditional constant propagation/unreachable code elimination."); 48 "Do conditional constant propagation/unreachable code elimination.");
(...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after
1395 Isolate* const isolate = thread->isolate(); 1396 Isolate* const isolate = thread->isolate();
1396 const Object& result = 1397 const Object& result =
1397 PassiveObject::Handle(isolate->object_store()->sticky_error()); 1398 PassiveObject::Handle(isolate->object_store()->sticky_error());
1398 isolate->object_store()->clear_sticky_error(); 1399 isolate->object_store()->clear_sticky_error();
1399 return result.raw(); 1400 return result.raw();
1400 } 1401 }
1401 UNREACHABLE(); 1402 UNREACHABLE();
1402 return Object::null(); 1403 return Object::null();
1403 } 1404 }
1404 1405
1406
1407 // A simple workqueue containing functions to be optimized.
1408 // TODO(srdjan): Write a more efficient implementation.
1409 class CompilationWorkQueue : public ValueObject {
1410 public:
1411 explicit CompilationWorkQueue(Isolate* isolate) :
1412 data_(GrowableObjectArray::Handle()) {
1413 data_ = isolate->background_compilation_queue();
1414 }
1415
1416 intptr_t IsEmpty() const { return data_.Length() == 0; }
1417
1418 // Adds to the queue only if not already in there.
1419 void AddUnique(const Function& function) {
1420 for (intptr_t i = 0; i < data_.Length(); i++) {
1421 if (data_.At(i) == function.raw()) {
1422 return;
1423 }
1424 }
1425 // Insert new element in front.
1426 Object& f = Object::Handle();
1427 data_.Add(f);
1428 for (intptr_t i = data_.Length() - 1; i > 0; i--) {
1429 f = data_.At(i - 1);
1430 data_.SetAt(i, f);
1431 }
1432 data_.SetAt(0, function);
1433 }
1434
1435
1436 RawFunction* Remove() {
1437 ASSERT(!IsEmpty());
1438 Object& result = Object::Handle();
1439 result = data_.At(data_.Length() - 1);
1440 data_.SetLength(data_.Length() - 1);
1441 return Function::Cast(result).raw();
1442 }
1443
1444 private:
1445 GrowableObjectArray& data_;
1446
1447 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
1448 };
1449
1450
1451 CompileOptimizedTask::CompileOptimizedTask(Isolate* isolate)
1452 : isolate_(isolate), running_(true), done_(new bool()),
1453 monitor_(new Monitor()), done_monitor_(new Monitor()) {
1454 *done_ = false;
1455 }
1456
1457
1458 void CompileOptimizedTask::Run() {
1459 while (running_) {
1460 {
1461 // Wait to be notified when the workqueue is not empty.
1462 MonitorLocker ml(monitor_);
1463 ml.Wait();
1464 }
1465
1466 Thread::EnterIsolateAsHelper(isolate_);
1467 {
1468 Thread* thread = Thread::Current();
1469 StackZone stack_zone(thread);
1470 HANDLESCOPE(thread);
1471 // In case the thread was awoken because of a safepoint request.
1472 isolate_->thread_registry()->CheckSafepoint();
1473 Function& function = Function::Handle();
1474 function = RemoveOrNull();
1475 while (!function.IsNull()) {
1476 // Debugging printing
1477 // THR_Print("Background compilation: %s\n",
1478 // function.ToQualifiedCString());
1479 const Error& error = Error::Handle(
1480 Compiler::CompileOptimizedFunction(thread, function));
1481 // TODO(srdjan): We do not expect errors in optimized code. If it
1482 // still happens mark function as not optimizable.
1483 ASSERT(error.IsNull());
1484 function = RemoveOrNull();
1485 }
1486 }
1487 Thread::ExitIsolateAsHelper();
1488 }
1489 {
1490 // Notify that the thread is done.
1491 MonitorLocker ml_done(done_monitor_);
1492 *done_ = true;
1493 ml_done.Notify();
1494 }
1495 }
1496
1497
1498 void CompileOptimizedTask::CompileOptimized(const Function& function) {
1499 Add(function);
1500 }
1501
1502
1503 void CompileOptimizedTask::Add(const Function& f) {
1504 MonitorLocker ml(monitor_);
1505 CompilationWorkQueue queue(isolate_);
1506 queue.AddUnique(f);
1507 ml.Notify();
1508 }
1509
1510
1511 RawFunction* CompileOptimizedTask::RemoveOrNull() {
1512 MonitorLocker ml(monitor_);
1513 CompilationWorkQueue queue(isolate_);
1514 return queue.IsEmpty() ? Function::null() : queue.Remove();
1515 }
1516
1517
1518 void CompileOptimizedTask::Stop(CompileOptimizedTask* task) {
1519 if (task == NULL) {
1520 return;
1521 }
1522 Monitor* monitor = task->monitor_;
1523 Monitor* done_monitor = task->done_monitor_;
1524 bool* task_done = task->done_;
1525 // Wake up compiler task and stop it.
1526 {
1527 MonitorLocker ml(task->monitor_);
1528 task->running_ = false;
1529 task = NULL;
1530 // 'task' will be deleted by thread pool.
1531 ml.Notify();
1532 }
1533
1534 {
1535 MonitorLocker ml_done(done_monitor);
1536 while (!(*task_done)) {
1537 ml_done.Wait();
1538 }
1539 }
1540 delete task_done;
1541 delete done_monitor;
1542 delete monitor;
1543 }
1544
1545
1546 void CompileOptimizedTask::EnsureInit(Isolate* isolate) {
1547 MutexLocker ml(isolate->mutex());
1548 if (isolate->compile_optimized_task() == NULL) {
1549 CompileOptimizedTask* task = new CompileOptimizedTask(isolate);
1550 isolate->set_compile_optimized_task(task);
1551 isolate->set_background_compilation_queue(
1552 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()));
1553 Dart::thread_pool()->Run(task);
1554 }
1555 }
1556
1405 } // namespace dart 1557 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698