21 #ifndef V8_INTERPRETED_REGEXP
94 #define __ ACCESS_MASM((&masm_))
98 int registers_to_save,
100 : NativeRegExpMacroAssembler(zone),
101 masm_(zone->isolate(),
NULL, kRegExpCodeSize),
102 no_root_array_scope_(&masm_),
103 code_relative_fixup_positions_(4, zone),
105 num_registers_(registers_to_save),
106 num_saved_registers_(registers_to_save),
113 __ jmp(&entry_label_);
114 __ bind(&start_label_);
118 RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() {
120 entry_label_.Unuse();
121 start_label_.Unuse();
122 success_label_.Unuse();
123 backtrack_label_.Unuse();
125 check_preempt_label_.Unuse();
126 stack_overflow_label_.Unuse();
130 int RegExpMacroAssemblerX64::stack_limit_slack() {
131 return RegExpStack::kStackLimitSlack;
135 void RegExpMacroAssemblerX64::AdvanceCurrentPosition(
int by) {
137 __ addq(
rdi, Immediate(by * char_size()));
142 void RegExpMacroAssemblerX64::AdvanceRegister(
int reg,
int by) {
144 DCHECK(reg < num_registers_);
146 __ addp(register_location(reg), Immediate(by));
151 void RegExpMacroAssemblerX64::Backtrack() {
155 __ addp(
rbx, code_object_pointer());
160 void RegExpMacroAssemblerX64::Bind(Label* label) {
165 void RegExpMacroAssemblerX64::CheckCharacter(
uint32_t c, Label* on_equal) {
166 __ cmpl(current_character(), Immediate(c));
167 BranchOrBacktrack(
equal, on_equal);
171 void RegExpMacroAssemblerX64::CheckCharacterGT(
uc16 limit, Label* on_greater) {
172 __ cmpl(current_character(), Immediate(limit));
173 BranchOrBacktrack(
greater, on_greater);
177 void RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) {
180 __ cmpl(Operand(
rbp, kStartIndex), Immediate(0));
181 BranchOrBacktrack(
not_equal, ¬_at_start);
184 __ cmpp(
rax, Operand(
rbp, kInputStart));
185 BranchOrBacktrack(
equal, on_at_start);
186 __ bind(¬_at_start);
190 void RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) {
192 __ cmpl(Operand(
rbp, kStartIndex), Immediate(0));
193 BranchOrBacktrack(
not_equal, on_not_at_start);
196 __ cmpp(
rax, Operand(
rbp, kInputStart));
197 BranchOrBacktrack(
not_equal, on_not_at_start);
201 void RegExpMacroAssemblerX64::CheckCharacterLT(
uc16 limit, Label* on_less) {
202 __ cmpl(current_character(), Immediate(limit));
203 BranchOrBacktrack(
less, on_less);
207 void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
209 __ cmpl(
rdi, Operand(backtrack_stackpointer(), 0));
213 __ bind(&fallthrough);
217 void RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase(
219 Label* on_no_match) {
221 ReadPositionFromRegister(
rdx, start_reg);
222 ReadPositionFromRegister(
rbx, start_reg + 1);
245 BranchOrBacktrack(
greater, on_no_match);
247 if (mode_ == LATIN1) {
248 Label loop_increment;
249 if (on_no_match ==
NULL) {
250 on_no_match = &backtrack_label_;
263 __ movzxbl(
rdx, Operand(
r9, 0));
273 __ orp(
rax, Immediate(0x20));
274 __ orp(
rdx, Immediate(0x20));
277 __ subb(
rax, Immediate(
'a'));
278 __ cmpb(
rax, Immediate(
'z' -
'a'));
281 __ subb(
rax, Immediate(224 -
'a'));
282 __ cmpb(
rax, Immediate(254 - 224));
284 __ cmpb(
rax, Immediate(247 - 224));
286 __ bind(&loop_increment);
288 __ addp(
r11, Immediate(1));
289 __ addp(
r9, Immediate(1));
305 __ pushq(backtrack_stackpointer());
307 static const int num_arguments = 4;
308 __ PrepareCallCFunction(num_arguments);
323 __ LoadAddress(
r9, ExternalReference::isolate_address(isolate()));
334 __ LoadAddress(
rcx, ExternalReference::isolate_address(isolate()));
339 AllowExternalCallThatCantCauseGC scope(&masm_);
340 ExternalReference compare =
341 ExternalReference::re_case_insensitive_compare_uc16(isolate());
342 __ CallCFunction(compare, num_arguments);
346 __ Move(code_object_pointer(), masm_.CodeObject());
347 __ popq(backtrack_stackpointer());
355 BranchOrBacktrack(
zero, on_no_match);
360 __ bind(&fallthrough);
364 void RegExpMacroAssemblerX64::CheckNotBackReference(
366 Label* on_no_match) {
370 ReadPositionFromRegister(
rdx, start_reg);
371 ReadPositionFromRegister(
rax, start_reg + 1);
389 BranchOrBacktrack(
greater, on_no_match);
403 if (mode_ == LATIN1) {
411 BranchOrBacktrack(
not_equal, on_no_match);
413 __ addp(
rbx, Immediate(char_size()));
414 __ addp(
rdx, Immediate(char_size()));
424 __ bind(&fallthrough);
428 void RegExpMacroAssemblerX64::CheckNotCharacter(
uint32_t c,
429 Label* on_not_equal) {
430 __ cmpl(current_character(), Immediate(c));
431 BranchOrBacktrack(
not_equal, on_not_equal);
435 void RegExpMacroAssemblerX64::CheckCharacterAfterAnd(
uint32_t c,
439 __ testl(current_character(), Immediate(mask));
441 __ movl(
rax, Immediate(mask));
442 __ andp(
rax, current_character());
443 __ cmpl(
rax, Immediate(c));
445 BranchOrBacktrack(
equal, on_equal);
449 void RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(
uint32_t c,
451 Label* on_not_equal) {
453 __ testl(current_character(), Immediate(mask));
455 __ movl(
rax, Immediate(mask));
456 __ andp(
rax, current_character());
457 __ cmpl(
rax, Immediate(c));
459 BranchOrBacktrack(
not_equal, on_not_equal);
463 void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd(
467 Label* on_not_equal) {
468 DCHECK(minus < String::kMaxUtf16CodeUnit);
469 __ leap(
rax, Operand(current_character(), -minus));
470 __ andp(
rax, Immediate(mask));
471 __ cmpl(
rax, Immediate(c));
472 BranchOrBacktrack(
not_equal, on_not_equal);
476 void RegExpMacroAssemblerX64::CheckCharacterInRange(
479 Label* on_in_range) {
480 __ leal(
rax, Operand(current_character(), -from));
481 __ cmpl(
rax, Immediate(
to - from));
486 void RegExpMacroAssemblerX64::CheckCharacterNotInRange(
489 Label* on_not_in_range) {
490 __ leal(
rax, Operand(current_character(), -from));
491 __ cmpl(
rax, Immediate(
to - from));
492 BranchOrBacktrack(
above, on_not_in_range);
496 void RegExpMacroAssemblerX64::CheckBitInTable(
497 Handle<ByteArray> table,
500 Register index = current_character();
501 if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
502 __ movp(
rbx, current_character());
503 __ andp(
rbx, Immediate(kTableMask));
508 BranchOrBacktrack(
not_equal, on_bit_set);
512 bool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(
uc16 type,
513 Label* on_no_match) {
521 if (mode_ == LATIN1) {
524 __ cmpl(current_character(), Immediate(
' '));
525 __ j(
equal, &success, Label::kNear);
527 __ leap(
rax, Operand(current_character(), -
'\t'));
528 __ cmpl(
rax, Immediate(
'\r' -
'\t'));
531 __ cmpl(
rax, Immediate(0x00a0 -
'\t'));
532 BranchOrBacktrack(
not_equal, on_no_match);
542 __ leap(
rax, Operand(current_character(), -
'0'));
543 __ cmpl(
rax, Immediate(
'9' -
'0'));
544 BranchOrBacktrack(
above, on_no_match);
548 __ leap(
rax, Operand(current_character(), -
'0'));
549 __ cmpl(
rax, Immediate(
'9' -
'0'));
554 __ movl(
rax, current_character());
555 __ xorp(
rax, Immediate(0x01));
557 __ subl(
rax, Immediate(0x0b));
558 __ cmpl(
rax, Immediate(0x0c - 0x0b));
564 __ subl(
rax, Immediate(0x2028 - 0x0b));
565 __ cmpl(
rax, Immediate(0x2029 - 0x2028));
572 __ movl(
rax, current_character());
573 __ xorp(
rax, Immediate(0x01));
575 __ subl(
rax, Immediate(0x0b));
576 __ cmpl(
rax, Immediate(0x0c - 0x0b));
577 if (mode_ == LATIN1) {
578 BranchOrBacktrack(
above, on_no_match);
585 __ subl(
rax, Immediate(0x2028 - 0x0b));
586 __ cmpl(
rax, Immediate(0x2029 - 0x2028));
587 BranchOrBacktrack(
above, on_no_match);
593 if (mode_ != LATIN1) {
595 __ cmpl(current_character(), Immediate(
'z'));
596 BranchOrBacktrack(
above, on_no_match);
598 __ Move(
rbx, ExternalReference::re_word_character_map());
601 current_character());
602 BranchOrBacktrack(
zero, on_no_match);
607 if (mode_ != LATIN1) {
609 __ cmpl(current_character(), Immediate(
'z'));
612 __ Move(
rbx, ExternalReference::re_word_character_map());
615 current_character());
616 BranchOrBacktrack(
not_zero, on_no_match);
617 if (mode_ != LATIN1) {
633 void RegExpMacroAssemblerX64::Fail() {
636 __ Set(
rax, FAILURE);
638 __ jmp(&exit_label_);
642 Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
647 __ bind(&entry_label_);
651 FrameScope scope(&masm_, StackFrame::MANUAL);
661 __ movq(Operand(
rbp, kInputString),
rcx);
662 __ movq(Operand(
rbp, kStartIndex),
rdx);
663 __ movq(Operand(
rbp, kInputStart),
r8);
664 __ movq(Operand(
rbp, kInputEnd),
r9);
692 Label stack_limit_hit;
695 ExternalReference stack_limit =
696 ExternalReference::address_of_stack_limit(isolate());
708 __ Set(
rax, EXCEPTION);
711 __ bind(&stack_limit_hit);
712 __ Move(code_object_pointer(), masm_.CodeObject());
713 CallCheckStackGuardState();
723 __ movp(
rsi, Operand(
rbp, kInputEnd));
725 __ movp(
rdi, Operand(
rbp, kInputStart));
730 __ movp(
rbx, Operand(
rbp, kStartIndex));
739 __ movp(Operand(
rbp, kInputStartMinusOne),
rax);
744 const int kPageSize = 4096;
746 for (
int i = num_saved_registers_ + kRegistersPerPage - 1;
748 i += kRegistersPerPage) {
749 __ movp(register_location(
i),
rax);
754 __ Move(code_object_pointer(), masm_.CodeObject());
756 Label load_char_start_regexp, start_regexp;
758 __ cmpl(Operand(
rbp, kStartIndex), Immediate(0));
759 __ j(
not_equal, &load_char_start_regexp, Label::kNear);
760 __ Set(current_character(),
'\n');
761 __ jmp(&start_regexp, Label::kNear);
764 __ bind(&load_char_start_regexp);
766 LoadCurrentCharacterUnchecked(-1, 1);
767 __ bind(&start_regexp);
770 if (num_saved_registers_ > 0) {
774 if (num_saved_registers_ > 8) {
775 __ Set(
rcx, kRegisterZero);
781 Immediate(kRegisterZero - num_saved_registers_ *
kPointerSize));
784 for (
int i = 0;
i < num_saved_registers_;
i++) {
785 __ movp(register_location(
i),
rax);
791 __ movp(backtrack_stackpointer(), Operand(
rbp, kStackHighEnd));
793 __ jmp(&start_label_);
796 if (success_label_.is_linked()) {
798 __ bind(&success_label_);
799 if (num_saved_registers_ > 0) {
801 __ movp(
rdx, Operand(
rbp, kStartIndex));
802 __ movp(
rbx, Operand(
rbp, kRegisterOutput));
803 __ movp(
rcx, Operand(
rbp, kInputEnd));
804 __ subp(
rcx, Operand(
rbp, kInputStart));
810 for (
int i = 0;
i < num_saved_registers_;
i++) {
811 __ movp(
rax, register_location(
i));
812 if (
i == 0 && global_with_zero_length_check()) {
818 __ sarp(
rax, Immediate(1));
827 __ incp(Operand(
rbp, kSuccessfulCaptures));
830 __ movsxlq(
rcx, Operand(
rbp, kNumOutputRegisters));
831 __ subp(
rcx, Immediate(num_saved_registers_));
833 __ cmpp(
rcx, Immediate(num_saved_registers_));
836 __ movp(Operand(
rbp, kNumOutputRegisters),
rcx);
838 __ addp(Operand(
rbp, kRegisterOutput),
839 Immediate(num_saved_registers_ *
kIntSize));
842 __ movp(
rax, Operand(
rbp, kInputStartMinusOne));
844 if (global_with_zero_length_check()) {
852 __ j(
zero, &exit_label_, Label::kNear);
855 __ addq(
rdi, Immediate(2));
861 __ jmp(&load_char_start_regexp);
863 __ movp(
rax, Immediate(SUCCESS));
867 __ bind(&exit_label_);
870 __ movp(
rax, Operand(
rbp, kSuccessfulCaptures));
873 __ bind(&return_rax);
876 __ leap(
rsp, Operand(
rbp, kLastCalleeSaveRegister));
883 __ movp(
rbx, Operand(
rbp, kBackup_rbx));
892 if (backtrack_label_.is_linked()) {
893 __ bind(&backtrack_label_);
897 Label exit_with_exception;
900 if (check_preempt_label_.is_linked()) {
901 SafeCallTarget(&check_preempt_label_);
903 __ pushq(backtrack_stackpointer());
906 CallCheckStackGuardState();
913 __ Move(code_object_pointer(), masm_.CodeObject());
915 __ popq(backtrack_stackpointer());
917 __ movp(
rsi, Operand(
rbp, kInputEnd));
922 if (stack_overflow_label_.is_linked()) {
923 SafeCallTarget(&stack_overflow_label_);
935 static const int num_arguments = 3;
936 __ PrepareCallCFunction(num_arguments);
940 __ leap(
rdx, Operand(
rbp, kStackHighEnd));
941 __ LoadAddress(
r8, ExternalReference::isolate_address(isolate()));
944 __ movp(
rdi, backtrack_stackpointer());
945 __ leap(
rsi, Operand(
rbp, kStackHighEnd));
946 __ LoadAddress(
rdx, ExternalReference::isolate_address(isolate()));
948 ExternalReference grow_stack =
949 ExternalReference::re_grow_stack(isolate());
950 __ CallCFunction(grow_stack, num_arguments);
954 __ j(
equal, &exit_with_exception);
956 __ movp(backtrack_stackpointer(),
rax);
958 __ Move(code_object_pointer(), masm_.CodeObject());
966 if (exit_with_exception.is_linked()) {
968 __ bind(&exit_with_exception);
970 __ Set(
rax, EXCEPTION);
974 FixupCodeRelativePositions();
977 masm_.GetCode(&code_desc);
978 Isolate* isolate = this->isolate();
979 Handle<Code> code = isolate->factory()->NewCode(
980 code_desc, Code::ComputeFlags(Code::REGEXP),
982 PROFILE(isolate, RegExpCodeCreateEvent(*code, *source));
983 return Handle<HeapObject>::cast(code);
987 void RegExpMacroAssemblerX64::GoTo(Label*
to) {
992 void RegExpMacroAssemblerX64::IfRegisterGE(
int reg,
995 __ cmpp(register_location(reg), Immediate(comparand));
1000 void RegExpMacroAssemblerX64::IfRegisterLT(
int reg,
1003 __ cmpp(register_location(reg), Immediate(comparand));
1004 BranchOrBacktrack(
less, if_lt);
1008 void RegExpMacroAssemblerX64::IfRegisterEqPos(
int reg,
1010 __ cmpp(
rdi, register_location(reg));
1011 BranchOrBacktrack(
equal, if_eq);
1015 RegExpMacroAssembler::IrregexpImplementation
1016 RegExpMacroAssemblerX64::Implementation() {
1017 return kX64Implementation;
1021 void RegExpMacroAssemblerX64::LoadCurrentCharacter(
int cp_offset,
1022 Label* on_end_of_input,
1026 DCHECK(cp_offset < (1<<30));
1028 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1030 LoadCurrentCharacterUnchecked(cp_offset, characters);
1034 void RegExpMacroAssemblerX64::PopCurrentPosition() {
1039 void RegExpMacroAssemblerX64::PopRegister(
int register_index) {
1041 __ movp(register_location(register_index),
rax);
1045 void RegExpMacroAssemblerX64::PushBacktrack(Label* label) {
1051 void RegExpMacroAssemblerX64::PushCurrentPosition() {
1056 void RegExpMacroAssemblerX64::PushRegister(
int register_index,
1057 StackCheckFlag check_stack_limit) {
1058 __ movp(
rax, register_location(register_index));
1060 if (check_stack_limit) CheckStackLimit();
1067 void RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(
int reg) {
1069 __ movq(
rdi, register_location(reg));
1072 __ movsxlq(
rdi, register_location(reg));
1077 void RegExpMacroAssemblerX64::ReadPositionFromRegister(Register dst,
int reg) {
1079 __ movq(dst, register_location(reg));
1082 __ movsxlq(dst, register_location(reg));
1087 void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(
int reg) {
1088 __ movp(backtrack_stackpointer(), register_location(reg));
1089 __ addp(backtrack_stackpointer(), Operand(
rbp, kStackHighEnd));
1093 void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(
int by) {
1094 Label after_position;
1095 __ cmpp(
rdi, Immediate(-by * char_size()));
1097 __ movq(
rdi, Immediate(-by * char_size()));
1101 LoadCurrentCharacterUnchecked(-1, 1);
1102 __ bind(&after_position);
1106 void RegExpMacroAssemblerX64::SetRegister(
int register_index,
int to) {
1107 DCHECK(register_index >= num_saved_registers_);
1108 __ movp(register_location(register_index), Immediate(
to));
1112 bool RegExpMacroAssemblerX64::Succeed() {
1113 __ jmp(&success_label_);
1118 void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(
int reg,
1120 if (cp_offset == 0) {
1121 __ movp(register_location(reg),
rdi);
1123 __ leap(
rax, Operand(
rdi, cp_offset * char_size()));
1124 __ movp(register_location(reg),
rax);
1129 void RegExpMacroAssemblerX64::ClearRegisters(
int reg_from,
int reg_to) {
1130 DCHECK(reg_from <= reg_to);
1131 __ movp(
rax, Operand(
rbp, kInputStartMinusOne));
1132 for (
int reg = reg_from; reg <= reg_to; reg++) {
1133 __ movp(register_location(reg),
rax);
1138 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(
int reg) {
1139 __ movp(
rax, backtrack_stackpointer());
1140 __ subp(
rax, Operand(
rbp, kStackHighEnd));
1141 __ movp(register_location(reg),
rax);
1147 void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
1150 static const int num_arguments = 3;
1151 __ PrepareCallCFunction(num_arguments);
1154 __ movp(
rdx, code_object_pointer());
1164 __ movp(
rsi, code_object_pointer());
1169 ExternalReference stack_check =
1170 ExternalReference::re_check_stack_guard_state(isolate());
1171 __ CallCFunction(stack_check, num_arguments);
1176 template <
typename T>
1177 static T& frame_entry(
Address re_frame,
int frame_offset) {
1178 return reinterpret_cast<T&
>(Memory::int32_at(re_frame + frame_offset));
1182 int RegExpMacroAssemblerX64::CheckStackGuardState(
Address* return_address,
1185 Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
1186 StackLimitCheck check(isolate);
1187 if (check.JsHasOverflowed()) {
1188 isolate->StackOverflow();
1197 if (frame_entry<int>(re_frame, kDirectCall) == 1) {
1202 HandleScope handles(isolate);
1203 Handle<Code> code_handle(re_code);
1205 Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
1208 bool is_one_byte = subject->IsOneByteRepresentationUnderneath();
1210 DCHECK(re_code->instruction_start() <= *return_address);
1211 DCHECK(*return_address <=
1212 re_code->instruction_start() + re_code->instruction_size());
1214 Object* result = isolate->stack_guard()->HandleInterrupts();
1216 if (*code_handle != re_code) {
1217 intptr_t delta = code_handle->address() - re_code->address();
1219 *return_address += delta;
1222 if (result->IsException()) {
1226 Handle<String> subject_tmp = subject;
1227 int slice_offset = 0;
1230 if (StringShape(*subject_tmp).IsCons()) {
1231 subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first());
1232 }
else if (StringShape(*subject_tmp).IsSliced()) {
1233 SlicedString* slice = SlicedString::cast(*subject_tmp);
1234 subject_tmp = Handle<String>(slice->parent());
1235 slice_offset = slice->offset();
1239 if (subject_tmp->IsOneByteRepresentation() != is_one_byte) {
1250 DCHECK(StringShape(*subject_tmp).IsSequential() ||
1251 StringShape(*subject_tmp).IsExternal());
1254 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart);
1258 int start_index = frame_entry<int>(re_frame, kStartIndex);
1259 const byte* new_address = StringCharacterPosition(*subject_tmp,
1260 start_index + slice_offset);
1262 if (start_address != new_address) {
1265 const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd);
1266 int byte_length =
static_cast<int>(end_address - start_address);
1267 frame_entry<const String*>(re_frame, kInputString) = *subject;
1268 frame_entry<const byte*>(re_frame, kInputStart) = new_address;
1269 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
1270 }
else if (frame_entry<const String*>(re_frame, kInputString) != *subject) {
1274 frame_entry<const String*>(re_frame, kInputString) = *subject;
1281 Operand RegExpMacroAssemblerX64::register_location(
int register_index) {
1282 DCHECK(register_index < (1<<30));
1283 if (num_registers_ <= register_index) {
1284 num_registers_ = register_index + 1;
1290 void RegExpMacroAssemblerX64::CheckPosition(
int cp_offset,
1291 Label* on_outside_input) {
1292 __ cmpl(
rdi, Immediate(-cp_offset * char_size()));
1297 void RegExpMacroAssemblerX64::BranchOrBacktrack(
Condition condition,
1299 if (condition < 0) {
1308 __ j(condition, &backtrack_label_);
1311 __ j(condition,
to);
1315 void RegExpMacroAssemblerX64::SafeCall(Label*
to) {
1320 void RegExpMacroAssemblerX64::SafeCallTarget(Label* label) {
1322 __ subp(Operand(
rsp, 0), code_object_pointer());
1326 void RegExpMacroAssemblerX64::SafeReturn() {
1327 __ addp(Operand(
rsp, 0), code_object_pointer());
1333 DCHECK(!source.is(backtrack_stackpointer()));
1335 __ subp(backtrack_stackpointer(), Immediate(
kIntSize));
1336 __ movl(Operand(backtrack_stackpointer(), 0), source);
1342 __ subp(backtrack_stackpointer(), Immediate(
kIntSize));
1343 __ movl(Operand(backtrack_stackpointer(), 0), value);
1347 void RegExpMacroAssemblerX64::FixupCodeRelativePositions() {
1348 for (
int i = 0, n = code_relative_fixup_positions_.length();
i < n;
i++) {
1349 int position = code_relative_fixup_positions_[
i];
1353 int patch_position = position -
kIntSize;
1354 int offset = masm_.long_at(patch_position);
1355 masm_.long_at_put(patch_position,
1361 code_relative_fixup_positions_.Clear();
1366 __ subp(backtrack_stackpointer(), Immediate(
kIntSize));
1367 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target);
1368 MarkPositionForCodeRelativeFixup();
1372 void RegExpMacroAssemblerX64::Pop(Register target) {
1373 DCHECK(!target.is(backtrack_stackpointer()));
1374 __ movsxlq(target, Operand(backtrack_stackpointer(), 0));
1376 __ addp(backtrack_stackpointer(), Immediate(
kIntSize));
1380 void RegExpMacroAssemblerX64::Drop() {
1381 __ addp(backtrack_stackpointer(), Immediate(
kIntSize));
1385 void RegExpMacroAssemblerX64::CheckPreemption() {
1388 ExternalReference stack_limit =
1389 ExternalReference::address_of_stack_limit(isolate());
1390 __ load_rax(stack_limit);
1394 SafeCall(&check_preempt_label_);
1396 __ bind(&no_preempt);
1400 void RegExpMacroAssemblerX64::CheckStackLimit() {
1401 Label no_stack_overflow;
1402 ExternalReference stack_limit =
1403 ExternalReference::address_of_regexp_stack_limit(isolate());
1404 __ load_rax(stack_limit);
1405 __ cmpp(backtrack_stackpointer(),
rax);
1406 __ j(
above, &no_stack_overflow);
1408 SafeCall(&stack_overflow_label_);
1410 __ bind(&no_stack_overflow);
1414 void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(
int cp_offset,
1416 if (mode_ == LATIN1) {
1417 if (characters == 4) {
1419 }
else if (characters == 2) {
1420 __ movzxwl(current_character(), Operand(
rsi,
rdi,
times_1, cp_offset));
1423 __ movzxbl(current_character(), Operand(
rsi,
rdi,
times_1, cp_offset));
1427 if (characters == 2) {
1428 __ movl(current_character(),
1432 __ movzxwl(current_character(),
RegExpMacroAssemblerX64(Mode mode, int registers_to_save, Zone *zone)
#define PROFILE(IsolateGetter, Call)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes to(mksnapshot only)") DEFINE_STRING(raw_context_file
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define STATIC_ASSERT(test)
static int Push(SpecialRPOStackFrame *stack, int depth, BasicBlock *child, int unvisited)
const Register kScratchRegister
Operand FieldOperand(Register object, int offset)
kSerializedDataOffset Object
Debugger support for the V8 JavaScript engine.
#define T(name, string, precedence)
Definitions and convenience functions for working with unicode.