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

Side by Side Diff: runtime/vm/jit_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/vm/intrinsifier_x64.cc ('k') | runtime/vm/method_recognizer.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) 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/jit_optimizer.h" 5 #include "vm/jit_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 737 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 // from string-from-char-code instruction. 748 // from string-from-char-code instruction.
749 static bool IsLengthOneString(Definition* d) { 749 static bool IsLengthOneString(Definition* d) {
750 if (d->IsConstant()) { 750 if (d->IsConstant()) {
751 const Object& obj = d->AsConstant()->value(); 751 const Object& obj = d->AsConstant()->value();
752 if (obj.IsString()) { 752 if (obj.IsString()) {
753 return String::Cast(obj).Length() == 1; 753 return String::Cast(obj).Length() == 1;
754 } else { 754 } else {
755 return false; 755 return false;
756 } 756 }
757 } else { 757 } else {
758 return d->IsStringFromCharCode(); 758 return d->IsOneByteStringFromCharCode();
759 } 759 }
760 } 760 }
761 761
762 762
763 // Returns true if the string comparison was converted into char-code 763 // Returns true if the string comparison was converted into char-code
764 // comparison. Conversion is only possible for strings of length one. 764 // comparison. Conversion is only possible for strings of length one.
765 // E.g., detect str[x] == "x"; and use an integer comparison of char-codes. 765 // E.g., detect str[x] == "x"; and use an integer comparison of char-codes.
766 // TODO(srdjan): Expand for two-byte and external strings. 766 // TODO(srdjan): Expand for two-byte and external strings.
767 bool JitOptimizer::TryStringLengthOneEquality(InstanceCallInstr* call, 767 bool JitOptimizer::TryStringLengthOneEquality(InstanceCallInstr* call,
768 Token::Kind op_kind) { 768 Token::Kind op_kind) {
(...skipping 13 matching lines...) Expand all
782 if (IsLengthOneString(left)) { 782 if (IsLengthOneString(left)) {
783 // Optimize if left is a string with length one (either constant or 783 // Optimize if left is a string with length one (either constant or
784 // result of string-from-char-code. 784 // result of string-from-char-code.
785 if (left->IsConstant()) { 785 if (left->IsConstant()) {
786 ConstantInstr* left_const = left->AsConstant(); 786 ConstantInstr* left_const = left->AsConstant();
787 const String& str = String::Cast(left_const->value()); 787 const String& str = String::Cast(left_const->value());
788 ASSERT(str.Length() == 1); 788 ASSERT(str.Length() == 1);
789 ConstantInstr* char_code_left = flow_graph()->GetConstant( 789 ConstantInstr* char_code_left = flow_graph()->GetConstant(
790 Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0))))); 790 Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0)))));
791 left_val = new(Z) Value(char_code_left); 791 left_val = new(Z) Value(char_code_left);
792 } else if (left->IsStringFromCharCode()) { 792 } else if (left->IsOneByteStringFromCharCode()) {
793 // Use input of string-from-charcode as left value. 793 // Use input of string-from-charcode as left value.
794 StringFromCharCodeInstr* instr = left->AsStringFromCharCode(); 794 OneByteStringFromCharCodeInstr* instr =
795 left->AsOneByteStringFromCharCode();
795 left_val = new(Z) Value(instr->char_code()->definition()); 796 left_val = new(Z) Value(instr->char_code()->definition());
796 to_remove_left = instr; 797 to_remove_left = instr;
797 } else { 798 } else {
798 // IsLengthOneString(left) should have been false. 799 // IsLengthOneString(left) should have been false.
799 UNREACHABLE(); 800 UNREACHABLE();
800 } 801 }
801 802
802 Definition* to_remove_right = NULL; 803 Definition* to_remove_right = NULL;
803 Value* right_val = NULL; 804 Value* right_val = NULL;
804 if (right->IsStringFromCharCode()) { 805 if (right->IsOneByteStringFromCharCode()) {
805 // Skip string-from-char-code, and use its input as right value. 806 // Skip string-from-char-code, and use its input as right value.
806 StringFromCharCodeInstr* right_instr = right->AsStringFromCharCode(); 807 OneByteStringFromCharCodeInstr* right_instr =
808 right->AsOneByteStringFromCharCode();
807 right_val = new(Z) Value(right_instr->char_code()->definition()); 809 right_val = new(Z) Value(right_instr->char_code()->definition());
808 to_remove_right = right_instr; 810 to_remove_right = right_instr;
809 } else { 811 } else {
810 const ICData& unary_checks_1 = 812 const ICData& unary_checks_1 =
811 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)); 813 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1));
812 AddCheckClass(right, 814 AddCheckClass(right,
813 unary_checks_1, 815 unary_checks_1,
814 call->deopt_id(), 816 call->deopt_id(),
815 call->env(), 817 call->env(),
816 call); 818 call);
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
1757 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr( 1759 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
1758 GrowableObjectArray::length_offset(), 1760 GrowableObjectArray::length_offset(),
1759 new(Z) Value(array), 1761 new(Z) Value(array),
1760 new(Z) Value(value), 1762 new(Z) Value(value),
1761 kNoStoreBarrier, 1763 kNoStoreBarrier,
1762 call->token_pos()); 1764 call->token_pos());
1763 ReplaceCall(call, store); 1765 ReplaceCall(call, store);
1764 return true; 1766 return true;
1765 } 1767 }
1766 1768
1767 if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) || 1769 if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
1768 (recognized_kind == MethodRecognizer::kStringBaseCharAt)) && 1770 (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
1769 (ic_data.NumberOfChecks() == 1) && 1771 (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
1770 ((class_ids[0] == kOneByteStringCid) || 1772 (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
1771 (class_ids[0] == kTwoByteStringCid))) { 1773 ASSERT(ic_data.NumberOfChecks() == 1);
1774 ASSERT((class_ids[0] == kOneByteStringCid) ||
1775 (class_ids[0] == kTwoByteStringCid) ||
1776 (class_ids[0] == kExternalOneByteStringCid) ||
1777 (class_ids[0] == kExternalTwoByteStringCid));
1772 return TryReplaceInstanceCallWithInline(call); 1778 return TryReplaceInstanceCallWithInline(call);
1773 } 1779 }
1774 1780
1781 if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
1782 (ic_data.NumberOfChecks() == 1)) {
1783 ASSERT((class_ids[0] == kOneByteStringCid) ||
1784 (class_ids[0] == kTwoByteStringCid) ||
1785 (class_ids[0] == kExternalOneByteStringCid) ||
1786 (class_ids[0] == kExternalTwoByteStringCid));
1787 return TryReplaceInstanceCallWithInline(call);
1788 }
1789
1775 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { 1790 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
1776 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { 1791 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
1777 // This is an internal method, no need to check argument types nor 1792 // This is an internal method, no need to check argument types nor
1778 // range. 1793 // range.
1779 Definition* str = call->ArgumentAt(0); 1794 Definition* str = call->ArgumentAt(0);
1780 Definition* index = call->ArgumentAt(1); 1795 Definition* index = call->ArgumentAt(1);
1781 Definition* value = call->ArgumentAt(2); 1796 Definition* value = call->ArgumentAt(2);
1782 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr( 1797 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr(
1783 new(Z) Value(str), 1798 new(Z) Value(str),
1784 new(Z) Value(index), 1799 new(Z) Value(index),
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 3081
3067 // Discard the environment from the original instruction because the store 3082 // Discard the environment from the original instruction because the store
3068 // can't deoptimize. 3083 // can't deoptimize.
3069 instr->RemoveEnvironment(); 3084 instr->RemoveEnvironment();
3070 ReplaceCall(instr, store); 3085 ReplaceCall(instr, store);
3071 return true; 3086 return true;
3072 } 3087 }
3073 3088
3074 3089
3075 } // namespace dart 3090 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_x64.cc ('k') | runtime/vm/method_recognizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698