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 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1156 | 1156 |
1157 | 1157 |
1158 RawError* Compiler::CompileOptimizedFunction(Thread* thread, | 1158 RawError* Compiler::CompileOptimizedFunction(Thread* thread, |
1159 const Function& function, | 1159 const Function& function, |
1160 intptr_t osr_id) { | 1160 intptr_t osr_id) { |
1161 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId); | 1161 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId); |
1162 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, | 1162 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, |
1163 "OptimizedFunction", function); | 1163 "OptimizedFunction", function); |
1164 | 1164 |
1165 // Optimization must happen in non-mutator/Dart thread if background | 1165 // Optimization must happen in non-mutator/Dart thread if background |
1166 // compilation is on. | 1166 // compilation is on. OSR compilation still occura in the main thread. |
siva
2015/10/16 23:29:40
still occurs
srdjan
2015/10/16 23:50:17
Done.
| |
1167 ASSERT(!FLAG_background_compilation || | 1167 ASSERT((osr_id != Thread::kNoDeoptId) || !FLAG_background_compilation || |
1168 !thread->isolate()->MutatorThreadIsCurrentThread()); | 1168 !thread->isolate()->MutatorThreadIsCurrentThread()); |
1169 CompilationPipeline* pipeline = | 1169 CompilationPipeline* pipeline = |
1170 CompilationPipeline::New(thread->zone(), function); | 1170 CompilationPipeline::New(thread->zone(), function); |
1171 return CompileFunctionHelper(pipeline, function, true, osr_id); | 1171 return CompileFunctionHelper(pipeline, function, true, osr_id); |
1172 } | 1172 } |
1173 | 1173 |
1174 | 1174 |
1175 // This is only used from unit tests. | 1175 // This is only used from unit tests. |
1176 RawError* Compiler::CompileParsedFunction( | 1176 RawError* Compiler::CompileParsedFunction( |
1177 ParsedFunction* parsed_function) { | 1177 ParsedFunction* parsed_function) { |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1439 } | 1439 } |
1440 | 1440 |
1441 RawFunction* PopBack() { | 1441 RawFunction* PopBack() { |
1442 ASSERT(!IsEmpty()); | 1442 ASSERT(!IsEmpty()); |
1443 Object& result = Object::Handle(); | 1443 Object& result = Object::Handle(); |
1444 result = data_.At(data_.Length() - 1); | 1444 result = data_.At(data_.Length() - 1); |
1445 data_.SetLength(data_.Length() - 1); | 1445 data_.SetLength(data_.Length() - 1); |
1446 return Function::Cast(result).raw(); | 1446 return Function::Cast(result).raw(); |
1447 } | 1447 } |
1448 | 1448 |
1449 RawFunction* Last() { | |
1450 ASSERT(!IsEmpty()); | |
1451 Object& result = Object::Handle(); | |
1452 result = data_.At(data_.Length() - 1); | |
1453 return Function::Cast(result).raw(); | |
siva
2015/10/16 23:29:40
maybe just:
return RawFunction::RawCast(data_.At(
srdjan
2015/10/16 23:50:17
Done: Function::RawCast.
| |
1454 } | |
1455 | |
1449 private: | 1456 private: |
1450 GrowableObjectArray& data_; | 1457 GrowableObjectArray& data_; |
1451 | 1458 |
1452 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); | 1459 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); |
1453 }; | 1460 }; |
1454 | 1461 |
1455 | 1462 |
1456 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) | 1463 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) |
1457 : isolate_(isolate), running_(true), done_(new bool()), | 1464 : isolate_(isolate), running_(true), done_(new bool()), |
1458 monitor_(new Monitor()), done_monitor_(new Monitor()) { | 1465 queue_monitor_(new Monitor()), done_monitor_(new Monitor()) { |
1459 *done_ = false; | 1466 *done_ = false; |
1460 } | 1467 } |
1461 | 1468 |
1462 | 1469 |
1463 void BackgroundCompiler::Run() { | 1470 void BackgroundCompiler::Run() { |
1464 while (running_) { | 1471 while (running_) { |
1465 { | 1472 // Maybe something is already in the queue, check first before waiting |
1466 // Wait to be notified when the work queue is not empty. | 1473 // to be notified. |
1467 MonitorLocker ml(monitor_); | |
1468 ml.Wait(); | |
1469 } | |
1470 | |
1471 Thread::EnterIsolateAsHelper(isolate_); | 1474 Thread::EnterIsolateAsHelper(isolate_); |
1472 { | 1475 { |
1473 Thread* thread = Thread::Current(); | 1476 Thread* thread = Thread::Current(); |
1474 StackZone stack_zone(thread); | 1477 StackZone stack_zone(thread); |
1475 HANDLESCOPE(thread); | 1478 HANDLESCOPE(thread); |
1476 Function& function = Function::Handle(); | 1479 Zone* zone = stack_zone.GetZone(); |
1477 function = RemoveOrNull(); | 1480 Function& function = Function::Handle(zone); |
1478 while (!function.IsNull()) { | 1481 Function& temp_function = Function::Handle(zone); |
1479 const Error& error = Error::Handle( | 1482 function = LastOrNull(); |
1483 while (!function.IsNull() && running_) { | |
1484 const Error& error = Error::Handle(zone, | |
1480 Compiler::CompileOptimizedFunction(thread, function)); | 1485 Compiler::CompileOptimizedFunction(thread, function)); |
1481 // TODO(srdjan): We do not expect errors while compiling optimized | 1486 // TODO(srdjan): We do not expect errors while compiling optimized |
1482 // code, any errors should have been caught when compiling | 1487 // code, any errors should have been caught when compiling |
1483 // unoptimized code. | 1488 // unoptimized code. |
1484 // If it still happens mark function as not optimizable. | 1489 // If it still happens mark function as not optimizable. |
1485 ASSERT(error.IsNull()); | 1490 ASSERT(error.IsNull()); |
1486 function = RemoveOrNull(); | 1491 temp_function = RemoveOrNull(); |
1492 ASSERT(temp_function.raw() == function.raw()); | |
1493 function = LastOrNull(); | |
1487 } | 1494 } |
1488 } | 1495 } |
1489 Thread::ExitIsolateAsHelper(); | 1496 Thread::ExitIsolateAsHelper(); |
1497 { | |
1498 // Wait to be notified when the work queue is not empty. | |
1499 MonitorLocker ml(queue_monitor_); | |
1500 // TODO(srdjan): Add a loop here, while queue is empty. Figure out how. | |
1501 // Currently we may block while there is still something in the queue. | |
1502 // We cannot access the queue as we cannot create handles here. | |
1503 // We cannot call EnterIsolateAsHelper to allocate handles because | |
1504 // safepoint would not be reachable here otherwise. | |
1505 ml.Wait(); | |
1506 } | |
1490 } | 1507 } |
1491 { | 1508 { |
1492 // Notify that the thread is done. | 1509 // Notify that the thread is done. |
1493 MonitorLocker ml_done(done_monitor_); | 1510 MonitorLocker ml_done(done_monitor_); |
1494 *done_ = true; | 1511 *done_ = true; |
1495 ml_done.Notify(); | 1512 ml_done.Notify(); |
1496 } | 1513 } |
1497 } | 1514 } |
1498 | 1515 |
1499 | 1516 |
1500 void BackgroundCompiler::CompileOptimized(const Function& function) { | 1517 void BackgroundCompiler::CompileOptimized(const Function& function) { |
1501 Add(function); | 1518 Add(function); |
1502 } | 1519 } |
1503 | 1520 |
1504 | 1521 |
1505 void BackgroundCompiler::Add(const Function& f) const { | 1522 void BackgroundCompiler::Add(const Function& f) const { |
1506 MonitorLocker ml(monitor_); | 1523 MonitorLocker ml(queue_monitor_); |
1507 CompilationWorkQueue queue(isolate_); | 1524 CompilationWorkQueue queue(isolate_); |
1508 queue.PushFront(f); | 1525 queue.PushFront(f); |
1509 ml.Notify(); | 1526 ml.Notify(); |
1510 } | 1527 } |
1511 | 1528 |
1512 | 1529 |
1513 RawFunction* BackgroundCompiler::RemoveOrNull() const { | 1530 RawFunction* BackgroundCompiler::RemoveOrNull() const { |
1514 MonitorLocker ml(monitor_); | 1531 MonitorLocker ml(queue_monitor_); |
1515 CompilationWorkQueue queue(isolate_); | 1532 CompilationWorkQueue queue(isolate_); |
1516 return queue.IsEmpty() ? Function::null() : queue.PopBack(); | 1533 return queue.IsEmpty() ? Function::null() : queue.PopBack(); |
1517 } | 1534 } |
1518 | 1535 |
1519 | 1536 |
1537 RawFunction* BackgroundCompiler::LastOrNull() const { | |
1538 MonitorLocker ml(queue_monitor_); | |
1539 CompilationWorkQueue queue(isolate_); | |
1540 return queue.IsEmpty() ? Function::null() : queue.Last(); | |
1541 } | |
1542 | |
1543 | |
1520 void BackgroundCompiler::Stop(BackgroundCompiler* task) { | 1544 void BackgroundCompiler::Stop(BackgroundCompiler* task) { |
1521 if (task == NULL) { | 1545 if (task == NULL) { |
1522 return; | 1546 return; |
1523 } | 1547 } |
1524 Monitor* monitor = task->monitor_; | 1548 Monitor* monitor = task->queue_monitor_; |
1525 Monitor* done_monitor = task->done_monitor_; | 1549 Monitor* done_monitor = task->done_monitor_; |
1526 bool* task_done = task->done_; | 1550 bool* task_done = task->done_; |
1527 // Wake up compiler task and stop it. | 1551 // Wake up compiler task and stop it. |
1528 { | 1552 { |
1529 MonitorLocker ml(task->monitor_); | 1553 MonitorLocker ml(task->queue_monitor_); |
1530 task->running_ = false; | 1554 task->running_ = false; |
1531 // 'task' will be deleted by thread pool. | 1555 // 'task' will be deleted by thread pool. |
1532 task = NULL; | 1556 task = NULL; |
1533 ml.Notify(); | 1557 ml.Notify(); // Stop waiting for the queue. |
1534 } | 1558 } |
1535 | 1559 |
1536 { | 1560 { |
1537 MonitorLocker ml_done(done_monitor); | 1561 MonitorLocker ml_done(done_monitor); |
1538 while (!(*task_done)) { | 1562 while (!(*task_done)) { |
1539 ml_done.Wait(); | 1563 ml_done.Wait(); |
1540 } | 1564 } |
1541 } | 1565 } |
1542 delete task_done; | 1566 delete task_done; |
1543 delete done_monitor; | 1567 delete done_monitor; |
(...skipping 12 matching lines...) Expand all Loading... | |
1556 isolate->current_zone(), GrowableObjectArray::New())); | 1580 isolate->current_zone(), GrowableObjectArray::New())); |
1557 start_task = true; | 1581 start_task = true; |
1558 } | 1582 } |
1559 } | 1583 } |
1560 if (start_task) { | 1584 if (start_task) { |
1561 Dart::thread_pool()->Run(isolate->background_compiler()); | 1585 Dart::thread_pool()->Run(isolate->background_compiler()); |
1562 } | 1586 } |
1563 } | 1587 } |
1564 | 1588 |
1565 } // namespace dart | 1589 } // namespace dart |
OLD | NEW |