Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(535)

Side by Side Diff: src/x64/regexp-macro-assembler-x64.cc

Issue 6759025: Version 3.2.6 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/regexp-macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 * int (*match)(String* input_string, 102 * int (*match)(String* input_string,
103 * int start_index, 103 * int start_index,
104 * Address start, 104 * Address start,
105 * Address end, 105 * Address end,
106 * int* capture_output_array, 106 * int* capture_output_array,
107 * bool at_start, 107 * bool at_start,
108 * byte* stack_area_base, 108 * byte* stack_area_base,
109 * bool direct_call) 109 * bool direct_call)
110 */ 110 */
111 111
112 #define __ ACCESS_MASM(masm_) 112 #define __ ACCESS_MASM((&masm_))
113 113
114 RegExpMacroAssemblerX64::RegExpMacroAssemblerX64( 114 RegExpMacroAssemblerX64::RegExpMacroAssemblerX64(
115 Mode mode, 115 Mode mode,
116 int registers_to_save) 116 int registers_to_save)
117 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), 117 : masm_(NULL, kRegExpCodeSize),
118 no_root_array_scope_(masm_), 118 no_root_array_scope_(&masm_),
119 code_relative_fixup_positions_(4), 119 code_relative_fixup_positions_(4),
120 mode_(mode), 120 mode_(mode),
121 num_registers_(registers_to_save), 121 num_registers_(registers_to_save),
122 num_saved_registers_(registers_to_save), 122 num_saved_registers_(registers_to_save),
123 entry_label_(), 123 entry_label_(),
124 start_label_(), 124 start_label_(),
125 success_label_(), 125 success_label_(),
126 backtrack_label_(), 126 backtrack_label_(),
127 exit_label_() { 127 exit_label_() {
128 ASSERT_EQ(0, registers_to_save % 2); 128 ASSERT_EQ(0, registers_to_save % 2);
129 __ jmp(&entry_label_); // We'll write the entry code when we know more. 129 __ jmp(&entry_label_); // We'll write the entry code when we know more.
130 __ bind(&start_label_); // And then continue from here. 130 __ bind(&start_label_); // And then continue from here.
131 } 131 }
132 132
133 133
134 RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() { 134 RegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() {
135 delete masm_;
136 // Unuse labels in case we throw away the assembler without calling GetCode. 135 // Unuse labels in case we throw away the assembler without calling GetCode.
137 entry_label_.Unuse(); 136 entry_label_.Unuse();
138 start_label_.Unuse(); 137 start_label_.Unuse();
139 success_label_.Unuse(); 138 success_label_.Unuse();
140 backtrack_label_.Unuse(); 139 backtrack_label_.Unuse();
141 exit_label_.Unuse(); 140 exit_label_.Unuse();
142 check_preempt_label_.Unuse(); 141 check_preempt_label_.Unuse();
143 stack_overflow_label_.Unuse(); 142 stack_overflow_label_.Unuse();
144 } 143 }
145 144
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // Compute byte_offset2 (current position = rsi+rdi). 420 // Compute byte_offset2 (current position = rsi+rdi).
422 __ lea(rax, Operand(rsi, rdi, times_1, 0)); 421 __ lea(rax, Operand(rsi, rdi, times_1, 0));
423 // Compute and set byte_offset1 (start of capture). 422 // Compute and set byte_offset1 (start of capture).
424 __ lea(rdi, Operand(rsi, rdx, times_1, 0)); 423 __ lea(rdi, Operand(rsi, rdx, times_1, 0));
425 // Set byte_offset2. 424 // Set byte_offset2.
426 __ movq(rsi, rax); 425 __ movq(rsi, rax);
427 // Set byte_length. 426 // Set byte_length.
428 __ movq(rdx, rbx); 427 __ movq(rdx, rbx);
429 #endif 428 #endif
430 ExternalReference compare = 429 ExternalReference compare =
431 ExternalReference::re_case_insensitive_compare_uc16(masm_->isolate()); 430 ExternalReference::re_case_insensitive_compare_uc16(masm_.isolate());
432 __ CallCFunction(compare, num_arguments); 431 __ CallCFunction(compare, num_arguments);
433 432
434 // Restore original values before reacting on result value. 433 // Restore original values before reacting on result value.
435 __ Move(code_object_pointer(), masm_->CodeObject()); 434 __ Move(code_object_pointer(), masm_.CodeObject());
436 __ pop(backtrack_stackpointer()); 435 __ pop(backtrack_stackpointer());
437 #ifndef _WIN64 436 #ifndef _WIN64
438 __ pop(rdi); 437 __ pop(rdi);
439 __ pop(rsi); 438 __ pop(rsi);
440 #endif 439 #endif
441 440
442 // Check if function returned non-zero for success or zero for failure. 441 // Check if function returned non-zero for success or zero for failure.
443 __ testq(rax, rax); 442 __ testq(rax, rax);
444 BranchOrBacktrack(zero, on_no_match); 443 BranchOrBacktrack(zero, on_no_match);
445 // On success, increment position by length of capture. 444 // On success, increment position by length of capture.
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 __ push(rbx); // Callee-save 738 __ push(rbx); // Callee-save
740 #endif 739 #endif
741 740
742 __ push(Immediate(0)); // Make room for "at start" constant. 741 __ push(Immediate(0)); // Make room for "at start" constant.
743 742
744 // Check if we have space on the stack for registers. 743 // Check if we have space on the stack for registers.
745 Label stack_limit_hit; 744 Label stack_limit_hit;
746 Label stack_ok; 745 Label stack_ok;
747 746
748 ExternalReference stack_limit = 747 ExternalReference stack_limit =
749 ExternalReference::address_of_stack_limit(masm_->isolate()); 748 ExternalReference::address_of_stack_limit(masm_.isolate());
750 __ movq(rcx, rsp); 749 __ movq(rcx, rsp);
751 __ movq(kScratchRegister, stack_limit); 750 __ movq(kScratchRegister, stack_limit);
752 __ subq(rcx, Operand(kScratchRegister, 0)); 751 __ subq(rcx, Operand(kScratchRegister, 0));
753 // Handle it if the stack pointer is already below the stack limit. 752 // Handle it if the stack pointer is already below the stack limit.
754 __ j(below_equal, &stack_limit_hit); 753 __ j(below_equal, &stack_limit_hit);
755 // Check if there is room for the variable number of registers above 754 // Check if there is room for the variable number of registers above
756 // the stack limit. 755 // the stack limit.
757 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize)); 756 __ cmpq(rcx, Immediate(num_registers_ * kPointerSize));
758 __ j(above_equal, &stack_ok); 757 __ j(above_equal, &stack_ok);
759 // Exit with OutOfMemory exception. There is not enough space on the stack 758 // Exit with OutOfMemory exception. There is not enough space on the stack
760 // for our working registers. 759 // for our working registers.
761 __ movq(rax, Immediate(EXCEPTION)); 760 __ movq(rax, Immediate(EXCEPTION));
762 __ jmp(&exit_label_); 761 __ jmp(&exit_label_);
763 762
764 __ bind(&stack_limit_hit); 763 __ bind(&stack_limit_hit);
765 __ Move(code_object_pointer(), masm_->CodeObject()); 764 __ Move(code_object_pointer(), masm_.CodeObject());
766 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. 765 CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp.
767 __ testq(rax, rax); 766 __ testq(rax, rax);
768 // If returned value is non-zero, we exit with the returned value as result. 767 // If returned value is non-zero, we exit with the returned value as result.
769 __ j(not_zero, &exit_label_); 768 __ j(not_zero, &exit_label_);
770 769
771 __ bind(&stack_ok); 770 __ bind(&stack_ok);
772 771
773 // Allocate space on stack for registers. 772 // Allocate space on stack for registers.
774 __ subq(rsp, Immediate(num_registers_ * kPointerSize)); 773 __ subq(rsp, Immediate(num_registers_ * kPointerSize));
775 // Load string length. 774 // Load string length.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 const int kRegistersPerPage = kPageSize / kPointerSize; 809 const int kRegistersPerPage = kPageSize / kPointerSize;
811 for (int i = num_saved_registers_ + kRegistersPerPage - 1; 810 for (int i = num_saved_registers_ + kRegistersPerPage - 1;
812 i < num_registers_; 811 i < num_registers_;
813 i += kRegistersPerPage) { 812 i += kRegistersPerPage) {
814 __ movq(register_location(i), rax); // One write every page. 813 __ movq(register_location(i), rax); // One write every page.
815 } 814 }
816 815
817 // Initialize backtrack stack pointer. 816 // Initialize backtrack stack pointer.
818 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); 817 __ movq(backtrack_stackpointer(), Operand(rbp, kStackHighEnd));
819 // Initialize code object pointer. 818 // Initialize code object pointer.
820 __ Move(code_object_pointer(), masm_->CodeObject()); 819 __ Move(code_object_pointer(), masm_.CodeObject());
821 // Load previous char as initial value of current-character. 820 // Load previous char as initial value of current-character.
822 Label at_start; 821 Label at_start;
823 __ cmpb(Operand(rbp, kStartIndex), Immediate(0)); 822 __ cmpb(Operand(rbp, kStartIndex), Immediate(0));
824 __ j(equal, &at_start); 823 __ j(equal, &at_start);
825 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char. 824 LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
826 __ jmp(&start_label_); 825 __ jmp(&start_label_);
827 __ bind(&at_start); 826 __ bind(&at_start);
828 __ movq(current_character(), Immediate('\n')); 827 __ movq(current_character(), Immediate('\n'));
829 __ jmp(&start_label_); 828 __ jmp(&start_label_);
830 829
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 __ push(backtrack_stackpointer()); 890 __ push(backtrack_stackpointer());
892 __ push(rdi); 891 __ push(rdi);
893 892
894 CallCheckStackGuardState(); 893 CallCheckStackGuardState();
895 __ testq(rax, rax); 894 __ testq(rax, rax);
896 // If returning non-zero, we should end execution with the given 895 // If returning non-zero, we should end execution with the given
897 // result as return value. 896 // result as return value.
898 __ j(not_zero, &exit_label_); 897 __ j(not_zero, &exit_label_);
899 898
900 // Restore registers. 899 // Restore registers.
901 __ Move(code_object_pointer(), masm_->CodeObject()); 900 __ Move(code_object_pointer(), masm_.CodeObject());
902 __ pop(rdi); 901 __ pop(rdi);
903 __ pop(backtrack_stackpointer()); 902 __ pop(backtrack_stackpointer());
904 // String might have moved: Reload esi from frame. 903 // String might have moved: Reload esi from frame.
905 __ movq(rsi, Operand(rbp, kInputEnd)); 904 __ movq(rsi, Operand(rbp, kInputEnd));
906 SafeReturn(); 905 SafeReturn();
907 } 906 }
908 907
909 // Backtrack stack overflow code. 908 // Backtrack stack overflow code.
910 if (stack_overflow_label_.is_linked()) { 909 if (stack_overflow_label_.is_linked()) {
911 SafeCallTarget(&stack_overflow_label_); 910 SafeCallTarget(&stack_overflow_label_);
(...skipping 13 matching lines...) Expand all
925 #ifdef _WIN64 924 #ifdef _WIN64
926 // Microsoft passes parameters in rcx, rdx. 925 // Microsoft passes parameters in rcx, rdx.
927 // First argument, backtrack stackpointer, is already in rcx. 926 // First argument, backtrack stackpointer, is already in rcx.
928 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument 927 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument
929 #else 928 #else
930 // AMD64 ABI passes parameters in rdi, rsi. 929 // AMD64 ABI passes parameters in rdi, rsi.
931 __ movq(rdi, backtrack_stackpointer()); // First argument. 930 __ movq(rdi, backtrack_stackpointer()); // First argument.
932 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument. 931 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument.
933 #endif 932 #endif
934 ExternalReference grow_stack = 933 ExternalReference grow_stack =
935 ExternalReference::re_grow_stack(masm_->isolate()); 934 ExternalReference::re_grow_stack(masm_.isolate());
936 __ CallCFunction(grow_stack, num_arguments); 935 __ CallCFunction(grow_stack, num_arguments);
937 // If return NULL, we have failed to grow the stack, and 936 // If return NULL, we have failed to grow the stack, and
938 // must exit with a stack-overflow exception. 937 // must exit with a stack-overflow exception.
939 __ testq(rax, rax); 938 __ testq(rax, rax);
940 __ j(equal, &exit_with_exception); 939 __ j(equal, &exit_with_exception);
941 // Otherwise use return value as new stack pointer. 940 // Otherwise use return value as new stack pointer.
942 __ movq(backtrack_stackpointer(), rax); 941 __ movq(backtrack_stackpointer(), rax);
943 // Restore saved registers and continue. 942 // Restore saved registers and continue.
944 __ Move(code_object_pointer(), masm_->CodeObject()); 943 __ Move(code_object_pointer(), masm_.CodeObject());
945 #ifndef _WIN64 944 #ifndef _WIN64
946 __ pop(rdi); 945 __ pop(rdi);
947 __ pop(rsi); 946 __ pop(rsi);
948 #endif 947 #endif
949 SafeReturn(); 948 SafeReturn();
950 } 949 }
951 950
952 if (exit_with_exception.is_linked()) { 951 if (exit_with_exception.is_linked()) {
953 // If any of the code above needed to exit with an exception. 952 // If any of the code above needed to exit with an exception.
954 __ bind(&exit_with_exception); 953 __ bind(&exit_with_exception);
955 // Exit with Result EXCEPTION(-1) to signal thrown exception. 954 // Exit with Result EXCEPTION(-1) to signal thrown exception.
956 __ movq(rax, Immediate(EXCEPTION)); 955 __ movq(rax, Immediate(EXCEPTION));
957 __ jmp(&exit_label_); 956 __ jmp(&exit_label_);
958 } 957 }
959 958
960 FixupCodeRelativePositions(); 959 FixupCodeRelativePositions();
961 960
962 CodeDesc code_desc; 961 CodeDesc code_desc;
963 masm_->GetCode(&code_desc); 962 masm_.GetCode(&code_desc);
964 Isolate* isolate = ISOLATE; 963 Isolate* isolate = ISOLATE;
965 Handle<Code> code = isolate->factory()->NewCode( 964 Handle<Code> code = isolate->factory()->NewCode(
966 code_desc, Code::ComputeFlags(Code::REGEXP), 965 code_desc, Code::ComputeFlags(Code::REGEXP),
967 masm_->CodeObject()); 966 masm_.CodeObject());
968 PROFILE(isolate, RegExpCodeCreateEvent(*code, *source)); 967 PROFILE(isolate, RegExpCodeCreateEvent(*code, *source));
969 return Handle<Object>::cast(code); 968 return Handle<Object>::cast(code);
970 } 969 }
971 970
972 971
973 void RegExpMacroAssemblerX64::GoTo(Label* to) { 972 void RegExpMacroAssemblerX64::GoTo(Label* to) {
974 BranchOrBacktrack(no_condition, to); 973 BranchOrBacktrack(no_condition, to);
975 } 974 }
976 975
977 976
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1127 #else 1126 #else
1128 // Third argument: RegExp code frame pointer. 1127 // Third argument: RegExp code frame pointer.
1129 __ movq(rdx, rbp); 1128 __ movq(rdx, rbp);
1130 // Second argument: Code* of self. 1129 // Second argument: Code* of self.
1131 __ movq(rsi, code_object_pointer()); 1130 __ movq(rsi, code_object_pointer());
1132 // First argument: Next address on the stack (will be address of 1131 // First argument: Next address on the stack (will be address of
1133 // return address). 1132 // return address).
1134 __ lea(rdi, Operand(rsp, -kPointerSize)); 1133 __ lea(rdi, Operand(rsp, -kPointerSize));
1135 #endif 1134 #endif
1136 ExternalReference stack_check = 1135 ExternalReference stack_check =
1137 ExternalReference::re_check_stack_guard_state(masm_->isolate()); 1136 ExternalReference::re_check_stack_guard_state(masm_.isolate());
1138 __ CallCFunction(stack_check, num_arguments); 1137 __ CallCFunction(stack_check, num_arguments);
1139 } 1138 }
1140 1139
1141 1140
1142 // Helper function for reading a value out of a stack frame. 1141 // Helper function for reading a value out of a stack frame.
1143 template <typename T> 1142 template <typename T>
1144 static T& frame_entry(Address re_frame, int frame_offset) { 1143 static T& frame_entry(Address re_frame, int frame_offset) {
1145 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 1144 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset));
1146 } 1145 }
1147 1146
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 } 1291 }
1293 1292
1294 1293
1295 void RegExpMacroAssemblerX64::FixupCodeRelativePositions() { 1294 void RegExpMacroAssemblerX64::FixupCodeRelativePositions() {
1296 for (int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) { 1295 for (int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) {
1297 int position = code_relative_fixup_positions_[i]; 1296 int position = code_relative_fixup_positions_[i];
1298 // The position succeeds a relative label offset from position. 1297 // The position succeeds a relative label offset from position.
1299 // Patch the relative offset to be relative to the Code object pointer 1298 // Patch the relative offset to be relative to the Code object pointer
1300 // instead. 1299 // instead.
1301 int patch_position = position - kIntSize; 1300 int patch_position = position - kIntSize;
1302 int offset = masm_->long_at(patch_position); 1301 int offset = masm_.long_at(patch_position);
1303 masm_->long_at_put(patch_position, 1302 masm_.long_at_put(patch_position,
1304 offset 1303 offset
1305 + position 1304 + position
1306 + Code::kHeaderSize 1305 + Code::kHeaderSize
1307 - kHeapObjectTag); 1306 - kHeapObjectTag);
1308 } 1307 }
1309 code_relative_fixup_positions_.Clear(); 1308 code_relative_fixup_positions_.Clear();
1310 } 1309 }
1311 1310
1312 1311
1313 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) { 1312 void RegExpMacroAssemblerX64::Push(Label* backtrack_target) {
(...skipping 13 matching lines...) Expand all
1327 1326
1328 void RegExpMacroAssemblerX64::Drop() { 1327 void RegExpMacroAssemblerX64::Drop() {
1329 __ addq(backtrack_stackpointer(), Immediate(kIntSize)); 1328 __ addq(backtrack_stackpointer(), Immediate(kIntSize));
1330 } 1329 }
1331 1330
1332 1331
1333 void RegExpMacroAssemblerX64::CheckPreemption() { 1332 void RegExpMacroAssemblerX64::CheckPreemption() {
1334 // Check for preemption. 1333 // Check for preemption.
1335 Label no_preempt; 1334 Label no_preempt;
1336 ExternalReference stack_limit = 1335 ExternalReference stack_limit =
1337 ExternalReference::address_of_stack_limit(masm_->isolate()); 1336 ExternalReference::address_of_stack_limit(masm_.isolate());
1338 __ load_rax(stack_limit); 1337 __ load_rax(stack_limit);
1339 __ cmpq(rsp, rax); 1338 __ cmpq(rsp, rax);
1340 __ j(above, &no_preempt); 1339 __ j(above, &no_preempt);
1341 1340
1342 SafeCall(&check_preempt_label_); 1341 SafeCall(&check_preempt_label_);
1343 1342
1344 __ bind(&no_preempt); 1343 __ bind(&no_preempt);
1345 } 1344 }
1346 1345
1347 1346
1348 void RegExpMacroAssemblerX64::CheckStackLimit() { 1347 void RegExpMacroAssemblerX64::CheckStackLimit() {
1349 Label no_stack_overflow; 1348 Label no_stack_overflow;
1350 ExternalReference stack_limit = 1349 ExternalReference stack_limit =
1351 ExternalReference::address_of_regexp_stack_limit(masm_->isolate()); 1350 ExternalReference::address_of_regexp_stack_limit(masm_.isolate());
1352 __ load_rax(stack_limit); 1351 __ load_rax(stack_limit);
1353 __ cmpq(backtrack_stackpointer(), rax); 1352 __ cmpq(backtrack_stackpointer(), rax);
1354 __ j(above, &no_stack_overflow); 1353 __ j(above, &no_stack_overflow);
1355 1354
1356 SafeCall(&stack_overflow_label_); 1355 SafeCall(&stack_overflow_label_);
1357 1356
1358 __ bind(&no_stack_overflow); 1357 __ bind(&no_stack_overflow);
1359 } 1358 }
1360 1359
1361 1360
(...skipping 21 matching lines...) Expand all
1383 } 1382 }
1384 } 1383 }
1385 1384
1386 #undef __ 1385 #undef __
1387 1386
1388 #endif // V8_INTERPRETED_REGEXP 1387 #endif // V8_INTERPRETED_REGEXP
1389 1388
1390 }} // namespace v8::internal 1389 }} // namespace v8::internal
1391 1390
1392 #endif // V8_TARGET_ARCH_X64 1391 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/regexp-macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698