v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
regexp-macro-assembler-x64.h
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
29 #define V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
30 
31 #include "x64/assembler-x64.h"
32 #include "x64/assembler-x64-inl.h"
33 #include "macro-assembler.h"
34 #include "code.h"
36 
37 namespace v8 {
38 namespace internal {
39 
40 #ifndef V8_INTERPRETED_REGEXP
41 
43  public:
44  RegExpMacroAssemblerX64(Mode mode, int registers_to_save, Zone* zone);
45  virtual ~RegExpMacroAssemblerX64();
46  virtual int stack_limit_slack();
47  virtual void AdvanceCurrentPosition(int by);
48  virtual void AdvanceRegister(int reg, int by);
49  virtual void Backtrack();
50  virtual void Bind(Label* label);
51  virtual void CheckAtStart(Label* on_at_start);
52  virtual void CheckCharacter(uint32_t c, Label* on_equal);
53  virtual void CheckCharacterAfterAnd(uint32_t c,
54  uint32_t mask,
55  Label* on_equal);
56  virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
57  virtual void CheckCharacterLT(uc16 limit, Label* on_less);
58  // A "greedy loop" is a loop that is both greedy and with a simple
59  // body. It has a particularly simple implementation.
60  virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
61  virtual void CheckNotAtStart(Label* on_not_at_start);
62  virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
63  virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
64  Label* on_no_match);
65  virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal);
66  virtual void CheckNotCharacterAfterAnd(uint32_t c,
67  uint32_t mask,
68  Label* on_not_equal);
69  virtual void CheckNotCharacterAfterMinusAnd(uc16 c,
70  uc16 minus,
71  uc16 mask,
72  Label* on_not_equal);
73  virtual void CheckCharacterInRange(uc16 from,
74  uc16 to,
75  Label* on_in_range);
76  virtual void CheckCharacterNotInRange(uc16 from,
77  uc16 to,
78  Label* on_not_in_range);
79  virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set);
80 
81  // Checks whether the given offset from the current position is before
82  // the end of the string.
83  virtual void CheckPosition(int cp_offset, Label* on_outside_input);
84  virtual bool CheckSpecialCharacterClass(uc16 type,
85  Label* on_no_match);
86  virtual void Fail();
88  virtual void GoTo(Label* label);
89  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
90  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
91  virtual void IfRegisterEqPos(int reg, Label* if_eq);
93  virtual void LoadCurrentCharacter(int cp_offset,
94  Label* on_end_of_input,
95  bool check_bounds = true,
96  int characters = 1);
97  virtual void PopCurrentPosition();
98  virtual void PopRegister(int register_index);
99  virtual void PushBacktrack(Label* label);
100  virtual void PushCurrentPosition();
101  virtual void PushRegister(int register_index,
102  StackCheckFlag check_stack_limit);
103  virtual void ReadCurrentPositionFromRegister(int reg);
104  virtual void ReadStackPointerFromRegister(int reg);
105  virtual void SetCurrentPositionFromEnd(int by);
106  virtual void SetRegister(int register_index, int to);
107  virtual bool Succeed();
108  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
109  virtual void ClearRegisters(int reg_from, int reg_to);
110  virtual void WriteStackPointerToRegister(int reg);
111 
112  static Result Match(Handle<Code> regexp,
113  Handle<String> subject,
114  int* offsets_vector,
115  int offsets_vector_length,
116  int previous_index,
117  Isolate* isolate);
118 
119  static Result Execute(Code* code,
120  String* input,
121  int start_offset,
122  const byte* input_start,
123  const byte* input_end,
124  int* output,
125  bool at_start);
126 
127  // Called from RegExp if the stack-guard is triggered.
128  // If the code object is relocated, the return address is fixed before
129  // returning.
130  static int CheckStackGuardState(Address* return_address,
131  Code* re_code,
132  Address re_frame);
133 
134  private:
135  // Offsets from rbp of function parameters and stored registers.
136  static const int kFramePointer = 0;
137  // Above the frame pointer - function parameters and return address.
138  static const int kReturn_eip = kFramePointer + kPointerSize;
139  static const int kFrameAlign = kReturn_eip + kPointerSize;
140 
141 #ifdef _WIN64
142  // Parameters (first four passed as registers, but with room on stack).
143  // In Microsoft 64-bit Calling Convention, there is room on the callers
144  // stack (before the return address) to spill parameter registers. We
145  // use this space to store the register passed parameters.
146  static const int kInputString = kFrameAlign;
147  // StartIndex is passed as 32 bit int.
148  static const int kStartIndex = kInputString + kPointerSize;
149  static const int kInputStart = kStartIndex + kPointerSize;
150  static const int kInputEnd = kInputStart + kPointerSize;
151  static const int kRegisterOutput = kInputEnd + kPointerSize;
152  // For the case of global regular expression, we have room to store at least
153  // one set of capture results. For the case of non-global regexp, we ignore
154  // this value. NumOutputRegisters is passed as 32-bit value. The upper
155  // 32 bit of this 64-bit stack slot may contain garbage.
156  static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
157  static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
158  // DirectCall is passed as 32 bit int (values 0 or 1).
159  static const int kDirectCall = kStackHighEnd + kPointerSize;
160  static const int kIsolate = kDirectCall + kPointerSize;
161 #else
162  // In AMD64 ABI Calling Convention, the first six integer parameters
163  // are passed as registers, and caller must allocate space on the stack
164  // if it wants them stored. We push the parameters after the frame pointer.
165  static const int kInputString = kFramePointer - kPointerSize;
166  static const int kStartIndex = kInputString - kPointerSize;
167  static const int kInputStart = kStartIndex - kPointerSize;
168  static const int kInputEnd = kInputStart - kPointerSize;
169  static const int kRegisterOutput = kInputEnd - kPointerSize;
170  // For the case of global regular expression, we have room to store at least
171  // one set of capture results. For the case of non-global regexp, we ignore
172  // this value.
173  static const int kNumOutputRegisters = kRegisterOutput - kPointerSize;
174  static const int kStackHighEnd = kFrameAlign;
175  static const int kDirectCall = kStackHighEnd + kPointerSize;
176  static const int kIsolate = kDirectCall + kPointerSize;
177 #endif
178 
179 #ifdef _WIN64
180  // Microsoft calling convention has three callee-saved registers
181  // (that we are using). We push these after the frame pointer.
182  static const int kBackup_rsi = kFramePointer - kPointerSize;
183  static const int kBackup_rdi = kBackup_rsi - kPointerSize;
184  static const int kBackup_rbx = kBackup_rdi - kPointerSize;
185  static const int kLastCalleeSaveRegister = kBackup_rbx;
186 #else
187  // AMD64 Calling Convention has only one callee-save register that
188  // we use. We push this after the frame pointer (and after the
189  // parameters).
190  static const int kBackup_rbx = kNumOutputRegisters - kPointerSize;
191  static const int kLastCalleeSaveRegister = kBackup_rbx;
192 #endif
193 
194  static const int kSuccessfulCaptures = kLastCalleeSaveRegister - kPointerSize;
195  // When adding local variables remember to push space for them in
196  // the frame in GetCode.
197  static const int kInputStartMinusOne = kSuccessfulCaptures - kPointerSize;
198 
199  // First register address. Following registers are below it on the stack.
200  static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
201 
202  // Initial size of code buffer.
203  static const size_t kRegExpCodeSize = 1024;
204 
205  // Load a number of characters at the given offset from the
206  // current position, into the current-character register.
207  void LoadCurrentCharacterUnchecked(int cp_offset, int character_count);
208 
209  // Check whether preemption has been requested.
210  void CheckPreemption();
211 
212  // Check whether we are exceeding the stack limit on the backtrack stack.
213  void CheckStackLimit();
214 
215  // Generate a call to CheckStackGuardState.
216  void CallCheckStackGuardState();
217 
218  // The rbp-relative location of a regexp register.
219  Operand register_location(int register_index);
220 
221  // The register containing the current character after LoadCurrentCharacter.
222  inline Register current_character() { return rdx; }
223 
224  // The register containing the backtrack stack top. Provides a meaningful
225  // name to the register.
226  inline Register backtrack_stackpointer() { return rcx; }
227 
228  // The registers containing a self pointer to this code's Code object.
229  inline Register code_object_pointer() { return r8; }
230 
231  // Byte size of chars in the string to match (decided by the Mode argument)
232  inline int char_size() { return static_cast<int>(mode_); }
233 
234  // Equivalent to a conditional branch to the label, unless the label
235  // is NULL, in which case it is a conditional Backtrack.
236  void BranchOrBacktrack(Condition condition, Label* to);
237 
238  void MarkPositionForCodeRelativeFixup() {
239  code_relative_fixup_positions_.Add(masm_.pc_offset(), zone());
240  }
241 
242  void FixupCodeRelativePositions();
243 
244  // Call and return internally in the generated code in a way that
245  // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
246  inline void SafeCall(Label* to);
247  inline void SafeCallTarget(Label* label);
248  inline void SafeReturn();
249 
250  // Pushes the value of a register on the backtrack stack. Decrements the
251  // stack pointer (rcx) by a word size and stores the register's value there.
252  inline void Push(Register source);
253 
254  // Pushes a value on the backtrack stack. Decrements the stack pointer (rcx)
255  // by a word size and stores the value there.
256  inline void Push(Immediate value);
257 
258  // Pushes the Code object relative offset of a label on the backtrack stack
259  // (i.e., a backtrack target). Decrements the stack pointer (rcx)
260  // by a word size and stores the value there.
261  inline void Push(Label* label);
262 
263  // Pops a value from the backtrack stack. Reads the word at the stack pointer
264  // (rcx) and increments it by a word size.
265  inline void Pop(Register target);
266 
267  // Drops the top value from the backtrack stack without reading it.
268  // Increments the stack pointer (rcx) by a word size.
269  inline void Drop();
270 
271  Isolate* isolate() const { return masm_.isolate(); }
272 
273  MacroAssembler masm_;
274  MacroAssembler::NoRootArrayScope no_root_array_scope_;
275 
276  ZoneList<int> code_relative_fixup_positions_;
277 
278  // Which mode to generate code for (ASCII or UC16).
279  Mode mode_;
280 
281  // One greater than maximal register index actually used.
282  int num_registers_;
283 
284  // Number of registers to output at the end (the saved registers
285  // are always 0..num_saved_registers_-1)
286  int num_saved_registers_;
287 
288  // Labels used internally.
289  Label entry_label_;
290  Label start_label_;
291  Label success_label_;
292  Label backtrack_label_;
293  Label exit_label_;
294  Label check_preempt_label_;
295  Label stack_overflow_label_;
296 };
297 
298 #endif // V8_INTERPRETED_REGEXP
299 
300 }} // namespace v8::internal
301 
302 #endif // V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
byte * Address
Definition: globals.h:186
const Register rdx
virtual void CheckAtStart(Label *on_at_start)
static Result Execute(Code *code, String *input, int start_offset, const byte *input_start, const byte *input_end, int *output, bool at_start)
Isolate * isolate() const
Definition: assembler.h:62
virtual void IfRegisterLT(int reg, int comparand, Label *if_lt)
virtual void ReadCurrentPositionFromRegister(int reg)
virtual void SetCurrentPositionFromEnd(int by)
virtual void IfRegisterGE(int reg, int comparand, Label *if_ge)
virtual bool CheckSpecialCharacterClass(uc16 type, Label *on_no_match)
virtual void LoadCurrentCharacter(int cp_offset, Label *on_end_of_input, bool check_bounds=true, int characters=1)
virtual void CheckNotCharacterAfterMinusAnd(uc16 c, uc16 minus, uc16 mask, Label *on_not_equal)
virtual void Bind(Label *label)
virtual void CheckGreedyLoop(Label *on_tos_equals_current_position)
virtual Handle< HeapObject > GetCode(Handle< String > source)
uint8_t byte
Definition: globals.h:185
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
virtual void ReadStackPointerFromRegister(int reg)
RegExpMacroAssemblerX64(Mode mode, int registers_to_save, Zone *zone)
const int kPointerSize
Definition: globals.h:268
virtual void PopRegister(int register_index)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
virtual void CheckNotCharacter(uint32_t c, Label *on_not_equal)
virtual IrregexpImplementation Implementation()
virtual void CheckCharacterAfterAnd(uint32_t c, uint32_t mask, Label *on_equal)
virtual void CheckNotBackReference(int start_reg, Label *on_no_match)
virtual void CheckNotAtStart(Label *on_not_at_start)
virtual void CheckCharacter(uint32_t c, Label *on_equal)
virtual void WriteStackPointerToRegister(int reg)
virtual void GoTo(Label *label)
virtual void SetRegister(int register_index, int to)
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset)
static Result Match(Handle< Code > regexp, Handle< String > subject, int *offsets_vector, int offsets_vector_length, int previous_index, Isolate *isolate)
virtual void CheckCharacterInRange(uc16 from, uc16 to, Label *on_in_range)
virtual void CheckNotBackReferenceIgnoreCase(int start_reg, Label *on_no_match)
virtual void AdvanceCurrentPosition(int by)
virtual void PushRegister(int register_index, StackCheckFlag check_stack_limit)
virtual void CheckCharacterNotInRange(uc16 from, uc16 to, Label *on_not_in_range)
uint16_t uc16
Definition: globals.h:309
const Register r8
const Register rcx
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:39
virtual void IfRegisterEqPos(int reg, Label *if_eq)
virtual void AdvanceRegister(int reg, int by)
virtual void CheckBitInTable(Handle< ByteArray > table, Label *on_bit_set)
virtual void ClearRegisters(int reg_from, int reg_to)
virtual void PushBacktrack(Label *label)
static int CheckStackGuardState(Address *return_address, Code *re_code, Address re_frame)
virtual void CheckPosition(int cp_offset, Label *on_outside_input)
virtual void CheckCharacterGT(uc16 limit, Label *on_greater)
virtual void CheckCharacterLT(uc16 limit, Label *on_less)
virtual void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, Label *on_not_equal)