OLD | NEW |
1 // Copyright 2008-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2008-2009 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 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 __ sub(edi, Operand(esi)); | 318 __ sub(edi, Operand(esi)); |
319 } else { | 319 } else { |
320 ASSERT(mode_ == UC16); | 320 ASSERT(mode_ == UC16); |
321 // Save registers before calling C function. | 321 // Save registers before calling C function. |
322 __ push(esi); | 322 __ push(esi); |
323 __ push(edi); | 323 __ push(edi); |
324 __ push(backtrack_stackpointer()); | 324 __ push(backtrack_stackpointer()); |
325 __ push(ebx); | 325 __ push(ebx); |
326 | 326 |
327 const int argument_count = 3; | 327 const int argument_count = 3; |
328 FrameAlign(argument_count, ecx); | 328 __ PrepareCallCFunction(argument_count, ecx); |
329 // Put arguments into allocated stack area, last argument highest on stack. | 329 // Put arguments into allocated stack area, last argument highest on stack. |
330 // Parameters are | 330 // Parameters are |
331 // Address byte_offset1 - Address captured substring's start. | 331 // Address byte_offset1 - Address captured substring's start. |
332 // Address byte_offset2 - Address of current character position. | 332 // Address byte_offset2 - Address of current character position. |
333 // size_t byte_length - length of capture in bytes(!) | 333 // size_t byte_length - length of capture in bytes(!) |
334 | 334 |
335 // Set byte_length. | 335 // Set byte_length. |
336 __ mov(Operand(esp, 2 * kPointerSize), ebx); | 336 __ mov(Operand(esp, 2 * kPointerSize), ebx); |
337 // Set byte_offset2. | 337 // Set byte_offset2. |
338 // Found by adding negative string-end offset of current position (edi) | 338 // Found by adding negative string-end offset of current position (edi) |
339 // to end of string. | 339 // to end of string. |
340 __ add(edi, Operand(esi)); | 340 __ add(edi, Operand(esi)); |
341 __ mov(Operand(esp, 1 * kPointerSize), edi); | 341 __ mov(Operand(esp, 1 * kPointerSize), edi); |
342 // Set byte_offset1. | 342 // Set byte_offset1. |
343 // Start of capture, where edx already holds string-end negative offset. | 343 // Start of capture, where edx already holds string-end negative offset. |
344 __ add(edx, Operand(esi)); | 344 __ add(edx, Operand(esi)); |
345 __ mov(Operand(esp, 0 * kPointerSize), edx); | 345 __ mov(Operand(esp, 0 * kPointerSize), edx); |
346 | 346 |
347 ExternalReference compare = | 347 ExternalReference compare = |
348 ExternalReference::re_case_insensitive_compare_uc16(); | 348 ExternalReference::re_case_insensitive_compare_uc16(); |
349 CallCFunction(compare, argument_count); | 349 __ CallCFunction(compare, argument_count); |
350 // Pop original values before reacting on result value. | 350 // Pop original values before reacting on result value. |
351 __ pop(ebx); | 351 __ pop(ebx); |
352 __ pop(backtrack_stackpointer()); | 352 __ pop(backtrack_stackpointer()); |
353 __ pop(edi); | 353 __ pop(edi); |
354 __ pop(esi); | 354 __ pop(esi); |
355 | 355 |
356 // Check if function returned non-zero for success or zero for failure. | 356 // Check if function returned non-zero for success or zero for failure. |
357 __ or_(eax, Operand(eax)); | 357 __ or_(eax, Operand(eax)); |
358 BranchOrBacktrack(zero, on_no_match); | 358 BranchOrBacktrack(zero, on_no_match); |
359 // On success, increment position by length of capture. | 359 // On success, increment position by length of capture. |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 SafeCallTarget(&stack_overflow_label_); | 778 SafeCallTarget(&stack_overflow_label_); |
779 // Reached if the backtrack-stack limit has been hit. | 779 // Reached if the backtrack-stack limit has been hit. |
780 | 780 |
781 Label grow_failed; | 781 Label grow_failed; |
782 // Save registers before calling C function | 782 // Save registers before calling C function |
783 __ push(esi); | 783 __ push(esi); |
784 __ push(edi); | 784 __ push(edi); |
785 | 785 |
786 // Call GrowStack(backtrack_stackpointer()) | 786 // Call GrowStack(backtrack_stackpointer()) |
787 int num_arguments = 2; | 787 int num_arguments = 2; |
788 FrameAlign(num_arguments, ebx); | 788 __ PrepareCallCFunction(num_arguments, ebx); |
789 __ lea(eax, Operand(ebp, kStackHighEnd)); | 789 __ lea(eax, Operand(ebp, kStackHighEnd)); |
790 __ mov(Operand(esp, 1 * kPointerSize), eax); | 790 __ mov(Operand(esp, 1 * kPointerSize), eax); |
791 __ mov(Operand(esp, 0 * kPointerSize), backtrack_stackpointer()); | 791 __ mov(Operand(esp, 0 * kPointerSize), backtrack_stackpointer()); |
792 ExternalReference grow_stack = ExternalReference::re_grow_stack(); | 792 ExternalReference grow_stack = ExternalReference::re_grow_stack(); |
793 CallCFunction(grow_stack, num_arguments); | 793 __ CallCFunction(grow_stack, num_arguments); |
794 // If return NULL, we have failed to grow the stack, and | 794 // If return NULL, we have failed to grow the stack, and |
795 // must exit with a stack-overflow exception. | 795 // must exit with a stack-overflow exception. |
796 __ or_(eax, Operand(eax)); | 796 __ or_(eax, Operand(eax)); |
797 __ j(equal, &exit_with_exception); | 797 __ j(equal, &exit_with_exception); |
798 // Otherwise use return value as new stack pointer. | 798 // Otherwise use return value as new stack pointer. |
799 __ mov(backtrack_stackpointer(), eax); | 799 __ mov(backtrack_stackpointer(), eax); |
800 // Restore saved registers and continue. | 800 // Restore saved registers and continue. |
801 __ pop(edi); | 801 __ pop(edi); |
802 __ pop(esi); | 802 __ pop(esi); |
803 SafeReturn(); | 803 SafeReturn(); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 __ mov(eax, backtrack_stackpointer()); | 945 __ mov(eax, backtrack_stackpointer()); |
946 __ sub(eax, Operand(ebp, kStackHighEnd)); | 946 __ sub(eax, Operand(ebp, kStackHighEnd)); |
947 __ mov(register_location(reg), eax); | 947 __ mov(register_location(reg), eax); |
948 } | 948 } |
949 | 949 |
950 | 950 |
951 // Private methods: | 951 // Private methods: |
952 | 952 |
953 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) { | 953 void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) { |
954 int num_arguments = 3; | 954 int num_arguments = 3; |
955 FrameAlign(num_arguments, scratch); | 955 __ PrepareCallCFunction(num_arguments, scratch); |
956 // RegExp code frame pointer. | 956 // RegExp code frame pointer. |
957 __ mov(Operand(esp, 2 * kPointerSize), ebp); | 957 __ mov(Operand(esp, 2 * kPointerSize), ebp); |
958 // Code* of self. | 958 // Code* of self. |
959 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); | 959 __ mov(Operand(esp, 1 * kPointerSize), Immediate(masm_->CodeObject())); |
960 // Next address on the stack (will be address of return address). | 960 // Next address on the stack (will be address of return address). |
961 __ lea(eax, Operand(esp, -kPointerSize)); | 961 __ lea(eax, Operand(esp, -kPointerSize)); |
962 __ mov(Operand(esp, 0 * kPointerSize), eax); | 962 __ mov(Operand(esp, 0 * kPointerSize), eax); |
963 ExternalReference check_stack_guard = | 963 ExternalReference check_stack_guard = |
964 ExternalReference::re_check_stack_guard_state(); | 964 ExternalReference::re_check_stack_guard_state(); |
965 CallCFunction(check_stack_guard, num_arguments); | 965 __ CallCFunction(check_stack_guard, num_arguments); |
966 } | 966 } |
967 | 967 |
968 | 968 |
969 // Helper function for reading a value out of a stack frame. | 969 // Helper function for reading a value out of a stack frame. |
970 template <typename T> | 970 template <typename T> |
971 static T& frame_entry(Address re_frame, int frame_offset) { | 971 static T& frame_entry(Address re_frame, int frame_offset) { |
972 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); | 972 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); |
973 } | 973 } |
974 | 974 |
975 | 975 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 ExternalReference::address_of_regexp_stack_limit(); | 1146 ExternalReference::address_of_regexp_stack_limit(); |
1147 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); | 1147 __ cmp(backtrack_stackpointer(), Operand::StaticVariable(stack_limit)); |
1148 __ j(above, &no_stack_overflow); | 1148 __ j(above, &no_stack_overflow); |
1149 | 1149 |
1150 SafeCall(&stack_overflow_label_); | 1150 SafeCall(&stack_overflow_label_); |
1151 | 1151 |
1152 __ bind(&no_stack_overflow); | 1152 __ bind(&no_stack_overflow); |
1153 } | 1153 } |
1154 | 1154 |
1155 | 1155 |
1156 void RegExpMacroAssemblerIA32::FrameAlign(int num_arguments, Register scratch) { | |
1157 // TODO(lrn): Since we no longer use the system stack arbitrarily (but we do | |
1158 // use it, e.g., for SafeCall), we know the number of elements on the stack | |
1159 // since the last frame alignment. We might be able to do this simpler then. | |
1160 int frameAlignment = OS::ActivationFrameAlignment(); | |
1161 if (frameAlignment != 0) { | |
1162 // Make stack end at alignment and make room for num_arguments words | |
1163 // and the original value of esp. | |
1164 __ mov(scratch, esp); | |
1165 __ sub(Operand(esp), Immediate((num_arguments + 1) * kPointerSize)); | |
1166 ASSERT(IsPowerOf2(frameAlignment)); | |
1167 __ and_(esp, -frameAlignment); | |
1168 __ mov(Operand(esp, num_arguments * kPointerSize), scratch); | |
1169 } else { | |
1170 __ sub(Operand(esp), Immediate(num_arguments * kPointerSize)); | |
1171 } | |
1172 } | |
1173 | |
1174 | |
1175 void RegExpMacroAssemblerIA32::CallCFunction(ExternalReference function, | |
1176 int num_arguments) { | |
1177 __ mov(Operand(eax), Immediate(function)); | |
1178 __ call(Operand(eax)); | |
1179 if (OS::ActivationFrameAlignment() != 0) { | |
1180 __ mov(esp, Operand(esp, num_arguments * kPointerSize)); | |
1181 } else { | |
1182 __ add(Operand(esp), Immediate(num_arguments * sizeof(int32_t))); | |
1183 } | |
1184 } | |
1185 | |
1186 | |
1187 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, | 1156 void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset, |
1188 int characters) { | 1157 int characters) { |
1189 if (mode_ == ASCII) { | 1158 if (mode_ == ASCII) { |
1190 if (characters == 4) { | 1159 if (characters == 4) { |
1191 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1160 __ mov(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1192 } else if (characters == 2) { | 1161 } else if (characters == 2) { |
1193 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1162 __ movzx_w(current_character(), Operand(esi, edi, times_1, cp_offset)); |
1194 } else { | 1163 } else { |
1195 ASSERT(characters == 1); | 1164 ASSERT(characters == 1); |
1196 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); | 1165 __ movzx_b(current_character(), Operand(esi, edi, times_1, cp_offset)); |
(...skipping 10 matching lines...) Expand all Loading... |
1207 } | 1176 } |
1208 } | 1177 } |
1209 } | 1178 } |
1210 | 1179 |
1211 | 1180 |
1212 #undef __ | 1181 #undef __ |
1213 | 1182 |
1214 #endif // V8_NATIVE_REGEXP | 1183 #endif // V8_NATIVE_REGEXP |
1215 | 1184 |
1216 }} // namespace v8::internal | 1185 }} // namespace v8::internal |
OLD | NEW |