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

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

Powered by Google App Engine
This is Rietveld 408576698