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