30 #if defined(V8_TARGET_ARCH_ARM)
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),
135 __ jmp(&entry_label_);
136 EmitBacktrackConstantPool();
137 __ bind(&start_label_);
141 RegExpMacroAssemblerARM::~RegExpMacroAssemblerARM() {
144 entry_label_.Unuse();
145 start_label_.Unuse();
146 success_label_.Unuse();
147 backtrack_label_.Unuse();
149 check_preempt_label_.Unuse();
150 stack_overflow_label_.Unuse();
154 int RegExpMacroAssemblerARM::stack_limit_slack() {
155 return RegExpStack::kStackLimitSlack;
159 void RegExpMacroAssemblerARM::AdvanceCurrentPosition(
int by) {
161 __ add(current_input_offset(),
162 current_input_offset(), Operand(by * char_size()));
167 void RegExpMacroAssemblerARM::AdvanceRegister(
int reg,
int by) {
169 ASSERT(reg < num_registers_);
171 __ ldr(
r0, register_location(reg));
172 __ add(
r0,
r0, Operand(by));
173 __ str(
r0, register_location(reg));
178 void RegExpMacroAssemblerARM::Backtrack() {
182 __ add(
pc,
r0, Operand(code_pointer()));
186 void RegExpMacroAssemblerARM::Bind(Label* label) {
191 void RegExpMacroAssemblerARM::CheckCharacter(uint32_t c, Label* on_equal) {
192 __ cmp(current_character(), Operand(c));
193 BranchOrBacktrack(
eq, on_equal);
197 void RegExpMacroAssemblerARM::CheckCharacterGT(
uc16 limit, Label* on_greater) {
198 __ cmp(current_character(), Operand(limit));
199 BranchOrBacktrack(
gt, on_greater);
203 void RegExpMacroAssemblerARM::CheckAtStart(Label* on_at_start) {
208 BranchOrBacktrack(
ne, ¬_at_start);
212 __ add(
r0, end_of_input_address(), Operand(current_input_offset()));
214 BranchOrBacktrack(
eq, on_at_start);
215 __ bind(¬_at_start);
219 void RegExpMacroAssemblerARM::CheckNotAtStart(Label* on_not_at_start) {
223 BranchOrBacktrack(
ne, on_not_at_start);
226 __ add(
r0, end_of_input_address(), Operand(current_input_offset()));
228 BranchOrBacktrack(
ne, on_not_at_start);
232 void RegExpMacroAssemblerARM::CheckCharacterLT(
uc16 limit, Label* on_less) {
233 __ cmp(current_character(), Operand(limit));
234 BranchOrBacktrack(
lt, on_less);
238 void RegExpMacroAssemblerARM::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 __ add(
r0, end_of_input_address(), Operand(current_input_offset()));
254 if (cp_offset != 0) {
255 int byte_offset = cp_offset * char_size();
256 __ add(
r0,
r0, Operand(byte_offset));
260 int stored_high_byte = 0;
261 for (
int i = 0; i < str.length(); i++) {
262 if (mode_ == ASCII) {
265 __ cmp(
r1, Operand(str[i]));
268 uc16 match_char = str[i];
269 int match_high_byte = (match_char >> 8);
270 if (match_high_byte == 0) {
271 __ cmp(
r1, Operand(str[i]));
273 if (match_high_byte != stored_high_byte) {
274 __ mov(
r2, Operand(match_high_byte));
275 stored_high_byte = match_high_byte;
277 __ add(
r3,
r2, Operand(match_char & 0xff));
281 BranchOrBacktrack(
ne, on_failure);
286 void RegExpMacroAssemblerARM::CheckGreedyLoop(Label* on_equal) {
288 __ cmp(current_input_offset(),
r0);
289 __ add(backtrack_stackpointer(),
291 BranchOrBacktrack(
eq, on_equal);
295 void RegExpMacroAssemblerARM::CheckNotBackReferenceIgnoreCase(
297 Label* on_no_match) {
299 __ ldr(
r0, register_location(start_reg));
300 __ ldr(
r1, register_location(start_reg + 1));
305 __ b(
eq, &fallthrough);
308 __ cmn(
r1, Operand(current_input_offset()));
309 BranchOrBacktrack(
gt, on_no_match);
311 if (mode_ == ASCII) {
318 __ add(
r0,
r0, Operand(end_of_input_address()));
319 __ add(
r2, end_of_input_address(), Operand(current_input_offset()));
331 __ b(
eq, &loop_check);
334 __ orr(
r3,
r3, Operand(0x20));
335 __ orr(
r4,
r4, Operand(0x20));
338 __ sub(
r3,
r3, Operand(
'a'));
339 __ cmp(
r3, Operand(
'z' -
'a'));
343 __ bind(&loop_check);
349 BranchOrBacktrack(
al, on_no_match);
353 __ sub(current_input_offset(),
r2, end_of_input_address());
356 int argument_count = 4;
357 __ PrepareCallCFunction(argument_count,
r2);
370 __ add(
r0,
r0, Operand(end_of_input_address()));
376 __ add(
r1, current_input_offset(), Operand(end_of_input_address()));
378 __ mov(
r3, Operand(ExternalReference::isolate_address()));
381 AllowExternalCallThatCantCauseGC scope(masm_);
382 ExternalReference
function =
383 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate());
384 __ CallCFunction(
function, argument_count);
389 BranchOrBacktrack(
eq, on_no_match);
391 __ add(current_input_offset(), current_input_offset(), Operand(
r4));
394 __ bind(&fallthrough);
398 void RegExpMacroAssemblerARM::CheckNotBackReference(
400 Label* on_no_match) {
405 __ ldr(
r0, register_location(start_reg));
406 __ ldr(
r1, register_location(start_reg + 1));
409 __ b(
eq, &fallthrough);
412 __ cmn(
r1, Operand(current_input_offset()));
413 BranchOrBacktrack(
gt, on_no_match);
416 __ add(
r0,
r0, Operand(end_of_input_address()));
417 __ add(
r2, end_of_input_address(), Operand(current_input_offset()));
422 if (mode_ == ASCII) {
431 BranchOrBacktrack(
ne, on_no_match);
436 __ sub(current_input_offset(),
r2, end_of_input_address());
437 __ bind(&fallthrough);
441 void RegExpMacroAssemblerARM::CheckNotCharacter(
unsigned c,
442 Label* on_not_equal) {
443 __ cmp(current_character(), Operand(c));
444 BranchOrBacktrack(
ne, on_not_equal);
448 void RegExpMacroAssemblerARM::CheckCharacterAfterAnd(uint32_t c,
452 __ tst(current_character(), Operand(mask));
454 __ and_(
r0, current_character(), Operand(mask));
455 __ cmp(
r0, Operand(c));
457 BranchOrBacktrack(
eq, on_equal);
461 void RegExpMacroAssemblerARM::CheckNotCharacterAfterAnd(
unsigned c,
463 Label* on_not_equal) {
465 __ tst(current_character(), Operand(mask));
467 __ and_(
r0, current_character(), Operand(mask));
468 __ cmp(
r0, Operand(c));
470 BranchOrBacktrack(
ne, on_not_equal);
474 void RegExpMacroAssemblerARM::CheckNotCharacterAfterMinusAnd(
478 Label* on_not_equal) {
479 ASSERT(minus < String::kMaxUtf16CodeUnit);
480 __ sub(
r0, current_character(), Operand(minus));
481 __ and_(
r0,
r0, Operand(mask));
482 __ cmp(
r0, Operand(c));
483 BranchOrBacktrack(
ne, on_not_equal);
487 void RegExpMacroAssemblerARM::CheckCharacterInRange(
490 Label* on_in_range) {
491 __ sub(
r0, current_character(), Operand(from));
492 __ cmp(
r0, Operand(to - from));
493 BranchOrBacktrack(
ls, on_in_range);
497 void RegExpMacroAssemblerARM::CheckCharacterNotInRange(
500 Label* on_not_in_range) {
501 __ sub(
r0, current_character(), Operand(from));
502 __ cmp(
r0, Operand(to - from));
503 BranchOrBacktrack(
hi, on_not_in_range);
507 void RegExpMacroAssemblerARM::CheckBitInTable(
508 Handle<ByteArray> table,
510 __ mov(
r0, Operand(table));
512 __ and_(
r1, current_character(), Operand(kTableSize - 1));
520 __ cmp(
r0, Operand(0));
521 BranchOrBacktrack(
ne, on_bit_set);
525 bool RegExpMacroAssemblerARM::CheckSpecialCharacterClass(
uc16 type,
526 Label* on_no_match) {
532 if (mode_ == ASCII) {
535 __ cmp(current_character(), Operand(
' '));
538 __ sub(
r0, current_character(), Operand(
'\t'));
539 __ cmp(
r0, Operand(
'\r' -
'\t'));
540 BranchOrBacktrack(
hi, on_no_match);
547 if (mode_ == ASCII) {
549 __ cmp(current_character(), Operand(
' '));
550 BranchOrBacktrack(
eq, on_no_match);
551 __ sub(
r0, current_character(), Operand(
'\t'));
552 __ cmp(
r0, Operand(
'\r' -
'\t'));
553 BranchOrBacktrack(
ls, on_no_match);
559 __ sub(
r0, current_character(), Operand(
'0'));
560 __ cmp(current_character(), Operand(
'9' -
'0'));
561 BranchOrBacktrack(
hi, on_no_match);
565 __ sub(
r0, current_character(), Operand(
'0'));
566 __ cmp(
r0, Operand(
'9' -
'0'));
567 BranchOrBacktrack(
ls, on_no_match);
571 __ eor(
r0, current_character(), Operand(0x01));
573 __ sub(
r0,
r0, Operand(0x0b));
574 __ cmp(
r0, Operand(0x0c - 0x0b));
575 BranchOrBacktrack(
ls, on_no_match);
580 __ sub(
r0,
r0, Operand(0x2028 - 0x0b));
581 __ cmp(
r0, Operand(1));
582 BranchOrBacktrack(
ls, on_no_match);
588 __ eor(
r0, current_character(), Operand(0x01));
590 __ sub(
r0,
r0, Operand(0x0b));
591 __ cmp(
r0, Operand(0x0c - 0x0b));
592 if (mode_ == ASCII) {
593 BranchOrBacktrack(
hi, on_no_match);
600 __ sub(
r0,
r0, Operand(0x2028 - 0x0b));
601 __ cmp(
r0, Operand(1));
602 BranchOrBacktrack(
hi, on_no_match);
608 if (mode_ != ASCII) {
610 __ cmp(current_character(), Operand(
'z'));
611 BranchOrBacktrack(
hi, on_no_match);
613 ExternalReference map = ExternalReference::re_word_character_map();
614 __ mov(
r0, Operand(map));
616 __ cmp(
r0, Operand(0));
617 BranchOrBacktrack(
eq, on_no_match);
622 if (mode_ != ASCII) {
624 __ cmp(current_character(), Operand(
'z'));
627 ExternalReference map = ExternalReference::re_word_character_map();
628 __ mov(
r0, Operand(map));
630 __ cmp(
r0, Operand(0));
631 BranchOrBacktrack(
ne, on_no_match);
632 if (mode_ != ASCII) {
648 __ mov(
r0, Operand(FAILURE));
649 __ jmp(&exit_label_);
653 Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
659 __ bind(&entry_label_);
663 FrameScope scope(masm_, StackFrame::MANUAL);
674 __ stm(
db_w,
sp, argument_registers | registers_to_retain |
lr.
bit());
682 Label stack_limit_hit;
685 ExternalReference stack_limit =
686 ExternalReference::address_of_stack_limit(masm_->isolate());
687 __ mov(
r0, Operand(stack_limit));
691 __ b(
ls, &stack_limit_hit);
698 __ mov(
r0, Operand(EXCEPTION));
701 __ bind(&stack_limit_hit);
702 CallCheckStackGuardState(
r0);
705 __ b(
ne, &return_r0);
712 __ ldr(end_of_input_address(),
MemOperand(frame_pointer(), kInputEnd));
716 __ sub(current_input_offset(),
r0, end_of_input_address());
720 __ sub(
r0, current_input_offset(), Operand(char_size()));
721 __ sub(
r0,
r0, Operand(
r1,
LSL, (mode_ == UC16) ? 1 : 0));
727 __ mov(code_pointer(), Operand(masm_->CodeObject()));
729 Label load_char_start_regexp, start_regexp;
732 __ b(
ne, &load_char_start_regexp);
733 __ mov(current_character(), Operand(
'\n'),
LeaveCC,
eq);
734 __ jmp(&start_regexp);
737 __ bind(&load_char_start_regexp);
739 LoadCurrentCharacterUnchecked(-1, 1);
740 __ bind(&start_regexp);
743 if (num_saved_registers_ > 0) {
745 if (num_saved_registers_ > 8) {
747 __ add(
r1, frame_pointer(), Operand(kRegisterZero));
748 __ mov(
r2, Operand(num_saved_registers_));
753 __ b(
ne, &init_loop);
755 for (
int i = 0; i < num_saved_registers_; i++) {
756 __ str(
r0, register_location(i));
762 __ ldr(backtrack_stackpointer(),
MemOperand(frame_pointer(), kStackHighEnd));
764 __ jmp(&start_label_);
767 if (success_label_.is_linked()) {
769 __ bind(&success_label_);
770 if (num_saved_registers_ > 0) {
775 __ sub(
r1, end_of_input_address(),
r1);
788 for (
int i = 0; i < num_saved_registers_; i += 2) {
789 __ ldr(
r2, register_location(i));
790 __ ldr(
r3, register_location(i + 1));
791 if (i == 0 && global_with_zero_length_check()) {
813 __ add(
r0,
r0, Operand(1));
817 __ sub(
r1,
r1, Operand(num_saved_registers_));
819 __ cmp(
r1, Operand(num_saved_registers_));
820 __ b(
lt, &return_r0);
830 if (global_with_zero_length_check()) {
833 __ cmp(current_input_offset(),
r4);
835 __ b(
ne, &load_char_start_regexp);
837 __ cmp(current_input_offset(), Operand(0));
838 __ b(
eq, &exit_label_);
840 __ add(current_input_offset(),
841 current_input_offset(),
842 Operand((mode_ == UC16) ? 2 : 1));
845 __ b(&load_char_start_regexp);
847 __ mov(
r0, Operand(SUCCESS));
852 __ bind(&exit_label_);
859 __ mov(
sp, frame_pointer());
864 if (backtrack_label_.is_linked()) {
865 __ bind(&backtrack_label_);
869 Label exit_with_exception;
872 if (check_preempt_label_.is_linked()) {
873 SafeCallTarget(&check_preempt_label_);
875 CallCheckStackGuardState(
r0);
879 __ b(
ne, &return_r0);
882 __ ldr(end_of_input_address(),
MemOperand(frame_pointer(), kInputEnd));
887 if (stack_overflow_label_.is_linked()) {
888 SafeCallTarget(&stack_overflow_label_);
893 static const int num_arguments = 3;
894 __ PrepareCallCFunction(num_arguments,
r0);
895 __ mov(
r0, backtrack_stackpointer());
896 __ add(
r1, frame_pointer(), Operand(kStackHighEnd));
897 __ mov(
r2, Operand(ExternalReference::isolate_address()));
898 ExternalReference grow_stack =
899 ExternalReference::re_grow_stack(masm_->isolate());
900 __ CallCFunction(grow_stack, num_arguments);
904 __ b(
eq, &exit_with_exception);
906 __ mov(backtrack_stackpointer(),
r0);
911 if (exit_with_exception.is_linked()) {
913 __ bind(&exit_with_exception);
915 __ mov(
r0, Operand(EXCEPTION));
920 masm_->GetCode(&code_desc);
922 Code::ComputeFlags(Code::REGEXP),
923 masm_->CodeObject());
924 PROFILE(Isolate::Current(), RegExpCodeCreateEvent(*code, *source));
925 return Handle<HeapObject>::cast(code);
929 void RegExpMacroAssemblerARM::GoTo(Label* to) {
930 BranchOrBacktrack(
al, to);
934 void RegExpMacroAssemblerARM::IfRegisterGE(
int reg,
937 __ ldr(
r0, register_location(reg));
938 __ cmp(
r0, Operand(comparand));
939 BranchOrBacktrack(
ge, if_ge);
943 void RegExpMacroAssemblerARM::IfRegisterLT(
int reg,
946 __ ldr(
r0, register_location(reg));
947 __ cmp(
r0, Operand(comparand));
948 BranchOrBacktrack(
lt, if_lt);
952 void RegExpMacroAssemblerARM::IfRegisterEqPos(
int reg,
954 __ ldr(
r0, register_location(reg));
955 __ cmp(
r0, Operand(current_input_offset()));
956 BranchOrBacktrack(
eq, if_eq);
960 RegExpMacroAssembler::IrregexpImplementation
961 RegExpMacroAssemblerARM::Implementation() {
962 return kARMImplementation;
966 void RegExpMacroAssemblerARM::LoadCurrentCharacter(
int cp_offset,
967 Label* on_end_of_input,
971 ASSERT(cp_offset < (1<<30));
973 CheckPosition(cp_offset + characters - 1, on_end_of_input);
975 LoadCurrentCharacterUnchecked(cp_offset, characters);
979 void RegExpMacroAssemblerARM::PopCurrentPosition() {
980 Pop(current_input_offset());
984 void RegExpMacroAssemblerARM::PopRegister(
int register_index) {
986 __ str(
r0, register_location(register_index));
990 static bool is_valid_memory_offset(
int value) {
991 if (value < 0) value = -value;
992 return value < (1<<12);
996 void RegExpMacroAssemblerARM::PushBacktrack(Label* label) {
997 if (label->is_bound()) {
998 int target = label->pos();
1001 int constant_offset = GetBacktrackConstantPoolEntry();
1002 masm_->label_at_put(label, constant_offset);
1005 unsigned int offset_of_pc_register_read =
1006 masm_->pc_offset() + Assembler::kPcLoadDelta;
1007 int pc_offset_of_constant =
1008 constant_offset - offset_of_pc_register_read;
1009 ASSERT(pc_offset_of_constant < 0);
1010 if (is_valid_memory_offset(pc_offset_of_constant)) {
1011 Assembler::BlockConstPoolScope block_const_pool(masm_);
1016 Assembler::BlockConstPoolScope block_const_pool(masm_);
1017 __ mov(
r0, Operand(pc_offset_of_constant + Assembler::kInstrSize));
1026 void RegExpMacroAssemblerARM::PushCurrentPosition() {
1027 Push(current_input_offset());
1031 void RegExpMacroAssemblerARM::PushRegister(
int register_index,
1032 StackCheckFlag check_stack_limit) {
1033 __ ldr(
r0, register_location(register_index));
1035 if (check_stack_limit) CheckStackLimit();
1039 void RegExpMacroAssemblerARM::ReadCurrentPositionFromRegister(
int reg) {
1040 __ ldr(current_input_offset(), register_location(reg));
1044 void RegExpMacroAssemblerARM::ReadStackPointerFromRegister(
int reg) {
1045 __ ldr(backtrack_stackpointer(), register_location(reg));
1047 __ add(backtrack_stackpointer(), backtrack_stackpointer(), Operand(
r0));
1051 void RegExpMacroAssemblerARM::SetCurrentPositionFromEnd(
int by) {
1052 Label after_position;
1053 __ cmp(current_input_offset(), Operand(-by * char_size()));
1054 __ b(
ge, &after_position);
1055 __ mov(current_input_offset(), Operand(-by * char_size()));
1059 LoadCurrentCharacterUnchecked(-1, 1);
1060 __ bind(&after_position);
1064 void RegExpMacroAssemblerARM::SetRegister(
int register_index,
int to) {
1065 ASSERT(register_index >= num_saved_registers_);
1066 __ mov(
r0, Operand(to));
1067 __ str(
r0, register_location(register_index));
1071 bool RegExpMacroAssemblerARM::Succeed() {
1072 __ jmp(&success_label_);
1077 void RegExpMacroAssemblerARM::WriteCurrentPositionToRegister(
int reg,
1079 if (cp_offset == 0) {
1080 __ str(current_input_offset(), register_location(reg));
1082 __ add(
r0, current_input_offset(), Operand(cp_offset * char_size()));
1083 __ str(
r0, register_location(reg));
1088 void RegExpMacroAssemblerARM::ClearRegisters(
int reg_from,
int reg_to) {
1089 ASSERT(reg_from <= reg_to);
1091 for (
int reg = reg_from; reg <= reg_to; reg++) {
1092 __ str(
r0, register_location(reg));
1097 void RegExpMacroAssemblerARM::WriteStackPointerToRegister(
int reg) {
1099 __ sub(
r0, backtrack_stackpointer(),
r1);
1100 __ str(
r0, register_location(reg));
1106 void RegExpMacroAssemblerARM::CallCheckStackGuardState(Register scratch) {
1107 static const int num_arguments = 3;
1108 __ PrepareCallCFunction(num_arguments, scratch);
1110 __ mov(
r2, frame_pointer());
1112 __ mov(
r1, Operand(masm_->CodeObject()));
1114 ExternalReference stack_guard_check =
1115 ExternalReference::re_check_stack_guard_state(masm_->isolate());
1116 CallCFunctionUsingStub(stack_guard_check, num_arguments);
1121 template <
typename T>
1122 static T& frame_entry(
Address re_frame,
int frame_offset) {
1123 return reinterpret_cast<T&
>(Memory::int32_at(re_frame + frame_offset));
1127 int RegExpMacroAssemblerARM::CheckStackGuardState(
Address* return_address,
1130 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
1131 ASSERT(isolate == Isolate::Current());
1132 if (isolate->stack_guard()->IsStackOverflow()) {
1133 isolate->StackOverflow();
1142 if (frame_entry<int>(re_frame, kDirectCall) == 1) {
1147 HandleScope handles(isolate);
1148 Handle<Code> code_handle(re_code);
1150 Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
1153 bool is_ascii = subject->IsAsciiRepresentationUnderneath();
1155 ASSERT(re_code->instruction_start() <= *return_address);
1156 ASSERT(*return_address <=
1157 re_code->instruction_start() + re_code->instruction_size());
1159 MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
1161 if (*code_handle != re_code) {
1162 int delta = code_handle->address() - re_code->address();
1164 *return_address += delta;
1167 if (result->IsException()) {
1171 Handle<String> subject_tmp = subject;
1172 int slice_offset = 0;
1175 if (StringShape(*subject_tmp).IsCons()) {
1176 subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first());
1177 }
else if (StringShape(*subject_tmp).IsSliced()) {
1178 SlicedString* slice = SlicedString::cast(*subject_tmp);
1179 subject_tmp = Handle<String>(slice->parent());
1180 slice_offset = slice->offset();
1184 if (subject_tmp->IsAsciiRepresentation() != is_ascii) {
1195 ASSERT(StringShape(*subject_tmp).IsSequential() ||
1196 StringShape(*subject_tmp).IsExternal());
1199 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart);
1203 int start_index = frame_entry<int>(re_frame, kStartIndex);
1204 const byte* new_address = StringCharacterPosition(*subject_tmp,
1205 start_index + slice_offset);
1207 if (start_address != new_address) {
1210 const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd);
1211 int byte_length =
static_cast<int>(end_address - start_address);
1212 frame_entry<const String*>(re_frame, kInputString) = *subject;
1213 frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1214 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
1215 }
else if (frame_entry<const String*>(re_frame, kInputString) != *subject) {
1219 frame_entry<const String*>(re_frame, kInputString) = *subject;
1226 MemOperand RegExpMacroAssemblerARM::register_location(
int register_index) {
1227 ASSERT(register_index < (1<<30));
1228 if (num_registers_ <= register_index) {
1229 num_registers_ = register_index + 1;
1236 void RegExpMacroAssemblerARM::CheckPosition(
int cp_offset,
1237 Label* on_outside_input) {
1238 __ cmp(current_input_offset(), Operand(-cp_offset * char_size()));
1239 BranchOrBacktrack(
ge, on_outside_input);
1243 void RegExpMacroAssemblerARM::BranchOrBacktrack(
Condition condition,
1245 if (condition ==
al) {
1254 __ b(condition, &backtrack_label_);
1257 __ b(condition, to);
1261 void RegExpMacroAssemblerARM::SafeCall(Label* to,
Condition cond) {
1266 void RegExpMacroAssemblerARM::SafeReturn() {
1268 __ add(
pc,
lr, Operand(masm_->CodeObject()));
1272 void RegExpMacroAssemblerARM::SafeCallTarget(Label* name) {
1274 __ sub(
lr,
lr, Operand(masm_->CodeObject()));
1279 void RegExpMacroAssemblerARM::Push(Register source) {
1280 ASSERT(!source.is(backtrack_stackpointer()));
1286 void RegExpMacroAssemblerARM::Pop(Register target) {
1287 ASSERT(!target.is(backtrack_stackpointer()));
1293 void RegExpMacroAssemblerARM::CheckPreemption() {
1295 ExternalReference stack_limit =
1296 ExternalReference::address_of_stack_limit(masm_->isolate());
1297 __ mov(
r0, Operand(stack_limit));
1300 SafeCall(&check_preempt_label_,
ls);
1304 void RegExpMacroAssemblerARM::CheckStackLimit() {
1305 ExternalReference stack_limit =
1306 ExternalReference::address_of_regexp_stack_limit(masm_->isolate());
1307 __ mov(
r0, Operand(stack_limit));
1309 __ cmp(backtrack_stackpointer(), Operand(
r0));
1310 SafeCall(&stack_overflow_label_,
ls);
1314 void RegExpMacroAssemblerARM::EmitBacktrackConstantPool() {
1315 __ CheckConstPool(
false,
false);
1316 Assembler::BlockConstPoolScope block_const_pool(masm_);
1317 backtrack_constant_pool_offset_ = masm_->pc_offset();
1318 for (
int i = 0; i < kBacktrackConstantPoolSize; i++) {
1322 backtrack_constant_pool_capacity_ = kBacktrackConstantPoolSize;
1326 int RegExpMacroAssemblerARM::GetBacktrackConstantPoolEntry() {
1327 while (backtrack_constant_pool_capacity_ > 0) {
1328 int offset = backtrack_constant_pool_offset_;
1330 backtrack_constant_pool_capacity_--;
1331 if (masm_->pc_offset() - offset < 2 *
KB) {
1335 Label new_pool_skip;
1336 __ jmp(&new_pool_skip);
1337 EmitBacktrackConstantPool();
1338 __ bind(&new_pool_skip);
1339 int offset = backtrack_constant_pool_offset_;
1341 backtrack_constant_pool_capacity_--;
1346 void RegExpMacroAssemblerARM::CallCFunctionUsingStub(
1347 ExternalReference
function,
1348 int num_arguments) {
1350 ASSERT(num_arguments <= 4);
1351 __ mov(code_pointer(), Operand(
function));
1352 RegExpCEntryStub stub;
1354 if (OS::ActivationFrameAlignment() != 0) {
1357 __ mov(code_pointer(), Operand(masm_->CodeObject()));
1361 bool RegExpMacroAssemblerARM::CanReadUnaligned() {
1366 void RegExpMacroAssemblerARM::LoadCurrentCharacterUnchecked(
int cp_offset,
1368 Register offset = current_input_offset();
1369 if (cp_offset != 0) {
1371 __ add(
r4, current_input_offset(), Operand(cp_offset * char_size()));
1378 if (!CanReadUnaligned()) {
1382 if (mode_ == ASCII) {
1383 if (characters == 4) {
1384 __ ldr(current_character(),
MemOperand(end_of_input_address(), offset));
1385 }
else if (characters == 2) {
1386 __ ldrh(current_character(),
MemOperand(end_of_input_address(), offset));
1389 __ ldrb(current_character(),
MemOperand(end_of_input_address(), offset));
1393 if (characters == 2) {
1394 __ ldr(current_character(),
MemOperand(end_of_input_address(), offset));
1397 __ ldrh(current_character(),
MemOperand(end_of_input_address(), offset));
1403 void RegExpCEntryStub::Generate(MacroAssembler* masm_) {
1404 int stack_alignment = OS::ActivationFrameAlignment();
1416 #endif // V8_INTERPRETED_REGEXP
1420 #endif // V8_TARGET_ARCH_ARM
v8::Handle< v8::Value > Fail(const v8::Arguments &args)
#define ASSERT(condition)
#define PROFILE(isolate, Call)
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)
#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
RegExpMacroAssemblerARM(Mode mode, int registers_to_save, Zone *zone)
const uc32 kMaxAsciiCharCode