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

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: sync 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
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/isolate.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 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 PushBackInteger(const Integer& value) { PushBack(value); }
1468 RawCode* PopBackCode() { return Code::RawCast(PopBack()); } 1480 RawCode* PopBackCode() { return Code::RawCast(PopBack()); }
1469 RawCode* LastCode() { return Code::RawCast(Last()); } 1481 RawInteger* PopBackInteger() {
1482 Object& o = Object::Handle(PopBack());
1483 if (o.IsNull()) {
1484 return Integer::null();
1485 } else {
1486 return Integer::Cast(o).raw();
1487 }
1488 }
1470 1489
1471 private: 1490 private:
1472 // Adds to the queue only if 'function' is not already in there. 1491 // Adds to the queue only if 'function' is not already in there.
1473 void PushFront(const Object& value) { 1492 void PushFront(const Object& value) {
1474 for (intptr_t i = 0; i < data_->Length(); i++) { 1493 for (intptr_t i = 0; i < data_->Length(); i++) {
1475 if (data_->At(i) == value.raw()) { 1494 if (data_->At(i) == value.raw()) {
1476 return; 1495 return;
1477 } 1496 }
1478 } 1497 }
1479 // Insert new element in front. 1498 // Insert new element in front.
(...skipping 24 matching lines...) Expand all
1504 ASSERT(!IsEmpty()); 1523 ASSERT(!IsEmpty());
1505 return data_->At(data_->Length() - 1); 1524 return data_->At(data_->Length() - 1);
1506 } 1525 }
1507 1526
1508 GrowableObjectArray* data_; 1527 GrowableObjectArray* data_;
1509 1528
1510 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue); 1529 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationWorkQueue);
1511 }; 1530 };
1512 1531
1513 1532
1533
1534 BackgroundCompilationResult::BackgroundCompilationResult()
1535 : result_code_(Code::Handle()),
1536 cha_invalidation_gen_(Integer::Handle()),
1537 field_invalidation_gen_(Integer::Handle()),
1538 prefix_invalidation_gen_(Integer::Handle()) {
1539 }
1540
1541
1542 void BackgroundCompilationResult::Init() {
1543 Isolate* i = Isolate::Current();
1544 result_code_ = Code::null();
1545 cha_invalidation_gen_ = Integer::New(i->cha_invalidation_gen(), Heap::kOld);
1546 field_invalidation_gen_ =
1547 Integer::New(i->field_invalidation_gen(), Heap::kOld);
1548 prefix_invalidation_gen_ =
1549 Integer::New(i->prefix_invalidation_gen(), Heap::kOld);
1550 }
1551
1552
1553 bool BackgroundCompilationResult::IsValid() const {
1554 if (result_code().IsNull() || result_code().IsDisabled()) {
1555 return false;
1556 }
1557 Isolate* i = Isolate::Current();
1558 if (!cha_invalidation_gen_.IsNull() &&
1559 (cha_invalidation_gen_.AsInt64Value() != i->cha_invalidation_gen())) {
1560 return false;
1561 }
1562 if (!field_invalidation_gen_.IsNull() &&
1563 (field_invalidation_gen_.AsInt64Value() != i->field_invalidation_gen())) {
1564 return false;
1565 }
1566 if (!prefix_invalidation_gen_.IsNull() &&
1567 (prefix_invalidation_gen_.AsInt64Value() !=
1568 i->prefix_invalidation_gen())) {
1569 return false;
1570 }
1571 return true;
1572 }
1573
1574
1575 void BackgroundCompilationResult::PrintValidity() const {
1576 Object& o = Object::Handle(result_code().owner());
1577 THR_Print("BackgroundCompilationResult: %s\n",
1578 Function::Cast(o).ToQualifiedCString());
1579 if (result_code().IsNull()) {
1580 THR_Print(" result_code is NULL\n");
1581 return;
1582 }
1583 if (result_code().IsDisabled()) {
1584 THR_Print(" result_code is disabled\n");
1585 return;
1586 }
1587 Isolate* i = Isolate::Current();
1588 THR_Print(" cha_invalidation_gen: %s (current: %u)\n",
1589 cha_invalidation_gen_.ToCString(), i->cha_invalidation_gen());
1590 THR_Print(" field_invalidation_gen: %s (current: %u)\n",
1591 field_invalidation_gen_.ToCString(), i->field_invalidation_gen());
1592 THR_Print(" prefix_invalidation_gen: %s (current: %u)\n",
1593 prefix_invalidation_gen_.ToCString(), i->prefix_invalidation_gen());
1594 }
1595
1596
1597 void BackgroundCompilationResult::PushOnQueue(
1598 CompilationWorkQueue* queue) const {
1599 queue->PushBackCode(result_code());
1600 queue->PushBackInteger(cha_invalidation_gen_);
1601 queue->PushBackInteger(field_invalidation_gen_);
1602 queue->PushBackInteger(prefix_invalidation_gen_);
1603 }
1604
1605
1606 void BackgroundCompilationResult::PopFromQueue(CompilationWorkQueue* queue) {
1607 prefix_invalidation_gen_ = queue->PopBackInteger();
1608 field_invalidation_gen_ = queue->PopBackInteger();
1609 cha_invalidation_gen_ = queue->PopBackInteger();
1610 result_code_ = queue->PopBackCode();
1611 }
1612
1613
1514 BackgroundCompiler::BackgroundCompiler(Isolate* isolate) 1614 BackgroundCompiler::BackgroundCompiler(Isolate* isolate)
1515 : isolate_(isolate), running_(true), done_(new bool()), 1615 : isolate_(isolate), running_(true), done_(new bool()),
1516 queue_monitor_(new Monitor()), done_monitor_(new Monitor()), 1616 queue_monitor_(new Monitor()), done_monitor_(new Monitor()),
1517 function_queue_length_(0) { 1617 function_queue_length_(0) {
1518 *done_ = false; 1618 *done_ = false;
1519 } 1619 }
1520 1620
1521 1621
1522 void BackgroundCompiler::Run() { 1622 void BackgroundCompiler::Run() {
1523 while (running_) { 1623 while (running_) {
1524 // Maybe something is already in the queue, check first before waiting 1624 // Maybe something is already in the queue, check first before waiting
1525 // to be notified. 1625 // to be notified.
1526 Thread::EnterIsolateAsHelper(isolate_); 1626 Thread::EnterIsolateAsHelper(isolate_);
1527 { 1627 {
1528 Thread* thread = Thread::Current(); 1628 Thread* thread = Thread::Current();
1529 StackZone stack_zone(thread); 1629 StackZone stack_zone(thread);
1530 HANDLESCOPE(thread); 1630 HANDLESCOPE(thread);
1531 Zone* zone = stack_zone.GetZone(); 1631 Zone* zone = stack_zone.GetZone();
1532 Function& function = Function::Handle(zone); 1632 Function& function = Function::Handle(zone);
1533 Function& temp_function = Function::Handle(zone); 1633 Function& temp_function = Function::Handle(zone);
1534 Code& code = Code::Handle(zone);
1535 function = LastFunctionOrNull(); 1634 function = LastFunctionOrNull();
1635 BackgroundCompilationResult result;
1536 // Finish all compilation before exiting (even if running_ is changed to 1636 // Finish all compilation before exiting (even if running_ is changed to
1537 // false). 1637 // false).
1538 while (!function.IsNull()) { 1638 while (!function.IsNull()) {
1639 result.Init();
1539 const Error& error = Error::Handle(zone, 1640 const Error& error = Error::Handle(zone,
1540 Compiler::CompileOptimizedFunction(thread, 1641 Compiler::CompileOptimizedFunction(thread,
1541 function, 1642 function,
1542 Compiler::kNoOSRDeoptId, 1643 Compiler::kNoOSRDeoptId,
1543 &code)); 1644 &result));
1544 // TODO(srdjan): We do not expect errors while compiling optimized 1645 // TODO(srdjan): We do not expect errors while compiling optimized
1545 // code, any errors should have been caught when compiling 1646 // code, any errors should have been caught when compiling
1546 // unoptimized code. 1647 // unoptimized code.
1547 // If it still happens mark function as not optimizable. 1648 // If it still happens mark function as not optimizable.
1548 ASSERT(error.IsNull()); 1649 ASSERT(error.IsNull());
1549 temp_function = RemoveFunctionOrNull(); 1650 temp_function = RemoveFunctionOrNull();
1550 ASSERT(temp_function.raw() == function.raw()); 1651 ASSERT(temp_function.raw() == function.raw());
1551 function = LastFunctionOrNull(); 1652 function = LastFunctionOrNull();
1552 ASSERT(!code.IsNull()); 1653 ASSERT(!result.result_code().IsNull());
1553 AddCode(code); 1654 AddResult(result);
1554 } 1655 }
1555 } 1656 }
1556 Thread::ExitIsolateAsHelper(); 1657 Thread::ExitIsolateAsHelper();
1557 { 1658 {
1558 // Wait to be notified when the work queue is not empty. 1659 // Wait to be notified when the work queue is not empty.
1559 MonitorLocker ml(queue_monitor_); 1660 MonitorLocker ml(queue_monitor_);
1560 while ((function_queue_length() == 0) && running_) { 1661 while ((function_queue_length() == 0) && running_) {
1561 ml.Wait(); 1662 ml.Wait();
1562 } 1663 }
1563 } 1664 }
1564 } 1665 }
1565 { 1666 {
1566 // Notify that the thread is done. 1667 // Notify that the thread is done.
1567 MonitorLocker ml_done(done_monitor_); 1668 MonitorLocker ml_done(done_monitor_);
1568 *done_ = true; 1669 *done_ = true;
1569 ml_done.Notify(); 1670 ml_done.Notify();
1570 } 1671 }
1571 } 1672 }
1572 1673
1573 1674
1574 void BackgroundCompiler::CompileOptimized(const Function& function) { 1675 void BackgroundCompiler::CompileOptimized(const Function& function) {
1575 AddFunction(function); 1676 AddFunction(function);
1576 } 1677 }
1577 1678
1578 1679
1579 void BackgroundCompiler::InstallGeneratedCode() { 1680 void BackgroundCompiler::InstallGeneratedCode() {
1681 ASSERT(Thread::Current()->IsMutatorThread());
1580 MonitorLocker ml(queue_monitor_); 1682 MonitorLocker ml(queue_monitor_);
1581 CompilationWorkQueue queue(CodesQueue()); 1683 CompilationWorkQueue queue(ResultQueue());
1582 Code& code = Code::Handle();
1583 Object& owner = Object::Handle(); 1684 Object& owner = Object::Handle();
1584 for (intptr_t i = 0; i < queue.Length(); i++) { 1685 for (intptr_t i = 0; i < queue.Length(); i++) {
1585 code = queue.PopBackCode(); 1686 BackgroundCompilationResult result;
1586 if (code.IsDisabled()) continue; 1687 result.PopFromQueue(&queue);
1587 owner = code.owner(); 1688 owner = result.result_code().owner();
1588 const Function& function = Function::Cast(owner); 1689 const Function& function = Function::Cast(owner);
1589 function.InstallOptimizedCode(code, false /* not OSR */); 1690 if (result.IsValid()) {
1691 function.InstallOptimizedCode(result.result_code(), false /* not OSR */);
1692 } else if (FLAG_trace_compiler) {
1693 THR_Print("Drop code generated in the background compiler:\n");
1694 result.PrintValidity();
1695 }
1590 if (function.usage_counter() < 0) { 1696 if (function.usage_counter() < 0) {
1591 // Reset to 0 so that it can be recompiled if needed. 1697 // Reset to 0 so that it can be recompiled if needed.
1592 function.set_usage_counter(0); 1698 function.set_usage_counter(0);
1593 } 1699 }
1594 } 1700 }
1595 } 1701 }
1596 1702
1597 1703
1598 GrowableObjectArray* BackgroundCompiler::FunctionsQueue() const { 1704 GrowableObjectArray* BackgroundCompiler::FunctionsQueue() const {
1599 return 1705 return
1600 &GrowableObjectArray::ZoneHandle(isolate_->compilation_function_queue()); 1706 &GrowableObjectArray::ZoneHandle(isolate_->compilation_function_queue());
1601 } 1707 }
1602 1708
1603 1709
1604 GrowableObjectArray* BackgroundCompiler::CodesQueue() const { 1710 GrowableObjectArray* BackgroundCompiler::ResultQueue() const {
1605 // Use code queue 1711 return &GrowableObjectArray::ZoneHandle(isolate_->compilation_result_queue());
1606 return &GrowableObjectArray::ZoneHandle(isolate_->compilation_code_queue());
1607 } 1712 }
1608 1713
1609 1714
1610 void BackgroundCompiler::AddFunction(const Function& f) { 1715 void BackgroundCompiler::AddFunction(const Function& f) {
1611 MonitorLocker ml(queue_monitor_); 1716 MonitorLocker ml(queue_monitor_);
1612 CompilationWorkQueue queue(FunctionsQueue()); 1717 CompilationWorkQueue queue(FunctionsQueue());
1613 queue.PushFrontFunction(f); 1718 queue.PushFrontFunction(f);
1614 set_function_queue_length(queue.Length()); 1719 set_function_queue_length(queue.Length());
1615 // Notify waiting background compiler task. 1720 // Notify waiting background compiler task.
1616 ml.Notify(); 1721 ml.Notify();
1617 } 1722 }
1618 1723
1619 1724
1620 RawFunction* BackgroundCompiler::RemoveFunctionOrNull() { 1725 RawFunction* BackgroundCompiler::RemoveFunctionOrNull() {
1621 MonitorLocker ml(queue_monitor_); 1726 MonitorLocker ml(queue_monitor_);
1622 CompilationWorkQueue queue(FunctionsQueue()); 1727 CompilationWorkQueue queue(FunctionsQueue());
1623 if (queue.IsEmpty()) return Function::null(); 1728 if (queue.IsEmpty()) return Function::null();
1624 set_function_queue_length(queue.Length() - 1); 1729 set_function_queue_length(queue.Length() - 1);
1625 return queue.PopBackFunction(); 1730 return queue.PopBackFunction();
1626 } 1731 }
1627 1732
1628 1733
1629 RawFunction* BackgroundCompiler::LastFunctionOrNull() const { 1734 RawFunction* BackgroundCompiler::LastFunctionOrNull() const {
1630 MonitorLocker ml(queue_monitor_); 1735 MonitorLocker ml(queue_monitor_);
1631 CompilationWorkQueue queue(FunctionsQueue()); 1736 CompilationWorkQueue queue(FunctionsQueue());
1632 return queue.IsEmpty() ? Function::null() : queue.LastFunction(); 1737 return queue.IsEmpty() ? Function::null() : queue.LastFunction();
1633 } 1738 }
1634 1739
1635 1740
1636 void BackgroundCompiler::AddCode(const Code& c) { 1741 void BackgroundCompiler::AddResult(const BackgroundCompilationResult& value) {
1637 MonitorLocker ml(queue_monitor_); 1742 MonitorLocker ml(queue_monitor_);
1638 CompilationWorkQueue queue(CodesQueue()); 1743 CompilationWorkQueue queue(ResultQueue());
1639 queue.PushBackCode(c); 1744 value.PushOnQueue(&queue);
1640 } 1745 }
1641 1746
1642 1747
1643 void BackgroundCompiler::Stop(BackgroundCompiler* task) { 1748 void BackgroundCompiler::Stop(BackgroundCompiler* task) {
1644 ASSERT(Isolate::Current()->background_compiler() == task); 1749 ASSERT(Isolate::Current()->background_compiler() == task);
1645 if (task == NULL) { 1750 if (task == NULL) {
1646 return; 1751 return;
1647 } 1752 }
1648 Monitor* monitor = task->queue_monitor_; 1753 Monitor* monitor = task->queue_monitor_;
1649 Monitor* done_monitor = task->done_monitor_; 1754 Monitor* done_monitor = task->done_monitor_;
(...skipping 23 matching lines...) Expand all
1673 void BackgroundCompiler::EnsureInit(Thread* thread) { 1778 void BackgroundCompiler::EnsureInit(Thread* thread) {
1674 bool start_task = false; 1779 bool start_task = false;
1675 Isolate* isolate = thread->isolate(); 1780 Isolate* isolate = thread->isolate();
1676 { 1781 {
1677 MutexLocker ml(isolate->mutex()); 1782 MutexLocker ml(isolate->mutex());
1678 if (isolate->background_compiler() == NULL) { 1783 if (isolate->background_compiler() == NULL) {
1679 BackgroundCompiler* task = new BackgroundCompiler(isolate); 1784 BackgroundCompiler* task = new BackgroundCompiler(isolate);
1680 isolate->set_background_compiler(task); 1785 isolate->set_background_compiler(task);
1681 isolate->set_compilation_function_queue(GrowableObjectArray::Handle( 1786 isolate->set_compilation_function_queue(GrowableObjectArray::Handle(
1682 thread->zone(), GrowableObjectArray::New())); 1787 thread->zone(), GrowableObjectArray::New()));
1683 isolate->set_compilation_code_queue(GrowableObjectArray::Handle( 1788 isolate->set_compilation_result_queue(GrowableObjectArray::Handle(
1684 thread->zone(), GrowableObjectArray::New())); 1789 thread->zone(), GrowableObjectArray::New()));
1685 start_task = true; 1790 start_task = true;
1686 } 1791 }
1687 } 1792 }
1688 if (start_task) { 1793 if (start_task) {
1689 Dart::thread_pool()->Run(isolate->background_compiler()); 1794 Dart::thread_pool()->Run(isolate->background_compiler());
1690 } 1795 }
1691 } 1796 }
1692 1797
1693 } // namespace dart 1798 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698