OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 if (by != 0) { | 159 if (by != 0) { |
160 __ addq(rdi, Immediate(by * char_size())); | 160 __ addq(rdi, Immediate(by * char_size())); |
161 } | 161 } |
162 } | 162 } |
163 | 163 |
164 | 164 |
165 void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) { | 165 void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) { |
166 ASSERT(reg >= 0); | 166 ASSERT(reg >= 0); |
167 ASSERT(reg < num_registers_); | 167 ASSERT(reg < num_registers_); |
168 if (by != 0) { | 168 if (by != 0) { |
169 __ addq(register_location(reg), Immediate(by)); | 169 __ addp(register_location(reg), Immediate(by)); |
170 } | 170 } |
171 } | 171 } |
172 | 172 |
173 | 173 |
174 void RegExpMacroAssemblerX64::Backtrack() { | 174 void RegExpMacroAssemblerX64::Backtrack() { |
175 CheckPreemption(); | 175 CheckPreemption(); |
176 // Pop Code* offset from backtrack stack, add Code* and jump to location. | 176 // Pop Code* offset from backtrack stack, add Code* and jump to location. |
177 Pop(rbx); | 177 Pop(rbx); |
178 __ addq(rbx, code_object_pointer()); | 178 __ addp(rbx, code_object_pointer()); |
179 __ jmp(rbx); | 179 __ jmp(rbx); |
180 } | 180 } |
181 | 181 |
182 | 182 |
183 void RegExpMacroAssemblerX64::Bind(Label* label) { | 183 void RegExpMacroAssemblerX64::Bind(Label* label) { |
184 __ bind(label); | 184 __ bind(label); |
185 } | 185 } |
186 | 186 |
187 | 187 |
188 void RegExpMacroAssemblerX64::CheckCharacter(uint32_t c, Label* on_equal) { | 188 void RegExpMacroAssemblerX64::CheckCharacter(uint32_t c, Label* on_equal) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 __ bind(&fallthrough); | 236 __ bind(&fallthrough); |
237 } | 237 } |
238 | 238 |
239 | 239 |
240 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( | 240 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( |
241 int start_reg, | 241 int start_reg, |
242 Label* on_no_match) { | 242 Label* on_no_match) { |
243 Label fallthrough; | 243 Label fallthrough; |
244 __ movq(rdx, register_location(start_reg)); // Offset of start of capture | 244 __ movq(rdx, register_location(start_reg)); // Offset of start of capture |
245 __ movq(rbx, register_location(start_reg + 1)); // Offset of end of capture | 245 __ movq(rbx, register_location(start_reg + 1)); // Offset of end of capture |
246 __ subq(rbx, rdx); // Length of capture. | 246 __ subp(rbx, rdx); // Length of capture. |
247 | 247 |
248 // ----------------------- | 248 // ----------------------- |
249 // rdx = Start offset of capture. | 249 // rdx = Start offset of capture. |
250 // rbx = Length of capture | 250 // rbx = Length of capture |
251 | 251 |
252 // If length is negative, this code will fail (it's a symptom of a partial or | 252 // If length is negative, this code will fail (it's a symptom of a partial or |
253 // illegal capture where start of capture after end of capture). | 253 // illegal capture where start of capture after end of capture). |
254 // This must not happen (no back-reference can reference a capture that wasn't | 254 // This must not happen (no back-reference can reference a capture that wasn't |
255 // closed before in the reg-exp, and we must not generate code that can cause | 255 // closed before in the reg-exp, and we must not generate code that can cause |
256 // this condition). | 256 // this condition). |
(...skipping 11 matching lines...) Expand all Loading... |
268 BranchOrBacktrack(greater, on_no_match); | 268 BranchOrBacktrack(greater, on_no_match); |
269 | 269 |
270 if (mode_ == ASCII) { | 270 if (mode_ == ASCII) { |
271 Label loop_increment; | 271 Label loop_increment; |
272 if (on_no_match == NULL) { | 272 if (on_no_match == NULL) { |
273 on_no_match = &backtrack_label_; | 273 on_no_match = &backtrack_label_; |
274 } | 274 } |
275 | 275 |
276 __ lea(r9, Operand(rsi, rdx, times_1, 0)); | 276 __ lea(r9, Operand(rsi, rdx, times_1, 0)); |
277 __ lea(r11, Operand(rsi, rdi, times_1, 0)); | 277 __ lea(r11, Operand(rsi, rdi, times_1, 0)); |
278 __ addq(rbx, r9); // End of capture | 278 __ addp(rbx, r9); // End of capture |
279 // --------------------- | 279 // --------------------- |
280 // r11 - current input character address | 280 // r11 - current input character address |
281 // r9 - current capture character address | 281 // r9 - current capture character address |
282 // rbx - end of capture | 282 // rbx - end of capture |
283 | 283 |
284 Label loop; | 284 Label loop; |
285 __ bind(&loop); | 285 __ bind(&loop); |
286 __ movzxbl(rdx, Operand(r9, 0)); | 286 __ movzxbl(rdx, Operand(r9, 0)); |
287 __ movzxbl(rax, Operand(r11, 0)); | 287 __ movzxbl(rax, Operand(r11, 0)); |
288 // al - input character | 288 // al - input character |
(...skipping 12 matching lines...) Expand all Loading... |
301 __ cmpb(rax, Immediate('z' - 'a')); | 301 __ cmpb(rax, Immediate('z' - 'a')); |
302 __ j(below_equal, &loop_increment); // In range 'a'-'z'. | 302 __ j(below_equal, &loop_increment); // In range 'a'-'z'. |
303 // Latin-1: Check for values in range [224,254] but not 247. | 303 // Latin-1: Check for values in range [224,254] but not 247. |
304 __ subb(rax, Immediate(224 - 'a')); | 304 __ subb(rax, Immediate(224 - 'a')); |
305 __ cmpb(rax, Immediate(254 - 224)); | 305 __ cmpb(rax, Immediate(254 - 224)); |
306 __ j(above, on_no_match); // Weren't Latin-1 letters. | 306 __ j(above, on_no_match); // Weren't Latin-1 letters. |
307 __ cmpb(rax, Immediate(247 - 224)); // Check for 247. | 307 __ cmpb(rax, Immediate(247 - 224)); // Check for 247. |
308 __ j(equal, on_no_match); | 308 __ j(equal, on_no_match); |
309 __ bind(&loop_increment); | 309 __ bind(&loop_increment); |
310 // Increment pointers into match and capture strings. | 310 // Increment pointers into match and capture strings. |
311 __ addq(r11, Immediate(1)); | 311 __ addp(r11, Immediate(1)); |
312 __ addq(r9, Immediate(1)); | 312 __ addp(r9, Immediate(1)); |
313 // Compare to end of capture, and loop if not done. | 313 // Compare to end of capture, and loop if not done. |
314 __ cmpq(r9, rbx); | 314 __ cmpq(r9, rbx); |
315 __ j(below, &loop); | 315 __ j(below, &loop); |
316 | 316 |
317 // Compute new value of character position after the matched part. | 317 // Compute new value of character position after the matched part. |
318 __ movp(rdi, r11); | 318 __ movp(rdi, r11); |
319 __ subq(rdi, rsi); | 319 __ subq(rdi, rsi); |
320 } else { | 320 } else { |
321 ASSERT(mode_ == UC16); | 321 ASSERT(mode_ == UC16); |
322 // Save important/volatile registers before calling C function. | 322 // Save important/volatile registers before calling C function. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 | 385 |
386 | 386 |
387 void RegExpMacroAssemblerX64::CheckNotBackReference( | 387 void RegExpMacroAssemblerX64::CheckNotBackReference( |
388 int start_reg, | 388 int start_reg, |
389 Label* on_no_match) { | 389 Label* on_no_match) { |
390 Label fallthrough; | 390 Label fallthrough; |
391 | 391 |
392 // Find length of back-referenced capture. | 392 // Find length of back-referenced capture. |
393 __ movq(rdx, register_location(start_reg)); | 393 __ movq(rdx, register_location(start_reg)); |
394 __ movq(rax, register_location(start_reg + 1)); | 394 __ movq(rax, register_location(start_reg + 1)); |
395 __ subq(rax, rdx); // Length to check. | 395 __ subp(rax, rdx); // Length to check. |
396 | 396 |
397 // Fail on partial or illegal capture (start of capture after end of capture). | 397 // Fail on partial or illegal capture (start of capture after end of capture). |
398 // This must not happen (no back-reference can reference a capture that wasn't | 398 // This must not happen (no back-reference can reference a capture that wasn't |
399 // closed before in the reg-exp). | 399 // closed before in the reg-exp). |
400 __ Check(greater_equal, kInvalidCaptureReferenced); | 400 __ Check(greater_equal, kInvalidCaptureReferenced); |
401 | 401 |
402 // Succeed on empty capture (including non-participating capture) | 402 // Succeed on empty capture (including non-participating capture) |
403 __ j(equal, &fallthrough); | 403 __ j(equal, &fallthrough); |
404 | 404 |
405 // ----------------------- | 405 // ----------------------- |
406 // rdx - Start of capture | 406 // rdx - Start of capture |
407 // rax - length of capture | 407 // rax - length of capture |
408 | 408 |
409 // Check that there are sufficient characters left in the input. | 409 // Check that there are sufficient characters left in the input. |
410 __ movl(rbx, rdi); | 410 __ movl(rbx, rdi); |
411 __ addl(rbx, rax); | 411 __ addl(rbx, rax); |
412 BranchOrBacktrack(greater, on_no_match); | 412 BranchOrBacktrack(greater, on_no_match); |
413 | 413 |
414 // Compute pointers to match string and capture string | 414 // Compute pointers to match string and capture string |
415 __ lea(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match. | 415 __ lea(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match. |
416 __ addq(rdx, rsi); // Start of capture. | 416 __ addp(rdx, rsi); // Start of capture. |
417 __ lea(r9, Operand(rdx, rax, times_1, 0)); // End of capture | 417 __ lea(r9, Operand(rdx, rax, times_1, 0)); // End of capture |
418 | 418 |
419 // ----------------------- | 419 // ----------------------- |
420 // rbx - current capture character address. | 420 // rbx - current capture character address. |
421 // rbx - current input character address . | 421 // rbx - current input character address . |
422 // r9 - end of input to match (capture length after rbx). | 422 // r9 - end of input to match (capture length after rbx). |
423 | 423 |
424 Label loop; | 424 Label loop; |
425 __ bind(&loop); | 425 __ bind(&loop); |
426 if (mode_ == ASCII) { | 426 if (mode_ == ASCII) { |
427 __ movzxbl(rax, Operand(rdx, 0)); | 427 __ movzxbl(rax, Operand(rdx, 0)); |
428 __ cmpb(rax, Operand(rbx, 0)); | 428 __ cmpb(rax, Operand(rbx, 0)); |
429 } else { | 429 } else { |
430 ASSERT(mode_ == UC16); | 430 ASSERT(mode_ == UC16); |
431 __ movzxwl(rax, Operand(rdx, 0)); | 431 __ movzxwl(rax, Operand(rdx, 0)); |
432 __ cmpw(rax, Operand(rbx, 0)); | 432 __ cmpw(rax, Operand(rbx, 0)); |
433 } | 433 } |
434 BranchOrBacktrack(not_equal, on_no_match); | 434 BranchOrBacktrack(not_equal, on_no_match); |
435 // Increment pointers into capture and match string. | 435 // Increment pointers into capture and match string. |
436 __ addq(rbx, Immediate(char_size())); | 436 __ addp(rbx, Immediate(char_size())); |
437 __ addq(rdx, Immediate(char_size())); | 437 __ addp(rdx, Immediate(char_size())); |
438 // Check if we have reached end of match area. | 438 // Check if we have reached end of match area. |
439 __ cmpq(rdx, r9); | 439 __ cmpq(rdx, r9); |
440 __ j(below, &loop); | 440 __ j(below, &loop); |
441 | 441 |
442 // Success. | 442 // Success. |
443 // Set current character position to position after match. | 443 // Set current character position to position after match. |
444 __ movp(rdi, rbx); | 444 __ movp(rdi, rbx); |
445 __ subq(rdi, rsi); | 445 __ subq(rdi, rsi); |
446 | 446 |
447 __ bind(&fallthrough); | 447 __ bind(&fallthrough); |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
712 __ Push(Immediate(0)); // Make room for "input start - 1" constant. | 712 __ Push(Immediate(0)); // Make room for "input start - 1" constant. |
713 | 713 |
714 // Check if we have space on the stack for registers. | 714 // Check if we have space on the stack for registers. |
715 Label stack_limit_hit; | 715 Label stack_limit_hit; |
716 Label stack_ok; | 716 Label stack_ok; |
717 | 717 |
718 ExternalReference stack_limit = | 718 ExternalReference stack_limit = |
719 ExternalReference::address_of_stack_limit(isolate()); | 719 ExternalReference::address_of_stack_limit(isolate()); |
720 __ movp(rcx, rsp); | 720 __ movp(rcx, rsp); |
721 __ Move(kScratchRegister, stack_limit); | 721 __ Move(kScratchRegister, stack_limit); |
722 __ subq(rcx, Operand(kScratchRegister, 0)); | 722 __ subp(rcx, Operand(kScratchRegister, 0)); |
723 // Handle it if the stack pointer is already below the stack limit. | 723 // Handle it if the stack pointer is already below the stack limit. |
724 __ j(below_equal, &stack_limit_hit); | 724 __ j(below_equal, &stack_limit_hit); |
725 // Check if there is room for the variable number of registers above | 725 // Check if there is room for the variable number of registers above |
726 // the stack limit. | 726 // the stack limit. |
727 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); | 727 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); |
728 __ j(above_equal, &stack_ok); | 728 __ j(above_equal, &stack_ok); |
729 // Exit with OutOfMemory exception. There is not enough space on the stack | 729 // Exit with OutOfMemory exception. There is not enough space on the stack |
730 // for our working registers. | 730 // for our working registers. |
731 __ Set(rax, EXCEPTION); | 731 __ Set(rax, EXCEPTION); |
732 __ jmp(&return_rax); | 732 __ jmp(&return_rax); |
733 | 733 |
734 __ bind(&stack_limit_hit); | 734 __ bind(&stack_limit_hit); |
735 __ Move(code_object_pointer(), masm_.CodeObject()); | 735 __ Move(code_object_pointer(), masm_.CodeObject()); |
736 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. | 736 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. |
737 __ testq(rax, rax); | 737 __ testq(rax, rax); |
738 // If returned value is non-zero, we exit with the returned value as result. | 738 // If returned value is non-zero, we exit with the returned value as result. |
739 __ j(not_zero, &return_rax); | 739 __ j(not_zero, &return_rax); |
740 | 740 |
741 __ bind(&stack_ok); | 741 __ bind(&stack_ok); |
742 | 742 |
743 // Allocate space on stack for registers. | 743 // Allocate space on stack for registers. |
744 __ subq(rsp, Immediate(num_registers_ * kPointerSize)); | 744 __ subp(rsp, Immediate(num_registers_ * kPointerSize)); |
745 // Load string length. | 745 // Load string length. |
746 __ movp(rsi, Operand(rbp, kInputEnd)); | 746 __ movp(rsi, Operand(rbp, kInputEnd)); |
747 // Load input position. | 747 // Load input position. |
748 __ movp(rdi, Operand(rbp, kInputStart)); | 748 __ movp(rdi, Operand(rbp, kInputStart)); |
749 // Set up rdi to be negative offset from string end. | 749 // Set up rdi to be negative offset from string end. |
750 __ subq(rdi, rsi); | 750 __ subp(rdi, rsi); |
751 // Set rax to address of char before start of the string | 751 // Set rax to address of char before start of the string |
752 // (effectively string position -1). | 752 // (effectively string position -1). |
753 __ movp(rbx, Operand(rbp, kStartIndex)); | 753 __ movp(rbx, Operand(rbp, kStartIndex)); |
754 __ neg(rbx); | 754 __ neg(rbx); |
755 if (mode_ == UC16) { | 755 if (mode_ == UC16) { |
756 __ lea(rax, Operand(rdi, rbx, times_2, -char_size())); | 756 __ lea(rax, Operand(rdi, rbx, times_2, -char_size())); |
757 } else { | 757 } else { |
758 __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); | 758 __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); |
759 } | 759 } |
760 // Store this value in a local variable, for use when clearing | 760 // Store this value in a local variable, for use when clearing |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
817 | 817 |
818 // Exit code: | 818 // Exit code: |
819 if (success_label_.is_linked()) { | 819 if (success_label_.is_linked()) { |
820 // Save captures when successful. | 820 // Save captures when successful. |
821 __ bind(&success_label_); | 821 __ bind(&success_label_); |
822 if (num_saved_registers_ > 0) { | 822 if (num_saved_registers_ > 0) { |
823 // copy captures to output | 823 // copy captures to output |
824 __ movp(rdx, Operand(rbp, kStartIndex)); | 824 __ movp(rdx, Operand(rbp, kStartIndex)); |
825 __ movp(rbx, Operand(rbp, kRegisterOutput)); | 825 __ movp(rbx, Operand(rbp, kRegisterOutput)); |
826 __ movp(rcx, Operand(rbp, kInputEnd)); | 826 __ movp(rcx, Operand(rbp, kInputEnd)); |
827 __ subq(rcx, Operand(rbp, kInputStart)); | 827 __ subp(rcx, Operand(rbp, kInputStart)); |
828 if (mode_ == UC16) { | 828 if (mode_ == UC16) { |
829 __ lea(rcx, Operand(rcx, rdx, times_2, 0)); | 829 __ lea(rcx, Operand(rcx, rdx, times_2, 0)); |
830 } else { | 830 } else { |
831 __ addq(rcx, rdx); | 831 __ addp(rcx, rdx); |
832 } | 832 } |
833 for (int i = 0; i < num_saved_registers_; i++) { | 833 for (int i = 0; i < num_saved_registers_; i++) { |
834 __ movq(rax, register_location(i)); | 834 __ movq(rax, register_location(i)); |
835 if (i == 0 && global_with_zero_length_check()) { | 835 if (i == 0 && global_with_zero_length_check()) { |
836 // Keep capture start in rdx for the zero-length check later. | 836 // Keep capture start in rdx for the zero-length check later. |
837 __ movp(rdx, rax); | 837 __ movp(rdx, rax); |
838 } | 838 } |
839 __ addq(rax, rcx); // Convert to index from start, not end. | 839 __ addp(rax, rcx); // Convert to index from start, not end. |
840 if (mode_ == UC16) { | 840 if (mode_ == UC16) { |
841 __ sar(rax, Immediate(1)); // Convert byte index to character index. | 841 __ sar(rax, Immediate(1)); // Convert byte index to character index. |
842 } | 842 } |
843 __ movl(Operand(rbx, i * kIntSize), rax); | 843 __ movl(Operand(rbx, i * kIntSize), rax); |
844 } | 844 } |
845 } | 845 } |
846 | 846 |
847 if (global()) { | 847 if (global()) { |
848 // Restart matching if the regular expression is flagged as global. | 848 // Restart matching if the regular expression is flagged as global. |
849 // Increment success counter. | 849 // Increment success counter. |
850 __ incq(Operand(rbp, kSuccessfulCaptures)); | 850 __ incq(Operand(rbp, kSuccessfulCaptures)); |
851 // Capture results have been stored, so the number of remaining global | 851 // Capture results have been stored, so the number of remaining global |
852 // output registers is reduced by the number of stored captures. | 852 // output registers is reduced by the number of stored captures. |
853 __ movsxlq(rcx, Operand(rbp, kNumOutputRegisters)); | 853 __ movsxlq(rcx, Operand(rbp, kNumOutputRegisters)); |
854 __ subq(rcx, Immediate(num_saved_registers_)); | 854 __ subp(rcx, Immediate(num_saved_registers_)); |
855 // Check whether we have enough room for another set of capture results. | 855 // Check whether we have enough room for another set of capture results. |
856 __ cmpq(rcx, Immediate(num_saved_registers_)); | 856 __ cmpq(rcx, Immediate(num_saved_registers_)); |
857 __ j(less, &exit_label_); | 857 __ j(less, &exit_label_); |
858 | 858 |
859 __ movp(Operand(rbp, kNumOutputRegisters), rcx); | 859 __ movp(Operand(rbp, kNumOutputRegisters), rcx); |
860 // Advance the location for output. | 860 // Advance the location for output. |
861 __ addq(Operand(rbp, kRegisterOutput), | 861 __ addp(Operand(rbp, kRegisterOutput), |
862 Immediate(num_saved_registers_ * kIntSize)); | 862 Immediate(num_saved_registers_ * kIntSize)); |
863 | 863 |
864 // Prepare rax to initialize registers with its value in the next run. | 864 // Prepare rax to initialize registers with its value in the next run. |
865 __ movp(rax, Operand(rbp, kInputStartMinusOne)); | 865 __ movp(rax, Operand(rbp, kInputStartMinusOne)); |
866 | 866 |
867 if (global_with_zero_length_check()) { | 867 if (global_with_zero_length_check()) { |
868 // Special case for zero-length matches. | 868 // Special case for zero-length matches. |
869 // rdx: capture start index | 869 // rdx: capture start index |
870 __ cmpq(rdi, rdx); | 870 __ cmpq(rdi, rdx); |
871 // Not a zero-length match, restart. | 871 // Not a zero-length match, restart. |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 } | 1084 } |
1085 | 1085 |
1086 | 1086 |
1087 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) { | 1087 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) { |
1088 __ movq(rdi, register_location(reg)); | 1088 __ movq(rdi, register_location(reg)); |
1089 } | 1089 } |
1090 | 1090 |
1091 | 1091 |
1092 void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) { | 1092 void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) { |
1093 __ movq(backtrack_stackpointer(), register_location(reg)); | 1093 __ movq(backtrack_stackpointer(), register_location(reg)); |
1094 __ addq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); | 1094 __ addp(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); |
1095 } | 1095 } |
1096 | 1096 |
1097 | 1097 |
1098 void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) { | 1098 void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) { |
1099 Label after_position; | 1099 Label after_position; |
1100 __ cmpq(rdi, Immediate(-by * char_size())); | 1100 __ cmpq(rdi, Immediate(-by * char_size())); |
1101 __ j(greater_equal, &after_position, Label::kNear); | 1101 __ j(greater_equal, &after_position, Label::kNear); |
1102 __ movq(rdi, Immediate(-by * char_size())); | 1102 __ movq(rdi, Immediate(-by * char_size())); |
1103 // On RegExp code entry (where this operation is used), the character before | 1103 // On RegExp code entry (where this operation is used), the character before |
1104 // the current position is expected to be already loaded. | 1104 // the current position is expected to be already loaded. |
(...skipping 30 matching lines...) Expand all Loading... |
1135 ASSERT(reg_from <= reg_to); | 1135 ASSERT(reg_from <= reg_to); |
1136 __ movp(rax, Operand(rbp, kInputStartMinusOne)); | 1136 __ movp(rax, Operand(rbp, kInputStartMinusOne)); |
1137 for (int reg = reg_from; reg <= reg_to; reg++) { | 1137 for (int reg = reg_from; reg <= reg_to; reg++) { |
1138 __ movp(register_location(reg), rax); | 1138 __ movp(register_location(reg), rax); |
1139 } | 1139 } |
1140 } | 1140 } |
1141 | 1141 |
1142 | 1142 |
1143 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { | 1143 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { |
1144 __ movp(rax, backtrack_stackpointer()); | 1144 __ movp(rax, backtrack_stackpointer()); |
1145 __ subq(rax, Operand(rbp, kStackHighEnd)); | 1145 __ subp(rax, Operand(rbp, kStackHighEnd)); |
1146 __ movp(register_location(reg), rax); | 1146 __ movp(register_location(reg), rax); |
1147 } | 1147 } |
1148 | 1148 |
1149 | 1149 |
1150 // Private methods: | 1150 // Private methods: |
1151 | 1151 |
1152 void RegExpMacroAssemblerX64::CallCheckStackGuardState() { | 1152 void RegExpMacroAssemblerX64::CallCheckStackGuardState() { |
1153 // This function call preserves no register values. Caller should | 1153 // This function call preserves no register values. Caller should |
1154 // store anything volatile in a C call or overwritten by this function. | 1154 // store anything volatile in a C call or overwritten by this function. |
1155 static const int num_arguments = 3; | 1155 static const int num_arguments = 3; |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 } | 1316 } |
1317 | 1317 |
1318 | 1318 |
1319 void RegExpMacroAssemblerX64::SafeCall(Label* to) { | 1319 void RegExpMacroAssemblerX64::SafeCall(Label* to) { |
1320 __ call(to); | 1320 __ call(to); |
1321 } | 1321 } |
1322 | 1322 |
1323 | 1323 |
1324 void RegExpMacroAssemblerX64::SafeCallTarget(Label* label) { | 1324 void RegExpMacroAssemblerX64::SafeCallTarget(Label* label) { |
1325 __ bind(label); | 1325 __ bind(label); |
1326 __ subq(Operand(rsp, 0), code_object_pointer()); | 1326 __ subp(Operand(rsp, 0), code_object_pointer()); |
1327 } | 1327 } |
1328 | 1328 |
1329 | 1329 |
1330 void RegExpMacroAssemblerX64::SafeReturn() { | 1330 void RegExpMacroAssemblerX64::SafeReturn() { |
1331 __ addq(Operand(rsp, 0), code_object_pointer()); | 1331 __ addp(Operand(rsp, 0), code_object_pointer()); |
1332 __ ret(0); | 1332 __ ret(0); |
1333 } | 1333 } |
1334 | 1334 |
1335 | 1335 |
1336 void RegExpMacroAssemblerX64::Push(Register source) { | 1336 void RegExpMacroAssemblerX64::Push(Register source) { |
1337 ASSERT(!source.is(backtrack_stackpointer())); | 1337 ASSERT(!source.is(backtrack_stackpointer())); |
1338 // Notice: This updates flags, unlike normal Push. | 1338 // Notice: This updates flags, unlike normal Push. |
1339 __ subq(backtrack_stackpointer(), Immediate(kIntSize)); | 1339 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); |
1340 __ movl(Operand(backtrack_stackpointer(), 0), source); | 1340 __ movl(Operand(backtrack_stackpointer(), 0), source); |
1341 } | 1341 } |
1342 | 1342 |
1343 | 1343 |
1344 void RegExpMacroAssemblerX64::Push(Immediate value) { | 1344 void RegExpMacroAssemblerX64::Push(Immediate value) { |
1345 // Notice: This updates flags, unlike normal Push. | 1345 // Notice: This updates flags, unlike normal Push. |
1346 __ subq(backtrack_stackpointer(), Immediate(kIntSize)); | 1346 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); |
1347 __ movl(Operand(backtrack_stackpointer(), 0), value); | 1347 __ movl(Operand(backtrack_stackpointer(), 0), value); |
1348 } | 1348 } |
1349 | 1349 |
1350 | 1350 |
1351 void RegExpMacroAssemblerX64::FixupCodeRelativePositions() { | 1351 void RegExpMacroAssemblerX64::FixupCodeRelativePositions() { |
1352 for (int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) { | 1352 for (int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) { |
1353 int position = code_relative_fixup_positions_[i]; | 1353 int position = code_relative_fixup_positions_[i]; |
1354 // The position succeeds a relative label offset from position. | 1354 // The position succeeds a relative label offset from position. |
1355 // Patch the relative offset to be relative to the Code object pointer | 1355 // Patch the relative offset to be relative to the Code object pointer |
1356 // instead. | 1356 // instead. |
1357 int patch_position = position - kIntSize; | 1357 int patch_position = position - kIntSize; |
1358 int offset = masm_.long_at(patch_position); | 1358 int offset = masm_.long_at(patch_position); |
1359 masm_.long_at_put(patch_position, | 1359 masm_.long_at_put(patch_position, |
1360 offset | 1360 offset |
1361 + position | 1361 + position |
1362 + Code::kHeaderSize | 1362 + Code::kHeaderSize |
1363 - kHeapObjectTag); | 1363 - kHeapObjectTag); |
1364 } | 1364 } |
1365 code_relative_fixup_positions_.Clear(); | 1365 code_relative_fixup_positions_.Clear(); |
1366 } | 1366 } |
1367 | 1367 |
1368 | 1368 |
1369 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) { | 1369 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) { |
1370 __ subq(backtrack_stackpointer(), Immediate(kIntSize)); | 1370 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); |
1371 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target); | 1371 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target); |
1372 MarkPositionForCodeRelativeFixup(); | 1372 MarkPositionForCodeRelativeFixup(); |
1373 } | 1373 } |
1374 | 1374 |
1375 | 1375 |
1376 void RegExpMacroAssemblerX64::Pop(Register target) { | 1376 void RegExpMacroAssemblerX64::Pop(Register target) { |
1377 ASSERT(!target.is(backtrack_stackpointer())); | 1377 ASSERT(!target.is(backtrack_stackpointer())); |
1378 __ movsxlq(target, Operand(backtrack_stackpointer(), 0)); | 1378 __ movsxlq(target, Operand(backtrack_stackpointer(), 0)); |
1379 // Notice: This updates flags, unlike normal Pop. | 1379 // Notice: This updates flags, unlike normal Pop. |
1380 __ addq(backtrack_stackpointer(), Immediate(kIntSize)); | 1380 __ addp(backtrack_stackpointer(), Immediate(kIntSize)); |
1381 } | 1381 } |
1382 | 1382 |
1383 | 1383 |
1384 void RegExpMacroAssemblerX64::Drop() { | 1384 void RegExpMacroAssemblerX64::Drop() { |
1385 __ addq(backtrack_stackpointer(), Immediate(kIntSize)); | 1385 __ addp(backtrack_stackpointer(), Immediate(kIntSize)); |
1386 } | 1386 } |
1387 | 1387 |
1388 | 1388 |
1389 void RegExpMacroAssemblerX64::CheckPreemption() { | 1389 void RegExpMacroAssemblerX64::CheckPreemption() { |
1390 // Check for preemption. | 1390 // Check for preemption. |
1391 Label no_preempt; | 1391 Label no_preempt; |
1392 ExternalReference stack_limit = | 1392 ExternalReference stack_limit = |
1393 ExternalReference::address_of_stack_limit(isolate()); | 1393 ExternalReference::address_of_stack_limit(isolate()); |
1394 __ load_rax(stack_limit); | 1394 __ load_rax(stack_limit); |
1395 __ cmpq(rsp, rax); | 1395 __ cmpq(rsp, rax); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1439 } | 1439 } |
1440 } | 1440 } |
1441 | 1441 |
1442 #undef __ | 1442 #undef __ |
1443 | 1443 |
1444 #endif // V8_INTERPRETED_REGEXP | 1444 #endif // V8_INTERPRETED_REGEXP |
1445 | 1445 |
1446 }} // namespace v8::internal | 1446 }} // namespace v8::internal |
1447 | 1447 |
1448 #endif // V8_TARGET_ARCH_X64 | 1448 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |