| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { | 197 void RegExpMacroAssemblerARM::CheckCharacterGT(uc16 limit, Label* on_greater) { |
| 198 __ cmp(current_character(), Operand(limit)); | 198 __ cmp(current_character(), Operand(limit)); |
| 199 BranchOrBacktrack(gt, on_greater); | 199 BranchOrBacktrack(gt, on_greater); |
| 200 } | 200 } |
| 201 | 201 |
| 202 | 202 |
| 203 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { | 203 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) { |
| 204 Label not_at_start; | 204 Label not_at_start; |
| 205 // Did we start the match at the start of the string at all? | 205 // Did we start the match at the start of the string at all? |
| 206 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 206 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); |
| 207 __ cmp(r0, Operand(0, RelocInfo::NONE32)); | 207 __ cmp(r0, Operand::Zero()); |
| 208 BranchOrBacktrack(ne, ¬_at_start); | 208 BranchOrBacktrack(ne, ¬_at_start); |
| 209 | 209 |
| 210 // If we did, are we still at the start of the input? | 210 // If we did, are we still at the start of the input? |
| 211 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 211 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
| 212 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | 212 __ add(r0, end_of_input_address(), Operand(current_input_offset())); |
| 213 __ cmp(r0, r1); | 213 __ cmp(r0, r1); |
| 214 BranchOrBacktrack(eq, on_at_start); | 214 BranchOrBacktrack(eq, on_at_start); |
| 215 __ bind(¬_at_start); | 215 __ bind(¬_at_start); |
| 216 } | 216 } |
| 217 | 217 |
| 218 | 218 |
| 219 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { | 219 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) { |
| 220 // Did we start the match at the start of the string at all? | 220 // Did we start the match at the start of the string at all? |
| 221 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); | 221 __ ldr(r0, MemOperand(frame_pointer(), kStartIndex)); |
| 222 __ cmp(r0, Operand(0, RelocInfo::NONE32)); | 222 __ cmp(r0, Operand::Zero()); |
| 223 BranchOrBacktrack(ne, on_not_at_start); | 223 BranchOrBacktrack(ne, on_not_at_start); |
| 224 // If we did, are we still at the start of the input? | 224 // If we did, are we still at the start of the input? |
| 225 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); | 225 __ ldr(r1, MemOperand(frame_pointer(), kInputStart)); |
| 226 __ add(r0, end_of_input_address(), Operand(current_input_offset())); | 226 __ add(r0, end_of_input_address(), Operand(current_input_offset())); |
| 227 __ cmp(r0, r1); | 227 __ cmp(r0, r1); |
| 228 BranchOrBacktrack(ne, on_not_at_start); | 228 BranchOrBacktrack(ne, on_not_at_start); |
| 229 } | 229 } |
| 230 | 230 |
| 231 | 231 |
| 232 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { | 232 void RegExpMacroAssemblerARM::CheckCharacterLT(uc16 limit, Label* on_less) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 __ mov(r3, Operand(ExternalReference::isolate_address())); | 378 __ mov(r3, Operand(ExternalReference::isolate_address())); |
| 379 | 379 |
| 380 { | 380 { |
| 381 AllowExternalCallThatCantCauseGC scope(masm_); | 381 AllowExternalCallThatCantCauseGC scope(masm_); |
| 382 ExternalReference function = | 382 ExternalReference function = |
| 383 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); | 383 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); |
| 384 __ CallCFunction(function, argument_count); | 384 __ CallCFunction(function, argument_count); |
| 385 } | 385 } |
| 386 | 386 |
| 387 // Check if function returned non-zero for success or zero for failure. | 387 // Check if function returned non-zero for success or zero for failure. |
| 388 __ cmp(r0, Operand(0, RelocInfo::NONE32)); | 388 __ cmp(r0, Operand::Zero()); |
| 389 BranchOrBacktrack(eq, on_no_match); | 389 BranchOrBacktrack(eq, on_no_match); |
| 390 // On success, increment position by length of capture. | 390 // On success, increment position by length of capture. |
| 391 __ add(current_input_offset(), current_input_offset(), Operand(r4)); | 391 __ add(current_input_offset(), current_input_offset(), Operand(r4)); |
| 392 } | 392 } |
| 393 | 393 |
| 394 __ bind(&fallthrough); | 394 __ bind(&fallthrough); |
| 395 } | 395 } |
| 396 | 396 |
| 397 | 397 |
| 398 void RegExpMacroAssemblerARM::CheckNotBackReference( | 398 void RegExpMacroAssemblerARM::CheckNotBackReference( |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 __ mov(r0, Operand(table)); | 510 __ mov(r0, Operand(table)); |
| 511 if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) { | 511 if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) { |
| 512 __ and_(r1, current_character(), Operand(kTableSize - 1)); | 512 __ and_(r1, current_character(), Operand(kTableSize - 1)); |
| 513 __ add(r1, r1, Operand(ByteArray::kHeaderSize - kHeapObjectTag)); | 513 __ add(r1, r1, Operand(ByteArray::kHeaderSize - kHeapObjectTag)); |
| 514 } else { | 514 } else { |
| 515 __ add(r1, | 515 __ add(r1, |
| 516 current_character(), | 516 current_character(), |
| 517 Operand(ByteArray::kHeaderSize - kHeapObjectTag)); | 517 Operand(ByteArray::kHeaderSize - kHeapObjectTag)); |
| 518 } | 518 } |
| 519 __ ldrb(r0, MemOperand(r0, r1)); | 519 __ ldrb(r0, MemOperand(r0, r1)); |
| 520 __ cmp(r0, Operand(0)); | 520 __ cmp(r0, Operand::Zero()); |
| 521 BranchOrBacktrack(ne, on_bit_set); | 521 BranchOrBacktrack(ne, on_bit_set); |
| 522 } | 522 } |
| 523 | 523 |
| 524 | 524 |
| 525 bool RegExpMacroAssemblerARM::CheckSpecialCharacterClass(uc16 type, | 525 bool RegExpMacroAssemblerARM::CheckSpecialCharacterClass(uc16 type, |
| 526 Label* on_no_match) { | 526 Label* on_no_match) { |
| 527 // Range checks (c in min..max) are generally implemented by an unsigned | 527 // Range checks (c in min..max) are generally implemented by an unsigned |
| 528 // (c - min) <= (max - min) check | 528 // (c - min) <= (max - min) check |
| 529 switch (type) { | 529 switch (type) { |
| 530 case 's': | 530 case 's': |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 } | 606 } |
| 607 case 'w': { | 607 case 'w': { |
| 608 if (mode_ != ASCII) { | 608 if (mode_ != ASCII) { |
| 609 // Table is 128 entries, so all ASCII characters can be tested. | 609 // Table is 128 entries, so all ASCII characters can be tested. |
| 610 __ cmp(current_character(), Operand('z')); | 610 __ cmp(current_character(), Operand('z')); |
| 611 BranchOrBacktrack(hi, on_no_match); | 611 BranchOrBacktrack(hi, on_no_match); |
| 612 } | 612 } |
| 613 ExternalReference map = ExternalReference::re_word_character_map(); | 613 ExternalReference map = ExternalReference::re_word_character_map(); |
| 614 __ mov(r0, Operand(map)); | 614 __ mov(r0, Operand(map)); |
| 615 __ ldrb(r0, MemOperand(r0, current_character())); | 615 __ ldrb(r0, MemOperand(r0, current_character())); |
| 616 __ cmp(r0, Operand(0)); | 616 __ cmp(r0, Operand::Zero()); |
| 617 BranchOrBacktrack(eq, on_no_match); | 617 BranchOrBacktrack(eq, on_no_match); |
| 618 return true; | 618 return true; |
| 619 } | 619 } |
| 620 case 'W': { | 620 case 'W': { |
| 621 Label done; | 621 Label done; |
| 622 if (mode_ != ASCII) { | 622 if (mode_ != ASCII) { |
| 623 // Table is 128 entries, so all ASCII characters can be tested. | 623 // Table is 128 entries, so all ASCII characters can be tested. |
| 624 __ cmp(current_character(), Operand('z')); | 624 __ cmp(current_character(), Operand('z')); |
| 625 __ b(hi, &done); | 625 __ b(hi, &done); |
| 626 } | 626 } |
| 627 ExternalReference map = ExternalReference::re_word_character_map(); | 627 ExternalReference map = ExternalReference::re_word_character_map(); |
| 628 __ mov(r0, Operand(map)); | 628 __ mov(r0, Operand(map)); |
| 629 __ ldrb(r0, MemOperand(r0, current_character())); | 629 __ ldrb(r0, MemOperand(r0, current_character())); |
| 630 __ cmp(r0, Operand(0)); | 630 __ cmp(r0, Operand::Zero()); |
| 631 BranchOrBacktrack(ne, on_no_match); | 631 BranchOrBacktrack(ne, on_no_match); |
| 632 if (mode_ != ASCII) { | 632 if (mode_ != ASCII) { |
| 633 __ bind(&done); | 633 __ bind(&done); |
| 634 } | 634 } |
| 635 return true; | 635 return true; |
| 636 } | 636 } |
| 637 case '*': | 637 case '*': |
| 638 // Match any character. | 638 // Match any character. |
| 639 return true; | 639 return true; |
| 640 // No custom implementation (yet): s(UC16), S(UC16). | 640 // No custom implementation (yet): s(UC16), S(UC16). |
| (...skipping 27 matching lines...) Expand all Loading... |
| 668 // Start new stack frame. | 668 // Start new stack frame. |
| 669 // Store link register in existing stack-cell. | 669 // Store link register in existing stack-cell. |
| 670 // Order here should correspond to order of offset constants in header file. | 670 // Order here should correspond to order of offset constants in header file. |
| 671 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | | 671 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | |
| 672 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); | 672 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); |
| 673 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); | 673 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); |
| 674 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); | 674 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); |
| 675 // Set frame pointer in space for it if this is not a direct call | 675 // Set frame pointer in space for it if this is not a direct call |
| 676 // from generated code. | 676 // from generated code. |
| 677 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); | 677 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); |
| 678 __ mov(r0, Operand(0, RelocInfo::NONE32)); | 678 __ mov(r0, Operand::Zero()); |
| 679 __ push(r0); // Make room for success counter and initialize it to 0. | 679 __ push(r0); // Make room for success counter and initialize it to 0. |
| 680 __ push(r0); // Make room for "position - 1" constant (value is irrelevant). | 680 __ push(r0); // Make room for "position - 1" constant (value is irrelevant). |
| 681 // Check if we have space on the stack for registers. | 681 // Check if we have space on the stack for registers. |
| 682 Label stack_limit_hit; | 682 Label stack_limit_hit; |
| 683 Label stack_ok; | 683 Label stack_ok; |
| 684 | 684 |
| 685 ExternalReference stack_limit = | 685 ExternalReference stack_limit = |
| 686 ExternalReference::address_of_stack_limit(masm_->isolate()); | 686 ExternalReference::address_of_stack_limit(masm_->isolate()); |
| 687 __ mov(r0, Operand(stack_limit)); | 687 __ mov(r0, Operand(stack_limit)); |
| 688 __ ldr(r0, MemOperand(r0)); | 688 __ ldr(r0, MemOperand(r0)); |
| 689 __ sub(r0, sp, r0, SetCC); | 689 __ sub(r0, sp, r0, SetCC); |
| 690 // Handle it if the stack pointer is already below the stack limit. | 690 // Handle it if the stack pointer is already below the stack limit. |
| 691 __ b(ls, &stack_limit_hit); | 691 __ b(ls, &stack_limit_hit); |
| 692 // Check if there is room for the variable number of registers above | 692 // Check if there is room for the variable number of registers above |
| 693 // the stack limit. | 693 // the stack limit. |
| 694 __ cmp(r0, Operand(num_registers_ * kPointerSize)); | 694 __ cmp(r0, Operand(num_registers_ * kPointerSize)); |
| 695 __ b(hs, &stack_ok); | 695 __ b(hs, &stack_ok); |
| 696 // Exit with OutOfMemory exception. There is not enough space on the stack | 696 // Exit with OutOfMemory exception. There is not enough space on the stack |
| 697 // for our working registers. | 697 // for our working registers. |
| 698 __ mov(r0, Operand(EXCEPTION)); | 698 __ mov(r0, Operand(EXCEPTION)); |
| 699 __ jmp(&return_r0); | 699 __ jmp(&return_r0); |
| 700 | 700 |
| 701 __ bind(&stack_limit_hit); | 701 __ bind(&stack_limit_hit); |
| 702 CallCheckStackGuardState(r0); | 702 CallCheckStackGuardState(r0); |
| 703 __ cmp(r0, Operand(0, RelocInfo::NONE32)); | 703 __ cmp(r0, Operand::Zero()); |
| 704 // If returned value is non-zero, we exit with the returned value as result. | 704 // If returned value is non-zero, we exit with the returned value as result. |
| 705 __ b(ne, &return_r0); | 705 __ b(ne, &return_r0); |
| 706 | 706 |
| 707 __ bind(&stack_ok); | 707 __ bind(&stack_ok); |
| 708 | 708 |
| 709 // Allocate space on stack for registers. | 709 // Allocate space on stack for registers. |
| 710 __ sub(sp, sp, Operand(num_registers_ * kPointerSize)); | 710 __ sub(sp, sp, Operand(num_registers_ * kPointerSize)); |
| 711 // Load string end. | 711 // Load string end. |
| 712 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 712 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
| 713 // Load input start. | 713 // Load input start. |
| 714 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); | 714 __ ldr(r0, MemOperand(frame_pointer(), kInputStart)); |
| 715 // Find negative length (offset of start relative to end). | 715 // Find negative length (offset of start relative to end). |
| 716 __ sub(current_input_offset(), r0, end_of_input_address()); | 716 __ sub(current_input_offset(), r0, end_of_input_address()); |
| 717 // Set r0 to address of char before start of the input string | 717 // Set r0 to address of char before start of the input string |
| 718 // (effectively string position -1). | 718 // (effectively string position -1). |
| 719 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); | 719 __ ldr(r1, MemOperand(frame_pointer(), kStartIndex)); |
| 720 __ sub(r0, current_input_offset(), Operand(char_size())); | 720 __ sub(r0, current_input_offset(), Operand(char_size())); |
| 721 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); | 721 __ sub(r0, r0, Operand(r1, LSL, (mode_ == UC16) ? 1 : 0)); |
| 722 // Store this value in a local variable, for use when clearing | 722 // Store this value in a local variable, for use when clearing |
| 723 // position registers. | 723 // position registers. |
| 724 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); | 724 __ str(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); |
| 725 | 725 |
| 726 // Initialize code pointer register | 726 // Initialize code pointer register |
| 727 __ mov(code_pointer(), Operand(masm_->CodeObject())); | 727 __ mov(code_pointer(), Operand(masm_->CodeObject())); |
| 728 | 728 |
| 729 Label load_char_start_regexp, start_regexp; | 729 Label load_char_start_regexp, start_regexp; |
| 730 // Load newline if index is at start, previous character otherwise. | 730 // Load newline if index is at start, previous character otherwise. |
| 731 __ cmp(r1, Operand(0, RelocInfo::NONE32)); | 731 __ cmp(r1, Operand::Zero()); |
| 732 __ b(ne, &load_char_start_regexp); | 732 __ b(ne, &load_char_start_regexp); |
| 733 __ mov(current_character(), Operand('\n'), LeaveCC, eq); | 733 __ mov(current_character(), Operand('\n'), LeaveCC, eq); |
| 734 __ jmp(&start_regexp); | 734 __ jmp(&start_regexp); |
| 735 | 735 |
| 736 // Global regexp restarts matching here. | 736 // Global regexp restarts matching here. |
| 737 __ bind(&load_char_start_regexp); | 737 __ bind(&load_char_start_regexp); |
| 738 // Load previous char as initial value of current character register. | 738 // Load previous char as initial value of current character register. |
| 739 LoadCurrentCharacterUnchecked(-1, 1); | 739 LoadCurrentCharacterUnchecked(-1, 1); |
| 740 __ bind(&start_regexp); | 740 __ bind(&start_regexp); |
| 741 | 741 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 // Prepare r0 to initialize registers with its value in the next run. | 827 // Prepare r0 to initialize registers with its value in the next run. |
| 828 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); | 828 __ ldr(r0, MemOperand(frame_pointer(), kInputStartMinusOne)); |
| 829 | 829 |
| 830 if (global_with_zero_length_check()) { | 830 if (global_with_zero_length_check()) { |
| 831 // Special case for zero-length matches. | 831 // Special case for zero-length matches. |
| 832 // r4: capture start index | 832 // r4: capture start index |
| 833 __ cmp(current_input_offset(), r4); | 833 __ cmp(current_input_offset(), r4); |
| 834 // Not a zero-length match, restart. | 834 // Not a zero-length match, restart. |
| 835 __ b(ne, &load_char_start_regexp); | 835 __ b(ne, &load_char_start_regexp); |
| 836 // Offset from the end is zero if we already reached the end. | 836 // Offset from the end is zero if we already reached the end. |
| 837 __ cmp(current_input_offset(), Operand(0)); | 837 __ cmp(current_input_offset(), Operand::Zero()); |
| 838 __ b(eq, &exit_label_); | 838 __ b(eq, &exit_label_); |
| 839 // Advance current position after a zero-length match. | 839 // Advance current position after a zero-length match. |
| 840 __ add(current_input_offset(), | 840 __ add(current_input_offset(), |
| 841 current_input_offset(), | 841 current_input_offset(), |
| 842 Operand((mode_ == UC16) ? 2 : 1)); | 842 Operand((mode_ == UC16) ? 2 : 1)); |
| 843 } | 843 } |
| 844 | 844 |
| 845 __ b(&load_char_start_regexp); | 845 __ b(&load_char_start_regexp); |
| 846 } else { | 846 } else { |
| 847 __ mov(r0, Operand(SUCCESS)); | 847 __ mov(r0, Operand(SUCCESS)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 866 Backtrack(); | 866 Backtrack(); |
| 867 } | 867 } |
| 868 | 868 |
| 869 Label exit_with_exception; | 869 Label exit_with_exception; |
| 870 | 870 |
| 871 // Preempt-code | 871 // Preempt-code |
| 872 if (check_preempt_label_.is_linked()) { | 872 if (check_preempt_label_.is_linked()) { |
| 873 SafeCallTarget(&check_preempt_label_); | 873 SafeCallTarget(&check_preempt_label_); |
| 874 | 874 |
| 875 CallCheckStackGuardState(r0); | 875 CallCheckStackGuardState(r0); |
| 876 __ cmp(r0, Operand(0, RelocInfo::NONE32)); | 876 __ cmp(r0, Operand::Zero()); |
| 877 // If returning non-zero, we should end execution with the given | 877 // If returning non-zero, we should end execution with the given |
| 878 // result as return value. | 878 // result as return value. |
| 879 __ b(ne, &return_r0); | 879 __ b(ne, &return_r0); |
| 880 | 880 |
| 881 // String might have moved: Reload end of string from frame. | 881 // String might have moved: Reload end of string from frame. |
| 882 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 882 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
| 883 SafeReturn(); | 883 SafeReturn(); |
| 884 } | 884 } |
| 885 | 885 |
| 886 // Backtrack stack overflow code. | 886 // Backtrack stack overflow code. |
| 887 if (stack_overflow_label_.is_linked()) { | 887 if (stack_overflow_label_.is_linked()) { |
| 888 SafeCallTarget(&stack_overflow_label_); | 888 SafeCallTarget(&stack_overflow_label_); |
| 889 // Reached if the backtrack-stack limit has been hit. | 889 // Reached if the backtrack-stack limit has been hit. |
| 890 Label grow_failed; | 890 Label grow_failed; |
| 891 | 891 |
| 892 // Call GrowStack(backtrack_stackpointer(), &stack_base) | 892 // Call GrowStack(backtrack_stackpointer(), &stack_base) |
| 893 static const int num_arguments = 3; | 893 static const int num_arguments = 3; |
| 894 __ PrepareCallCFunction(num_arguments, r0); | 894 __ PrepareCallCFunction(num_arguments, r0); |
| 895 __ mov(r0, backtrack_stackpointer()); | 895 __ mov(r0, backtrack_stackpointer()); |
| 896 __ add(r1, frame_pointer(), Operand(kStackHighEnd)); | 896 __ add(r1, frame_pointer(), Operand(kStackHighEnd)); |
| 897 __ mov(r2, Operand(ExternalReference::isolate_address())); | 897 __ mov(r2, Operand(ExternalReference::isolate_address())); |
| 898 ExternalReference grow_stack = | 898 ExternalReference grow_stack = |
| 899 ExternalReference::re_grow_stack(masm_->isolate()); | 899 ExternalReference::re_grow_stack(masm_->isolate()); |
| 900 __ CallCFunction(grow_stack, num_arguments); | 900 __ CallCFunction(grow_stack, num_arguments); |
| 901 // If return NULL, we have failed to grow the stack, and | 901 // If return NULL, we have failed to grow the stack, and |
| 902 // must exit with a stack-overflow exception. | 902 // must exit with a stack-overflow exception. |
| 903 __ cmp(r0, Operand(0, RelocInfo::NONE32)); | 903 __ cmp(r0, Operand::Zero()); |
| 904 __ b(eq, &exit_with_exception); | 904 __ b(eq, &exit_with_exception); |
| 905 // Otherwise use return value as new stack pointer. | 905 // Otherwise use return value as new stack pointer. |
| 906 __ mov(backtrack_stackpointer(), r0); | 906 __ mov(backtrack_stackpointer(), r0); |
| 907 // Restore saved registers and continue. | 907 // Restore saved registers and continue. |
| 908 SafeReturn(); | 908 SafeReturn(); |
| 909 } | 909 } |
| 910 | 910 |
| 911 if (exit_with_exception.is_linked()) { | 911 if (exit_with_exception.is_linked()) { |
| 912 // If any of the code above needed to exit with an exception. | 912 // If any of the code above needed to exit with an exception. |
| 913 __ bind(&exit_with_exception); | 913 __ bind(&exit_with_exception); |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 __ ldr(pc, MemOperand(sp, stack_alignment, PostIndex)); | 1411 __ ldr(pc, MemOperand(sp, stack_alignment, PostIndex)); |
| 1412 } | 1412 } |
| 1413 | 1413 |
| 1414 #undef __ | 1414 #undef __ |
| 1415 | 1415 |
| 1416 #endif // V8_INTERPRETED_REGEXP | 1416 #endif // V8_INTERPRETED_REGEXP |
| 1417 | 1417 |
| 1418 }} // namespace v8::internal | 1418 }} // namespace v8::internal |
| 1419 | 1419 |
| 1420 #endif // V8_TARGET_ARCH_ARM | 1420 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |