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

Side by Side Diff: runtime/vm/compiler.cc

Issue 1409173002: More work for background compilation; move pending_functions_ from ObjectStore to Thread. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Implement loop/wait 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
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/compiler_stats.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after
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.
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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 // PushFront and PopBack to add and read from queue. 1413 // PushFront and PopBack to add and read from queue.
1414 // TODO(srdjan): Write a more efficient implementation. 1414 // TODO(srdjan): Write a more efficient implementation.
1415 class CompilationWorkQueue : public ValueObject { 1415 class CompilationWorkQueue : public ValueObject {
1416 public: 1416 public:
1417 explicit CompilationWorkQueue(Isolate* isolate) : 1417 explicit CompilationWorkQueue(Isolate* isolate) :
1418 data_(GrowableObjectArray::Handle()) { 1418 data_(GrowableObjectArray::Handle()) {
1419 data_ = isolate->background_compilation_queue(); 1419 data_ = isolate->background_compilation_queue();
1420 } 1420 }
1421 1421
1422 intptr_t IsEmpty() const { return data_.Length() == 0; } 1422 intptr_t IsEmpty() const { return data_.Length() == 0; }
1423 intptr_t Length() const { return data_.Length(); }
1423 1424
1424 // Adds to the queue only if 'function' is not already in there. 1425 // Adds to the queue only if 'function' is not already in there.
1425 void PushFront(const Function& function) { 1426 void PushFront(const Function& function) {
1426 for (intptr_t i = 0; i < data_.Length(); i++) { 1427 for (intptr_t i = 0; i < data_.Length(); i++) {
1427 if (data_.At(i) == function.raw()) { 1428 if (data_.At(i) == function.raw()) {
1428 return; 1429 return;
1429 } 1430 }
1430 } 1431 }
1431 // Insert new element in front. 1432 // Insert new element in front.
1432 Object& f = Object::Handle(); 1433 Object& f = Object::Handle();
1433 data_.Add(f); 1434 data_.Add(f);
1434 for (intptr_t i = data_.Length() - 1; i > 0; i--) { 1435 for (intptr_t i = data_.Length() - 1; i > 0; i--) {
1435 f = data_.At(i - 1); 1436 f = data_.At(i - 1);
1436 data_.SetAt(i, f); 1437 data_.SetAt(i, f);
1437 } 1438 }
1438 data_.SetAt(0, function); 1439 data_.SetAt(0, function);
1439 } 1440 }
1440 1441
1441 RawFunction* PopBack() { 1442 RawFunction* PopBack() {
1442 ASSERT(!IsEmpty()); 1443 ASSERT(!IsEmpty());
1443 Object& result = Object::Handle(); 1444 Object& result = Object::Handle();
1444 result = data_.At(data_.Length() - 1); 1445 result = data_.At(data_.Length() - 1);
1445 data_.SetLength(data_.Length() - 1); 1446 data_.SetLength(data_.Length() - 1);
1446 return Function::Cast(result).raw(); 1447 return Function::Cast(result).raw();
1447 } 1448 }
1448 1449
1450 RawFunction* Last() {
1451 ASSERT(!IsEmpty());
1452 Object& result = Object::Handle();
1453 result = data_.At(data_.Length() - 1);
1454 return Function::Cast(result).raw();
1455 }
1456
1449 private: 1457 private:
1450 GrowableObjectArray& data_; 1458 GrowableObjectArray& data_;
1451 1459
1452 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); 1460 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
1453 }; 1461 };
1454 1462
1455 1463
1456 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) 1464 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
1457 : isolate_(isolate), running_(true), done_(new bool()), 1465 : isolate_(isolate), running_(true), done_(new bool()),
1458 monitor_(new Monitor()), done_monitor_(new Monitor()) { 1466 queue_monitor_(new Monitor()), done_monitor_(new Monitor()),
1467 queue_length_(0) {
1459 *done_ = false; 1468 *done_ = false;
1460 } 1469 }
1461 1470
1462 1471
1463 void BackgroundCompiler::Run() { 1472 void BackgroundCompiler::Run() {
1464 while (running_) { 1473 while (running_) {
siva 2015/10/16 23:29:40 running_ is being accessed here without holding th
srdjan 2015/10/16 23:50:17 Yes, running_ is not guarded by queue lock. It can
1465 { 1474 // Maybe something is already in the queue, check first before waiting
1466 // Wait to be notified when the work queue is not empty. 1475 // to be notified.
1467 MonitorLocker ml(monitor_);
1468 ml.Wait();
1469 }
1470
1471 Thread::EnterIsolateAsHelper(isolate_); 1476 Thread::EnterIsolateAsHelper(isolate_);
1472 { 1477 {
1473 Thread* thread = Thread::Current(); 1478 Thread* thread = Thread::Current();
1474 StackZone stack_zone(thread); 1479 StackZone stack_zone(thread);
1475 HANDLESCOPE(thread); 1480 HANDLESCOPE(thread);
1476 Function& function = Function::Handle(); 1481 Zone* zone = stack_zone.GetZone();
1477 function = RemoveOrNull(); 1482 Function& function = Function::Handle(zone);
1478 while (!function.IsNull()) { 1483 Function& temp_function = Function::Handle(zone);
1479 const Error& error = Error::Handle( 1484 function = LastOrNull();
1485 while (!function.IsNull() && running_) {
siva 2015/10/16 23:29:40 Ditto question about running_ accessed here withou
srdjan 2015/10/16 23:50:17 ditto.
1486 const Error& error = Error::Handle(zone,
1480 Compiler::CompileOptimizedFunction(thread, function)); 1487 Compiler::CompileOptimizedFunction(thread, function));
1481 // TODO(srdjan): We do not expect errors while compiling optimized 1488 // TODO(srdjan): We do not expect errors while compiling optimized
1482 // code, any errors should have been caught when compiling 1489 // code, any errors should have been caught when compiling
1483 // unoptimized code. 1490 // unoptimized code.
1484 // If it still happens mark function as not optimizable. 1491 // If it still happens mark function as not optimizable.
1485 ASSERT(error.IsNull()); 1492 ASSERT(error.IsNull());
1486 function = RemoveOrNull(); 1493 temp_function = RemoveOrNull();
1494 ASSERT(temp_function.raw() == function.raw());
1495 function = LastOrNull();
1487 } 1496 }
1488 } 1497 }
1489 Thread::ExitIsolateAsHelper(); 1498 Thread::ExitIsolateAsHelper();
1499 {
1500 // Wait to be notified when the work queue is not empty.
1501 MonitorLocker ml(queue_monitor_);
1502 while (queue_length() == 0) {
siva 2015/10/16 23:29:40 while ((queue_length() == 0) && running_) { }
srdjan 2015/10/16 23:50:17 Done.
1503 ml.Wait();
1504 }
1505 }
1490 } 1506 }
1491 { 1507 {
1492 // Notify that the thread is done. 1508 // Notify that the thread is done.
1493 MonitorLocker ml_done(done_monitor_); 1509 MonitorLocker ml_done(done_monitor_);
1494 *done_ = true; 1510 *done_ = true;
1495 ml_done.Notify(); 1511 ml_done.Notify();
1496 } 1512 }
1497 } 1513 }
1498 1514
1499 1515
1500 void BackgroundCompiler::CompileOptimized(const Function& function) { 1516 void BackgroundCompiler::CompileOptimized(const Function& function) {
1501 Add(function); 1517 Add(function);
1502 } 1518 }
1503 1519
1504 1520
1505 void BackgroundCompiler::Add(const Function& f) const { 1521 void BackgroundCompiler::Add(const Function& f) {
1506 MonitorLocker ml(monitor_); 1522 MonitorLocker ml(queue_monitor_);
1507 CompilationWorkQueue queue(isolate_); 1523 CompilationWorkQueue queue(isolate_);
1508 queue.PushFront(f); 1524 queue.PushFront(f);
1525 set_queue_length(queue.Length());
1509 ml.Notify(); 1526 ml.Notify();
1510 } 1527 }
1511 1528
1512 1529
1513 RawFunction* BackgroundCompiler::RemoveOrNull() const { 1530 RawFunction* BackgroundCompiler::RemoveOrNull() {
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 if (queue.IsEmpty()) return Function::null();
1534 set_queue_length(queue.Length() - 1);
1535 return queue.PopBack();
1517 } 1536 }
1518 1537
1519 1538
1539 RawFunction* BackgroundCompiler::LastOrNull() const {
1540 MonitorLocker ml(queue_monitor_);
1541 CompilationWorkQueue queue(isolate_);
1542 return queue.IsEmpty() ? Function::null() : queue.Last();
1543 }
1544
1545
1520 void BackgroundCompiler::Stop(BackgroundCompiler* task) { 1546 void BackgroundCompiler::Stop(BackgroundCompiler* task) {
1521 if (task == NULL) { 1547 if (task == NULL) {
1522 return; 1548 return;
1523 } 1549 }
1524 Monitor* monitor = task->monitor_; 1550 Monitor* monitor = task->queue_monitor_;
1525 Monitor* done_monitor = task->done_monitor_; 1551 Monitor* done_monitor = task->done_monitor_;
1526 bool* task_done = task->done_; 1552 bool* task_done = task->done_;
1527 // Wake up compiler task and stop it. 1553 // Wake up compiler task and stop it.
1528 { 1554 {
1529 MonitorLocker ml(task->monitor_); 1555 MonitorLocker ml(task->queue_monitor_);
1530 task->running_ = false; 1556 task->running_ = false;
1531 // 'task' will be deleted by thread pool. 1557 // 'task' will be deleted by thread pool.
1532 task = NULL; 1558 task = NULL;
1533 ml.Notify(); 1559 ml.Notify(); // Stop waiting for the queue.
1534 } 1560 }
1535 1561
1536 { 1562 {
1537 MonitorLocker ml_done(done_monitor); 1563 MonitorLocker ml_done(done_monitor);
1538 while (!(*task_done)) { 1564 while (!(*task_done)) {
1539 ml_done.Wait(); 1565 ml_done.Wait();
1540 } 1566 }
1541 } 1567 }
1542 delete task_done; 1568 delete task_done;
1543 delete done_monitor; 1569 delete done_monitor;
(...skipping 12 matching lines...) Expand all
1556 isolate->current_zone(), GrowableObjectArray::New())); 1582 isolate->current_zone(), GrowableObjectArray::New()));
1557 start_task = true; 1583 start_task = true;
1558 } 1584 }
1559 } 1585 }
1560 if (start_task) { 1586 if (start_task) {
1561 Dart::thread_pool()->Run(isolate->background_compiler()); 1587 Dart::thread_pool()->Run(isolate->background_compiler());
1562 } 1588 }
1563 } 1589 }
1564 1590
1565 } // namespace dart 1591 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/compiler_stats.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698