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

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

Issue 2744263002: [string] Refactor direct string conversions (Closed)
Patch Set: Tweaks Created 3 years, 9 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 | « src/builtins/builtins-regexp.h ('k') | src/code-stub-assembler.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 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 6
7 #include "src/builtins/builtins-constructor.h" 7 #include "src/builtins/builtins-constructor.h"
8 #include "src/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils.h"
9 #include "src/builtins/builtins.h" 9 #include "src/builtins/builtins.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 Branch(IntPtrGreaterThanOrEqual(var_i.value(), names_length), &out, 209 Branch(IntPtrGreaterThanOrEqual(var_i.value(), names_length), &out,
210 &loop); 210 &loop);
211 } 211 }
212 } 212 }
213 213
214 Bind(&out); 214 Bind(&out);
215 return result; 215 return result;
216 } 216 }
217 217
218 void RegExpBuiltinsAssembler::GetStringPointers( 218 void RegExpBuiltinsAssembler::GetStringPointers(
219 Node* const string, Node* const offset, Node* const last_index, 219 Node* const string_data, Node* const offset, Node* const last_index,
220 Node* const string_length, bool is_one_byte, Variable* var_string_start, 220 Node* const string_length, String::Encoding encoding,
221 Variable* var_string_end) { 221 Variable* var_string_start, Variable* var_string_end) {
222 DCHECK_EQ(var_string_start->rep(), MachineType::PointerRepresentation()); 222 DCHECK_EQ(var_string_start->rep(), MachineType::PointerRepresentation());
223 DCHECK_EQ(var_string_end->rep(), MachineType::PointerRepresentation()); 223 DCHECK_EQ(var_string_end->rep(), MachineType::PointerRepresentation());
224 224
225 STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize); 225 const ElementsKind kind = (encoding == String::ONE_BYTE_ENCODING)
226 const int kHeaderSize = SeqOneByteString::kHeaderSize - kHeapObjectTag; 226 ? UINT8_ELEMENTS
227 const ElementsKind kind = is_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS; 227 : UINT16_ELEMENTS;
228 228
229 Node* const from_offset = ElementOffsetFromIndex( 229 Node* const from_offset = ElementOffsetFromIndex(
230 IntPtrAdd(offset, last_index), kind, INTPTR_PARAMETERS, kHeaderSize); 230 IntPtrAdd(offset, last_index), kind, INTPTR_PARAMETERS);
231 var_string_start->Bind(IntPtrAdd(string, from_offset)); 231 var_string_start->Bind(IntPtrAdd(string_data, from_offset));
232 232
233 Node* const to_offset = ElementOffsetFromIndex( 233 Node* const to_offset = ElementOffsetFromIndex(
234 IntPtrAdd(offset, string_length), kind, INTPTR_PARAMETERS, kHeaderSize); 234 IntPtrAdd(offset, string_length), kind, INTPTR_PARAMETERS);
235 var_string_end->Bind(IntPtrAdd(string, to_offset)); 235 var_string_end->Bind(IntPtrAdd(string_data, to_offset));
236 } 236 }
237 237
238 Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context, 238 Node* RegExpBuiltinsAssembler::IrregexpExec(Node* const context,
239 Node* const regexp, 239 Node* const regexp,
240 Node* const string, 240 Node* const string,
241 Node* const last_index, 241 Node* const last_index,
242 Node* const match_info) { 242 Node* const match_info) {
243 // Just jump directly to runtime if native RegExp is not selected at compile 243 // Just jump directly to runtime if native RegExp is not selected at compile
244 // time or if regexp entry in generated code is turned off runtime switch or 244 // time or if regexp entry in generated code is turned off runtime switch or
245 // at compilation. 245 // at compilation.
246 #ifdef V8_INTERPRETED_REGEXP 246 #ifdef V8_INTERPRETED_REGEXP
247 return CallRuntime(Runtime::kRegExpExec, context, regexp, string, last_index, 247 return CallRuntime(Runtime::kRegExpExec, context, regexp, string, last_index,
248 match_info); 248 match_info);
249 #else // V8_INTERPRETED_REGEXP 249 #else // V8_INTERPRETED_REGEXP
250 CSA_ASSERT(this, TaggedIsNotSmi(regexp)); 250 CSA_ASSERT(this, TaggedIsNotSmi(regexp));
251 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE)); 251 CSA_ASSERT(this, HasInstanceType(regexp, JS_REGEXP_TYPE));
252 252
253 CSA_ASSERT(this, TaggedIsNotSmi(string)); 253 CSA_ASSERT(this, TaggedIsNotSmi(string));
254 CSA_ASSERT(this, IsString(string)); 254 CSA_ASSERT(this, IsString(string));
255 255
256 CSA_ASSERT(this, IsHeapNumberMap(LoadReceiverMap(last_index))); 256 CSA_ASSERT(this, IsHeapNumberMap(LoadReceiverMap(last_index)));
257 CSA_ASSERT(this, IsFixedArrayMap(LoadReceiverMap(match_info))); 257 CSA_ASSERT(this, IsFixedArrayMap(LoadReceiverMap(match_info)));
258 258
259 Node* const int_zero = IntPtrConstant(0); 259 Node* const int_zero = IntPtrConstant(0);
260 260
261 ToDirectStringAssembler to_direct(state(), string);
262
261 Variable var_result(this, MachineRepresentation::kTagged); 263 Variable var_result(this, MachineRepresentation::kTagged);
262 Variable var_string(this, MachineType::PointerRepresentation(), int_zero);
263 Variable var_string_offset(this, MachineType::PointerRepresentation(),
264 int_zero);
265 Variable var_string_instance_type(this, MachineRepresentation::kWord32,
266 Int32Constant(0));
267
268 Label out(this), runtime(this, Label::kDeferred); 264 Label out(this), runtime(this, Label::kDeferred);
269 265
270 // External constants. 266 // External constants.
271 Node* const regexp_stack_memory_size_address = ExternalConstant( 267 Node* const regexp_stack_memory_size_address = ExternalConstant(
272 ExternalReference::address_of_regexp_stack_memory_size(isolate())); 268 ExternalReference::address_of_regexp_stack_memory_size(isolate()));
273 Node* const static_offsets_vector_address = ExternalConstant( 269 Node* const static_offsets_vector_address = ExternalConstant(
274 ExternalReference::address_of_static_offsets_vector(isolate())); 270 ExternalReference::address_of_static_offsets_vector(isolate()));
275 Node* const pending_exception_address = ExternalConstant( 271 Node* const pending_exception_address = ExternalConstant(
276 ExternalReference(Isolate::kPendingExceptionAddress, isolate())); 272 ExternalReference(Isolate::kPendingExceptionAddress, isolate()));
277 273
(...skipping 23 matching lines...) Expand all
301 297
302 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2); 298 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
303 GotoIf(SmiAbove( 299 GotoIf(SmiAbove(
304 capture_count, 300 capture_count,
305 SmiConstant(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1)), 301 SmiConstant(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1)),
306 &runtime); 302 &runtime);
307 } 303 }
308 304
309 // Unpack the string if possible. 305 // Unpack the string if possible.
310 306
311 var_string.Bind(BitcastTaggedToWord(string)); 307 to_direct.TryToDirect(&runtime);
312 var_string_offset.Bind(int_zero);
313 var_string_instance_type.Bind(LoadInstanceType(string));
314
315 {
316 TryUnpackString(&var_string, &var_string_offset, &var_string_instance_type,
317 &runtime);
318
319 // At this point, {var_string} may contain a faked sequential string (i.e.
320 // an external string with an adjusted offset) so we cannot assert
321 // IsString({var_string}). We also cannot allocate after this point since
322 // GC could move {var_string}'s underlying string.
323 }
324 308
325 Node* const smi_string_length = LoadStringLength(string); 309 Node* const smi_string_length = LoadStringLength(string);
326 310
327 // Bail out to runtime for invalid {last_index} values. 311 // Bail out to runtime for invalid {last_index} values.
328 GotoIfNot(TaggedIsSmi(last_index), &runtime); 312 GotoIfNot(TaggedIsSmi(last_index), &runtime);
329 GotoIf(SmiAboveOrEqual(last_index, smi_string_length), &runtime); 313 GotoIf(SmiAboveOrEqual(last_index, smi_string_length), &runtime);
330 314
331 // Load the irregexp code object and offsets into the subject string. Both 315 // Load the irregexp code object and offsets into the subject string. Both
332 // depend on whether the string is one- or two-byte. 316 // depend on whether the string is one- or two-byte.
333 317
334 Node* const int_last_index = SmiUntag(last_index); 318 Node* const int_last_index = SmiUntag(last_index);
335 319
336 Variable var_string_start(this, MachineType::PointerRepresentation()); 320 Variable var_string_start(this, MachineType::PointerRepresentation());
337 Variable var_string_end(this, MachineType::PointerRepresentation()); 321 Variable var_string_end(this, MachineType::PointerRepresentation());
338 Variable var_code(this, MachineRepresentation::kTagged); 322 Variable var_code(this, MachineRepresentation::kTagged);
339 323
340 { 324 {
341 Node* const int_string_length = SmiUntag(smi_string_length); 325 Node* const int_string_length = SmiUntag(smi_string_length);
342 326 Node* const direct_string_data = to_direct.PointerToData(&runtime);
343 Node* const string_instance_type = var_string_instance_type.value();
344 CSA_ASSERT(this, IsSequentialStringInstanceType(string_instance_type));
345 327
346 Label next(this), if_isonebyte(this), if_istwobyte(this, Label::kDeferred); 328 Label next(this), if_isonebyte(this), if_istwobyte(this, Label::kDeferred);
347 Branch(IsOneByteStringInstanceType(string_instance_type), &if_isonebyte, 329 Branch(IsOneByteStringInstanceType(to_direct.instance_type()),
348 &if_istwobyte); 330 &if_isonebyte, &if_istwobyte);
349 331
350 Bind(&if_isonebyte); 332 Bind(&if_isonebyte);
351 { 333 {
352 const bool kIsOneByte = true; 334 GetStringPointers(direct_string_data, to_direct.offset(), int_last_index,
353 GetStringPointers(var_string.value(), var_string_offset.value(), 335 int_string_length, String::ONE_BYTE_ENCODING,
354 int_last_index, int_string_length, kIsOneByte,
355 &var_string_start, &var_string_end); 336 &var_string_start, &var_string_end);
356 var_code.Bind( 337 var_code.Bind(
357 LoadFixedArrayElement(data, JSRegExp::kIrregexpLatin1CodeIndex)); 338 LoadFixedArrayElement(data, JSRegExp::kIrregexpLatin1CodeIndex));
358 Goto(&next); 339 Goto(&next);
359 } 340 }
360 341
361 Bind(&if_istwobyte); 342 Bind(&if_istwobyte);
362 { 343 {
363 const bool kIsOneByte = false; 344 GetStringPointers(direct_string_data, to_direct.offset(), int_last_index,
364 GetStringPointers(var_string.value(), var_string_offset.value(), 345 int_string_length, String::TWO_BYTE_ENCODING,
365 int_last_index, int_string_length, kIsOneByte,
366 &var_string_start, &var_string_end); 346 &var_string_start, &var_string_end);
367 var_code.Bind( 347 var_code.Bind(
368 LoadFixedArrayElement(data, JSRegExp::kIrregexpUC16CodeIndex)); 348 LoadFixedArrayElement(data, JSRegExp::kIrregexpUC16CodeIndex));
369 Goto(&next); 349 Goto(&next);
370 } 350 }
371 351
372 Bind(&next); 352 Bind(&next);
373 } 353 }
374 354
375 // Check that the irregexp code has been generated for the actual string 355 // Check that the irregexp code has been generated for the actual string
(...skipping 2465 matching lines...) Expand 10 before | Expand all | Expand 10 after
2841 Bind(&if_matched); 2821 Bind(&if_matched);
2842 { 2822 {
2843 Node* result = 2823 Node* result =
2844 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string); 2824 ConstructNewResultFromMatchInfo(context, regexp, match_indices, string);
2845 Return(result); 2825 Return(result);
2846 } 2826 }
2847 } 2827 }
2848 2828
2849 } // namespace internal 2829 } // namespace internal
2850 } // namespace v8 2830 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-regexp.h ('k') | src/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698