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

Side by Side Diff: src/regexp/arm64/regexp-macro-assembler-arm64.cc

Issue 1451373003: Revert of Experimental support for RegExp lookbehind. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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/regexp/arm64/regexp-macro-assembler-arm64.h ('k') | src/regexp/bytecodes-irregexp.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h" 7 #include "src/regexp/arm64/regexp-macro-assembler-arm64.h"
8 8
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/log.h" 10 #include "src/log.h"
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 } 203 }
204 204
205 205
206 void RegExpMacroAssemblerARM64::CheckCharacterGT(uc16 limit, 206 void RegExpMacroAssemblerARM64::CheckCharacterGT(uc16 limit,
207 Label* on_greater) { 207 Label* on_greater) {
208 CompareAndBranchOrBacktrack(current_character(), limit, hi, on_greater); 208 CompareAndBranchOrBacktrack(current_character(), limit, hi, on_greater);
209 } 209 }
210 210
211 211
212 void RegExpMacroAssemblerARM64::CheckAtStart(Label* on_at_start) { 212 void RegExpMacroAssemblerARM64::CheckAtStart(Label* on_at_start) {
213 __ Add(w10, current_input_offset(), Operand(-char_size())); 213 Label not_at_start;
214 __ Cmp(w10, string_start_minus_one()); 214 // Did we start the match at the start of the input string?
215 CompareAndBranchOrBacktrack(start_offset(), 0, ne, &not_at_start);
216 // If we did, are we still at the start of the input string?
217 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW));
218 __ Cmp(x10, input_start());
215 BranchOrBacktrack(eq, on_at_start); 219 BranchOrBacktrack(eq, on_at_start);
220 __ Bind(&not_at_start);
216 } 221 }
217 222
218 223
219 void RegExpMacroAssemblerARM64::CheckNotAtStart(int cp_offset, 224 void RegExpMacroAssemblerARM64::CheckNotAtStart(Label* on_not_at_start) {
220 Label* on_not_at_start) { 225 // Did we start the match at the start of the input string?
221 __ Add(w10, current_input_offset(), 226 CompareAndBranchOrBacktrack(start_offset(), 0, ne, on_not_at_start);
222 Operand(-char_size() + cp_offset * char_size())); 227 // If we did, are we still at the start of the input string?
223 __ Cmp(w10, string_start_minus_one()); 228 __ Add(x10, input_end(), Operand(current_input_offset(), SXTW));
229 __ Cmp(x10, input_start());
224 BranchOrBacktrack(ne, on_not_at_start); 230 BranchOrBacktrack(ne, on_not_at_start);
225 } 231 }
226 232
227 233
228 void RegExpMacroAssemblerARM64::CheckCharacterLT(uc16 limit, Label* on_less) { 234 void RegExpMacroAssemblerARM64::CheckCharacterLT(uc16 limit, Label* on_less) {
229 CompareAndBranchOrBacktrack(current_character(), limit, lo, on_less); 235 CompareAndBranchOrBacktrack(current_character(), limit, lo, on_less);
230 } 236 }
231 237
232 238
233 void RegExpMacroAssemblerARM64::CheckCharacters(Vector<const uc16> str, 239 void RegExpMacroAssemblerARM64::CheckCharacters(Vector<const uc16> str,
(...skipping 30 matching lines...) Expand all
264 270
265 void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) { 271 void RegExpMacroAssemblerARM64::CheckGreedyLoop(Label* on_equal) {
266 __ Ldr(w10, MemOperand(backtrack_stackpointer())); 272 __ Ldr(w10, MemOperand(backtrack_stackpointer()));
267 __ Cmp(current_input_offset(), w10); 273 __ Cmp(current_input_offset(), w10);
268 __ Cset(x11, eq); 274 __ Cset(x11, eq);
269 __ Add(backtrack_stackpointer(), 275 __ Add(backtrack_stackpointer(),
270 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2)); 276 backtrack_stackpointer(), Operand(x11, LSL, kWRegSizeLog2));
271 BranchOrBacktrack(eq, on_equal); 277 BranchOrBacktrack(eq, on_equal);
272 } 278 }
273 279
274
275 void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase( 280 void RegExpMacroAssemblerARM64::CheckNotBackReferenceIgnoreCase(
276 int start_reg, bool read_backward, Label* on_no_match) { 281 int start_reg,
282 Label* on_no_match) {
277 Label fallthrough; 283 Label fallthrough;
278 284
279 Register capture_start_offset = w10; 285 Register capture_start_offset = w10;
280 // Save the capture length in a callee-saved register so it will 286 // Save the capture length in a callee-saved register so it will
281 // be preserved if we call a C helper. 287 // be preserved if we call a C helper.
282 Register capture_length = w19; 288 Register capture_length = w19;
283 DCHECK(kCalleeSaved.IncludesAliasOf(capture_length)); 289 DCHECK(kCalleeSaved.IncludesAliasOf(capture_length));
284 290
285 // Find length of back-referenced capture. 291 // Find length of back-referenced capture.
286 DCHECK((start_reg % 2) == 0); 292 DCHECK((start_reg % 2) == 0);
287 if (start_reg < kNumCachedRegisters) { 293 if (start_reg < kNumCachedRegisters) {
288 __ Mov(capture_start_offset.X(), GetCachedRegister(start_reg)); 294 __ Mov(capture_start_offset.X(), GetCachedRegister(start_reg));
289 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); 295 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits);
290 } else { 296 } else {
291 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10)); 297 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10));
292 } 298 }
293 __ Sub(capture_length, w11, capture_start_offset); // Length to check. 299 __ Sub(capture_length, w11, capture_start_offset); // Length to check.
294 300 // Succeed on empty capture (including no capture).
295 // At this point, the capture registers are either both set or both cleared. 301 __ Cbz(capture_length, &fallthrough);
296 // If the capture length is zero, then the capture is either empty or cleared.
297 // Fall through in both cases.
298 __ CompareAndBranch(capture_length, Operand(0), eq, &fallthrough);
299 302
300 // Check that there are enough characters left in the input. 303 // Check that there are enough characters left in the input.
301 if (read_backward) { 304 __ Cmn(capture_length, current_input_offset());
302 __ Add(w12, string_start_minus_one(), capture_length); 305 BranchOrBacktrack(gt, on_no_match);
303 __ Cmp(current_input_offset(), w12);
304 BranchOrBacktrack(le, on_no_match);
305 } else {
306 __ Cmn(capture_length, current_input_offset());
307 BranchOrBacktrack(gt, on_no_match);
308 }
309 306
310 if (mode_ == LATIN1) { 307 if (mode_ == LATIN1) {
311 Label success; 308 Label success;
312 Label fail; 309 Label fail;
313 Label loop_check; 310 Label loop_check;
314 311
315 Register capture_start_address = x12; 312 Register capture_start_address = x12;
316 Register capture_end_addresss = x13; 313 Register capture_end_addresss = x13;
317 Register current_position_address = x14; 314 Register current_position_address = x14;
318 315
319 __ Add(capture_start_address, 316 __ Add(capture_start_address,
320 input_end(), 317 input_end(),
321 Operand(capture_start_offset, SXTW)); 318 Operand(capture_start_offset, SXTW));
322 __ Add(capture_end_addresss, 319 __ Add(capture_end_addresss,
323 capture_start_address, 320 capture_start_address,
324 Operand(capture_length, SXTW)); 321 Operand(capture_length, SXTW));
325 __ Add(current_position_address, 322 __ Add(current_position_address,
326 input_end(), 323 input_end(),
327 Operand(current_input_offset(), SXTW)); 324 Operand(current_input_offset(), SXTW));
328 if (read_backward) {
329 // Offset by length when matching backwards.
330 __ Sub(current_position_address, current_position_address,
331 Operand(capture_length, SXTW));
332 }
333 325
334 Label loop; 326 Label loop;
335 __ Bind(&loop); 327 __ Bind(&loop);
336 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); 328 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex));
337 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); 329 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex));
338 __ Cmp(w10, w11); 330 __ Cmp(w10, w11);
339 __ B(eq, &loop_check); 331 __ B(eq, &loop_check);
340 332
341 // Mismatch, try case-insensitive match (converting letters to lower-case). 333 // Mismatch, try case-insensitive match (converting letters to lower-case).
342 __ Orr(w10, w10, 0x20); // Convert capture character to lower-case. 334 __ Orr(w10, w10, 0x20); // Convert capture character to lower-case.
(...skipping 19 matching lines...) Expand all
362 354
363 __ Bind(&success); 355 __ Bind(&success);
364 // Compute new value of character position after the matched part. 356 // Compute new value of character position after the matched part.
365 __ Sub(current_input_offset().X(), current_position_address, input_end()); 357 __ Sub(current_input_offset().X(), current_position_address, input_end());
366 if (masm_->emit_debug_code()) { 358 if (masm_->emit_debug_code()) {
367 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); 359 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
368 __ Ccmp(current_input_offset(), 0, NoFlag, eq); 360 __ Ccmp(current_input_offset(), 0, NoFlag, eq);
369 // The current input offset should be <= 0, and fit in a W register. 361 // The current input offset should be <= 0, and fit in a W register.
370 __ Check(le, kOffsetOutOfRange); 362 __ Check(le, kOffsetOutOfRange);
371 } 363 }
372 if (read_backward) {
373 __ Sub(current_input_offset(), current_input_offset(),
374 Operand(capture_length, SXTW));
375 }
376 } else { 364 } else {
377 DCHECK(mode_ == UC16); 365 DCHECK(mode_ == UC16);
378 int argument_count = 4; 366 int argument_count = 4;
379 367
380 // The cached registers need to be retained. 368 // The cached registers need to be retained.
381 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7); 369 CPURegList cached_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 7);
382 DCHECK((cached_registers.Count() * 2) == kNumCachedRegisters); 370 DCHECK((cached_registers.Count() * 2) == kNumCachedRegisters);
383 __ PushCPURegList(cached_registers); 371 __ PushCPURegList(cached_registers);
384 372
385 // Put arguments into arguments registers. 373 // Put arguments into arguments registers.
386 // Parameters are 374 // Parameters are
387 // x0: Address byte_offset1 - Address captured substring's start. 375 // x0: Address byte_offset1 - Address captured substring's start.
388 // x1: Address byte_offset2 - Address of current character position. 376 // x1: Address byte_offset2 - Address of current character position.
389 // w2: size_t byte_length - length of capture in bytes(!) 377 // w2: size_t byte_length - length of capture in bytes(!)
390 // x3: Isolate* isolate 378 // x3: Isolate* isolate
391 379
392 // Address of start of capture. 380 // Address of start of capture.
393 __ Add(x0, input_end(), Operand(capture_start_offset, SXTW)); 381 __ Add(x0, input_end(), Operand(capture_start_offset, SXTW));
394 // Length of capture. 382 // Length of capture.
395 __ Mov(w2, capture_length); 383 __ Mov(w2, capture_length);
396 // Address of current input position. 384 // Address of current input position.
397 __ Add(x1, input_end(), Operand(current_input_offset(), SXTW)); 385 __ Add(x1, input_end(), Operand(current_input_offset(), SXTW));
398 if (read_backward) {
399 __ Sub(x1, x1, Operand(capture_length, SXTW));
400 }
401 // Isolate. 386 // Isolate.
402 __ Mov(x3, ExternalReference::isolate_address(isolate())); 387 __ Mov(x3, ExternalReference::isolate_address(isolate()));
403 388
404 { 389 {
405 AllowExternalCallThatCantCauseGC scope(masm_); 390 AllowExternalCallThatCantCauseGC scope(masm_);
406 ExternalReference function = 391 ExternalReference function =
407 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 392 ExternalReference::re_case_insensitive_compare_uc16(isolate());
408 __ CallCFunction(function, argument_count); 393 __ CallCFunction(function, argument_count);
409 } 394 }
410 395
411 // Check if function returned non-zero for success or zero for failure. 396 // Check if function returned non-zero for success or zero for failure.
412 // x0 is one of the registers used as a cache so it must be tested before 397 // x0 is one of the registers used as a cache so it must be tested before
413 // the cache is restored. 398 // the cache is restored.
414 __ Cmp(x0, 0); 399 __ Cmp(x0, 0);
415 __ PopCPURegList(cached_registers); 400 __ PopCPURegList(cached_registers);
416 BranchOrBacktrack(eq, on_no_match); 401 BranchOrBacktrack(eq, on_no_match);
417 402
418 // On success, advance position by length of capture. 403 // On success, increment position by length of capture.
419 if (read_backward) { 404 __ Add(current_input_offset(), current_input_offset(), capture_length);
420 __ Sub(current_input_offset(), current_input_offset(), capture_length);
421 } else {
422 __ Add(current_input_offset(), current_input_offset(), capture_length);
423 }
424 } 405 }
425 406
426 __ Bind(&fallthrough); 407 __ Bind(&fallthrough);
427 } 408 }
428 409
429 void RegExpMacroAssemblerARM64::CheckNotBackReference(int start_reg, 410 void RegExpMacroAssemblerARM64::CheckNotBackReference(
430 bool read_backward, 411 int start_reg,
431 Label* on_no_match) { 412 Label* on_no_match) {
432 Label fallthrough; 413 Label fallthrough;
433 414
434 Register capture_start_address = x12; 415 Register capture_start_address = x12;
435 Register capture_end_address = x13; 416 Register capture_end_address = x13;
436 Register current_position_address = x14; 417 Register current_position_address = x14;
437 Register capture_length = w15; 418 Register capture_length = w15;
438 419
439 // Find length of back-referenced capture. 420 // Find length of back-referenced capture.
440 DCHECK((start_reg % 2) == 0); 421 DCHECK((start_reg % 2) == 0);
441 if (start_reg < kNumCachedRegisters) { 422 if (start_reg < kNumCachedRegisters) {
442 __ Mov(x10, GetCachedRegister(start_reg)); 423 __ Mov(x10, GetCachedRegister(start_reg));
443 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits); 424 __ Lsr(x11, GetCachedRegister(start_reg), kWRegSizeInBits);
444 } else { 425 } else {
445 __ Ldp(w11, w10, capture_location(start_reg, x10)); 426 __ Ldp(w11, w10, capture_location(start_reg, x10));
446 } 427 }
447 __ Sub(capture_length, w11, w10); // Length to check. 428 __ Sub(capture_length, w11, w10); // Length to check.
448 429 // Succeed on empty capture (including no capture).
449 // At this point, the capture registers are either both set or both cleared. 430 __ Cbz(capture_length, &fallthrough);
450 // If the capture length is zero, then the capture is either empty or cleared.
451 // Fall through in both cases.
452 __ CompareAndBranch(capture_length, Operand(0), eq, &fallthrough);
453 431
454 // Check that there are enough characters left in the input. 432 // Check that there are enough characters left in the input.
455 if (read_backward) { 433 __ Cmn(capture_length, current_input_offset());
456 __ Add(w12, string_start_minus_one(), capture_length); 434 BranchOrBacktrack(gt, on_no_match);
457 __ Cmp(current_input_offset(), w12);
458 BranchOrBacktrack(le, on_no_match);
459 } else {
460 __ Cmn(capture_length, current_input_offset());
461 BranchOrBacktrack(gt, on_no_match);
462 }
463 435
464 // Compute pointers to match string and capture string 436 // Compute pointers to match string and capture string
465 __ Add(capture_start_address, input_end(), Operand(w10, SXTW)); 437 __ Add(capture_start_address, input_end(), Operand(w10, SXTW));
466 __ Add(capture_end_address, 438 __ Add(capture_end_address,
467 capture_start_address, 439 capture_start_address,
468 Operand(capture_length, SXTW)); 440 Operand(capture_length, SXTW));
469 __ Add(current_position_address, 441 __ Add(current_position_address,
470 input_end(), 442 input_end(),
471 Operand(current_input_offset(), SXTW)); 443 Operand(current_input_offset(), SXTW));
472 if (read_backward) {
473 // Offset by length when matching backwards.
474 __ Sub(current_position_address, current_position_address,
475 Operand(capture_length, SXTW));
476 }
477 444
478 Label loop; 445 Label loop;
479 __ Bind(&loop); 446 __ Bind(&loop);
480 if (mode_ == LATIN1) { 447 if (mode_ == LATIN1) {
481 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); 448 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex));
482 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); 449 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex));
483 } else { 450 } else {
484 DCHECK(mode_ == UC16); 451 DCHECK(mode_ == UC16);
485 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex)); 452 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex));
486 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex)); 453 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex));
487 } 454 }
488 __ Cmp(w10, w11); 455 __ Cmp(w10, w11);
489 BranchOrBacktrack(ne, on_no_match); 456 BranchOrBacktrack(ne, on_no_match);
490 __ Cmp(capture_start_address, capture_end_address); 457 __ Cmp(capture_start_address, capture_end_address);
491 __ B(lt, &loop); 458 __ B(lt, &loop);
492 459
493 // Move current character position to position after match. 460 // Move current character position to position after match.
494 __ Sub(current_input_offset().X(), current_position_address, input_end()); 461 __ Sub(current_input_offset().X(), current_position_address, input_end());
495 if (read_backward) {
496 __ Sub(current_input_offset(), current_input_offset(),
497 Operand(capture_length, SXTW));
498 }
499
500 if (masm_->emit_debug_code()) { 462 if (masm_->emit_debug_code()) {
501 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); 463 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
502 __ Ccmp(current_input_offset(), 0, NoFlag, eq); 464 __ Ccmp(current_input_offset(), 0, NoFlag, eq);
503 // The current input offset should be <= 0, and fit in a W register. 465 // The current input offset should be <= 0, and fit in a W register.
504 __ Check(le, kOffsetOutOfRange); 466 __ Check(le, kOffsetOutOfRange);
505 } 467 }
506 __ Bind(&fallthrough); 468 __ Bind(&fallthrough);
507 } 469 }
508 470
509 471
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 // Check that the input string length is < 2^30. 751 // Check that the input string length is < 2^30.
790 __ Neg(x11, x10); 752 __ Neg(x11, x10);
791 __ Cmp(x11, (1<<30) - 1); 753 __ Cmp(x11, (1<<30) - 1);
792 __ Check(ls, kInputStringTooLong); 754 __ Check(ls, kInputStringTooLong);
793 } 755 }
794 __ Mov(current_input_offset(), w10); 756 __ Mov(current_input_offset(), w10);
795 757
796 // The non-position value is used as a clearing value for the 758 // The non-position value is used as a clearing value for the
797 // capture registers, it corresponds to the position of the first character 759 // capture registers, it corresponds to the position of the first character
798 // minus one. 760 // minus one.
799 __ Sub(string_start_minus_one(), current_input_offset(), char_size()); 761 __ Sub(non_position_value(), current_input_offset(), char_size());
800 __ Sub(string_start_minus_one(), string_start_minus_one(), 762 __ Sub(non_position_value(), non_position_value(),
801 Operand(start_offset(), LSL, (mode_ == UC16) ? 1 : 0)); 763 Operand(start_offset(), LSL, (mode_ == UC16) ? 1 : 0));
802 // We can store this value twice in an X register for initializing 764 // We can store this value twice in an X register for initializing
803 // on-stack registers later. 765 // on-stack registers later.
804 __ Orr(twice_non_position_value(), string_start_minus_one().X(), 766 __ Orr(twice_non_position_value(),
805 Operand(string_start_minus_one().X(), LSL, kWRegSizeInBits)); 767 non_position_value().X(),
768 Operand(non_position_value().X(), LSL, kWRegSizeInBits));
806 769
807 // Initialize code pointer register. 770 // Initialize code pointer register.
808 __ Mov(code_pointer(), Operand(masm_->CodeObject())); 771 __ Mov(code_pointer(), Operand(masm_->CodeObject()));
809 772
810 Label load_char_start_regexp, start_regexp; 773 Label load_char_start_regexp, start_regexp;
811 // Load newline if index is at start, previous character otherwise. 774 // Load newline if index is at start, previous character otherwise.
812 __ Cbnz(start_offset(), &load_char_start_regexp); 775 __ Cbnz(start_offset(), &load_char_start_regexp);
813 __ Mov(current_character(), '\n'); 776 __ Mov(current_character(), '\n');
814 __ B(&start_regexp); 777 __ B(&start_regexp);
815 778
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 return kARM64Implementation; 1074 return kARM64Implementation;
1112 } 1075 }
1113 1076
1114 1077
1115 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset, 1078 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset,
1116 Label* on_end_of_input, 1079 Label* on_end_of_input,
1117 bool check_bounds, 1080 bool check_bounds,
1118 int characters) { 1081 int characters) {
1119 // TODO(pielan): Make sure long strings are caught before this, and not 1082 // TODO(pielan): Make sure long strings are caught before this, and not
1120 // just asserted in debug mode. 1083 // just asserted in debug mode.
1084 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
1121 // Be sane! (And ensure that an int32_t can be used to index the string) 1085 // Be sane! (And ensure that an int32_t can be used to index the string)
1122 DCHECK(cp_offset < (1<<30)); 1086 DCHECK(cp_offset < (1<<30));
1123 if (check_bounds) { 1087 if (check_bounds) {
1124 if (cp_offset >= 0) { 1088 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1125 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1126 } else {
1127 CheckPosition(cp_offset, on_end_of_input);
1128 }
1129 } 1089 }
1130 LoadCurrentCharacterUnchecked(cp_offset, characters); 1090 LoadCurrentCharacterUnchecked(cp_offset, characters);
1131 } 1091 }
1132 1092
1133 1093
1134 void RegExpMacroAssemblerARM64::PopCurrentPosition() { 1094 void RegExpMacroAssemblerARM64::PopCurrentPosition() {
1135 Pop(current_input_offset()); 1095 Pop(current_input_offset());
1136 } 1096 }
1137 1097
1138 1098
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 } 1203 }
1244 1204
1245 1205
1246 void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) { 1206 void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) {
1247 DCHECK(reg_from <= reg_to); 1207 DCHECK(reg_from <= reg_to);
1248 int num_registers = reg_to - reg_from + 1; 1208 int num_registers = reg_to - reg_from + 1;
1249 1209
1250 // If the first capture register is cached in a hardware register but not 1210 // If the first capture register is cached in a hardware register but not
1251 // aligned on a 64-bit one, we need to clear the first one specifically. 1211 // aligned on a 64-bit one, we need to clear the first one specifically.
1252 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) { 1212 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) {
1253 StoreRegister(reg_from, string_start_minus_one()); 1213 StoreRegister(reg_from, non_position_value());
1254 num_registers--; 1214 num_registers--;
1255 reg_from++; 1215 reg_from++;
1256 } 1216 }
1257 1217
1258 // Clear cached registers in pairs as far as possible. 1218 // Clear cached registers in pairs as far as possible.
1259 while ((num_registers >= 2) && (reg_from < kNumCachedRegisters)) { 1219 while ((num_registers >= 2) && (reg_from < kNumCachedRegisters)) {
1260 DCHECK(GetRegisterState(reg_from) == CACHED_LSW); 1220 DCHECK(GetRegisterState(reg_from) == CACHED_LSW);
1261 __ Mov(GetCachedRegister(reg_from), twice_non_position_value()); 1221 __ Mov(GetCachedRegister(reg_from), twice_non_position_value());
1262 reg_from += 2; 1222 reg_from += 2;
1263 num_registers -= 2; 1223 num_registers -= 2;
1264 } 1224 }
1265 1225
1266 if ((num_registers % 2) == 1) { 1226 if ((num_registers % 2) == 1) {
1267 StoreRegister(reg_from, string_start_minus_one()); 1227 StoreRegister(reg_from, non_position_value());
1268 num_registers--; 1228 num_registers--;
1269 reg_from++; 1229 reg_from++;
1270 } 1230 }
1271 1231
1272 if (num_registers > 0) { 1232 if (num_registers > 0) {
1273 // If there are some remaining registers, they are stored on the stack. 1233 // If there are some remaining registers, they are stored on the stack.
1274 DCHECK(reg_from >= kNumCachedRegisters); 1234 DCHECK(reg_from >= kNumCachedRegisters);
1275 1235
1276 // Move down the indexes of the registers on stack to get the correct offset 1236 // Move down the indexes of the registers on stack to get the correct offset
1277 // in memory. 1237 // in memory.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 const byte** input_start, const byte** input_end) { 1294 const byte** input_start, const byte** input_end) {
1335 return NativeRegExpMacroAssembler::CheckStackGuardState( 1295 return NativeRegExpMacroAssembler::CheckStackGuardState(
1336 frame_entry<Isolate*>(re_frame, kIsolate), start_index, 1296 frame_entry<Isolate*>(re_frame, kIsolate), start_index,
1337 frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code, 1297 frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code,
1338 frame_entry_address<String*>(re_frame, kInput), input_start, input_end); 1298 frame_entry_address<String*>(re_frame, kInput), input_start, input_end);
1339 } 1299 }
1340 1300
1341 1301
1342 void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset, 1302 void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset,
1343 Label* on_outside_input) { 1303 Label* on_outside_input) {
1344 if (cp_offset >= 0) { 1304 CompareAndBranchOrBacktrack(current_input_offset(),
1345 CompareAndBranchOrBacktrack(current_input_offset(), 1305 -cp_offset * char_size(),
1346 -cp_offset * char_size(), ge, on_outside_input); 1306 ge,
1347 } else { 1307 on_outside_input);
1348 __ Add(w12, current_input_offset(), Operand(cp_offset * char_size()));
1349 __ Cmp(w12, string_start_minus_one());
1350 BranchOrBacktrack(le, on_outside_input);
1351 }
1352 } 1308 }
1353 1309
1354 1310
1355 bool RegExpMacroAssemblerARM64::CanReadUnaligned() { 1311 bool RegExpMacroAssemblerARM64::CanReadUnaligned() {
1356 // TODO(pielan): See whether or not we should disable unaligned accesses. 1312 // TODO(pielan): See whether or not we should disable unaligned accesses.
1357 return !slow_safe(); 1313 return !slow_safe();
1358 } 1314 }
1359 1315
1360 1316
1361 // Private methods: 1317 // Private methods:
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 } 1606 }
1651 } 1607 }
1652 } 1608 }
1653 1609
1654 #endif // V8_INTERPRETED_REGEXP 1610 #endif // V8_INTERPRETED_REGEXP
1655 1611
1656 } // namespace internal 1612 } // namespace internal
1657 } // namespace v8 1613 } // namespace v8
1658 1614
1659 #endif // V8_TARGET_ARCH_ARM64 1615 #endif // V8_TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « src/regexp/arm64/regexp-macro-assembler-arm64.h ('k') | src/regexp/bytecodes-irregexp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698