OLD | NEW |
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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/cpu-profiler.h" | 10 #include "src/cpu-profiler.h" |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 Register characters_address = x11; | 253 Register characters_address = x11; |
254 | 254 |
255 __ Add(characters_address, | 255 __ Add(characters_address, |
256 input_end(), | 256 input_end(), |
257 Operand(current_input_offset(), SXTW)); | 257 Operand(current_input_offset(), SXTW)); |
258 if (cp_offset != 0) { | 258 if (cp_offset != 0) { |
259 __ Add(characters_address, characters_address, cp_offset * char_size()); | 259 __ Add(characters_address, characters_address, cp_offset * char_size()); |
260 } | 260 } |
261 | 261 |
262 for (int i = 0; i < str.length(); i++) { | 262 for (int i = 0; i < str.length(); i++) { |
263 if (mode_ == ASCII) { | 263 if (mode_ == LATIN1) { |
264 __ Ldrb(w10, MemOperand(characters_address, 1, PostIndex)); | 264 __ Ldrb(w10, MemOperand(characters_address, 1, PostIndex)); |
265 DCHECK(str[i] <= String::kMaxOneByteCharCode); | 265 DCHECK(str[i] <= String::kMaxOneByteCharCode); |
266 } else { | 266 } else { |
267 __ Ldrh(w10, MemOperand(characters_address, 2, PostIndex)); | 267 __ Ldrh(w10, MemOperand(characters_address, 2, PostIndex)); |
268 } | 268 } |
269 CompareAndBranchOrBacktrack(w10, str[i], ne, on_failure); | 269 CompareAndBranchOrBacktrack(w10, str[i], ne, on_failure); |
270 } | 270 } |
271 } | 271 } |
272 | 272 |
273 | 273 |
(...skipping 26 matching lines...) Expand all Loading... |
300 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10)); | 300 __ Ldp(w11, capture_start_offset, capture_location(start_reg, x10)); |
301 } | 301 } |
302 __ Sub(capture_length, w11, capture_start_offset); // Length to check. | 302 __ Sub(capture_length, w11, capture_start_offset); // Length to check. |
303 // Succeed on empty capture (including no capture). | 303 // Succeed on empty capture (including no capture). |
304 __ Cbz(capture_length, &fallthrough); | 304 __ Cbz(capture_length, &fallthrough); |
305 | 305 |
306 // Check that there are enough characters left in the input. | 306 // Check that there are enough characters left in the input. |
307 __ Cmn(capture_length, current_input_offset()); | 307 __ Cmn(capture_length, current_input_offset()); |
308 BranchOrBacktrack(gt, on_no_match); | 308 BranchOrBacktrack(gt, on_no_match); |
309 | 309 |
310 if (mode_ == ASCII) { | 310 if (mode_ == LATIN1) { |
311 Label success; | 311 Label success; |
312 Label fail; | 312 Label fail; |
313 Label loop_check; | 313 Label loop_check; |
314 | 314 |
315 Register capture_start_address = x12; | 315 Register capture_start_address = x12; |
316 Register capture_end_addresss = x13; | 316 Register capture_end_addresss = x13; |
317 Register current_position_address = x14; | 317 Register current_position_address = x14; |
318 | 318 |
319 __ Add(capture_start_address, | 319 __ Add(capture_start_address, |
320 input_end(), | 320 input_end(), |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 __ Add(capture_start_address, input_end(), Operand(w10, SXTW)); | 440 __ Add(capture_start_address, input_end(), Operand(w10, SXTW)); |
441 __ Add(capture_end_address, | 441 __ Add(capture_end_address, |
442 capture_start_address, | 442 capture_start_address, |
443 Operand(capture_length, SXTW)); | 443 Operand(capture_length, SXTW)); |
444 __ Add(current_position_address, | 444 __ Add(current_position_address, |
445 input_end(), | 445 input_end(), |
446 Operand(current_input_offset(), SXTW)); | 446 Operand(current_input_offset(), SXTW)); |
447 | 447 |
448 Label loop; | 448 Label loop; |
449 __ Bind(&loop); | 449 __ Bind(&loop); |
450 if (mode_ == ASCII) { | 450 if (mode_ == LATIN1) { |
451 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); | 451 __ Ldrb(w10, MemOperand(capture_start_address, 1, PostIndex)); |
452 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); | 452 __ Ldrb(w11, MemOperand(current_position_address, 1, PostIndex)); |
453 } else { | 453 } else { |
454 DCHECK(mode_ == UC16); | 454 DCHECK(mode_ == UC16); |
455 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex)); | 455 __ Ldrh(w10, MemOperand(capture_start_address, 2, PostIndex)); |
456 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex)); | 456 __ Ldrh(w11, MemOperand(current_position_address, 2, PostIndex)); |
457 } | 457 } |
458 __ Cmp(w10, w11); | 458 __ Cmp(w10, w11); |
459 BranchOrBacktrack(ne, on_no_match); | 459 BranchOrBacktrack(ne, on_no_match); |
460 __ Cmp(capture_start_address, capture_end_address); | 460 __ Cmp(capture_start_address, capture_end_address); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 __ Sub(w10, current_character(), from); | 523 __ Sub(w10, current_character(), from); |
524 // Unsigned higher condition. | 524 // Unsigned higher condition. |
525 CompareAndBranchOrBacktrack(w10, to - from, hi, on_not_in_range); | 525 CompareAndBranchOrBacktrack(w10, to - from, hi, on_not_in_range); |
526 } | 526 } |
527 | 527 |
528 | 528 |
529 void RegExpMacroAssemblerARM64::CheckBitInTable( | 529 void RegExpMacroAssemblerARM64::CheckBitInTable( |
530 Handle<ByteArray> table, | 530 Handle<ByteArray> table, |
531 Label* on_bit_set) { | 531 Label* on_bit_set) { |
532 __ Mov(x11, Operand(table)); | 532 __ Mov(x11, Operand(table)); |
533 if ((mode_ != ASCII) || (kTableMask != String::kMaxOneByteCharCode)) { | 533 if ((mode_ != LATIN1) || (kTableMask != String::kMaxOneByteCharCode)) { |
534 __ And(w10, current_character(), kTableMask); | 534 __ And(w10, current_character(), kTableMask); |
535 __ Add(w10, w10, ByteArray::kHeaderSize - kHeapObjectTag); | 535 __ Add(w10, w10, ByteArray::kHeaderSize - kHeapObjectTag); |
536 } else { | 536 } else { |
537 __ Add(w10, current_character(), ByteArray::kHeaderSize - kHeapObjectTag); | 537 __ Add(w10, current_character(), ByteArray::kHeaderSize - kHeapObjectTag); |
538 } | 538 } |
539 __ Ldrb(w11, MemOperand(x11, w10, UXTW)); | 539 __ Ldrb(w11, MemOperand(x11, w10, UXTW)); |
540 CompareAndBranchOrBacktrack(w11, 0, ne, on_bit_set); | 540 CompareAndBranchOrBacktrack(w11, 0, ne, on_bit_set); |
541 } | 541 } |
542 | 542 |
543 | 543 |
544 bool RegExpMacroAssemblerARM64::CheckSpecialCharacterClass(uc16 type, | 544 bool RegExpMacroAssemblerARM64::CheckSpecialCharacterClass(uc16 type, |
545 Label* on_no_match) { | 545 Label* on_no_match) { |
546 // Range checks (c in min..max) are generally implemented by an unsigned | 546 // Range checks (c in min..max) are generally implemented by an unsigned |
547 // (c - min) <= (max - min) check | 547 // (c - min) <= (max - min) check |
548 switch (type) { | 548 switch (type) { |
549 case 's': | 549 case 's': |
550 // Match space-characters | 550 // Match space-characters |
551 if (mode_ == ASCII) { | 551 if (mode_ == LATIN1) { |
552 // One byte space characters are '\t'..'\r', ' ' and \u00a0. | 552 // One byte space characters are '\t'..'\r', ' ' and \u00a0. |
553 Label success; | 553 Label success; |
554 // Check for ' ' or 0x00a0. | 554 // Check for ' ' or 0x00a0. |
555 __ Cmp(current_character(), ' '); | 555 __ Cmp(current_character(), ' '); |
556 __ Ccmp(current_character(), 0x00a0, ZFlag, ne); | 556 __ Ccmp(current_character(), 0x00a0, ZFlag, ne); |
557 __ B(eq, &success); | 557 __ B(eq, &success); |
558 // Check range 0x09..0x0d. | 558 // Check range 0x09..0x0d. |
559 __ Sub(w10, current_character(), '\t'); | 559 __ Sub(w10, current_character(), '\t'); |
560 CompareAndBranchOrBacktrack(w10, '\r' - '\t', hi, on_no_match); | 560 CompareAndBranchOrBacktrack(w10, '\r' - '\t', hi, on_no_match); |
561 __ Bind(&success); | 561 __ Bind(&success); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 // If the Z flag was set we clear the flags to force a fall-through. | 604 // If the Z flag was set we clear the flags to force a fall-through. |
605 __ Ccmp(w10, 0x2029 - 0x2028, NoFlag, ne); | 605 __ Ccmp(w10, 0x2029 - 0x2028, NoFlag, ne); |
606 // hi -> (C==1) && (Z==0) | 606 // hi -> (C==1) && (Z==0) |
607 BranchOrBacktrack(hi, on_no_match); | 607 BranchOrBacktrack(hi, on_no_match); |
608 } else { | 608 } else { |
609 BranchOrBacktrack(ne, on_no_match); | 609 BranchOrBacktrack(ne, on_no_match); |
610 } | 610 } |
611 return true; | 611 return true; |
612 } | 612 } |
613 case 'w': { | 613 case 'w': { |
614 if (mode_ != ASCII) { | 614 if (mode_ != LATIN1) { |
615 // Table is 128 entries, so all ASCII characters can be tested. | 615 // Table is 256 entries, so all Latin1 characters can be tested. |
616 CompareAndBranchOrBacktrack(current_character(), 'z', hi, on_no_match); | 616 CompareAndBranchOrBacktrack(current_character(), 'z', hi, on_no_match); |
617 } | 617 } |
618 ExternalReference map = ExternalReference::re_word_character_map(); | 618 ExternalReference map = ExternalReference::re_word_character_map(); |
619 __ Mov(x10, map); | 619 __ Mov(x10, map); |
620 __ Ldrb(w10, MemOperand(x10, current_character(), UXTW)); | 620 __ Ldrb(w10, MemOperand(x10, current_character(), UXTW)); |
621 CompareAndBranchOrBacktrack(w10, 0, eq, on_no_match); | 621 CompareAndBranchOrBacktrack(w10, 0, eq, on_no_match); |
622 return true; | 622 return true; |
623 } | 623 } |
624 case 'W': { | 624 case 'W': { |
625 Label done; | 625 Label done; |
626 if (mode_ != ASCII) { | 626 if (mode_ != LATIN1) { |
627 // Table is 128 entries, so all ASCII characters can be tested. | 627 // Table is 256 entries, so all Latin1 characters can be tested. |
628 __ Cmp(current_character(), 'z'); | 628 __ Cmp(current_character(), 'z'); |
629 __ B(hi, &done); | 629 __ B(hi, &done); |
630 } | 630 } |
631 ExternalReference map = ExternalReference::re_word_character_map(); | 631 ExternalReference map = ExternalReference::re_word_character_map(); |
632 __ Mov(x10, map); | 632 __ Mov(x10, map); |
633 __ Ldrb(w10, MemOperand(x10, current_character(), UXTW)); | 633 __ Ldrb(w10, MemOperand(x10, current_character(), UXTW)); |
634 CompareAndBranchOrBacktrack(w10, 0, ne, on_no_match); | 634 CompareAndBranchOrBacktrack(w10, 0, ne, on_no_match); |
635 __ Bind(&done); | 635 __ Bind(&done); |
636 return true; | 636 return true; |
637 } | 637 } |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 return RETRY; | 1308 return RETRY; |
1309 } | 1309 } |
1310 | 1310 |
1311 // Prepare for possible GC. | 1311 // Prepare for possible GC. |
1312 HandleScope handles(isolate); | 1312 HandleScope handles(isolate); |
1313 Handle<Code> code_handle(re_code); | 1313 Handle<Code> code_handle(re_code); |
1314 | 1314 |
1315 Handle<String> subject(frame_entry<String*>(re_frame, kInput)); | 1315 Handle<String> subject(frame_entry<String*>(re_frame, kInput)); |
1316 | 1316 |
1317 // Current string. | 1317 // Current string. |
1318 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); | 1318 bool is_one_byte = subject->IsOneByteRepresentationUnderneath(); |
1319 | 1319 |
1320 DCHECK(re_code->instruction_start() <= *return_address); | 1320 DCHECK(re_code->instruction_start() <= *return_address); |
1321 DCHECK(*return_address <= | 1321 DCHECK(*return_address <= |
1322 re_code->instruction_start() + re_code->instruction_size()); | 1322 re_code->instruction_start() + re_code->instruction_size()); |
1323 | 1323 |
1324 Object* result = isolate->stack_guard()->HandleInterrupts(); | 1324 Object* result = isolate->stack_guard()->HandleInterrupts(); |
1325 | 1325 |
1326 if (*code_handle != re_code) { // Return address no longer valid | 1326 if (*code_handle != re_code) { // Return address no longer valid |
1327 int delta = code_handle->address() - re_code->address(); | 1327 int delta = code_handle->address() - re_code->address(); |
1328 // Overwrite the return address on the stack. | 1328 // Overwrite the return address on the stack. |
(...skipping 10 matching lines...) Expand all Loading... |
1339 // Extract the underlying string and the slice offset. | 1339 // Extract the underlying string and the slice offset. |
1340 if (StringShape(*subject_tmp).IsCons()) { | 1340 if (StringShape(*subject_tmp).IsCons()) { |
1341 subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first()); | 1341 subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first()); |
1342 } else if (StringShape(*subject_tmp).IsSliced()) { | 1342 } else if (StringShape(*subject_tmp).IsSliced()) { |
1343 SlicedString* slice = SlicedString::cast(*subject_tmp); | 1343 SlicedString* slice = SlicedString::cast(*subject_tmp); |
1344 subject_tmp = Handle<String>(slice->parent()); | 1344 subject_tmp = Handle<String>(slice->parent()); |
1345 slice_offset = slice->offset(); | 1345 slice_offset = slice->offset(); |
1346 } | 1346 } |
1347 | 1347 |
1348 // String might have changed. | 1348 // String might have changed. |
1349 if (subject_tmp->IsOneByteRepresentation() != is_ascii) { | 1349 if (subject_tmp->IsOneByteRepresentation() != is_one_byte) { |
1350 // If we changed between an ASCII and an UC16 string, the specialized | 1350 // If we changed between an Latin1 and an UC16 string, the specialized |
1351 // code cannot be used, and we need to restart regexp matching from | 1351 // code cannot be used, and we need to restart regexp matching from |
1352 // scratch (including, potentially, compiling a new version of the code). | 1352 // scratch (including, potentially, compiling a new version of the code). |
1353 return RETRY; | 1353 return RETRY; |
1354 } | 1354 } |
1355 | 1355 |
1356 // Otherwise, the content of the string might have moved. It must still | 1356 // Otherwise, the content of the string might have moved. It must still |
1357 // be a sequential or external string with the same content. | 1357 // be a sequential or external string with the same content. |
1358 // Update the start and end pointers in the stack frame to the current | 1358 // Update the start and end pointers in the stack frame to the current |
1359 // location (whether it has actually moved or not). | 1359 // location (whether it has actually moved or not). |
1360 DCHECK(StringShape(*subject_tmp).IsSequential() || | 1360 DCHECK(StringShape(*subject_tmp).IsSequential() || |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1668 __ Add(x10, x10, Operand(current_input_offset(), SXTW)); | 1668 __ Add(x10, x10, Operand(current_input_offset(), SXTW)); |
1669 __ Cmp(x10, Operand(w10, SXTW)); | 1669 __ Cmp(x10, Operand(w10, SXTW)); |
1670 // The offset needs to fit in a W register. | 1670 // The offset needs to fit in a W register. |
1671 __ Check(eq, kOffsetOutOfRange); | 1671 __ Check(eq, kOffsetOutOfRange); |
1672 } else { | 1672 } else { |
1673 __ Add(w10, current_input_offset(), cp_offset * char_size()); | 1673 __ Add(w10, current_input_offset(), cp_offset * char_size()); |
1674 } | 1674 } |
1675 offset = w10; | 1675 offset = w10; |
1676 } | 1676 } |
1677 | 1677 |
1678 if (mode_ == ASCII) { | 1678 if (mode_ == LATIN1) { |
1679 if (characters == 4) { | 1679 if (characters == 4) { |
1680 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW)); | 1680 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW)); |
1681 } else if (characters == 2) { | 1681 } else if (characters == 2) { |
1682 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW)); | 1682 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW)); |
1683 } else { | 1683 } else { |
1684 DCHECK(characters == 1); | 1684 DCHECK(characters == 1); |
1685 __ Ldrb(current_character(), MemOperand(input_end(), offset, SXTW)); | 1685 __ Ldrb(current_character(), MemOperand(input_end(), offset, SXTW)); |
1686 } | 1686 } |
1687 } else { | 1687 } else { |
1688 DCHECK(mode_ == UC16); | 1688 DCHECK(mode_ == UC16); |
1689 if (characters == 2) { | 1689 if (characters == 2) { |
1690 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW)); | 1690 __ Ldr(current_character(), MemOperand(input_end(), offset, SXTW)); |
1691 } else { | 1691 } else { |
1692 DCHECK(characters == 1); | 1692 DCHECK(characters == 1); |
1693 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW)); | 1693 __ Ldrh(current_character(), MemOperand(input_end(), offset, SXTW)); |
1694 } | 1694 } |
1695 } | 1695 } |
1696 } | 1696 } |
1697 | 1697 |
1698 #endif // V8_INTERPRETED_REGEXP | 1698 #endif // V8_INTERPRETED_REGEXP |
1699 | 1699 |
1700 }} // namespace v8::internal | 1700 }} // namespace v8::internal |
1701 | 1701 |
1702 #endif // V8_TARGET_ARCH_ARM64 | 1702 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |