Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(463)

Side by Side Diff: src/regexp-macro-assembler-ia32.cc

Issue 17642: Irregexp-32: Fixes us of "enter" opcode. (Closed)
Patch Set: Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/regexp-macro-assembler-ia32.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 * The stack will have the following structure: 56 * The stack will have the following structure:
57 * - stack_area_top (High end of the memory area to use as 57 * - stack_area_top (High end of the memory area to use as
58 * backtracking stack) 58 * backtracking stack)
59 * - at_start (if 1, start at start of string, if 0, don't) 59 * - at_start (if 1, start at start of string, if 0, don't)
60 * - int* capture_array (int[num_saved_registers_], for output). 60 * - int* capture_array (int[num_saved_registers_], for output).
61 * - end of input (index of end of string, relative to *string_base) 61 * - end of input (index of end of string, relative to *string_base)
62 * - start of input (index of first character in string, relative 62 * - start of input (index of first character in string, relative
63 * to *string_base) 63 * to *string_base)
64 * - void** string_base (location of a handle containing the string) 64 * - void** string_base (location of a handle containing the string)
65 * - return address 65 * - return address
66 * ebp-> - old ebp
66 * - backup of caller esi 67 * - backup of caller esi
67 * - backup of caller edi 68 * - backup of caller edi
68 * - backup of caller ebx 69 * - backup of caller ebx
69 * ebp-> - old ebp
70 * - register 0 ebp[-4] (Only positions must be stored in the first 70 * - register 0 ebp[-4] (Only positions must be stored in the first
71 * - register 1 ebp[-8] num_saved_registers_ registers) 71 * - register 1 ebp[-8] num_saved_registers_ registers)
72 * - ... 72 * - ...
73 * 73 *
74 * The first num_saved_registers_ registers are initialized to point to 74 * The first num_saved_registers_ registers are initialized to point to
75 * "character -1" in the string (i.e., char_size() bytes before the first 75 * "character -1" in the string (i.e., char_size() bytes before the first
76 * character of the string). The remaining registers starts out as garbage. 76 * character of the string). The remaining registers starts out as garbage.
77 * 77 *
78 * The data up to the return address must be placed there by the calling 78 * The data up to the return address must be placed there by the calling
79 * code, e.g., by calling the code as cast to: 79 * code, e.g., by calling the code as cast to:
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 __ jmp(&exit_label_); 593 __ jmp(&exit_label_);
594 } 594 }
595 595
596 596
597 Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { 597 Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
598 // Finalize code - write the entry point code now we know how many 598 // Finalize code - write the entry point code now we know how many
599 // registers we need. 599 // registers we need.
600 600
601 // Entry code: 601 // Entry code:
602 __ bind(&entry_label_); 602 __ bind(&entry_label_);
603 // Start new stack frame.
604 __ push(ebp);
605 __ mov(ebp, esp);
603 // Save callee-save registers. Order here should correspond to order of 606 // Save callee-save registers. Order here should correspond to order of
604 // kBackup_ebx etc. 607 // kBackup_ebx etc.
605 __ push(esi); 608 __ push(esi);
606 __ push(edi); 609 __ push(edi);
607 __ push(ebx); // Callee-save on MacOS. 610 __ push(ebx); // Callee-save on MacOS.
608 611
609 // Check if we have space on the stack for registers. 612 // Check if we have space on the stack for registers.
610 Label retry_stack_check; 613 Label retry_stack_check;
611 Label stack_limit_hit; 614 Label stack_limit_hit;
612 Label stack_ok; 615 Label stack_ok;
613 616
614 __ bind(&retry_stack_check); 617 __ bind(&retry_stack_check);
615 ExternalReference stack_guard_limit = 618 ExternalReference stack_guard_limit =
616 ExternalReference::address_of_stack_guard_limit(); 619 ExternalReference::address_of_stack_guard_limit();
617 __ mov(ecx, esp); 620 __ mov(ecx, esp);
618 __ sub(ecx, Operand::StaticVariable(stack_guard_limit)); 621 __ sub(ecx, Operand::StaticVariable(stack_guard_limit));
619 // Handle it if the stack pointer is already below the stack limit. 622 // Handle it if the stack pointer is already below the stack limit.
620 __ j(below_equal, &stack_limit_hit, not_taken); 623 __ j(below_equal, &stack_limit_hit, not_taken);
621 // Check if there is room for the variable number of registers above 624 // Check if there is room for the variable number of registers above
622 // the stack limit. 625 // the stack limit.
623 __ cmp(ecx, num_registers_ * kPointerSize); 626 __ cmp(ecx, num_registers_ * kPointerSize);
624 __ j(above_equal, &stack_ok, taken); 627 __ j(above_equal, &stack_ok, taken);
625 // Exit with exception. 628 // Exit with exception.
626 __ mov(eax, EXCEPTION); 629 __ mov(eax, EXCEPTION);
627 Label exit_without_leave; 630 __ jmp(&exit_label_);
628 __ jmp(&exit_without_leave);
629 631
630 __ bind(&stack_limit_hit); 632 __ bind(&stack_limit_hit);
631 int num_arguments = 2; 633 int num_arguments = 2;
632 FrameAlign(num_arguments); 634 FrameAlign(num_arguments);
633 __ mov(Operand(esp, 1 * kPointerSize), Immediate(self_)); 635 __ mov(Operand(esp, 1 * kPointerSize), Immediate(self_));
634 __ lea(eax, Operand(esp, -kPointerSize)); 636 __ lea(eax, Operand(esp, -kPointerSize));
635 __ mov(Operand(esp, 0 * kPointerSize), eax); 637 __ mov(Operand(esp, 0 * kPointerSize), eax);
636 CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments); 638 CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments);
637 __ or_(eax, Operand(eax)); 639 __ or_(eax, Operand(eax));
638 // If returned value is non-zero, the stack guard reports the actual 640 // If returned value is non-zero, the stack guard reports the actual
639 // stack limit being hit and an exception has already been raised. 641 // stack limit being hit and an exception has already been raised.
640 // Otherwise it was a preemption and we just check the limit again. 642 // Otherwise it was a preemption and we just check the limit again.
641 __ j(equal, &retry_stack_check); 643 __ j(equal, &retry_stack_check);
642 // Return value was non-zero. Exit with exception. 644 // Return value was non-zero. Exit with exception.
643 __ mov(eax, EXCEPTION); 645 __ mov(eax, EXCEPTION);
644 __ jmp(&exit_without_leave); 646 __ jmp(&exit_label_);
645 647
646 __ bind(&stack_ok); 648 __ bind(&stack_ok);
647 649
648 // Allocate space on stack for registers. 650 // Allocate space on stack for registers.
649 __ enter(Immediate(num_registers_ * kPointerSize)); 651 __ sub(Operand(esp), Immediate(num_registers_ * kPointerSize));
650 // Load string length. 652 // Load string length.
651 __ mov(esi, Operand(ebp, kInputEndOffset)); 653 __ mov(esi, Operand(ebp, kInputEndOffset));
652 // Load input position. 654 // Load input position.
653 __ mov(edi, Operand(ebp, kInputStartOffset)); 655 __ mov(edi, Operand(ebp, kInputStartOffset));
654 // Set up edi to be negative offset from string end. 656 // Set up edi to be negative offset from string end.
655 __ sub(edi, Operand(esi)); 657 __ sub(edi, Operand(esi));
656 // Set up esi to be end of string. First get location. 658 // Set up esi to be end of string. First get location.
657 __ mov(edx, Operand(ebp, kInputBuffer)); 659 __ mov(edx, Operand(ebp, kInputBuffer));
658 // Dereference location to get string start. 660 // Dereference location to get string start.
659 __ mov(edx, Operand(edx, 0)); 661 __ mov(edx, Operand(edx, 0));
660 // Add start to length to complete esi setup. 662 // Add start to length to complete esi setup.
661 __ add(esi, Operand(edx)); 663 __ add(esi, Operand(edx));
662 if (num_saved_registers_ > 0) { 664 if (num_saved_registers_ > 0) {
663 // Fill saved registers with initial value = start offset - 1 665 // Fill saved registers with initial value = start offset - 1
664 // Fill in stack push order, to avoid accessing across an unwritten 666 // Fill in stack push order, to avoid accessing across an unwritten
665 // page (a problem on Windows). 667 // page (a problem on Windows).
666 const int kRegisterZeroEBPOffset = -1; 668 __ mov(ecx, kRegisterZero);
667 __ mov(ecx, kRegisterZeroEBPOffset); 669 // Set eax to address of char before start of input
668 // Set eax to address of char before start of input. 670 // (effectively string position -1).
669 __ lea(eax, Operand(edi, -char_size())); 671 __ lea(eax, Operand(edi, -char_size()));
670 Label init_loop; 672 Label init_loop;
671 __ bind(&init_loop); 673 __ bind(&init_loop);
672 __ mov(Operand(ebp, ecx, times_4, +0), eax); 674 __ mov(Operand(ebp, ecx, times_1, +0), eax);
673 __ sub(Operand(ecx), Immediate(1)); 675 __ sub(Operand(ecx), Immediate(kPointerSize));
674 __ cmp(ecx, -num_saved_registers_); 676 __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
675 __ j(greater_equal, &init_loop); 677 __ j(greater, &init_loop);
676 } 678 }
677 // Ensure that we have written to each stack page. Skipping a page on 679 // Ensure that we have written to each stack page, in order. Skipping a page
678 // Windows can cause segmentation faults. Assuming page size is 4k. 680 // on Windows can cause segmentation faults. Assuming page size is 4k.
679 const int kPageSize = 4096; 681 const int kPageSize = 4096;
680 const int kRegistersPerPage = kPageSize / kPointerSize; 682 const int kRegistersPerPage = kPageSize / kPointerSize;
681 for (int i = num_saved_registers_ + kRegistersPerPage - 1; 683 for (int i = num_saved_registers_ + kRegistersPerPage - 1;
682 i < num_registers_; 684 i < num_registers_;
683 i += kRegistersPerPage) { 685 i += kRegistersPerPage) {
684 __ mov(register_location(i), eax); // One write every page. 686 __ mov(register_location(i), eax); // One write every page.
685 } 687 }
686 688
687 689
688 // Initialize backtrack stack pointer. 690 // Initialize backtrack stack pointer.
689 __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd)); 691 __ mov(backtrack_stackpointer(), Operand(ebp, kStackHighEnd));
690 // Load previous char as initial value of current-character. 692 // Load previous char as initial value of current-character.
691 Label at_start; 693 Label at_start;
692 __ cmp(Operand(ebp, kAtStart), Immediate(0)); 694 __ cmp(Operand(ebp, kAtStart), Immediate(0));
693 __ j(not_equal, &at_start); 695 __ j(not_equal, &at_start);
694 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. 696 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
695 __ jmp(&start_label_); 697 __ jmp(&start_label_);
696 __ bind(&at_start); 698 __ bind(&at_start);
697 __ mov(current_character(), '\n'); 699 __ mov(current_character(), '\n');
698 __ jmp(&start_label_); 700 __ jmp(&start_label_);
699 701
700 702
701 // Exit code: 703 // Exit code:
702 if (success_label_.is_linked()) { 704 if (success_label_.is_linked()) {
703 // Success 705 // Save captures when successful.
704 __ bind(&success_label_); 706 __ bind(&success_label_);
705 if (num_saved_registers_ > 0) { 707 if (num_saved_registers_ > 0) {
706 // copy captures to output 708 // copy captures to output
707 __ mov(ebx, Operand(ebp, kRegisterOutput)); 709 __ mov(ebx, Operand(ebp, kRegisterOutput));
708 __ mov(ecx, Operand(ebp, kInputEndOffset)); 710 __ mov(ecx, Operand(ebp, kInputEndOffset));
709 __ sub(ecx, Operand(ebp, kInputStartOffset)); 711 __ sub(ecx, Operand(ebp, kInputStartOffset));
710 for (int i = 0; i < num_saved_registers_; i++) { 712 for (int i = 0; i < num_saved_registers_; i++) {
711 __ mov(eax, register_location(i)); 713 __ mov(eax, register_location(i));
712 __ add(eax, Operand(ecx)); // Convert to index from start, not end. 714 __ add(eax, Operand(ecx)); // Convert to index from start, not end.
713 if (mode_ == UC16) { 715 if (mode_ == UC16) {
714 __ sar(eax, 1); // Convert byte index to character index. 716 __ sar(eax, 1); // Convert byte index to character index.
715 } 717 }
716 __ mov(Operand(ebx, i * kPointerSize), eax); 718 __ mov(Operand(ebx, i * kPointerSize), eax);
717 } 719 }
718 } 720 }
719 __ mov(eax, Immediate(SUCCESS)); 721 __ mov(eax, Immediate(SUCCESS));
720 } 722 }
721 // Exit and return eax 723 // Exit and return eax
722 __ bind(&exit_label_); 724 __ bind(&exit_label_);
723 __ leave(); 725 // Skip esp past regexp registers.
724 __ bind(&exit_without_leave); // For exiting before doing enter. 726 __ lea(esp, Operand(ebp, kBackup_ebx));
727 // Restore callee-save registers.
725 __ pop(ebx); 728 __ pop(ebx);
726 __ pop(edi); 729 __ pop(edi);
727 __ pop(esi); 730 __ pop(esi);
731 // Exit function frame, restore previus one.
732 __ pop(ebp);
728 __ ret(0); 733 __ ret(0);
729 734
730 // Backtrack code (branch target for conditional backtracks). 735 // Backtrack code (branch target for conditional backtracks).
731 if (backtrack_label_.is_linked()) { 736 if (backtrack_label_.is_linked()) {
732 __ bind(&backtrack_label_); 737 __ bind(&backtrack_label_);
733 Backtrack(); 738 Backtrack();
734 } 739 }
735 740
736 Label exit_with_exception; 741 Label exit_with_exception;
737 742
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 } 1041 }
1037 return stack_top + (new_stack_end - old_stack_end); 1042 return stack_top + (new_stack_end - old_stack_end);
1038 } 1043 }
1039 1044
1040 1045
1041 Operand RegExpMacroAssemblerIA32::register_location(int register_index) { 1046 Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
1042 ASSERT(register_index < (1<<30)); 1047 ASSERT(register_index < (1<<30));
1043 if (num_registers_ <= register_index) { 1048 if (num_registers_ <= register_index) {
1044 num_registers_ = register_index + 1; 1049 num_registers_ = register_index + 1;
1045 } 1050 }
1046 return Operand(ebp, -(register_index + 1) * kPointerSize); 1051 return Operand(ebp, kRegisterZero - register_index * kPointerSize);
1047 } 1052 }
1048 1053
1049 1054
1050 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset, 1055 void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset,
1051 Label* on_outside_input) { 1056 Label* on_outside_input) {
1052 __ cmp(edi, -cp_offset * char_size()); 1057 __ cmp(edi, -cp_offset * char_size());
1053 BranchOrBacktrack(greater_equal, on_outside_input); 1058 BranchOrBacktrack(greater_equal, on_outside_input);
1054 } 1059 }
1055 1060
1056 1061
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 1199
1195 1200
1196 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg, 1201 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg,
1197 ArraySlice* buffer) { 1202 ArraySlice* buffer) {
1198 __ mov(reg, buffer->array()); 1203 __ mov(reg, buffer->array());
1199 __ add(Operand(reg), Immediate(buffer->base_offset())); 1204 __ add(Operand(reg), Immediate(buffer->base_offset()));
1200 } 1205 }
1201 1206
1202 #undef __ 1207 #undef __
1203 }} // namespace v8::internal 1208 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/regexp-macro-assembler-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698