Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |