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

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

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