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

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

Issue 165443: X64: Implement RegExp natively. (Closed)
Patch Set: Addressed review comments. Created 11 years, 4 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
OLDNEW
1 // Copyright 2008-2009 the V8 project authors. All rights reserved. 1 // Copyright 2008-2009 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 * - esi : end of input (points to byte after last character in input). 47 * - esi : end of input (points to byte after last character in input).
48 * - ebp : frame pointer. Used to access arguments, local variables and 48 * - ebp : frame pointer. Used to access arguments, local variables and
49 * RegExp registers. 49 * RegExp registers.
50 * - esp : points to tip of C stack. 50 * - esp : points to tip of C stack.
51 * - ecx : points to tip of backtrack stack 51 * - ecx : points to tip of backtrack stack
52 * 52 *
53 * The registers eax, ebx and ecx are free to use for computations. 53 * The registers eax, ebx and ecx are free to use for computations.
54 * 54 *
55 * Each call to a public method should retain this convention. 55 * Each call to a public method should retain this convention.
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_base (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 (Address of end of string) 61 * - end of input (Address of end of string)
62 * - start of input (Address of first character in string) 62 * - start of input (Address of first character in string)
63 * - void* input_string (location of a handle containing the string) 63 * - void* input_string (location of a handle containing the string)
64 * --- frame alignment (if applicable) --- 64 * --- frame alignment (if applicable) ---
65 * - return address 65 * - return address
66 * ebp-> - old ebp 66 * ebp-> - old ebp
67 * - backup of caller esi 67 * - backup of caller esi
68 * - backup of caller edi 68 * - backup of caller edi
69 * - backup of caller ebx 69 * - backup of caller ebx
70 * - Offset of location before start of input (effectively character 70 * - Offset of location before start of input (effectively character
71 * position -1). Used to initialize capture registers to a non-position. 71 * position -1). Used to initialize capture registers to a non-position.
72 * - register 0 ebp[-4] (Only positions must be stored in the first 72 * - register 0 ebp[-4] (Only positions must be stored in the first
73 * - register 1 ebp[-8] num_saved_registers_ registers) 73 * - register 1 ebp[-8] num_saved_registers_ registers)
74 * - ... 74 * - ...
75 * 75 *
76 * The first num_saved_registers_ registers are initialized to point to 76 * The first num_saved_registers_ registers are initialized to point to
77 * "character -1" in the string (i.e., char_size() bytes before the first 77 * "character -1" in the string (i.e., char_size() bytes before the first
78 * character of the string). The remaining registers starts out as garbage. 78 * character of the string). The remaining registers starts out as garbage.
79 * 79 *
80 * The data up to the return address must be placed there by the calling 80 * The data up to the return address must be placed there by the calling
81 * code, e.g., by calling the code entry as cast to: 81 * code, by calling the code entry as cast to a function with the signature:
82 * int (*match)(String* input_string, 82 * int (*match)(String* input_string,
83 * Address start, 83 * Address start,
84 * Address end, 84 * Address end,
85 * int* capture_output_array, 85 * int* capture_output_array,
86 * bool at_start, 86 * bool at_start,
87 * byte* stack_area_top) 87 * byte* stack_area_base)
88 */ 88 */
89 89
90 #define __ ACCESS_MASM(masm_) 90 #define __ ACCESS_MASM(masm_)
91 91
92 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32( 92 RegExpMacroAssemblerIA32::RegExpMacroAssemblerIA32(
93 Mode mode, 93 Mode mode,
94 int registers_to_save) 94 int registers_to_save)
95 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), 95 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)),
96 constants_(kRegExpConstantsSize),
97 mode_(mode), 96 mode_(mode),
98 num_registers_(registers_to_save), 97 num_registers_(registers_to_save),
99 num_saved_registers_(registers_to_save), 98 num_saved_registers_(registers_to_save),
100 entry_label_(), 99 entry_label_(),
101 start_label_(), 100 start_label_(),
102 success_label_(), 101 success_label_(),
103 backtrack_label_(), 102 backtrack_label_(),
104 exit_label_() { 103 exit_label_() {
105 __ jmp(&entry_label_); // We'll write the entry code later. 104 __ jmp(&entry_label_); // We'll write the entry code later.
106 __ bind(&start_label_); // And then continue from here. 105 __ bind(&start_label_); // And then continue from here.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 __ add(Operand(ebx), Immediate(masm_->CodeObject())); 148 __ add(Operand(ebx), Immediate(masm_->CodeObject()));
150 __ jmp(Operand(ebx)); 149 __ jmp(Operand(ebx));
151 } 150 }
152 151
153 152
154 void RegExpMacroAssemblerIA32::Bind(Label* label) { 153 void RegExpMacroAssemblerIA32::Bind(Label* label) {
155 __ bind(label); 154 __ bind(label);
156 } 155 }
157 156
158 157
159 void RegExpMacroAssemblerIA32::CheckBitmap(uc16 start,
160 Label* bitmap,
161 Label* on_zero) {
162 UNIMPLEMENTED();
163 }
164
165
166 void RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) { 158 void RegExpMacroAssemblerIA32::CheckCharacter(uint32_t c, Label* on_equal) {
167 __ cmp(current_character(), c); 159 __ cmp(current_character(), c);
168 BranchOrBacktrack(equal, on_equal); 160 BranchOrBacktrack(equal, on_equal);
169 } 161 }
170 162
171 163
172 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) { 164 void RegExpMacroAssemblerIA32::CheckCharacterGT(uc16 limit, Label* on_greater) {
173 __ cmp(current_character(), limit); 165 __ cmp(current_character(), limit);
174 BranchOrBacktrack(greater, on_greater); 166 BranchOrBacktrack(greater, on_greater);
175 } 167 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 Label* on_failure, 202 Label* on_failure,
211 bool check_end_of_string) { 203 bool check_end_of_string) {
212 int byte_length = str.length() * char_size(); 204 int byte_length = str.length() * char_size();
213 int byte_offset = cp_offset * char_size(); 205 int byte_offset = cp_offset * char_size();
214 if (check_end_of_string) { 206 if (check_end_of_string) {
215 // Check that there are at least str.length() characters left in the input. 207 // Check that there are at least str.length() characters left in the input.
216 __ cmp(Operand(edi), Immediate(-(byte_offset + byte_length))); 208 __ cmp(Operand(edi), Immediate(-(byte_offset + byte_length)));
217 BranchOrBacktrack(greater, on_failure); 209 BranchOrBacktrack(greater, on_failure);
218 } 210 }
219 211
220 Label backtrack;
221 if (on_failure == NULL) { 212 if (on_failure == NULL) {
222 // Avoid inlining the Backtrack macro for each test. 213 // Instead of inlining a backtrack, (re)use the global backtrack target.
223 Label skip_backtrack; 214 on_failure = &backtrack_label_;
224 __ jmp(&skip_backtrack);
225 __ bind(&backtrack);
226 Backtrack();
227 __ bind(&skip_backtrack);
228 on_failure = &backtrack;
229 } 215 }
230 216
231 for (int i = 0; i < str.length(); i++) { 217 for (int i = 0; i < str.length(); i++) {
232 if (mode_ == ASCII) { 218 if (mode_ == ASCII) {
233 __ cmpb(Operand(esi, edi, times_1, byte_offset + i), 219 __ cmpb(Operand(esi, edi, times_1, byte_offset + i),
234 static_cast<int8_t>(str[i])); 220 static_cast<int8_t>(str[i]));
235 } else { 221 } else {
236 ASSERT(mode_ == UC16); 222 ASSERT(mode_ == UC16);
237 __ cmpw(Operand(esi, edi, times_1, byte_offset + i * sizeof(uc16)), 223 __ cmpw(Operand(esi, edi, times_1, byte_offset + i * sizeof(uc16)),
238 Immediate(str[i])); 224 Immediate(str[i]));
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 if (check_offset) { 560 if (check_offset) {
575 CheckPosition(cp_offset, on_no_match); 561 CheckPosition(cp_offset, on_no_match);
576 } 562 }
577 return true; 563 return true;
578 // No custom implementation (yet): w, W, s(UC16), S(UC16). 564 // No custom implementation (yet): w, W, s(UC16), S(UC16).
579 default: 565 default:
580 return false; 566 return false;
581 } 567 }
582 } 568 }
583 569
584 void RegExpMacroAssemblerIA32::DispatchHalfNibbleMap(
585 uc16 start,
586 Label* half_nibble_map,
587 const Vector<Label*>& destinations) {
588 UNIMPLEMENTED();
589 }
590
591
592 void RegExpMacroAssemblerIA32::DispatchByteMap(
593 uc16 start,
594 Label* byte_map,
595 const Vector<Label*>& destinations) {
596 UNIMPLEMENTED();
597 }
598
599
600 void RegExpMacroAssemblerIA32::DispatchHighByteMap(
601 byte start,
602 Label* byte_map,
603 const Vector<Label*>& destinations) {
604 UNIMPLEMENTED();
605 }
606
607
608 void RegExpMacroAssemblerIA32::EmitOrLink(Label* label) {
609 UNIMPLEMENTED(); // Has no use.
610 }
611
612 570
613 void RegExpMacroAssemblerIA32::Fail() { 571 void RegExpMacroAssemblerIA32::Fail() {
614 ASSERT(FAILURE == 0); // Return value for failure is zero. 572 ASSERT(FAILURE == 0); // Return value for failure is zero.
615 __ xor_(eax, Operand(eax)); // zero eax. 573 __ xor_(eax, Operand(eax)); // zero eax.
616 __ jmp(&exit_label_); 574 __ jmp(&exit_label_);
617 } 575 }
618 576
619 577
620 Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) { 578 Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
621 // Finalize code - write the entry point code now we know how many 579 // Finalize code - write the entry point code now we know how many
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 __ bind(&stack_ok); 619 __ bind(&stack_ok);
662 620
663 // Allocate space on stack for registers. 621 // Allocate space on stack for registers.
664 __ sub(Operand(esp), Immediate(num_registers_ * kPointerSize)); 622 __ sub(Operand(esp), Immediate(num_registers_ * kPointerSize));
665 // Load string length. 623 // Load string length.
666 __ mov(esi, Operand(ebp, kInputEnd)); 624 __ mov(esi, Operand(ebp, kInputEnd));
667 // Load input position. 625 // Load input position.
668 __ mov(edi, Operand(ebp, kInputStart)); 626 __ mov(edi, Operand(ebp, kInputStart));
669 // Set up edi to be negative offset from string end. 627 // Set up edi to be negative offset from string end.
670 __ sub(edi, Operand(esi)); 628 __ sub(edi, Operand(esi));
671 if (num_saved_registers_ > 0) { 629 // Set eax to address of char before start of input
630 // (effectively string position -1).
631 __ lea(eax, Operand(edi, -char_size()));
632 // Store this value in a local variable, for use when clearing
633 // position registers.
634 __ mov(Operand(ebp, kInputStartMinusOne), eax);
635 if (num_saved_registers_ > 0) { // Always is, if generated from a regexp.
672 // Fill saved registers with initial value = start offset - 1 636 // Fill saved registers with initial value = start offset - 1
673 // Fill in stack push order, to avoid accessing across an unwritten 637 // Fill in stack push order, to avoid accessing across an unwritten
674 // page (a problem on Windows). 638 // page (a problem on Windows).
675 __ mov(ecx, kRegisterZero); 639 __ mov(ecx, kRegisterZero);
676 // Set eax to address of char before start of input
677 // (effectively string position -1).
678 __ lea(eax, Operand(edi, -char_size()));
679 // Store this value in a local variable, for use when clearing
680 // position registers.
681 __ mov(Operand(ebp, kInputStartMinusOne), eax);
682 Label init_loop; 640 Label init_loop;
683 __ bind(&init_loop); 641 __ bind(&init_loop);
684 __ mov(Operand(ebp, ecx, times_1, +0), eax); 642 __ mov(Operand(ebp, ecx, times_1, +0), eax);
685 __ sub(Operand(ecx), Immediate(kPointerSize)); 643 __ sub(Operand(ecx), Immediate(kPointerSize));
686 __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize); 644 __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
687 __ j(greater, &init_loop); 645 __ j(greater, &init_loop);
688 } 646 }
689 // Ensure that we have written to each stack page, in order. Skipping a page 647 // Ensure that we have written to each stack page, in order. Skipping a page
690 // on Windows can cause segmentation faults. Assuming page size is 4k. 648 // on Windows can cause segmentation faults. Assuming page size is 4k.
691 const int kPageSize = 4096; 649 const int kPageSize = 4096;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 } 893 }
936 894
937 895
938 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) { 896 void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
939 __ mov(eax, backtrack_stackpointer()); 897 __ mov(eax, backtrack_stackpointer());
940 __ sub(eax, Operand(ebp, kStackHighEnd)); 898 __ sub(eax, Operand(ebp, kStackHighEnd));
941 __ mov(register_location(reg), eax); 899 __ mov(register_location(reg), eax);
942 } 900 }
943 901
944 902
945 RegExpMacroAssemblerIA32::Result RegExpMacroAssemblerIA32::Match(
946 Handle<Code> regexp_code,
947 Handle<String> subject,
948 int* offsets_vector,
949 int offsets_vector_length,
950 int previous_index) {
951
952 ASSERT(subject->IsFlat());
953 ASSERT(previous_index >= 0);
954 ASSERT(previous_index <= subject->length());
955
956 // No allocations before calling the regexp, but we can't use
957 // AssertNoAllocation, since regexps might be preempted, and another thread
958 // might do allocation anyway.
959
960 String* subject_ptr = *subject;
961 // Character offsets into string.
962 int start_offset = previous_index;
963 int end_offset = subject_ptr->length();
964
965 bool is_ascii = subject->IsAsciiRepresentation();
966
967 if (StringShape(subject_ptr).IsCons()) {
968 subject_ptr = ConsString::cast(subject_ptr)->first();
969 } else if (StringShape(subject_ptr).IsSliced()) {
970 SlicedString* slice = SlicedString::cast(subject_ptr);
971 start_offset += slice->start();
972 end_offset += slice->start();
973 subject_ptr = slice->buffer();
974 }
975 // Ensure that an underlying string has the same ascii-ness.
976 ASSERT(subject_ptr->IsAsciiRepresentation() == is_ascii);
977 ASSERT(subject_ptr->IsExternalString() || subject_ptr->IsSeqString());
978 // String is now either Sequential or External
979 int char_size_shift = is_ascii ? 0 : 1;
980 int char_length = end_offset - start_offset;
981
982 const byte* input_start =
983 StringCharacterPosition(subject_ptr, start_offset);
984 int byte_length = char_length << char_size_shift;
985 const byte* input_end = input_start + byte_length;
986 RegExpMacroAssemblerIA32::Result res = Execute(*regexp_code,
987 subject_ptr,
988 start_offset,
989 input_start,
990 input_end,
991 offsets_vector,
992 previous_index == 0);
993
994 if (res == SUCCESS) {
995 // Capture values are relative to start_offset only.
996 // Convert them to be relative to start of string.
997 for (int i = 0; i < offsets_vector_length; i++) {
998 if (offsets_vector[i] >= 0) {
999 offsets_vector[i] += previous_index;
1000 }
1001 }
1002 }
1003
1004 return res;
1005 }
1006
1007 // Private methods: 903 // Private methods:
1008 904
1009 static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize;
1010
1011 RegExpMacroAssemblerIA32::Result RegExpMacroAssemblerIA32::Execute(
1012 Code* code,
1013 String* input,
1014 int start_offset,
1015 const byte* input_start,
1016 const byte* input_end,
1017 int* output,
1018 bool at_start) {
1019 typedef int (*matcher)(String*, int, const byte*,
1020 const byte*, int*, int, Address);
1021 matcher matcher_func = FUNCTION_CAST<matcher>(code->entry());
1022
1023 int at_start_val = at_start ? 1 : 0;
1024
1025 // Ensure that the minimum stack has been allocated.
1026 RegExpStack stack;
1027 Address stack_top = RegExpStack::stack_top();
1028
1029 int result = matcher_func(input,
1030 start_offset,
1031 input_start,
1032 input_end,
1033 output,
1034 at_start_val,
1035 stack_top);
1036 ASSERT(result <= SUCCESS);
1037 ASSERT(result >= RETRY);
1038
1039 if (result == EXCEPTION && !Top::has_pending_exception()) {
1040 // We detected a stack overflow (on the backtrack stack) in RegExp code,
1041 // but haven't created the exception yet.
1042 Top::StackOverflow();
1043 }
1044 return static_cast<Result>(result);
1045 }
1046
1047
1048 int RegExpMacroAssemblerIA32::CaseInsensitiveCompareUC16(Address byte_offset1,
1049 Address byte_offset2,
1050 size_t byte_length) {
1051 // This function is not allowed to cause a garbage collection.
1052 // A GC might move the calling generated code and invalidate the
1053 // return address on the stack.
1054 ASSERT(byte_length % 2 == 0);
1055 uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1);
1056 uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2);
1057 size_t length = byte_length >> 1;
1058
1059 for (size_t i = 0; i < length; i++) {
1060 unibrow::uchar c1 = substring1[i];
1061 unibrow::uchar c2 = substring2[i];
1062 if (c1 != c2) {
1063 unibrow::uchar s1[1] = { c1 };
1064 canonicalize.get(c1, '\0', s1);
1065 if (s1[0] != c2) {
1066 unibrow::uchar s2[1] = { c2 };
1067 canonicalize.get(c2, '\0', s2);
1068 if (s1[0] != s2[0]) {
1069 return 0;
1070 }
1071 }
1072 }
1073 }
1074 return 1;
1075 }
1076
1077
1078 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) { 905 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) {
1079 int num_arguments = 3; 906 int num_arguments = 3;
1080 FrameAlign(num_arguments, scratch); 907 FrameAlign(num_arguments, scratch);
1081 // RegExp code frame pointer. 908 // RegExp code frame pointer.
1082 __ mov(Operand(esp, 2 * kPointerSize), ebp); 909 __ mov(Operand(esp, 2 * kPointerSize), ebp);
1083 // Code* of self. 910 // Code* of self.
1084 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); 911 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject()));
1085 // Next address on the stack (will be address of return address). 912 // Next address on the stack (will be address of return address).
1086 __ lea(eax, Operand(esp, -kPointerSize)); 913 __ lea(eax, Operand(esp, -kPointerSize));
1087 __ mov(Operand(esp, 0 * kPointerSize), eax); 914 __ mov(Operand(esp, 0 * kPointerSize), eax);
1088 CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments); 915 CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments);
1089 } 916 }
1090 917
1091 918
1092 // Helper function for reading a value out of a stack frame. 919 // Helper function for reading a value out of a stack frame.
1093 template <typename T> 920 template <typename T>
1094 static T& frame_entry(Address re_frame, int frame_offset) { 921 static T& frame_entry(Address re_frame, int frame_offset) {
1095 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 922 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset));
1096 } 923 }
1097 924
1098 925
1099 const byte* RegExpMacroAssemblerIA32::StringCharacterPosition(String* subject,
1100 int start_index) {
1101 // Not just flat, but ultra flat.
1102 ASSERT(subject->IsExternalString() || subject->IsSeqString());
1103 ASSERT(start_index >= 0);
1104 ASSERT(start_index <= subject->length());
1105 if (subject->IsAsciiRepresentation()) {
1106 const byte* address;
1107 if (StringShape(subject).IsExternal()) {
1108 const char* data = ExternalAsciiString::cast(subject)->resource()->data();
1109 address = reinterpret_cast<const byte*>(data);
1110 } else {
1111 ASSERT(subject->IsSeqAsciiString());
1112 char* data = SeqAsciiString::cast(subject)->GetChars();
1113 address = reinterpret_cast<const byte*>(data);
1114 }
1115 return address + start_index;
1116 }
1117 const uc16* data;
1118 if (StringShape(subject).IsExternal()) {
1119 data = ExternalTwoByteString::cast(subject)->resource()->data();
1120 } else {
1121 ASSERT(subject->IsSeqTwoByteString());
1122 data = SeqTwoByteString::cast(subject)->GetChars();
1123 }
1124 return reinterpret_cast<const byte*>(data + start_index);
1125 }
1126
1127
1128 int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address, 926 int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
1129 Code* re_code, 927 Code* re_code,
1130 Address re_frame) { 928 Address re_frame) {
1131 if (StackGuard::IsStackOverflow()) { 929 if (StackGuard::IsStackOverflow()) {
1132 Top::StackOverflow(); 930 Top::StackOverflow();
1133 return EXCEPTION; 931 return EXCEPTION;
1134 } 932 }
1135 933
1136 // If not real stack overflow the stack guard was used to interrupt 934 // If not real stack overflow the stack guard was used to interrupt
1137 // execution for another purpose. 935 // execution for another purpose.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 frame_entry<const String*>(re_frame, kInputString) = *subject; 989 frame_entry<const String*>(re_frame, kInputString) = *subject;
1192 frame_entry<const byte*>(re_frame, kInputStart) = new_address; 990 frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1193 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length; 991 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
1194 } 992 }
1195 993
1196 return 0; 994 return 0;
1197 } 995 }
1198 996
1199 997
1200 Address RegExpMacroAssemblerIA32::GrowStack(Address stack_pointer, 998 Address RegExpMacroAssemblerIA32::GrowStack(Address stack_pointer,
1201 Address* stack_top) { 999 Address* stack_base) {
1202 size_t size = RegExpStack::stack_capacity(); 1000 size_t size = RegExpStack::stack_capacity();
1203 Address old_stack_top = RegExpStack::stack_top(); 1001 Address old_stack_base = RegExpStack::stack_base();
1204 ASSERT(old_stack_top == *stack_top); 1002 ASSERT(old_stack_base == *stack_base);
1205 ASSERT(stack_pointer <= old_stack_top); 1003 ASSERT(stack_pointer <= old_stack_base);
1206 ASSERT(static_cast<size_t>(old_stack_top - stack_pointer) <= size); 1004 ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size);
1207 Address new_stack_top = RegExpStack::EnsureCapacity(size * 2); 1005 Address new_stack_base = RegExpStack::EnsureCapacity(size * 2);
1208 if (new_stack_top == NULL) { 1006 if (new_stack_base == NULL) {
1209 return NULL; 1007 return NULL;
1210 } 1008 }
1211 *stack_top = new_stack_top; 1009 *stack_base = new_stack_base;
1212 return new_stack_top - (old_stack_top - stack_pointer); 1010 return new_stack_base - (old_stack_base - stack_pointer);
1213 } 1011 }
1214 1012
1215 1013
1216 Operand RegExpMacroAssemblerIA32::register_location(int register_index) { 1014 Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
1217 ASSERT(register_index < (1<<30)); 1015 ASSERT(register_index < (1<<30));
1218 if (num_registers_ <= register_index) { 1016 if (num_registers_ <= register_index) {
1219 num_registers_ = register_index + 1; 1017 num_registers_ = register_index + 1;
1220 } 1018 }
1221 return Operand(ebp, kRegisterZero - register_index * kPointerSize); 1019 return Operand(ebp, kRegisterZero - register_index * kPointerSize);
1222 } 1020 }
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); 1164 Operand(esi, edi, times_1, cp_offset * sizeof(uc16)));
1367 } else { 1165 } else {
1368 ASSERT(characters == 1); 1166 ASSERT(characters == 1);
1369 __ movzx_w(current_character(), 1167 __ movzx_w(current_character(),
1370 Operand(esi, edi, times_1, cp_offset * sizeof(uc16))); 1168 Operand(esi, edi, times_1, cp_offset * sizeof(uc16)));
1371 } 1169 }
1372 } 1170 }
1373 } 1171 }
1374 1172
1375 1173
1376 void RegExpMacroAssemblerIA32::LoadConstantBufferAddress(Register reg,
1377 ArraySlice* buffer) {
1378 __ mov(reg, buffer->array());
1379 __ add(Operand(reg), Immediate(buffer->base_offset()));
1380 }
1381
1382 #undef __ 1174 #undef __
1383 }} // namespace v8::internal 1175 }} // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698