| 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 |