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

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

Issue 9600016: Generate more compact code in regexp assembler with near jumps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
Jakob Kummerow 2012/03/05 14:35:31 nit: 2012
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
11 // with the distribution. 11 // with the distribution.
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 } 311 }
312 } 312 }
313 BranchOrBacktrack(not_equal, on_failure); 313 BranchOrBacktrack(not_equal, on_failure);
314 } 314 }
315 } 315 }
316 316
317 317
318 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) { 318 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
319 Label fallthrough; 319 Label fallthrough;
320 __ cmpl(rdi, Operand(backtrack_stackpointer(), 0)); 320 __ cmpl(rdi, Operand(backtrack_stackpointer(), 0));
321 __ j(not_equal, &fallthrough); 321 __ j(not_equal, &fallthrough, Label::kNear);
322 Drop(); 322 Drop();
323 BranchOrBacktrack(no_condition, on_equal); 323 BranchOrBacktrack(no_condition, on_equal);
324 __ bind(&fallthrough); 324 __ bind(&fallthrough);
325 } 325 }
326 326
327 327
328 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( 328 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
329 int start_reg, 329 int start_reg,
330 Label* on_no_match) { 330 Label* on_no_match) {
331 Label fallthrough; 331 Label fallthrough;
(...skipping 29 matching lines...) Expand all
361 // r9 - current capture character address 361 // r9 - current capture character address
362 // rbx - end of capture 362 // rbx - end of capture
363 363
364 Label loop; 364 Label loop;
365 __ bind(&loop); 365 __ bind(&loop);
366 __ movzxbl(rdx, Operand(r9, 0)); 366 __ movzxbl(rdx, Operand(r9, 0));
367 __ movzxbl(rax, Operand(r11, 0)); 367 __ movzxbl(rax, Operand(r11, 0));
368 // al - input character 368 // al - input character
369 // dl - capture character 369 // dl - capture character
370 __ cmpb(rax, rdx); 370 __ cmpb(rax, rdx);
371 __ j(equal, &loop_increment); 371 __ j(equal, &loop_increment, Label::kNear);
372 372
373 // Mismatch, try case-insensitive match (converting letters to lower-case). 373 // Mismatch, try case-insensitive match (converting letters to lower-case).
374 // I.e., if or-ing with 0x20 makes values equal and in range 'a'-'z', it's 374 // I.e., if or-ing with 0x20 makes values equal and in range 'a'-'z', it's
375 // a match. 375 // a match.
376 __ or_(rax, Immediate(0x20)); // Convert match character to lower-case. 376 __ or_(rax, Immediate(0x20)); // Convert match character to lower-case.
377 __ or_(rdx, Immediate(0x20)); // Convert capture character to lower-case. 377 __ or_(rdx, Immediate(0x20)); // Convert capture character to lower-case.
378 __ cmpb(rax, rdx); 378 __ cmpb(rax, rdx);
379 __ j(not_equal, on_no_match); // Definitely not equal. 379 __ j(not_equal, on_no_match); // Definitely not equal.
380 __ subb(rax, Immediate('a')); 380 __ subb(rax, Immediate('a'));
381 __ cmpb(rax, Immediate('z' - 'a')); 381 __ cmpb(rax, Immediate('z' - 'a'));
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 // (c - min) <= (max - min) check, using the sequence: 578 // (c - min) <= (max - min) check, using the sequence:
579 // lea(rax, Operand(current_character(), -min)) or sub(rax, Immediate(min)) 579 // lea(rax, Operand(current_character(), -min)) or sub(rax, Immediate(min))
580 // cmp(rax, Immediate(max - min)) 580 // cmp(rax, Immediate(max - min))
581 switch (type) { 581 switch (type) {
582 case 's': 582 case 's':
583 // Match space-characters 583 // Match space-characters
584 if (mode_ == ASCII) { 584 if (mode_ == ASCII) {
585 // ASCII space characters are '\t'..'\r' and ' '. 585 // ASCII space characters are '\t'..'\r' and ' '.
586 Label success; 586 Label success;
587 __ cmpl(current_character(), Immediate(' ')); 587 __ cmpl(current_character(), Immediate(' '));
588 __ j(equal, &success); 588 __ j(equal, &success, Label::kNear);
589 // Check range 0x09..0x0d 589 // Check range 0x09..0x0d
590 __ lea(rax, Operand(current_character(), -'\t')); 590 __ lea(rax, Operand(current_character(), -'\t'));
591 __ cmpl(rax, Immediate('\r' - '\t')); 591 __ cmpl(rax, Immediate('\r' - '\t'));
592 BranchOrBacktrack(above, on_no_match); 592 BranchOrBacktrack(above, on_no_match);
593 __ bind(&success); 593 __ bind(&success);
594 return true; 594 return true;
595 } 595 }
596 return false; 596 return false;
597 case 'S': 597 case 'S':
598 // Match non-space characters. 598 // Match non-space characters.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 __ testb(Operand(rbx, current_character(), times_1, 0), 669 __ testb(Operand(rbx, current_character(), times_1, 0),
670 current_character()); 670 current_character());
671 BranchOrBacktrack(zero, on_no_match); 671 BranchOrBacktrack(zero, on_no_match);
672 return true; 672 return true;
673 } 673 }
674 case 'W': { 674 case 'W': {
675 Label done; 675 Label done;
676 if (mode_ != ASCII) { 676 if (mode_ != ASCII) {
677 // Table is 128 entries, so all ASCII characters can be tested. 677 // Table is 128 entries, so all ASCII characters can be tested.
678 __ cmpl(current_character(), Immediate('z')); 678 __ cmpl(current_character(), Immediate('z'));
679 __ j(above, &done); 679 __ j(above, &done, Label::kNear);
680 } 680 }
681 __ movq(rbx, ExternalReference::re_word_character_map()); 681 __ movq(rbx, ExternalReference::re_word_character_map());
682 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. 682 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char.
683 __ testb(Operand(rbx, current_character(), times_1, 0), 683 __ testb(Operand(rbx, current_character(), times_1, 0),
684 current_character()); 684 current_character());
685 BranchOrBacktrack(not_zero, on_no_match); 685 BranchOrBacktrack(not_zero, on_no_match);
686 if (mode_ != ASCII) { 686 if (mode_ != ASCII) {
687 __ bind(&done); 687 __ bind(&done);
688 } 688 }
689 return true; 689 return true;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 // Check if we have space on the stack for registers. 756 // Check if we have space on the stack for registers.
757 Label stack_limit_hit; 757 Label stack_limit_hit;
758 Label stack_ok; 758 Label stack_ok;
759 759
760 ExternalReference stack_limit = 760 ExternalReference stack_limit =
761 ExternalReference::address_of_stack_limit(masm_.isolate()); 761 ExternalReference::address_of_stack_limit(masm_.isolate());
762 __ movq(rcx, rsp); 762 __ movq(rcx, rsp);
763 __ movq(kScratchRegister, stack_limit); 763 __ movq(kScratchRegister, stack_limit);
764 __ subq(rcx, Operand(kScratchRegister, 0)); 764 __ subq(rcx, Operand(kScratchRegister, 0));
765 // Handle it if the stack pointer is already below the stack limit. 765 // Handle it if the stack pointer is already below the stack limit.
766 __ j(below_equal, &stack_limit_hit); 766 __ j(below_equal, &stack_limit_hit, Label::kNear);
767 // Check if there is room for the variable number of registers above 767 // Check if there is room for the variable number of registers above
768 // the stack limit. 768 // the stack limit.
769 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); 769 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize));
770 __ j(above_equal, &stack_ok); 770 __ j(above_equal, &stack_ok, Label::kNear);
771 // Exit with OutOfMemory exception. There is not enough space on the stack 771 // Exit with OutOfMemory exception. There is not enough space on the stack
772 // for our working registers. 772 // for our working registers.
773 __ Set(rax, EXCEPTION); 773 __ Set(rax, EXCEPTION);
774 __ jmp(&exit_label_); 774 __ jmp(&exit_label_);
775 775
776 __ bind(&stack_limit_hit); 776 __ bind(&stack_limit_hit);
777 __ Move(code_object_pointer(), masm_.CodeObject()); 777 __ Move(code_object_pointer(), masm_.CodeObject());
778 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. 778 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp.
779 __ testq(rax, rax); 779 __ testq(rax, rax);
780 // If returned value is non-zero, we exit with the returned value as result. 780 // If returned value is non-zero, we exit with the returned value as result.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 __ movq(register_location(i), rax); // One write every page. 826 __ movq(register_location(i), rax); // One write every page.
827 } 827 }
828 828
829 // Initialize backtrack stack pointer. 829 // Initialize backtrack stack pointer.
830 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); 830 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
831 // Initialize code object pointer. 831 // Initialize code object pointer.
832 __ Move(code_object_pointer(), masm_.CodeObject()); 832 __ Move(code_object_pointer(), masm_.CodeObject());
833 // Load previous char as initial value of current-character. 833 // Load previous char as initial value of current-character.
834 Label at_start; 834 Label at_start;
835 __ cmpb(Operand(rbp, kStartIndex), Immediate(0)); 835 __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
836 __ j(equal, &at_start); 836 __ j(equal, &at_start, Label::kNear);
837 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. 837 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
838 __ jmp(&start_label_); 838 __ jmp(&start_label_);
839 __ bind(&at_start); 839 __ bind(&at_start);
840 __ Set(current_character(), '\n'); 840 __ Set(current_character(), '\n');
841 __ jmp(&start_label_); 841 __ jmp(&start_label_);
842 842
843 843
844 // Exit code: 844 // Exit code:
845 if (success_label_.is_linked()) { 845 if (success_label_.is_linked()) {
846 // Save captures when successful. 846 // Save captures when successful.
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 } 1363 }
1364 1364
1365 1365
1366 void RegExpMacroAssemblerX64::CheckPreemption() { 1366 void RegExpMacroAssemblerX64::CheckPreemption() {
1367 // Check for preemption. 1367 // Check for preemption.
1368 Label no_preempt; 1368 Label no_preempt;
1369 ExternalReference stack_limit = 1369 ExternalReference stack_limit =
1370 ExternalReference::address_of_stack_limit(masm_.isolate()); 1370 ExternalReference::address_of_stack_limit(masm_.isolate());
1371 __ load_rax(stack_limit); 1371 __ load_rax(stack_limit);
1372 __ cmpq(rsp, rax); 1372 __ cmpq(rsp, rax);
1373 __ j(above, &no_preempt); 1373 __ j(above, &no_preempt, Label::kNear);
1374 1374
1375 SafeCall(&check_preempt_label_); 1375 SafeCall(&check_preempt_label_);
1376 1376
1377 __ bind(&no_preempt); 1377 __ bind(&no_preempt);
1378 } 1378 }
1379 1379
1380 1380
1381 void RegExpMacroAssemblerX64::CheckStackLimit() { 1381 void RegExpMacroAssemblerX64::CheckStackLimit() {
1382 Label no_stack_overflow; 1382 Label no_stack_overflow;
1383 ExternalReference stack_limit = 1383 ExternalReference stack_limit =
1384 ExternalReference::address_of_regexp_stack_limit(masm_.isolate()); 1384 ExternalReference::address_of_regexp_stack_limit(masm_.isolate());
1385 __ load_rax(stack_limit); 1385 __ load_rax(stack_limit);
1386 __ cmpq(backtrack_stackpointer(), rax); 1386 __ cmpq(backtrack_stackpointer(), rax);
1387 __ j(above, &no_stack_overflow); 1387 __ j(above, &no_stack_overflow, Label::kNear);
1388 1388
1389 SafeCall(&stack_overflow_label_); 1389 SafeCall(&stack_overflow_label_);
1390 1390
1391 __ bind(&no_stack_overflow); 1391 __ bind(&no_stack_overflow);
1392 } 1392 }
1393 1393
1394 1394
1395 void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset, 1395 void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset,
1396 int characters) { 1396 int characters) {
1397 if (mode_ == ASCII) { 1397 if (mode_ == ASCII) {
(...skipping 18 matching lines...) Expand all
1416 } 1416 }
1417 } 1417 }
1418 1418
1419 #undef __ 1419 #undef __
1420 1420
1421 #endif // V8_INTERPRETED_REGEXP 1421 #endif // V8_INTERPRETED_REGEXP
1422 1422
1423 }} // namespace v8::internal 1423 }} // namespace v8::internal
1424 1424
1425 #endif // V8_TARGET_ARCH_X64 1425 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/ia32/regexp-macro-assembler-ia32.cc ('K') | « src/ia32/regexp-macro-assembler-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698