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 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1395 Isolate* const isolate = thread->isolate(); | 1395 Isolate* const isolate = thread->isolate(); |
1396 const Object& result = | 1396 const Object& result = |
1397 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1397 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
1398 isolate->object_store()->clear_sticky_error(); | 1398 isolate->object_store()->clear_sticky_error(); |
1399 return result.raw(); | 1399 return result.raw(); |
1400 } | 1400 } |
1401 UNREACHABLE(); | 1401 UNREACHABLE(); |
1402 return Object::null(); | 1402 return Object::null(); |
1403 } | 1403 } |
1404 | 1404 |
1405 | |
1406 // A simple workqueue containing functions to be optimized. | |
1407 // TODO(srdjan): Write a more efficient implementation. | |
1408 class CompilationWorkQueue : public ValueObject { | |
koda
2015/10/05 18:13:00
Be consistent w.r.t. "work queue" vs "workqueue".
srdjan
2015/10/05 19:16:47
Done; Two words.
| |
1409 public: | |
1410 explicit CompilationWorkQueue(Isolate* isolate) : | |
1411 data_(GrowableObjectArray::Handle()) { | |
1412 data_ = isolate->background_compilation_queue(); | |
1413 } | |
1414 | |
1415 intptr_t IsEmpty() const { return data_.Length() == 0; } | |
1416 | |
1417 // Adds to the queue only if not already in there. | |
1418 void AddUnique(const Function& function) { | |
1419 for (intptr_t i = 0; i < data_.Length(); i++) { | |
1420 if (data_.At(i) == function.raw()) { | |
1421 return; | |
1422 } | |
1423 } | |
1424 // Insert new element in front. | |
1425 Object& f = Object::Handle(); | |
1426 data_.Add(f); | |
1427 for (intptr_t i = data_.Length() - 1; i > 0; i--) { | |
1428 f = data_.At(i - 1); | |
1429 data_.SetAt(i, f); | |
1430 } | |
1431 data_.SetAt(0, function); | |
1432 } | |
1433 | |
1434 | |
1435 RawFunction* Remove() { | |
koda
2015/10/05 18:13:00
Clarify/emphasize that AddUnique/Remove together m
srdjan
2015/10/05 19:16:47
Renamed to PushFront/PopBack.
| |
1436 ASSERT(!IsEmpty()); | |
1437 Object& result = Object::Handle(); | |
1438 result = data_.At(data_.Length() - 1); | |
1439 data_.SetLength(data_.Length() - 1); | |
1440 return Function::Cast(result).raw(); | |
1441 } | |
1442 | |
1443 private: | |
1444 GrowableObjectArray& data_; | |
1445 | |
1446 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); | |
1447 }; | |
1448 | |
1449 | |
1450 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) | |
1451 : isolate_(isolate), running_(true), done_(new bool()), | |
1452 monitor_(new Monitor()), done_monitor_(new Monitor()) { | |
1453 *done_ = false; | |
1454 } | |
1455 | |
1456 | |
1457 void BackgroundCompiler::Run() { | |
1458 while (running_) { | |
1459 { | |
1460 // Wait to be notified when the workqueue is not empty. | |
1461 MonitorLocker ml(monitor_); | |
1462 ml.Wait(); | |
1463 } | |
1464 | |
1465 Thread::EnterIsolateAsHelper(isolate_); | |
1466 { | |
1467 Thread* thread = Thread::Current(); | |
1468 StackZone stack_zone(thread); | |
1469 HANDLESCOPE(thread); | |
1470 Function& function = Function::Handle(); | |
1471 function = RemoveOrNull(); | |
1472 while (!function.IsNull()) { | |
1473 if (true) { | |
1474 // Debugging printing | |
1475 THR_Print("Background compilation: %s\n", | |
1476 function.ToQualifiedCString()); | |
1477 } else { | |
1478 const Error& error = Error::Handle( | |
1479 Compiler::CompileOptimizedFunction(thread, function)); | |
1480 // TODO(srdjan): We do not expect errors in optimized code. If it | |
koda
2015/10/05 18:13:00
Clarify that you mean errors *while compiling* opt
srdjan
2015/10/05 19:16:47
Done.
| |
1481 // still happens mark function as not optimizable. | |
1482 ASSERT(error.IsNull()); | |
1483 } | |
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 BackgroundCompiler::CompileOptimized(const Function& function) { | |
1499 Add(function); | |
1500 } | |
1501 | |
1502 | |
1503 void BackgroundCompiler::Add(const Function& f) const { | |
1504 MonitorLocker ml(monitor_); | |
1505 CompilationWorkQueue queue(isolate_); | |
1506 queue.AddUnique(f); | |
1507 ml.Notify(); | |
1508 } | |
1509 | |
1510 | |
1511 RawFunction* BackgroundCompiler::RemoveOrNull() const { | |
1512 MonitorLocker ml(monitor_); | |
1513 CompilationWorkQueue queue(isolate_); | |
1514 return queue.IsEmpty() ? Function::null() : queue.Remove(); | |
1515 } | |
1516 | |
1517 | |
1518 void BackgroundCompiler::Stop(BackgroundCompiler* 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. | |
koda
2015/10/05 18:13:00
This comment should go before NULL'ing task, to be
srdjan
2015/10/05 19:16:47
Done.
| |
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 BackgroundCompiler::EnsureInit(Isolate* isolate) { | |
1547 MutexLocker ml(isolate->mutex()); | |
1548 if (isolate->background_compiler() == NULL) { | |
1549 BackgroundCompiler* task = new BackgroundCompiler(isolate); | |
1550 isolate->set_background_compiler(task); | |
1551 isolate->set_background_compilation_queue( | |
1552 GrowableObjectArray::Handle(isolate, GrowableObjectArray::New())); | |
1553 Dart::thread_pool()->Run(task); | |
koda
2015/10/05 18:13:00
This does not need to be under the lock and is a n
srdjan
2015/10/05 19:16:47
Done.
| |
1554 } | |
1555 } | |
1556 | |
1405 } // namespace dart | 1557 } // namespace dart |
OLD | NEW |