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

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

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