~ubuntu-branches/ubuntu/trusty/libv8/trusty

« back to all changes in this revision

Viewing changes to src/ia32/regexp-macro-assembler-ia32.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2012-02-20 14:08:17 UTC
  • mfrom: (15.1.24 sid)
  • Revision ID: package-import@ubuntu.com-20120220140817-bsvmeoa4sxsj5hbz
Tags: 3.7.12.22-3
Fix mipsel build, allow test debug-step-3 to fail (non-crucial)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2008-2009 the V8 project authors. All rights reserved.
 
1
// Copyright 2011 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:
134
134
 
135
135
void RegExpMacroAssemblerIA32::AdvanceCurrentPosition(int by) {
136
136
  if (by != 0) {
137
 
    __ add(Operand(edi), Immediate(by * char_size()));
 
137
    __ add(edi, Immediate(by * char_size()));
138
138
  }
139
139
}
140
140
 
152
152
  CheckPreemption();
153
153
  // Pop Code* offset from backtrack stack, add Code* and jump to location.
154
154
  Pop(ebx);
155
 
  __ add(Operand(ebx), Immediate(masm_->CodeObject()));
156
 
  __ jmp(Operand(ebx));
 
155
  __ add(ebx, Immediate(masm_->CodeObject()));
 
156
  __ jmp(ebx);
157
157
}
158
158
 
159
159
 
219
219
  int byte_offset = cp_offset * char_size();
220
220
  if (check_end_of_string) {
221
221
    // Check that there are at least str.length() characters left in the input.
222
 
    __ cmp(Operand(edi), Immediate(-(byte_offset + byte_length)));
 
222
    __ cmp(edi, Immediate(-(byte_offset + byte_length)));
223
223
    BranchOrBacktrack(greater, on_failure);
224
224
  }
225
225
 
288
288
  Label fallthrough;
289
289
  __ cmp(edi, Operand(backtrack_stackpointer(), 0));
290
290
  __ j(not_equal, &fallthrough);
291
 
  __ add(Operand(backtrack_stackpointer()), Immediate(kPointerSize));  // Pop.
 
291
  __ add(backtrack_stackpointer(), Immediate(kPointerSize));  // Pop.
292
292
  BranchOrBacktrack(no_condition, on_equal);
293
293
  __ bind(&fallthrough);
294
294
}
300
300
  Label fallthrough;
301
301
  __ mov(edx, register_location(start_reg));  // Index of start of capture
302
302
  __ mov(ebx, register_location(start_reg + 1));  // Index of end of capture
303
 
  __ sub(ebx, Operand(edx));  // Length of capture.
 
303
  __ sub(ebx, edx);  // Length of capture.
304
304
 
305
305
  // The length of a capture should not be negative. This can only happen
306
306
  // if the end of the capture is unrecorded, or at a point earlier than
320
320
    __ push(backtrack_stackpointer());
321
321
    // After this, the eax, ecx, and edi registers are available.
322
322
 
323
 
    __ add(edx, Operand(esi));  // Start of capture
324
 
    __ add(edi, Operand(esi));  // Start of text to match against capture.
325
 
    __ add(ebx, Operand(edi));  // End of text to match against capture.
 
323
    __ add(edx, esi);  // Start of capture
 
324
    __ add(edi, esi);  // Start of text to match against capture.
 
325
    __ add(ebx, edi);  // End of text to match against capture.
326
326
 
327
327
    Label loop;
328
328
    __ bind(&loop);
339
339
    __ movzx_b(ecx, Operand(edx, 0));
340
340
    __ or_(ecx, 0x20);
341
341
 
342
 
    __ cmp(eax, Operand(ecx));
 
342
    __ cmp(eax, ecx);
343
343
    __ j(not_equal, &fail);
344
344
 
345
345
    __ bind(&loop_increment);
346
346
    // Increment pointers into match and capture strings.
347
 
    __ add(Operand(edx), Immediate(1));
348
 
    __ add(Operand(edi), Immediate(1));
 
347
    __ add(edx, Immediate(1));
 
348
    __ add(edi, Immediate(1));
349
349
    // Compare to end of match, and loop if not done.
350
 
    __ cmp(edi, Operand(ebx));
 
350
    __ cmp(edi, ebx);
351
351
    __ j(below, &loop);
352
352
    __ jmp(&success);
353
353
 
361
361
    // Restore original value before continuing.
362
362
    __ pop(backtrack_stackpointer());
363
363
    // Drop original value of character position.
364
 
    __ add(Operand(esp), Immediate(kPointerSize));
 
