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

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: Cleanup 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 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 Isolate* const isolate = thread->isolate(); 1408 Isolate* const isolate = thread->isolate();
1408 const Object& result = 1409 const Object& result =
1409 PassiveObject::Handle(isolate->object_store()->sticky_error()); 1410 PassiveObject::Handle(isolate->object_store()->sticky_error());
1410 isolate->object_store()->clear_sticky_error(); 1411 isolate->object_store()->clear_sticky_error();
1411 return result.raw(); 1412 return result.raw();
1412 } 1413 }
1413 UNREACHABLE(); 1414 UNREACHABLE();
1414 return Object::null(); 1415 return Object::null();
1415 } 1416 }
1416 1417
1418
1419 // A simple workqueue containing functions to be optimized.
1420 // TODO(srdjan): Write a more efficient implementation.
1421 class CompilationWorkQueue : public ValueObject {
1422 public:
1423 explicit CompilationWorkQueue(Isolate* isolate) :
1424 data_(GrowableObjectArray::Handle()) {
1425 data_ = isolate->background_compilation_queue();
1426 }
1427
1428 intptr_t IsEmpty() const { return data_.Length() == 0; }
1429
1430 // Adds to the queue only if not already in there.
1431 void AddUnique(const Function& function) {
1432 for (intptr_t i = 0; i < data_.Length(); i++) {
1433 if (data_.At(i) == function.raw()) {
1434 return;
1435 }
1436 }
1437 // Insert new element in front.
1438 Object& f = Object::Handle();
1439 data_.Add(f);
1440 for (intptr_t i = data_.Length() - 1; i > 0; i--) {
1441 f = data_.At(i - 1);
1442 data_.SetAt(i, f);
1443 }
1444 data_.SetAt(0, function);
1445 }
1446
1447
1448 RawFunction* Remove() {
1449 ASSERT(!IsEmpty());
1450 Object& result = Object::Handle();
1451 result = data_.At(data_.Length() - 1);
1452 data_.SetLength(data_.Length() - 1);
1453 return Function::Cast(result).raw();
1454 }
1455
1456 private:
1457 GrowableObjectArray& data_;
1458
1459 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
1460 };
1461
1462
1463 CompileOptimizedTask::CompileOptimizedTask(Isolate* isolate)
1464 : isolate_(isolate), running_(true), done_(new bool()),
1465 monitor_(new Monitor()), done_monitor_(new Monitor()) {
1466 *done_ = false;
1467 }
1468
1469 CompileOptimizedTask::~CompileOptimizedTask() {
1470 delete monitor_;
1471 monitor_ = NULL;
1472 // done_monitor_ is owned by 'Stop', do not delete here.
1473 done_monitor_ = NULL;
1474 // bool_ is owned by 'Stop', do not delete here.
koda 2015/10/01 22:27:02 bool_ -> done_
srdjan 2015/10/01 23:11:24 Done.
1475 done_ = NULL;
1476 }
1477
1478
1479 void CompileOptimizedTask::Run() {
1480 while (running_) {
1481 {
1482 // Wait to be notified when the workqueue is not empty.
1483 MonitorLocker ml(monitor_);
1484 ml.Wait();
1485 }
1486
1487 Thread::EnterIsolateAsHelper(isolate_);
1488 {
1489 Thread* thread = Thread::Current();
1490 StackZone stack_zone(thread);
1491 HANDLESCOPE(thread);
1492 // In case the thread was awoken because of a safepoint request.
1493 isolate_->thread_registry()->CheckSafepoint();
1494 Function& function = Function::Handle();
1495 function = RemoveOrNull();
1496 while (!function.IsNull()) {
1497 // Debugging printing
1498 // THR_Print("Basckground compilation: %s\n",
1499 // function.ToQualifiedCString());
1500 const Error& error = Error::Handle(
1501 Compiler::CompileOptimizedFunction(thread, function));
1502 // TODO(srdjan): We do not expect errors in optimized code. If it
1503 // still happens make function as not optimizable.
koda 2015/10/01 22:27:02 make -> mark?
srdjan 2015/10/01 23:11:24 Done.
1504 ASSERT(error.IsNull());
1505 function = RemoveOrNull();
1506 }
1507 }
1508 Thread::ExitIsolateAsHelper();
1509 }
1510 {
1511 // Notify that the thread is done.
1512 MonitorLocker ml_done(done_monitor_);
1513 *done_ = true;
1514 ml_done.Notify();
1515 }
1516 }
1517
1518
1519 void CompileOptimizedTask::CompileOptimized(const Function& function) {
1520 Add(function);
1521 }
1522
1523
1524 void CompileOptimizedTask::Add(const Function& f) {
1525 MonitorLocker ml(monitor_);
1526 CompilationWorkQueue queue(isolate_);
1527 queue.AddUnique(f);
1528 ml.Notify();
1529 }
1530
1531
1532 RawFunction* CompileOptimizedTask::RemoveOrNull() {
1533 MonitorLocker ml(monitor_);
1534 CompilationWorkQueue queue(isolate_);
1535 return queue.IsEmpty() ? Function::null() : queue.Remove();
1536 }
1537
1538
1539 void CompileOptimizedTask::Stop(CompileOptimizedTask* task) {
1540 if (task == NULL) {
1541 return;
1542 }
1543 Monitor* done_monitor = task->done_monitor_;
1544 bool* task_done = task->done_;
1545 // Wake up compiler task and stop it.
1546 {
1547 MonitorLocker ml(task->monitor_);
1548 task->running_ = false;
1549 ml.Notify();
1550 }
1551 {
1552 MonitorLocker ml_done(done_monitor);
1553 while (!(*task_done)) {
1554 ml_done.Wait();
1555 }
1556 }
koda 2015/10/01 22:27:02 Starting here, 'task' is concurrently destructed b
srdjan 2015/10/01 23:11:24 Done.
1557 delete task_done;
1558 delete done_monitor;
1559 }
1560
1561
1562 void CompileOptimizedTask::Init(Isolate* isolate) {
1563 isolate->set_background_compilation_queue(
1564 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New()));
1565 CompileOptimizedTask* task = new CompileOptimizedTask(isolate);
1566 isolate->set_compile_optimized_task(task);
1567 Dart::thread_pool()->Run(task);
1568 }
1569
1417 } // namespace dart 1570 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698