| 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 |