364
    __ add(esp, Immediate(kPointerSize));
365
365
    // Compute new value of character position after the matched part.
366
 
    __ sub(edi, Operand(esi));
 
366
    __ sub(edi, esi);
367
367
  } else {
368
368
    ASSERT(mode_ == UC16);
369
369
    // Save registers before calling C function.
389
389
    // Set byte_offset2.
390
390
    // Found by adding negative string-end offset of current position (edi)
391
391
    // to end of string.
392
 
    __ add(edi, Operand(esi));
 
392
    __ add(edi, esi);
393
393
    __ mov(Operand(esp, 1 * kPointerSize), edi);
394
394
    // Set byte_offset1.
395
395
    // Start of capture, where edx already holds string-end negative offset.
396
 
    __ add(edx, Operand(esi));
 
396
    __ add(edx, esi);
397
397
    __ mov(Operand(esp, 0 * kPointerSize), edx);
398
398
 
399
 
    ExternalReference compare =
400
 
        ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
401
 
    __ CallCFunction(compare, argument_count);
 
399
    {
 
400
      AllowExternalCallThatCantCauseGC scope(masm_);
 
401
      ExternalReference compare =
 
402
          ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
 
403
      __ CallCFunction(compare, argument_count);
 
404
    }
402
405
    // Pop original values before reacting on result value.
403
406
    __ pop(ebx);
404
407
    __ pop(backtrack_stackpointer());
406
409
    __ pop(esi);
407
410
 
408
411
    // Check if function returned non-zero for success or zero for failure.
409
 
    __ or_(eax, Operand(eax));
 
412
    __ or_(eax, eax);
410
413
    BranchOrBacktrack(zero, on_no_match);
411
414
    // On success, increment position by length of capture.
412
 
    __ add(edi, Operand(ebx));
 
415
    __ add(edi, ebx);
413
416
  }
414
417
  __ bind(&fallthrough);
415
418
}
425
428
  // Find length of back-referenced capture.
426
429
  __ mov(edx, register_location(start_reg));
427
430
  __ mov(eax, register_location(start_reg + 1));
428
 
  __ sub(eax, Operand(edx));  // Length to check.
 
431
  __ sub(eax, edx);  // Length to check.
429
432
  // Fail on partial or illegal capture (start of capture after end of capture).
430
433
  BranchOrBacktrack(less, on_no_match);
431
434
  // Succeed on empty capture (including no capture)
433
436
 
434
437
  // Check that there are sufficient characters left in the input.
435
438
  __ mov(ebx, edi);
436
 
  __ add(ebx, Operand(eax));
 
439
  __ add(ebx, eax);
437
440
  BranchOrBacktrack(greater, on_no_match);
438
441
 
439
442
  // Save register to make it available below.
441
444
 
442
445
  // Compute pointers to match string and capture string
443
446
  __ lea(ebx, Operand(esi, edi, times_1, 0));  // Start of match.
444
 
  __ add(edx, Operand(esi));  // Start of capture.
 
447
  __ add(edx, esi);  // Start of capture.
445
448
  __ lea(ecx, Operand(eax, ebx, times_1, 0));  // End of match
446
449
 
447
450
  Label loop;
456
459
  }
457
460
  __ j(not_equal, &fail);
458
461
  // Increment pointers into capture and match string.
459
 
  __ add(Operand(edx), Immediate(char_size()));
460
 
  __ add(Operand(ebx), Immediate(char_size()));
 
462
  __ add(edx, Immediate(char_size()));
 
463
  __ add(ebx, Immediate(char_size()));
461
464
  // Check if we have reached end of match area.
462
 
  __ cmp(ebx, Operand(ecx));
 
465
  __ cmp(ebx, ecx);
463
466
  __ j(below, &loop);
464
467
  __ jmp(&success);
465
468
 
471
474
  __ bind(&success);
472
475
  // Move current character position to position after match.
473
476
  __ mov(edi, ecx);
474
 
  __ sub(Operand(edi), esi);
 
477
  __ sub(edi, esi);
475
478
  // Restore backtrack stackpointer.
476
479
  __ pop(backtrack_stackpointer());
477
480
 
574
577
    return true;
