115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 69dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/log.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/regexp-macro-assembler.h" 134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/regexp-stack.h" 144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/serialize.h" 154b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/unicode.h" 16196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/x64/regexp-macro-assembler-x64.h" 17911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 18911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgnamespace v8 { 19911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgnamespace internal { 20911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 21c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#ifndef V8_INTERPRETED_REGEXP 2218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 23911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org/* 24911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * This assembler uses the following register assignment convention 252c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org * - rdx : Currently loaded character(s) as Latin1 or UC16. Must be loaded 2615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * using LoadCurrentCharacter before using any of the dispatch methods. 2715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * Temporarily stores the index of capture start after a matching pass 2815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * for a global regexp. 2915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - rdi : Current position in input, as negative offset from end of string. 30911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * Please notice that this is the byte offset, not the character 3115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * offset! Is always a 32-bit signed (negative) offset, but must be 32911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * maintained sign-extended to 64 bits, since it is used as index. 3315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - rsi : End of input (points to byte after last character in input), 34911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * so that rsi+rdi points to the current character. 3515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - rbp : Frame pointer. Used to access arguments, local variables and 36911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * RegExp registers. 3715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - rsp : Points to tip of C stack. 3815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - rcx : Points to tip of backtrack stack. The backtrack stack contains 3915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * only 32-bit values. Most are offsets from some base (e.g., character 40911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * positions from end of string or code location from Code* pointer). 4115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - r8 : Code object pointer. Used to convert between absolute and 42911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * code-object-relative addresses. 43911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * 440c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * The registers rax, rbx, r9 and r11 are free to use for computations. 45911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * If changed to use r12+, they should be saved as callee-save registers. 46ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org * The macro assembler special registers r12 and r13 (kSmiConstantRegister, 47ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org * kRootRegister) aren't special during execution of RegExp code (they don't 48ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org * hold the values assumed when creating JS code), so no Smi or Root related 49ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org * macro operations can be used. 50911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * 51911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * Each call to a C++ method should retain these registers. 52911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * 53911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * The stack will have the following content, in some order, indexable from the 54911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * frame pointer (see, e.g., kStackHighEnd): 5515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - Isolate* isolate (address of the current isolate) 560c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - direct_call (if 1, direct call from JavaScript code, if 0 call 570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * through the runtime system) 5815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - stack_area_base (high end of the memory area to use as 590c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * backtracking stack) 6015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - capture array size (may fit multiple sets of matches) 610c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - int* capture_array (int[num_saved_registers_], for output). 6215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - end of input (address of end of string) 6315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - start of input (address of first character in string) 640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - start index (character index of start) 650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * - String* input_string (input string) 66911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * - return address 67911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * - backup of callee save registers (rbx, possibly rsi and rdi). 6815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * - success counter (only useful for global regexp to count matches) 69911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * - Offset of location before start of input (effectively character 7015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * position -1). Used to initialize capture registers to a non-position. 71b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org * - At start of string (if 1, we are starting at the start of the 72b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org * string, otherwise 0) 73911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * - register 0 rbp[-n] (Only positions must be stored in the first 74911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * - register 1 rbp[-n-8] num_saved_registers_ registers) 75911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * - ... 76911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * 77911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * The first num_saved_registers_ registers are initialized to point to 78911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * "character -1" in the string (i.e., char_size() bytes before the first 7915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org * character of the string). The remaining registers starts out uninitialized. 80911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * 81911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * The first seven values must be provided by the calling code by 82911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * calling the code's entry address cast to a function pointer with the 83911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * following signature: 84911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * int (*match)(String* input_string, 850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * int start_index, 86911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * Address start, 87911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * Address end, 88911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * int* capture_output_array, 89911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org * bool at_start, 900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * byte* stack_area_base, 910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org * bool direct_call) 92911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org */ 93911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define __ ACCESS_MASM((&masm_)) 95911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 96911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgRegExpMacroAssemblerX64::RegExpMacroAssemblerX64( 97911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Mode mode, 987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org int registers_to_save, 997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Zone* zone) 1007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org : NativeRegExpMacroAssembler(zone), 1011fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org masm_(zone->isolate(), NULL, kRegExpCodeSize), 1027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org no_root_array_scope_(&masm_), 1037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org code_relative_fixup_positions_(4, zone), 104911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org mode_(mode), 105911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org num_registers_(registers_to_save), 106911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org num_saved_registers_(registers_to_save), 107911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org entry_label_(), 108911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org start_label_(), 109911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org success_label_(), 110911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org backtrack_label_(), 111911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org exit_label_() { 112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, registers_to_save % 2); 113911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ jmp(&entry_label_); // We'll write the entry code when we know more. 114911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&start_label_); // And then continue from here. 115911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 116911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 117911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 118911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgRegExpMacroAssemblerX64::~RegExpMacroAssemblerX64() { 119911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Unuse labels in case we throw away the assembler without calling GetCode. 120911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org entry_label_.Unuse(); 121911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org start_label_.Unuse(); 122911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org success_label_.Unuse(); 123911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org backtrack_label_.Unuse(); 124911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org exit_label_.Unuse(); 125911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org check_preempt_label_.Unuse(); 126911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org stack_overflow_label_.Unuse(); 127911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 128911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 129911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 130911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgint RegExpMacroAssemblerX64::stack_limit_slack() { 131911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return RegExpStack::kStackLimitSlack; 132911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 133911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 134911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 135911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::AdvanceCurrentPosition(int by) { 136911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (by != 0) { 137911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ addq(rdi, Immediate(by * char_size())); 138911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 139911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 140911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 141911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 142911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::AdvanceRegister(int reg, int by) { 143e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg >= 0); 144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg < num_registers_); 145911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (by != 0) { 146fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(register_location(reg), Immediate(by)); 147911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 148911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 149911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 150911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 151911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Backtrack() { 152911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org CheckPreemption(); 153911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Pop Code* offset from backtrack stack, add Code* and jump to location. 154911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Pop(rbx); 155fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rbx, code_object_pointer()); 156911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ jmp(rbx); 157911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 158911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 159911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 160911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Bind(Label* label) { 161911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(label); 162911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 163911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 164911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 165911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckCharacter(uint32_t c, Label* on_equal) { 166911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(current_character(), Immediate(c)); 167911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(equal, on_equal); 168911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 169911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 170911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 171911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckCharacterGT(uc16 limit, Label* on_greater) { 172911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(current_character(), Immediate(limit)); 173911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(greater, on_greater); 174911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 175911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 176911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 177911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckAtStart(Label* on_at_start) { 178911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label not_at_start; 179911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Did we start the match at the start of the string at all? 180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmpl(Operand(rbp, kStartIndex), Immediate(0)); 181dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org BranchOrBacktrack(not_equal, ¬_at_start); 182911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If we did, are we still at the start of the input? 183895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(rsi, rdi, times_1, 0)); 1847a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rax, Operand(rbp, kInputStart)); 185911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(equal, on_at_start); 186911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(¬_at_start); 187911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 188911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 189911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 190911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckNotAtStart(Label* on_not_at_start) { 191911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Did we start the match at the start of the string at all? 192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmpl(Operand(rbp, kStartIndex), Immediate(0)); 193dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org BranchOrBacktrack(not_equal, on_not_at_start); 194911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If we did, are we still at the start of the input? 195895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(rsi, rdi, times_1, 0)); 1967a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rax, Operand(rbp, kInputStart)); 197911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(not_equal, on_not_at_start); 198911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 199911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 200911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 201911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckCharacterLT(uc16 limit, Label* on_less) { 202911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(current_character(), Immediate(limit)); 203911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(less, on_less); 204911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 205911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 206911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 207911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) { 208911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label fallthrough; 209911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(rdi, Operand(backtrack_stackpointer(), 0)); 210bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(not_equal, &fallthrough); 211911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Drop(); 212911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(no_condition, on_equal); 213911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&fallthrough); 214911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 215911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 216911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 217911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckNotBackReferenceIgnoreCase( 218911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int start_reg, 219911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_no_match) { 220911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label fallthrough; 2214edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture 2224edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ReadPositionFromRegister(rbx, start_reg + 1); // Offset of end of capture 223fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rbx, rdx); // Length of capture. 224911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 225911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------- 226911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // rdx = Start offset of capture. 227911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // rbx = Length of capture 228911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 229911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If length is negative, this code will fail (it's a symptom of a partial or 230911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // illegal capture where start of capture after end of capture). 231911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // This must not happen (no back-reference can reference a capture that wasn't 232911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // closed before in the reg-exp, and we must not generate code that can cause 233911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // this condition). 234911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 235911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If length is zero, either the capture is empty or it is nonparticipating. 236911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // In either case succeed immediately. 237911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(equal, &fallthrough); 238911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 2395a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // ----------------------- 2405a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // rdx - Start of capture 2415a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // rbx - length of capture 2425a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org // Check that there are sufficient characters left in the input. 2435a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org __ movl(rax, rdi); 2445a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org __ addl(rax, rbx); 2455a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org BranchOrBacktrack(greater, on_no_match); 2465a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org 2472c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 248911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label loop_increment; 249911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (on_no_match == NULL) { 250911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org on_no_match = &backtrack_label_; 251911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 252911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 253895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(r9, Operand(rsi, rdx, times_1, 0)); 254895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(r11, Operand(rsi, rdi, times_1, 0)); 255fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rbx, r9); // End of capture 256911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // --------------------- 257911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // r11 - current input character address 258911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // r9 - current capture character address 259911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // rbx - end of capture 260911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 261911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label loop; 262911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&loop); 263911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movzxbl(rdx, Operand(r9, 0)); 264911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movzxbl(rax, Operand(r11, 0)); 265911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // al - input character 266911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // dl - capture character 267911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpb(rax, rdx); 268bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(equal, &loop_increment); 269911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 270911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Mismatch, try case-insensitive match (converting letters to lower-case). 271911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // I.e., if or-ing with 0x20 makes values equal and in range 'a'-'z', it's 272911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // a match. 273895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(rax, Immediate(0x20)); // Convert match character to lower-case. 274895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orp(rdx, Immediate(0x20)); // Convert capture character to lower-case. 275911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpb(rax, rdx); 276911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(not_equal, on_no_match); // Definitely not equal. 277911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ subb(rax, Immediate('a')); 278911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpb(rax, Immediate('z' - 'a')); 27959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ j(below_equal, &loop_increment); // In range 'a'-'z'. 28059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Latin-1: Check for values in range [224,254] but not 247. 28159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ subb(rax, Immediate(224 - 'a')); 28259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmpb(rax, Immediate(254 - 224)); 28359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ j(above, on_no_match); // Weren't Latin-1 letters. 28459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmpb(rax, Immediate(247 - 224)); // Check for 247. 28559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ j(equal, on_no_match); 286911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&loop_increment); 287911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Increment pointers into match and capture strings. 288fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(r11, Immediate(1)); 289fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(r9, Immediate(1)); 290911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Compare to end of capture, and loop if not done. 2917a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(r9, rbx); 292911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(below, &loop); 293911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 294911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Compute new value of character position after the matched part. 29543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, r11); 296911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ subq(rdi, rsi); 297911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } else { 298e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ == UC16); 299911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Save important/volatile registers before calling C function. 30096c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifndef _WIN64 301b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Caller save on Linux and callee save in Windows. 302763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rsi); 303763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdi); 304911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 305763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(backtrack_stackpointer()); 306911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 307c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org static const int num_arguments = 4; 308b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ PrepareCallCFunction(num_arguments); 309911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 310911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Put arguments into parameter registers. Parameters are 311911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Address byte_offset1 - Address captured substring's start. 312911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Address byte_offset2 - Address of current character position. 313911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // size_t byte_length - length of capture in bytes(!) 314c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Isolate* isolate 31596c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifdef _WIN64 316911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Compute and set byte_offset1 (start of capture). 317895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rcx, Operand(rsi, rdx, times_1, 0)); 318911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Set byte_offset2. 319895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdx, Operand(rsi, rdi, times_1, 0)); 320911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Set byte_length. 32143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r8, rbx); 322c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Isolate. 32332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ LoadAddress(r9, ExternalReference::isolate_address(isolate())); 324911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#else // AMD64 calling convention 325911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Compute byte_offset2 (current position = rsi+rdi). 326895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(rsi, rdi, times_1, 0)); 327911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Compute and set byte_offset1 (start of capture). 328895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdi, Operand(rsi, rdx, times_1, 0)); 329911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Set byte_offset2. 33043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, rax); 331911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Set byte_length. 33243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, rbx); 333c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Isolate. 33432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ LoadAddress(rcx, ExternalReference::isolate_address(isolate())); 335911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { // NOLINT: Can't find a way to open this scope without confusing the 338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // linter. 339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllowExternalCallThatCantCauseGC scope(&masm_); 340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference compare = 34132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_case_insensitive_compare_uc16(isolate()); 342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallCFunction(compare, num_arguments); 343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 344911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 345911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Restore original values before reacting on result value. 3467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ Move(code_object_pointer(), masm_.CodeObject()); 347763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(backtrack_stackpointer()); 34896c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifndef _WIN64 349763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdi); 350763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rsi); 351911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 352911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 353911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Check if function returned non-zero for success or zero for failure. 3547a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 355911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(zero, on_no_match); 356911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // On success, increment position by length of capture. 357911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Requires that rbx is callee save (true for both Win64 and AMD64 ABIs). 358911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ addq(rdi, rbx); 359911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 360911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&fallthrough); 361911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 362911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 363911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 364911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckNotBackReference( 365911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int start_reg, 366911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_no_match) { 367911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label fallthrough; 368911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 369911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Find length of back-referenced capture. 3704edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ReadPositionFromRegister(rdx, start_reg); // Offset of start of capture 3714edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org ReadPositionFromRegister(rax, start_reg + 1); // Offset of end of capture 372fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rax, rdx); // Length to check. 373911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 374911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Fail on partial or illegal capture (start of capture after end of capture). 375911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // This must not happen (no back-reference can reference a capture that wasn't 376911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // closed before in the reg-exp). 377594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(greater_equal, kInvalidCaptureReferenced); 378911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 379911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Succeed on empty capture (including non-participating capture) 380911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(equal, &fallthrough); 381911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 382911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------- 383911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // rdx - Start of capture 384911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // rax - length of capture 385911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 386911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Check that there are sufficient characters left in the input. 387911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movl(rbx, rdi); 388911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ addl(rbx, rax); 389911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(greater, on_no_match); 390911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 391911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Compute pointers to match string and capture string 392895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rbx, Operand(rsi, rdi, times_1, 0)); // Start of match. 393fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rdx, rsi); // Start of capture. 394895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(r9, Operand(rdx, rax, times_1, 0)); // End of capture 395911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 396911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------- 397911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // rbx - current capture character address. 398911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // rbx - current input character address . 399911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // r9 - end of input to match (capture length after rbx). 400911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 401911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label loop; 402911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&loop); 4032c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 404911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movzxbl(rax, Operand(rdx, 0)); 405911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpb(rax, Operand(rbx, 0)); 406911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } else { 407e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ == UC16); 408911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movzxwl(rax, Operand(rdx, 0)); 409911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpw(rax, Operand(rbx, 0)); 410911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 411911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(not_equal, on_no_match); 412911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Increment pointers into capture and match string. 413fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rbx, Immediate(char_size())); 414fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rdx, Immediate(char_size())); 415911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Check if we have reached end of match area. 4167a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdx, r9); 417911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(below, &loop); 418911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 419911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Success. 420911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Set current character position to position after match. 42143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, rbx); 422911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ subq(rdi, rsi); 423911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 424911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&fallthrough); 425911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 426911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 427911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 428911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckNotCharacter(uint32_t c, 429911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_not_equal) { 430911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(current_character(), Immediate(c)); 431911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(not_equal, on_not_equal); 432911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 433911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 434911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 435911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckCharacterAfterAnd(uint32_t c, 436911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org uint32_t mask, 437911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_equal) { 4387d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org if (c == 0) { 4397d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ testl(current_character(), Immediate(mask)); 4407d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } else { 4417d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ movl(rax, Immediate(mask)); 442895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ andp(rax, current_character()); 4437d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ cmpl(rax, Immediate(c)); 4447d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } 445911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(equal, on_equal); 446911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 447911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 448911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 449911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckNotCharacterAfterAnd(uint32_t c, 450911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org uint32_t mask, 451911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_not_equal) { 4527d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org if (c == 0) { 4537d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ testl(current_character(), Immediate(mask)); 4547d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } else { 4557d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ movl(rax, Immediate(mask)); 456895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ andp(rax, current_character()); 4577d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ cmpl(rax, Immediate(c)); 4587d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org } 459911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(not_equal, on_not_equal); 460911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 461911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 462911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 463911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckNotCharacterAfterMinusAnd( 464911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org uc16 c, 465911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org uc16 minus, 466911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org uc16 mask, 467911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_not_equal) { 468e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(minus < String::kMaxUtf16CodeUnit); 469895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(current_character(), -minus)); 470895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ andp(rax, Immediate(mask)); 471911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(rax, Immediate(c)); 472911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(not_equal, on_not_equal); 473911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 474911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 475911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 4761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerX64::CheckCharacterInRange( 4771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 from, 4781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 to, 4791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_in_range) { 4801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ leal(rax, Operand(current_character(), -from)); 4811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmpl(rax, Immediate(to - from)); 4821456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(below_equal, on_in_range); 4831456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4841456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4851456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4861456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerX64::CheckCharacterNotInRange( 4871456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 from, 4881456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org uc16 to, 4891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_not_in_range) { 4901456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ leal(rax, Operand(current_character(), -from)); 4911456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmpl(rax, Immediate(to - from)); 4921456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(above, on_not_in_range); 4931456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4941456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4951456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4961456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgvoid RegExpMacroAssemblerX64::CheckBitInTable( 4971456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Handle<ByteArray> table, 4981456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Label* on_bit_set) { 4991456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ Move(rax, table); 5001456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Register index = current_character(); 5012c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) { 50243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, current_character()); 503895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ andp(rbx, Immediate(kTableMask)); 5041456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org index = rbx; 5051456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 5061456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org __ cmpb(FieldOperand(rax, index, times_1, ByteArray::kHeaderSize), 5071456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org Immediate(0)); 5081456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org BranchOrBacktrack(not_equal, on_bit_set); 5091456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 5101456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 5111456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 512911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgbool RegExpMacroAssemblerX64::CheckSpecialCharacterClass(uc16 type, 513911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_no_match) { 514911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Range checks (c in min..max) are generally implemented by an unsigned 5150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // (c - min) <= (max - min) check, using the sequence: 516895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org // leap(rax, Operand(current_character(), -min)) or sub(rax, Immediate(min)) 5170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // cmp(rax, Immediate(max - min)) 518911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org switch (type) { 519911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org case 's': 520911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Match space-characters 5212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 5226e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // One byte space characters are '\t'..'\r', ' ' and \u00a0. 523911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label success; 524911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(current_character(), Immediate(' ')); 5256e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ j(equal, &success, Label::kNear); 526911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Check range 0x09..0x0d 527895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(current_character(), -'\t')); 5280c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmpl(rax, Immediate('\r' - '\t')); 5296e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ j(below_equal, &success, Label::kNear); 5306e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // \u00a0 (NBSP). 5316e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org __ cmpl(rax, Immediate(0x00a0 - '\t')); 5326e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org BranchOrBacktrack(not_equal, on_no_match); 533911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&success); 534911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return true; 535911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 536911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return false; 537911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org case 'S': 5386e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org // The emitted code for generic character classes is good enough. 539911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return false; 540911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org case 'd': 541911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Match ASCII digits ('0'..'9') 542895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(current_character(), -'0')); 5430c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmpl(rax, Immediate('9' - '0')); 544911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(above, on_no_match); 545911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return true; 546911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org case 'D': 547911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Match non ASCII-digits 548895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(current_character(), -'0')); 5490c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmpl(rax, Immediate('9' - '0')); 550911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(below_equal, on_no_match); 551911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return true; 552911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org case '.': { 553911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) 5540c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ movl(rax, current_character()); 555895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ xorp(rax, Immediate(0x01)); 556911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 5570c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ subl(rax, Immediate(0x0b)); 5580c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmpl(rax, Immediate(0x0c - 0x0b)); 559911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(below_equal, on_no_match); 560911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (mode_ == UC16) { 561911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Compare original value to 0x2028 and 0x2029, using the already 562911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 563911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 5640c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ subl(rax, Immediate(0x2028 - 0x0b)); 5650c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmpl(rax, Immediate(0x2029 - 0x2028)); 566911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(below_equal, on_no_match); 567911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 568911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return true; 569911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 5700c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'n': { 5710c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029) 5720c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ movl(rax, current_character()); 573895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ xorp(rax, Immediate(0x01)); 5740c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c 5750c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ subl(rax, Immediate(0x0b)); 5760c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmpl(rax, Immediate(0x0c - 0x0b)); 5772c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 5780c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org BranchOrBacktrack(above, on_no_match); 5790c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } else { 5800c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org Label done; 5810c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org BranchOrBacktrack(below_equal, &done); 5820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // Compare original value to 0x2028 and 0x2029, using the already 5830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // computed (current_char ^ 0x01 - 0x0b). I.e., check for 5840c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // 0x201d (0x2028 - 0x0b) or 0x201e. 5850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ subl(rax, Immediate(0x2028 - 0x0b)); 5860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ cmpl(rax, Immediate(0x2029 - 0x2028)); 5870c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org BranchOrBacktrack(above, on_no_match); 5880c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org __ bind(&done); 5890c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 5900c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 5910c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 5920c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'w': { 5932c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1) { 5942c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Table is 256 entries, so all Latin1 characters can be tested. 595b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ cmpl(current_character(), Immediate('z')); 596b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(above, on_no_match); 597b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 598e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(rbx, ExternalReference::re_word_character_map()); 599e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, word_character_map[0]); // Character '\0' is not a word char. 600b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ testb(Operand(rbx, current_character(), times_1, 0), 601b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org current_character()); 602b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(zero, on_no_match); 6030c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 6040c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 6050c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org case 'W': { 606b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org Label done; 6072c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1) { 6082c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Table is 256 entries, so all Latin1 characters can be tested. 609b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ cmpl(current_character(), Immediate('z')); 610bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above, &done); 611b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 612e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(rbx, ExternalReference::re_word_character_map()); 613e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0, word_character_map[0]); // Character '\0' is not a word char. 614b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ testb(Operand(rbx, current_character(), times_1, 0), 615b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org current_character()); 616b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BranchOrBacktrack(not_zero, on_no_match); 6172c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ != LATIN1) { 618b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ bind(&done); 619b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 6200c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org return true; 6210c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org } 622b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 623911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org case '*': 624911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Match any character. 625911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return true; 6260c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org // No custom implementation (yet): s(UC16), S(UC16). 627911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org default: 628911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return false; 629911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 630911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 631911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 632911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 633911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Fail() { 63415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org STATIC_ASSERT(FAILURE == 0); // Return value for failure is zero. 63515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (!global()) { 63615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ Set(rax, FAILURE); 63715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 638911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ jmp(&exit_label_); 639911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 640911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 641911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 64283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.orgHandle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) { 64315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label return_rax; 644911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Finalize code - write the entry point code now we know how many 645911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // registers we need. 646911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Entry code: 647911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&entry_label_); 648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Tell the system that we have a stack frame. Because the type is MANUAL, no 650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // is generated. 651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(&masm_, StackFrame::MANUAL); 652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Actually emit code to start a new stack frame. 654763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbp); 65543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbp, rsp); 656911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Save parameters and callee-save registers. Order here should correspond 657911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // to order of kBackup_ebx etc. 65896c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifdef _WIN64 659911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // MSVC passes arguments in rcx, rdx, r8, r9, with backing stack slots. 660911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Store register parameters in pre-allocated stack slots, 661911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movq(Operand(rbp, kInputString), rcx); 662a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org __ movq(Operand(rbp, kStartIndex), rdx); // Passed as int32 in edx. 663911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movq(Operand(rbp, kInputStart), r8); 664911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movq(Operand(rbp, kInputEnd), r9); 665911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Callee-save on Win64. 666763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rsi); 667763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdi); 668763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbx); 669911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#else 670911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack). 671911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Push register parameters on stack for reference. 672e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kInputString, -1 * kRegisterSize); 673e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kStartIndex, -2 * kRegisterSize); 674e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kInputStart, -3 * kRegisterSize); 675e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kInputEnd, -4 * kRegisterSize); 676e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kRegisterOutput, -5 * kRegisterSize); 677e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(kNumOutputRegisters, -6 * kRegisterSize); 678763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdi); 679763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rsi); 680763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdx); 681763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rcx); 682763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(r8); 683763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(r9); 684763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org 685763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbx); // Callee-save 686911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 687b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 688763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Immediate(0)); // Number of successful matches in a global regexp. 689763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(Immediate(0)); // Make room for "input start - 1" constant. 690911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 691911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Check if we have space on the stack for registers. 692911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label stack_limit_hit; 693911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label stack_ok; 694911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 695c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org ExternalReference stack_limit = 69632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_stack_limit(isolate()); 69743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, rsp); 698e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, stack_limit); 699fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rcx, Operand(kScratchRegister, 0)); 700911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Handle it if the stack pointer is already below the stack limit. 701bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(below_equal, &stack_limit_hit); 702911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Check if there is room for the variable number of registers above 703911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // the stack limit. 7047a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rcx, Immediate(num_registers_ * kPointerSize)); 705bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above_equal, &stack_ok); 706911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Exit with OutOfMemory exception. There is not enough space on the stack 707911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // for our working registers. 708a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ Set(rax, EXCEPTION); 70915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&return_rax); 710911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 711911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&stack_limit_hit); 7127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ Move(code_object_pointer(), masm_.CodeObject()); 713911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp. 7147a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 715911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If returned value is non-zero, we exit with the returned value as result. 71615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(not_zero, &return_rax); 717911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 718911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&stack_ok); 719911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 720911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Allocate space on stack for registers. 721fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rsp, Immediate(num_registers_ * kPointerSize)); 722911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Load string length. 72343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, kInputEnd)); 724911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Load input position. 72543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, Operand(rbp, kInputStart)); 726911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Set up rdi to be negative offset from string end. 7274edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org __ subq(rdi, rsi); 728cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org // Set rax to address of char before start of the string 729911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // (effectively string position -1). 73043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rbp, kStartIndex)); 7317a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ negq(rbx); 732cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org if (mode_ == UC16) { 733895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(rdi, rbx, times_2, -char_size())); 734cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } else { 735895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(rdi, rbx, times_1, -char_size())); 736cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } 737911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Store this value in a local variable, for use when clearing 738911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // position registers. 73943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rbp, kInputStartMinusOne), rax); 740b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 741662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org#if V8_OS_WIN 742911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Ensure that we have written to each stack page, in order. Skipping a page 743911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // on Windows can cause segmentation faults. Assuming page size is 4k. 744911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const int kPageSize = 4096; 745911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const int kRegistersPerPage = kPageSize / kPointerSize; 746911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org for (int i = num_saved_registers_ + kRegistersPerPage - 1; 747911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org i < num_registers_; 748911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org i += kRegistersPerPage) { 74943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(i), rax); // One write every page. 750911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 751662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org#endif // V8_OS_WIN 752911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 753911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Initialize code object pointer. 7547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ Move(code_object_pointer(), masm_.CodeObject()); 75515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 75615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label load_char_start_regexp, start_regexp; 75715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Load newline if index is at start, previous character otherwise. 75815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ cmpl(Operand(rbp, kStartIndex), Immediate(0)); 75915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(not_equal, &load_char_start_regexp, Label::kNear); 760a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ Set(current_character(), '\n'); 76115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&start_regexp, Label::kNear); 76215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 76315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Global regexp restarts matching here. 76415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&load_char_start_regexp); 76515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Load previous char as initial value of current character register. 76615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 76715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&start_regexp); 76815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 76915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Initialize on-stack registers. 77015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (num_saved_registers_ > 0) { 77115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Fill saved registers with initial value = start offset - 1 77215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Fill in stack push order, to avoid accessing across an unwritten 77315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // page (a problem on Windows). 77415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (num_saved_registers_ > 8) { 77515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ Set(rcx, kRegisterZero); 77615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Label init_loop; 77715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&init_loop); 77843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rbp, rcx, times_1, 0), rax); 77915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ subq(rcx, Immediate(kPointerSize)); 78015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ cmpq(rcx, 78115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Immediate(kRegisterZero - num_saved_registers_ * kPointerSize)); 78215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(greater, &init_loop); 78315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } else { // Unroll the loop. 78415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org for (int i = 0; i < num_saved_registers_; i++) { 78543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(i), rax); 78615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 78715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 78815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 78915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 79015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Initialize backtrack stack pointer. 79143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); 792911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 79315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&start_label_); 794911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 795911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Exit code: 796911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (success_label_.is_linked()) { 797911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Save captures when successful. 798911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&success_label_); 799911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (num_saved_registers_ > 0) { 800911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // copy captures to output 80143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, Operand(rbp, kStartIndex)); 80243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rbp, kRegisterOutput)); 80343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rcx, Operand(rbp, kInputEnd)); 804fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rcx, Operand(rbp, kInputStart)); 805cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org if (mode_ == UC16) { 806895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rcx, Operand(rcx, rdx, times_2, 0)); 807cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } else { 808fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rcx, rdx); 809cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } 810911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org for (int i = 0; i < num_saved_registers_; i++) { 8114edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org __ movp(rax, register_location(i)); 812400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (i == 0 && global_with_zero_length_check()) { 81315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Keep capture start in rdx for the zero-length check later. 81443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, rax); 81515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 816fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rax, rcx); // Convert to index from start, not end. 817911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (mode_ == UC16) { 8182f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ sarp(rax, Immediate(1)); // Convert byte index to character index. 819911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 820911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movl(Operand(rbx, i * kIntSize), rax); 821911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 822911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 82315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 82415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (global()) { 82515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Restart matching if the regular expression is flagged as global. 82615613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Increment success counter. 8277a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ incp(Operand(rbp, kSuccessfulCaptures)); 82815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Capture results have been stored, so the number of remaining global 82915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // output registers is reduced by the number of stored captures. 83015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ movsxlq(rcx, Operand(rbp, kNumOutputRegisters)); 831fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rcx, Immediate(num_saved_registers_)); 83215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Check whether we have enough room for another set of capture results. 8337a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rcx, Immediate(num_saved_registers_)); 83415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(less, &exit_label_); 83515613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 83643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rbp, kNumOutputRegisters), rcx); 83715613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Advance the location for output. 838fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(Operand(rbp, kRegisterOutput), 83915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org Immediate(num_saved_registers_ * kIntSize)); 84015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 84115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Prepare rax to initialize registers with its value in the next run. 84243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, kInputStartMinusOne)); 84315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org 844400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (global_with_zero_length_check()) { 845400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Special case for zero-length matches. 846400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // rdx: capture start index 8477a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdi, rdx); 848400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Not a zero-length match, restart. 849400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ j(not_equal, &load_char_start_regexp); 850400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // rdi (offset from the end) is zero if we already reached the end. 8517a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rdi, rdi); 852400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ j(zero, &exit_label_, Label::kNear); 853400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org // Advance current position after a zero-length match. 854400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org if (mode_ == UC16) { 855400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ addq(rdi, Immediate(2)); 856400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org } else { 857400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org __ incq(rdi); 858400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org } 85915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 860400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org 86115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&load_char_start_regexp); 86215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } else { 86343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Immediate(SUCCESS)); 86415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 865911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 866911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 867911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&exit_label_); 86815613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org if (global()) { 86915613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org // Return the number of successful captures. 87043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, kSuccessfulCaptures)); 87115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org } 872911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 87315613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ bind(&return_rax); 87496c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifdef _WIN64 875911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Restore callee save registers. 876895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rsp, Operand(rbp, kLastCalleeSaveRegister)); 877763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbx); 878763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdi); 879763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rsi); 880911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Stack now at rbp. 881911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#else 882911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Restore callee save register. 88343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, Operand(rbp, kBackup_rbx)); 884911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Skip rsp to rbp. 88543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsp, rbp); 886911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 887911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Exit function frame, restore previous one. 888763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 889911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ ret(0); 890911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 891911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Backtrack code (branch target for conditional backtracks). 892911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (backtrack_label_.is_linked()) { 893911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&backtrack_label_); 894911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Backtrack(); 895911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 896911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 897911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label exit_with_exception; 898911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 899911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Preempt-code 900911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (check_preempt_label_.is_linked()) { 901911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org SafeCallTarget(&check_preempt_label_); 902911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 903763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(backtrack_stackpointer()); 904763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdi); 905911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 906911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org CallCheckStackGuardState(); 9077a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 908911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If returning non-zero, we should end execution with the given 909911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // result as return value. 91015613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ j(not_zero, &return_rax); 911911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 912911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Restore registers. 9137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ Move(code_object_pointer(), masm_.CodeObject()); 914763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdi); 915763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(backtrack_stackpointer()); 916911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // String might have moved: Reload esi from frame. 91743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, kInputEnd)); 918911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org SafeReturn(); 919911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 920911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 921911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Backtrack stack overflow code. 922911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (stack_overflow_label_.is_linked()) { 923911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org SafeCallTarget(&stack_overflow_label_); 924911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Reached if the backtrack-stack limit has been hit. 925911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 926911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label grow_failed; 927911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Save registers before calling C function 92896c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifndef _WIN64 929911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Callee-save in Microsoft 64-bit ABI, but not in AMD64 ABI. 930763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rsi); 931763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rdi); 932911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 933911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 934911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Call GrowStack(backtrack_stackpointer()) 935c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org static const int num_arguments = 3; 936b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ PrepareCallCFunction(num_arguments); 93796c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifdef _WIN64 938c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Microsoft passes parameters in rcx, rdx, r8. 939911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // First argument, backtrack stackpointer, is already in rcx. 940895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdx, Operand(rbp, kStackHighEnd)); // Second argument 94132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ LoadAddress(r8, ExternalReference::isolate_address(isolate())); 942911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#else 943c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // AMD64 ABI passes parameters in rdi, rsi, rdx. 94443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdi, backtrack_stackpointer()); // First argument. 945895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rsi, Operand(rbp, kStackHighEnd)); // Second argument. 94632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ LoadAddress(rdx, ExternalReference::isolate_address(isolate())); 947911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 948ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference grow_stack = 94932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_grow_stack(isolate()); 950b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ CallCFunction(grow_stack, num_arguments); 951911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If return NULL, we have failed to grow the stack, and 952911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // must exit with a stack-overflow exception. 9537a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ testp(rax, rax); 954911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(equal, &exit_with_exception); 955911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Otherwise use return value as new stack pointer. 95643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(backtrack_stackpointer(), rax); 957911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Restore saved registers and continue. 9587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org __ Move(code_object_pointer(), masm_.CodeObject()); 95996c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifndef _WIN64 960763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rdi); 961763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rsi); 962911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 963911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org SafeReturn(); 964911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 965911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 966911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (exit_with_exception.is_linked()) { 967911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If any of the code above needed to exit with an exception. 968911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&exit_with_exception); 969911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Exit with Result EXCEPTION(-1) to signal thrown exception. 970a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org __ Set(rax, EXCEPTION); 97115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org __ jmp(&return_rax); 972911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 973911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 974911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org FixupCodeRelativePositions(); 975911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 976911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org CodeDesc code_desc; 9777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org masm_.GetCode(&code_desc); 978c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org Isolate* isolate = this->isolate(); 979ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Code> code = isolate->factory()->NewCode( 980ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org code_desc, Code::ComputeFlags(Code::REGEXP), 9817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org masm_.CodeObject()); 982ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org PROFILE(isolate, RegExpCodeCreateEvent(*code, *source)); 98383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org return Handle<HeapObject>::cast(code); 984911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 985911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 986911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 987911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::GoTo(Label* to) { 988911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(no_condition, to); 989911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 990911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 991911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 992911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::IfRegisterGE(int reg, 993911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int comparand, 994911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* if_ge) { 9957a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(register_location(reg), Immediate(comparand)); 996911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(greater_equal, if_ge); 997911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 998911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 999911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1000911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::IfRegisterLT(int reg, 1001911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int comparand, 1002911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* if_lt) { 10037a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(register_location(reg), Immediate(comparand)); 1004911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(less, if_lt); 1005911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1006911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1007911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1008911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::IfRegisterEqPos(int reg, 1009911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* if_eq) { 10107a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdi, register_location(reg)); 1011911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(equal, if_eq); 1012911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1013911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1014911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1015911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgRegExpMacroAssembler::IrregexpImplementation 1016911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org RegExpMacroAssemblerX64::Implementation() { 1017911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return kX64Implementation; 1018911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1019911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1020911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1021911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::LoadCurrentCharacter(int cp_offset, 1022911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_end_of_input, 1023911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org bool check_bounds, 1024911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int characters) { 1025e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cp_offset >= -1); // ^ and \b can look behind one character. 1026e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 102718ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org if (check_bounds) { 102818ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org CheckPosition(cp_offset + characters - 1, on_end_of_input); 102918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org } 1030911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org LoadCurrentCharacterUnchecked(cp_offset, characters); 1031911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1032911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1033911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1034911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::PopCurrentPosition() { 1035911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Pop(rdi); 1036911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1037911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1038911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1039911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::PopRegister(int register_index) { 1040911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Pop(rax); 104143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(register_index), rax); 1042911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1043911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1044911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1045911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::PushBacktrack(Label* label) { 1046911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Push(label); 1047911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org CheckStackLimit(); 1048911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1049911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1050911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1051911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::PushCurrentPosition() { 1052911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Push(rdi); 1053911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1054911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1055911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1056911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::PushRegister(int register_index, 1057911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org StackCheckFlag check_stack_limit) { 105843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, register_location(register_index)); 1059911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Push(rax); 1060911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (check_stack_limit) CheckStackLimit(); 1061911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1062911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1063911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 10644edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgSTATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size); 10654edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 10664edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 1067911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::ReadCurrentPositionFromRegister(int reg) { 10684edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org if (kPointerSize == kInt64Size) { 10694edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org __ movq(rdi, register_location(reg)); 10704edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org } else { 10714edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org // Need sign extension for x32 as rdi might be used as an index register. 10724edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org __ movsxlq(rdi, register_location(reg)); 10734edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org } 10744edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org} 10754edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 10764edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org 10774edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.orgvoid RegExpMacroAssemblerX64::ReadPositionFromRegister(Register dst, int reg) { 10784edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org if (kPointerSize == kInt64Size) { 10794edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org __ movq(dst, register_location(reg)); 10804edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org } else { 10814edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org // Need sign extension for x32 as dst might be used as an index register. 10824edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org __ movsxlq(dst, register_location(reg)); 10834edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org } 1084911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1085911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1086911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1087911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) { 10884edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org __ movp(backtrack_stackpointer(), register_location(reg)); 1089fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(backtrack_stackpointer(), Operand(rbp, kStackHighEnd)); 1090911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1091911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1092911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 10934a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.orgvoid RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) { 109483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org Label after_position; 10957a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rdi, Immediate(-by * char_size())); 109683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org __ j(greater_equal, &after_position, Label::kNear); 10974a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ movq(rdi, Immediate(-by * char_size())); 10984a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // On RegExp code entry (where this operation is used), the character before 10994a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // the current position is expected to be already loaded. 11004a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org // We have advanced the position, so it's safe to read backwards. 11014a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org LoadCurrentCharacterUnchecked(-1, 1); 11024a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org __ bind(&after_position); 11034a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org} 11044a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 11054a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org 1106911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::SetRegister(int register_index, int to) { 1107e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(register_index >= num_saved_registers_); // Reserved for positions! 110843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(register_index), Immediate(to)); 1109911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1110911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1111911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 111215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.orgbool RegExpMacroAssemblerX64::Succeed() { 1113911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ jmp(&success_label_); 111415613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org return global(); 1115911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1116911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1117911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1118911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::WriteCurrentPositionToRegister(int reg, 1119911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int cp_offset) { 1120911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (cp_offset == 0) { 112143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(reg), rdi); 1122911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } else { 1123895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rax, Operand(rdi, cp_offset * char_size())); 112443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(reg), rax); 1125911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1126911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1127911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1128911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1129911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::ClearRegisters(int reg_from, int reg_to) { 1130e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(reg_from <= reg_to); 113143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, Operand(rbp, kInputStartMinusOne)); 1132911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org for (int reg = reg_from; reg <= reg_to; reg++) { 113343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(reg), rax); 1134911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1135911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1136911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1137911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1138911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) { 113943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rax, backtrack_stackpointer()); 1140fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(rax, Operand(rbp, kStackHighEnd)); 114143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(register_location(reg), rax); 1142911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1143911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1144911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1145911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org// Private methods: 1146911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1147911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CallCheckStackGuardState() { 1148911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // This function call preserves no register values. Caller should 1149911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // store anything volatile in a C call or overwritten by this function. 1150ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org static const int num_arguments = 3; 1151b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ PrepareCallCFunction(num_arguments); 115296c75b57eba103edd76da075b60997bd1faf781eager@chromium.org#ifdef _WIN64 1153911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Second argument: Code* of self. (Do this before overwriting r8). 115443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, code_object_pointer()); 1155911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Third argument: RegExp code frame pointer. 115643c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r8, rbp); 1157911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // First argument: Next address on the stack (will be address of 1158911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // return address). 1159895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rcx, Operand(rsp, -kPointerSize)); 1160911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#else 1161911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Third argument: RegExp code frame pointer. 116243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, rbp); 1163911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Second argument: Code* of self. 116443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, code_object_pointer()); 1165911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // First argument: Next address on the stack (will be address of 1166911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // return address). 1167895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdi, Operand(rsp, -kRegisterSize)); 1168911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 116918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org ExternalReference stack_check = 117032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::re_check_stack_guard_state(isolate()); 1171b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ CallCFunction(stack_check, num_arguments); 1172911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1173911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1174911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1175911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org// Helper function for reading a value out of a stack frame. 1176911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgtemplate <typename T> 1177911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgstatic T& frame_entry(Address re_frame, int frame_offset) { 1178911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset)); 1179911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1180911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1181911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1182911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgint RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address, 1183911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Code* re_code, 1184911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Address re_frame) { 1185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate); 11863ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org StackLimitCheck check(isolate); 11873ee7a7ed19002e4a0efbf6cdb2a201f21763a80adanno@chromium.org if (check.JsHasOverflowed()) { 1188ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->StackOverflow(); 1189911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return EXCEPTION; 1190911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1191911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1192911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If not real stack overflow the stack guard was used to interrupt 1193911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // execution for another purpose. 1194911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1195b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // If this is a direct call from JavaScript retry the RegExp forcing the call 1196b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // through the runtime system. Currently the direct call cannot handle a GC. 1197b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (frame_entry<int>(re_frame, kDirectCall) == 1) { 1198b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org return RETRY; 1199b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 1200b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 1201911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Prepare for possible GC. 12024668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org HandleScope handles(isolate); 1203911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Handle<Code> code_handle(re_code); 1204911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1205911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Handle<String> subject(frame_entry<String*>(re_frame, kInputString)); 12064668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 1207911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Current string. 12082c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org bool is_one_byte = subject->IsOneByteRepresentationUnderneath(); 1209911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1210e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(re_code->instruction_start() <= *return_address); 1211e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(*return_address <= 1212911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org re_code->instruction_start() + re_code->instruction_size()); 1213911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 12143c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org Object* result = isolate->stack_guard()->HandleInterrupts(); 1215911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1216911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (*code_handle != re_code) { // Return address no longer valid 121780c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org intptr_t delta = code_handle->address() - re_code->address(); 1218911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Overwrite the return address on the stack. 1219911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org *return_address += delta; 1220911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1221911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1222911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (result->IsException()) { 1223911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return EXCEPTION; 1224911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1225911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 12264668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org Handle<String> subject_tmp = subject; 12274668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org int slice_offset = 0; 12284668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 12294668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org // Extract the underlying string and the slice offset. 12304668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org if (StringShape(*subject_tmp).IsCons()) { 12314668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first()); 12324668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } else if (StringShape(*subject_tmp).IsSliced()) { 12334668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org SlicedString* slice = SlicedString::cast(*subject_tmp); 12344668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org subject_tmp = Handle<String>(slice->parent()); 12354668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org slice_offset = slice->offset(); 12364668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org } 12374668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org 1238911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // String might have changed. 12392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (subject_tmp->IsOneByteRepresentation() != is_one_byte) { 12402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // If we changed between an Latin1 and an UC16 string, the specialized 1241911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // code cannot be used, and we need to restart regexp matching from 1242911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // scratch (including, potentially, compiling a new version of the code). 1243911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return RETRY; 1244911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1245911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1246911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Otherwise, the content of the string might have moved. It must still 1247911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // be a sequential or external string with the same content. 1248911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Update the start and end pointers in the stack frame to the current 1249911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // location (whether it has actually moved or not). 1250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(StringShape(*subject_tmp).IsSequential() || 12514668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org StringShape(*subject_tmp).IsExternal()); 1252911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1253911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // The original start address of the characters to match. 1254911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart); 1255911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1256911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Find the current start address of the same character at the current string 1257911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // position. 1258911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int start_index = frame_entry<int>(re_frame, kStartIndex); 12594668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org const byte* new_address = StringCharacterPosition(*subject_tmp, 12604668a2c7a746d01b382f23aa32e163701e3075f8ricow@chromium.org start_index + slice_offset); 1261911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1262911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (start_address != new_address) { 1263911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If there is a difference, update the object pointer and start and end 1264911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // addresses in the RegExp stack frame to match the new value. 1265911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org const byte* end_address = frame_entry<const byte* >(re_frame, kInputEnd); 1266c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org int byte_length = static_cast<int>(end_address - start_address); 1267911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org frame_entry<const String*>(re_frame, kInputString) = *subject; 1268911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org frame_entry<const byte*>(re_frame, kInputStart) = new_address; 1269911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length; 1270394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else if (frame_entry<const String*>(re_frame, kInputString) != *subject) { 1271394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Subject string might have been a ConsString that underwent 1272394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // short-circuiting during GC. That will not change start_address but 1273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // will change pointer inside the subject handle. 1274394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com frame_entry<const String*>(re_frame, kInputString) = *subject; 1275911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1276911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1277911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return 0; 1278911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1279911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1280911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1281911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgOperand RegExpMacroAssemblerX64::register_location(int register_index) { 1282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(register_index < (1<<30)); 1283911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (num_registers_ <= register_index) { 1284911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org num_registers_ = register_index + 1; 1285911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1286911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return Operand(rbp, kRegisterZero - register_index * kPointerSize); 1287911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1288911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1289911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1290911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckPosition(int cp_offset, 1291911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* on_outside_input) { 1292911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ cmpl(rdi, Immediate(-cp_offset * char_size())); 1293911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org BranchOrBacktrack(greater_equal, on_outside_input); 1294911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1295911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1296911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1297911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::BranchOrBacktrack(Condition condition, 1298911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label* to) { 1299911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (condition < 0) { // No condition 1300911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (to == NULL) { 1301911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Backtrack(); 1302911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return; 1303911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1304911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ jmp(to); 1305911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return; 1306911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1307911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (to == NULL) { 1308911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(condition, &backtrack_label_); 1309911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org return; 1310911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1311911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ j(condition, to); 1312911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1313911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1314911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1315911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::SafeCall(Label* to) { 1316911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ call(to); 1317911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1318911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1319911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1320911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::SafeCallTarget(Label* label) { 1321911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(label); 1322fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(Operand(rsp, 0), code_object_pointer()); 1323911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1324911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1325911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1326911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::SafeReturn() { 1327fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(Operand(rsp, 0), code_object_pointer()); 1328911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ ret(0); 1329911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1330911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1331911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1332911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Push(Register source) { 1333e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!source.is(backtrack_stackpointer())); 1334911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Notice: This updates flags, unlike normal Push. 1335fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(backtrack_stackpointer(), Immediate(kIntSize)); 1336911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movl(Operand(backtrack_stackpointer(), 0), source); 1337911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1338911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1339911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1340911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Push(Immediate value) { 1341911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Notice: This updates flags, unlike normal Push. 1342fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(backtrack_stackpointer(), Immediate(kIntSize)); 1343911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movl(Operand(backtrack_stackpointer(), 0), value); 1344911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1345911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1346911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1347911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::FixupCodeRelativePositions() { 1348911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org for (int i = 0, n = code_relative_fixup_positions_.length(); i < n; i++) { 1349911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int position = code_relative_fixup_positions_[i]; 1350911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // The position succeeds a relative label offset from position. 1351911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Patch the relative offset to be relative to the Code object pointer 1352911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // instead. 1353911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int patch_position = position - kIntSize; 13547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org int offset = masm_.long_at(patch_position); 13557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org masm_.long_at_put(patch_position, 1356911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org offset 1357911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org + position 1358911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org + Code::kHeaderSize 1359911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org - kHeapObjectTag); 1360911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1361911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org code_relative_fixup_positions_.Clear(); 1362911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1363911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1364911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1365911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Push(Label* backtrack_target) { 1366fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ subp(backtrack_stackpointer(), Immediate(kIntSize)); 1367911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movl(Operand(backtrack_stackpointer(), 0), backtrack_target); 1368911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org MarkPositionForCodeRelativeFixup(); 1369911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1370911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1371911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1372911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Pop(Register target) { 1373e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!target.is(backtrack_stackpointer())); 1374911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movsxlq(target, Operand(backtrack_stackpointer(), 0)); 1375911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Notice: This updates flags, unlike normal Pop. 1376fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(backtrack_stackpointer(), Immediate(kIntSize)); 1377911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1378911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1379911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1380911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::Drop() { 1381fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(backtrack_stackpointer(), Immediate(kIntSize)); 1382911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1383911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1384911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1385911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckPreemption() { 1386911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Check for preemption. 1387911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Label no_preempt; 1388c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org ExternalReference stack_limit = 138932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_stack_limit(isolate()); 1390c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org __ load_rax(stack_limit); 13917a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(rsp, rax); 1392bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above, &no_preempt); 1393911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1394911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org SafeCall(&check_preempt_label_); 1395911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1396911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ bind(&no_preempt); 1397911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1398911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1399911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1400911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::CheckStackLimit() { 14013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label no_stack_overflow; 14023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org ExternalReference stack_limit = 140332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::address_of_regexp_stack_limit(isolate()); 14043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ load_rax(stack_limit); 14057a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ cmpp(backtrack_stackpointer(), rax); 1406bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ j(above, &no_stack_overflow); 1407911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 14083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org SafeCall(&stack_overflow_label_); 1409911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 14103811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ bind(&no_stack_overflow); 1411911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1412911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1413911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1414911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgvoid RegExpMacroAssemblerX64::LoadCurrentCharacterUnchecked(int cp_offset, 1415911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org int characters) { 14162c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org if (mode_ == LATIN1) { 1417911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (characters == 4) { 1418911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); 1419911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } else if (characters == 2) { 1420911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movzxwl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); 1421911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } else { 1422e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(characters == 1); 1423911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movzxbl(current_character(), Operand(rsi, rdi, times_1, cp_offset)); 1424911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1425911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } else { 1426e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(mode_ == UC16); 1427911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (characters == 2) { 1428911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movl(current_character(), 1429911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); 1430911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } else { 1431e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(characters == 1); 1432911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movzxwl(current_character(), 1433911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org Operand(rsi, rdi, times_1, cp_offset * sizeof(uc16))); 1434911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1435911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 1436911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 1437911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1438911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#undef __ 143918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1440c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#endif // V8_INTERPRETED_REGEXP 144118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org 1442911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org}} // namespace v8::internal 14439dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 14449dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 1445