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

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: Better code. 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 occurs 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 return Function::RawCast(data_.At(data_.Length() - 1));
1453 }
1454
1449 private: 1455 private:
1450 GrowableObjectArray& data_; 1456 GrowableObjectArray& data_;
1451 1457
1452 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); 1458 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
1453 }; 1459 };
1454 1460
1455 1461
1456 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) 1462 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
1457 : isolate_(isolate), running_(true), done_(new bool()), 1463 : isolate_(isolate), running_(true), done_(new bool()),
1458 monitor_(new Monitor()), done_monitor_(new Monitor()) { 1464 queue_monitor_(new Monitor()), done_monitor_(new Monitor()),
1465 queue_length_(0) {
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 while ((queue_length() == 0) && running_) {
1501 ml.Wait();
1502 }
1503 }
1490 } 1504 }
1491 { 1505 {
1492 // Notify that the thread is done. 1506 // Notify that the thread is done.
1493 MonitorLocker ml_done(done_monitor_); 1507 MonitorLocker ml_done(done_monitor_);
1494 *done_ = true; 1508 *done_ = true;
1495 ml_done.Notify(); 1509 ml_done.Notify();
1496 } 1510 }
1497 } 1511 }
1498 1512
1499 1513
1500 void BackgroundCompiler::CompileOptimized(const Function& function) { 1514 void BackgroundCompiler::CompileOptimized(const Function& function) {
1501 Add(function); 1515 Add(function);
1502 } 1516 }
1503 1517
1504 1518
1505 void BackgroundCompiler::Add(const Function& f) const { 1519 void BackgroundCompiler::Add(const Function& f) {
1506 MonitorLocker ml(monitor_); 1520 MonitorLocker ml(queue_monitor_);
1507 CompilationWorkQueue queue(isolate_); 1521 CompilationWorkQueue queue(isolate_);
1508 queue.PushFront(f); 1522 queue.PushFront(f);
1523 set_queue_length(queue.Length());
1509 ml.Notify(); 1524 ml.Notify();
1510 } 1525 }
1511 1526
1512 1527
1513 RawFunction* BackgroundCompiler::RemoveOrNull() const { 1528 RawFunction* BackgroundCompiler::RemoveOrNull() {
1514 MonitorLocker ml(monitor_); 1529 MonitorLocker ml(queue_monitor_);
1515 CompilationWorkQueue queue(isolate_); 1530 CompilationWorkQueue queue(isolate_);
1516 return queue.IsEmpty() ? Function::null() : queue.PopBack(); 1531 if (queue.IsEmpty()) return Function::null();
1532 set_queue_length(queue.Length() - 1);
1533 return 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
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
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