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 |