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

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

Issue 1451373003: Revert of Experimental support for RegExp lookbehind. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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/x64/regexp-macro-assembler-x64.h ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/regexp/x64/regexp-macro-assembler-x64.h" 7 #include "src/regexp/x64/regexp-macro-assembler-x64.h"
8 8
9 #include "src/log.h" 9 #include "src/log.h"
10 #include "src/macro-assembler.h" 10 #include "src/macro-assembler.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 * - capture array size (may fit multiple sets of matches) 57 * - capture array size (may fit multiple sets of matches)
58 * - int* capture_array (int[num_saved_registers_], for output). 58 * - int* capture_array (int[num_saved_registers_], for output).
59 * - end of input (address of end of string) 59 * - end of input (address of end of string)
60 * - start of input (address of first character in string) 60 * - start of input (address of first character in string)
61 * - start index (character index of start) 61 * - start index (character index of start)
62 * - String* input_string (input string) 62 * - String* input_string (input string)
63 * - return address 63 * - return address
64 * - backup of callee save registers (rbx, possibly rsi and rdi). 64 * - backup of callee save registers (rbx, possibly rsi and rdi).
65 * - success counter (only useful for global regexp to count matches) 65 * - success counter (only useful for global regexp to count matches)
66 * - Offset of location before start of input (effectively character 66 * - Offset of location before start of input (effectively character
67 * string start - 1). Used to initialize capture registers to a 67 * position -1). Used to initialize capture registers to a non-position.
68 * non-position.
69 * - At start of string (if 1, we are starting at the start of the 68 * - At start of string (if 1, we are starting at the start of the
70 * string, otherwise 0) 69 * string, otherwise 0)
71 * - register 0 rbp[-n] (Only positions must be stored in the first 70 * - register 0 rbp[-n] (Only positions must be stored in the first
72 * - register 1 rbp[-n-8] num_saved_registers_ registers) 71 * - register 1 rbp[-n-8] num_saved_registers_ registers)
73 * - ... 72 * - ...
74 * 73 *
75 * The first num_saved_registers_ registers are initialized to point to 74 * The first num_saved_registers_ registers are initialized to point to
76 * "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
77 * character of the string). The remaining registers starts out uninitialized. 76 * character of the string). The remaining registers starts out uninitialized.
78 * 77 *
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 164 }
166 165
167 166
168 void RegExpMacroAssemblerX64::CheckCharacterGT(uc16 limit, Label* on_greater) { 167 void RegExpMacroAssemblerX64::CheckCharacterGT(uc16 limit, Label* on_greater) {
169 __ cmpl(current_character(), Immediate(limit)); 168 __ cmpl(current_character(), Immediate(limit));
170 BranchOrBacktrack(greater, on_greater); 169 BranchOrBacktrack(greater, on_greater);
171 } 170 }
172 171
173 172
174 void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) { 173 void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) {
175 __ leap(rax, Operand(rdi, -char_size())); 174 Label not_at_start;
176 __ cmpp(rax, Operand(rbp, kStringStartMinusOne)); 175 // Did we start the match at the start of the string at all?
176 __ cmpl(Operand(rbp, kStartIndex), Immediate(0));
177 BranchOrBacktrack(not_equal, &not_at_start);
178 // If we did, are we still at the start of the input?
179 __ leap(rax, Operand(rsi, rdi, times_1, 0));
180 __ cmpp(rax, Operand(rbp, kInputStart));
177 BranchOrBacktrack(equal, on_at_start); 181 BranchOrBacktrack(equal, on_at_start);
182 __ bind(&not_at_start);
178 } 183 }
179 184
180 185
181 void RegExpMacroAssemblerX64::CheckNotAtStart(int cp_offset, 186 void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) {
182 Label* on_not_at_start) { 187 // Did we start the match at the start of the string at all?
183 __ leap(rax, Operand(rdi, -char_size() + cp_offset * char_size())); 188 __ cmpl(Operand(rbp, kStartIndex), Immediate(0));
184 __ cmpp(rax, Operand(rbp, kStringStartMinusOne)); 189 BranchOrBacktrack(not_equal, on_not_at_start);
190 // If we did, are we still at the start of the input?
191 __ leap(rax, Operand(rsi, rdi, times_1, 0));
192 __ cmpp(rax, Operand(rbp, kInputStart));
185 BranchOrBacktrack(not_equal, on_not_at_start); 193 BranchOrBacktrack(not_equal, on_not_at_start);
186 } 194 }
187 195
188 196
189 void RegExpMacroAssemblerX64::CheckCharacterLT(uc16 limit, Label* on_less) { 197 void RegExpMacroAssemblerX64::CheckCharacterLT(uc16 limit, Label* on_less) {
190 __ cmpl(current_character(), Immediate(limit)); 198 __ cmpl(current_character(), Immediate(limit));
191 BranchOrBacktrack(less, on_less); 199 BranchOrBacktrack(less, on_less);
192 } 200 }
193 201
194 202
195 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) { 203 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
196 Label fallthrough; 204 Label fallthrough;
197 __ cmpl(rdi, Operand(backtrack_stackpointer(), 0)); 205 __ cmpl(rdi, Operand(backtrack_stackpointer(), 0));
198 __ j(not_equal, &fallthrough); 206 __ j(not_equal, &fallthrough);
199 Drop(); 207 Drop();
200 BranchOrBacktrack(no_condition, on_equal); 208 BranchOrBacktrack(no_condition, on_equal);
201 __ bind(&fallthrough); 209 __ bind(&fallthrough);
202 } 210 }
203 211
204 212
205 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( 213 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
206 int start_reg, bool read_backward, Label* on_no_match) { 214 int start_reg,
215 Label* on_no_match) {
207 Label fallthrough; 216 Label fallthrough;
208 ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture 217 ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture
209 ReadPositionFromRegister(rbx, start_reg + 1); // Offset of end of capture 218 ReadPositionFromRegister(rbx, start_reg + 1); // Offset of end of capture
210 __ subp(rbx, rdx); // Length of capture. 219 __ subp(rbx, rdx); // Length of capture.
211 220
212 // ----------------------- 221 // -----------------------
213 // rdx = Start offset of capture. 222 // rdx = Start offset of capture.
214 // rbx = Length of capture 223 // rbx = Length of capture
215 224
216 // At this point, the capture registers are either both set or both cleared. 225 // If length is negative, this code will fail (it's a symptom of a partial or
217 // If the capture length is zero, then the capture is either empty or cleared. 226 // illegal capture where start of capture after end of capture).
218 // Fall through in both cases. 227 // This must not happen (no back-reference can reference a capture that wasn't
228 // closed before in the reg-exp, and we must not generate code that can cause
229 // this condition).
230
231 // If length is zero, either the capture is empty or it is nonparticipating.
232 // In either case succeed immediately.
219 __ j(equal, &fallthrough); 233 __ j(equal, &fallthrough);
220 234
221 // ----------------------- 235 // -----------------------
222 // rdx - Start of capture 236 // rdx - Start of capture
223 // rbx - length of capture 237 // rbx - length of capture
224 // Check that there are sufficient characters left in the input. 238 // Check that there are sufficient characters left in the input.
225 if (read_backward) { 239 __ movl(rax, rdi);
226 __ movl(rax, Operand(rbp, kStringStartMinusOne)); 240 __ addl(rax, rbx);
227 __ addl(rax, rbx); 241 BranchOrBacktrack(greater, on_no_match);
228 __ cmpl(rdi, rax);
229 BranchOrBacktrack(less_equal, on_no_match);
230 } else {
231 __ movl(rax, rdi);
232 __ addl(rax, rbx);
233 BranchOrBacktrack(greater, on_no_match);
234 }
235 242
236 if (mode_ == LATIN1) { 243 if (mode_ == LATIN1) {
237 Label loop_increment; 244 Label loop_increment;
238 if (on_no_match == NULL) { 245 if (on_no_match == NULL) {
239 on_no_match = &backtrack_label_; 246 on_no_match = &backtrack_label_;
240 } 247 }
241 248
242 __ leap(r9, Operand(rsi, rdx, times_1, 0)); 249 __ leap(r9, Operand(rsi, rdx, times_1, 0));
243 __ leap(r11, Operand(rsi, rdi, times_1, 0)); 250 __ leap(r11, Operand(rsi, rdi, times_1, 0));
244 if (read_backward) {
245 __ subp(r11, rbx); // Offset by length when matching backwards.
246 }
247 __ addp(rbx, r9); // End of capture 251 __ addp(rbx, r9); // End of capture
248 // --------------------- 252 // ---------------------
249 // r11 - current input character address 253 // r11 - current input character address
250 // r9 - current capture character address 254 // r9 - current capture character address
251 // rbx - end of capture 255 // rbx - end of capture
252 256
253 Label loop; 257 Label loop;
254 __ bind(&loop); 258 __ bind(&loop);
255 __ movzxbl(rdx, Operand(r9, 0)); 259 __ movzxbl(rdx, Operand(r9, 0));
256 __ movzxbl(rax, Operand(r11, 0)); 260 __ movzxbl(rax, Operand(r11, 0));
(...skipping 22 matching lines...) Expand all
279 // Increment pointers into match and capture strings. 283 // Increment pointers into match and capture strings.
280 __ addp(r11, Immediate(1)); 284 __ addp(r11, Immediate(1));
281 __ addp(r9, Immediate(1)); 285 __ addp(r9, Immediate(1));
282 // Compare to end of capture, and loop if not done. 286 // Compare to end of capture, and loop if not done.
283 __ cmpp(r9, rbx); 287 __ cmpp(r9, rbx);
284 __ j(below, &loop); 288 __ j(below, &loop);
285 289
286 // Compute new value of character position after the matched part. 290 // Compute new value of character position after the matched part.
287 __ movp(rdi, r11); 291 __ movp(rdi, r11);
288 __ subq(rdi, rsi); 292 __ subq(rdi, rsi);
289 if (read_backward) {
290 // Subtract match length if we matched backward.
291 __ addq(rdi, register_location(start_reg));
292 __ subq(rdi, register_location(start_reg + 1));
293 }
294 } else { 293 } else {
295 DCHECK(mode_ == UC16); 294 DCHECK(mode_ == UC16);
296 // Save important/volatile registers before calling C function. 295 // Save important/volatile registers before calling C function.
297 #ifndef _WIN64 296 #ifndef _WIN64
298 // Caller save on Linux and callee save in Windows. 297 // Caller save on Linux and callee save in Windows.
299 __ pushq(rsi); 298 __ pushq(rsi);
300 __ pushq(rdi); 299 __ pushq(rdi);
301 #endif 300 #endif
302 __ pushq(backtrack_stackpointer()); 301 __ pushq(backtrack_stackpointer());
303 302
304 static const int num_arguments = 4; 303 static const int num_arguments = 4;
305 __ PrepareCallCFunction(num_arguments); 304 __ PrepareCallCFunction(num_arguments);
306 305
307 // Put arguments into parameter registers. Parameters are 306 // Put arguments into parameter registers. Parameters are
308 // Address byte_offset1 - Address captured substring's start. 307 // Address byte_offset1 - Address captured substring's start.
309 // Address byte_offset2 - Address of current character position. 308 // Address byte_offset2 - Address of current character position.
310 // size_t byte_length - length of capture in bytes(!) 309 // size_t byte_length - length of capture in bytes(!)
311 // Isolate* isolate 310 // Isolate* isolate
312 #ifdef _WIN64 311 #ifdef _WIN64
313 // Compute and set byte_offset1 (start of capture). 312 // Compute and set byte_offset1 (start of capture).
314 __ leap(rcx, Operand(rsi, rdx, times_1, 0)); 313 __ leap(rcx, Operand(rsi, rdx, times_1, 0));
315 // Set byte_offset2. 314 // Set byte_offset2.
316 __ leap(rdx, Operand(rsi, rdi, times_1, 0)); 315 __ leap(rdx, Operand(rsi, rdi, times_1, 0));
317 if (read_backward) {
318 __ subq(rdx, rbx);
319 }
320 // Set byte_length. 316 // Set byte_length.
321 __ movp(r8, rbx); 317 __ movp(r8, rbx);
322 // Isolate. 318 // Isolate.
323 __ LoadAddress(r9, ExternalReference::isolate_address(isolate())); 319 __ LoadAddress(r9, ExternalReference::isolate_address(isolate()));
324 #else // AMD64 calling convention 320 #else // AMD64 calling convention
325 // Compute byte_offset2 (current position = rsi+rdi). 321 // Compute byte_offset2 (current position = rsi+rdi).
326 __ leap(rax, Operand(rsi, rdi, times_1, 0)); 322 __ leap(rax, Operand(rsi, rdi, times_1, 0));
327 // Compute and set byte_offset1 (start of capture). 323 // Compute and set byte_offset1 (start of capture).
328 __ leap(rdi, Operand(rsi, rdx, times_1, 0)); 324 __ leap(rdi, Operand(rsi, rdx, times_1, 0));
329 // Set byte_offset2. 325 // Set byte_offset2.
330 __ movp(rsi, rax); 326 __ movp(rsi, rax);
331 if (read_backward) {
332 __ subq(rsi, rbx);
333 }
334 // Set byte_length. 327 // Set byte_length.
335 __ movp(rdx, rbx); 328 __ movp(rdx, rbx);
336 // Isolate. 329 // Isolate.
337 __ LoadAddress(rcx, ExternalReference::isolate_address(isolate())); 330 __ LoadAddress(rcx, ExternalReference::isolate_address(isolate()));
338 #endif 331 #endif
339 332
340 { // NOLINT: Can't find a way to open this scope without confusing the 333 { // NOLINT: Can't find a way to open this scope without confusing the
341 // linter. 334 // linter.
342 AllowExternalCallThatCantCauseGC scope(&masm_); 335 AllowExternalCallThatCantCauseGC scope(&masm_);
343 ExternalReference compare = 336 ExternalReference compare =
344 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 337 ExternalReference::re_case_insensitive_compare_uc16(isolate());
345 __ CallCFunction(compare, num_arguments); 338 __ CallCFunction(compare, num_arguments);
346 } 339 }
347 340
348 // Restore original values before reacting on result value. 341 // Restore original values before reacting on result value.
349 __ Move(code_object_pointer(), masm_.CodeObject()); 342 __ Move(code_object_pointer(), masm_.CodeObject());
350 __ popq(backtrack_stackpointer()); 343 __ popq(backtrack_stackpointer());
351 #ifndef _WIN64 344 #ifndef _WIN64
352 __ popq(rdi); 345 __ popq(rdi);
353 __ popq(rsi); 346 __ popq(rsi);
354 #endif 347 #endif
355 348
356 // Check if function returned non-zero for success or zero for failure. 349 // Check if function returned non-zero for success or zero for failure.
357 __ testp(rax, rax); 350 __ testp(rax, rax);
358 BranchOrBacktrack(zero, on_no_match); 351 BranchOrBacktrack(zero, on_no_match);
359 // On success, advance position by length of capture. 352 // On success, increment position by length of capture.
360 // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs). 353 // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs).
361 if (read_backward) { 354 __ addq(rdi, rbx);
362 __ subq(rdi, rbx);
363 } else {
364 __ addq(rdi, rbx);
365 }
366 } 355 }
367 __ bind(&fallthrough); 356 __ bind(&fallthrough);
368 } 357 }
369 358
370 359
371 void RegExpMacroAssemblerX64::CheckNotBackReference(int start_reg, 360 void RegExpMacroAssemblerX64::CheckNotBackReference(
372 bool read_backward, 361 int start_reg,
373 Label* on_no_match) { 362 Label* on_no_match) {
374 Label fallthrough; 363 Label fallthrough;
375 364
376 // Find length of back-referenced capture. 365 // Find length of back-referenced capture.
377 ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture 366 ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture
378 ReadPositionFromRegister(rax, start_reg + 1); // Offset of end of capture 367 ReadPositionFromRegister(rax, start_reg + 1); // Offset of end of capture
379 __ subp(rax, rdx); // Length to check. 368 __ subp(rax, rdx); // Length to check.
380 369
381 // At this point, the capture registers are either both set or both cleared. 370 // Fail on partial or illegal capture (start of capture after end of capture).
382 // If the capture length is zero, then the capture is either empty or cleared. 371 // This must not happen (no back-reference can reference a capture that wasn't
383 // Fall through in both cases. 372 // closed before in the reg-exp).
373 __ Check(greater_equal, kInvalidCaptureReferenced);
374
375 // Succeed on empty capture (including non-participating capture)
384 __ j(equal, &fallthrough); 376 __ j(equal, &fallthrough);
385 377
386 // ----------------------- 378 // -----------------------
387 // rdx - Start of capture 379 // rdx - Start of capture
388 // rax - length of capture 380 // rax - length of capture
381
389 // Check that there are sufficient characters left in the input. 382 // Check that there are sufficient characters left in the input.
390 if (read_backward) { 383 __ movl(rbx, rdi);
391 __ movl(rbx, Operand(rbp, kStringStartMinusOne)); 384 __ addl(rbx, rax);
392 __ addl(rbx, rax); 385 BranchOrBacktrack(greater, on_no_match);
393 __ cmpl(rdi, rbx);
394 BranchOrBacktrack(less_equal, on_no_match);
395 } else {
396 __ movl(rbx, rdi);
397 __ addl(rbx, rax);
398 BranchOrBacktrack(greater, on_no_match);
399 }
400 386
401 // Compute pointers to match string and capture string 387 // Compute pointers to match string and capture string
402 __ leap(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match. 388 __ leap(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match.
403 if (read_backward) {
404 __ subq(rbx, rax); // Offset by length when matching backwards.
405 }
406 __ addp(rdx, rsi); // Start of capture. 389 __ addp(rdx, rsi); // Start of capture.
407 __ leap(r9, Operand(rdx, rax, times_1, 0)); // End of capture 390 __ leap(r9, Operand(rdx, rax, times_1, 0)); // End of capture
408 391
409 // ----------------------- 392 // -----------------------
410 // rbx - current capture character address. 393 // rbx - current capture character address.
411 // rbx - current input character address . 394 // rbx - current input character address .
412 // r9 - end of input to match (capture length after rbx). 395 // r9 - end of input to match (capture length after rbx).
413 396
414 Label loop; 397 Label loop;
415 __ bind(&loop); 398 __ bind(&loop);
(...skipping 10 matching lines...) Expand all
426 __ addp(rbx, Immediate(char_size())); 409 __ addp(rbx, Immediate(char_size()));
427 __ addp(rdx, Immediate(char_size())); 410 __ addp(rdx, Immediate(char_size()));
428 // Check if we have reached end of match area. 411 // Check if we have reached end of match area.
429 __ cmpp(rdx, r9); 412 __ cmpp(rdx, r9);
430 __ j(below, &loop); 413 __ j(below, &loop);
431 414
432 // Success. 415 // Success.
433 // Set current character position to position after match. 416 // Set current character position to position after match.
434 __ movp(rdi, rbx); 417 __ movp(rdi, rbx);
435 __ subq(rdi, rsi); 418 __ subq(rdi, rsi);
436 if (read_backward) {
437 // Subtract match length if we matched backward.
438 __ addq(rdi, register_location(start_reg));
439 __ subq(rdi, register_location(start_reg + 1));
440 }
441 419
442 __ bind(&fallthrough); 420 __ bind(&fallthrough);
443 } 421 }
444 422
445 423
446 void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c, 424 void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c,
447 Label* on_not_equal) { 425 Label* on_not_equal) {
448 __ cmpl(current_character(), Immediate(c)); 426 __ cmpl(current_character(), Immediate(c));
449 BranchOrBacktrack(not_equal, on_not_equal); 427 BranchOrBacktrack(not_equal, on_not_equal);
450 } 428 }
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 __ pushq(rsi); 675 __ pushq(rsi);
698 __ pushq(rdx); 676 __ pushq(rdx);
699 __ pushq(rcx); 677 __ pushq(rcx);
700 __ pushq(r8); 678 __ pushq(r8);
701 __ pushq(r9); 679 __ pushq(r9);
702 680
703 __ pushq(rbx); // Callee-save 681 __ pushq(rbx); // Callee-save
704 #endif 682 #endif
705 683
706 __ Push(Immediate(0)); // Number of successful matches in a global regexp. 684 __ Push(Immediate(0)); // Number of successful matches in a global regexp.
707 __ Push(Immediate(0)); // Make room for "string start - 1" constant. 685 __ Push(Immediate(0)); // Make room for "input start - 1" constant.
708 686
709 // Check if we have space on the stack for registers. 687 // Check if we have space on the stack for registers.
710 Label stack_limit_hit; 688 Label stack_limit_hit;
711 Label stack_ok; 689 Label stack_ok;
712 690
713 ExternalReference stack_limit = 691 ExternalReference stack_limit =
714 ExternalReference::address_of_stack_limit(isolate()); 692 ExternalReference::address_of_stack_limit(isolate());
715 __ movp(rcx, rsp); 693 __ movp(rcx, rsp);
716 __ Move(kScratchRegister, stack_limit); 694 __ Move(kScratchRegister, stack_limit);
717 __ subp(rcx, Operand(kScratchRegister, 0)); 695 __ subp(rcx, Operand(kScratchRegister, 0));
(...skipping 29 matching lines...) Expand all
747 // (effectively string position -1). 725 // (effectively string position -1).
748 __ movp(rbx, Operand(rbp, kStartIndex)); 726 __ movp(rbx, Operand(rbp, kStartIndex));
749 __ negq(rbx); 727 __ negq(rbx);
750 if (mode_ == UC16) { 728 if (mode_ == UC16) {
751 __ leap(rax, Operand(rdi, rbx, times_2, -char_size())); 729 __ leap(rax, Operand(rdi, rbx, times_2, -char_size()));
752 } else { 730 } else {
753 __ leap(rax, Operand(rdi, rbx, times_1, -char_size())); 731 __ leap(rax, Operand(rdi, rbx, times_1, -char_size()));
754 } 732 }
755 // Store this value in a local variable, for use when clearing 733 // Store this value in a local variable, for use when clearing
756 // position registers. 734 // position registers.
757 __ movp(Operand(rbp, kStringStartMinusOne), rax); 735 __ movp(Operand(rbp, kInputStartMinusOne), rax);
758 736
759 #if V8_OS_WIN 737 #if V8_OS_WIN
760 // Ensure that we have written to each stack page, in order. Skipping a page 738 // Ensure that we have written to each stack page, in order. Skipping a page
761 // on Windows can cause segmentation faults. Assuming page size is 4k. 739 // on Windows can cause segmentation faults. Assuming page size is 4k.
762 const int kPageSize = 4096; 740 const int kPageSize = 4096;
763 const int kRegistersPerPage = kPageSize / kPointerSize; 741 const int kRegistersPerPage = kPageSize / kPointerSize;
764 for (int i = num_saved_registers_ + kRegistersPerPage - 1; 742 for (int i = num_saved_registers_ + kRegistersPerPage - 1;
765 i < num_registers_; 743 i < num_registers_;
766 i += kRegistersPerPage) { 744 i += kRegistersPerPage) {
767 __ movp(register_location(i), rax); // One write every page. 745 __ movp(register_location(i), rax); // One write every page.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 // Check whether we have enough room for another set of capture results. 828 // Check whether we have enough room for another set of capture results.
851 __ cmpp(rcx, Immediate(num_saved_registers_)); 829 __ cmpp(rcx, Immediate(num_saved_registers_));
852 __ j(less, &exit_label_); 830 __ j(less, &exit_label_);
853 831
854 __ movp(Operand(rbp, kNumOutputRegisters), rcx); 832 __ movp(Operand(rbp, kNumOutputRegisters), rcx);
855 // Advance the location for output. 833 // Advance the location for output.
856 __ addp(Operand(rbp, kRegisterOutput), 834 __ addp(Operand(rbp, kRegisterOutput),
857 Immediate(num_saved_registers_ * kIntSize)); 835 Immediate(num_saved_registers_ * kIntSize));
858 836
859 // Prepare rax to initialize registers with its value in the next run. 837 // Prepare rax to initialize registers with its value in the next run.
860 __ movp(rax, Operand(rbp, kStringStartMinusOne)); 838 __ movp(rax, Operand(rbp, kInputStartMinusOne));
861 839
862 if (global_with_zero_length_check()) { 840 if (global_with_zero_length_check()) {
863 // Special case for zero-length matches. 841 // Special case for zero-length matches.
864 // rdx: capture start index 842 // rdx: capture start index
865 __ cmpp(rdi, rdx); 843 __ cmpp(rdi, rdx);
866 // Not a zero-length match, restart. 844 // Not a zero-length match, restart.
867 __ j(not_equal, &load_char_start_regexp); 845 __ j(not_equal, &load_char_start_regexp);
868 // rdi (offset from the end) is zero if we already reached the end. 846 // rdi (offset from the end) is zero if we already reached the end.
869 __ testp(rdi, rdi); 847 __ testp(rdi, rdi);
870 __ j(zero, &exit_label_, Label::kNear); 848 __ j(zero, &exit_label_, Label::kNear);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 RegExpMacroAssembler::IrregexpImplementation 1011 RegExpMacroAssembler::IrregexpImplementation
1034 RegExpMacroAssemblerX64::Implementation() { 1012 RegExpMacroAssemblerX64::Implementation() {
1035 return kX64Implementation; 1013 return kX64Implementation;
1036 } 1014 }
1037 1015
1038 1016
1039 void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset, 1017 void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset,
1040 Label* on_end_of_input, 1018 Label* on_end_of_input,
1041 bool check_bounds, 1019 bool check_bounds,
1042 int characters) { 1020 int characters) {
1021 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character.
1043 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 1022 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
1044 if (check_bounds) { 1023 if (check_bounds) {
1045 if (cp_offset >= 0) { 1024 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1046 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1047 } else {
1048 CheckPosition(cp_offset, on_end_of_input);
1049 }
1050 } 1025 }
1051 LoadCurrentCharacterUnchecked(cp_offset, characters); 1026 LoadCurrentCharacterUnchecked(cp_offset, characters);
1052 } 1027 }
1053 1028
1054 1029
1055 void RegExpMacroAssemblerX64::PopCurrentPosition() { 1030 void RegExpMacroAssemblerX64::PopCurrentPosition() {
1056 Pop(rdi); 1031 Pop(rdi);
1057 } 1032 }
1058 1033
1059 1034
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 __ movp(register_location(reg), rdi); 1117 __ movp(register_location(reg), rdi);
1143 } else { 1118 } else {
1144 __ leap(rax, Operand(rdi, cp_offset * char_size())); 1119 __ leap(rax, Operand(rdi, cp_offset * char_size()));
1145 __ movp(register_location(reg), rax); 1120 __ movp(register_location(reg), rax);
1146 } 1121 }
1147 } 1122 }
1148 1123
1149 1124
1150 void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) { 1125 void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) {
1151 DCHECK(reg_from <= reg_to); 1126 DCHECK(reg_from <= reg_to);
1152 __ movp(rax, Operand(rbp, kStringStartMinusOne)); 1127 __ movp(rax, Operand(rbp, kInputStartMinusOne));
1153 for (int reg = reg_from; reg <= reg_to; reg++) { 1128 for (int reg = reg_from; reg <= reg_to; reg++) {
1154 __ movp(register_location(reg), rax); 1129 __ movp(register_location(reg), rax);
1155 } 1130 }
1156 } 1131 }
1157 1132
1158 1133
1159 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { 1134 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) {
1160 __ movp(rax, backtrack_stackpointer()); 1135 __ movp(rax, backtrack_stackpointer());
1161 __ subp(rax, Operand(rbp, kStackHighEnd)); 1136 __ subp(rax, Operand(rbp, kStackHighEnd));
1162 __ movp(register_location(reg), rax); 1137 __ movp(register_location(reg), rax);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 DCHECK(register_index < (1<<30)); 1198 DCHECK(register_index < (1<<30));
1224 if (num_registers_ <= register_index) { 1199 if (num_registers_ <= register_index) {
1225 num_registers_ = register_index + 1; 1200 num_registers_ = register_index + 1;
1226 } 1201 }
1227 return Operand(rbp, kRegisterZero - register_index * kPointerSize); 1202 return Operand(rbp, kRegisterZero - register_index * kPointerSize);
1228 } 1203 }
1229 1204
1230 1205
1231 void RegExpMacroAssemblerX64::CheckPosition(int cp_offset, 1206 void RegExpMacroAssemblerX64::CheckPosition(int cp_offset,
1232 Label* on_outside_input) { 1207 Label* on_outside_input) {
1233 if (cp_offset >= 0) { 1208 __ cmpl(rdi, Immediate(-cp_offset * char_size()));
1234 __ cmpl(rdi, Immediate(-cp_offset * char_size())); 1209 BranchOrBacktrack(greater_equal, on_outside_input);
1235 BranchOrBacktrack(greater_equal, on_outside_input);
1236 } else {
1237 __ leap(rax, Operand(rdi, cp_offset * char_size()));
1238 __ cmpp(rax, Operand(rbp, kStringStartMinusOne));
1239 BranchOrBacktrack(less_equal, on_outside_input);
1240 }
1241 } 1210 }
1242 1211
1243 1212
1244 void RegExpMacroAssemblerX64::BranchOrBacktrack(Condition condition, 1213 void RegExpMacroAssemblerX64::BranchOrBacktrack(Condition condition,
1245 Label* to) { 1214 Label* to) {
1246 if (condition < 0) { // No condition 1215 if (condition < 0) { // No condition
1247 if (to == NULL) { 1216 if (to == NULL) {
1248 Backtrack(); 1217 Backtrack();
1249 return; 1218 return;
1250 } 1219 }
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 } 1352 }
1384 1353
1385 #undef __ 1354 #undef __
1386 1355
1387 #endif // V8_INTERPRETED_REGEXP 1356 #endif // V8_INTERPRETED_REGEXP
1388 1357
1389 } // namespace internal 1358 } // namespace internal
1390 } // namespace v8 1359 } // namespace v8
1391 1360
1392 #endif // V8_TARGET_ARCH_X64 1361 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/regexp/x64/regexp-macro-assembler-x64.h ('k') | test/cctest/test-regexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698