575
578
  case '.': {
576
579
    // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
577
 
    __ mov(Operand(eax), current_character());
578
 
    __ xor_(Operand(eax), Immediate(0x01));
 
580
    __ mov(eax, current_character());
 
581
    __ xor_(eax, Immediate(0x01));
579
582
    // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
580
 
    __ sub(Operand(eax), Immediate(0x0b));
 
583
    __ sub(eax, Immediate(0x0b));
581
584
    __ cmp(eax, 0x0c - 0x0b);
582
585
    BranchOrBacktrack(below_equal, on_no_match);
583
586
    if (mode_ == UC16) {
584
587
      // Compare original value to 0x2028 and 0x2029, using the already
585
588
      // computed (current_char ^ 0x01 - 0x0b). I.e., check for
586
589
      // 0x201d (0x2028 - 0x0b) or 0x201e.
587
 
      __ sub(Operand(eax), Immediate(0x2028 - 0x0b));
 
590
      __ sub(eax, Immediate(0x2028 - 0x0b));
588
591
      __ cmp(eax, 0x2029 - 0x2028);
589
592
      BranchOrBacktrack(below_equal, on_no_match);
590
593
    }
593
596
  case 'w': {
594
597
    if (mode_ != ASCII) {
595
598
      // Table is 128 entries, so all ASCII characters can be tested.
596
 
      __ cmp(Operand(current_character()), Immediate('z'));
 
599
      __ cmp(current_character(), Immediate('z'));
597
600
      BranchOrBacktrack(above, on_no_match);
598
601
    }
599
602
    ASSERT_EQ(0, word_character_map[0]);  // Character '\0' is not a word char.
607
610
    Label done;
608
611
    if (mode_ != ASCII) {
609
612
      // Table is 128 entries, so all ASCII characters can be tested.
610
 
      __ cmp(Operand(current_character()), Immediate('z'));
 
613
      __ cmp(current_character(), Immediate('z'));
611
614
      __ j(above, &done);
612
615
    }
613
616
    ASSERT_EQ(0, word_character_map[0]);  // Character '\0' is not a word char.
627
630
  case 'n': {
628
631
    // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 or 0x2029).
629
632
    // The opposite of '.'.
630
 
    __ mov(Operand(eax), current_character());
631
 
    __ xor_(Operand(eax), Immediate(0x01));
 
633
    __ mov(eax, current_character());
 
634
    __ xor_(eax, Immediate(0x01));
632
635
    // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
633
 
    __ sub(Operand(eax), Immediate(0x0b));
 
636
    __ sub(eax, Immediate(0x0b));
634
637
    __ cmp(eax, 0x0c - 0x0b);
635
638
    if (mode_ == ASCII) {
636
639
      BranchOrBacktrack(above, on_no_match);
641
644
      // Compare original value to 0x2028 and 0x2029, using the already
642
645
      // computed (current_char ^ 0x01 - 0x0b). I.e., check for
643
646
      // 0x201d (0x2028 - 0x0b) or 0x201e.
644
 
      __ sub(Operand(eax), Immediate(0x2028 - 0x0b));
 
647
      __ sub(eax, Immediate(0x2028 - 0x0b));
645
648
      __ cmp(eax, 1);
646
649
      BranchOrBacktrack(above, on_no_match);
647
650
      __ bind(&done);
668
671
 
669
672
  // Entry code:
670
673
  __ bind(&entry_label_);
671
 
  // Start new stack frame.
 
674
 
 
675
  // Tell the system that we have a stack frame.  Because the type is MANUAL, no
 
676
  // code is generated.
 
677
  FrameScope scope(masm_, StackFrame::MANUAL);
 
678
 
 
679
  // Actually emit code to start a new stack frame.
672
680
  __ push(ebp);
673
681
  __ mov(ebp, esp);
674
682
  // Save callee-save registers. Order here should correspond to order of
699
707
 
700
708
  __ bind(&stack_limit_hit);
701
709
  CallCheckStackGuardState(ebx);
702
 
  __ or_(eax, Operand(eax));
 
710
  __ or_(eax, eax);
703
711
  // If returned value is non-zero, we exit with the returned value as result.
704
712
  __ j(not_zero, &exit_label_);
705
713
 
708
716
  __ mov(ebx, Operand(ebp, kStartIndex));
709
717
 
710
718
  // Allocate space on stack for registers.
711
 
  __ sub(Operand(esp), Immediate(num_registers_ * kPointerSize));
 
719
  __ sub(esp, Immediate(num_registers_ * kPointerSize));
712
720
  // Load string length.
713
721
  __ mov(esi, Operand(ebp, kInputEnd));
714
722
  // Load input position.
715
723
  __ mov(edi, Operand(ebp, kInputStart));
716
724
  // Set up edi to be negative offset from string end.
717
 
  __ sub(edi, Operand(esi));
 
725
  __ sub(edi, esi);
718
726
 
719
727
  // Set eax to address of char before start of the string.
720
728
  // (effectively string position -1).
736
744
    Label init_loop;
737
745
    __ bind(&init_loop);
738
746
    __ mov(Operand(ebp, ecx, times_1, +0), eax);
739
 
    __ sub(Operand(ecx), Immediate(kPointerSize));
 
747
    __ sub(ecx, Immediate(kPointerSize));
740
748
    __ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
741
749
    __ j(greater, &init_loop);
742
750
  }
777
785
      if (mode_ == UC16) {
778
786
        __ lea(ecx, Operand(ecx, edx, times_2, 0));
779
787
      } else {
780
 
        __ add(ecx, Operand(edx));
 
788
        __ add(ecx, edx);
781
789
      }
782
790
      for (int i = 0; i < num_saved_registers_; i++) {
783
791
        __ mov(eax, register_location(i));
784
792
        // Convert to index from start of string, not end.
785
 
        __ add(eax, Operand(ecx));
 
793
        __ add(eax, ecx);
786
794
        if (mode_ == UC16) {
787
795
          __ sar(eax, 1);  // Convert byte index to character index.
788
796
        }
819
827
    __ push(edi);
820
828
 
821
829
    CallCheckStackGuardState(ebx);
822
 
    __ or_(eax, Operand(eax));
 
830
    __ or_(eax, eax);
823
831
    // If returning non-zero, we should end execution with the given
824
832
    // result as return value.
825
833
    __ j(not_zero, &exit_label_);
854
862
    __ CallCFunction(grow_stack, num_arguments);
855
863
    // If return NULL, we have failed to grow the stack, and
856
864
    // must exit with a stack-overflow exception.
857
 
    __ or_(eax, Operand(eax));
 
865
    __ or_(eax, eax);
858
866
    __ j(equal, &exit_with_exception);
859
867
    // Otherwise use return value as new stack pointer.
860
868
    __ mov(backtrack_stackpointer(), eax);
1133
1141
    frame_entry<const String*>(re_frame, kInputString) = *subject;
1134
1142
    frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1135
1143
    frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
 
1144
  } else if (frame_entry<const String*>(re_frame, kInputString) != *subject) {
 
1145
    // Subject string might have been a ConsString that underwent
 
1146
    // short-circuiting during GC. That will not change start_address but
 
1147
    // will change pointer inside the subject handle.
 
1148
    frame_entry<const String*>(re_frame, kInputString) = *subject;
1136
1149
  }
1137
1150
 
1138
1151
  return 0;
1183
1196
 
1184
1197
void RegExpMacroAssemblerIA32::SafeReturn() {
1185
1198
  __ pop(ebx);
1186
 
  __ add(Operand(ebx), Immediate(masm_->CodeObject()));
1187
 
  __ jmp(Operand(ebx));
 
1199
  __ add(ebx, Immediate(masm_->CodeObject()));
 
1200
  __ jmp(ebx);
1188
1201
}
1189
1202
 
1190
1203
 
1196
1209
void RegExpMacroAssemblerIA32::Push(Register source) {
1197
1210
  ASSERT(!source.is(backtrack_stackpointer()));
1198
1211
  // Notice: This updates flags, unlike normal Push.
1199
 
  __ sub(Operand(backtrack_stackpointer()), Immediate(kPointerSize));
 
1212
  __ sub(backtrack_stackpointer(), Immediate(kPointerSize));
1200
1213
  __ mov(Operand(backtrack_stackpointer(), 0), source);
1201
1214
}
1202
1215
 
1203
1216
 
1204
1217
void RegExpMacroAssemblerIA32::Push(Immediate value) {
1205
1218
  // Notice: This updates flags, unlike normal Push.
1206
 
  __ sub(Operand(backtrack_stackpointer()), Immediate(kPointerSize));
 
1219
  __ sub(backtrack_stackpointer(), Immediate(kPointerSize));
1207
1220
  __ mov(Operand(backtrack_stackpointer(), 0), value);
1208
1221
}
1209
1222
 
1212
1225
  ASSERT(!target.is(backtrack_stackpointer()));
1213
1226
  __ mov(target, Operand(backtrack_stackpointer(), 0));
1214
1227
  // Notice: This updates flags, unlike normal Pop.
1215
 
  __ add(Operand(backtrack_stackpointer()), Immediate(kPointerSize));
 
1228
  __ add(backtrack_stackpointer(), Immediate(kPointerSize));
1216
1229
}
1217
1230
 
1218
1231