OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/cpu-profiler.h" | 9 #include "src/cpu-profiler.h" |
10 #include "src/log.h" | 10 #include "src/log.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 no_root_array_scope_(&masm_), | 102 no_root_array_scope_(&masm_), |
103 code_relative_fixup_positions_(4, zone), | 103 code_relative_fixup_positions_(4, zone), |
104 mode_(mode), | 104 mode_(mode), |
105 num_registers_(registers_to_save), | 105 num_registers_(registers_to_save), |
106 num_saved_registers_(registers_to_save), | 106 num_saved_registers_(registers_to_save), |
107 entry_label_(), | 107 entry_label_(), |
108 start_label_(), | 108 start_label_(), |
109 success_label_(), | 109 success_label_(), |
110 backtrack_label_(), | 110 backtrack_label_(), |
111 exit_label_() { | 111 exit_label_() { |
112 ASSERT_EQ(0, registers_to_save % 2); | 112 DCHECK_EQ(0, registers_to_save % 2); |
113 __ jmp(&entry_label_); // We'll write the entry code when we know more. | 113 __ jmp(&entry_label_); // We'll write the entry code when we know more. |
114 __ bind(&start_label_); // And then continue from here. | 114 __ bind(&start_label_); // And then continue from here. |
115 } | 115 } |
116 | 116 |
117 | 117 |
118 RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() { | 118 RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() { |
119 // Unuse labels in case we throw away the assembler without calling GetCode. | 119 // Unuse labels in case we throw away the assembler without calling GetCode. |
120 entry_label_.Unuse(); | 120 entry_label_.Unuse(); |
121 start_label_.Unuse(); | 121 start_label_.Unuse(); |
122 success_label_.Unuse(); | 122 success_label_.Unuse(); |
(...skipping 10 matching lines...) Expand all Loading... |
133 | 133 |
134 | 134 |
135 void RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) { | 135 void RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) { |
136 if (by != 0) { | 136 if (by != 0) { |
137 __ addq(rdi, Immediate(by * char_size())); | 137 __ addq(rdi, Immediate(by * char_size())); |
138 } | 138 } |
139 } | 139 } |
140 | 140 |
141 | 141 |
142 void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) { | 142 void RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) { |
143 ASSERT(reg >= 0); | 143 DCHECK(reg >= 0); |
144 ASSERT(reg < num_registers_); | 144 DCHECK(reg < num_registers_); |
145 if (by != 0) { | 145 if (by != 0) { |
146 __ addp(register_location(reg), Immediate(by)); | 146 __ addp(register_location(reg), Immediate(by)); |
147 } | 147 } |
148 } | 148 } |
149 | 149 |
150 | 150 |
151 void RegExpMacroAssemblerX64::Backtrack() { | 151 void RegExpMacroAssemblerX64::Backtrack() { |
152 CheckPreemption(); | 152 CheckPreemption(); |
153 // Pop Code* offset from backtrack stack, add Code* and jump to location. | 153 // Pop Code* offset from backtrack stack, add Code* and jump to location. |
154 Pop(rbx); | 154 Pop(rbx); |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 __ addp(r11, Immediate(1)); | 288 __ addp(r11, Immediate(1)); |
289 __ addp(r9, Immediate(1)); | 289 __ addp(r9, Immediate(1)); |
290 // Compare to end of capture, and loop if not done. | 290 // Compare to end of capture, and loop if not done. |
291 __ cmpp(r9, rbx); | 291 __ cmpp(r9, rbx); |
292 __ j(below, &loop); | 292 __ j(below, &loop); |
293 | 293 |
294 // Compute new value of character position after the matched part. | 294 // Compute new value of character position after the matched part. |
295 __ movp(rdi, r11); | 295 __ movp(rdi, r11); |
296 __ subq(rdi, rsi); | 296 __ subq(rdi, rsi); |
297 } else { | 297 } else { |
298 ASSERT(mode_ == UC16); | 298 DCHECK(mode_ == UC16); |
299 // Save important/volatile registers before calling C function. | 299 // Save important/volatile registers before calling C function. |
300 #ifndef _WIN64 | 300 #ifndef _WIN64 |
301 // Caller save on Linux and callee save in Windows. | 301 // Caller save on Linux and callee save in Windows. |
302 __ pushq(rsi); | 302 __ pushq(rsi); |
303 __ pushq(rdi); | 303 __ pushq(rdi); |
304 #endif | 304 #endif |
305 __ pushq(backtrack_stackpointer()); | 305 __ pushq(backtrack_stackpointer()); |
306 | 306 |
307 static const int num_arguments = 4; | 307 static const int num_arguments = 4; |
308 __ PrepareCallCFunction(num_arguments); | 308 __ PrepareCallCFunction(num_arguments); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 // rbx - current capture character address. | 397 // rbx - current capture character address. |
398 // rbx - current input character address . | 398 // rbx - current input character address . |
399 // r9 - end of input to match (capture length after rbx). | 399 // r9 - end of input to match (capture length after rbx). |
400 | 400 |
401 Label loop; | 401 Label loop; |
402 __ bind(&loop); | 402 __ bind(&loop); |
403 if (mode_ == ASCII) { | 403 if (mode_ == ASCII) { |
404 __ movzxbl(rax, Operand(rdx, 0)); | 404 __ movzxbl(rax, Operand(rdx, 0)); |
405 __ cmpb(rax, Operand(rbx, 0)); | 405 __ cmpb(rax, Operand(rbx, 0)); |
406 } else { | 406 } else { |
407 ASSERT(mode_ == UC16); | 407 DCHECK(mode_ == UC16); |
408 __ movzxwl(rax, Operand(rdx, 0)); | 408 __ movzxwl(rax, Operand(rdx, 0)); |
409 __ cmpw(rax, Operand(rbx, 0)); | 409 __ cmpw(rax, Operand(rbx, 0)); |
410 } | 410 } |
411 BranchOrBacktrack(not_equal, on_no_match); | 411 BranchOrBacktrack(not_equal, on_no_match); |
412 // Increment pointers into capture and match string. | 412 // Increment pointers into capture and match string. |
413 __ addp(rbx, Immediate(char_size())); | 413 __ addp(rbx, Immediate(char_size())); |
414 __ addp(rdx, Immediate(char_size())); | 414 __ addp(rdx, Immediate(char_size())); |
415 // Check if we have reached end of match area. | 415 // Check if we have reached end of match area. |
416 __ cmpp(rdx, r9); | 416 __ cmpp(rdx, r9); |
417 __ j(below, &loop); | 417 __ j(below, &loop); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 } | 458 } |
459 BranchOrBacktrack(not_equal, on_not_equal); | 459 BranchOrBacktrack(not_equal, on_not_equal); |
460 } | 460 } |
461 | 461 |
462 | 462 |
463 void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd( | 463 void RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd( |
464 uc16 c, | 464 uc16 c, |
465 uc16 minus, | 465 uc16 minus, |
466 uc16 mask, | 466 uc16 mask, |
467 Label* on_not_equal) { | 467 Label* on_not_equal) { |
468 ASSERT(minus < String::kMaxUtf16CodeUnit); | 468 DCHECK(minus < String::kMaxUtf16CodeUnit); |
469 __ leap(rax, Operand(current_character(), -minus)); | 469 __ leap(rax, Operand(current_character(), -minus)); |
470 __ andp(rax, Immediate(mask)); | 470 __ andp(rax, Immediate(mask)); |
471 __ cmpl(rax, Immediate(c)); | 471 __ cmpl(rax, Immediate(c)); |
472 BranchOrBacktrack(not_equal, on_not_equal); | 472 BranchOrBacktrack(not_equal, on_not_equal); |
473 } | 473 } |
474 | 474 |
475 | 475 |
476 void RegExpMacroAssemblerX64::CheckCharacterInRange( | 476 void RegExpMacroAssemblerX64::CheckCharacterInRange( |
477 uc16 from, | 477 uc16 from, |
478 uc16 to, | 478 uc16 to, |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 } | 589 } |
590 return true; | 590 return true; |
591 } | 591 } |
592 case 'w': { | 592 case 'w': { |
593 if (mode_ != ASCII) { | 593 if (mode_ != ASCII) { |
594 // Table is 128 entries, so all ASCII characters can be tested. | 594 // Table is 128 entries, so all ASCII characters can be tested. |
595 __ cmpl(current_character(), Immediate('z')); | 595 __ cmpl(current_character(), Immediate('z')); |
596 BranchOrBacktrack(above, on_no_match); | 596 BranchOrBacktrack(above, on_no_match); |
597 } | 597 } |
598 __ Move(rbx, ExternalReference::re_word_character_map()); | 598 __ Move(rbx, ExternalReference::re_word_character_map()); |
599 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. | 599 DCHECK_EQ(0, word_character_map[0]); // Character '\0' is not a word char. |
600 __ testb(Operand(rbx, current_character(), times_1, 0), | 600 __ testb(Operand(rbx, current_character(), times_1, 0), |
601 current_character()); | 601 current_character()); |
602 BranchOrBacktrack(zero, on_no_match); | 602 BranchOrBacktrack(zero, on_no_match); |
603 return true; | 603 return true; |
604 } | 604 } |
605 case 'W': { | 605 case 'W': { |
606 Label done; | 606 Label done; |
607 if (mode_ != ASCII) { | 607 if (mode_ != ASCII) { |
608 // Table is 128 entries, so all ASCII characters can be tested. | 608 // Table is 128 entries, so all ASCII characters can be tested. |
609 __ cmpl(current_character(), Immediate('z')); | 609 __ cmpl(current_character(), Immediate('z')); |
610 __ j(above, &done); | 610 __ j(above, &done); |
611 } | 611 } |
612 __ Move(rbx, ExternalReference::re_word_character_map()); | 612 __ Move(rbx, ExternalReference::re_word_character_map()); |
613 ASSERT_EQ(0, word_character_map[0]); // Character '\0' is not a word char. | 613 DCHECK_EQ(0, word_character_map[0]); // Character '\0' is not a word char. |
614 __ testb(Operand(rbx, current_character(), times_1, 0), | 614 __ testb(Operand(rbx, current_character(), times_1, 0), |
615 current_character()); | 615 current_character()); |
616 BranchOrBacktrack(not_zero, on_no_match); | 616 BranchOrBacktrack(not_zero, on_no_match); |
617 if (mode_ != ASCII) { | 617 if (mode_ != ASCII) { |
618 __ bind(&done); | 618 __ bind(&done); |
619 } | 619 } |
620 return true; | 620 return true; |
621 } | 621 } |
622 | 622 |
623 case '*': | 623 case '*': |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 __ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx. | 662 __ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx. |
663 __ movq(Operand(rbp, kInputStart), r8); | 663 __ movq(Operand(rbp, kInputStart), r8); |
664 __ movq(Operand(rbp, kInputEnd), r9); | 664 __ movq(Operand(rbp, kInputEnd), r9); |
665 // Callee-save on Win64. | 665 // Callee-save on Win64. |
666 __ pushq(rsi); | 666 __ pushq(rsi); |
667 __ pushq(rdi); | 667 __ pushq(rdi); |
668 __ pushq(rbx); | 668 __ pushq(rbx); |
669 #else | 669 #else |
670 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack). | 670 // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack). |
671 // Push register parameters on stack for reference. | 671 // Push register parameters on stack for reference. |
672 ASSERT_EQ(kInputString, -1 * kRegisterSize); | 672 DCHECK_EQ(kInputString, -1 * kRegisterSize); |
673 ASSERT_EQ(kStartIndex, -2 * kRegisterSize); | 673 DCHECK_EQ(kStartIndex, -2 * kRegisterSize); |
674 ASSERT_EQ(kInputStart, -3 * kRegisterSize); | 674 DCHECK_EQ(kInputStart, -3 * kRegisterSize); |
675 ASSERT_EQ(kInputEnd, -4 * kRegisterSize); | 675 DCHECK_EQ(kInputEnd, -4 * kRegisterSize); |
676 ASSERT_EQ(kRegisterOutput, -5 * kRegisterSize); | 676 DCHECK_EQ(kRegisterOutput, -5 * kRegisterSize); |
677 ASSERT_EQ(kNumOutputRegisters, -6 * kRegisterSize); | 677 DCHECK_EQ(kNumOutputRegisters, -6 * kRegisterSize); |
678 __ pushq(rdi); | 678 __ pushq(rdi); |
679 __ pushq(rsi); | 679 __ pushq(rsi); |
680 __ pushq(rdx); | 680 __ pushq(rdx); |
681 __ pushq(rcx); | 681 __ pushq(rcx); |
682 __ pushq(r8); | 682 __ pushq(r8); |
683 __ pushq(r9); | 683 __ pushq(r9); |
684 | 684 |
685 __ pushq(rbx); // Callee-save | 685 __ pushq(rbx); // Callee-save |
686 #endif | 686 #endif |
687 | 687 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 RegExpMacroAssembler::IrregexpImplementation | 1015 RegExpMacroAssembler::IrregexpImplementation |
1016 RegExpMacroAssemblerX64::Implementation() { | 1016 RegExpMacroAssemblerX64::Implementation() { |
1017 return kX64Implementation; | 1017 return kX64Implementation; |
1018 } | 1018 } |
1019 | 1019 |
1020 | 1020 |
1021 void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset, | 1021 void RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset, |
1022 Label* on_end_of_input, | 1022 Label* on_end_of_input, |
1023 bool check_bounds, | 1023 bool check_bounds, |
1024 int characters) { | 1024 int characters) { |
1025 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. | 1025 DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. |
1026 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) | 1026 DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) |
1027 if (check_bounds) { | 1027 if (check_bounds) { |
1028 CheckPosition(cp_offset + characters - 1, on_end_of_input); | 1028 CheckPosition(cp_offset + characters - 1, on_end_of_input); |
1029 } | 1029 } |
1030 LoadCurrentCharacterUnchecked(cp_offset, characters); | 1030 LoadCurrentCharacterUnchecked(cp_offset, characters); |
1031 } | 1031 } |
1032 | 1032 |
1033 | 1033 |
1034 void RegExpMacroAssemblerX64::PopCurrentPosition() { | 1034 void RegExpMacroAssemblerX64::PopCurrentPosition() { |
1035 Pop(rdi); | 1035 Pop(rdi); |
1036 } | 1036 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 __ movq(rdi, Immediate(-by * char_size())); | 1097 __ movq(rdi, Immediate(-by * char_size())); |
1098 // On RegExp code entry (where this operation is used), the character before | 1098 // On RegExp code entry (where this operation is used), the character before |
1099 // the current position is expected to be already loaded. | 1099 // the current position is expected to be already loaded. |
1100 // We have advanced the position, so it's safe to read backwards. | 1100 // We have advanced the position, so it's safe to read backwards. |
1101 LoadCurrentCharacterUnchecked(-1, 1); | 1101 LoadCurrentCharacterUnchecked(-1, 1); |
1102 __ bind(&after_position); | 1102 __ bind(&after_position); |
1103 } | 1103 } |
1104 | 1104 |
1105 | 1105 |
1106 void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) { | 1106 void RegExpMacroAssemblerX64::SetRegister(int register_index, int to) { |
1107 ASSERT(register_index >= num_saved_registers_); // Reserved for positions! | 1107 DCHECK(register_index >= num_saved_registers_); // Reserved for positions! |
1108 __ movp(register_location(register_index), Immediate(to)); | 1108 __ movp(register_location(register_index), Immediate(to)); |
1109 } | 1109 } |
1110 | 1110 |
1111 | 1111 |
1112 bool RegExpMacroAssemblerX64::Succeed() { | 1112 bool RegExpMacroAssemblerX64::Succeed() { |
1113 __ jmp(&success_label_); | 1113 __ jmp(&success_label_); |
1114 return global(); | 1114 return global(); |
1115 } | 1115 } |
1116 | 1116 |
1117 | 1117 |
1118 void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg, | 1118 void RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg, |
1119 int cp_offset) { | 1119 int cp_offset) { |
1120 if (cp_offset == 0) { | 1120 if (cp_offset == 0) { |
1121 __ movp(register_location(reg), rdi); | 1121 __ movp(register_location(reg), rdi); |
1122 } else { | 1122 } else { |
1123 __ leap(rax, Operand(rdi, cp_offset * char_size())); | 1123 __ leap(rax, Operand(rdi, cp_offset * char_size())); |
1124 __ movp(register_location(reg), rax); | 1124 __ movp(register_location(reg), rax); |
1125 } | 1125 } |
1126 } | 1126 } |
1127 | 1127 |
1128 | 1128 |
1129 void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) { | 1129 void RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) { |
1130 ASSERT(reg_from <= reg_to); | 1130 DCHECK(reg_from <= reg_to); |
1131 __ movp(rax, Operand(rbp, kInputStartMinusOne)); | 1131 __ movp(rax, Operand(rbp, kInputStartMinusOne)); |
1132 for (int reg = reg_from; reg <= reg_to; reg++) { | 1132 for (int reg = reg_from; reg <= reg_to; reg++) { |
1133 __ movp(register_location(reg), rax); | 1133 __ movp(register_location(reg), rax); |
1134 } | 1134 } |
1135 } | 1135 } |
1136 | 1136 |
1137 | 1137 |
1138 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { | 1138 void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { |
1139 __ movp(rax, backtrack_stackpointer()); | 1139 __ movp(rax, backtrack_stackpointer()); |
1140 __ subp(rax, Operand(rbp, kStackHighEnd)); | 1140 __ subp(rax, Operand(rbp, kStackHighEnd)); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1200 | 1200 |
1201 // Prepare for possible GC. | 1201 // Prepare for possible GC. |
1202 HandleScope handles(isolate); | 1202 HandleScope handles(isolate); |
1203 Handle<Code> code_handle(re_code); | 1203 Handle<Code> code_handle(re_code); |
1204 | 1204 |
1205 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); | 1205 Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); |
1206 | 1206 |
1207 // Current string. | 1207 // Current string. |
1208 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); | 1208 bool is_ascii = subject->IsOneByteRepresentationUnderneath(); |
1209 | 1209 |
1210 ASSERT(re_code->instruction_start() <= *return_address); | 1210 DCHECK(re_code->instruction_start() <= *return_address); |
1211 ASSERT(*return_address <= | 1211 DCHECK(*return_address <= |
1212 re_code->instruction_start() + re_code->instruction_size()); | 1212 re_code->instruction_start() + re_code->instruction_size()); |
1213 | 1213 |
1214 Object* result = isolate->stack_guard()->HandleInterrupts(); | 1214 Object* result = isolate->stack_guard()->HandleInterrupts(); |
1215 | 1215 |
1216 if (*code_handle != re_code) { // Return address no longer valid | 1216 if (*code_handle != re_code) { // Return address no longer valid |
1217 intptr_t delta = code_handle->address() - re_code->address(); | 1217 intptr_t delta = code_handle->address() - re_code->address(); |
1218 // Overwrite the return address on the stack. | 1218 // Overwrite the return address on the stack. |
1219 *return_address += delta; | 1219 *return_address += delta; |
1220 } | 1220 } |
1221 | 1221 |
(...skipping 18 matching lines...) Expand all Loading... |
1240 // If we changed between an ASCII and an UC16 string, the specialized | 1240 // If we changed between an ASCII and an UC16 string, the specialized |
1241 // code cannot be used, and we need to restart regexp matching from | 1241 // code cannot be used, and we need to restart regexp matching from |
1242 // scratch (including, potentially, compiling a new version of the code). | 1242 // scratch (including, potentially, compiling a new version of the code). |
1243 return RETRY; | 1243 return RETRY; |
1244 } | 1244 } |
1245 | 1245 |
1246 // Otherwise, the content of the string might have moved. It must still | 1246 // Otherwise, the content of the string might have moved. It must still |
1247 // be a sequential or external string with the same content. | 1247 // be a sequential or external string with the same content. |
1248 // Update the start and end pointers in the stack frame to the current | 1248 // Update the start and end pointers in the stack frame to the current |
1249 // location (whether it has actually moved or not). | 1249 // location (whether it has actually moved or not). |
1250 ASSERT(StringShape(*subject_tmp).IsSequential() || | 1250 DCHECK(StringShape(*subject_tmp).IsSequential() || |
1251 StringShape(*subject_tmp).IsExternal()); | 1251 StringShape(*subject_tmp).IsExternal()); |
1252 | 1252 |
1253 // The original start address of the characters to match. | 1253 // The original start address of the characters to match. |
1254 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); | 1254 const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); |
1255 | 1255 |
1256 // Find the current start address of the same character at the current string | 1256 // Find the current start address of the same character at the current string |
1257 // position. | 1257 // position. |
1258 int start_index = frame_entry<int>(re_frame, kStartIndex); | 1258 int start_index = frame_entry<int>(re_frame, kStartIndex); |
1259 const byte* new_address = StringCharacterPosition(*subject_tmp, | 1259 const byte* new_address = StringCharacterPosition(*subject_tmp, |
1260 start_index + slice_offset); | 1260 start_index + slice_offset); |
(...skipping 11 matching lines...) Expand all Loading... |
1272 // short-circuiting during GC. That will not change start_address but | 1272 // short-circuiting during GC. That will not change start_address but |
1273 // will change pointer inside the subject handle. | 1273 // will change pointer inside the subject handle. |
1274 frame_entry<const String*>(re_frame, kInputString) = *subject; | 1274 frame_entry<const String*>(re_frame, kInputString) = *subject; |
1275 } | 1275 } |
1276 | 1276 |
1277 return 0; | 1277 return 0; |
1278 } | 1278 } |
1279 | 1279 |
1280 | 1280 |
1281 Operand RegExpMacroAssemblerX64::register_location(int register_index) { | 1281 Operand RegExpMacroAssemblerX64::register_location(int register_index) { |
1282 ASSERT(register_index < (1<<30)); | 1282 DCHECK(register_index < (1<<30)); |
1283 if (num_registers_ <= register_index) { | 1283 if (num_registers_ <= register_index) { |
1284 num_registers_ = register_index + 1; | 1284 num_registers_ = register_index + 1; |
1285 } | 1285 } |
1286 return Operand(rbp, kRegisterZero - register_index * kPointerSize); | 1286 return Operand(rbp, kRegisterZero - register_index * kPointerSize); |
1287 } | 1287 } |
1288 | 1288 |
1289 | 1289 |
1290 void RegExpMacroAssemblerX64::CheckPosition(int cp_offset, | 1290 void RegExpMacroAssemblerX64::CheckPosition(int cp_offset, |
1291 Label* on_outside_input) { | 1291 Label* on_outside_input) { |
1292 __ cmpl(rdi, Immediate(-cp_offset * char_size())); | 1292 __ cmpl(rdi, Immediate(-cp_offset * char_size())); |
(...skipping 30 matching lines...) Expand all Loading... |
1323 } | 1323 } |
1324 | 1324 |
1325 | 1325 |
1326 void RegExpMacroAssemblerX64::SafeReturn() { | 1326 void RegExpMacroAssemblerX64::SafeReturn() { |
1327 __ addp(Operand(rsp, 0), code_object_pointer()); | 1327 __ addp(Operand(rsp, 0), code_object_pointer()); |
1328 __ ret(0); | 1328 __ ret(0); |
1329 } | 1329 } |
1330 | 1330 |
1331 | 1331 |
1332 void RegExpMacroAssemblerX64::Push(Register source) { | 1332 void RegExpMacroAssemblerX64::Push(Register source) { |
1333 ASSERT(!source.is(backtrack_stackpointer())); | 1333 DCHECK(!source.is(backtrack_stackpointer())); |
1334 // Notice: This updates flags, unlike normal Push. | 1334 // Notice: This updates flags, unlike normal Push. |
1335 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); | 1335 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); |
1336 __ movl(Operand(backtrack_stackpointer(), 0), source); | 1336 __ movl(Operand(backtrack_stackpointer(), 0), source); |
1337 } | 1337 } |
1338 | 1338 |
1339 | 1339 |
1340 void RegExpMacroAssemblerX64::Push(Immediate value) { | 1340 void RegExpMacroAssemblerX64::Push(Immediate value) { |
1341 // Notice: This updates flags, unlike normal Push. | 1341 // Notice: This updates flags, unlike normal Push. |
1342 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); | 1342 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); |
1343 __ movl(Operand(backtrack_stackpointer(), 0), value); | 1343 __ movl(Operand(backtrack_stackpointer(), 0), value); |
(...skipping 19 matching lines...) Expand all Loading... |
1363 | 1363 |
1364 | 1364 |
1365 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) { | 1365 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) { |
1366 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); | 1366 __ subp(backtrack_stackpointer(), Immediate(kIntSize)); |
1367 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target); | 1367 __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target); |
1368 MarkPositionForCodeRelativeFixup(); | 1368 MarkPositionForCodeRelativeFixup(); |
1369 } | 1369 } |
1370 | 1370 |
1371 | 1371 |
1372 void RegExpMacroAssemblerX64::Pop(Register target) { | 1372 void RegExpMacroAssemblerX64::Pop(Register target) { |
1373 ASSERT(!target.is(backtrack_stackpointer())); | 1373 DCHECK(!target.is(backtrack_stackpointer())); |
1374 __ movsxlq(target, Operand(backtrack_stackpointer(), 0)); | 1374 __ movsxlq(target, Operand(backtrack_stackpointer(), 0)); |
1375 // Notice: This updates flags, unlike normal Pop. | 1375 // Notice: This updates flags, unlike normal Pop. |
1376 __ addp(backtrack_stackpointer(), Immediate(kIntSize)); | 1376 __ addp(backtrack_stackpointer(), Immediate(kIntSize)); |
1377 } | 1377 } |
1378 | 1378 |
1379 | 1379 |
1380 void RegExpMacroAssemblerX64::Drop() { | 1380 void RegExpMacroAssemblerX64::Drop() { |
1381 __ addp(backtrack_stackpointer(), Immediate(kIntSize)); | 1381 __ addp(backtrack_stackpointer(), Immediate(kIntSize)); |
1382 } | 1382 } |
1383 | 1383 |
(...skipping 28 matching lines...) Expand all Loading... |
1412 | 1412 |
1413 | 1413 |
1414 void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset, | 1414 void RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset, |
1415 int characters) { | 1415 int characters) { |
1416 if (mode_ == ASCII) { | 1416 if (mode_ == ASCII) { |
1417 if (characters == 4) { | 1417 if (characters == 4) { |
1418 __ movl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); | 1418 __ movl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); |
1419 } else if (characters == 2) { | 1419 } else if (characters == 2) { |
1420 __ movzxwl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); | 1420 __ movzxwl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); |
1421 } else { | 1421 } else { |
1422 ASSERT(characters == 1); | 1422 DCHECK(characters == 1); |
1423 __ movzxbl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); | 1423 __ movzxbl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); |
1424 } | 1424 } |
1425 } else { | 1425 } else { |
1426 ASSERT(mode_ == UC16); | 1426 DCHECK(mode_ == UC16); |
1427 if (characters == 2) { | 1427 if (characters == 2) { |
1428 __ movl(current_character(), | 1428 __ movl(current_character(), |
1429 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); | 1429 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); |
1430 } else { | 1430 } else { |
1431 ASSERT(characters == 1); | 1431 DCHECK(characters == 1); |
1432 __ movzxwl(current_character(), | 1432 __ movzxwl(current_character(), |
1433 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); | 1433 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); |
1434 } | 1434 } |
1435 } | 1435 } |
1436 } | 1436 } |
1437 | 1437 |
1438 #undef __ | 1438 #undef __ |
1439 | 1439 |
1440 #endif // V8_INTERPRETED_REGEXP | 1440 #endif // V8_INTERPRETED_REGEXP |
1441 | 1441 |
1442 }} // namespace v8::internal | 1442 }} // namespace v8::internal |
1443 | 1443 |
1444 #endif // V8_TARGET_ARCH_X64 | 1444 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |