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

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: addressed comments 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
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 // The length of the capture can only be negative if the end of the
296 // capture is not yet recorded. If the length is zero, the capture is
297 // either empty or uncaptured. In either of those cases, succeed.
298 __ CompareAndBranch(capture_length, Operand(0), le, &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 __ Sub(w12, current_input_offset(), capture_length);
303 __ Cmp(w12, string_start_minus_one());
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 19 matching lines...) Expand all
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());
358 if (masm_->emit_debug_code()) { 366 if (masm_->emit_debug_code()) {
359 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); 367 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
360 __ Ccmp(current_input_offset(), 0, NoFlag, eq); 368 __ Ccmp(current_input_offset(), 0, NoFlag, eq);
361 // The current input offset should be <= 0, and fit in a W register. 369 // The current input offset should be <= 0, and fit in a W register.
362 __ Check(le, kOffsetOutOfRange); 370 __ Check(le, kOffsetOutOfRange);
363 } 371 }
372 if (read_backward) {
373 __ Sub(current_input_offset(), current_input_offset(),
374 Operand(capture_length, SXTW));
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 // The length of the capture can only be negative if the end of the
430 __ Cbz(capture_length, &fallthrough); 449 // capture is not yet recorded. If the length is zero, the capture is
450 // either empty or uncaptured. In either of those cases, succeed.
451 __ CompareAndBranch(capture_length, Operand(0), le, &fallthrough);
431 452
432 // Check that there are enough characters left in the input. 453 // Check that there are enough characters left in the input.
433 __ Cmn(capture_length, current_input_offset()); 454 if (read_backward) {
434 BranchOrBacktrack(gt, on_no_match); 455 __ Sub(w12, current_input_offset(), capture_length);
456 __ Cmp(w12, string_start_minus_one());
457 BranchOrBacktrack(le, on_no_match);
458 } else {
459 __ Cmn(capture_length, current_input_offset());
460 BranchOrBacktrack(gt, on_no_match);
461 }
435 462
436 // Compute pointers to match string and capture string 463 // Compute pointers to match string and capture string
437 __ Add(capture_start_address, input_end(), Operand(w10, SXTW)); 464 __ Add(capture_start_address, input_end(), Operand(w10, SXTW));
438 __ Add(capture_end_address, 465 __ Add(capture_end_address,
439 capture_start_address, 466 capture_start_address,
440 Operand(capture_length, SXTW)); 467 Operand(capture_length, SXTW));
441 __ Add(current_position_address, 468 __ Add(current_position_address,
442 input_end(), 469 input_end(),
443 Operand(current_input_offset(), SXTW)); 470 Operand(current_input_offset(), SXTW));
471 if (read_backward) {
472 // Offset by length when matching backwards.
473 __ Sub(current_position_address, current_position_address,
474 Operand(capture_length, SXTW));
475 }
444 476
445 Label loop; 477 Label loop;
446 __ Bind(&loop); 478 __ Bind(&loop);
447 if (mode_ == LATIN1) { 479 if (mode_ == LATIN1) {
448 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); 480 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex));
449 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); 481 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex));
450 } else { 482 } else {
451 DCHECK(mode_ == UC16); 483 DCHECK(mode_ == UC16);
452 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex)); 484 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex));
453 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex)); 485 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex));
454 } 486 }
455 __ Cmp(w10, w11); 487 __ Cmp(w10, w11);
456 BranchOrBacktrack(ne, on_no_match); 488 BranchOrBacktrack(ne, on_no_match);
457 __ Cmp(capture_start_address, capture_end_address); 489 __ Cmp(capture_start_address, capture_end_address);
458 __ B(lt, &loop); 490 __ B(lt, &loop);
459 491
460 // Move current character position to position after match. 492 // Move current character position to position after match.
461 __ Sub(current_input_offset().X(), current_position_address, input_end()); 493 __ Sub(current_input_offset().X(), current_position_address, input_end());
494 if (read_backward) {
495 __ Sub(current_input_offset(), current_input_offset(),
496 Operand(capture_length, SXTW));
497 }
498
462 if (masm_->emit_debug_code()) { 499 if (masm_->emit_debug_code()) {
463 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW)); 500 __ Cmp(current_input_offset().X(), Operand(current_input_offset(), SXTW));
464 __ Ccmp(current_input_offset(), 0, NoFlag, eq); 501 __ Ccmp(current_input_offset(), 0, NoFlag, eq);
465 // The current input offset should be <= 0, and fit in a W register. 502 // The current input offset should be <= 0, and fit in a W register.
466 __ Check(le, kOffsetOutOfRange); 503 __ Check(le, kOffsetOutOfRange);
467 } 504 }
468 __ Bind(&fallthrough); 505 __ Bind(&fallthrough);
469 } 506 }
470 507
471 508
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 // Check that the input string length is < 2^30. 788 // Check that the input string length is < 2^30.
752 __ Neg(x11, x10); 789 __ Neg(x11, x10);
753 __ Cmp(x11, (1<<30) - 1); 790 __ Cmp(x11, (1<<30) - 1);
754 __ Check(ls, kInputStringTooLong); 791 __ Check(ls, kInputStringTooLong);
755 } 792 }
756 __ Mov(current_input_offset(), w10); 793 __ Mov(current_input_offset(), w10);
757 794
758 // The non-position value is used as a clearing value for the 795 // The non-position value is used as a clearing value for the
759 // capture registers, it corresponds to the position of the first character 796 // capture registers, it corresponds to the position of the first character
760 // minus one. 797 // minus one.
761 __ Sub(non_position_value(), current_input_offset(), char_size()); 798 __ Sub(string_start_minus_one(), current_input_offset(), char_size());
762 __ Sub(non_position_value(), non_position_value(), 799 __ Sub(string_start_minus_one(), string_start_minus_one(),
763 Operand(start_offset(), LSL, (mode_ == UC16) ? 1 : 0)); 800 Operand(start_offset(), LSL, (mode_ == UC16) ? 1 : 0));
764 // We can store this value twice in an X register for initializing 801 // We can store this value twice in an X register for initializing
765 // on-stack registers later. 802 // on-stack registers later.
766 __ Orr(twice_non_position_value(), 803 __ Orr(twice_non_position_value(), string_start_minus_one().X(),
767 non_position_value().X(), 804 Operand(string_start_minus_one().X(), LSL, kWRegSizeInBits));
768 Operand(non_position_value().X(), LSL, kWRegSizeInBits));
769 805
770 // Initialize code pointer register. 806 // Initialize code pointer register.
771 __ Mov(code_pointer(), Operand(masm_->CodeObject())); 807 __ Mov(code_pointer(), Operand(masm_->CodeObject()));
772 808
773 Label load_char_start_regexp, start_regexp; 809 Label load_char_start_regexp, start_regexp;
774 // Load newline if index is at start, previous character otherwise. 810 // Load newline if index is at start, previous character otherwise.
775 __ Cbnz(start_offset(), &load_char_start_regexp); 811 __ Cbnz(start_offset(), &load_char_start_regexp);
776 __ Mov(current_character(), '\n'); 812 __ Mov(current_character(), '\n');
777 __ B(&start_regexp); 813 __ B(&start_regexp);
778 814
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 return kARM64Implementation; 1110 return kARM64Implementation;
1075 } 1111 }
1076 1112
1077 1113
1078 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset, 1114 void RegExpMacroAssemblerARM64::LoadCurrentCharacter(int cp_offset,
1079 Label* on_end_of_input, 1115 Label* on_end_of_input,
1080 bool check_bounds, 1116 bool check_bounds,
1081 int characters) { 1117 int characters) {
1082 // TODO(pielan): Make sure long strings are caught before this, and not 1118 // TODO(pielan): Make sure long strings are caught before this, and not
1083 // just asserted in debug mode. 1119 // 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) 1120 // Be sane! (And ensure that an int32_t can be used to index the string)
1086 DCHECK(cp_offset < (1<<30)); 1121 DCHECK(cp_offset < (1<<30));
1087 if (check_bounds) { 1122 if (check_bounds) {
1088 CheckPosition(cp_offset + characters - 1, on_end_of_input); 1123 if (cp_offset >= 0) {
1124 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1125 } else {
1126 CheckPosition(cp_offset, on_end_of_input);
1127 }
1089 } 1128 }
1090 LoadCurrentCharacterUnchecked(cp_offset, characters); 1129 LoadCurrentCharacterUnchecked(cp_offset, characters);
1091 } 1130 }
1092 1131
1093 1132
1094 void RegExpMacroAssemblerARM64::PopCurrentPosition() { 1133 void RegExpMacroAssemblerARM64::PopCurrentPosition() {
1095 Pop(current_input_offset()); 1134 Pop(current_input_offset());
1096 } 1135 }
1097 1136
1098 1137
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 } 1242 }
1204 1243
1205 1244
1206 void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) { 1245 void RegExpMacroAssemblerARM64::ClearRegisters(int reg_from, int reg_to) {
1207 DCHECK(reg_from <= reg_to); 1246 DCHECK(reg_from <= reg_to);
1208 int num_registers = reg_to - reg_from + 1; 1247 int num_registers = reg_to - reg_from + 1;
1209 1248
1210 // If the first capture register is cached in a hardware register but not 1249 // 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. 1250 // aligned on a 64-bit one, we need to clear the first one specifically.
1212 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) { 1251 if ((reg_from < kNumCachedRegisters) && ((reg_from % 2) != 0)) {
1213 StoreRegister(reg_from, non_position_value()); 1252 StoreRegister(reg_from, string_start_minus_one());
1214 num_registers--; 1253 num_registers--;
1215 reg_from++; 1254 reg_from++;
1216 } 1255 }
1217 1256
1218 // Clear cached registers in pairs as far as possible. 1257 // Clear cached registers in pairs as far as possible.
1219 while ((num_registers >= 2) && (reg_from < kNumCachedRegisters)) { 1258 while ((num_registers >= 2) && (reg_from < kNumCachedRegisters)) {
1220 DCHECK(GetRegisterState(reg_from) == CACHED_LSW); 1259 DCHECK(GetRegisterState(reg_from) == CACHED_LSW);
1221 __ Mov(GetCachedRegister(reg_from), twice_non_position_value()); 1260 __ Mov(GetCachedRegister(reg_from), twice_non_position_value());
1222 reg_from += 2; 1261 reg_from += 2;
1223 num_registers -= 2; 1262 num_registers -= 2;
1224 } 1263 }
1225 1264
1226 if ((num_registers % 2) == 1) { 1265 if ((num_registers % 2) == 1) {
1227 StoreRegister(reg_from, non_position_value()); 1266 StoreRegister(reg_from, string_start_minus_one());
1228 num_registers--; 1267 num_registers--;
1229 reg_from++; 1268 reg_from++;
1230 } 1269 }
1231 1270
1232 if (num_registers > 0) { 1271 if (num_registers > 0) {
1233 // If there are some remaining registers, they are stored on the stack. 1272 // If there are some remaining registers, they are stored on the stack.
1234 DCHECK(reg_from >= kNumCachedRegisters); 1273 DCHECK(reg_from >= kNumCachedRegisters);
1235 1274
1236 // Move down the indexes of the registers on stack to get the correct offset 1275 // Move down the indexes of the registers on stack to get the correct offset
1237 // in memory. 1276 // in memory.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 const byte** input_start, const byte** input_end) { 1333 const byte** input_start, const byte** input_end) {
1295 return NativeRegExpMacroAssembler::CheckStackGuardState( 1334 return NativeRegExpMacroAssembler::CheckStackGuardState(
1296 frame_entry<Isolate*>(re_frame, kIsolate), start_index, 1335 frame_entry<Isolate*>(re_frame, kIsolate), start_index,
1297 frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code, 1336 frame_entry<int>(re_frame, kDirectCall) == 1, return_address, re_code,
1298 frame_entry_address<String*>(re_frame, kInput), input_start, input_end); 1337 frame_entry_address<String*>(re_frame, kInput), input_start, input_end);
1299 } 1338 }
1300 1339
1301 1340
1302 void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset, 1341 void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset,
1303 Label* on_outside_input) { 1342 Label* on_outside_input) {
1304 CompareAndBranchOrBacktrack(current_input_offset(), 1343 if (cp_offset >= 0) {
1305 -cp_offset * char_size(), 1344 CompareAndBranchOrBacktrack(current_input_offset(),
1306 ge, 1345 -cp_offset * char_size(), ge, on_outside_input);
1307 on_outside_input); 1346 } else {
1347 __ Add(w12, current_input_offset(), Operand(cp_offset * char_size()));
1348 __ Cmp(w12, string_start_minus_one());
1349 BranchOrBacktrack(le, on_outside_input);
1350 }
1308 } 1351 }
1309 1352
1310 1353
1311 bool RegExpMacroAssemblerARM64::CanReadUnaligned() { 1354 bool RegExpMacroAssemblerARM64::CanReadUnaligned() {
1312 // TODO(pielan): See whether or not we should disable unaligned accesses. 1355 // TODO(pielan): See whether or not we should disable unaligned accesses.
1313 return !slow_safe(); 1356 return !slow_safe();
1314 } 1357 }
1315 1358
1316 1359
1317 // Private methods: 1360 // Private methods:
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1606 } 1649 }
1607 } 1650 }
1608 } 1651 }
1609 1652
1610 #endif // V8_INTERPRETED_REGEXP 1653 #endif // V8_INTERPRETED_REGEXP
1611 1654
1612 } // namespace internal 1655 } // namespace internal
1613 } // namespace v8 1656 } // namespace v8
1614 1657
1615 #endif // V8_TARGET_ARCH_ARM64 1658 #endif // V8_TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698