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

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

Issue 23003026: Avoid array bounds check when allowed by guarded field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 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
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 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
763 Definition** array, 763 Definition** array,
764 Definition** index) { 764 Definition** index) {
765 // Insert class check and index smi checks and attach a copy of the 765 // Insert class check and index smi checks and attach a copy of the
766 // original environment because the operation can still deoptimize. 766 // original environment because the operation can still deoptimize.
767 AddReceiverCheck(call); 767 AddReceiverCheck(call);
768 InsertBefore(call, 768 InsertBefore(call,
769 new CheckSmiInstr(new Value(*index), call->deopt_id()), 769 new CheckSmiInstr(new Value(*index), call->deopt_id()),
770 call->env(), 770 call->env(),
771 Definition::kEffect); 771 Definition::kEffect);
772 772
773 // Get the field if the array is loaded from a class field.
774 const Field* field = NULL;
775 if ((*array)->IsLoadField()) {
776 LoadFieldInstr* load_field_instr = (*array)->AsLoadField();
777 field = load_field_instr->field();
778 }
779
773 // Insert array length load and bounds check. 780 // Insert array length load and bounds check.
774 const bool is_immutable = 781 const bool is_immutable =
775 CheckArrayBoundInstr::IsFixedLengthArrayType(class_id); 782 CheckArrayBoundInstr::IsFixedLengthArrayType(class_id);
776 LoadFieldInstr* length = 783 LoadFieldInstr* length =
777 new LoadFieldInstr(new Value(*array), 784 new LoadFieldInstr(new Value(*array),
778 CheckArrayBoundInstr::LengthOffsetFor(class_id), 785 CheckArrayBoundInstr::LengthOffsetFor(class_id),
779 Type::ZoneHandle(Type::SmiType()), 786 Type::ZoneHandle(Type::SmiType()),
780 is_immutable); 787 is_immutable);
781 length->set_result_cid(kSmiCid); 788 length->set_result_cid(kSmiCid);
782 length->set_recognized_kind( 789 length->set_recognized_kind(
783 LoadFieldInstr::RecognizedKindFromArrayCid(class_id)); 790 LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
784 InsertBefore(call, length, NULL, Definition::kValue); 791 InsertBefore(call, length, NULL, Definition::kValue);
785 InsertBefore(call, 792 InsertBefore(call,
786 new CheckArrayBoundInstr(new Value(length), 793 new CheckArrayBoundInstr(field,
794 new Value(length),
787 new Value(*index), 795 new Value(*index),
788 call->deopt_id()), 796 call->deopt_id()),
789 call->env(), 797 call->env(),
790 Definition::kEffect); 798 Definition::kEffect);
791 799
792 if (class_id == kGrowableObjectArrayCid) { 800 if (class_id == kGrowableObjectArrayCid) {
793 // Insert data elements load. 801 // Insert data elements load.
794 LoadFieldInstr* elements = 802 LoadFieldInstr* elements =
795 new LoadFieldInstr(new Value(*array), 803 new LoadFieldInstr(new Value(*array),
796 GrowableObjectArray::data_offset(), 804 GrowableObjectArray::data_offset(),
(...skipping 884 matching lines...) Expand 10 before | Expand all | Expand 10 after
1681 String::Cast(str->AsConstant()->value()); 1689 String::Cast(str->AsConstant()->value());
1682 const Object& constant_index = index->AsConstant()->value(); 1690 const Object& constant_index = index->AsConstant()->value();
1683 skip_check = constant_index.IsSmi() && 1691 skip_check = constant_index.IsSmi() &&
1684 (Smi::Cast(constant_index).Value() < constant_string.Length()); 1692 (Smi::Cast(constant_index).Value() < constant_string.Length());
1685 } 1693 }
1686 if (!skip_check) { 1694 if (!skip_check) {
1687 // Insert bounds check. 1695 // Insert bounds check.
1688 LoadFieldInstr* length = BuildLoadStringLength(str); 1696 LoadFieldInstr* length = BuildLoadStringLength(str);
1689 InsertBefore(call, length, NULL, Definition::kValue); 1697 InsertBefore(call, length, NULL, Definition::kValue);
1690 InsertBefore(call, 1698 InsertBefore(call,
1691 new CheckArrayBoundInstr(new Value(length), 1699 new CheckArrayBoundInstr(NULL,
1700 new Value(length),
1692 new Value(index), 1701 new Value(index),
1693 call->deopt_id()), 1702 call->deopt_id()),
1694 call->env(), 1703 call->env(),
1695 Definition::kEffect); 1704 Definition::kEffect);
1696 } 1705 }
1697 return new LoadIndexedInstr(new Value(str), 1706 return new LoadIndexedInstr(new Value(str),
1698 new Value(index), 1707 new Value(index),
1699 FlowGraphCompiler::ElementSizeFor(cid), 1708 FlowGraphCompiler::ElementSizeFor(cid),
1700 cid, 1709 cid,
1701 Isolate::kNoDeoptId); // Can't deoptimize. 1710 Isolate::kNoDeoptId); // Can't deoptimize.
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
2454 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size))); 2463 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size)));
2455 BinarySmiOpInstr* len_in_bytes = 2464 BinarySmiOpInstr* len_in_bytes =
2456 new BinarySmiOpInstr(Token::kMUL, 2465 new BinarySmiOpInstr(Token::kMUL,
2457 new Value(length), 2466 new Value(length),
2458 new Value(bytes_per_element), 2467 new Value(bytes_per_element),
2459 call->deopt_id()); 2468 call->deopt_id());
2460 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue); 2469 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue);
2461 2470
2462 // Check byte_index < len_in_bytes. 2471 // Check byte_index < len_in_bytes.
2463 InsertBefore(call, 2472 InsertBefore(call,
2464 new CheckArrayBoundInstr(new Value(len_in_bytes), 2473 new CheckArrayBoundInstr(NULL,
2474 new Value(len_in_bytes),
2465 new Value(byte_index), 2475 new Value(byte_index),
2466 call->deopt_id()), 2476 call->deopt_id()),
2467 call->env(), 2477 call->env(),
2468 Definition::kEffect); 2478 Definition::kEffect);
2469 2479
2470 // Insert load of elements for external typed arrays. 2480 // Insert load of elements for external typed arrays.
2471 if (RawObject::IsExternalTypedDataClassId(receiver_cid)) { 2481 if (RawObject::IsExternalTypedDataClassId(receiver_cid)) {
2472 LoadUntaggedInstr* elements = 2482 LoadUntaggedInstr* elements =
2473 new LoadUntaggedInstr(new Value(*array), 2483 new LoadUntaggedInstr(new Value(*array),
2474 ExternalTypedData::data_offset()); 2484 ExternalTypedData::data_offset());
(...skipping 5032 matching lines...) Expand 10 before | Expand all | Expand 10 after
7507 } 7517 }
7508 7518
7509 // Insert materializations at environment uses. 7519 // Insert materializations at environment uses.
7510 for (intptr_t i = 0; i < exits.length(); i++) { 7520 for (intptr_t i = 0; i < exits.length(); i++) {
7511 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7521 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7512 } 7522 }
7513 } 7523 }
7514 7524
7515 7525
7516 } // namespace dart 7526 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.h » ('j') | runtime/vm/intermediate_language_arm.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698