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

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

Issue 2579413002: Revert "Save and restore feedback from JIT." (Closed)
Patch Set: Created 4 years 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/flow_graph_compiler.cc ('k') | runtime/vm/intermediate_language.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 #if !defined(DART_PRECOMPILED_RUNTIME) 4 #if !defined(DART_PRECOMPILED_RUNTIME)
5 #include "vm/flow_graph_inliner.h" 5 #include "vm/flow_graph_inliner.h"
6 6
7 #include "vm/aot_optimizer.h" 7 #include "vm/aot_optimizer.h"
8 #include "vm/precompiler.h"
9 #include "vm/block_scheduler.h" 8 #include "vm/block_scheduler.h"
10 #include "vm/branch_optimizer.h" 9 #include "vm/branch_optimizer.h"
11 #include "vm/compiler.h" 10 #include "vm/compiler.h"
12 #include "vm/kernel.h" 11 #include "vm/kernel.h"
13 #include "vm/kernel_to_il.h" 12 #include "vm/kernel_to_il.h"
14 #include "vm/flags.h" 13 #include "vm/flags.h"
15 #include "vm/flow_graph.h" 14 #include "vm/flow_graph.h"
16 #include "vm/flow_graph_builder.h" 15 #include "vm/flow_graph_builder.h"
17 #include "vm/flow_graph_compiler.h" 16 #include "vm/flow_graph_compiler.h"
18 #include "vm/flow_graph_type_propagator.h" 17 #include "vm/flow_graph_type_propagator.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 inlined(inlined_function), 206 inlined(inlined_function),
208 inlined_depth(depth), 207 inlined_depth(depth),
209 call_instr(call), 208 call_instr(call),
210 bailout_reason(reason) {} 209 bailout_reason(reason) {}
211 }; 210 };
212 211
213 212
214 // A collection of call sites to consider for inlining. 213 // A collection of call sites to consider for inlining.
215 class CallSites : public ValueObject { 214 class CallSites : public ValueObject {
216 public: 215 public:
217 explicit CallSites(FlowGraph* flow_graph, intptr_t threshold) 216 explicit CallSites(FlowGraph* flow_graph)
218 : inlining_depth_threshold_(threshold), 217 : static_calls_(), closure_calls_(), instance_calls_() {}
219 static_calls_(),
220 closure_calls_(),
221 instance_calls_() {}
222 218
223 struct InstanceCallInfo { 219 struct InstanceCallInfo {
224 PolymorphicInstanceCallInstr* call; 220 PolymorphicInstanceCallInstr* call;
225 double ratio; 221 double ratio;
226 const FlowGraph* caller_graph; 222 const FlowGraph* caller_graph;
227 InstanceCallInfo(PolymorphicInstanceCallInstr* call_arg, 223 InstanceCallInfo(PolymorphicInstanceCallInstr* call_arg,
228 FlowGraph* flow_graph) 224 FlowGraph* flow_graph)
229 : call(call_arg), ratio(0.0), caller_graph(flow_graph) {} 225 : call(call_arg), ratio(0.0), caller_graph(flow_graph) {}
230 const Function& caller() const { return caller_graph->function(); } 226 const Function& caller() const { return caller_graph->function(); }
231 }; 227 };
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 } 350 }
355 } 351 }
356 } 352 }
357 } 353 }
358 354
359 355
360 void FindCallSites(FlowGraph* graph, 356 void FindCallSites(FlowGraph* graph,
361 intptr_t depth, 357 intptr_t depth,
362 GrowableArray<InlinedInfo>* inlined_info) { 358 GrowableArray<InlinedInfo>* inlined_info) {
363 ASSERT(graph != NULL); 359 ASSERT(graph != NULL);
364 if (depth > inlining_depth_threshold_) { 360 if (depth > FLAG_inlining_depth_threshold) {
365 if (FLAG_print_inlining_tree) { 361 if (FLAG_print_inlining_tree) {
366 RecordAllNotInlinedFunction(graph, depth, inlined_info); 362 RecordAllNotInlinedFunction(graph, depth, inlined_info);
367 } 363 }
368 return; 364 return;
369 } 365 }
370 366
371 // Recognized methods are not treated as normal calls. They don't have 367 // Recognized methods are not treated as normal calls. They don't have
372 // calls in themselves, so we keep adding those even when at the threshold. 368 // calls in themselves, so we keep adding those even when at the threshold.
373 const bool inline_only_recognized_methods = 369 const bool inline_only_recognized_methods =
374 (depth == inlining_depth_threshold_); 370 (depth == FLAG_inlining_depth_threshold);
375 371
376 const intptr_t instance_call_start_ix = instance_calls_.length(); 372 const intptr_t instance_call_start_ix = instance_calls_.length();
377 const intptr_t static_call_start_ix = static_calls_.length(); 373 const intptr_t static_call_start_ix = static_calls_.length();
378 for (BlockIterator block_it = graph->postorder_iterator(); !block_it.Done(); 374 for (BlockIterator block_it = graph->postorder_iterator(); !block_it.Done();
379 block_it.Advance()) { 375 block_it.Advance()) {
380 for (ForwardInstructionIterator it(block_it.Current()); !it.Done(); 376 for (ForwardInstructionIterator it(block_it.Current()); !it.Done();
381 it.Advance()) { 377 it.Advance()) {
382 Instruction* current = it.Current(); 378 Instruction* current = it.Current();
383 if (current->IsPolymorphicInstanceCall()) { 379 if (current->IsPolymorphicInstanceCall()) {
384 PolymorphicInstanceCallInstr* instance_call = 380 PolymorphicInstanceCallInstr* instance_call =
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 ClosureCallInstr* closure_call = current->AsClosureCall(); 416 ClosureCallInstr* closure_call = current->AsClosureCall();
421 closure_calls_.Add(ClosureCallInfo(closure_call, graph)); 417 closure_calls_.Add(ClosureCallInfo(closure_call, graph));
422 } 418 }
423 } 419 }
424 } 420 }
425 } 421 }
426 ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix); 422 ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix);
427 } 423 }
428 424
429 private: 425 private:
430 intptr_t inlining_depth_threshold_;
431 GrowableArray<StaticCallInfo> static_calls_; 426 GrowableArray<StaticCallInfo> static_calls_;
432 GrowableArray<ClosureCallInfo> closure_calls_; 427 GrowableArray<ClosureCallInfo> closure_calls_;
433 GrowableArray<InstanceCallInfo> instance_calls_; 428 GrowableArray<InstanceCallInfo> instance_calls_;
434 429
435 DISALLOW_COPY_AND_ASSIGN(CallSites); 430 DISALLOW_COPY_AND_ASSIGN(CallSites);
436 }; 431 };
437 432
438 433
439 struct InlinedCallData { 434 struct InlinedCallData {
440 InlinedCallData(Definition* call, 435 InlinedCallData(Definition* call,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 return true; 506 return true;
512 } 507 }
513 } 508 }
514 } 509 }
515 return false; 510 return false;
516 } 511 }
517 512
518 513
519 class CallSiteInliner : public ValueObject { 514 class CallSiteInliner : public ValueObject {
520 public: 515 public:
521 explicit CallSiteInliner(FlowGraphInliner* inliner, intptr_t threshold) 516 explicit CallSiteInliner(FlowGraphInliner* inliner)
522 : inliner_(inliner), 517 : inliner_(inliner),
523 caller_graph_(inliner->flow_graph()), 518 caller_graph_(inliner->flow_graph()),
524 inlined_(false), 519 inlined_(false),
525 initial_size_(inliner->flow_graph()->InstructionCount()), 520 initial_size_(inliner->flow_graph()->InstructionCount()),
526 inlined_size_(0), 521 inlined_size_(0),
527 inlined_recursive_call_(false), 522 inlined_recursive_call_(false),
528 inlining_depth_(1), 523 inlining_depth_(1),
529 inlining_recursion_depth_(0), 524 inlining_recursion_depth_(0),
530 inlining_depth_threshold_(threshold),
531 collected_call_sites_(NULL), 525 collected_call_sites_(NULL),
532 inlining_call_sites_(NULL), 526 inlining_call_sites_(NULL),
533 function_cache_(), 527 function_cache_(),
534 inlined_info_() {} 528 inlined_info_() {}
535 529
536 FlowGraph* caller_graph() const { return caller_graph_; } 530 FlowGraph* caller_graph() const { return caller_graph_; }
537 531
538 Thread* thread() const { return caller_graph_->thread(); } 532 Thread* thread() const { return caller_graph_->thread(); }
539 Isolate* isolate() const { return caller_graph_->isolate(); } 533 Isolate* isolate() const { return caller_graph_->isolate(); }
540 Zone* zone() const { return caller_graph_->zone(); } 534 Zone* zone() const { return caller_graph_->zone(); }
(...skipping 28 matching lines...) Expand all
569 } 563 }
570 if ((const_arg_count >= FLAG_inlining_constant_arguments_count) && 564 if ((const_arg_count >= FLAG_inlining_constant_arguments_count) &&
571 (instr_count <= FLAG_inlining_constant_arguments_min_size_threshold)) { 565 (instr_count <= FLAG_inlining_constant_arguments_min_size_threshold)) {
572 return true; 566 return true;
573 } 567 }
574 return false; 568 return false;
575 } 569 }
576 570
577 void InlineCalls() { 571 void InlineCalls() {
578 // If inlining depth is less then one abort. 572 // If inlining depth is less then one abort.
579 if (inlining_depth_threshold_ < 1) return; 573 if (FLAG_inlining_depth_threshold < 1) return;
580 if (caller_graph_->function().deoptimization_counter() >= 574 if (caller_graph_->function().deoptimization_counter() >=
581 FLAG_deoptimization_counter_inlining_threshold) { 575 FLAG_deoptimization_counter_inlining_threshold) {
582 return; 576 return;
583 } 577 }
584 // Create two call site collections to swap between. 578 // Create two call site collections to swap between.
585 CallSites sites1(caller_graph_, inlining_depth_threshold_); 579 CallSites sites1(caller_graph_);
586 CallSites sites2(caller_graph_, inlining_depth_threshold_); 580 CallSites sites2(caller_graph_);
587 CallSites* call_sites_temp = NULL; 581 CallSites* call_sites_temp = NULL;
588 collected_call_sites_ = &sites1; 582 collected_call_sites_ = &sites1;
589 inlining_call_sites_ = &sites2; 583 inlining_call_sites_ = &sites2;
590 // Collect initial call sites. 584 // Collect initial call sites.
591 collected_call_sites_->FindCallSites(caller_graph_, inlining_depth_, 585 collected_call_sites_->FindCallSites(caller_graph_, inlining_depth_,
592 &inlined_info_); 586 &inlined_info_);
593 while (collected_call_sites_->HasCalls()) { 587 while (collected_call_sites_->HasCalls()) {
594 TRACE_INLINING( 588 TRACE_INLINING(
595 THR_Print(" Depth %" Pd " ----------\n", inlining_depth_)); 589 THR_Print(" Depth %" Pd " ----------\n", inlining_depth_));
596 if (collected_call_sites_->NumCalls() > FLAG_max_inlined_per_depth) { 590 if (collected_call_sites_->NumCalls() > FLAG_max_inlined_per_depth) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 662
669 // Do not rely on function type feedback or presence of code to determine 663 // Do not rely on function type feedback or presence of code to determine
670 // if a function was compiled. 664 // if a function was compiled.
671 if (!FLAG_precompiled_mode && !function.was_compiled()) { 665 if (!FLAG_precompiled_mode && !function.was_compiled()) {
672 TRACE_INLINING(THR_Print(" Bailout: not compiled yet\n")); 666 TRACE_INLINING(THR_Print(" Bailout: not compiled yet\n"));
673 PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function, 667 PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function,
674 call_data->call); 668 call_data->call);
675 return false; 669 return false;
676 } 670 }
677 671
678 if ((inliner_->precompiler_ != NULL) &&
679 inliner_->precompiler_->HasFeedback() &&
680 (function.usage_counter() <= 0) && !inliner_->AlwaysInline(function)) {
681 TRACE_INLINING(THR_Print(" Bailout: not compiled yet\n"));
682 PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function,
683 call_data->call);
684 return false;
685 }
686
687 // Type feedback may have been cleared for this function (ClearICDataArray), 672 // Type feedback may have been cleared for this function (ClearICDataArray),
688 // but we need it for inlining. 673 // but we need it for inlining.
689 if (!FLAG_precompiled_mode && (function.ic_data_array() == Array::null())) { 674 if (!FLAG_precompiled_mode && (function.ic_data_array() == Array::null())) {
690 TRACE_INLINING(THR_Print(" Bailout: type feedback cleared\n")); 675 TRACE_INLINING(THR_Print(" Bailout: type feedback cleared\n"));
691 PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function, 676 PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function,
692 call_data->call); 677 call_data->call);
693 return false; 678 return false;
694 } 679 }
695 680
696 // Abort if this function has deoptimized too much. 681 // Abort if this function has deoptimized too much.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 callee_graph = builder.BuildGraph(); 783 callee_graph = builder.BuildGraph();
799 } 784 }
800 } else { 785 } else {
801 FlowGraphBuilder builder(*parsed_function, *ic_data_array, 786 FlowGraphBuilder builder(*parsed_function, *ic_data_array,
802 exit_collector, Compiler::kNoOSRDeoptId); 787 exit_collector, Compiler::kNoOSRDeoptId);
803 builder.SetInitialBlockId(caller_graph_->max_block_id()); 788 builder.SetInitialBlockId(caller_graph_->max_block_id());
804 { 789 {
805 CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer); 790 CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
806 callee_graph = builder.BuildGraph(); 791 callee_graph = builder.BuildGraph();
807 } 792 }
808 #ifdef DART_PRECOMPILER
809 Precompiler::PopulateWithICData(parsed_function->function(),
810 callee_graph);
811 if (inliner_->precompiler_ != NULL) {
812 inliner_->precompiler_->TryApplyFeedback(
813 parsed_function->function(), callee_graph);
814 }
815 #endif
816 } 793 }
817 794
818 // The parameter stubs are a copy of the actual arguments providing 795 // The parameter stubs are a copy of the actual arguments providing
819 // concrete information about the values, for example constant values, 796 // concrete information about the values, for example constant values,
820 // without linking between the caller and callee graphs. 797 // without linking between the caller and callee graphs.
821 // TODO(zerny): Put more information in the stubs, eg, type information. 798 // TODO(zerny): Put more information in the stubs, eg, type information.
822 ZoneGrowableArray<Definition*>* param_stubs = 799 ZoneGrowableArray<Definition*>* param_stubs =
823 new (Z) ZoneGrowableArray<Definition*>(function.NumParameters()); 800 new (Z) ZoneGrowableArray<Definition*>(function.NumParameters());
824 801
825 // Create a parameter stub for each fixed positional parameter. 802 // Create a parameter stub for each fixed positional parameter.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
873 850
874 { 851 {
875 CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer); 852 CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer);
876 // TODO(fschneider): Improve suppression of speculative inlining. 853 // TODO(fschneider): Improve suppression of speculative inlining.
877 // Deopt-ids overlap between caller and callee. 854 // Deopt-ids overlap between caller and callee.
878 if (FLAG_precompiled_mode) { 855 if (FLAG_precompiled_mode) {
879 #ifdef DART_PRECOMPILER 856 #ifdef DART_PRECOMPILER
880 AotOptimizer optimizer(inliner_->precompiler_, callee_graph, 857 AotOptimizer optimizer(inliner_->precompiler_, callee_graph,
881 inliner_->use_speculative_inlining_, 858 inliner_->use_speculative_inlining_,
882 inliner_->inlining_black_list_); 859 inliner_->inlining_black_list_);
860 optimizer.PopulateWithICData();
883 861
884 optimizer.ApplyClassIds(); 862 optimizer.ApplyClassIds();
885 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 863 DEBUG_ASSERT(callee_graph->VerifyUseLists());
886 864
887 FlowGraphTypePropagator::Propagate(callee_graph); 865 FlowGraphTypePropagator::Propagate(callee_graph);
888 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 866 DEBUG_ASSERT(callee_graph->VerifyUseLists());
889 867
890 optimizer.ApplyICData(); 868 optimizer.ApplyICData();
891 DEBUG_ASSERT(callee_graph->VerifyUseLists()); 869 DEBUG_ASSERT(callee_graph->VerifyUseLists());
892 870
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 } 1368 }
1391 1369
1392 FlowGraphInliner* inliner_; 1370 FlowGraphInliner* inliner_;
1393 FlowGraph* caller_graph_; 1371 FlowGraph* caller_graph_;
1394 bool inlined_; 1372 bool inlined_;
1395 const intptr_t initial_size_; 1373 const intptr_t initial_size_;
1396 intptr_t inlined_size_; 1374 intptr_t inlined_size_;
1397 bool inlined_recursive_call_; 1375 bool inlined_recursive_call_;
1398 intptr_t inlining_depth_; 1376 intptr_t inlining_depth_;
1399 intptr_t inlining_recursion_depth_; 1377 intptr_t inlining_recursion_depth_;
1400 intptr_t inlining_depth_threshold_;
1401 CallSites* collected_call_sites_; 1378 CallSites* collected_call_sites_;
1402 CallSites* inlining_call_sites_; 1379 CallSites* inlining_call_sites_;
1403 GrowableArray<ParsedFunction*> function_cache_; 1380 GrowableArray<ParsedFunction*> function_cache_;
1404 GrowableArray<InlinedInfo> inlined_info_; 1381 GrowableArray<InlinedInfo> inlined_info_;
1405 1382
1406 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner); 1383 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner);
1407 }; 1384 };
1408 1385
1409 1386
1410 PolymorphicInliner::PolymorphicInliner(CallSiteInliner* owner, 1387 PolymorphicInliner::PolymorphicInliner(CallSiteInliner* owner,
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
1945 TRACE_INLINING( 1922 TRACE_INLINING(
1946 THR_Print("AlwaysInline annotation for %s\n", function.ToCString())); 1923 THR_Print("AlwaysInline annotation for %s\n", function.ToCString()));
1947 return true; 1924 return true;
1948 } 1925 }
1949 1926
1950 if (function.IsDispatcherOrImplicitAccessor()) { 1927 if (function.IsDispatcherOrImplicitAccessor()) {
1951 // Smaller or same size as the call. 1928 // Smaller or same size as the call.
1952 return true; 1929 return true;
1953 } 1930 }
1954 1931
1955 if (function.is_const()) {
1956 // Inlined const fields are smaller than a call.
1957 return true;
1958 }
1959
1960 if (function.IsGetterFunction() || function.IsSetterFunction() || 1932 if (function.IsGetterFunction() || function.IsSetterFunction() ||
1961 IsInlineableOperator(function) || 1933 IsInlineableOperator(function) ||
1962 (function.kind() == RawFunction::kConstructor)) { 1934 (function.kind() == RawFunction::kConstructor)) {
1963 const intptr_t count = function.optimized_instruction_count(); 1935 const intptr_t count = function.optimized_instruction_count();
1964 if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) { 1936 if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) {
1965 return true; 1937 return true;
1966 } 1938 }
1967 } 1939 }
1968 return MethodRecognizer::AlwaysInline(function); 1940 return MethodRecognizer::AlwaysInline(function);
1969 } 1941 }
(...skipping 13 matching lines...) Expand all
1983 TRACE_INLINING(THR_Print("Inlining calls in %s\n", top.ToCString())); 1955 TRACE_INLINING(THR_Print("Inlining calls in %s\n", top.ToCString()));
1984 1956
1985 if (FLAG_support_il_printer && trace_inlining() && 1957 if (FLAG_support_il_printer && trace_inlining() &&
1986 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { 1958 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
1987 THR_Print("Before Inlining of %s\n", 1959 THR_Print("Before Inlining of %s\n",
1988 flow_graph_->function().ToFullyQualifiedCString()); 1960 flow_graph_->function().ToFullyQualifiedCString());
1989 FlowGraphPrinter printer(*flow_graph_); 1961 FlowGraphPrinter printer(*flow_graph_);
1990 printer.PrintBlocks(); 1962 printer.PrintBlocks();
1991 } 1963 }
1992 1964
1993 intptr_t inlining_depth_threshold = FLAG_inlining_depth_threshold; 1965 CallSiteInliner inliner(this);
1994 if ((precompiler_ != NULL) && precompiler_->HasFeedback() &&
1995 (top.usage_counter() <= 0)) {
1996 inlining_depth_threshold = 1;
1997 }
1998
1999 CallSiteInliner inliner(this, inlining_depth_threshold);
2000 inliner.InlineCalls(); 1966 inliner.InlineCalls();
2001 if (FLAG_print_inlining_tree) { 1967 if (FLAG_print_inlining_tree) {
2002 inliner.PrintInlinedInfo(top); 1968 inliner.PrintInlinedInfo(top);
2003 } 1969 }
2004 1970
2005 if (inliner.inlined()) { 1971 if (inliner.inlined()) {
2006 flow_graph_->DiscoverBlocks(); 1972 flow_graph_->DiscoverBlocks();
2007 if (trace_inlining()) { 1973 if (trace_inlining()) {
2008 THR_Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); 1974 THR_Print("Inlining growth factor: %f\n", inliner.GrowthFactor());
2009 if (FLAG_support_il_printer && 1975 if (FLAG_support_il_printer &&
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after
3631 } 3597 }
3632 3598
3633 default: 3599 default:
3634 return false; 3600 return false;
3635 } 3601 }
3636 } 3602 }
3637 3603
3638 3604
3639 } // namespace dart 3605 } // namespace dart
3640 #endif // !defined(DART_PRECOMPILED_RUNTIME) 3606 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler.cc ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698