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

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

Issue 1418813008: This adds a mechanism to invalidate code that was generated in the background. The invalidation can… (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: f Created 5 years, 1 month 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
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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 } 383 }
384 384
385 385
386 // Return false if bailed out. 386 // Return false if bailed out.
387 // If optimized_result_code is not NULL then it is caller's responsibility 387 // If optimized_result_code is not NULL then it is caller's responsibility
388 // to install code. 388 // to install code.
389 static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline, 389 static bool CompileParsedFunctionHelper(CompilationPipeline* pipeline,
390 ParsedFunction* parsed_function, 390 ParsedFunction* parsed_function,
391 bool optimized, 391 bool optimized,
392 intptr_t osr_id, 392 intptr_t osr_id,
393 Code* optimized_result_code) { 393 BackgroundCompilationResult* result) {
394 const Function& function = parsed_function->function(); 394 const Function& function = parsed_function->function();
395 if (optimized && !function.IsOptimizable()) { 395 if (optimized && !function.IsOptimizable()) {
396 return false; 396 return false;
397 } 397 }
398 bool is_compiled = false; 398 bool is_compiled = false;
399 Thread* const thread = Thread::Current(); 399 Thread* const thread = Thread::Current();
400 Zone* const zone = thread->zone(); 400 Zone* const zone = thread->zone();
401 Isolate* const isolate = thread->isolate(); 401 Isolate* const isolate = thread->isolate();
402 CSTAT_TIMER_SCOPE(thread, codegen_timer); 402 CSTAT_TIMER_SCOPE(thread, codegen_timer);
403 HANDLESCOPE(thread); 403 HANDLESCOPE(thread);
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 765
766 graph_compiler.FinalizePcDescriptors(code); 766 graph_compiler.FinalizePcDescriptors(code);
767 code.set_deopt_info_array(deopt_info_array); 767 code.set_deopt_info_array(deopt_info_array);
768 768
769 graph_compiler.FinalizeStackmaps(code); 769 graph_compiler.FinalizeStackmaps(code);
770 graph_compiler.FinalizeVarDescriptors(code); 770 graph_compiler.FinalizeVarDescriptors(code);
771 graph_compiler.FinalizeExceptionHandlers(code); 771 graph_compiler.FinalizeExceptionHandlers(code);
772 graph_compiler.FinalizeStaticCallTargetsTable(code); 772 graph_compiler.FinalizeStaticCallTargetsTable(code);
773 773
774 if (optimized) { 774 if (optimized) {
775 if (optimized_result_code != NULL) { 775 if (result != NULL) {
776 ASSERT(!Thread::Current()->IsMutatorThread());
776 // Do not install code, but return it instead. 777 // Do not install code, but return it instead.
777 // Since code dependencies (CHA, fields) are defined eagerly, 778 // Since code dependencies (CHA, fields) are defined eagerly,
778 // the code may be disabled before installing it. 779 // the code may be disabled before installing it.
779 code.set_owner(function); 780 code.set_owner(function);
780 *optimized_result_code = code.raw(); 781 result->set_result_code(code);
782 // Disable invalidation counters that are not relevant.
783 if (thread->cha()->leaf_classes().is_empty()) {
784 result->ClearCHAInvalidationGen();
785 }
786 if (flow_graph->guarded_fields()->is_empty()) {
787 result->ClearFieldInnvalidationGen();
788 }
789 if (!parsed_function->HasDeferredPrefixes()) {
790 result->ClearPrefixInnvalidationGen();
791 }
781 } else { 792 } else {
782 const bool is_osr = osr_id != Compiler::kNoOSRDeoptId; 793 const bool is_osr = osr_id != Compiler::kNoOSRDeoptId;
783 function.InstallOptimizedCode(code, is_osr); 794 function.InstallOptimizedCode(code, is_osr);
784 } 795 }
785 796
786 // TODO(srdjan): In background compilation, verify that CHA has not 797 // TODO(srdjan): In background compilation, verify that CHA has not
787 // been invalidated in the meantime. 798 // been invalidated in the meantime.
788 // Register code with the classes it depends on because of CHA. 799 // Register code with the classes it depends on because of CHA.
789 for (intptr_t i = 0; 800 for (intptr_t i = 0;
790 i < thread->cha()->leaf_classes().length(); 801 i < thread->cha()->leaf_classes().length();
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 function.raw()); 1027 function.raw());
1017 } 1028 }
1018 } 1029 }
1019 #endif 1030 #endif
1020 1031
1021 1032
1022 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, 1033 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline,
1023 const Function& function, 1034 const Function& function,
1024 bool optimized, 1035 bool optimized,
1025 intptr_t osr_id, 1036 intptr_t osr_id,
1026 Code* result_code) { 1037 BackgroundCompilationResult* result) {
1027 // Check that we optimize if 'Compiler::always_optimize()' is set to true, 1038 // Check that we optimize if 'Compiler::always_optimize()' is set to true,
1028 // except if the function is marked as not optimizable. 1039 // except if the function is marked as not optimizable.
1029 ASSERT(!function.IsOptimizable() || 1040 ASSERT(!function.IsOptimizable() ||
1030 !Compiler::always_optimize() || optimized); 1041 !Compiler::always_optimize() || optimized);
1031 ASSERT(Compiler::allow_recompilation() || !function.HasCode()); 1042 ASSERT(Compiler::allow_recompilation() || !function.HasCode());
1032 LongJumpScope jump; 1043 LongJumpScope jump;
1033 if (setjmp(*jump.Set()) == 0) { 1044 if (setjmp(*jump.Set()) == 0) {
1034 Thread* const thread = Thread::Current(); 1045 Thread* const thread = Thread::Current();
1035 Isolate* const isolate = thread->isolate(); 1046 Isolate* const isolate = thread->isolate();
1036 StackZone stack_zone(thread); 1047 StackZone stack_zone(thread);
(...skipping 22 matching lines...) Expand all
1059 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed); 1070 const int64_t num_tokens_after = STAT_VALUE(thread, num_tokens_consumed);
1060 INC_STAT(thread, 1071 INC_STAT(thread,
1061 num_func_tokens_compiled, 1072 num_func_tokens_compiled,
1062 num_tokens_after - num_tokens_before); 1073 num_tokens_after - num_tokens_before);
1063 } 1074 }
1064 1075
1065 const bool success = CompileParsedFunctionHelper(pipeline, 1076 const bool success = CompileParsedFunctionHelper(pipeline,
1066 parsed_function, 1077 parsed_function,
1067 optimized, 1078 optimized,
1068 osr_id, 1079 osr_id,
1069 result_code); 1080 result);
1070 if (!success) { 1081 if (!success) {
1071 if (optimized) { 1082 if (optimized) {
1072 ASSERT(!Compiler::always_optimize()); // Optimized is the only code. 1083 ASSERT(!Compiler::always_optimize()); // Optimized is the only code.
1073 // Optimizer bailed out. Disable optimizations and never try again. 1084 // Optimizer bailed out. Disable optimizations and never try again.
1074 if (FLAG_trace_compiler) { 1085 if (FLAG_trace_compiler) {
1075 THR_Print("--> disabling optimizations for '%s'\n", 1086 THR_Print("--> disabling optimizations for '%s'\n",
1076 function.ToFullyQualifiedCString()); 1087 function.ToFullyQualifiedCString());
1077 } else if (FLAG_trace_failed_optimization_attempts) { 1088 } else if (FLAG_trace_failed_optimization_attempts) {
1078 THR_Print("Cannot optimize: %s\n", 1089 THR_Print("Cannot optimize: %s\n",
1079 function.ToFullyQualifiedCString()); 1090 function.ToFullyQualifiedCString());
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1182 if (FLAG_trace_compiler) { 1193 if (FLAG_trace_compiler) {
1183 THR_Print("Ensure unoptimized code for %s\n", function.ToCString()); 1194 THR_Print("Ensure unoptimized code for %s\n", function.ToCString());
1184 } 1195 }
1185 return Error::null(); 1196 return Error::null();
1186 } 1197 }
1187 1198
1188 1199
1189 RawError* Compiler::CompileOptimizedFunction(Thread* thread, 1200 RawError* Compiler::CompileOptimizedFunction(Thread* thread,
1190 const Function& function, 1201 const Function& function,
1191 intptr_t osr_id, 1202 intptr_t osr_id,
1192 Code* result_code) { 1203 BackgroundCompilationResult* res) {
1193 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId); 1204 VMTagScope tagScope(thread, VMTag::kCompileOptimizedTagId);
1194 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, 1205 TIMELINE_FUNCTION_COMPILATION_DURATION(thread,
1195 "OptimizedFunction", function); 1206 "OptimizedFunction", function);
1196 1207
1197 // Optimization must happen in non-mutator/Dart thread if background 1208 // Optimization must happen in non-mutator/Dart thread if background
1198 // compilation is on. OSR compilation still occurs in the main thread. 1209 // compilation is on. OSR compilation still occurs in the main thread.
1199 ASSERT((osr_id != kNoOSRDeoptId) || !FLAG_background_compilation || 1210 ASSERT((osr_id != kNoOSRDeoptId) || !FLAG_background_compilation ||
1200 !thread->IsMutatorThread()); 1211 !thread->IsMutatorThread());
1201 CompilationPipeline* pipeline = 1212 CompilationPipeline* pipeline =
1202 CompilationPipeline::New(thread->zone(), function); 1213 CompilationPipeline::New(thread->zone(), function);
1203 return CompileFunctionHelper(pipeline, 1214 return CompileFunctionHelper(pipeline,
1204 function, 1215 function,
1205 true, /* optimized */ 1216 true, /* optimized */
1206 osr_id, 1217 osr_id,
1207 result_code); 1218 res);
1208 } 1219 }
1209 1220
1210 1221
1211 // This is only used from unit tests. 1222 // This is only used from unit tests.
1212 RawError* Compiler::CompileParsedFunction( 1223 RawError* Compiler::CompileParsedFunction(
1213 ParsedFunction* parsed_function) { 1224 ParsedFunction* parsed_function) {
1214 LongJumpScope jump; 1225 LongJumpScope jump;
1215 if (setjmp(*jump.Set()) == 0) { 1226 if (setjmp(*jump.Set()) == 0) {
1216 // Non-optimized code generator. 1227 // Non-optimized code generator.
1217 DartCompilationPipeline pipeline; 1228 DartCompilationPipeline pipeline;
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 explicit CompilationWorkQueue(GrowableObjectArray* data) : data_(data) {} 1469 explicit CompilationWorkQueue(GrowableObjectArray* data) : data_(data) {}
1459 1470
1460 intptr_t IsEmpty() const { return data_->Length() == 0; } 1471 intptr_t IsEmpty() const { return data_->Length() == 0; }
1461 intptr_t Length() const { return data_->Length(); } 1472 intptr_t Length() const { return data_->Length(); }
1462 1473
1463 void PushFrontFunction(const Function& function) { PushFront(function); } 1474 void PushFrontFunction(const Function& function) { PushFront(function); }
1464 RawFunction* PopBackFunction() { return Function::RawCast(PopBack()); } 1475 RawFunction* PopBackFunction() { return Function::RawCast(PopBack()); }
1465 RawFunction* LastFunction() { return Function::RawCast(Last()); } 1476 RawFunction* LastFunction() { return Function::RawCast(Last()); }
1466 1477
1467 void PushBackCode(const Code& code) { PushBack(code); } 1478 void PushBackCode(const Code& code) { PushBack(code); }
1479 void PushBackInt(intptr_t value) { PushBack(Smi::Handle(Smi::New(value))); }
1468 RawCode* PopBackCode() { return Code::RawCast(PopBack()); } 1480 RawCode* PopBackCode() { return Code::RawCast(PopBack()); }
1469 RawCode* LastCode() { return Code::RawCast(Last()); } 1481 intptr_t PopBackInt() { return Smi::Handle(Smi::RawCast(PopBack())).Value(); }
1470 1482
1471 private: 1483 private:
1472 // Adds to the queue only if 'function' is not already in there. 1484 // Adds to the queue only if 'function' is not already in there.
1473 void PushFront(const Object& value) { 1485 void PushFront(const Object& value) {
1474 for (intptr_t i = 0; i < data_->Length(); i++) { 1486 for (intptr_t i = 0; i < data_->Length(); i++) {
1475 if (data_->At(i) == value.raw()) { 1487 if (data_->At(i) == value.raw()) {
1476 return; 1488 return;
1477 } 1489 }
1478 } 1490 }
1479 // Insert new element in front. 1491 // Insert new element in front.
(...skipping 24 matching lines...) Expand all
1504 ASSERT(!IsEmpty()); 1516 ASSERT(!IsEmpty());
1505 return data_->At(data_->Length() - 1); 1517 return data_->At(data_->Length() - 1);
1506 } 1518 }
1507 1519
1508 GrowableObjectArray* data_; 1520 GrowableObjectArray* data_;
1509 1521
1510 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); 1522 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
1511 }; 1523 };
1512 1524
1513 1525
1526
1527 BackgroundCompilationResult::BackgroundCompilationResult()
1528 : result_code_(Code::Handle()),
1529 cha_invalidation_gen_(0),
1530 field_invalidation_gen_(0),
1531 prefix_invalidation_gen_(0) {
1532 }
1533
1534
1535 void BackgroundCompilationResult::Init() {
1536 Isolate* i = Isolate::Current();
1537 result_code_ = Code::null();
1538 cha_invalidation_gen_ = i->cha_invalidation_gen();
1539 field_invalidation_gen_ = i->field_invalidation_gen();
1540 prefix_invalidation_gen_ = i->prefix_invalidation_gen();
1541 }
1542
1543
1544 bool BackgroundCompilationResult::IsValid() const {
1545 if (result_code().IsNull() || result_code().IsDisabled()) {
1546 return false;
1547 }
1548 Isolate* i = Isolate::Current();
1549 if ((cha_invalidation_gen_ != -1 ) &&
1550 (cha_invalidation_gen_ != i->cha_invalidation_gen())) {
1551 return false;
1552 }
1553 if ((field_invalidation_gen_ != -1 ) &&
1554 (field_invalidation_gen_ != i->field_invalidation_gen())) {
1555 return false;
1556 }
1557 if ((prefix_invalidation_gen_ != -1 ) &&
1558 (prefix_invalidation_gen_ != i->prefix_invalidation_gen())) {
1559 return false;
1560 }
1561 return true;
1562 }
1563
1564
1565 void BackgroundCompilationResult::PrintValidity() {
1566 Object& o = Object::Handle(result_code().owner());
1567 THR_Print("BackgroundCompilationResult: %s\n",
1568 Function::Cast(o).ToQualifiedCString());
1569 if (result_code().IsNull()) {
1570 THR_Print(" result_code is NULL\n");
1571 return;
1572 }
1573 if (result_code().IsDisabled()) {
1574 THR_Print(" result_code is disabled\n");
1575 return;
1576 }
1577 Isolate* i = Isolate::Current();
1578 THR_Print(" cha_invalidation_gen: %" Pd " (current: %" Pd ")\n",
1579 cha_invalidation_gen_, i->cha_invalidation_gen());
1580 THR_Print(" field_invalidation_gen: %" Pd " (current: %" Pd ")\n",
1581 field_invalidation_gen_, i->field_invalidation_gen());
1582 THR_Print(" prefix_invalidation_gen: %" Pd " (current: %" Pd ")\n",
1583 prefix_invalidation_gen_, i->prefix_invalidation_gen());
1584 }
1585
1586
1587 void BackgroundCompilationResult::PushOnQueue(
1588 CompilationWorkQueue* queue) const {
1589 queue->PushBackCode(result_code());
1590 queue->PushBackInt(cha_invalidation_gen_);
1591 queue->PushBackInt(field_invalidation_gen_);
1592 queue->PushBackInt(prefix_invalidation_gen_);
1593 }
1594
1595
1596 void BackgroundCompilationResult::PopFromQueue(CompilationWorkQueue* queue) {
1597 prefix_invalidation_gen_ = queue->PopBackInt();
1598 field_invalidation_gen_ = queue->PopBackInt();
1599 cha_invalidation_gen_ = queue->PopBackInt();
1600 result_code_ = queue->PopBackCode();
1601 }
1602
1603
1514 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) 1604 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
1515 : isolate_(isolate), running_(true), done_(new bool()), 1605 : isolate_(isolate), running_(true), done_(new bool()),
1516 queue_monitor_(new Monitor()), done_monitor_(new Monitor()), 1606 queue_monitor_(new Monitor()), done_monitor_(new Monitor()),
1517 function_queue_length_(0) { 1607 function_queue_length_(0) {
1518 *done_ = false; 1608 *done_ = false;
1519 } 1609 }
1520 1610
1521 1611
1522 void BackgroundCompiler::Run() { 1612 void BackgroundCompiler::Run() {
1523 while (running_) { 1613 while (running_) {
1524 // Maybe something is already in the queue, check first before waiting 1614 // Maybe something is already in the queue, check first before waiting
1525 // to be notified. 1615 // to be notified.
1526 Thread::EnterIsolateAsHelper(isolate_); 1616 Thread::EnterIsolateAsHelper(isolate_);
1527 { 1617 {
1528 Thread* thread = Thread::Current(); 1618 Thread* thread = Thread::Current();
1529 StackZone stack_zone(thread); 1619 StackZone stack_zone(thread);
1530 HANDLESCOPE(thread); 1620 HANDLESCOPE(thread);
1531 Zone* zone = stack_zone.GetZone(); 1621 Zone* zone = stack_zone.GetZone();
1532 Function& function = Function::Handle(zone); 1622 Function& function = Function::Handle(zone);
1533 Function& temp_function = Function::Handle(zone); 1623 Function& temp_function = Function::Handle(zone);
1534 Code& code = Code::Handle(zone);
1535 function = LastFunctionOrNull(); 1624 function = LastFunctionOrNull();
1625 BackgroundCompilationResult result;
1536 // Finish all compilation before exiting (even if running_ is changed to 1626 // Finish all compilation before exiting (even if running_ is changed to
1537 // false). 1627 // false).
1538 while (!function.IsNull()) { 1628 while (!function.IsNull()) {
1629 result.Init();
1539 const Error& error = Error::Handle(zone, 1630 const Error& error = Error::Handle(zone,
1540 Compiler::CompileOptimizedFunction(thread, 1631 Compiler::CompileOptimizedFunction(thread,
1541 function, 1632 function,
1542 Compiler::kNoOSRDeoptId, 1633 Compiler::kNoOSRDeoptId,
1543 &code)); 1634 &result));
1544 // TODO(srdjan): We do not expect errors while compiling optimized 1635 // TODO(srdjan): We do not expect errors while compiling optimized
1545 // code, any errors should have been caught when compiling 1636 // code, any errors should have been caught when compiling
1546 // unoptimized code. 1637 // unoptimized code.
1547 // If it still happens mark function as not optimizable. 1638 // If it still happens mark function as not optimizable.
1548 ASSERT(error.IsNull()); 1639 ASSERT(error.IsNull());
1549 temp_function = RemoveFunctionOrNull(); 1640 temp_function = RemoveFunctionOrNull();
1550 ASSERT(temp_function.raw() == function.raw()); 1641 ASSERT(temp_function.raw() == function.raw());
1551 function = LastFunctionOrNull(); 1642 function = LastFunctionOrNull();
1552 ASSERT(!code.IsNull()); 1643 ASSERT(!result.result_code().IsNull());
1553 AddCode(code); 1644 AddResult(result);
1554 } 1645 }
1555 } 1646 }
1556 Thread::ExitIsolateAsHelper(); 1647 Thread::ExitIsolateAsHelper();
1557 { 1648 {
1558 // Wait to be notified when the work queue is not empty. 1649 // Wait to be notified when the work queue is not empty.
1559 MonitorLocker ml(queue_monitor_); 1650 MonitorLocker ml(queue_monitor_);
1560 while ((function_queue_length() == 0) && running_) { 1651 while ((function_queue_length() == 0) && running_) {
1561 ml.Wait(); 1652 ml.Wait();
1562 } 1653 }
1563 } 1654 }
1564 } 1655 }
1565 { 1656 {
1566 // Notify that the thread is done. 1657 // Notify that the thread is done.
1567 MonitorLocker ml_done(done_monitor_); 1658 MonitorLocker ml_done(done_monitor_);
1568 *done_ = true; 1659 *done_ = true;
1569 ml_done.Notify(); 1660 ml_done.Notify();
1570 } 1661 }
1571 } 1662 }
1572 1663
1573 1664
1574 void BackgroundCompiler::CompileOptimized(const Function& function) { 1665 void BackgroundCompiler::CompileOptimized(const Function& function) {
1575 AddFunction(function); 1666 AddFunction(function);
1576 } 1667 }
1577 1668
1578 1669
1579 void BackgroundCompiler::InstallGeneratedCode() { 1670 void BackgroundCompiler::InstallGeneratedCode() {
1671 ASSERT(Thread::Current()->IsMutatorThread());
1580 MonitorLocker ml(queue_monitor_); 1672 MonitorLocker ml(queue_monitor_);
1581 CompilationWorkQueue queue(CodesQueue()); 1673 CompilationWorkQueue queue(ResultQueue());
1582 Code& code = Code::Handle();
1583 Object& owner = Object::Handle(); 1674 Object& owner = Object::Handle();
1584 for (intptr_t i = 0; i < queue.Length(); i++) { 1675 for (intptr_t i = 0; i < queue.Length(); i++) {
1585 code = queue.PopBackCode(); 1676 BackgroundCompilationResult result;
1586 if (code.IsDisabled()) continue; 1677 result.PopFromQueue(&queue);
1587 owner = code.owner(); 1678 owner = result.result_code().owner();
1588 const Function& function = Function::Cast(owner); 1679 const Function& function = Function::Cast(owner);
1589 function.InstallOptimizedCode(code, false /* not OSR */); 1680 if (result.IsValid()) {
1681 function.InstallOptimizedCode(result.result_code(), false /* not OSR */);
1682 }
1590 if (function.usage_counter() < 0) { 1683 if (function.usage_counter() < 0) {
1591 // Reset to 0 so that it can be recompiled if needed. 1684 // Reset to 0 so that it can be recompiled if needed.
1592 function.set_usage_counter(0); 1685 function.set_usage_counter(0);
1593 } 1686 }
1594 } 1687 }
1595 } 1688 }
1596 1689
1597 1690
1598 GrowableObjectArray* BackgroundCompiler::FunctionsQueue() const { 1691 GrowableObjectArray* BackgroundCompiler::FunctionsQueue() const {
1599 return 1692 return
1600 &GrowableObjectArray::ZoneHandle(isolate_->compilation_function_queue()); 1693 &GrowableObjectArray::ZoneHandle(isolate_->compilation_function_queue());
1601 } 1694 }
1602 1695
1603 1696
1604 GrowableObjectArray* BackgroundCompiler::CodesQueue() const { 1697 GrowableObjectArray* BackgroundCompiler::ResultQueue() const {
1605 // Use code queue 1698 return &GrowableObjectArray::ZoneHandle(isolate_->compilation_result_queue());
1606 return &GrowableObjectArray::ZoneHandle(isolate_->compilation_code_queue());
1607 } 1699 }
1608 1700
1609 1701
1610 void BackgroundCompiler::AddFunction(const Function& f) { 1702 void BackgroundCompiler::AddFunction(const Function& f) {
1611 MonitorLocker ml(queue_monitor_); 1703 MonitorLocker ml(queue_monitor_);
1612 CompilationWorkQueue queue(FunctionsQueue()); 1704 CompilationWorkQueue queue(FunctionsQueue());
1613 queue.PushFrontFunction(f); 1705 queue.PushFrontFunction(f);
1614 set_function_queue_length(queue.Length()); 1706 set_function_queue_length(queue.Length());
1615 // Notify waiting background compiler task. 1707 // Notify waiting background compiler task.
1616 ml.Notify(); 1708 ml.Notify();
1617 } 1709 }
1618 1710
1619 1711
1620 RawFunction* BackgroundCompiler::RemoveFunctionOrNull() { 1712 RawFunction* BackgroundCompiler::RemoveFunctionOrNull() {
1621 MonitorLocker ml(queue_monitor_); 1713 MonitorLocker ml(queue_monitor_);
1622 CompilationWorkQueue queue(FunctionsQueue()); 1714 CompilationWorkQueue queue(FunctionsQueue());
1623 if (queue.IsEmpty()) return Function::null(); 1715 if (queue.IsEmpty()) return Function::null();
1624 set_function_queue_length(queue.Length() - 1); 1716 set_function_queue_length(queue.Length() - 1);
1625 return queue.PopBackFunction(); 1717 return queue.PopBackFunction();
1626 } 1718 }
1627 1719
1628 1720
1629 RawFunction* BackgroundCompiler::LastFunctionOrNull() const { 1721 RawFunction* BackgroundCompiler::LastFunctionOrNull() const {
1630 MonitorLocker ml(queue_monitor_); 1722 MonitorLocker ml(queue_monitor_);
1631 CompilationWorkQueue queue(FunctionsQueue()); 1723 CompilationWorkQueue queue(FunctionsQueue());
1632 return queue.IsEmpty() ? Function::null() : queue.LastFunction(); 1724 return queue.IsEmpty() ? Function::null() : queue.LastFunction();
1633 } 1725 }
1634 1726
1635 1727
1636 void BackgroundCompiler::AddCode(const Code& c) { 1728 void BackgroundCompiler::AddResult(const BackgroundCompilationResult& value) {
1637 MonitorLocker ml(queue_monitor_); 1729 MonitorLocker ml(queue_monitor_);
1638 CompilationWorkQueue queue(CodesQueue()); 1730 CompilationWorkQueue queue(ResultQueue());
1639 queue.PushBackCode(c); 1731 value.PushOnQueue(&queue);
1640 } 1732 }
1641 1733
1642 1734
1643 void BackgroundCompiler::Stop(BackgroundCompiler* task) { 1735 void BackgroundCompiler::Stop(BackgroundCompiler* task) {
1644 ASSERT(Isolate::Current()->background_compiler() == task); 1736 ASSERT(Isolate::Current()->background_compiler() == task);
1645 if (task == NULL) { 1737 if (task == NULL) {
1646 return; 1738 return;
1647 } 1739 }
1648 Monitor* monitor = task->queue_monitor_; 1740 Monitor* monitor = task->queue_monitor_;
1649 Monitor* done_monitor = task->done_monitor_; 1741 Monitor* done_monitor = task->done_monitor_;
(...skipping 23 matching lines...) Expand all
1673 void BackgroundCompiler::EnsureInit(Thread* thread) { 1765 void BackgroundCompiler::EnsureInit(Thread* thread) {
1674 bool start_task = false; 1766 bool start_task = false;
1675 Isolate* isolate = thread->isolate(); 1767 Isolate* isolate = thread->isolate();
1676 { 1768 {
1677 MutexLocker ml(isolate->mutex()); 1769 MutexLocker ml(isolate->mutex());
1678 if (isolate->background_compiler() == NULL) { 1770 if (isolate->background_compiler() == NULL) {
1679 BackgroundCompiler* task = new BackgroundCompiler(isolate); 1771 BackgroundCompiler* task = new BackgroundCompiler(isolate);
1680 isolate->set_background_compiler(task); 1772 isolate->set_background_compiler(task);
1681 isolate->set_compilation_function_queue(GrowableObjectArray::Handle( 1773 isolate->set_compilation_function_queue(GrowableObjectArray::Handle(
1682 thread->zone(), GrowableObjectArray::New())); 1774 thread->zone(), GrowableObjectArray::New()));
1683 isolate->set_compilation_code_queue(GrowableObjectArray::Handle( 1775 isolate->set_compilation_result_queue(GrowableObjectArray::Handle(
1684 thread->zone(), GrowableObjectArray::New())); 1776 thread->zone(), GrowableObjectArray::New()));
1685 start_task = true; 1777 start_task = true;
1686 } 1778 }
1687 } 1779 }
1688 if (start_task) { 1780 if (start_task) {
1689 Dart::thread_pool()->Run(isolate->background_compiler()); 1781 Dart::thread_pool()->Run(isolate->background_compiler());
1690 } 1782 }
1691 } 1783 }
1692 1784
1693 } // namespace dart 1785 } // namespace dart
OLDNEW
« runtime/vm/compiler.h ('K') | « runtime/vm/compiler.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698