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

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

Issue 1988009: RegExp: Remove use of 16-bit immediates on ia32/x64. (Closed)
Patch Set: Created 10 years, 7 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 2009 the V8 project authors. All rights reserved. 1 // Copyright 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 181
182 void RegExpMacroAssemblerX64::CheckCharacterGT(uc16 limit, Label* on_greater) { 182 void RegExpMacroAssemblerX64::CheckCharacterGT(uc16 limit, Label* on_greater) {
183 __ cmpl(current_character(), Immediate(limit)); 183 __ cmpl(current_character(), Immediate(limit));
184 BranchOrBacktrack(greater, on_greater); 184 BranchOrBacktrack(greater, on_greater);
185 } 185 }
186 186
187 187
188 void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) { 188 void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) {
189 Label not_at_start; 189 Label not_at_start;
190 // Did we start the match at the start of the string at all? 190 // Did we start the match at the start of the string at all?
191 __ cmpb(Operand(rbp, kAtStart), Immediate(0)); 191 __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
192 BranchOrBacktrack(equal, &not_at_start); 192 BranchOrBacktrack(not_equal, &not_at_start);
193 // If we did, are we still at the start of the input? 193 // If we did, are we still at the start of the input?
194 __ lea(rax, Operand(rsi, rdi, times_1, 0)); 194 __ lea(rax, Operand(rsi, rdi, times_1, 0));
195 __ cmpq(rax, Operand(rbp, kInputStart)); 195 __ cmpq(rax, Operand(rbp, kInputStart));
196 BranchOrBacktrack(equal, on_at_start); 196 BranchOrBacktrack(equal, on_at_start);
197 __ bind(&not_at_start); 197 __ bind(&not_at_start);
198 } 198 }
199 199
200 200
201 void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) { 201 void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) {
202 // Did we start the match at the start of the string at all? 202 // Did we start the match at the start of the string at all?
203 __ cmpb(Operand(rbp, kAtStart), Immediate(0)); 203 __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
204 BranchOrBacktrack(equal, on_not_at_start); 204 BranchOrBacktrack(not_equal, on_not_at_start);
205 // If we did, are we still at the start of the input? 205 // If we did, are we still at the start of the input?
206 __ lea(rax, Operand(rsi, rdi, times_1, 0)); 206 __ lea(rax, Operand(rsi, rdi, times_1, 0));
207 __ cmpq(rax, Operand(rbp, kInputStart)); 207 __ cmpq(rax, Operand(rbp, kInputStart));
208 BranchOrBacktrack(not_equal, on_not_at_start); 208 BranchOrBacktrack(not_equal, on_not_at_start);
209 } 209 }
210 210
211 211
212 void RegExpMacroAssemblerX64::CheckCharacterLT(uc16 limit, Label* on_less) { 212 void RegExpMacroAssemblerX64::CheckCharacterLT(uc16 limit, Label* on_less) {
213 __ cmpl(current_character(), Immediate(limit)); 213 __ cmpl(current_character(), Immediate(limit));
214 BranchOrBacktrack(less, on_less); 214 BranchOrBacktrack(less, on_less);
215 } 215 }
216 216
217 217
218 void RegExpMacroAssemblerX64::CheckCharacters(Vector<const uc16> str, 218 void RegExpMacroAssemblerX64::CheckCharacters(Vector<const uc16> str,
219 int cp_offset, 219 int cp_offset,
220 Label* on_failure, 220 Label* on_failure,
221 bool check_end_of_string) { 221 bool check_end_of_string) {
222 #ifdef DEBUG
223 // If input is ASCII, don't even bother calling here if the string to
224 // match contains a non-ascii character.
225 if (mode_ == ASCII) {
226 for (int i = 0; i < str.length(); i++) {
227 ASSERT(str[i] <= String::kMaxAsciiCharCodeU);
228 }
229 }
230 #endif
222 int byte_length = str.length() * char_size(); 231 int byte_length = str.length() * char_size();
223 int byte_offset = cp_offset * char_size(); 232 int byte_offset = cp_offset * char_size();
224 if (check_end_of_string) { 233 if (check_end_of_string) {
225 // Check that there are at least str.length() characters left in the input. 234 // Check that there are at least str.length() characters left in the input.
226 __ cmpl(rdi, Immediate(-(byte_offset + byte_length))); 235 __ cmpl(rdi, Immediate(-(byte_offset + byte_length)));
227 BranchOrBacktrack(greater, on_failure); 236 BranchOrBacktrack(greater, on_failure);
228 } 237 }
229 238
230 if (on_failure == NULL) { 239 if (on_failure == NULL) {
231 // Instead of inlining a backtrack, (re)use the global backtrack target. 240 // Instead of inlining a backtrack, (re)use the global backtrack target.
232 on_failure = &backtrack_label_; 241 on_failure = &backtrack_label_;
233 } 242 }
234 243
235 // TODO(lrn): Test multiple characters at a time by loading 4 or 8 bytes 244 // Do one character test first to minimize loading for the case that
236 // at a time. 245 // we don't match at all (loading more than one character introduces that
237 for (int i = 0; i < str.length(); i++) { 246 // chance of reading unaligned and reading across cache boundaries).
247 // If the first character matches, expect a larger chance of matching the
248 // string, and start loading more characters at a time.
249 if (mode_ == ASCII) {
250 __ cmpb(Operand(rsi, rdi, times_1, byte_offset),
251 Immediate(static_cast<int8_t>(str[0])));
252 } else {
253 // Don't use 16-bit immediate. The size changing prefix throws off
254 // pre-decoding.
255 __ movzxwl(rax,
256 Operand(rsi, rdi, times_1, byte_offset));
257 __ cmpl(rax, Immediate(static_cast<int32_t>(str[0])));
258 }
259 BranchOrBacktrack(not_equal, on_failure);
260
261 __ lea(rbx, Operand(rsi, rdi, times_1, 0));
262 for (int i = 1, n = str.length(); i < n; ) {
238 if (mode_ == ASCII) { 263 if (mode_ == ASCII) {
239 __ cmpb(Operand(rsi, rdi, times_1, byte_offset + i), 264 if (i + 8 <= n) {
240 Immediate(static_cast<int8_t>(str[i]))); 265 uint64_t combined_chars =
266 (static_cast<uint64_t>(str[i + 0]) << 0) ||
267 (static_cast<uint64_t>(str[i + 1]) << 8) ||
268 (static_cast<uint64_t>(str[i + 2]) << 16) ||
269 (static_cast<uint64_t>(str[i + 3]) << 24) ||
270 (static_cast<uint64_t>(str[i + 4]) << 32) ||
271 (static_cast<uint64_t>(str[i + 5]) << 40) ||
272 (static_cast<uint64_t>(str[i + 6]) << 48) ||
273 (static_cast<uint64_t>(str[i + 7]) << 56);
274 __ movq(rax, combined_chars, RelocInfo::NONE);
275 __ cmpq(rax, Operand(rbx, byte_offset + i));
276 i += 8;
277 } else if (i + 4 <= n) {
278 uint32_t combined_chars =
279 (static_cast<uint32_t>(str[i + 0]) << 0) ||
280 (static_cast<uint32_t>(str[i + 1]) << 8) ||
281 (static_cast<uint32_t>(str[i + 2]) << 16) ||
282 (static_cast<uint32_t>(str[i + 3]) << 24);
283 __ cmpl(Operand(rbx, byte_offset + i), Immediate(combined_chars));
284 i += 4;
285 } else {
286 __ cmpb(Operand(rbx, byte_offset + i),
287 Immediate(static_cast<int8_t>(str[i])));
288 i++;
289 }
241 } else { 290 } else {
242 ASSERT(mode_ == UC16); 291 ASSERT(mode_ == UC16);
243 __ cmpw(Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)), 292 if (i + 4 <= n) {
244 Immediate(str[i])); 293 uint64_t combined_chars = *reinterpret_cast<const uint64_t*>(&str[i]);
294 __ movq(rax, combined_chars, RelocInfo::NONE);
295 __ cmpq(rax,
296 Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)));
297 i += 4;
298 } else if (i + 2 <= n) {
299 uint32_t combined_chars = *reinterpret_cast<const uint32_t*>(&str[i]);
300 __ cmpl(Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)),
301 Immediate(combined_chars));
302 i += 2;
303 } else {
304 __ movzxwl(rax,
305 Operand(rsi, rdi, times_1, byte_offset + i * sizeof(uc16)));
306 __ cmpl(rax, Immediate(str[i]));
307 i++;
308 }
245 } 309 }
246 BranchOrBacktrack(not_equal, on_failure); 310 BranchOrBacktrack(not_equal, on_failure);
247 } 311 }
248 } 312 }
249 313
250 314
251 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) { 315 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
252 Label fallthrough; 316 Label fallthrough;
253 __ cmpl(rdi, Operand(backtrack_stackpointer(), 0)); 317 __ cmpl(rdi, Operand(backtrack_stackpointer(), 0));
254 __ j(not_equal, &fallthrough); 318 __ j(not_equal, &fallthrough);
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 __ push(rdi); 728 __ push(rdi);
665 __ push(rsi); 729 __ push(rsi);
666 __ push(rdx); 730 __ push(rdx);
667 __ push(rcx); 731 __ push(rcx);
668 __ push(r8); 732 __ push(r8);
669 __ push(r9); 733 __ push(r9);
670 734
671 __ push(rbx); // Callee-save 735 __ push(rbx); // Callee-save
672 #endif 736 #endif
673 737
674 __ push(Immediate(0)); // Make room for "input start - 1" constant.
675 __ push(Immediate(0)); // Make room for "at start" constant. 738 __ push(Immediate(0)); // Make room for "at start" constant.
676 739
677 // Check if we have space on the stack for registers. 740 // Check if we have space on the stack for registers.
678 Label stack_limit_hit; 741 Label stack_limit_hit;
679 Label stack_ok; 742 Label stack_ok;
680 743
681 ExternalReference stack_limit = 744 ExternalReference stack_limit =
682 ExternalReference::address_of_stack_limit(); 745 ExternalReference::address_of_stack_limit();
683 __ movq(rcx, rsp); 746 __ movq(rcx, rsp);
684 __ movq(kScratchRegister, stack_limit); 747 __ movq(kScratchRegister, stack_limit);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 __ neg(rbx); 780 __ neg(rbx);
718 if (mode_ == UC16) { 781 if (mode_ == UC16) {
719 __ lea(rax, Operand(rdi, rbx, times_2, -char_size())); 782 __ lea(rax, Operand(rdi, rbx, times_2, -char_size()));
720 } else { 783 } else {
721 __ lea(rax, Operand(rdi, rbx, times_1, -char_size())); 784 __ lea(rax, Operand(rdi, rbx, times_1, -char_size()));
722 } 785 }
723 // Store this value in a local variable, for use when clearing 786 // Store this value in a local variable, for use when clearing
724 // position registers. 787 // position registers.
725 __ movq(Operand(rbp, kInputStartMinusOne), rax); 788 __ movq(Operand(rbp, kInputStartMinusOne), rax);
726 789
727 // Determine whether the start index is zero, that is at the start of the
728 // string, and store that value in a local variable.
729 __ movq(rbx, Operand(rbp, kStartIndex));
730 __ xor_(rcx, rcx); // setcc only operates on cl (lower byte of rcx).
731 __ testq(rbx, rbx);
732 __ setcc(zero, rcx); // 1 if 0 (start of string), 0 if positive.
733 __ movq(Operand(rbp, kAtStart), rcx);
734
735 if (num_saved_registers_ > 0) { 790 if (num_saved_registers_ > 0) {
736 // Fill saved registers with initial value = start offset - 1 791 // Fill saved registers with initial value = start offset - 1
737 // Fill in stack push order, to avoid accessing across an unwritten 792 // Fill in stack push order, to avoid accessing across an unwritten
738 // page (a problem on Windows). 793 // page (a problem on Windows).
739 __ movq(rcx, Immediate(kRegisterZero)); 794 __ movq(rcx, Immediate(kRegisterZero));
740 Label init_loop; 795 Label init_loop;
741 __ bind(&init_loop); 796 __ bind(&init_loop);
742 __ movq(Operand(rbp, rcx, times_1, 0), rax); 797 __ movq(Operand(rbp, rcx, times_1, 0), rax);
743 __ subq(rcx, Immediate(kPointerSize)); 798 __ subq(rcx, Immediate(kPointerSize));
744 __ cmpq(rcx, 799 __ cmpq(rcx,
745 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize)); 800 Immediate(kRegisterZero - num_saved_registers_ * kPointerSize));
746 __ j(greater, &init_loop); 801 __ j(greater, &init_loop);
747 } 802 }
748 // Ensure that we have written to each stack page, in order. Skipping a page 803 // Ensure that we have written to each stack page, in order. Skipping a page
749 // on Windows can cause segmentation faults. Assuming page size is 4k. 804 // on Windows can cause segmentation faults. Assuming page size is 4k.
750 const int kPageSize = 4096; 805 const int kPageSize = 4096;
751 const int kRegistersPerPage = kPageSize / kPointerSize; 806 const int kRegistersPerPage = kPageSize / kPointerSize;
752 for (int i = num_saved_registers_ + kRegistersPerPage - 1; 807 for (int i = num_saved_registers_ + kRegistersPerPage - 1;
753 i < num_registers_; 808 i < num_registers_;
754 i += kRegistersPerPage) { 809 i += kRegistersPerPage) {
755 __ movq(register_location(i), rax); // One write every page. 810 __ movq(register_location(i), rax); // One write every page.
756 } 811 }
757 812
758 // Initialize backtrack stack pointer. 813 // Initialize backtrack stack pointer.
759 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); 814 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
760 // Initialize code object pointer. 815 // Initialize code object pointer.
761 __ Move(code_object_pointer(), masm_->CodeObject()); 816 __ Move(code_object_pointer(), masm_->CodeObject());
762 // Load previous char as initial value of current-character. 817 // Load previous char as initial value of current-character.
763 Label at_start; 818 Label at_start;
764 __ cmpb(Operand(rbp, kAtStart), Immediate(0)); 819 __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
765 __ j(not_equal, &at_start); 820 __ j(equal, &at_start);
766 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. 821 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
767 __ jmp(&start_label_); 822 __ jmp(&start_label_);
768 __ bind(&at_start); 823 __ bind(&at_start);
769 __ movq(current_character(), Immediate('\n')); 824 __ movq(current_character(), Immediate('\n'));
770 __ jmp(&start_label_); 825 __ jmp(&start_label_);
771 826
772 827
773 // Exit code: 828 // Exit code:
774 if (success_label_.is_linked()) { 829 if (success_label_.is_linked()) {
775 // Save captures when successful. 830 // Save captures when successful.
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); 1361 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16)));
1307 } 1362 }
1308 } 1363 }
1309 } 1364 }
1310 1365
1311 #undef __ 1366 #undef __
1312 1367
1313 #endif // V8_INTERPRETED_REGEXP 1368 #endif // V8_INTERPRETED_REGEXP
1314 1369
1315 }} // namespace v8::internal 1370 }} // namespace v8::internal
OLDNEW
« src/ia32/regexp-macro-assembler-ia32.cc ('K') | « src/x64/regexp-macro-assembler-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698