v8  3.11.10(node0.8.26)
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);
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:172
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:171
virtual void ReadStackPointerFromRegister(int reg)
RegExpMacroAssemblerX64(Mode mode, int registers_to_save, Zone *zone)
const int kPointerSize
Definition: globals.h:234
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:273
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)
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)
FlagType type() const
Definition: flags.cc:1358
virtual void CheckNotCharacterAfterAnd(uint32_t c, uint32_t mask, Label *on_not_equal)