~ubuntu-branches/ubuntu/saucy/nodejs/saucy-proposed

« back to all changes in this revision

Viewing changes to deps/v8/src/mips/regexp-macro-assembler-mips.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2006-2010 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
43
43
#ifndef V8_INTERPRETED_REGEXP
44
44
/*
45
45
 * This assembler uses the following register assignment convention
 
46
 * - t7 : Temporarily stores the index of capture start after a matching pass
 
47
 *        for a global regexp.
46
48
 * - t1 : Pointer to current code object (Code*) including heap object tag.
47
49
 * - t2 : Current position in input, as negative offset from end of string.
48
50
 *        Please notice that this is the byte offset, not the character offset!
49
51
 * - t3 : Currently loaded character. Must be loaded using
50
52
 *        LoadCurrentCharacter before using any of the dispatch methods.
51
 
 * - t4 : points to tip of backtrack stack
 
53
 * - t4 : Points to tip of backtrack stack
52
54
 * - t5 : Unused.
53
55
 * - t6 : End of input (points to byte after last character in input).
54
56
 * - fp : Frame pointer. Used to access arguments, local variables and
55
57
 *         RegExp registers.
56
 
 * - sp : points to tip of C stack.
 
58
 * - sp : Points to tip of C stack.
57
59
 *
58
60
 * The remaining registers are free for computations.
59
61
 * Each call to a public method should retain this convention.
60
62
 *
61
63
 * The stack will have the following structure:
62
64
 *
63
 
 *  - fp[56]  direct_call  (if 1, direct call from JavaScript code,
 
65
 *  - fp[64]  Isolate* isolate   (address of the current isolate)
 
66
 *  - fp[60]  direct_call  (if 1, direct call from JavaScript code,
64
67
 *                          if 0, call through the runtime system).
65
 
 *  - fp[52]  stack_area_base (High end of the memory area to use as
 
68
 *  - fp[56]  stack_area_base (High end of the memory area to use as
66
69
 *                             backtracking stack).
 
70
 *  - fp[52]  capture array size (may fit multiple sets of matches)
67
71
 *  - fp[48]  int* capture_array (int[num_saved_registers_], for output).
68
72
 *  - fp[44]  secondary link/return address used by native call.
69
73
 *  --- sp when called ---
70
 
 *  - fp[40]  return address (lr).
71
 
 *  - fp[36]  old frame pointer (r11).
 
74
 *  - fp[40]  return address      (lr).
 
75
 *  - fp[36]  old frame pointer   (r11).
72
76
 *  - fp[0..32]  backup of registers s0..s7.
73
77
 *  --- frame pointer ----
74
 
 *  - fp[-4]  end of input       (Address of end of string).
75
 
 *  - fp[-8]  start of input     (Address of first character in string).
 
78
 *  - fp[-4]  end of input       (address of end of string).
 
79
 *  - fp[-8]  start of input     (address of first character in string).
76
80
 *  - fp[-12] start index        (character index of start).
77
81
 *  - fp[-16] void* input_string (location of a handle containing the string).
78
 
 *  - fp[-20] Offset of location before start of input (effectively character
 
82
 *  - fp[-20] success counter    (only for global regexps to count matches).
 
83
 *  - fp[-24] Offset of location before start of input (effectively character
79
84
 *            position -1). Used to initialize capture registers to a
80
85
 *            non-position.
81
 
 *  - fp[-24] At start (if 1, we are starting at the start of the
 
86
 *  - fp[-28] At start (if 1, we are starting at the start of the
82
87
 *    string, otherwise 0)
83
 
 *  - fp[-28] register 0         (Only positions must be stored in the first
 
88
 *  - fp[-32] register 0         (Only positions must be stored in the first
84
89
 *  -         register 1          num_saved_registers_ registers)
85
90
 *  -         ...
86
91
 *  -         register num_registers-1
114
119
 
115
120
RegExpMacroAssemblerMIPS::RegExpMacroAssemblerMIPS(
116
121
    Mode mode,
117
 
    int registers_to_save)
118
 
    : masm_(new MacroAssembler(Isolate::Current(), NULL, kRegExpCodeSize)),
 
122
    int registers_to_save,
 
123
    Zone* zone)
 
124
    : NativeRegExpMacroAssembler(zone),
 
125
      masm_(new MacroAssembler(Isolate::Current(), NULL, kRegExpCodeSize)),
119
126
      mode_(mode),
120
127
      num_registers_(registers_to_save),
121
128
      num_saved_registers_(registers_to_save),
158
165
void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(int by) {
159
166
  if (by != 0) {
160
167
    __ Addu(current_input_offset(),
161
 
           current_input_offset(), Operand(by * char_size()));
 
168
            current_input_offset(), Operand(by * char_size()));
162
169
  }
163
170
}
164
171
 
201
208
void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
202
209
  Label not_at_start;
203
210
  // Did we start the match at the start of the string at all?
204
 
  __ lw(a0, MemOperand(frame_pointer(), kAtStart));
205
 
  BranchOrBacktrack(&not_at_start, eq, a0, Operand(zero_reg));
 
211
  __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
 
212
  BranchOrBacktrack(&not_at_start, ne, a0, Operand(zero_reg));
206
213
 
207
214
  // If we did, are we still at the start of the input?
208
215
  __ lw(a1, MemOperand(frame_pointer(), kInputStart));
214
221
 
215
222
void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
216
223
  // Did we start the match at the start of the string at all?
217
 
  __ lw(a0, MemOperand(frame_pointer(), kAtStart));
218
 
  BranchOrBacktrack(on_not_at_start, eq, a0, Operand(zero_reg));
 
224
  __ lw(a0, MemOperand(frame_pointer(), kStartIndex));
 
225
  BranchOrBacktrack(on_not_at_start, ne, a0, Operand(zero_reg));
219
226
  // If we did, are we still at the start of the input?
220
227
  __ lw(a1, MemOperand(frame_pointer(), kInputStart));
221
228
  __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
229
236
 
230
237
 
231
238
void RegExpMacroAssemblerMIPS::CheckCharacters(Vector<const uc16> str,
232
 
                                              int cp_offset,
233
 
                                              Label* on_failure,
234
 
                                              bool check_end_of_string) {
 
239
                                               int cp_offset,
 
240
                                               Label* on_failure,
 
241
                                               bool check_end_of_string) {
235
242
  if (on_failure == NULL) {
236
243
    // Instead of inlining a backtrack for each test, (re)use the global
237
244
    // backtrack target.
377
384
    // Isolate.
378
385
    __ li(a3, Operand(ExternalReference::isolate_address()));
379
386
 
380
 
    ExternalReference function =
381
 
        ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
382
 
    __ CallCFunction(function, argument_count);
 
387
    {
 
388
      AllowExternalCallThatCantCauseGC scope(masm_);
 
389
      ExternalReference function =
 
390
          ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
 
391
      __ CallCFunction(function, argument_count);
 
392
    }
383
393
 
384
394
    // Restore regexp engine registers.
385
395
    __ MultiPop(regexp_registers_to_retain);
386
 
    __ li(code_pointer(), Operand(masm_->CodeObject()));
 
396
    __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
387
397
    __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
388
398
 
389
399
    // Check if function returned non-zero for success or zero for failure.
441
451
}
442
452
 
443
453
 
444
 
void RegExpMacroAssemblerMIPS::CheckNotRegistersEqual(int reg1,
445
 
                                                      int reg2,
446
 
                                                      Label* on_not_equal) {
447
 
  UNIMPLEMENTED_MIPS();
448
 
}
449
 
 
450
 
 
451
454
void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
452
 
                                                Label* on_not_equal) {
 
455
                                                 Label* on_not_equal) {
453
456
  BranchOrBacktrack(on_not_equal, ne, current_character(), Operand(c));
454
457
}
455
458
 
456
459
 
457
460
void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c,
458
 
                                                     uint32_t mask,
459
 
                                                     Label* on_equal) {
 
461
                                                      uint32_t mask,
 
462
                                                      Label* on_equal) {
460
463
  __ And(a0, current_character(), Operand(mask));
461
 
  BranchOrBacktrack(on_equal, eq, a0, Operand(c));
 
464
  Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
 
465
  BranchOrBacktrack(on_equal, eq, a0, rhs);
462
466
}
463
467
 
464
468
 
465
469
void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c,
466
 
                                                        uint32_t mask,
467
 
                                                        Label* on_not_equal) {
 
470
                                                         uint32_t mask,
 
471
                                                         Label* on_not_equal) {
468
472
  __ And(a0, current_character(), Operand(mask));
469
 
  BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
 
473
  Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
 
474
  BranchOrBacktrack(on_not_equal, ne, a0, rhs);
470
475
}
471
476
 
472
477
 
475
480
    uc16 minus,
476
481
    uc16 mask,
477
482
    Label* on_not_equal) {
478
 
  UNIMPLEMENTED_MIPS();
 
483
  ASSERT(minus < String::kMaxUtf16CodeUnit);
 
484
  __ Subu(a0, current_character(), Operand(minus));
 
485
  __ And(a0, a0, Operand(mask));
 
486
  BranchOrBacktrack(on_not_equal, ne, a0, Operand(c));
 
487
}
 
488
 
 
489
 
 
490
void RegExpMacroAssemblerMIPS::CheckCharacterInRange(
 
491
    uc16 from,
 
492
    uc16 to,
 
493
    Label* on_in_range) {
 
494
  __ Subu(a0, current_character(), Operand(from));
 
495
  // Unsigned lower-or-same condition.
 
496
  BranchOrBacktrack(on_in_range, ls, a0, Operand(to - from));
 
497
}
 
498
 
 
499
 
 
500
void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange(
 
501
    uc16 from,
 
502
    uc16 to,
 
503
    Label* on_not_in_range) {
 
504
  __ Subu(a0, current_character(), Operand(from));
 
505
  // Unsigned higher condition.
 
506
  BranchOrBacktrack(on_not_in_range, hi, a0, Operand(to - from));
 
507
}
 
508
 
 
509
 
 
510
void RegExpMacroAssemblerMIPS::CheckBitInTable(
 
511
    Handle<ByteArray> table,
 
512
    Label* on_bit_set) {
 
513
  __ li(a0, Operand(table));
 
514
  if (mode_ != ASCII || kTableMask != String::kMaxAsciiCharCode) {
 
515
    __ And(a1, current_character(), Operand(kTableSize - 1));
 
516
    __ Addu(a0, a0, a1);
 
517
  } else {
 
518
    __ Addu(a0, a0, current_character());
 
519
  }
 
520
 
 
521
  __ lbu(a0, FieldMemOperand(a0, ByteArray::kHeaderSize));
 
522
  BranchOrBacktrack(on_bit_set, ne, a0, Operand(zero_reg));
479
523
}
480
524
 
481
525
 
482
526
bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(uc16 type,
483
 
                                                         Label* on_no_match) {
 
527
                                                          Label* on_no_match) {
484
528
  // Range checks (c in min..max) are generally implemented by an unsigned
485
529
  // (c - min) <= (max - min) check.
486
530
  switch (type) {
596
640
 
597
641
 
598
642
Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
 
643
  Label return_v0;
599
644
  if (masm_->has_exception()) {
600
645
    // If the code gets corrupted due to long regular expressions and lack of
601
646
    // space on trampolines, an internal exception flag is set. If this case
607
652
 
608
653
    // Entry code:
609
654
    __ bind(&entry_label_);
 
655
 
 
656
    // Tell the system that we have a stack frame.  Because the type is MANUAL,
 
657
    // no is generated.
 
658
    FrameScope scope(masm_, StackFrame::MANUAL);
 
659
 
 
660
    // Actually emit code to start a new stack frame.
610
661
    // Push arguments
611
662
    // Save callee-save registers.
612
663
    // Start new stack frame.
619
670
    // Set frame pointer in space for it if this is not a direct call
620
671
    // from generated code.
621
672
    __ Addu(frame_pointer(), sp, Operand(4 * kPointerSize));
 
673
    __ mov(a0, zero_reg);
 
674
    __ push(a0);  // Make room for success counter and initialize it to 0.
622
675
    __ push(a0);  // Make room for "position - 1" constant (value irrelevant).
623
 
    __ push(a0);  // Make room for "at start" constant (value irrelevant).
624
676
 
625
677
    // Check if we have space on the stack for registers.
626
678
    Label stack_limit_hit;
639
691
    // Exit with OutOfMemory exception. There is not enough space on the stack
640
692
    // for our working registers.
641
693
    __ li(v0, Operand(EXCEPTION));
642
 
    __ jmp(&exit_label_);
 
694
    __ jmp(&return_v0);
643
695
 
644
696
    __ bind(&stack_limit_hit);
645
697
    CallCheckStackGuardState(a0);
646
698
    // If returned value is non-zero, we exit with the returned value as result.
647
 
    __ Branch(&exit_label_, ne, v0, Operand(zero_reg));
 
699
    __ Branch(&return_v0, ne, v0, Operand(zero_reg));
648
700
 
649
701
    __ bind(&stack_ok);
650
702
    // Allocate space on stack for registers.
665
717
    // position registers.
666
718
    __ sw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
667
719
 
668
 
    // Determine whether the start index is zero, that is at the start of the
669
 
    // string, and store that value in a local variable.
670
 
    __ mov(t5, a1);
671
 
    __ li(a1, Operand(1));
672
 
    __ movn(a1, zero_reg, t5);
673
 
    __ sw(a1, MemOperand(frame_pointer(), kAtStart));
674
 
 
 
720
    // Initialize code pointer register
 
721
    __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
 
722
 
 
723
    Label load_char_start_regexp, start_regexp;
 
724
    // Load newline if index is at start, previous character otherwise.
 
725
    __ Branch(&load_char_start_regexp, ne, a1, Operand(zero_reg));
 
726
    __ li(current_character(), Operand('\n'));
 
727
    __ jmp(&start_regexp);
 
728
 
 
729
    // Global regexp restarts matching here.
 
730
    __ bind(&load_char_start_regexp);
 
731
    // Load previous char as initial value of current character register.
 
732
    LoadCurrentCharacterUnchecked(-1, 1);
 
733
    __ bind(&start_regexp);
 
734
 
 
735
    // Initialize on-stack registers.
675
736
    if (num_saved_registers_ > 0) {  // Always is, if generated from a regexp.
676
737
      // Fill saved registers with initial value = start offset - 1.
677
 
 
678
 
      // Address of register 0.
679
 
      __ Addu(a1, frame_pointer(), Operand(kRegisterZero));
680
 
      __ li(a2, Operand(num_saved_registers_));
681
 
      Label init_loop;
682
 
      __ bind(&init_loop);
683
 
      __ sw(a0, MemOperand(a1));
684
 
      __ Addu(a1, a1, Operand(-kPointerSize));
685
 
      __ Subu(a2, a2, Operand(1));
686
 
      __ Branch(&init_loop, ne, a2, Operand(zero_reg));
 
738
      if (num_saved_registers_ > 8) {
 
739
        // Address of register 0.
 
740
        __ Addu(a1, frame_pointer(), Operand(kRegisterZero));
 
741
        __ li(a2, Operand(num_saved_registers_));
 
742
        Label init_loop;
 
743
        __ bind(&init_loop);
 
744
        __ sw(a0, MemOperand(a1));
 
745
        __ Addu(a1, a1, Operand(-kPointerSize));
 
746
        __ Subu(a2, a2, Operand(1));
 
747
        __ Branch(&init_loop, ne, a2, Operand(zero_reg));
 
748
      } else {
 
749
        for (int i = 0; i < num_saved_registers_; i++) {
 
750
          __ sw(a0, register_location(i));
 
751
        }
 
752
      }
687
753
    }
688
754
 
689
755
    // Initialize backtrack stack pointer.
690
756
    __ lw(backtrack_stackpointer(), MemOperand(frame_pointer(), kStackHighEnd));
691
 
    // Initialize code pointer register
692
 
    __ li(code_pointer(), Operand(masm_->CodeObject()));
693
 
    // Load previous char as initial value of current character register.
694
 
    Label at_start;
695
 
    __ lw(a0, MemOperand(frame_pointer(), kAtStart));
696
 
    __ Branch(&at_start, ne, a0, Operand(zero_reg));
697
 
    LoadCurrentCharacterUnchecked(-1, 1);  // Load previous char.
698
 
    __ jmp(&start_label_);
699
 
    __ bind(&at_start);
700
 
    __ li(current_character(), Operand('\n'));
 
757
 
701
758
    __ jmp(&start_label_);
702
759
 
703
760
 
726
783
        for (int i = 0; i < num_saved_registers_; i += 2) {
727
784
          __ lw(a2, register_location(i));
728
785
          __ lw(a3, register_location(i + 1));
 
786
          if (i == 0 && global_with_zero_length_check()) {
 
787
            // Keep capture start in a4 for the zero-length check later.
 
788
            __ mov(t7, a2);
 
789
          }
729
790
          if (mode_ == UC16) {
730
791
            __ sra(a2, a2, 1);
731
792
            __ Addu(a2, a2, a1);
741
802
          __ Addu(a0, a0, kPointerSize);
742
803
        }
743
804
      }
744
 
      __ li(v0, Operand(SUCCESS));
 
805
 
 
806
      if (global()) {
 
807
        // Restart matching if the regular expression is flagged as global.
 
808
        __ lw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
 
809
        __ lw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
 
810
        __ lw(a2, MemOperand(frame_pointer(), kRegisterOutput));
 
811
        // Increment success counter.
 
812
        __ Addu(a0, a0, 1);
 
813
        __ sw(a0, MemOperand(frame_pointer(), kSuccessfulCaptures));
 
814
        // Capture results have been stored, so the number of remaining global
 
815
        // output registers is reduced by the number of stored captures.
 
816
        __ Subu(a1, a1, num_saved_registers_);
 
817
        // Check whether we have enough room for another set of capture results.
 
818
        __ mov(v0, a0);
 
819
        __ Branch(&return_v0, lt, a1, Operand(num_saved_registers_));
 
820
 
 
821
        __ sw(a1, MemOperand(frame_pointer(), kNumOutputRegisters));
 
822
        // Advance the location for output.
 
823
        __ Addu(a2, a2, num_saved_registers_ * kPointerSize);
 
824
        __ sw(a2, MemOperand(frame_pointer(), kRegisterOutput));
 
825
 
 
826
        // Prepare a0 to initialize registers with its value in the next run.
 
827
        __ lw(a0, MemOperand(frame_pointer(), kInputStartMinusOne));
 
828
 
 
829
        if (global_with_zero_length_check()) {
 
830
          // Special case for zero-length matches.
 
831
          // t7: capture start index
 
832
          // Not a zero-length match, restart.
 
833
          __ Branch(
 
834
              &load_char_start_regexp, ne, current_input_offset(), Operand(t7));
 
835
          // Offset from the end is zero if we already reached the end.
 
836
          __ Branch(&exit_label_, eq, current_input_offset(),
 
837
                    Operand(zero_reg));
 
838
          // Advance current position after a zero-length match.
 
839
          __ Addu(current_input_offset(),
 
840
                  current_input_offset(),
 
841
                  Operand((mode_ == UC16) ? 2 : 1));
 
842
        }
 
843
 
 
844
        __ Branch(&load_char_start_regexp);
 
845
      } else {
 
846
        __ li(v0, Operand(SUCCESS));
 
847
      }
745
848
    }
746
849
    // Exit and return v0.
747
850
    __ bind(&exit_label_);
 
851
    if (global()) {
 
852
      __ lw(v0, MemOperand(frame_pointer(), kSuccessfulCaptures));
 
853
    }
 
854
 
 
855
    __ bind(&return_v0);
748
856
    // Skip sp past regexp registers and local variables..
749
857
    __ mov(sp, frame_pointer());
750
858
    // Restore registers s0..s7 and return (restoring ra to pc).
770
878
      __ MultiPop(regexp_registers_to_retain);
771
879
      // If returning non-zero, we should end execution with the given
772
880
      // result as return value.
773
 
      __ Branch(&exit_label_, ne, v0, Operand(zero_reg));
 
881
      __ Branch(&return_v0, ne, v0, Operand(zero_reg));
774
882
 
775
883
      // String might have moved: Reload end of string from frame.
776
884
      __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
777
 
      __ li(code_pointer(), Operand(masm_->CodeObject()));
 
885
      __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
778
886
      SafeReturn();
779
887
    }
780
888
 
804
912
      // Otherwise use return value as new stack pointer.
805
913
      __ mov(backtrack_stackpointer(), v0);
806
914
      // Restore saved registers and continue.
807
 
      __ li(code_pointer(), Operand(masm_->CodeObject()));
 
915
      __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
808
916
      __ lw(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
809
917
      SafeReturn();
810
918
    }
814
922
      __ bind(&exit_with_exception);
815
923
      // Exit with Result EXCEPTION(-1) to signal thrown exception.
816
924
      __ li(v0, Operand(EXCEPTION));
817
 
      __ jmp(&exit_label_);
 
925
      __ jmp(&return_v0);
818
926
    }
819
927
  }
820
928
 
839
947
 
840
948
 
841
949
void RegExpMacroAssemblerMIPS::IfRegisterGE(int reg,
842
 
                                           int comparand,
843
 
                                           Label* if_ge) {
 
950
                                            int comparand,
 
951
                                            Label* if_ge) {
844
952
  __ lw(a0, register_location(reg));
845
953
    BranchOrBacktrack(if_ge, ge, a0, Operand(comparand));
846
954
}
847
955
 
848
956
 
849
957
void RegExpMacroAssemblerMIPS::IfRegisterLT(int reg,
850
 
                                           int comparand,
851
 
                                           Label* if_lt) {
 
958
                                            int comparand,
 
959
                                            Label* if_lt) {
852
960
  __ lw(a0, register_location(reg));
853
961
  BranchOrBacktrack(if_lt, lt, a0, Operand(comparand));
854
962
}
855
963
 
856
964
 
857
965
void RegExpMacroAssemblerMIPS::IfRegisterEqPos(int reg,
858
 
                                              Label* if_eq) {
 
966
                                               Label* if_eq) {
859
967
  __ lw(a0, register_location(reg));
860
968
  BranchOrBacktrack(if_eq, eq, a0, Operand(current_input_offset()));
861
969
}
868
976
 
869
977
 
870
978
void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(int cp_offset,
871
 
                                                   Label* on_end_of_input,
872
 
                                                   bool check_bounds,
873
 
                                                   int characters) {
 
979
                                                    Label* on_end_of_input,
 
980
                                                    bool check_bounds,
 
981
                                                    int characters) {
874
982
  ASSERT(cp_offset >= -1);      // ^ and \b can look behind one character.
875
983
  ASSERT(cp_offset < (1<<30));  // Be sane! (And ensure negation works).
876
984
  if (check_bounds) {
921
1029
 
922
1030
 
923
1031
void RegExpMacroAssemblerMIPS::PushRegister(int register_index,
924
 
                                           StackCheckFlag check_stack_limit) {
 
1032
                                            StackCheckFlag check_stack_limit) {
925
1033
  __ lw(a0, register_location(register_index));
926
1034
  Push(a0);
927
1035
  if (check_stack_limit) CheckStackLimit();
962
1070
}
963
1071
 
964
1072
 
965
 
void RegExpMacroAssemblerMIPS::Succeed() {
 
1073
bool RegExpMacroAssemblerMIPS::Succeed() {
966
1074
  __ jmp(&success_label_);
 
1075
  return global();
967
1076
}
968
1077
 
969
1078
 
970
1079
void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(int reg,
971
 
                                                             int cp_offset) {
 
1080
                                                              int cp_offset) {
972
1081
  if (cp_offset == 0) {
973
1082
    __ sw(current_input_offset(), register_location(reg));
974
1083
  } else {
994
1103
}
995
1104
 
996
1105
 
 
1106
bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
 
1107
  return false;
 
1108
}
 
1109
 
 
1110
 
997
1111
// Private methods:
998
1112
 
999
1113
void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
1001
1115
  __ PrepareCallCFunction(num_arguments, scratch);
1002
1116
  __ mov(a2, frame_pointer());
1003
1117
  // Code* of self.
1004
 
  __ li(a1, Operand(masm_->CodeObject()));
 
1118
  __ li(a1, Operand(masm_->CodeObject()), CONSTANT_SIZE);
1005
1119
  // a0 becomes return address pointer.
1006
1120
  ExternalReference stack_guard_check =
1007
1121
      ExternalReference::re_check_stack_guard_state(masm_->isolate());
1047
1161
  ASSERT(*return_address <=
1048
1162
      re_code->instruction_start() + re_code->instruction_size());
1049
1163
 
1050
 
  MaybeObject* result = Execution::HandleStackGuardInterrupt();
 
1164
  MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
1051
1165
 
1052
1166
  if (*code_handle != re_code) {  // Return address no longer valid.
1053
1167
    int delta = code_handle->address() - re_code->address();
1103
1217
    frame_entry<const String*>(re_frame, kInputString) = *subject;
1104
1218
    frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1105
1219
    frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
 
1220
  } else if (frame_entry<const String*>(re_frame, kInputString) != *subject) {
 
1221
    // Subject string might have been a ConsString that underwent
 
1222
    // short-circuiting during GC. That will not change start_address but
 
1223
    // will change pointer inside the subject handle.
 
1224
    frame_entry<const String*>(re_frame, kInputString) = *subject;
1106
1225
  }
1107
1226
 
1108
1227
  return 0;
1120
1239
 
1121
1240
 
1122
1241
void RegExpMacroAssemblerMIPS::CheckPosition(int cp_offset,
1123
 
                                            Label* on_outside_input) {
 
1242
                                             Label* on_outside_input) {
1124
1243
  BranchOrBacktrack(on_outside_input,
1125
1244
                    ge,
1126
1245
                    current_input_offset(),
1148
1267
}
1149
1268
 
1150
1269
 
1151
 
void RegExpMacroAssemblerMIPS::SafeCall(Label* to, Condition cond, Register rs,
1152
 
                                           const Operand& rt) {
 
1270
void RegExpMacroAssemblerMIPS::SafeCall(Label* to,
 
1271
                                        Condition cond,
 
1272
                                        Register rs,
 
1273
                                        const Operand& rt) {
1153
1274
  __ BranchAndLink(to, cond, rs, rt);
1154
1275
}
1155
1276
 
1215
1336
  if (OS::ActivationFrameAlignment() != 0) {
1216
1337
    __ lw(sp, MemOperand(sp, 16));
1217
1338
  }
1218
 
  __ li(code_pointer(), Operand(masm_->CodeObject()));
 
1339
  __ li(code_pointer(), Operand(masm_->CodeObject()), CONSTANT_SIZE);
1219
1340
}
1220
1341
 
1221
1342
 
1222
1343
void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(int cp_offset,
1223
 
                                                            int characters) {
 
1344
                                                             int characters) {
1224
1345
  Register offset = current_input_offset();
1225
1346
  if (cp_offset != 0) {
1226
 
    __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1227
 
    offset = a0;
 
1347
    // t7 is not being used to store the capture start index at this point.
 
1348
    __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size()));
 
1349
    offset = t7;
1228
1350
  }
1229
1351
  // We assume that we cannot do unaligned loads on MIPS, so this function
1230
1352
  // must only be used to load a single character at a time.
1244
1366
  if (stack_alignment < kPointerSize) stack_alignment = kPointerSize;
1245
1367
  // Stack is already aligned for call, so decrement by alignment
1246
1368
  // to make room for storing the return address.
1247
 
  __ Subu(sp, sp, Operand(stack_alignment));
1248
 
  __ sw(ra, MemOperand(sp, 0));
1249
 
  __ mov(a0, sp);
 
1369
  __ Subu(sp, sp, Operand(stack_alignment + kCArgsSlotsSize));
 
1370
  const int return_address_offset = kCArgsSlotsSize;
 
1371
  __ Addu(a0, sp, return_address_offset);
 
1372
  __ sw(ra, MemOperand(a0, 0));
1250
1373
  __ mov(t9, t1);
1251
1374
  __ Call(t9);
1252
 
  __ lw(ra, MemOperand(sp, 0));
1253
 
  __ Addu(sp, sp, Operand(stack_alignment));
 
1375
  __ lw(ra, MemOperand(sp, return_address_offset));
 
1376
  __ Addu(sp, sp, Operand(stack_alignment + kCArgsSlotsSize));
1254
1377
  __ Jump(ra);
1255
1378
}
1256
1379