30 #if defined(V8_TARGET_ARCH_X64)
43 #ifndef V8_INTERPRETED_REGEXP
116 #define __ ACCESS_MASM((&masm_))
120 int registers_to_save,
122 : NativeRegExpMacroAssembler(zone),
123 masm_(Isolate::Current(),
NULL, kRegExpCodeSize),
124 no_root_array_scope_(&masm_),
125 code_relative_fixup_positions_(4, zone),
127 num_registers_(registers_to_save),
128 num_saved_registers_(registers_to_save),
135 __ jmp(&entry_label_);
136 __ bind(&start_label_);
140 RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() {
142 entry_label_.Unuse();
143 start_label_.Unuse();
144 success_label_.Unuse();
145 backtrack_label_.Unuse();
147 check_preempt_label_.Unuse();
148 stack_overflow_label_.Unuse();
152 int RegExpMacroAssemblerX64::stack_limit_slack() {
153 return RegExpStack::kStackLimitSlack;
157 void RegExpMacroAssemblerX64::AdvanceCurrentPosition(
int by) {
159 __ addq(
rdi, Immediate(by * char_size()));
164 void RegExpMacroAssemblerX64::AdvanceRegister(
int reg,
int by) {
166 ASSERT(reg < num_registers_);
168 __ addq(register_location(reg), Immediate(by));
173 void RegExpMacroAssemblerX64::Backtrack() {
177 __ addq(
rbx, code_object_pointer());
182 void RegExpMacroAssemblerX64::Bind(Label* label) {
187 void RegExpMacroAssemblerX64::CheckCharacter(uint32_t c, Label* on_equal) {
188 __ cmpl(current_character(), Immediate(c));
189 BranchOrBacktrack(
equal, on_equal);
193 void RegExpMacroAssemblerX64::CheckCharacterGT(
uc16 limit, Label* on_greater) {
194 __ cmpl(current_character(), Immediate(limit));
195 BranchOrBacktrack(
greater, on_greater);
199 void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) {
202 __ cmpl(Operand(
rbp, kStartIndex), Immediate(0));
203 BranchOrBacktrack(
not_equal, ¬_at_start);
206 __ cmpq(
rax, Operand(
rbp, kInputStart));
207 BranchOrBacktrack(
equal, on_at_start);
208 __ bind(¬_at_start);
212 void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) {
214 __ cmpl(Operand(
rbp, kStartIndex), Immediate(0));
215 BranchOrBacktrack(
not_equal, on_not_at_start);
218 __ cmpq(
rax, Operand(
rbp, kInputStart));
219 BranchOrBacktrack(
not_equal, on_not_at_start);
223 void RegExpMacroAssemblerX64::CheckCharacterLT(
uc16 limit, Label* on_less) {
224 __ cmpl(current_character(), Immediate(limit));
225 BranchOrBacktrack(
less, on_less);
229 void RegExpMacroAssemblerX64::CheckCharacters(Vector<const uc16> str,
232 bool check_end_of_string) {
236 if (mode_ == ASCII) {
237 ASSERT(String::IsAscii(str.start(), str.length()));
240 int byte_length = str.length() * char_size();
241 int byte_offset = cp_offset * char_size();
242 if (check_end_of_string) {
244 __ cmpl(
rdi, Immediate(-(byte_offset + byte_length)));
245 BranchOrBacktrack(
greater, on_failure);
248 if (on_failure ==
NULL) {
250 on_failure = &backtrack_label_;
258 if (mode_ == ASCII) {
260 Immediate(static_cast<int8_t>(str[0])));
266 __ cmpl(
rax, Immediate(static_cast<int32_t>(str[0])));
268 BranchOrBacktrack(
not_equal, on_failure);
271 for (
int i = 1, n = str.length(); i < n; ) {
272 if (mode_ == ASCII) {
274 uint64_t combined_chars =
275 (
static_cast<uint64_t
>(str[i + 0]) << 0) ||
276 (
static_cast<uint64_t
>(str[i + 1]) << 8) ||
277 (
static_cast<uint64_t
>(str[i + 2]) << 16) ||
278 (
static_cast<uint64_t
>(str[i + 3]) << 24) ||
279 (
static_cast<uint64_t
>(str[i + 4]) << 32) ||
280 (
static_cast<uint64_t
>(str[i + 5]) << 40) ||
281 (
static_cast<uint64_t
>(str[i + 6]) << 48) ||
282 (
static_cast<uint64_t
>(str[i + 7]) << 56);
284 __ cmpq(
rax, Operand(
rbx, byte_offset + i));
286 }
else if (i + 4 <= n) {
287 uint32_t combined_chars =
288 (
static_cast<uint32_t
>(str[i + 0]) << 0) ||
289 (
static_cast<uint32_t
>(str[i + 1]) << 8) ||
290 (
static_cast<uint32_t
>(str[i + 2]) << 16) ||
291 (
static_cast<uint32_t
>(str[i + 3]) << 24);
292 __ cmpl(Operand(
rbx, byte_offset + i), Immediate(combined_chars));
295 __ cmpb(Operand(
rbx, byte_offset + i),
296 Immediate(static_cast<int8_t>(str[i])));
302 uint64_t combined_chars = *
reinterpret_cast<const uint64_t*
>(&str[i]);
307 }
else if (i + 2 <= n) {
308 uint32_t combined_chars = *
reinterpret_cast<const uint32_t*
>(&str[i]);
310 Immediate(combined_chars));
315 __ cmpl(
rax, Immediate(str[i]));
319 BranchOrBacktrack(
not_equal, on_failure);
324 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
326 __ cmpl(
rdi, Operand(backtrack_stackpointer(), 0));
330 __ bind(&fallthrough);
334 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
336 Label* on_no_match) {
338 __ movq(
rdx, register_location(start_reg));
339 __ movq(
rbx, register_location(start_reg + 1));
356 if (mode_ == ASCII) {
357 Label loop_increment;
358 if (on_no_match ==
NULL) {
359 on_no_match = &backtrack_label_;
372 __ movzxbl(
rdx, Operand(
r9, 0));
382 __ or_(
rax, Immediate(0x20));
383 __ or_(
rdx, Immediate(0x20));
386 __ subb(
rax, Immediate(
'a'));
387 __ cmpb(
rax, Immediate(
'z' -
'a'));
390 __ bind(&loop_increment);
392 __ addq(
r11, Immediate(1));
393 __ addq(
r9, Immediate(1));
409 __ push(backtrack_stackpointer());
411 static const int num_arguments = 4;
412 __ PrepareCallCFunction(num_arguments);
427 __ LoadAddress(
r9, ExternalReference::isolate_address());
428 #else // AMD64 calling convention
438 __ LoadAddress(
rcx, ExternalReference::isolate_address());
443 AllowExternalCallThatCantCauseGC scope(&masm_);
444 ExternalReference compare =
445 ExternalReference::re_case_insensitive_compare_uc16(masm_.isolate());
446 __ CallCFunction(compare, num_arguments);
450 __ Move(code_object_pointer(), masm_.CodeObject());
451 __ pop(backtrack_stackpointer());
459 BranchOrBacktrack(
zero, on_no_match);
464 __ bind(&fallthrough);
468 void RegExpMacroAssemblerX64::CheckNotBackReference(
470 Label* on_no_match) {
474 __ movq(
rdx, register_location(start_reg));
475 __ movq(
rax, register_location(start_reg + 1));
493 BranchOrBacktrack(
greater, on_no_match);
507 if (mode_ == ASCII) {
515 BranchOrBacktrack(
not_equal, on_no_match);
517 __ addq(
rbx, Immediate(char_size()));
518 __ addq(
rdx, Immediate(char_size()));
528 __ bind(&fallthrough);
532 void RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c,
533 Label* on_not_equal) {
534 __ cmpl(current_character(), Immediate(c));
535 BranchOrBacktrack(
not_equal, on_not_equal);
539 void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c,
543 __ testl(current_character(), Immediate(mask));
545 __ movl(
rax, Immediate(mask));
546 __ and_(
rax, current_character());
547 __ cmpl(
rax, Immediate(c));
549 BranchOrBacktrack(
equal, on_equal);
553 void RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(uint32_t c,
555 Label* on_not_equal) {
557 __ testl(current_character(), Immediate(mask));
559 __ movl(
rax, Immediate(mask));
560 __ and_(
rax, current_character());
561 __ cmpl(
rax, Immediate(c));
563 BranchOrBacktrack(
not_equal, on_not_equal);
567 void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd(
571 Label* on_not_equal) {
572 ASSERT(minus < String::kMaxUtf16CodeUnit);
573 __ lea(
rax, Operand(current_character(), -minus));
574 __ and_(
rax, Immediate(mask));
575 __ cmpl(
rax, Immediate(c));
576 BranchOrBacktrack(
not_equal, on_not_equal);
580 void RegExpMacroAssemblerX64::CheckCharacterInRange(
583 Label* on_in_range) {
584 __ leal(
rax, Operand(current_character(), -from));
585 __ cmpl(
rax, Immediate(to - from));
590 void RegExpMacroAssemblerX64::CheckCharacterNotInRange(
593 Label* on_not_in_range) {
594 __ leal(
rax, Operand(current_character(), -from));
595 __ cmpl(
rax, Immediate(to - from));
596 BranchOrBacktrack(
above, on_not_in_range);
600 void RegExpMacroAssemblerX64::CheckBitInTable(
601 Handle<ByteArray> table,
604 Register index = current_character();
606 __ movq(
rbx, current_character());
607 __ and_(
rbx, Immediate(kTableMask));
612 BranchOrBacktrack(
not_equal, on_bit_set);
616 bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(
uc16 type,
617 Label* on_no_match) {
625 if (mode_ == ASCII) {
628 __ cmpl(current_character(), Immediate(
' '));
631 __ lea(
rax, Operand(current_character(), -
'\t'));
632 __ cmpl(
rax, Immediate(
'\r' -
'\t'));
633 BranchOrBacktrack(
above, on_no_match);
640 if (mode_ == ASCII) {
642 __ cmpl(current_character(), Immediate(
' '));
643 BranchOrBacktrack(
equal, on_no_match);
644 __ lea(
rax, Operand(current_character(), -
'\t'));
645 __ cmpl(
rax, Immediate(
'\r' -
'\t'));
652 __ lea(
rax, Operand(current_character(), -
'0'));
653 __ cmpl(
rax, Immediate(
'9' -
'0'));
654 BranchOrBacktrack(
above, on_no_match);
658 __ lea(
rax, Operand(current_character(), -
'0'));
659 __ cmpl(
rax, Immediate(
'9' -
'0'));
664 __ movl(
rax, current_character());
665 __ xor_(
rax, Immediate(0x01));
667 __ subl(
rax, Immediate(0x0b));
668 __ cmpl(
rax, Immediate(0x0c - 0x0b));
674 __ subl(
rax, Immediate(0x2028 - 0x0b));
675 __ cmpl(
rax, Immediate(0x2029 - 0x2028));
682 __ movl(
rax, current_character());
683 __ xor_(
rax, Immediate(0x01));
685 __ subl(
rax, Immediate(0x0b));
686 __ cmpl(
rax, Immediate(0x0c - 0x0b));
687 if (mode_ == ASCII) {
688 BranchOrBacktrack(
above, on_no_match);
695 __ subl(
rax, Immediate(0x2028 - 0x0b));
696 __ cmpl(
rax, Immediate(0x2029 - 0x2028));
697 BranchOrBacktrack(
above, on_no_match);
703 if (mode_ != ASCII) {
705 __ cmpl(current_character(), Immediate(
'z'));
706 BranchOrBacktrack(
above, on_no_match);
708 __ movq(
rbx, ExternalReference::re_word_character_map());
711 current_character());
712 BranchOrBacktrack(
zero, on_no_match);
717 if (mode_ != ASCII) {
719 __ cmpl(current_character(), Immediate(
'z'));
722 __ movq(
rbx, ExternalReference::re_word_character_map());
725 current_character());
726 BranchOrBacktrack(
not_zero, on_no_match);
727 if (mode_ != ASCII) {
746 __ Set(
rax, FAILURE);
748 __ jmp(&exit_label_);
752 Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
757 __ bind(&entry_label_);
761 FrameScope scope(&masm_, StackFrame::MANUAL);
771 __ movq(Operand(
rbp, kInputString),
rcx);
772 __ movq(Operand(
rbp, kStartIndex),
rdx);
773 __ movq(Operand(
rbp, kInputStart),
r8);
774 __ movq(Operand(
rbp, kInputEnd),
r9);
798 __ push(Immediate(0));
799 __ push(Immediate(0));
802 Label stack_limit_hit;
805 ExternalReference stack_limit =
806 ExternalReference::address_of_stack_limit(masm_.isolate());
818 __ Set(
rax, EXCEPTION);
821 __ bind(&stack_limit_hit);
822 __ Move(code_object_pointer(), masm_.CodeObject());
823 CallCheckStackGuardState();
833 __ movq(
rsi, Operand(
rbp, kInputEnd));
835 __ movq(
rdi, Operand(
rbp, kInputStart));
840 __ movq(
rbx, Operand(
rbp, kStartIndex));
849 __ movq(Operand(
rbp, kInputStartMinusOne),
rax);
854 const int kPageSize = 4096;
856 for (
int i = num_saved_registers_ + kRegistersPerPage - 1;
858 i += kRegistersPerPage) {
859 __ movq(register_location(i),
rax);
864 __ Move(code_object_pointer(), masm_.CodeObject());
866 Label load_char_start_regexp, start_regexp;
868 __ cmpl(Operand(
rbp, kStartIndex), Immediate(0));
869 __ j(
not_equal, &load_char_start_regexp, Label::kNear);
870 __ Set(current_character(),
'\n');
871 __ jmp(&start_regexp, Label::kNear);
874 __ bind(&load_char_start_regexp);
876 LoadCurrentCharacterUnchecked(-1, 1);
877 __ bind(&start_regexp);
880 if (num_saved_registers_ > 0) {
884 if (num_saved_registers_ > 8) {
885 __ Set(
rcx, kRegisterZero);
891 Immediate(kRegisterZero - num_saved_registers_ *
kPointerSize));
894 for (
int i = 0; i < num_saved_registers_; i++) {
895 __ movq(register_location(i),
rax);
901 __ movq(backtrack_stackpointer(), Operand(
rbp, kStackHighEnd));
903 __ jmp(&start_label_);
906 if (success_label_.is_linked()) {
908 __ bind(&success_label_);
909 if (num_saved_registers_ > 0) {
911 __ movq(
rdx, Operand(
rbp, kStartIndex));
912 __ movq(
rbx, Operand(
rbp, kRegisterOutput));
913 __ movq(
rcx, Operand(
rbp, kInputEnd));
914 __ subq(
rcx, Operand(
rbp, kInputStart));
920 for (
int i = 0; i < num_saved_registers_; i++) {
921 __ movq(
rax, register_location(i));
922 if (i == 0 && global_with_zero_length_check()) {
928 __ sar(
rax, Immediate(1));
937 __ incq(Operand(
rbp, kSuccessfulCaptures));
940 __ movsxlq(
rcx, Operand(
rbp, kNumOutputRegisters));
941 __ subq(
rcx, Immediate(num_saved_registers_));
943 __ cmpq(
rcx, Immediate(num_saved_registers_));
946 __ movq(Operand(
rbp, kNumOutputRegisters),
rcx);
948 __ addq(Operand(
rbp, kRegisterOutput),
949 Immediate(num_saved_registers_ *
kIntSize));
952 __ movq(
rax, Operand(
rbp, kInputStartMinusOne));
954 if (global_with_zero_length_check()) {
962 __ j(
zero, &exit_label_, Label::kNear);
965 __ addq(
rdi, Immediate(2));
971 __ jmp(&load_char_start_regexp);
973 __ movq(
rax, Immediate(SUCCESS));
977 __ bind(&exit_label_);
980 __ movq(
rax, Operand(
rbp, kSuccessfulCaptures));
983 __ bind(&return_rax);
986 __ lea(
rsp, Operand(
rbp, kLastCalleeSaveRegister));
993 __ movq(
rbx, Operand(
rbp, kBackup_rbx));
1002 if (backtrack_label_.is_linked()) {
1003 __ bind(&backtrack_label_);
1007 Label exit_with_exception;
1010 if (check_preempt_label_.is_linked()) {
1011 SafeCallTarget(&check_preempt_label_);
1013 __ push(backtrack_stackpointer());
1016 CallCheckStackGuardState();
1023 __ Move(code_object_pointer(), masm_.CodeObject());
1025 __ pop(backtrack_stackpointer());
1027 __ movq(
rsi, Operand(
rbp, kInputEnd));
1032 if (stack_overflow_label_.is_linked()) {
1033 SafeCallTarget(&stack_overflow_label_);
1045 static const int num_arguments = 3;
1046 __ PrepareCallCFunction(num_arguments);
1050 __ lea(
rdx, Operand(
rbp, kStackHighEnd));
1051 __ LoadAddress(
r8, ExternalReference::isolate_address());
1054 __ movq(
rdi, backtrack_stackpointer());
1055 __ lea(
rsi, Operand(
rbp, kStackHighEnd));
1056 __ LoadAddress(
rdx, ExternalReference::isolate_address());
1058 ExternalReference grow_stack =
1059 ExternalReference::re_grow_stack(masm_.isolate());
1060 __ CallCFunction(grow_stack, num_arguments);
1064 __ j(
equal, &exit_with_exception);
1066 __ movq(backtrack_stackpointer(),
rax);
1068 __ Move(code_object_pointer(), masm_.CodeObject());
1076 if (exit_with_exception.is_linked()) {
1078 __ bind(&exit_with_exception);
1080 __ Set(
rax, EXCEPTION);
1081 __ jmp(&return_rax);
1084 FixupCodeRelativePositions();
1087 masm_.GetCode(&code_desc);
1089 Handle<Code> code = isolate->factory()->NewCode(
1090 code_desc, Code::ComputeFlags(Code::REGEXP),
1091 masm_.CodeObject());
1092 PROFILE(isolate, RegExpCodeCreateEvent(*code, *source));
1093 return Handle<HeapObject>::cast(code);
1097 void RegExpMacroAssemblerX64::GoTo(Label* to) {
1102 void RegExpMacroAssemblerX64::IfRegisterGE(
int reg,
1105 __ cmpq(register_location(reg), Immediate(comparand));
1110 void RegExpMacroAssemblerX64::IfRegisterLT(
int reg,
1113 __ cmpq(register_location(reg), Immediate(comparand));
1114 BranchOrBacktrack(
less, if_lt);
1118 void RegExpMacroAssemblerX64::IfRegisterEqPos(
int reg,
1120 __ cmpq(
rdi, register_location(reg));
1121 BranchOrBacktrack(
equal, if_eq);
1125 RegExpMacroAssembler::IrregexpImplementation
1126 RegExpMacroAssemblerX64::Implementation() {
1127 return kX64Implementation;
1131 void RegExpMacroAssemblerX64::LoadCurrentCharacter(
int cp_offset,
1132 Label* on_end_of_input,
1136 ASSERT(cp_offset < (1<<30));
1138 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1140 LoadCurrentCharacterUnchecked(cp_offset, characters);
1144 void RegExpMacroAssemblerX64::PopCurrentPosition() {
1149 void RegExpMacroAssemblerX64::PopRegister(
int register_index) {
1151 __ movq(register_location(register_index),
rax);
1155 void RegExpMacroAssemblerX64::PushBacktrack(Label* label) {
1161 void RegExpMacroAssemblerX64::PushCurrentPosition() {
1166 void RegExpMacroAssemblerX64::PushRegister(
int register_index,
1167 StackCheckFlag check_stack_limit) {
1168 __ movq(
rax, register_location(register_index));
1170 if (check_stack_limit) CheckStackLimit();
1174 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(
int reg) {
1175 __ movq(
rdi, register_location(reg));
1179 void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(
int reg) {
1180 __ movq(backtrack_stackpointer(), register_location(reg));
1181 __ addq(backtrack_stackpointer(), Operand(
rbp, kStackHighEnd));
1185 void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(
int by) {
1186 Label after_position;
1187 __ cmpq(
rdi, Immediate(-by * char_size()));
1189 __ movq(
rdi, Immediate(-by * char_size()));
1193 LoadCurrentCharacterUnchecked(-1, 1);
1194 __ bind(&after_position);
1198 void RegExpMacroAssemblerX64::SetRegister(
int register_index,
int to) {
1199 ASSERT(register_index >= num_saved_registers_);
1200 __ movq(register_location(register_index), Immediate(to));
1204 bool RegExpMacroAssemblerX64::Succeed() {
1205 __ jmp(&success_label_);
1210 void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(
int reg,
1212 if (cp_offset == 0) {
1213 __ movq(register_location(reg),
rdi);
1215 __ lea(
rax, Operand(
rdi, cp_offset * char_size()));
1216 __ movq(register_location(reg),
rax);
1221 void RegExpMacroAssemblerX64::ClearRegisters(
int reg_from,
int reg_to) {
1222 ASSERT(reg_from <= reg_to);
1223 __ movq(
rax, Operand(
rbp, kInputStartMinusOne));
1224 for (
int reg = reg_from; reg <= reg_to; reg++) {
1225 __ movq(register_location(reg),
rax);
1230 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(
int reg) {
1231 __ movq(
rax, backtrack_stackpointer());
1232 __ subq(
rax, Operand(
rbp, kStackHighEnd));
1233 __ movq(register_location(reg),
rax);
1239 void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
1242 static const int num_arguments = 3;
1243 __ PrepareCallCFunction(num_arguments);
1246 __ movq(
rdx, code_object_pointer());
1256 __ movq(
rsi, code_object_pointer());
1261 ExternalReference stack_check =
1262 ExternalReference::re_check_stack_guard_state(masm_.isolate());
1263 __ CallCFunction(stack_check, num_arguments);
1268 template <
typename T>
1269 static T& frame_entry(
Address re_frame,
int frame_offset) {
1270 return reinterpret_cast<T&
>(Memory::int32_at(re_frame + frame_offset));
1274 int RegExpMacroAssemblerX64::CheckStackGuardState(
Address* return_address,
1277 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
1278 ASSERT(isolate == Isolate::Current());
1279 if (isolate->stack_guard()->IsStackOverflow()) {
1280 isolate->StackOverflow();
1289 if (frame_entry<int>(re_frame, kDirectCall) == 1) {
1294 HandleScope handles(isolate);
1295 Handle<Code> code_handle(re_code);
1297 Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
1300 bool is_ascii = subject->IsAsciiRepresentationUnderneath();
1302 ASSERT(re_code->instruction_start() <= *return_address);
1303 ASSERT(*return_address <=
1304 re_code->instruction_start() + re_code->instruction_size());
1306 MaybeObject* result = Execution::HandleStackGuardInterrupt(isolate);
1308 if (*code_handle != re_code) {
1309 intptr_t delta = code_handle->address() - re_code->address();
1311 *return_address += delta;
1314 if (result->IsException()) {
1318 Handle<String> subject_tmp = subject;
1319 int slice_offset = 0;
1322 if (StringShape(*subject_tmp).IsCons()) {
1323 subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first());
1324 }
else if (StringShape(*subject_tmp).IsSliced()) {
1325 SlicedString* slice = SlicedString::cast(*subject_tmp);
1326 subject_tmp = Handle<String>(slice->parent());
1327 slice_offset = slice->offset();
1331 if (subject_tmp->IsAsciiRepresentation() != is_ascii) {
1342 ASSERT(StringShape(*subject_tmp).IsSequential() ||
1343 StringShape(*subject_tmp).IsExternal());
1346 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart);
1350 int start_index = frame_entry<int>(re_frame, kStartIndex);
1351 const byte* new_address = StringCharacterPosition(*subject_tmp,
1352 start_index + slice_offset);
1354 if (start_address != new_address) {
1357 const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd);
1358 int byte_length =
static_cast<int>(end_address - start_address);
1359 frame_entry<const String*>(re_frame, kInputString) = *subject;
1360 frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1361 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
1362 }
else if (frame_entry<const String*>(re_frame, kInputString) != *subject) {
1366 frame_entry<const String*>(re_frame, kInputString) = *subject;
1373 Operand RegExpMacroAssemblerX64::register_location(
int register_index) {
1374 ASSERT(register_index < (1<<30));
1375 if (num_registers_ <= register_index) {
1376 num_registers_ = register_index + 1;
1382 void RegExpMacroAssemblerX64::CheckPosition(
int cp_offset,
1383 Label* on_outside_input) {
1384 __ cmpl(
rdi, Immediate(-cp_offset * char_size()));
1389 void RegExpMacroAssemblerX64::BranchOrBacktrack(
Condition condition,
1391 if (condition < 0) {
1400 __ j(condition, &backtrack_label_);
1403 __ j(condition, to);
1407 void RegExpMacroAssemblerX64::SafeCall(Label* to) {
1412 void RegExpMacroAssemblerX64::SafeCallTarget(Label* label) {
1414 __ subq(Operand(
rsp, 0), code_object_pointer());
1418 void RegExpMacroAssemblerX64::SafeReturn() {
1419 __ addq(Operand(
rsp, 0), code_object_pointer());
1424 void RegExpMacroAssemblerX64::Push(Register source) {
1425 ASSERT(!source.is(backtrack_stackpointer()));
1427 __ subq(backtrack_stackpointer(), Immediate(
kIntSize));
1428 __ movl(Operand(backtrack_stackpointer(), 0), source);
1432 void RegExpMacroAssemblerX64::Push(Immediate value) {
1434 __ subq(backtrack_stackpointer(), Immediate(
kIntSize));
1435 __ movl(Operand(backtrack_stackpointer(), 0), value);
1439 void RegExpMacroAssemblerX64::FixupCodeRelativePositions() {
1440 for (
int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) {
1441 int position = code_relative_fixup_positions_[i];
1445 int patch_position = position -
kIntSize;
1446 int offset = masm_.long_at(patch_position);
1447 masm_.long_at_put(patch_position,
1453 code_relative_fixup_positions_.Clear();
1457 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) {
1458 __ subq(backtrack_stackpointer(), Immediate(kIntSize));
1459 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target);
1460 MarkPositionForCodeRelativeFixup();
1464 void RegExpMacroAssemblerX64::Pop(Register target) {
1465 ASSERT(!target.is(backtrack_stackpointer()));
1466 __ movsxlq(target, Operand(backtrack_stackpointer(), 0));
1468 __ addq(backtrack_stackpointer(), Immediate(kIntSize));
1472 void RegExpMacroAssemblerX64::Drop() {
1473 __ addq(backtrack_stackpointer(), Immediate(kIntSize));
1477 void RegExpMacroAssemblerX64::CheckPreemption() {
1480 ExternalReference stack_limit =
1481 ExternalReference::address_of_stack_limit(masm_.isolate());
1482 __ load_rax(stack_limit);
1486 SafeCall(&check_preempt_label_);
1488 __ bind(&no_preempt);
1492 void RegExpMacroAssemblerX64::CheckStackLimit() {
1493 Label no_stack_overflow;
1494 ExternalReference stack_limit =
1495 ExternalReference::address_of_regexp_stack_limit(masm_.isolate());
1496 __ load_rax(stack_limit);
1497 __ cmpq(backtrack_stackpointer(),
rax);
1498 __ j(
above, &no_stack_overflow);
1500 SafeCall(&stack_overflow_label_);
1502 __ bind(&no_stack_overflow);
1506 void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(
int cp_offset,
1508 if (mode_ == ASCII) {
1509 if (characters == 4) {
1511 }
else if (characters == 2) {
1512 __ movzxwl(current_character(), Operand(
rsi,
rdi,
times_1, cp_offset));
1515 __ movzxbl(current_character(), Operand(
rsi,
rdi,
times_1, cp_offset));
1519 if (characters == 2) {
1520 __ movl(current_character(),
1524 __ movzxwl(current_character(),
1532 #endif // V8_INTERPRETED_REGEXP
1536 #endif // V8_TARGET_ARCH_X64
v8::Handle< v8::Value > Fail(const v8::Arguments &args)
#define ASSERT(condition)
#define PROFILE(isolate, Call)
RegExpMacroAssemblerX64(Mode mode, int registers_to_save, Zone *zone)
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Operand FieldOperand(Register object, int offset)
#define T(name, string, precedence)
const Register kScratchRegister
#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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
#define STATIC_ASSERT(test)
const uc32 kMaxAsciiCharCode