30 #if defined(V8_TARGET_ARCH_MIPS)
43 #ifndef V8_INTERPRETED_REGEXP
118 #define __ ACCESS_MASM(masm_)
122 int registers_to_save,
124 : NativeRegExpMacroAssembler(zone),
125 masm_(new MacroAssembler(Isolate::Current(),
NULL, kRegExpCodeSize)),
127 num_registers_(registers_to_save),
128 num_saved_registers_(registers_to_save),
134 internal_failure_label_() {
136 __ jmp(&entry_label_);
139 __ bind(&internal_failure_label_);
140 __ li(v0, Operand(FAILURE));
142 __ bind(&start_label_);
146 RegExpMacroAssemblerMIPS::~RegExpMacroAssemblerMIPS() {
149 entry_label_.Unuse();
150 start_label_.Unuse();
151 success_label_.Unuse();
152 backtrack_label_.Unuse();
154 check_preempt_label_.Unuse();
155 stack_overflow_label_.Unuse();
156 internal_failure_label_.Unuse();
160 int RegExpMacroAssemblerMIPS::stack_limit_slack() {
161 return RegExpStack::kStackLimitSlack;
165 void RegExpMacroAssemblerMIPS::AdvanceCurrentPosition(
int by) {
167 __ Addu(current_input_offset(),
168 current_input_offset(), Operand(by * char_size()));
173 void RegExpMacroAssemblerMIPS::AdvanceRegister(
int reg,
int by) {
175 ASSERT(reg < num_registers_);
177 __ lw(a0, register_location(reg));
178 __ Addu(a0, a0, Operand(by));
179 __ sw(a0, register_location(reg));
184 void RegExpMacroAssemblerMIPS::Backtrack() {
188 __ Addu(a0, a0, code_pointer());
193 void RegExpMacroAssemblerMIPS::Bind(Label* label) {
198 void RegExpMacroAssemblerMIPS::CheckCharacter(uint32_t c, Label* on_equal) {
199 BranchOrBacktrack(on_equal,
eq, current_character(), Operand(c));
203 void RegExpMacroAssemblerMIPS::CheckCharacterGT(
uc16 limit, Label* on_greater) {
204 BranchOrBacktrack(on_greater,
gt, current_character(), Operand(limit));
208 void RegExpMacroAssemblerMIPS::CheckAtStart(Label* on_at_start) {
212 BranchOrBacktrack(¬_at_start,
ne, a0, Operand(zero_reg));
216 __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
217 BranchOrBacktrack(on_at_start,
eq, a0, Operand(a1));
218 __ bind(¬_at_start);
222 void RegExpMacroAssemblerMIPS::CheckNotAtStart(Label* on_not_at_start) {
225 BranchOrBacktrack(on_not_at_start,
ne, a0, Operand(zero_reg));
228 __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
229 BranchOrBacktrack(on_not_at_start,
ne, a0, Operand(a1));
233 void RegExpMacroAssemblerMIPS::CheckCharacterLT(
uc16 limit, Label* on_less) {
234 BranchOrBacktrack(on_less,
lt, current_character(), Operand(limit));
238 void RegExpMacroAssemblerMIPS::CheckCharacters(Vector<const uc16> str,
241 bool check_end_of_string) {
242 if (on_failure ==
NULL) {
245 on_failure = &backtrack_label_;
248 if (check_end_of_string) {
250 CheckPosition(cp_offset + str.length() - 1, on_failure);
253 __ Addu(a0, end_of_input_address(), Operand(current_input_offset()));
254 if (cp_offset != 0) {
255 int byte_offset = cp_offset * char_size();
256 __ Addu(a0, a0, Operand(byte_offset));
260 int stored_high_byte = 0;
261 for (
int i = 0; i < str.length(); i++) {
262 if (mode_ == ASCII) {
264 __ addiu(a0, a0, char_size());
266 BranchOrBacktrack(on_failure,
ne, a1, Operand(str[i]));
269 __ addiu(a0, a0, char_size());
270 uc16 match_char = str[i];
271 int match_high_byte = (match_char >> 8);
272 if (match_high_byte == 0) {
273 BranchOrBacktrack(on_failure,
ne, a1, Operand(str[i]));
275 if (match_high_byte != stored_high_byte) {
276 __ li(a2, Operand(match_high_byte));
277 stored_high_byte = match_high_byte;
279 __ Addu(a3, a2, Operand(match_char & 0xff));
280 BranchOrBacktrack(on_failure,
ne, a1, Operand(a3));
287 void RegExpMacroAssemblerMIPS::CheckGreedyLoop(Label* on_equal) {
288 Label backtrack_non_equal;
290 __ Branch(&backtrack_non_equal,
ne, current_input_offset(), Operand(a0));
291 __ Addu(backtrack_stackpointer(),
292 backtrack_stackpointer(),
294 __ bind(&backtrack_non_equal);
295 BranchOrBacktrack(on_equal,
eq, current_input_offset(), Operand(a0));
299 void RegExpMacroAssemblerMIPS::CheckNotBackReferenceIgnoreCase(
301 Label* on_no_match) {
303 __ lw(a0, register_location(start_reg));
304 __ lw(a1, register_location(start_reg + 1));
309 __ Branch(&fallthrough,
eq, a1, Operand(zero_reg));
311 __ Addu(t5, a1, current_input_offset());
313 BranchOrBacktrack(on_no_match,
gt, t5, Operand(zero_reg));
315 if (mode_ == ASCII) {
322 __ Addu(a0, a0, Operand(end_of_input_address()));
323 __ Addu(a2, end_of_input_address(), Operand(current_input_offset()));
324 __ Addu(a1, a0, Operand(a1));
333 __ addiu(a0, a0, char_size());
335 __ addiu(a2, a2, char_size());
337 __ Branch(&loop_check,
eq, t0, Operand(a3));
340 __ Or(a3, a3, Operand(0x20));
341 __ Or(t0, t0, Operand(0x20));
342 __ Branch(&fail,
ne, t0, Operand(a3));
343 __ Subu(a3, a3, Operand(
'a'));
344 __ Branch(&fail,
hi, a3, Operand(
'z' -
'a'));
346 __ bind(&loop_check);
347 __ Branch(&loop,
lt, a0, Operand(a1));
355 __ Subu(current_input_offset(), a2, end_of_input_address());
359 RegList regexp_registers_to_retain = current_input_offset().bit() |
360 current_character().bit() | backtrack_stackpointer().bit();
361 __ MultiPush(regexp_registers_to_retain);
363 int argument_count = 4;
364 __ PrepareCallCFunction(argument_count, a2);
377 __ Addu(a0, a0, Operand(end_of_input_address()));
383 __ Addu(a1, current_input_offset(), Operand(end_of_input_address()));
385 __ li(a3, Operand(ExternalReference::isolate_address()));
388 AllowExternalCallThatCantCauseGC scope(masm_);
389 ExternalReference
function =
390 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
391 __ CallCFunction(
function, argument_count);
395 __ MultiPop(regexp_registers_to_retain);
397 __ lw(end_of_input_address(),
MemOperand(frame_pointer(), kInputEnd));
400 BranchOrBacktrack(on_no_match,
eq, v0, Operand(zero_reg));
402 __ Addu(current_input_offset(), current_input_offset(), Operand(
s3));
405 __ bind(&fallthrough);
409 void RegExpMacroAssemblerMIPS::CheckNotBackReference(
411 Label* on_no_match) {
416 __ lw(a0, register_location(start_reg));
417 __ lw(a1, register_location(start_reg + 1));
420 __ Branch(&fallthrough,
eq, a1, Operand(zero_reg));
422 __ Addu(t5, a1, current_input_offset());
424 BranchOrBacktrack(on_no_match,
gt, t5, Operand(zero_reg));
427 __ Addu(a0, a0, Operand(end_of_input_address()));
428 __ Addu(a2, end_of_input_address(), Operand(current_input_offset()));
429 __ Addu(a1, a1, Operand(a0));
433 if (mode_ == ASCII) {
435 __ addiu(a0, a0, char_size());
437 __ addiu(a2, a2, char_size());
441 __ addiu(a0, a0, char_size());
443 __ addiu(a2, a2, char_size());
445 BranchOrBacktrack(on_no_match,
ne, a3, Operand(t0));
446 __ Branch(&loop,
lt, a0, Operand(a1));
449 __ Subu(current_input_offset(), a2, end_of_input_address());
450 __ bind(&fallthrough);
454 void RegExpMacroAssemblerMIPS::CheckNotCharacter(uint32_t c,
455 Label* on_not_equal) {
456 BranchOrBacktrack(on_not_equal,
ne, current_character(), Operand(c));
460 void RegExpMacroAssemblerMIPS::CheckCharacterAfterAnd(uint32_t c,
463 __ And(a0, current_character(), Operand(mask));
464 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
465 BranchOrBacktrack(on_equal,
eq, a0, rhs);
469 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterAnd(uint32_t c,
471 Label* on_not_equal) {
472 __ And(a0, current_character(), Operand(mask));
473 Operand rhs = (c == 0) ? Operand(zero_reg) : Operand(c);
474 BranchOrBacktrack(on_not_equal,
ne, a0, rhs);
478 void RegExpMacroAssemblerMIPS::CheckNotCharacterAfterMinusAnd(
482 Label* on_not_equal) {
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));
490 void RegExpMacroAssemblerMIPS::CheckCharacterInRange(
493 Label* on_in_range) {
494 __ Subu(a0, current_character(), Operand(from));
496 BranchOrBacktrack(on_in_range,
ls, a0, Operand(to - from));
500 void RegExpMacroAssemblerMIPS::CheckCharacterNotInRange(
503 Label* on_not_in_range) {
504 __ Subu(a0, current_character(), Operand(from));
506 BranchOrBacktrack(on_not_in_range,
hi, a0, Operand(to - from));
510 void RegExpMacroAssemblerMIPS::CheckBitInTable(
511 Handle<ByteArray> table,
513 __ li(a0, Operand(table));
515 __ And(a1, current_character(), Operand(kTableSize - 1));
518 __ Addu(a0, a0, current_character());
522 BranchOrBacktrack(on_bit_set,
ne, a0, Operand(zero_reg));
526 bool RegExpMacroAssemblerMIPS::CheckSpecialCharacterClass(
uc16 type,
527 Label* on_no_match) {
533 if (mode_ == ASCII) {
536 __ Branch(&success,
eq, current_character(), Operand(
' '));
538 __ Subu(a0, current_character(), Operand(
'\t'));
539 BranchOrBacktrack(on_no_match,
hi, a0, Operand(
'\r' -
'\t'));
546 if (mode_ == ASCII) {
548 BranchOrBacktrack(on_no_match,
eq, current_character(), Operand(
' '));
549 __ Subu(a0, current_character(), Operand(
'\t'));
550 BranchOrBacktrack(on_no_match,
ls, a0, Operand(
'\r' -
'\t'));
556 __ Subu(a0, current_character(), Operand(
'0'));
557 BranchOrBacktrack(on_no_match,
hi, a0, Operand(
'9' -
'0'));
561 __ Subu(a0, current_character(), Operand(
'0'));
562 BranchOrBacktrack(on_no_match,
ls, a0, Operand(
'9' -
'0'));
566 __ Xor(a0, current_character(), Operand(0x01));
568 __ Subu(a0, a0, Operand(0x0b));
569 BranchOrBacktrack(on_no_match,
ls, a0, Operand(0x0c - 0x0b));
574 __ Subu(a0, a0, Operand(0x2028 - 0x0b));
575 BranchOrBacktrack(on_no_match,
ls, a0, Operand(1));
581 __ Xor(a0, current_character(), Operand(0x01));
583 __ Subu(a0, a0, Operand(0x0b));
584 if (mode_ == ASCII) {
585 BranchOrBacktrack(on_no_match,
hi, a0, Operand(0x0c - 0x0b));
588 BranchOrBacktrack(&done,
ls, a0, Operand(0x0c - 0x0b));
592 __ Subu(a0, a0, Operand(0x2028 - 0x0b));
593 BranchOrBacktrack(on_no_match,
hi, a0, Operand(1));
599 if (mode_ != ASCII) {
601 BranchOrBacktrack(on_no_match,
hi, current_character(), Operand(
'z'));
603 ExternalReference map = ExternalReference::re_word_character_map();
604 __ li(a0, Operand(map));
605 __ Addu(a0, a0, current_character());
607 BranchOrBacktrack(on_no_match,
eq, a0, Operand(zero_reg));
612 if (mode_ != ASCII) {
614 __ Branch(&done,
hi, current_character(), Operand(
'z'));
616 ExternalReference map = ExternalReference::re_word_character_map();
617 __ li(a0, Operand(map));
618 __ Addu(a0, a0, current_character());
620 BranchOrBacktrack(on_no_match,
ne, a0, Operand(zero_reg));
621 if (mode_ != ASCII) {
637 __ li(v0, Operand(FAILURE));
638 __ jmp(&exit_label_);
642 Handle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(Handle<String> source) {
644 if (masm_->has_exception()) {
648 __ bind_to(&entry_label_, internal_failure_label_.pos());
654 __ bind(&entry_label_);
658 FrameScope scope(masm_, StackFrame::MANUAL);
668 RegList argument_registers = a0.bit() | a1.bit() | a2.bit() | a3.bit();
669 __ MultiPush(argument_registers | registers_to_retain | ra.bit());
673 __ mov(a0, zero_reg);
678 Label stack_limit_hit;
681 ExternalReference stack_limit =
682 ExternalReference::address_of_stack_limit(masm_->isolate());
683 __ li(a0, Operand(stack_limit));
687 __ Branch(&stack_limit_hit,
le, a0, Operand(zero_reg));
693 __ li(v0, Operand(EXCEPTION));
696 __ bind(&stack_limit_hit);
697 CallCheckStackGuardState(a0);
699 __ Branch(&return_v0,
ne, v0, Operand(zero_reg));
705 __ lw(end_of_input_address(),
MemOperand(frame_pointer(), kInputEnd));
709 __ Subu(current_input_offset(), a0, end_of_input_address());
713 __ Subu(a0, current_input_offset(), Operand(char_size()));
714 __ sll(t5, a1, (mode_ == UC16) ? 1 : 0);
718 __ sw(a0,
MemOperand(frame_pointer(), kInputStartMinusOne));
723 Label load_char_start_regexp, start_regexp;
725 __ Branch(&load_char_start_regexp,
ne, a1, Operand(zero_reg));
726 __ li(current_character(), Operand(
'\n'));
727 __ jmp(&start_regexp);
730 __ bind(&load_char_start_regexp);
732 LoadCurrentCharacterUnchecked(-1, 1);
733 __ bind(&start_regexp);
736 if (num_saved_registers_ > 0) {
738 if (num_saved_registers_ > 8) {
740 __ Addu(a1, frame_pointer(), Operand(kRegisterZero));
741 __ li(a2, Operand(num_saved_registers_));
746 __ Subu(a2, a2, Operand(1));
747 __ Branch(&init_loop,
ne, a2, Operand(zero_reg));
749 for (
int i = 0; i < num_saved_registers_; i++) {
750 __ sw(a0, register_location(i));
756 __ lw(backtrack_stackpointer(),
MemOperand(frame_pointer(), kStackHighEnd));
758 __ jmp(&start_label_);
762 if (success_label_.is_linked()) {
764 __ bind(&success_label_);
765 if (num_saved_registers_ > 0) {
768 __ lw(a0,
MemOperand(frame_pointer(), kRegisterOutput));
770 __ Subu(a1, end_of_input_address(), a1);
776 __ Addu(a1, a1, Operand(a2));
783 for (
int i = 0; i < num_saved_registers_; i += 2) {
784 __ lw(a2, register_location(i));
785 __ lw(a3, register_location(i + 1));
786 if (i == 0 && global_with_zero_length_check()) {
796 __ Addu(a2, a1, Operand(a2));
797 __ Addu(a3, a1, Operand(a3));
808 __ lw(a0,
MemOperand(frame_pointer(), kSuccessfulCaptures));
809 __ lw(a1,
MemOperand(frame_pointer(), kNumOutputRegisters));
810 __ lw(a2,
MemOperand(frame_pointer(), kRegisterOutput));
813 __ sw(a0,
MemOperand(frame_pointer(), kSuccessfulCaptures));
816 __ Subu(a1, a1, num_saved_registers_);
819 __ Branch(&return_v0,
lt, a1, Operand(num_saved_registers_));
821 __ sw(a1,
MemOperand(frame_pointer(), kNumOutputRegisters));
824 __ sw(a2,
MemOperand(frame_pointer(), kRegisterOutput));
827 __ lw(a0,
MemOperand(frame_pointer(), kInputStartMinusOne));
829 if (global_with_zero_length_check()) {
834 &load_char_start_regexp,
ne, current_input_offset(), Operand(t7));
836 __ Branch(&exit_label_,
eq, current_input_offset(),
839 __ Addu(current_input_offset(),
840 current_input_offset(),
841 Operand((mode_ == UC16) ? 2 : 1));
844 __ Branch(&load_char_start_regexp);
846 __ li(v0, Operand(SUCCESS));
850 __ bind(&exit_label_);
852 __ lw(v0,
MemOperand(frame_pointer(), kSuccessfulCaptures));
857 __ mov(
sp, frame_pointer());
859 __ MultiPop(registers_to_retain | ra.bit());
863 if (backtrack_label_.is_linked()) {
864 __ bind(&backtrack_label_);
868 Label exit_with_exception;
871 if (check_preempt_label_.is_linked()) {
872 SafeCallTarget(&check_preempt_label_);
874 RegList regexp_registers_to_retain = current_input_offset().bit() |
875 current_character().bit() | backtrack_stackpointer().bit();
876 __ MultiPush(regexp_registers_to_retain);
877 CallCheckStackGuardState(a0);
878 __ MultiPop(regexp_registers_to_retain);
881 __ Branch(&return_v0,
ne, v0, Operand(zero_reg));
884 __ lw(end_of_input_address(),
MemOperand(frame_pointer(), kInputEnd));
890 if (stack_overflow_label_.is_linked()) {
891 SafeCallTarget(&stack_overflow_label_);
894 RegList regexp_registers = current_input_offset().bit() |
895 current_character().bit();
896 __ MultiPush(regexp_registers);
899 static const int num_arguments = 3;
900 __ PrepareCallCFunction(num_arguments, a0);
901 __ mov(a0, backtrack_stackpointer());
902 __ Addu(a1, frame_pointer(), Operand(kStackHighEnd));
903 __ li(a2, Operand(ExternalReference::isolate_address()));
904 ExternalReference grow_stack =
905 ExternalReference::re_grow_stack(masm_->isolate());
906 __ CallCFunction(grow_stack, num_arguments);
908 __ MultiPop(regexp_registers);
911 __ Branch(&exit_with_exception,
eq, v0, Operand(zero_reg));
913 __ mov(backtrack_stackpointer(), v0);
916 __ lw(end_of_input_address(),
MemOperand(frame_pointer(), kInputEnd));
920 if (exit_with_exception.is_linked()) {
922 __ bind(&exit_with_exception);
924 __ li(v0, Operand(EXCEPTION));
930 masm_->GetCode(&code_desc);
932 Code::ComputeFlags(Code::REGEXP),
933 masm_->CodeObject());
934 LOG(Isolate::Current(), RegExpCodeCreateEvent(*code, *source));
935 return Handle<HeapObject>::cast(code);
939 void RegExpMacroAssemblerMIPS::GoTo(Label* to) {
949 void RegExpMacroAssemblerMIPS::IfRegisterGE(
int reg,
952 __ lw(a0, register_location(reg));
953 BranchOrBacktrack(if_ge,
ge, a0, Operand(comparand));
957 void RegExpMacroAssemblerMIPS::IfRegisterLT(
int reg,
960 __ lw(a0, register_location(reg));
961 BranchOrBacktrack(if_lt,
lt, a0, Operand(comparand));
965 void RegExpMacroAssemblerMIPS::IfRegisterEqPos(
int reg,
967 __ lw(a0, register_location(reg));
968 BranchOrBacktrack(if_eq,
eq, a0, Operand(current_input_offset()));
972 RegExpMacroAssembler::IrregexpImplementation
973 RegExpMacroAssemblerMIPS::Implementation() {
974 return kMIPSImplementation;
978 void RegExpMacroAssemblerMIPS::LoadCurrentCharacter(
int cp_offset,
979 Label* on_end_of_input,
983 ASSERT(cp_offset < (1<<30));
985 CheckPosition(cp_offset + characters - 1, on_end_of_input);
987 LoadCurrentCharacterUnchecked(cp_offset, characters);
991 void RegExpMacroAssemblerMIPS::PopCurrentPosition() {
992 Pop(current_input_offset());
996 void RegExpMacroAssemblerMIPS::PopRegister(
int register_index) {
998 __ sw(a0, register_location(register_index));
1002 void RegExpMacroAssemblerMIPS::PushBacktrack(Label* label) {
1003 if (label->is_bound()) {
1004 int target = label->pos();
1007 Label after_constant;
1008 __ Branch(&after_constant);
1009 int offset = masm_->pc_offset();
1012 masm_->label_at_put(label, offset);
1013 __ bind(&after_constant);
1017 __ Addu(a0, code_pointer(), cp_offset);
1026 void RegExpMacroAssemblerMIPS::PushCurrentPosition() {
1027 Push(current_input_offset());
1031 void RegExpMacroAssemblerMIPS::PushRegister(
int register_index,
1032 StackCheckFlag check_stack_limit) {
1033 __ lw(a0, register_location(register_index));
1035 if (check_stack_limit) CheckStackLimit();
1039 void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(
int reg) {
1040 __ lw(current_input_offset(), register_location(reg));
1044 void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(
int reg) {
1045 __ lw(backtrack_stackpointer(), register_location(reg));
1047 __ Addu(backtrack_stackpointer(), backtrack_stackpointer(), Operand(a0));
1051 void RegExpMacroAssemblerMIPS::SetCurrentPositionFromEnd(
int by) {
1052 Label after_position;
1053 __ Branch(&after_position,
1055 current_input_offset(),
1056 Operand(-by * char_size()));
1057 __ li(current_input_offset(), -by * char_size());
1061 LoadCurrentCharacterUnchecked(-1, 1);
1062 __ bind(&after_position);
1066 void RegExpMacroAssemblerMIPS::SetRegister(
int register_index,
int to) {
1067 ASSERT(register_index >= num_saved_registers_);
1068 __ li(a0, Operand(to));
1069 __ sw(a0, register_location(register_index));
1073 bool RegExpMacroAssemblerMIPS::Succeed() {
1074 __ jmp(&success_label_);
1079 void RegExpMacroAssemblerMIPS::WriteCurrentPositionToRegister(
int reg,
1081 if (cp_offset == 0) {
1082 __ sw(current_input_offset(), register_location(reg));
1084 __ Addu(a0, current_input_offset(), Operand(cp_offset * char_size()));
1085 __ sw(a0, register_location(reg));
1090 void RegExpMacroAssemblerMIPS::ClearRegisters(
int reg_from,
int reg_to) {
1091 ASSERT(reg_from <= reg_to);
1092 __ lw(a0,
MemOperand(frame_pointer(), kInputStartMinusOne));
1093 for (
int reg = reg_from; reg <= reg_to; reg++) {
1094 __ sw(a0, register_location(reg));
1099 void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(
int reg) {
1101 __ Subu(a0, backtrack_stackpointer(), a1);
1102 __ sw(a0, register_location(reg));
1106 bool RegExpMacroAssemblerMIPS::CanReadUnaligned() {
1113 void RegExpMacroAssemblerMIPS::CallCheckStackGuardState(Register scratch) {
1114 static const int num_arguments = 3;
1115 __ PrepareCallCFunction(num_arguments, scratch);
1116 __ mov(a2, frame_pointer());
1120 ExternalReference stack_guard_check =
1121 ExternalReference::re_check_stack_guard_state(masm_->isolate());
1122 CallCFunctionUsingStub(stack_guard_check, num_arguments);
1127 template <
typename T>
1128 static T& frame_entry(
Address re_frame,
int frame_offset) {
1129 return reinterpret_cast<T&
>(Memory::int32_at(re_frame + frame_offset));
1133 int RegExpMacroAssemblerMIPS::CheckStackGuardState(
Address* return_address,
1136 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
1137 ASSERT(isolate == Isolate::Current());
1138 if (isolate->stack_guard()->IsStackOverflow()) {
1139 isolate->StackOverflow();
1148 if (frame_entry<int>(re_frame, kDirectCall) == 1) {
1153 HandleScope handles(isolate);
1154 Handle<Code> code_handle(re_code);
1156 Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
1158 bool is_ascii = subject->IsAsciiRepresentationUnderneath();
1160 ASSERT(re_code->instruction_start() <= *return_address);
1161 ASSERT(*return_address <=
1162 re_code->instruction_start() + re_code->instruction_size());
1164 MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
1166 if (*code_handle != re_code) {
1167 int delta = code_handle->address() - re_code->address();
1169 *return_address += delta;
1172 if (result->IsException()) {
1176 Handle<String> subject_tmp = subject;
1177 int slice_offset = 0;
1180 if (StringShape(*subject_tmp).IsCons()) {
1181 subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first());
1182 }
else if (StringShape(*subject_tmp).IsSliced()) {
1183 SlicedString* slice = SlicedString::cast(*subject_tmp);
1184 subject_tmp = Handle<String>(slice->parent());
1185 slice_offset = slice->offset();
1189 if (subject_tmp->IsAsciiRepresentation() != is_ascii) {
1200 ASSERT(StringShape(*subject_tmp).IsSequential() ||
1201 StringShape(*subject_tmp).IsExternal());
1204 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart);
1208 int start_index = frame_entry<int>(re_frame, kStartIndex);
1209 const byte* new_address = StringCharacterPosition(*subject_tmp,
1210 start_index + slice_offset);
1212 if (start_address != new_address) {
1215 const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd);
1216 int byte_length =
static_cast<int>(end_address - start_address);
1217 frame_entry<const String*>(re_frame, kInputString) = *subject;
1218 frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1219 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
1220 }
else if (frame_entry<const String*>(re_frame, kInputString) != *subject) {
1224 frame_entry<const String*>(re_frame, kInputString) = *subject;
1231 MemOperand RegExpMacroAssemblerMIPS::register_location(
int register_index) {
1232 ASSERT(register_index < (1<<30));
1233 if (num_registers_ <= register_index) {
1234 num_registers_ = register_index + 1;
1241 void RegExpMacroAssemblerMIPS::CheckPosition(
int cp_offset,
1242 Label* on_outside_input) {
1243 BranchOrBacktrack(on_outside_input,
1245 current_input_offset(),
1246 Operand(-cp_offset * char_size()));
1250 void RegExpMacroAssemblerMIPS::BranchOrBacktrack(Label* to,
1253 const Operand& rt) {
1254 if (condition ==
al) {
1263 __ Branch(&backtrack_label_, condition, rs, rt);
1266 __ Branch(to, condition, rs, rt);
1270 void RegExpMacroAssemblerMIPS::SafeCall(Label* to,
1273 const Operand& rt) {
1274 __ BranchAndLink(to, cond, rs, rt);
1278 void RegExpMacroAssemblerMIPS::SafeReturn() {
1280 __ Addu(t5, ra, Operand(masm_->CodeObject()));
1285 void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) {
1287 __ Subu(ra, ra, Operand(masm_->CodeObject()));
1292 void RegExpMacroAssemblerMIPS::Push(Register source) {
1293 ASSERT(!source.is(backtrack_stackpointer()));
1294 __ Addu(backtrack_stackpointer(),
1295 backtrack_stackpointer(),
1301 void RegExpMacroAssemblerMIPS::Pop(Register target) {
1302 ASSERT(!target.is(backtrack_stackpointer()));
1304 __ Addu(backtrack_stackpointer(), backtrack_stackpointer(),
kPointerSize);
1308 void RegExpMacroAssemblerMIPS::CheckPreemption() {
1310 ExternalReference stack_limit =
1311 ExternalReference::address_of_stack_limit(masm_->isolate());
1312 __ li(a0, Operand(stack_limit));
1314 SafeCall(&check_preempt_label_,
ls,
sp, Operand(a0));
1318 void RegExpMacroAssemblerMIPS::CheckStackLimit() {
1319 ExternalReference stack_limit =
1320 ExternalReference::address_of_regexp_stack_limit(masm_->isolate());
1322 __ li(a0, Operand(stack_limit));
1324 SafeCall(&stack_overflow_label_,
ls, backtrack_stackpointer(), Operand(a0));
1328 void RegExpMacroAssemblerMIPS::CallCFunctionUsingStub(
1329 ExternalReference
function,
1330 int num_arguments) {
1332 ASSERT(num_arguments <= 4);
1333 __ li(code_pointer(), Operand(
function));
1334 RegExpCEntryStub stub;
1336 if (OS::ActivationFrameAlignment() != 0) {
1343 void RegExpMacroAssemblerMIPS::LoadCurrentCharacterUnchecked(
int cp_offset,
1345 Register offset = current_input_offset();
1346 if (cp_offset != 0) {
1348 __ Addu(t7, current_input_offset(), Operand(cp_offset * char_size()));
1354 __ Addu(t5, end_of_input_address(), Operand(offset));
1355 if (mode_ == ASCII) {
1364 void RegExpCEntryStub::Generate(MacroAssembler* masm_) {
1365 int stack_alignment = OS::ActivationFrameAlignment();
1371 __ Addu(a0,
sp, return_address_offset);
1383 #endif // V8_INTERPRETED_REGEXP
1387 #endif // V8_TARGET_ARCH_MIPS
const int kCArgsSlotsSize
RegExpMacroAssemblerMIPS(Mode mode, int registers_to_save, Zone *zone)
v8::Handle< v8::Value > Fail(const v8::Arguments &args)
#define LOG(isolate, Call)
#define ASSERT(condition)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
#define T(name, string, precedence)
MemOperand FieldMemOperand(Register object, int offset)
#define ASSERT_EQ(v1, v2)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
const uc32 kMaxAsciiCharCode