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

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: addressed comments 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
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 // The length of the capture can only be negative if the end of the
226 // illegal capture where start of capture after end of capture). 217 // capture is not yet recorded. If the length is zero, the capture is
227 // This must not happen (no back-reference can reference a capture that wasn't 218 // either empty or uncaptured. In either of those cases, succeed.
228 // closed before in the reg-exp, and we must not generate code that can cause 219 __ j(less_equal, &fallthrough);
229 // this condition).
230 220
231 // If length is zero, either the capture is empty or it is nonparticipating.
232 // In either case succeed immediately.
233 __ j(equal, &fallthrough);
234 221
235 // ----------------------- 222 // -----------------------
236 // rdx - Start of capture 223 // rdx - Start of capture
237 // rbx - length of capture 224 // rbx - length of capture
238 // Check that there are sufficient characters left in the input. 225 // Check that there are sufficient characters left in the input.
239 __ movl(rax, rdi); 226 if (read_backward) {
240 __ addl(rax, rbx); 227 __ movp(rax, rdi);
241 BranchOrBacktrack(greater, on_no_match); 228 __ subp(rax, rbx);
229 __ cmpp(rax, Operand(rbp, kStringStartMinusOne));
230 BranchOrBacktrack(less_equal, on_no_match);
231 } else {
232 __ movl(rax, rdi);
233 __ addl(rax, rbx);
234 BranchOrBacktrack(greater, on_no_match);
235 }
242 236
243 if (mode_ == LATIN1) { 237 if (mode_ == LATIN1) {
244 Label loop_increment; 238 Label loop_increment;
245 if (on_no_match == NULL) { 239 if (on_no_match == NULL) {
246 on_no_match = &backtrack_label_; 240 on_no_match = &backtrack_label_;
247 } 241 }
248 242
249 __ leap(r9, Operand(rsi, rdx, times_1, 0)); 243 __ leap(r9, Operand(rsi, rdx, times_1, 0));
250 __ leap(r11, Operand(rsi, rdi, times_1, 0)); 244 __ leap(r11, Operand(rsi, rdi, times_1, 0));
245 if (read_backward) {
246 __ subp(r11, rbx); // Offset by length when matching backwards.
247 }
251 __ addp(rbx, r9); // End of capture 248 __ addp(rbx, r9); // End of capture
252 // --------------------- 249 // ---------------------
253 // r11 - current input character address 250 // r11 - current input character address
254 // r9 - current capture character address 251 // r9 - current capture character address
255 // rbx - end of capture 252 // rbx - end of capture
256 253
257 Label loop; 254 Label loop;
258 __ bind(&loop); 255 __ bind(&loop);
259 __ movzxbl(rdx, Operand(r9, 0)); 256 __ movzxbl(rdx, Operand(r9, 0));
260 __ movzxbl(rax, Operand(r11, 0)); 257 __ movzxbl(rax, Operand(r11, 0));
(...skipping 22 matching lines...) Expand all
283 // Increment pointers into match and capture strings. 280 // Increment pointers into match and capture strings.
284 __ addp(r11, Immediate(1)); 281 __ addp(r11, Immediate(1));
285 __ addp(r9, Immediate(1)); 282 __ addp(r9, Immediate(1));
286 // Compare to end of capture, and loop if not done. 283 // Compare to end of capture, and loop if not done.
287 __ cmpp(r9, rbx); 284 __ cmpp(r9, rbx);
288 __ j(below, &loop); 285 __ j(below, &loop);
289 286
290 // Compute new value of character position after the matched part. 287 // Compute new value of character position after the matched part.
291 __ movp(rdi, r11); 288 __ movp(rdi, r11);
292 __ subq(rdi, rsi); 289 __ subq(rdi, rsi);
290 if (read_backward) {
291 // Subtract match length if we matched backward.
292 __ addq(rdi, register_location(start_reg));
293 __ subq(rdi, register_location(start_reg + 1));
294 }
293 } else { 295 } else {
294 DCHECK(mode_ == UC16); 296 DCHECK(mode_ == UC16);
295 // Save important/volatile registers before calling C function. 297 // Save important/volatile registers before calling C function.
296 #ifndef _WIN64 298 #ifndef _WIN64
297 // Caller save on Linux and callee save in Windows. 299 // Caller save on Linux and callee save in Windows.
298 __ pushq(rsi); 300 __ pushq(rsi);
299 __ pushq(rdi); 301 __ pushq(rdi);
300 #endif 302 #endif
301 __ pushq(backtrack_stackpointer()); 303 __ pushq(backtrack_stackpointer());
302 304
303 static const int num_arguments = 4; 305 static const int num_arguments = 4;
304 __ PrepareCallCFunction(num_arguments); 306 __ PrepareCallCFunction(num_arguments);
305 307
306 // Put arguments into parameter registers. Parameters are 308 // Put arguments into parameter registers. Parameters are
307 // Address byte_offset1 - Address captured substring's start. 309 // Address byte_offset1 - Address captured substring's start.
308 // Address byte_offset2 - Address of current character position. 310 // Address byte_offset2 - Address of current character position.
309 // size_t byte_length - length of capture in bytes(!) 311 // size_t byte_length - length of capture in bytes(!)
310 // Isolate* isolate 312 // Isolate* isolate
311 #ifdef _WIN64 313 #ifdef _WIN64
312 // Compute and set byte_offset1 (start of capture). 314 // Compute and set byte_offset1 (start of capture).
313 __ leap(rcx, Operand(rsi, rdx, times_1, 0)); 315 __ leap(rcx, Operand(rsi, rdx, times_1, 0));
314 // Set byte_offset2. 316 // Set byte_offset2.
315 __ leap(rdx, Operand(rsi, rdi, times_1, 0)); 317 __ leap(rdx, Operand(rsi, rdi, times_1, 0));
318 if (read_backward) {
319 __ subq(rdx, rbx);
320 }
316 // Set byte_length. 321 // Set byte_length.
317 __ movp(r8, rbx); 322 __ movp(r8, rbx);
318 // Isolate. 323 // Isolate.
319 __ LoadAddress(r9, ExternalReference::isolate_address(isolate())); 324 __ LoadAddress(r9, ExternalReference::isolate_address(isolate()));
320 #else // AMD64 calling convention 325 #else // AMD64 calling convention
321 // Compute byte_offset2 (current position = rsi+rdi). 326 // Compute byte_offset2 (current position = rsi+rdi).
322 __ leap(rax, Operand(rsi, rdi, times_1, 0)); 327 __ leap(rax, Operand(rsi, rdi, times_1, 0));
323 // Compute and set byte_offset1 (start of capture). 328 // Compute and set byte_offset1 (start of capture).
324 __ leap(rdi, Operand(rsi, rdx, times_1, 0)); 329 __ leap(rdi, Operand(rsi, rdx, times_1, 0));
325 // Set byte_offset2. 330 // Set byte_offset2.
326 __ movp(rsi, rax); 331 __ movp(rsi, rax);
332 if (read_backward) {
333 __ subq(rsi, rbx);
334 }
327 // Set byte_length. 335 // Set byte_length.
328 __ movp(rdx, rbx); 336 __ movp(rdx, rbx);
329 // Isolate. 337 // Isolate.
330 __ LoadAddress(rcx, ExternalReference::isolate_address(isolate())); 338 __ LoadAddress(rcx, ExternalReference::isolate_address(isolate()));
331 #endif 339 #endif
332 340
333 { // NOLINT: Can't find a way to open this scope without confusing the 341 { // NOLINT: Can't find a way to open this scope without confusing the
334 // linter. 342 // linter.
335 AllowExternalCallThatCantCauseGC scope(&masm_); 343 AllowExternalCallThatCantCauseGC scope(&masm_);
336 ExternalReference compare = 344 ExternalReference compare =
337 ExternalReference::re_case_insensitive_compare_uc16(isolate()); 345 ExternalReference::re_case_insensitive_compare_uc16(isolate());
338 __ CallCFunction(compare, num_arguments); 346 __ CallCFunction(compare, num_arguments);
339 } 347 }
340 348
341 // Restore original values before reacting on result value. 349 // Restore original values before reacting on result value.
342 __ Move(code_object_pointer(), masm_.CodeObject()); 350 __ Move(code_object_pointer(), masm_.CodeObject());
343 __ popq(backtrack_stackpointer()); 351 __ popq(backtrack_stackpointer());
344 #ifndef _WIN64 352 #ifndef _WIN64
345 __ popq(rdi); 353 __ popq(rdi);
346 __ popq(rsi); 354 __ popq(rsi);
347 #endif 355 #endif
348 356
349 // Check if function returned non-zero for success or zero for failure. 357 // Check if function returned non-zero for success or zero for failure.
350 __ testp(rax, rax); 358 __ testp(rax, rax);
351 BranchOrBacktrack(zero, on_no_match); 359 BranchOrBacktrack(zero, on_no_match);
352 // On success, increment position by length of capture. 360 // On success, advance position by length of capture.
353 // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs). 361 // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs).
354 __ addq(rdi, rbx); 362 if (read_backward) {
363 __ subq(rdi, rbx);
364 } else {
365 __ addq(rdi, rbx);
366 }
355 } 367 }
356 __ bind(&fallthrough); 368 __ bind(&fallthrough);
357 } 369 }
358 370
359 371
360 void RegExpMacroAssemblerX64::CheckNotBackReference( 372 void RegExpMacroAssemblerX64::CheckNotBackReference(int start_reg,
361 int start_reg, 373 bool read_backward,
362 Label* on_no_match) { 374 Label* on_no_match) {
363 Label fallthrough; 375 Label fallthrough;
364 376
365 // Find length of back-referenced capture. 377 // Find length of back-referenced capture.
366 ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture 378 ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture
367 ReadPositionFromRegister(rax, start_reg + 1); // Offset of end of capture 379 ReadPositionFromRegister(rax, start_reg + 1); // Offset of end of capture
368 __ subp(rax, rdx); // Length to check. 380 __ subp(rax, rdx); // Length to check.
369 381 // The length of the capture can only be negative if the end of the
370 // Fail on partial or illegal capture (start of capture after end of capture). 382 // capture is not yet recorded. If the length is zero, the capture is
371 // This must not happen (no back-reference can reference a capture that wasn't 383 // either empty or uncaptured. In either of those cases, succeed.
372 // closed before in the reg-exp). 384 __ j(less_equal, &fallthrough);
373 __ Check(greater_equal, kInvalidCaptureReferenced);
374
375 // Succeed on empty capture (including non-participating capture)
376 __ 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 __ movp(rbx, rdi);
385 BranchOrBacktrack(greater, on_no_match); 392 __ subp(rbx, rax);
393 __ cmpp(rbx, Operand(rbp, kStringStartMinusOne));
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

Powered by Google App Engine
This is Rietveld 408576698