OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 21 matching lines...) Expand all Loading... |
32 #include "ast.h" | 32 #include "ast.h" |
33 #include "regexp-stack.h" | 33 #include "regexp-stack.h" |
34 #include "macro-assembler.h" | 34 #include "macro-assembler.h" |
35 #include "regexp-macro-assembler.h" | 35 #include "regexp-macro-assembler.h" |
36 #include "x64/macro-assembler-x64.h" | 36 #include "x64/macro-assembler-x64.h" |
37 #include "x64/regexp-macro-assembler-x64.h" | 37 #include "x64/regexp-macro-assembler-x64.h" |
38 | 38 |
39 namespace v8 { | 39 namespace v8 { |
40 namespace internal { | 40 namespace internal { |
41 | 41 |
| 42 #ifdef V8_NATIVE_REGEXP |
| 43 |
42 /* | 44 /* |
43 * This assembler uses the following register assignment convention | 45 * This assembler uses the following register assignment convention |
44 * - rdx : currently loaded character(s) as ASCII or UC16. Must be loaded using | 46 * - rdx : currently loaded character(s) as ASCII or UC16. Must be loaded using |
45 * LoadCurrentCharacter before using any of the dispatch methods. | 47 * LoadCurrentCharacter before using any of the dispatch methods. |
46 * - rdi : current position in input, as negative offset from end of string. | 48 * - rdi : current position in input, as negative offset from end of string. |
47 * Please notice that this is the byte offset, not the character | 49 * Please notice that this is the byte offset, not the character |
48 * offset! Is always a 32-bit signed (negative) offset, but must be | 50 * offset! Is always a 32-bit signed (negative) offset, but must be |
49 * maintained sign-extended to 64 bits, since it is used as index. | 51 * maintained sign-extended to 64 bits, since it is used as index. |
50 * - rsi : end of input (points to byte after last character in input), | 52 * - rsi : end of input (points to byte after last character in input), |
51 * so that rsi+rdi points to the current character. | 53 * so that rsi+rdi points to the current character. |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 #else // AMD64 calling convention | 345 #else // AMD64 calling convention |
344 // Compute byte_offset2 (current position = rsi+rdi). | 346 // Compute byte_offset2 (current position = rsi+rdi). |
345 __ lea(rax, Operand(rsi, rdi, times_1, 0)); | 347 __ lea(rax, Operand(rsi, rdi, times_1, 0)); |
346 // Compute and set byte_offset1 (start of capture). | 348 // Compute and set byte_offset1 (start of capture). |
347 __ lea(rdi, Operand(rsi, rdx, times_1, 0)); | 349 __ lea(rdi, Operand(rsi, rdx, times_1, 0)); |
348 // Set byte_offset2. | 350 // Set byte_offset2. |
349 __ movq(rsi, rax); | 351 __ movq(rsi, rax); |
350 // Set byte_length. | 352 // Set byte_length. |
351 __ movq(rdx, rbx); | 353 __ movq(rdx, rbx); |
352 #endif | 354 #endif |
353 Address function_address = FUNCTION_ADDR(&CaseInsensitiveCompareUC16); | 355 ExternalReference compare = |
354 CallCFunction(function_address, num_arguments); | 356 ExternalReference::re_case_insensitive_compare_uc16(); |
| 357 CallCFunction(compare, num_arguments); |
355 | 358 |
356 // Restore original values before reacting on result value. | 359 // Restore original values before reacting on result value. |
357 __ Move(code_object_pointer(), masm_->CodeObject()); | 360 __ Move(code_object_pointer(), masm_->CodeObject()); |
358 __ pop(backtrack_stackpointer()); | 361 __ pop(backtrack_stackpointer()); |
359 #ifndef _WIN64 | 362 #ifndef _WIN64 |
360 __ pop(rdi); | 363 __ pop(rdi); |
361 __ pop(rsi); | 364 __ pop(rsi); |
362 #endif | 365 #endif |
363 | 366 |
364 // Check if function returned non-zero for success or zero for failure. | 367 // Check if function returned non-zero for success or zero for failure. |
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 #endif | 804 #endif |
802 | 805 |
803 // Call GrowStack(backtrack_stackpointer()) | 806 // Call GrowStack(backtrack_stackpointer()) |
804 int num_arguments = 2; | 807 int num_arguments = 2; |
805 FrameAlign(num_arguments); | 808 FrameAlign(num_arguments); |
806 #ifdef _WIN64 | 809 #ifdef _WIN64 |
807 // Microsoft passes parameters in rcx, rdx. | 810 // Microsoft passes parameters in rcx, rdx. |
808 // First argument, backtrack stackpointer, is already in rcx. | 811 // First argument, backtrack stackpointer, is already in rcx. |
809 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument | 812 __ lea(rdx, Operand(rbp, kStackHighEnd)); // Second argument |
810 #else | 813 #else |
811 // AMD64 ABI passes paremeters in rdi, rsi. | 814 // AMD64 ABI passes parameters in rdi, rsi. |
812 __ movq(rdi, backtrack_stackpointer()); // First argument. | 815 __ movq(rdi, backtrack_stackpointer()); // First argument. |
813 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument. | 816 __ lea(rsi, Operand(rbp, kStackHighEnd)); // Second argument. |
814 #endif | 817 #endif |
815 CallCFunction(FUNCTION_ADDR(&GrowStack), num_arguments); | 818 ExternalReference grow_stack = ExternalReference::re_grow_stack(); |
| 819 CallCFunction(grow_stack, num_arguments); |
816 // If return NULL, we have failed to grow the stack, and | 820 // If return NULL, we have failed to grow the stack, and |
817 // must exit with a stack-overflow exception. | 821 // must exit with a stack-overflow exception. |
818 __ testq(rax, rax); | 822 __ testq(rax, rax); |
819 __ j(equal, &exit_with_exception); | 823 __ j(equal, &exit_with_exception); |
820 // Otherwise use return value as new stack pointer. | 824 // Otherwise use return value as new stack pointer. |
821 __ movq(backtrack_stackpointer(), rax); | 825 __ movq(backtrack_stackpointer(), rax); |
822 // Restore saved registers and continue. | 826 // Restore saved registers and continue. |
823 __ Move(code_object_pointer(), masm_->CodeObject()); | 827 __ Move(code_object_pointer(), masm_->CodeObject()); |
824 #ifndef _WIN64 | 828 #ifndef _WIN64 |
825 __ pop(rdi); | 829 __ pop(rdi); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 __ lea(rcx, Operand(rsp, -kPointerSize)); | 994 __ lea(rcx, Operand(rsp, -kPointerSize)); |
991 #else | 995 #else |
992 // Third argument: RegExp code frame pointer. | 996 // Third argument: RegExp code frame pointer. |
993 __ movq(rdx, rbp); | 997 __ movq(rdx, rbp); |
994 // Second argument: Code* of self. | 998 // Second argument: Code* of self. |
995 __ movq(rsi, code_object_pointer()); | 999 __ movq(rsi, code_object_pointer()); |
996 // First argument: Next address on the stack (will be address of | 1000 // First argument: Next address on the stack (will be address of |
997 // return address). | 1001 // return address). |
998 __ lea(rdi, Operand(rsp, -kPointerSize)); | 1002 __ lea(rdi, Operand(rsp, -kPointerSize)); |
999 #endif | 1003 #endif |
1000 CallCFunction(FUNCTION_ADDR(&CheckStackGuardState), num_arguments); | 1004 ExternalReference stack_check = |
| 1005 ExternalReference::re_check_stack_guard_state(); |
| 1006 CallCFunction(stack_check, num_arguments); |
1001 } | 1007 } |
1002 | 1008 |
1003 | 1009 |
1004 // Helper function for reading a value out of a stack frame. | 1010 // Helper function for reading a value out of a stack frame. |
1005 template <typename T> | 1011 template <typename T> |
1006 static T& frame_entry(Address re_frame, int frame_offset) { | 1012 static T& frame_entry(Address re_frame, int frame_offset) { |
1007 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); | 1013 return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); |
1008 } | 1014 } |
1009 | 1015 |
1010 | 1016 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 int byte_length = end_address - start_address; | 1079 int byte_length = end_address - start_address; |
1074 frame_entry<const String*>(re_frame, kInputString) = *subject; | 1080 frame_entry<const String*>(re_frame, kInputString) = *subject; |
1075 frame_entry<const byte*>(re_frame, kInputStart) = new_address; | 1081 frame_entry<const byte*>(re_frame, kInputStart) = new_address; |
1076 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length; | 1082 frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length; |
1077 } | 1083 } |
1078 | 1084 |
1079 return 0; | 1085 return 0; |
1080 } | 1086 } |
1081 | 1087 |
1082 | 1088 |
1083 Address RegExpMacroAssemblerX64::GrowStack(Address stack_pointer, | |
1084 Address* stack_base) { | |
1085 size_t size = RegExpStack::stack_capacity(); | |
1086 Address old_stack_base = RegExpStack::stack_base(); | |
1087 ASSERT(old_stack_base == *stack_base); | |
1088 ASSERT(stack_pointer <= old_stack_base); | |
1089 ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size); | |
1090 Address new_stack_base = RegExpStack::EnsureCapacity(size * 2); | |
1091 if (new_stack_base == NULL) { | |
1092 return NULL; | |
1093 } | |
1094 *stack_base = new_stack_base; | |
1095 intptr_t stack_content_size = old_stack_base - stack_pointer; | |
1096 return new_stack_base - stack_content_size; | |
1097 } | |
1098 | |
1099 | |
1100 Operand RegExpMacroAssemblerX64::register_location(int register_index) { | 1089 Operand RegExpMacroAssemblerX64::register_location(int register_index) { |
1101 ASSERT(register_index < (1<<30)); | 1090 ASSERT(register_index < (1<<30)); |
1102 if (num_registers_ <= register_index) { | 1091 if (num_registers_ <= register_index) { |
1103 num_registers_ = register_index + 1; | 1092 num_registers_ = register_index + 1; |
1104 } | 1093 } |
1105 return Operand(rbp, kRegisterZero - register_index * kPointerSize); | 1094 return Operand(rbp, kRegisterZero - register_index * kPointerSize); |
1106 } | 1095 } |
1107 | 1096 |
1108 | 1097 |
1109 void RegExpMacroAssemblerX64::CheckPosition(int cp_offset, | 1098 void RegExpMacroAssemblerX64::CheckPosition(int cp_offset, |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1249 __ movq(Operand(rsp, num_arguments * kPointerSize), kScratchRegister); | 1238 __ movq(Operand(rsp, num_arguments * kPointerSize), kScratchRegister); |
1250 #else | 1239 #else |
1251 // Allocate space for old rsp. | 1240 // Allocate space for old rsp. |
1252 __ subq(rsp, Immediate(kPointerSize)); | 1241 __ subq(rsp, Immediate(kPointerSize)); |
1253 __ and_(rsp, Immediate(-frameAlignment)); | 1242 __ and_(rsp, Immediate(-frameAlignment)); |
1254 __ movq(Operand(rsp, 0), kScratchRegister); | 1243 __ movq(Operand(rsp, 0), kScratchRegister); |
1255 #endif | 1244 #endif |
1256 } | 1245 } |
1257 | 1246 |
1258 | 1247 |
1259 void RegExpMacroAssemblerX64::CallCFunction(Address function_address, | 1248 void RegExpMacroAssemblerX64::CallCFunction(ExternalReference function, |
1260 int num_arguments) { | 1249 int num_arguments) { |
1261 // Don't compile regexps with serialization enabled. The addresses of the C++ | 1250 // Don't compile regexps with serialization enabled. The addresses of the C++ |
1262 // function being called isn't relocatable. | 1251 // function being called isn't relocatable. |
1263 ASSERT(!Serializer::enabled()); | 1252 ASSERT(!Serializer::enabled()); |
1264 __ movq(rax, reinterpret_cast<intptr_t>(function_address), RelocInfo::NONE); | 1253 __ movq(rax, function); |
1265 __ call(rax); | 1254 __ call(rax); |
1266 ASSERT(OS::ActivationFrameAlignment() != 0); | 1255 ASSERT(OS::ActivationFrameAlignment() != 0); |
1267 #ifdef _WIN64 | 1256 #ifdef _WIN64 |
1268 __ movq(rsp, Operand(rsp, num_arguments * kPointerSize)); | 1257 __ movq(rsp, Operand(rsp, num_arguments * kPointerSize)); |
1269 #else | 1258 #else |
1270 __ pop(rsp); | 1259 __ pop(rsp); |
1271 #endif | 1260 #endif |
1272 } | 1261 } |
1273 | 1262 |
1274 | 1263 |
(...skipping 15 matching lines...) Expand all Loading... |
1290 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); | 1279 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); |
1291 } else { | 1280 } else { |
1292 ASSERT(characters == 1); | 1281 ASSERT(characters == 1); |
1293 __ movzxwl(current_character(), | 1282 __ movzxwl(current_character(), |
1294 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); | 1283 Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); |
1295 } | 1284 } |
1296 } | 1285 } |
1297 } | 1286 } |
1298 | 1287 |
1299 | 1288 |
| 1289 void RegExpCEntryStub::Generate(MacroAssembler* masm_) { |
| 1290 __ int3(); // Unused on x64. |
| 1291 } |
| 1292 |
1300 #undef __ | 1293 #undef __ |
| 1294 |
| 1295 #endif // V8_NATIVE_REGEXP |
| 1296 |
1301 }} // namespace v8::internal | 1297 }} // namespace v8::internal |
OLD | NEW |