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

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

Issue 1961393002: VM: Optimized code for all of [External]{One|Two}ByteString::codeUnitAt. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: addressed comment Created 4 years, 7 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
« no previous file with comments | « runtime/lib/string_patch.dart ('k') | runtime/vm/constant_propagator.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) 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/aot_optimizer.h" 5 #include "vm/aot_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/branch_optimizer.h" 8 #include "vm/branch_optimizer.h"
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 // from string-from-char-code instruction. 782 // from string-from-char-code instruction.
783 static bool IsLengthOneString(Definition* d) { 783 static bool IsLengthOneString(Definition* d) {
784 if (d->IsConstant()) { 784 if (d->IsConstant()) {
785 const Object& obj = d->AsConstant()->value(); 785 const Object& obj = d->AsConstant()->value();
786 if (obj.IsString()) { 786 if (obj.IsString()) {
787 return String::Cast(obj).Length() == 1; 787 return String::Cast(obj).Length() == 1;
788 } else { 788 } else {
789 return false; 789 return false;
790 } 790 }
791 } else { 791 } else {
792 return d->IsStringFromCharCode(); 792 return d->IsOneByteStringFromCharCode();
793 } 793 }
794 } 794 }
795 795
796 796
797 // Returns true if the string comparison was converted into char-code 797 // Returns true if the string comparison was converted into char-code
798 // comparison. Conversion is only possible for strings of length one. 798 // comparison. Conversion is only possible for strings of length one.
799 // E.g., detect str[x] == "x"; and use an integer comparison of char-codes. 799 // E.g., detect str[x] == "x"; and use an integer comparison of char-codes.
800 // TODO(srdjan): Expand for two-byte and external strings. 800 // TODO(srdjan): Expand for two-byte and external strings.
801 bool AotOptimizer::TryStringLengthOneEquality(InstanceCallInstr* call, 801 bool AotOptimizer::TryStringLengthOneEquality(InstanceCallInstr* call,
802 Token::Kind op_kind) { 802 Token::Kind op_kind) {
(...skipping 13 matching lines...) Expand all
816 if (IsLengthOneString(left)) { 816 if (IsLengthOneString(left)) {
817 // Optimize if left is a string with length one (either constant or 817 // Optimize if left is a string with length one (either constant or
818 // result of string-from-char-code. 818 // result of string-from-char-code.
819 if (left->IsConstant()) { 819 if (left->IsConstant()) {
820 ConstantInstr* left_const = left->AsConstant(); 820 ConstantInstr* left_const = left->AsConstant();
821 const String& str = String::Cast(left_const->value()); 821 const String& str = String::Cast(left_const->value());
822 ASSERT(str.Length() == 1); 822 ASSERT(str.Length() == 1);
823 ConstantInstr* char_code_left = flow_graph()->GetConstant( 823 ConstantInstr* char_code_left = flow_graph()->GetConstant(
824 Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0))))); 824 Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0)))));
825 left_val = new(Z) Value(char_code_left); 825 left_val = new(Z) Value(char_code_left);
826 } else if (left->IsStringFromCharCode()) { 826 } else if (left->IsOneByteStringFromCharCode()) {
827 // Use input of string-from-charcode as left value. 827 // Use input of string-from-charcode as left value.
828 StringFromCharCodeInstr* instr = left->AsStringFromCharCode(); 828 OneByteStringFromCharCodeInstr* instr =
829 left->AsOneByteStringFromCharCode();
829 left_val = new(Z) Value(instr->char_code()->definition()); 830 left_val = new(Z) Value(instr->char_code()->definition());
830 to_remove_left = instr; 831 to_remove_left = instr;
831 } else { 832 } else {
832 // IsLengthOneString(left) should have been false. 833 // IsLengthOneString(left) should have been false.
833 UNREACHABLE(); 834 UNREACHABLE();
834 } 835 }
835 836
836 Definition* to_remove_right = NULL; 837 Definition* to_remove_right = NULL;
837 Value* right_val = NULL; 838 Value* right_val = NULL;
838 if (right->IsStringFromCharCode()) { 839 if (right->IsOneByteStringFromCharCode()) {
839 // Skip string-from-char-code, and use its input as right value. 840 // Skip string-from-char-code, and use its input as right value.
840 StringFromCharCodeInstr* right_instr = right->AsStringFromCharCode(); 841 OneByteStringFromCharCodeInstr* right_instr =
842 right->AsOneByteStringFromCharCode();
841 right_val = new(Z) Value(right_instr->char_code()->definition()); 843 right_val = new(Z) Value(right_instr->char_code()->definition());
842 to_remove_right = right_instr; 844 to_remove_right = right_instr;
843 } else { 845 } else {
844 const ICData& unary_checks_1 = 846 const ICData& unary_checks_1 =
845 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)); 847 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1));
846 AddCheckClass(right, 848 AddCheckClass(right,
847 unary_checks_1, 849 unary_checks_1,
848 call->deopt_id(), 850 call->deopt_id(),
849 call->env(), 851 call->env(),
850 call); 852 call);
(...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr( 1782 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
1781 GrowableObjectArray::length_offset(), 1783 GrowableObjectArray::length_offset(),
1782 new(Z) Value(array), 1784 new(Z) Value(array),
1783 new(Z) Value(value), 1785 new(Z) Value(value),
1784 kNoStoreBarrier, 1786 kNoStoreBarrier,
1785 call->token_pos()); 1787 call->token_pos());
1786 ReplaceCall(call, store); 1788 ReplaceCall(call, store);
1787 return true; 1789 return true;
1788 } 1790 }
1789 1791
1790 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) || 1792 if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
1791 (recognized_kind == MethodRecognizer::kStringBaseCharAt)) && 1793 (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
1792 (ic_data.NumberOfChecks() == 1) && 1794 (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
1793 ((class_ids[0] == kOneByteStringCid) || 1795 (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
1794 (class_ids[0] == kTwoByteStringCid))) { 1796 ASSERT(ic_data.NumberOfChecks() == 1);
1797 ASSERT((class_ids[0] == kOneByteStringCid) ||
1798 (class_ids[0] == kTwoByteStringCid) ||
1799 (class_ids[0] == kExternalOneByteStringCid) ||
1800 (class_ids[0] == kExternalTwoByteStringCid));
1795 return TryReplaceInstanceCallWithInline(call); 1801 return TryReplaceInstanceCallWithInline(call);
1796 } 1802 }
1797 1803
1804 if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
1805 (ic_data.NumberOfChecks() == 1)) {
1806 ASSERT((class_ids[0] == kOneByteStringCid) ||
1807 (class_ids[0] == kTwoByteStringCid) ||
1808 (class_ids[0] == kExternalOneByteStringCid) ||
1809 (class_ids[0] == kExternalTwoByteStringCid));
1810 return TryReplaceInstanceCallWithInline(call);
1811 }
1812
1798 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { 1813 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
1799 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { 1814 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
1800 // This is an internal method, no need to check argument types nor 1815 // This is an internal method, no need to check argument types nor
1801 // range. 1816 // range.
1802 Definition* str = call->ArgumentAt(0); 1817 Definition* str = call->ArgumentAt(0);
1803 Definition* index = call->ArgumentAt(1); 1818 Definition* index = call->ArgumentAt(1);
1804 Definition* value = call->ArgumentAt(2); 1819 Definition* value = call->ArgumentAt(2);
1805 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr( 1820 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr(
1806 new(Z) Value(str), 1821 new(Z) Value(str),
1807 new(Z) Value(index), 1822 new(Z) Value(index),
(...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after
2756 2771
2757 // Discard the environment from the original instruction because the store 2772 // Discard the environment from the original instruction because the store
2758 // can't deoptimize. 2773 // can't deoptimize.
2759 instr->RemoveEnvironment(); 2774 instr->RemoveEnvironment();
2760 ReplaceCall(instr, store); 2775 ReplaceCall(instr, store);
2761 return true; 2776 return true;
2762 } 2777 }
2763 2778
2764 2779
2765 } // namespace dart 2780 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/string_patch.dart ('k') | runtime/vm/constant_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698