v8  3.14.5(node0.10.28)
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  virtual void CheckCharacters(Vector<const uc16> str,
59  int cp_offset,
60  Label* on_failure,
61  bool check_end_of_string);
62  // A "greedy loop" is a loop that is both greedy and with a simple
63  // body. It has a particularly simple implementation.
64  virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
65  virtual void CheckNotAtStart(Label* on_not_at_start);
66  virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
67  virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
68  Label* on_no_match);
69  virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal);
70  virtual void CheckNotCharacterAfterAnd(uint32_t c,
71  uint32_t mask,
72  Label* on_not_equal);
73  virtual void CheckNotCharacterAfterMinusAnd(uc16 c,
74  uc16 minus,
75  uc16 mask,
76  Label* on_not_equal);
77  virtual void CheckCharacterInRange(uc16 from,
78  uc16 to,
79  Label* on_in_range);
80  virtual void CheckCharacterNotInRange(uc16 from,
81  uc16 to,
82  Label* on_not_in_range);
83  virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set);
84 
85  // Checks whether the given offset from the current position is before
86  // the end of the string.
87  virtual void CheckPosition(int cp_offset, Label* on_outside_input);
88  virtual bool CheckSpecialCharacterClass(uc16 type,
89  Label* on_no_match);
90  virtual void Fail();
92  virtual void GoTo(Label* label);
93  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
94  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
95  virtual void IfRegisterEqPos(int reg, Label* if_eq);
97  virtual void LoadCurrentCharacter(int cp_offset,
98  Label* on_end_of_input,
99  bool check_bounds = true,
100  int characters = 1);
101  virtual void PopCurrentPosition();
102  virtual void PopRegister(int register_index);
103  virtual void PushBacktrack(Label* label);
104  virtual void PushCurrentPosition();
105  virtual void PushRegister(int register_index,
106  StackCheckFlag check_stack_limit);
107  virtual void ReadCurrentPositionFromRegister(int reg);
108  virtual void ReadStackPointerFromRegister(int reg);
109  virtual void SetCurrentPositionFromEnd(int by);
110  virtual void SetRegister(int register_index, int to);
111  virtual bool Succeed();
112  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
113  virtual void ClearRegisters(int reg_from, int reg_to);
114  virtual void WriteStackPointerToRegister(int reg);
115 
116  static Result Match(Handle<Code> regexp,
117  Handle<String> subject,
118  int* offsets_vector,
119  int offsets_vector_length,
120  int previous_index,
121  Isolate* isolate);
122 
123  static Result Execute(Code* code,
124  String* input,
125  int start_offset,
126  const byte* input_start,
127  const byte* input_end,
128  int* output,
129  bool at_start);
130 
131  // Called from RegExp if the stack-guard is triggered.
132  // If the code object is relocated, the return address is fixed before
133  // returning.
134  static int CheckStackGuardState(Address* return_address,
135  Code* re_code,
136  Address re_frame);
137 
138  private:
139  // Offsets from rbp of function parameters and stored registers.
140  static const int kFramePointer = 0;
141  // Above the frame pointer - function parameters and return address.
142  static const int kReturn_eip = kFramePointer + kPointerSize;
143  static const int kFrameAlign = kReturn_eip + kPointerSize;
144 
145 #ifdef _WIN64
146  // Parameters (first four passed as registers, but with room on stack).
147  // In Microsoft 64-bit Calling Convention, there is room on the callers
148  // stack (before the return address) to spill parameter registers. We
149  // use this space to store the register passed parameters.
150  static const int kInputString = kFrameAlign;
151  // StartIndex is passed as 32 bit int.
152  static const int kStartIndex = kInputString + kPointerSize;
153  static const int kInputStart = kStartIndex + kPointerSize;
154  static const int kInputEnd = kInputStart + kPointerSize;
155  static const int kRegisterOutput = kInputEnd + kPointerSize;
156  // For the case of global regular expression, we have room to store at least
157  // one set of capture results. For the case of non-global regexp, we ignore
158  // this value. NumOutputRegisters is passed as 32-bit value. The upper
159  // 32 bit of this 64-bit stack slot may contain garbage.
160  static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
161  static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
162  // DirectCall is passed as 32 bit int (values 0 or 1).
163  static const int kDirectCall = kStackHighEnd + kPointerSize;
164  static const int kIsolate = kDirectCall + kPointerSize;
165 #else
166  // In AMD64 ABI Calling Convention, the first six integer parameters
167  // are passed as registers, and caller must allocate space on the stack
168  // if it wants them stored. We push the parameters after the frame pointer.
169  static const int kInputString = kFramePointer - kPointerSize;
170  static const int kStartIndex = kInputString - kPointerSize;
171  static const int kInputStart = kStartIndex - kPointerSize;
172  static const int kInputEnd = kInputStart - kPointerSize;
173  static const int kRegisterOutput = kInputEnd - kPointerSize;
174  // For the case of global regular expression, we have room to store at least
175  // one set of capture results. For the case of non-global regexp, we ignore
176  // this value.
177  static const int kNumOutputRegisters = kRegisterOutput - kPointerSize;
178  static const int kStackHighEnd = kFrameAlign;
179  static const int kDirectCall = kStackHighEnd + kPointerSize;
180  static const int kIsolate = kDirectCall + kPointerSize;
181 #endif
182 
183 #ifdef _WIN64
184  // Microsoft calling convention has three callee-saved registers
185  // (that we are using). We push these after the frame pointer.
186  static const int kBackup_rsi = kFramePointer - kPointerSize;
187  static const int kBackup_rdi = kBackup_rsi - kPointerSize;
188  static const int kBackup_rbx = kBackup_rdi - kPointerSize;
189  static const int kLastCalleeSaveRegister = kBackup_rbx;
190 #else
191  // AMD64 Calling Convention has only one callee-save register that
192  // we use. We push this after the frame pointer (and after the
193  // parameters).
194  static const int kBackup_rbx = kNumOutputRegisters - kPointerSize;
195  static const int kLastCalleeSaveRegister = kBackup_rbx;
196 #endif
197 
198  static const int kSuccessfulCaptures = kLastCalleeSaveRegister - kPointerSize;
199  // When adding local variables remember to push space for them in
200  // the frame in GetCode.
201  static const int kInputStartMinusOne = kSuccessfulCaptures - kPointerSize;
202 
203  // First register address. Following registers are below it on the stack.
204  static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
205 
206  // Initial size of code buffer.
207  static const size_t kRegExpCodeSize = 1024;
208 
209  // Load a number of characters at the given offset from the
210  // current position, into the current-character register.
211  void LoadCurrentCharacterUnchecked(int cp_offset, int character_count);
212 
213  // Check whether preemption has been requested.
214  void CheckPreemption();
215 
216  // Check whether we are exceeding the stack limit on the backtrack stack.
217  void CheckStackLimit();
218 
219  // Generate a call to CheckStackGuardState.
220  void CallCheckStackGuardState();
221 
222  // The rbp-relative location of a regexp register.
223  Operand register_location(int register_index);
224 
225  // The register containing the current character after LoadCurrentCharacter.
226  inline Register current_character() { return rdx; }
227 
228  // The register containing the backtrack stack top. Provides a meaningful
229  // name to the register.
230  inline Register backtrack_stackpointer() { return rcx; }
231 
232  // The registers containing a self pointer to this code's Code object.
233  inline Register code_object_pointer() { return r8; }
234 
235  // Byte size of chars in the string to match (decided by the Mode argument)
236  inline int char_size() { return static_cast<int>(mode_); }
237 
238  // Equivalent to a conditional branch to the label, unless the label
239  // is NULL, in which case it is a conditional Backtrack.
240  void BranchOrBacktrack(Condition condition, Label* to);
241 
242  void MarkPositionForCodeRelativeFixup() {
243  code_relative_fixup_positions_.Add(masm_.pc_offset(), zone());
244  }
245 
246  void FixupCodeRelativePositions();
247 
248  // Call and return internally in the generated code in a way that
249  // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
250  inline void SafeCall(Label* to);
251  inline void SafeCallTarget(Label* label);
252  inline void SafeReturn();
253 
254  // Pushes the value of a register on the backtrack stack. Decrements the
255  // stack pointer (rcx) by a word size and stores the register's value there.
256  inline void Push(Register source);
257 
258  // Pushes a value on the backtrack stack. Decrements the stack pointer (rcx)
259  // by a word size and stores the value there.
260  inline void Push(Immediate value);
261 
262  // Pushes the Code object relative offset of a label on the backtrack stack
263  // (i.e., a backtrack target). Decrements the stack pointer (rcx)
264  // by a word size and stores the value there.
265  inline void Push(Label* label);
266 
267  // Pops a value from the backtrack stack. Reads the word at the stack pointer
268  // (rcx) and increments it by a word size.
269  inline void Pop(Register target);
270 
271  // Drops the top value from the backtrack stack without reading it.
272  // Increments the stack pointer (rcx) by a word size.
273  inline void Drop();
274 
275  MacroAssembler masm_;
276  MacroAssembler::NoRootArrayScope no_root_array_scope_;
277 
278  ZoneList<int> code_relative_fixup_positions_;
279 
280  // Which mode to generate code for (ASCII or UC16).
281  Mode mode_;
282 
283  // One greater than maximal register index actually used.
284  int num_registers_;
285 
286  // Number of registers to output at the end (the saved registers
287  // are always 0..num_saved_registers_-1)
288  int num_saved_registers_;
289 
290  // Labels used internally.
291  Label entry_label_;
292  Label start_label_;
293  Label success_label_;
294  Label backtrack_label_;
295  Label exit_label_;
296  Label check_preempt_label_;
297  Label stack_overflow_label_;
298 };
299 
300 #endif // V8_INTERPRETED_REGEXP
301 
302 }} // namespace v8::internal
303 
304 #endif // V8_X64_REGEXP_MACRO_ASSEMBLER_X64_H_
byte * Address
Definition: globals.h:157
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)
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:156
virtual void ReadStackPointerFromRegister(int reg)
RegExpMacroAssemblerX64(Mode mode, int registers_to_save, Zone *zone)
const int kPointerSize
Definition: globals.h:220
virtual void PopRegister(int register_index)
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:259
const Register r8
const Register rcx
virtual void CheckCharacters(Vector< const uc16 > str, int cp_offset, Label *on_failure, bool check_end_of_string)
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:38
virtual void IfRegisterEqPos(int reg, Label *if_eq)
virtual void AdvanceRegister(int reg, int by)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
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)