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

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

Issue 876603003: VM: Refactor more intrinsics of GrowableList to use IR builder. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 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/intrinsifier_arm.cc » ('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 // Class for intrinsifying functions. 4 // Class for intrinsifying functions.
5 5
6 #include "vm/assembler.h" 6 #include "vm/assembler.h"
7 #include "vm/intrinsifier.h" 7 #include "vm/intrinsifier.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/object.h" 9 #include "vm/object.h"
10 #include "vm/symbols.h" 10 #include "vm/symbols.h"
11 11
12 #include "vm/flow_graph.h" 12 #include "vm/flow_graph.h"
13 #include "vm/flow_graph_compiler.h" 13 #include "vm/flow_graph_compiler.h"
14 #include "vm/flow_graph_allocator.h" 14 #include "vm/flow_graph_allocator.h"
15 #include "vm/flow_graph_builder.h" 15 #include "vm/flow_graph_builder.h"
16 #include "vm/il_printer.h" 16 #include "vm/il_printer.h"
17 #include "vm/intermediate_language.h" 17 #include "vm/intermediate_language.h"
18 #include "vm/parser.h" 18 #include "vm/parser.h"
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DEFINE_FLAG(bool, intrinsify, true, "Instrinsify when possible"); 22 DEFINE_FLAG(bool, intrinsify, true, "Instrinsify when possible");
23 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); 23 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
24 DECLARE_FLAG(bool, code_comments); 24 DECLARE_FLAG(bool, code_comments);
25 DECLARE_FLAG(bool, print_flow_graph); 25 DECLARE_FLAG(bool, print_flow_graph);
26 DECLARE_FLAG(bool, print_flow_graph_optimized); 26 DECLARE_FLAG(bool, print_flow_graph_optimized);
27 DECLARE_FLAG(bool, enable_type_checks);
27 28
28 bool Intrinsifier::CanIntrinsify(const Function& function) { 29 bool Intrinsifier::CanIntrinsify(const Function& function) {
29 if (!FLAG_intrinsify) return false; 30 if (!FLAG_intrinsify) return false;
30 if (function.IsClosureFunction()) return false; 31 if (function.IsClosureFunction()) return false;
31 // Can occur because of compile-all flag. 32 // Can occur because of compile-all flag.
32 if (function.is_external()) return false; 33 if (function.is_external()) return false;
33 return function.is_intrinsic(); 34 return function.is_intrinsic();
34 } 35 }
35 36
36 37
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 // overflow. 199 // overflow.
199 switch (function.recognized_kind()) { 200 switch (function.recognized_kind()) {
200 ALL_INTRINSICS_NO_INTEGER_LIB_LIST(EMIT_CASE); 201 ALL_INTRINSICS_NO_INTEGER_LIB_LIST(EMIT_CASE);
201 default: 202 default:
202 break; 203 break;
203 } 204 }
204 } else { 205 } else {
205 switch (function.recognized_kind()) { 206 switch (function.recognized_kind()) {
206 ALL_INTRINSICS_LIST(EMIT_CASE); 207 ALL_INTRINSICS_LIST(EMIT_CASE);
207 default: 208 default:
208 UNREACHABLE();
209 break; 209 break;
210 } 210 }
211 } 211 }
212 #undef EMIT_INTRINSIC 212 #undef EMIT_INTRINSIC
213 } 213 }
214 214
215 215
216 class BlockBuilder : public ValueObject { 216 class BlockBuilder : public ValueObject {
217 public: 217 public:
218 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry) 218 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry)
(...skipping 27 matching lines...) Expand all
246 return AddToInitialDefinitions( 246 return AddToInitialDefinitions(
247 new ParameterInstr(adjustment + index, 247 new ParameterInstr(adjustment + index,
248 flow_graph_->graph_entry(), 248 flow_graph_->graph_entry(),
249 SPREG)); 249 SPREG));
250 } 250 }
251 251
252 intptr_t TokenPos() { 252 intptr_t TokenPos() {
253 return flow_graph_->parsed_function()->function().token_pos(); 253 return flow_graph_->parsed_function()->function().token_pos();
254 } 254 }
255 255
256 Definition* AddNullDefinition() {
257 return AddDefinition(
258 new ConstantInstr(Object::ZoneHandle(Object::null())));
259 }
260
256 private: 261 private:
257 FlowGraph* flow_graph_; 262 FlowGraph* flow_graph_;
258 BlockEntryInstr* entry_; 263 BlockEntryInstr* entry_;
259 Instruction* current_; 264 Instruction* current_;
260 }; 265 };
261 266
262 267
263 static void PrepareIndexedOp(BlockBuilder* builder, 268 static void PrepareIndexedOp(BlockBuilder* builder,
264 Definition* array, 269 Definition* array,
265 Definition* index, 270 Definition* index,
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 builder.AddInstruction( 380 builder.AddInstruction(
376 new StoreIndexedInstr(new Value(array), 381 new StoreIndexedInstr(new Value(array),
377 new Value(index), 382 new Value(index),
378 new Value(value), 383 new Value(value),
379 kNoStoreBarrier, 384 kNoStoreBarrier,
380 1, // index scale 385 1, // index scale
381 kTypedDataUint8ArrayCid, 386 kTypedDataUint8ArrayCid,
382 Isolate::kNoDeoptId, 387 Isolate::kNoDeoptId,
383 builder.TokenPos())); 388 builder.TokenPos()));
384 // Return null. 389 // Return null.
385 Definition* null_def = builder.AddDefinition( 390 Definition* null_def = builder.AddNullDefinition();
386 new ConstantInstr(Object::ZoneHandle(Object::null())));
387 builder.AddIntrinsicReturn(new Value(null_def)); 391 builder.AddIntrinsicReturn(new Value(null_def));
388 return true; 392 return true;
389 } 393 }
390 394
391 395
392 bool Intrinsifier::Build_ExternalUint8ArraySetIndexed(FlowGraph* flow_graph) { 396 bool Intrinsifier::Build_ExternalUint8ArraySetIndexed(FlowGraph* flow_graph) {
393 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); 397 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
394 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); 398 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
395 BlockBuilder builder(flow_graph, normal_entry); 399 BlockBuilder builder(flow_graph, normal_entry);
396 400
(...skipping 13 matching lines...) Expand all
410 builder.AddInstruction( 414 builder.AddInstruction(
411 new StoreIndexedInstr(new Value(elements), 415 new StoreIndexedInstr(new Value(elements),
412 new Value(index), 416 new Value(index),
413 new Value(value), 417 new Value(value),
414 kNoStoreBarrier, 418 kNoStoreBarrier,
415 1, // index scale 419 1, // index scale
416 kExternalTypedDataUint8ArrayCid, 420 kExternalTypedDataUint8ArrayCid,
417 Isolate::kNoDeoptId, 421 Isolate::kNoDeoptId,
418 builder.TokenPos())); 422 builder.TokenPos()));
419 // Return null. 423 // Return null.
420 Definition* null_def = builder.AddDefinition( 424 Definition* null_def = builder.AddNullDefinition();
421 new ConstantInstr(Object::ZoneHandle(Object::null())));
422 builder.AddIntrinsicReturn(new Value(null_def)); 425 builder.AddIntrinsicReturn(new Value(null_def));
423 return true; 426 return true;
424 } 427 }
425 428
426 429
427 bool Intrinsifier::Build_Float64ArraySetIndexed(FlowGraph* flow_graph) { 430 bool Intrinsifier::Build_Float64ArraySetIndexed(FlowGraph* flow_graph) {
428 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false; 431 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
429 432
430 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); 433 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
431 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); 434 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
(...skipping 30 matching lines...) Expand all
462 builder.AddInstruction( 465 builder.AddInstruction(
463 new StoreIndexedInstr(new Value(array), 466 new StoreIndexedInstr(new Value(array),
464 new Value(index), 467 new Value(index),
465 new Value(double_value), 468 new Value(double_value),
466 kNoStoreBarrier, 469 kNoStoreBarrier,
467 8, // index scale 470 8, // index scale
468 kTypedDataFloat64ArrayCid, 471 kTypedDataFloat64ArrayCid,
469 Isolate::kNoDeoptId, 472 Isolate::kNoDeoptId,
470 builder.TokenPos())); 473 builder.TokenPos()));
471 // Return null. 474 // Return null.
472 Definition* null_def = builder.AddDefinition( 475 Definition* null_def = builder.AddNullDefinition();
473 new ConstantInstr(Object::ZoneHandle(Object::null())));
474 builder.AddIntrinsicReturn(new Value(null_def)); 476 builder.AddIntrinsicReturn(new Value(null_def));
475 return true; 477 return true;
476 } 478 }
477 479
478 480
479 bool Intrinsifier::Build_Float64ArrayGetIndexed(FlowGraph* flow_graph) { 481 bool Intrinsifier::Build_Float64ArrayGetIndexed(FlowGraph* flow_graph) {
480 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false; 482 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false;
481 483
482 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); 484 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
483 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); 485 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 Definition* capacity = builder.AddDefinition( 561 Definition* capacity = builder.AddDefinition(
560 new LoadFieldInstr(new Value(backing_store), 562 new LoadFieldInstr(new Value(backing_store),
561 Array::length_offset(), 563 Array::length_offset(),
562 Type::ZoneHandle(), 564 Type::ZoneHandle(),
563 builder.TokenPos())); 565 builder.TokenPos()));
564 builder.AddIntrinsicReturn(new Value(capacity)); 566 builder.AddIntrinsicReturn(new Value(capacity));
565 return true; 567 return true;
566 } 568 }
567 569
568 570
571 bool Intrinsifier::Build_GrowableArrayGetIndexed(FlowGraph* flow_graph) {
572 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
573 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
574 BlockBuilder builder(flow_graph, normal_entry);
575
576 Definition* index = builder.AddParameter(1);
577 Definition* growable_array = builder.AddParameter(2);
578
579 PrepareIndexedOp(
580 &builder, growable_array, index, GrowableObjectArray::length_offset());
581
582 Definition* backing_store = builder.AddDefinition(
583 new LoadFieldInstr(new Value(growable_array),
584 GrowableObjectArray::data_offset(),
585 Type::ZoneHandle(),
586 builder.TokenPos()));
587 Definition* result = builder.AddDefinition(
588 new LoadIndexedInstr(new Value(backing_store),
589 new Value(index),
590 Instance::ElementSizeFor(kArrayCid), // index scale
591 kArrayCid,
592 Isolate::kNoDeoptId,
593 builder.TokenPos()));
594 builder.AddIntrinsicReturn(new Value(result));
595 return true;
596 }
597
598
599 bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) {
600 if (FLAG_enable_type_checks) return false;
601
602 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
603 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
604 BlockBuilder builder(flow_graph, normal_entry);
605
606 Definition* value = builder.AddParameter(1);
607 Definition* index = builder.AddParameter(2);
608 Definition* array = builder.AddParameter(3);
609
610 PrepareIndexedOp(
611 &builder, array, index, GrowableObjectArray::length_offset());
612
613 Definition* backing_store = builder.AddDefinition(
614 new LoadFieldInstr(new Value(array),
615 GrowableObjectArray::data_offset(),
616 Type::ZoneHandle(),
617 builder.TokenPos()));
618
619 builder.AddInstruction(
620 new StoreIndexedInstr(new Value(backing_store),
621 new Value(index),
622 new Value(value),
623 kEmitStoreBarrier,
624 Instance::ElementSizeFor(kArrayCid), // index scale
625 kArrayCid,
626 Isolate::kNoDeoptId,
627 builder.TokenPos()));
628 // Return null.
629 Definition* null_def = builder.AddNullDefinition();
630 builder.AddIntrinsicReturn(new Value(null_def));
631 return true;
632 }
633
634
635 bool Intrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) {
636 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
637 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
638 BlockBuilder builder(flow_graph, normal_entry);
639
640 Definition* data = builder.AddParameter(1);
641 Definition* growable_array = builder.AddParameter(2);
642
643 const ICData& value_check = ICData::ZoneHandle(ICData::New(
644 flow_graph->parsed_function()->function(),
645 String::Handle(flow_graph->parsed_function()->function().name()),
646 Object::empty_array(), // Dummy args. descr.
647 Isolate::kNoDeoptId,
648 1));
649 value_check.AddReceiverCheck(kArrayCid,
650 flow_graph->parsed_function()->function());
651 builder.AddInstruction(
652 new CheckClassInstr(new Value(data),
653 Isolate::kNoDeoptId,
654 value_check,
655 builder.TokenPos()));
656
657 builder.AddInstruction(
658 new StoreInstanceFieldInstr(GrowableObjectArray::data_offset(),
659 new Value(growable_array),
660 new Value(data),
661 kEmitStoreBarrier,
662 builder.TokenPos()));
663 // Return null.
664 Definition* null_def = builder.AddNullDefinition();
665 builder.AddIntrinsicReturn(new Value(null_def));
666 return true;
667 }
668
669
670 bool Intrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) {
671 GraphEntryInstr* graph_entry = flow_graph->graph_entry();
672 TargetEntryInstr* normal_entry = graph_entry->normal_entry();
673 BlockBuilder builder(flow_graph, normal_entry);
674
675 Definition* length = builder.AddParameter(1);
676 Definition* growable_array = builder.AddParameter(2);
677
678 builder.AddInstruction(
679 new CheckSmiInstr(new Value(length),
680 Isolate::kNoDeoptId,
681 builder.TokenPos()));
682 builder.AddInstruction(
683 new StoreInstanceFieldInstr(GrowableObjectArray::length_offset(),
684 new Value(growable_array),
685 new Value(length),
686 kNoStoreBarrier,
687 builder.TokenPos()));
688 Definition* null_def = builder.AddNullDefinition();
689 builder.AddIntrinsicReturn(new Value(null_def));
690 return true;
691 }
692
569 } // namespace dart 693 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intrinsifier_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698