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

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

Issue 23584002: Replace guarded list length field loads with constants (Closed) Base URL: https://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/intermediate_language.h » ('j') | runtime/vm/intermediate_language.h » ('J')
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 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 bool emit_bounds_check = true;
774 // Get the field for the array. 773 // Get the field for the array.
775 const Field* field = NULL; 774 const Field* field = NULL;
776 if ((*array)->IsLoadField()) { 775 if ((*array)->IsLoadField()) {
777 LoadFieldInstr* load_field_instr = (*array)->AsLoadField(); 776 LoadFieldInstr* load_field_instr = (*array)->AsLoadField();
778 field = load_field_instr->field(); 777 field = load_field_instr->field();
779 } 778 }
780 // Extract the guarded array length.
781 intptr_t guarded_array_length = -1;
782 if (field != NULL) {
783 if (field->guarded_list_length() >= 0) {
784 guarded_array_length = field->guarded_list_length();
785 }
786 }
787 Definition* i = *index;
788 // Check if we can skip emitting the bounds check.
789 if (i->IsConstant() && guarded_array_length >= 0) {
790 ConstantInstr* constant = i->AsConstant();
791 ASSERT(constant != NULL);
792 intptr_t ci = Smi::Cast(constant->value()).Value();
793 if (ci < guarded_array_length) {
794 emit_bounds_check = false;
795 }
796 }
797 779
798 if (emit_bounds_check) { 780 // Insert array length load and bounds check.
799 // Insert array length load and bounds check. 781 const bool is_immutable =
800 const bool is_immutable = 782 CheckArrayBoundInstr::IsFixedLengthArrayType(class_id);
801 CheckArrayBoundInstr::IsFixedLengthArrayType(class_id); 783 LoadFieldInstr* length =
Florian Schneider 2013/08/27 12:51:34 If the field has a guarded_list_length: could you
802 LoadFieldInstr* length = 784 new LoadFieldInstr(new Value(*array),
803 new LoadFieldInstr(new Value(*array), 785 CheckArrayBoundInstr::LengthOffsetFor(class_id),
804 CheckArrayBoundInstr::LengthOffsetFor(class_id), 786 Type::ZoneHandle(Type::SmiType()),
805 Type::ZoneHandle(Type::SmiType()), 787 is_immutable);
806 is_immutable); 788 length->set_result_cid(kSmiCid);
807 length->set_result_cid(kSmiCid); 789 length->set_recognized_kind(
808 length->set_recognized_kind( 790 LoadFieldInstr::RecognizedKindFromArrayCid(class_id));
809 LoadFieldInstr::RecognizedKindFromArrayCid(class_id)); 791 InsertBefore(call, length, NULL, Definition::kValue);
810 InsertBefore(call, length, NULL, Definition::kValue); 792 InsertBefore(call,
811 InsertBefore(call, 793 new CheckArrayBoundInstr(field,
812 new CheckArrayBoundInstr(new Value(length), 794 new Value(length),
813 new Value(*index), 795 new Value(*index),
814 call->deopt_id()), 796 call->deopt_id()),
815 call->env(), 797 call->env(),
816 Definition::kEffect); 798 Definition::kEffect);
817 }
818 799
819 800
820 if (class_id == kGrowableObjectArrayCid) { 801 if (class_id == kGrowableObjectArrayCid) {
821 // Insert data elements load. 802 // Insert data elements load.
822 LoadFieldInstr* elements = 803 LoadFieldInstr* elements =
823 new LoadFieldInstr(new Value(*array), 804 new LoadFieldInstr(new Value(*array),
824 GrowableObjectArray::data_offset(), 805 GrowableObjectArray::data_offset(),
825 Type::ZoneHandle(Type::DynamicType())); 806 Type::ZoneHandle(Type::DynamicType()));
826 elements->set_result_cid(kArrayCid); 807 elements->set_result_cid(kArrayCid);
827 InsertBefore(call, elements, NULL, Definition::kValue); 808 InsertBefore(call, elements, NULL, Definition::kValue);
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after
1709 String::Cast(str->AsConstant()->value()); 1690 String::Cast(str->AsConstant()->value());
1710 const Object& constant_index = index->AsConstant()->value(); 1691 const Object& constant_index = index->AsConstant()->value();
1711 skip_check = constant_index.IsSmi() && 1692 skip_check = constant_index.IsSmi() &&
1712 (Smi::Cast(constant_index).Value() < constant_string.Length()); 1693 (Smi::Cast(constant_index).Value() < constant_string.Length());
1713 } 1694 }
1714 if (!skip_check) { 1695 if (!skip_check) {
1715 // Insert bounds check. 1696 // Insert bounds check.
1716 LoadFieldInstr* length = BuildLoadStringLength(str); 1697 LoadFieldInstr* length = BuildLoadStringLength(str);
1717 InsertBefore(call, length, NULL, Definition::kValue); 1698 InsertBefore(call, length, NULL, Definition::kValue);
1718 InsertBefore(call, 1699 InsertBefore(call,
1719 new CheckArrayBoundInstr(new Value(length), 1700 new CheckArrayBoundInstr(NULL,
1701 new Value(length),
1720 new Value(index), 1702 new Value(index),
1721 call->deopt_id()), 1703 call->deopt_id()),
1722 call->env(), 1704 call->env(),
1723 Definition::kEffect); 1705 Definition::kEffect);
1724 } 1706 }
1725 return new LoadIndexedInstr(new Value(str), 1707 return new LoadIndexedInstr(new Value(str),
1726 new Value(index), 1708 new Value(index),
1727 FlowGraphCompiler::ElementSizeFor(cid), 1709 FlowGraphCompiler::ElementSizeFor(cid),
1728 cid, 1710 cid,
1729 Isolate::kNoDeoptId); // Can't deoptimize. 1711 Isolate::kNoDeoptId); // Can't deoptimize.
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size))); 2464 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size)));
2483 BinarySmiOpInstr* len_in_bytes = 2465 BinarySmiOpInstr* len_in_bytes =
2484 new BinarySmiOpInstr(Token::kMUL, 2466 new BinarySmiOpInstr(Token::kMUL,
2485 new Value(length), 2467 new Value(length),
2486 new Value(bytes_per_element), 2468 new Value(bytes_per_element),
2487 call->deopt_id()); 2469 call->deopt_id());
2488 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue); 2470 InsertBefore(call, len_in_bytes, call->env(), Definition::kValue);
2489 2471
2490 // Check byte_index < len_in_bytes. 2472 // Check byte_index < len_in_bytes.
2491 InsertBefore(call, 2473 InsertBefore(call,
2492 new CheckArrayBoundInstr(new Value(len_in_bytes), 2474 new CheckArrayBoundInstr(NULL,
2475 new Value(len_in_bytes),
2493 new Value(byte_index), 2476 new Value(byte_index),
2494 call->deopt_id()), 2477 call->deopt_id()),
2495 call->env(), 2478 call->env(),
2496 Definition::kEffect); 2479 Definition::kEffect);
2497 2480
2498 // Insert load of elements for external typed arrays. 2481 // Insert load of elements for external typed arrays.
2499 if (RawObject::IsExternalTypedDataClassId(receiver_cid)) { 2482 if (RawObject::IsExternalTypedDataClassId(receiver_cid)) {
2500 LoadUntaggedInstr* elements = 2483 LoadUntaggedInstr* elements =
2501 new LoadUntaggedInstr(new Value(*array), 2484 new LoadUntaggedInstr(new Value(*array),
2502 ExternalTypedData::data_offset()); 2485 ExternalTypedData::data_offset());
(...skipping 5040 matching lines...) Expand 10 before | Expand all | Expand 10 after
7543 } 7526 }
7544 7527
7545 // Insert materializations at environment uses. 7528 // Insert materializations at environment uses.
7546 for (intptr_t i = 0; i < exits.length(); i++) { 7529 for (intptr_t i = 0; i < exits.length(); i++) {
7547 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7530 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7548 } 7531 }
7549 } 7532 }
7550 7533
7551 7534
7552 } // namespace dart 7535 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.h » ('j') | runtime/vm/intermediate_language.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698