| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 Mode mode, | 86 Mode mode, |
| 87 int registers_to_save) | 87 int registers_to_save) |
| 88 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), | 88 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), |
| 89 constants_(kRegExpConstantsSize), | 89 constants_(kRegExpConstantsSize), |
| 90 mode_(mode), | 90 mode_(mode), |
| 91 num_registers_(registers_to_save), | 91 num_registers_(registers_to_save), |
| 92 num_saved_registers_(registers_to_save), | 92 num_saved_registers_(registers_to_save), |
| 93 entry_label_(), | 93 entry_label_(), |
| 94 start_label_(), | 94 start_label_(), |
| 95 success_label_(), | 95 success_label_(), |
| 96 backtrack_label_(), |
| 96 exit_label_(), | 97 exit_label_(), |
| 97 self_(Heap::undefined_value()) { | 98 self_(Heap::undefined_value()) { |
| 98 __ jmp(&entry_label_); // We'll write the entry code later. | 99 __ jmp(&entry_label_); // We'll write the entry code later. |
| 99 __ bind(&start_label_); // And then continue from here. | 100 __ bind(&start_label_); // And then continue from here. |
| 100 } | 101 } |
| 101 | 102 |
| 102 | 103 |
| 103 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { | 104 RegExpMacroAssemblerIA32::~RegExpMacroAssemblerIA32() { |
| 104 delete masm_; | 105 delete masm_; |
| 105 // Unuse labels in case we throw away the assembler without calling GetCode. | 106 // Unuse labels in case we throw away the assembler without calling GetCode. |
| 106 entry_label_.Unuse(); | 107 entry_label_.Unuse(); |
| 107 start_label_.Unuse(); | 108 start_label_.Unuse(); |
| 108 success_label_.Unuse(); | 109 success_label_.Unuse(); |
| 110 backtrack_label_.Unuse(); |
| 109 exit_label_.Unuse(); | 111 exit_label_.Unuse(); |
| 110 check_preempt_label_.Unuse(); | 112 check_preempt_label_.Unuse(); |
| 111 } | 113 } |
| 112 | 114 |
| 113 | 115 |
| 114 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { | 116 void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) { |
| 115 if (by != 0) { | 117 if (by != 0) { |
| 116 Label inside_string; | 118 Label inside_string; |
| 117 __ add(Operand(edi), Immediate(by * char_size())); | 119 __ add(Operand(edi), Immediate(by * char_size())); |
| 118 } | 120 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 147 __ shr(ebx, 3); | 149 __ shr(ebx, 3); |
| 148 // TODO(lrn): Where is the bitmap stored? Pass the bitmap as argument instead. | 150 // TODO(lrn): Where is the bitmap stored? Pass the bitmap as argument instead. |
| 149 // __ mov(ecx, position_of_bitmap); | 151 // __ mov(ecx, position_of_bitmap); |
| 150 __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0)); | 152 __ movzx_b(ebx, Operand(ecx, ebx, times_1, 0)); |
| 151 __ and_(eax, (1<<3)-1); | 153 __ and_(eax, (1<<3)-1); |
| 152 __ bt(Operand(ebx), eax); | 154 __ bt(Operand(ebx), eax); |
| 153 BranchOrBacktrack(carry, on_zero); | 155 BranchOrBacktrack(carry, on_zero); |
| 154 } | 156 } |
| 155 | 157 |
| 156 | 158 |
| 157 void RegExpMacroAssemblerIA32::CheckCharacter(uc16 c, Label* on_equal) { | 159 void RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) { |
| 158 __ cmp(current_character(), c); | 160 __ cmp(current_character(), c); |
| 159 BranchOrBacktrack(equal, on_equal); | 161 BranchOrBacktrack(equal, on_equal); |
| 160 } | 162 } |
| 161 | 163 |
| 162 | 164 |
| 163 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { | 165 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { |
| 164 __ cmp(current_character(), limit); | 166 __ cmp(current_character(), limit); |
| 165 BranchOrBacktrack(greater, on_greater); | 167 BranchOrBacktrack(greater, on_greater); |
| 166 } | 168 } |
| 167 | 169 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 | 360 |
| 359 void RegExpMacroAssemblerIA32::CheckNotRegistersEqual(int reg1, | 361 void RegExpMacroAssemblerIA32::CheckNotRegistersEqual(int reg1, |
| 360 int reg2, | 362 int reg2, |
| 361 Label* on_not_equal) { | 363 Label* on_not_equal) { |
| 362 __ mov(eax, register_location(reg1)); | 364 __ mov(eax, register_location(reg1)); |
| 363 __ cmp(eax, register_location(reg2)); | 365 __ cmp(eax, register_location(reg2)); |
| 364 BranchOrBacktrack(not_equal, on_not_equal); | 366 BranchOrBacktrack(not_equal, on_not_equal); |
| 365 } | 367 } |
| 366 | 368 |
| 367 | 369 |
| 368 void RegExpMacroAssemblerIA32::CheckNotCharacter(uc16 c, Label* on_not_equal) { | 370 void RegExpMacroAssemblerIA32::CheckNotCharacter(uint32_t c, |
| 371 Label* on_not_equal) { |
| 369 __ cmp(current_character(), c); | 372 __ cmp(current_character(), c); |
| 370 BranchOrBacktrack(not_equal, on_not_equal); | 373 BranchOrBacktrack(not_equal, on_not_equal); |
| 371 } | 374 } |
| 372 | 375 |
| 373 | 376 |
| 374 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterOr(uc16 c, | 377 void RegExpMacroAssemblerIA32::CheckCharacterAfterAnd(uint32_t c, |
| 375 uc16 mask, | 378 uint32_t mask, |
| 376 Label* on_not_equal) { | 379 Label* on_equal) { |
| 377 __ mov(eax, current_character()); | 380 __ mov(eax, current_character()); |
| 378 __ or_(eax, mask); | 381 __ and_(eax, mask); |
| 382 __ cmp(eax, c); |
| 383 BranchOrBacktrack(equal, on_equal); |
| 384 } |
| 385 |
| 386 |
| 387 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterAnd(uint32_t c, |
| 388 uint32_t mask, |
| 389 Label* on_not_equal) { |
| 390 __ mov(eax, current_character()); |
| 391 __ and_(eax, mask); |
| 379 __ cmp(eax, c); | 392 __ cmp(eax, c); |
| 380 BranchOrBacktrack(not_equal, on_not_equal); | 393 BranchOrBacktrack(not_equal, on_not_equal); |
| 381 } | 394 } |
| 382 | 395 |
| 383 | 396 |
| 384 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusOr( | 397 void RegExpMacroAssemblerIA32::CheckNotCharacterAfterMinusAnd( |
| 385 uc16 c, | 398 uc16 c, |
| 399 uc16 minus, |
| 386 uc16 mask, | 400 uc16 mask, |
| 387 Label* on_not_equal) { | 401 Label* on_not_equal) { |
| 388 __ lea(eax, Operand(current_character(), -mask)); | 402 ASSERT(minus < String::kMaxUC16CharCode); |
| 389 __ or_(eax, mask); | 403 __ lea(eax, Operand(current_character(), -minus)); |
| 404 __ and_(eax, mask); |
| 390 __ cmp(eax, c); | 405 __ cmp(eax, c); |
| 391 BranchOrBacktrack(not_equal, on_not_equal); | 406 BranchOrBacktrack(not_equal, on_not_equal); |
| 392 } | 407 } |
| 393 | 408 |
| 394 | 409 |
| 395 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap( | 410 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap( |
| 396 uc16 start, | 411 uc16 start, |
| 397 Label* half_nibble_map, | 412 Label* half_nibble_map, |
| 398 const Vector<Label*>& destinations) { | 413 const Vector<Label*>& destinations) { |
| 399 UNIMPLEMENTED(); | 414 UNIMPLEMENTED(); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 Label init_loop; | 524 Label init_loop; |
| 510 __ bind(&init_loop); | 525 __ bind(&init_loop); |
| 511 __ mov(Operand(ebp, ecx, times_4, +0), eax); | 526 __ mov(Operand(ebp, ecx, times_4, +0), eax); |
| 512 __ inc(ecx); | 527 __ inc(ecx); |
| 513 __ j(not_equal, &init_loop); | 528 __ j(not_equal, &init_loop); |
| 514 } | 529 } |
| 515 // Load previous char as initial value of current-character. | 530 // Load previous char as initial value of current-character. |
| 516 Label at_start; | 531 Label at_start; |
| 517 __ cmp(Operand(ebp, kAtStart), Immediate(0)); | 532 __ cmp(Operand(ebp, kAtStart), Immediate(0)); |
| 518 __ j(not_equal, &at_start); | 533 __ j(not_equal, &at_start); |
| 519 LoadCurrentCharacterUnchecked(-1); // Load previous char. | 534 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. |
| 520 __ jmp(&start_label_); | 535 __ jmp(&start_label_); |
| 521 __ bind(&at_start); | 536 __ bind(&at_start); |
| 522 __ mov(current_character(), '\n'); | 537 __ mov(current_character(), '\n'); |
| 523 __ jmp(&start_label_); | 538 __ jmp(&start_label_); |
| 524 | 539 |
| 525 | 540 |
| 526 // Exit code: | 541 // Exit code: |
| 527 if (success_label_.is_linked()) { | 542 if (success_label_.is_linked()) { |
| 528 // Success | 543 // Success |
| 529 __ bind(&success_label_); | 544 __ bind(&success_label_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 544 __ mov(eax, Immediate(1)); | 559 __ mov(eax, Immediate(1)); |
| 545 } | 560 } |
| 546 // Exit and return eax | 561 // Exit and return eax |
| 547 __ bind(&exit_label_); | 562 __ bind(&exit_label_); |
| 548 __ leave(); | 563 __ leave(); |
| 549 __ pop(ebx); | 564 __ pop(ebx); |
| 550 __ pop(edi); | 565 __ pop(edi); |
| 551 __ pop(esi); | 566 __ pop(esi); |
| 552 __ ret(0); | 567 __ ret(0); |
| 553 | 568 |
| 569 // Backtrack code (branch target for conditional backtracks). |
| 570 if (backtrack_label_.is_linked()) { |
| 571 __ bind(&backtrack_label_); |
| 572 Backtrack(); |
| 573 } |
| 574 |
| 554 // Preempt-code | 575 // Preempt-code |
| 555 if (check_preempt_label_.is_linked()) { | 576 if (check_preempt_label_.is_linked()) { |
| 556 __ bind(&check_preempt_label_); | 577 __ bind(&check_preempt_label_); |
| 557 // TODO(lrn): call C function to check the stack guard and return current | 578 // TODO(lrn): call C function to check the stack guard and return current |
| 558 // stack state (0 = ok, positive = out of stack, negative = preempt). | 579 // stack state (0 = ok, positive = out of stack, negative = preempt). |
| 559 // Then dispatch to an action depending on state, and loop. | 580 // Then dispatch to an action depending on state, and loop. |
| 560 __ push(edi); | 581 __ push(edi); |
| 561 | 582 |
| 562 Label retry; | 583 Label retry; |
| 563 Label stack_overflow; | 584 Label stack_overflow; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 624 } | 645 } |
| 625 | 646 |
| 626 | 647 |
| 627 RegExpMacroAssembler::IrregexpImplementation | 648 RegExpMacroAssembler::IrregexpImplementation |
| 628 RegExpMacroAssemblerIA32::Implementation() { | 649 RegExpMacroAssemblerIA32::Implementation() { |
| 629 return kIA32Implementation; | 650 return kIA32Implementation; |
| 630 } | 651 } |
| 631 | 652 |
| 632 | 653 |
| 633 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, | 654 void RegExpMacroAssemblerIA32::LoadCurrentCharacter(int cp_offset, |
| 634 Label* on_end_of_input) { | 655 Label* on_end_of_input, |
| 656 bool check_bounds, |
| 657 int characters) { |
| 635 ASSERT(cp_offset >= 0); | 658 ASSERT(cp_offset >= 0); |
| 636 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 659 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
| 637 __ cmp(edi, -cp_offset * char_size()); | 660 if (check_bounds) { |
| 638 BranchOrBacktrack(greater_equal, on_end_of_input); | 661 __ cmp(edi, -(cp_offset + characters) * char_size()); |
| 639 LoadCurrentCharacterUnchecked(cp_offset); | 662 BranchOrBacktrack(greater, on_end_of_input); |
| 663 } |
| 664 LoadCurrentCharacterUnchecked(cp_offset, characters); |
| 640 } | 665 } |
| 641 | 666 |
| 642 | 667 |
| 643 void RegExpMacroAssemblerIA32::PopCurrentPosition() { | 668 void RegExpMacroAssemblerIA32::PopCurrentPosition() { |
| 644 __ pop(edi); | 669 __ pop(edi); |
| 645 } | 670 } |
| 646 | 671 |
| 647 | 672 |
| 648 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { | 673 void RegExpMacroAssemblerIA32::PopRegister(int register_index) { |
| 649 __ pop(register_location(register_index)); | 674 __ pop(register_location(register_index)); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 Label* to) { | 819 Label* to) { |
| 795 if (condition < 0) { // No condition | 820 if (condition < 0) { // No condition |
| 796 if (to == NULL) { | 821 if (to == NULL) { |
| 797 Backtrack(); | 822 Backtrack(); |
| 798 return; | 823 return; |
| 799 } | 824 } |
| 800 __ jmp(to); | 825 __ jmp(to); |
| 801 return; | 826 return; |
| 802 } | 827 } |
| 803 if (to == NULL) { | 828 if (to == NULL) { |
| 804 Label skip; | 829 __ j(condition, &backtrack_label_); |
| 805 __ j(NegateCondition(condition), &skip); | |
| 806 Backtrack(); | |
| 807 __ bind(&skip); | |
| 808 return; | 830 return; |
| 809 } | 831 } |
| 810 __ j(condition, to); | 832 __ j(condition, to); |
| 811 } | 833 } |
| 812 | 834 |
| 813 | 835 |
| 814 void RegExpMacroAssemblerIA32::SafeCall(Label* to) { | 836 void RegExpMacroAssemblerIA32::SafeCall(Label* to) { |
| 815 Label return_to; | 837 Label return_to; |
| 816 __ push(Immediate::CodeRelativeOffset(&return_to)); | 838 __ push(Immediate::CodeRelativeOffset(&return_to)); |
| 817 __ jmp(to); | 839 __ jmp(to); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 __ mov(Operand(eax), Immediate(reinterpret_cast<int32_t>(function_address))); | 886 __ mov(Operand(eax), Immediate(reinterpret_cast<int32_t>(function_address))); |
| 865 __ call(Operand(eax)); | 887 __ call(Operand(eax)); |
| 866 if (OS::ActivationFrameAlignment() != 0) { | 888 if (OS::ActivationFrameAlignment() != 0) { |
| 867 __ mov(esp, Operand(esp, num_arguments * kPointerSize)); | 889 __ mov(esp, Operand(esp, num_arguments * kPointerSize)); |
| 868 } else { | 890 } else { |
| 869 __ add(Operand(esp), Immediate(num_arguments * sizeof(int32_t))); | 891 __ add(Operand(esp), Immediate(num_arguments * sizeof(int32_t))); |
| 870 } | 892 } |
| 871 } | 893 } |
| 872 | 894 |
| 873 | 895 |
| 874 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset) { | 896 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, |
| 897 int characters) { |
| 875 if (mode_ == ASCII) { | 898 if (mode_ == ASCII) { |
| 876 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); | 899 if (characters == 4) { |
| 900 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); |
| 901 } else if (characters == 2) { |
| 902 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); |
| 903 } else { |
| 904 ASSERT(characters == 1); |
| 905 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); |
| 906 } |
| 877 } else { | 907 } else { |
| 878 ASSERT(mode_ == UC16); | 908 ASSERT(mode_ == UC16); |
| 879 __ movzx_w(current_character(), | 909 if (characters == 2) { |
| 880 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); | 910 __ mov(current_character(), |
| 911 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); |
| 912 } else { |
| 913 ASSERT(characters == 1); |
| 914 __ movzx_w(current_character(), |
| 915 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); |
| 916 } |
| 881 } | 917 } |
| 882 } | 918 } |
| 883 | 919 |
| 884 | 920 |
| 885 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, | 921 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, |
| 886 ArraySlice* buffer) { | 922 ArraySlice* buffer) { |
| 887 __ mov(reg, buffer->array()); | 923 __ mov(reg, buffer->array()); |
| 888 __ add(Operand(reg), Immediate(buffer->base_offset())); | 924 __ add(Operand(reg), Immediate(buffer->base_offset())); |
| 889 } | 925 } |
| 890 | 926 |
| 891 #undef __ | 927 #undef __ |
| 892 }} // namespace v8::internal | 928 }} // namespace v8::internal |
| OLD | NEW |