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

Side by Side Diff: src/builtins/builtins-string.cc

Issue 2690853004: [builtins] Add support for ExternalOneByteStrings to StringEqual. (Closed)
Patch Set: Created 3 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/builtins/builtins-regexp.h" 5 #include "src/builtins/builtins-regexp.h"
6 #include "src/builtins/builtins-utils.h" 6 #include "src/builtins/builtins-utils.h"
7 #include "src/builtins/builtins.h" 7 #include "src/builtins/builtins.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stub-assembler.h" 9 #include "src/code-stub-assembler.h"
10 #include "src/regexp/regexp-utils.h" 10 #include "src/regexp/regexp-utils.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 typedef CodeStubAssembler::ResultMode ResultMode; 15 typedef CodeStubAssembler::ResultMode ResultMode;
16 typedef CodeStubAssembler::RelationalComparisonMode RelationalComparisonMode; 16 typedef CodeStubAssembler::RelationalComparisonMode RelationalComparisonMode;
17 17
18 class StringBuiltinsAssembler : public CodeStubAssembler { 18 class StringBuiltinsAssembler : public CodeStubAssembler {
19 public: 19 public:
20 explicit StringBuiltinsAssembler(compiler::CodeAssemblerState* state) 20 explicit StringBuiltinsAssembler(compiler::CodeAssemblerState* state)
21 : CodeStubAssembler(state) {} 21 : CodeStubAssembler(state) {}
22 22
23 protected: 23 protected:
24 Node* DirectStringData(Node* string, Node* string_instance_type) {
25 // Compute the effective offset of the first character.
26 Variable var_data(this, MachineType::PointerRepresentation());
27 Label if_sequential(this), if_external(this), if_join(this);
28 Branch(Word32Equal(Word32And(string_instance_type,
29 Int32Constant(kStringRepresentationMask)),
30 Int32Constant(kSeqStringTag)),
31 &if_sequential, &if_external);
32
33 Bind(&if_sequential);
34 {
35 var_data.Bind(IntPtrAdd(
36 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag),
37 BitcastTaggedToWord(string)));
38 Goto(&if_join);
39 }
40
41 Bind(&if_external);
42 {
43 // This is only valid for ExternalStrings where the resource data
44 // pointer is cached (i.e. no short external strings).
45 CSA_ASSERT(this, Word32NotEqual(
46 Word32And(string_instance_type,
47 Int32Constant(kShortExternalStringMask)),
48 Int32Constant(kShortExternalStringTag)));
49 var_data.Bind(LoadObjectField(string, ExternalString::kResourceDataOffset,
50 MachineType::Pointer()));
51 Goto(&if_join);
52 }
53
54 Bind(&if_join);
55 return var_data.value();
56 }
57
24 Node* LoadOneByteChar(Node* string, Node* index) { 58 Node* LoadOneByteChar(Node* string, Node* index) {
25 return Load(MachineType::Uint8(), string, OneByteCharOffset(index)); 59 return Load(MachineType::Uint8(), string, OneByteCharOffset(index));
26 } 60 }
27 61
28 Node* OneByteCharAddress(Node* string, Node* index) { 62 Node* OneByteCharAddress(Node* string, Node* index) {
29 Node* offset = OneByteCharOffset(index); 63 Node* offset = OneByteCharOffset(index);
30 return IntPtrAdd(BitcastTaggedToWord(string), offset); 64 return IntPtrAdd(BitcastTaggedToWord(string), offset);
31 } 65 }
32 66
33 Node* OneByteCharOffset(Node* index) { 67 Node* OneByteCharOffset(Node* index) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 // Check if both {lhs} and {rhs} are internalized. Since we already know 182 // Check if both {lhs} and {rhs} are internalized. Since we already know
149 // that they're not the same object, they're not equal in that case. 183 // that they're not the same object, they're not equal in that case.
150 int const kBothInternalizedMask = 184 int const kBothInternalizedMask =
151 kIsNotInternalizedMask | (kIsNotInternalizedMask << 8); 185 kIsNotInternalizedMask | (kIsNotInternalizedMask << 8);
152 int const kBothInternalizedTag = kInternalizedTag | (kInternalizedTag << 8); 186 int const kBothInternalizedTag = kInternalizedTag | (kInternalizedTag << 8);
153 GotoIf(Word32Equal(Word32And(both_instance_types, 187 GotoIf(Word32Equal(Word32And(both_instance_types,
154 Int32Constant(kBothInternalizedMask)), 188 Int32Constant(kBothInternalizedMask)),
155 Int32Constant(kBothInternalizedTag)), 189 Int32Constant(kBothInternalizedTag)),
156 &if_notequal); 190 &if_notequal);
157 191
158 // Check that both {lhs} and {rhs} are flat one-byte strings. 192 // Check that both {lhs} and {rhs} are flat one-byte strings, and that
159 int const kBothSeqOneByteStringMask = 193 // in case of ExternalStrings the data pointer is cached..
160 kStringEncodingMask | kStringRepresentationMask | 194 STATIC_ASSERT(kShortExternalStringTag != 0);
161 ((kStringEncodingMask | kStringRepresentationMask) << 8); 195 int const kBothDirectOneByteStringMask =
162 int const kBothSeqOneByteStringTag = 196 kStringEncodingMask | kIsIndirectStringMask | kShortExternalStringMask |
163 kOneByteStringTag | kSeqStringTag | 197 ((kStringEncodingMask | kIsIndirectStringMask | kShortExternalStringMask)
164 ((kOneByteStringTag | kSeqStringTag) << 8); 198 << 8);
165 Label if_bothonebyteseqstrings(this), if_notbothonebyteseqstrings(this); 199 int const kBothDirectOneByteStringTag =
200 kOneByteStringTag | (kOneByteStringTag << 8);
201 Label if_bothdirectonebytestrings(this), if_notbothdirectonebytestrings(this);
166 Branch(Word32Equal(Word32And(both_instance_types, 202 Branch(Word32Equal(Word32And(both_instance_types,
167 Int32Constant(kBothSeqOneByteStringMask)), 203 Int32Constant(kBothDirectOneByteStringMask)),
168 Int32Constant(kBothSeqOneByteStringTag)), 204 Int32Constant(kBothDirectOneByteStringTag)),
169 &if_bothonebyteseqstrings, &if_notbothonebyteseqstrings); 205 &if_bothdirectonebytestrings, &if_notbothdirectonebytestrings);
170 206
171 Bind(&if_bothonebyteseqstrings); 207 Bind(&if_bothdirectonebytestrings);
172 { 208 {
173 // Compute the effective offset of the first character. 209 // Compute the effective offset of the first character.
174 Node* begin = 210 Node* lhs_data = DirectStringData(lhs, lhs_instance_type);
175 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag); 211 Node* rhs_data = DirectStringData(rhs, rhs_instance_type);
176 212
177 // Compute the first offset after the string from the length. 213 // Compute the first offset after the string from the length.
178 Node* end = IntPtrAdd(begin, SmiUntag(lhs_length)); 214 Node* length = SmiUntag(lhs_length);
179 215
180 // Loop over the {lhs} and {rhs} strings to see if they are equal. 216 // Loop over the {lhs} and {rhs} strings to see if they are equal.
181 Variable var_offset(this, MachineType::PointerRepresentation()); 217 Variable var_offset(this, MachineType::PointerRepresentation());
182 Label loop(this, &var_offset); 218 Label loop(this, &var_offset);
183 var_offset.Bind(begin); 219 var_offset.Bind(IntPtrConstant(0));
184 Goto(&loop); 220 Goto(&loop);
185 Bind(&loop); 221 Bind(&loop);
186 { 222 {
187 // If {offset} equals {end}, no difference was found, so the 223 // If {offset} equals {end}, no difference was found, so the
188 // strings are equal. 224 // strings are equal.
189 Node* offset = var_offset.value(); 225 Node* offset = var_offset.value();
190 GotoIf(WordEqual(offset, end), &if_equal); 226 GotoIf(WordEqual(offset, length), &if_equal);
191 227
192 // Load the next characters from {lhs} and {rhs}. 228 // Load the next characters from {lhs} and {rhs}.
193 Node* lhs_value = Load(MachineType::Uint8(), lhs, offset); 229 Node* lhs_value = Load(MachineType::Uint8(), lhs_data, offset);
194 Node* rhs_value = Load(MachineType::Uint8(), rhs, offset); 230 Node* rhs_value = Load(MachineType::Uint8(), rhs_data, offset);
195 231
196 // Check if the characters match. 232 // Check if the characters match.
197 GotoIf(Word32NotEqual(lhs_value, rhs_value), &if_notequal); 233 GotoIf(Word32NotEqual(lhs_value, rhs_value), &if_notequal);
198 234
199 // Advance to next character. 235 // Advance to next character.
200 var_offset.Bind(IntPtrAdd(offset, IntPtrConstant(1))); 236 var_offset.Bind(IntPtrAdd(offset, IntPtrConstant(1)));
201 Goto(&loop); 237 Goto(&loop);
202 } 238 }
203 } 239 }
204 240
205 Bind(&if_notbothonebyteseqstrings); 241 Bind(&if_notbothdirectonebytestrings);
206 { 242 {
207 // Try to unwrap indirect strings, restart the above attempt on success. 243 // Try to unwrap indirect strings, restart the above attempt on success.
208 MaybeDerefIndirectStrings(&var_left, lhs_instance_type, &var_right, 244 MaybeDerefIndirectStrings(&var_left, lhs_instance_type, &var_right,
209 rhs_instance_type, &restart); 245 rhs_instance_type, &restart);
210 // TODO(bmeurer): Add support for two byte string equality checks. 246 // TODO(bmeurer): Add support for two byte string equality checks.
211 247
212 Runtime::FunctionId function_id = (mode == ResultMode::kDontNegateResult) 248 Runtime::FunctionId function_id = (mode == ResultMode::kDontNegateResult)
213 ? Runtime::kStringEqual 249 ? Runtime::kStringEqual
214 : Runtime::kStringNotEqual; 250 : Runtime::kStringNotEqual;
215 TailCallRuntime(function_id, context, lhs, rhs); 251 TailCallRuntime(function_id, context, lhs, rhs);
(...skipping 1655 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context, 1907 CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
1872 HeapConstant(factory()->NewStringFromAsciiChecked( 1908 HeapConstant(factory()->NewStringFromAsciiChecked(
1873 "String Iterator.prototype.next", TENURED)), 1909 "String Iterator.prototype.next", TENURED)),
1874 iterator); 1910 iterator);
1875 Return(result); // Never reached. 1911 Return(result); // Never reached.
1876 } 1912 }
1877 } 1913 }
1878 1914
1879 } // namespace internal 1915 } // namespace internal
1880 } // namespace v8 1916 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698