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

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

Issue 24315002: Reland: Fix bug in field type tracking and polymorphic inlining. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/flow_graph.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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 bool done = false; 263 bool done = false;
264 // volatile because the variable may be clobbered by a longjmp. 264 // volatile because the variable may be clobbered by a longjmp.
265 volatile bool use_far_branches = false; 265 volatile bool use_far_branches = false;
266 while (!done) { 266 while (!done) {
267 const intptr_t prev_deopt_id = isolate->deopt_id(); 267 const intptr_t prev_deopt_id = isolate->deopt_id();
268 isolate->set_deopt_id(0); 268 isolate->set_deopt_id(0);
269 LongJump* old_base = isolate->long_jump_base(); 269 LongJump* old_base = isolate->long_jump_base();
270 LongJump bailout_jump; 270 LongJump bailout_jump;
271 isolate->set_long_jump_base(&bailout_jump); 271 isolate->set_long_jump_base(&bailout_jump);
272 if (setjmp(*bailout_jump.Set()) == 0) { 272 if (setjmp(*bailout_jump.Set()) == 0) {
273 FlowGraphBuilder* builder = NULL;
273 FlowGraph* flow_graph = NULL; 274 FlowGraph* flow_graph = NULL;
275 GrowableArray<const Field*> guarded_fields;
274 // TimerScope needs an isolate to be properly terminated in case of a 276 // TimerScope needs an isolate to be properly terminated in case of a
275 // LongJump. 277 // LongJump.
276 { 278 {
277 TimerScope timer(FLAG_compiler_stats, 279 TimerScope timer(FLAG_compiler_stats,
278 &CompilerStats::graphbuilder_timer, 280 &CompilerStats::graphbuilder_timer,
279 isolate); 281 isolate);
280 Array& ic_data_array = Array::Handle(); 282 Array& ic_data_array = Array::Handle();
281 if (optimized) { 283 if (optimized) {
282 ASSERT(function.HasCode()); 284 ASSERT(function.HasCode());
283 // Extract type feedback before the graph is built, as the graph 285 // Extract type feedback before the graph is built, as the graph
284 // builder uses it to attach it to nodes. 286 // builder uses it to attach it to nodes.
285 ASSERT(function.deoptimization_counter() < 287 ASSERT(function.deoptimization_counter() <
286 FLAG_deoptimization_counter_threshold); 288 FLAG_deoptimization_counter_threshold);
287 const Code& unoptimized_code = 289 const Code& unoptimized_code =
288 Code::Handle(function.unoptimized_code()); 290 Code::Handle(function.unoptimized_code());
289 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray(); 291 ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
290 } 292 }
291 293
292 // Build the flow graph. 294 // Build the flow graph.
293 FlowGraphBuilder builder(parsed_function, 295 builder = new FlowGraphBuilder(parsed_function,
294 ic_data_array, 296 ic_data_array,
295 NULL, // NULL = not inlining. 297 NULL, // NULL = not inlining.
296 osr_id); 298 &guarded_fields,
297 flow_graph = builder.BuildGraph(); 299 osr_id);
300 flow_graph = builder->BuildGraph();
298 } 301 }
299 302
300 if (FLAG_print_flow_graph || 303 if (FLAG_print_flow_graph ||
301 (optimized && FLAG_print_flow_graph_optimized)) { 304 (optimized && FLAG_print_flow_graph_optimized)) {
302 if (osr_id == Isolate::kNoDeoptId) { 305 if (osr_id == Isolate::kNoDeoptId) {
303 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); 306 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
304 } else { 307 } else {
305 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); 308 FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
306 } 309 }
307 } 310 }
(...skipping 11 matching lines...) Expand all
319 flow_graph->ComputeSSA(0, NULL); 322 flow_graph->ComputeSSA(0, NULL);
320 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 323 DEBUG_ASSERT(flow_graph->VerifyUseLists());
321 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { 324 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
322 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); 325 FlowGraphPrinter::PrintGraph("After SSA", flow_graph);
323 } 326 }
324 } 327 }
325 328
326 // Collect all instance fields that are loaded in the graph and 329 // Collect all instance fields that are loaded in the graph and
327 // have non-generic type feedback attached to them that can 330 // have non-generic type feedback attached to them that can
328 // potentially affect optimizations. 331 // potentially affect optimizations.
329 GrowableArray<const Field*> guarded_fields(10);
330 if (optimized) { 332 if (optimized) {
331 TimerScope timer(FLAG_compiler_stats, 333 TimerScope timer(FLAG_compiler_stats,
332 &CompilerStats::graphoptimizer_timer, 334 &CompilerStats::graphoptimizer_timer,
333 isolate); 335 isolate);
334 336
335 FlowGraphOptimizer optimizer(flow_graph, &guarded_fields); 337 FlowGraphOptimizer optimizer(flow_graph);
336 optimizer.ApplyICData(); 338 optimizer.ApplyICData();
337 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 339 DEBUG_ASSERT(flow_graph->VerifyUseLists());
338 340
339 // Optimize (a << b) & c patterns. Must occur before 341 // Optimize (a << b) & c patterns. Must occur before
340 // 'SelectRepresentations' which inserts conversion nodes. 342 // 'SelectRepresentations' which inserts conversion nodes.
341 // TODO(srdjan): Moved before inlining until environment use list can 343 // TODO(srdjan): Moved before inlining until environment use list can
342 // be used to detect when shift-left is outside the scope of bit-and. 344 // be used to detect when shift-left is outside the scope of bit-and.
343 optimizer.TryOptimizeLeftShiftWithBitAndPattern(); 345 optimizer.TryOptimizeLeftShiftWithBitAndPattern();
344 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 346 DEBUG_ASSERT(flow_graph->VerifyUseLists());
345 347
346 // Inlining (mutates the flow graph) 348 // Inlining (mutates the flow graph)
347 if (FLAG_use_inlining) { 349 if (FLAG_use_inlining) {
348 TimerScope timer(FLAG_compiler_stats, 350 TimerScope timer(FLAG_compiler_stats,
349 &CompilerStats::graphinliner_timer); 351 &CompilerStats::graphinliner_timer);
350 // Propagate types to create more inlining opportunities. 352 // Propagate types to create more inlining opportunities.
351 if (FLAG_propagate_types) { 353 if (FLAG_propagate_types) {
352 FlowGraphTypePropagator propagator(flow_graph); 354 FlowGraphTypePropagator propagator(flow_graph);
353 propagator.Propagate(); 355 propagator.Propagate();
354 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 356 DEBUG_ASSERT(flow_graph->VerifyUseLists());
355 } 357 }
356 358
357 // Use propagated class-ids to create more inlining opportunities. 359 // Use propagated class-ids to create more inlining opportunities.
358 optimizer.ApplyClassIds(); 360 optimizer.ApplyClassIds();
359 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 361 DEBUG_ASSERT(flow_graph->VerifyUseLists());
360 362
361 FlowGraphInliner inliner(flow_graph, &guarded_fields); 363 FlowGraphInliner inliner(flow_graph);
362 inliner.Inline(); 364 inliner.Inline();
363 // Use lists are maintained and validated by the inliner. 365 // Use lists are maintained and validated by the inliner.
364 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 366 DEBUG_ASSERT(flow_graph->VerifyUseLists());
365 } 367 }
366 368
367 // Propagate types and eliminate more type tests. 369 // Propagate types and eliminate more type tests.
368 if (FLAG_propagate_types) { 370 if (FLAG_propagate_types) {
369 FlowGraphTypePropagator propagator(flow_graph); 371 FlowGraphTypePropagator propagator(flow_graph);
370 propagator.Propagate(); 372 propagator.Propagate();
371 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 373 DEBUG_ASSERT(flow_graph->VerifyUseLists());
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
923 Object::Handle(isolate->object_store()->sticky_error()); 925 Object::Handle(isolate->object_store()->sticky_error());
924 isolate->object_store()->clear_sticky_error(); 926 isolate->object_store()->clear_sticky_error();
925 isolate->set_long_jump_base(base); 927 isolate->set_long_jump_base(base);
926 return result.raw(); 928 return result.raw();
927 } 929 }
928 UNREACHABLE(); 930 UNREACHABLE();
929 return Object::null(); 931 return Object::null();
930 } 932 }
931 933
932 } // namespace dart 934 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698