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-arm64.h
Go to the documentation of this file.
1 // Copyright 2013 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_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
29 #define V8_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
30 
31 #include "arm64/assembler-arm64.h"
33 #include "macro-assembler.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 
39 #ifndef V8_INTERPRETED_REGEXP
41  public:
42  RegExpMacroAssemblerARM64(Mode mode, int registers_to_save, Zone* zone);
44  virtual int stack_limit_slack();
45  virtual void AdvanceCurrentPosition(int by);
46  virtual void AdvanceRegister(int reg, int by);
47  virtual void Backtrack();
48  virtual void Bind(Label* label);
49  virtual void CheckAtStart(Label* on_at_start);
50  virtual void CheckCharacter(unsigned c, Label* on_equal);
51  virtual void CheckCharacterAfterAnd(unsigned c,
52  unsigned mask,
53  Label* on_equal);
54  virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
55  virtual void CheckCharacterLT(uc16 limit, Label* on_less);
56  virtual void CheckCharacters(Vector<const uc16> str,
57  int cp_offset,
58  Label* on_failure,
59  bool check_end_of_string);
60  // A "greedy loop" is a loop that is both greedy and with a simple
61  // body. It has a particularly simple implementation.
62  virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
63  virtual void CheckNotAtStart(Label* on_not_at_start);
64  virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
65  virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
66  Label* on_no_match);
67  virtual void CheckNotCharacter(unsigned c, Label* on_not_equal);
68  virtual void CheckNotCharacterAfterAnd(unsigned c,
69  unsigned mask,
70  Label* on_not_equal);
71  virtual void CheckNotCharacterAfterMinusAnd(uc16 c,
72  uc16 minus,
73  uc16 mask,
74  Label* on_not_equal);
75  virtual void CheckCharacterInRange(uc16 from,
76  uc16 to,
77  Label* on_in_range);
78  virtual void CheckCharacterNotInRange(uc16 from,
79  uc16 to,
80  Label* on_not_in_range);
81  virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set);
82 
83  // Checks whether the given offset from the current position is before
84  // the end of the string.
85  virtual void CheckPosition(int cp_offset, Label* on_outside_input);
86  virtual bool CheckSpecialCharacterClass(uc16 type,
87  Label* on_no_match);
88  virtual void Fail();
90  virtual void GoTo(Label* label);
91  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
92  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
93  virtual void IfRegisterEqPos(int reg, Label* if_eq);
95  virtual void LoadCurrentCharacter(int cp_offset,
96  Label* on_end_of_input,
97  bool check_bounds = true,
98  int characters = 1);
99  virtual void PopCurrentPosition();
100  virtual void PopRegister(int register_index);
101  virtual void PushBacktrack(Label* label);
102  virtual void PushCurrentPosition();
103  virtual void PushRegister(int register_index,
104  StackCheckFlag check_stack_limit);
105  virtual void ReadCurrentPositionFromRegister(int reg);
106  virtual void ReadStackPointerFromRegister(int reg);
107  virtual void SetCurrentPositionFromEnd(int by);
108  virtual void SetRegister(int register_index, int to);
109  virtual bool Succeed();
110  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
111  virtual void ClearRegisters(int reg_from, int reg_to);
112  virtual void WriteStackPointerToRegister(int reg);
113  virtual bool CanReadUnaligned();
114 
115  // Called from RegExp if the stack-guard is triggered.
116  // If the code object is relocated, the return address is fixed before
117  // returning.
118  static int CheckStackGuardState(Address* return_address,
119  Code* re_code,
120  Address re_frame,
121  int start_offset,
122  const byte** input_start,
123  const byte** input_end);
124 
125  private:
126  // Above the frame pointer - Stored registers and stack passed parameters.
127  // Callee-saved registers x19-x29, where x29 is the old frame pointer.
128  static const int kCalleeSavedRegisters = 0;
129  // Return address.
130  // It is placed above the 11 callee-saved registers.
131  static const int kReturnAddress = kCalleeSavedRegisters + 11 * kPointerSize;
132  static const int kSecondaryReturnAddress = kReturnAddress + kPointerSize;
133  // Stack parameter placed by caller.
134  static const int kIsolate = kSecondaryReturnAddress + kPointerSize;
135 
136  // Below the frame pointer.
137  // Register parameters stored by setup code.
138  static const int kDirectCall = kCalleeSavedRegisters - kPointerSize;
139  static const int kStackBase = kDirectCall - kPointerSize;
140  static const int kOutputSize = kStackBase - kPointerSize;
141  static const int kInput = kOutputSize - kPointerSize;
142  // When adding local variables remember to push space for them in
143  // the frame in GetCode.
144  static const int kSuccessCounter = kInput - kPointerSize;
145  // First position register address on the stack. Following positions are
146  // below it. A position is a 32 bit value.
147  static const int kFirstRegisterOnStack = kSuccessCounter - kWRegSize;
148  // A capture is a 64 bit value holding two position.
149  static const int kFirstCaptureOnStack = kSuccessCounter - kXRegSize;
150 
151  // Initial size of code buffer.
152  static const size_t kRegExpCodeSize = 1024;
153 
154  // When initializing registers to a non-position value we can unroll
155  // the loop. Set the limit of registers to unroll.
156  static const int kNumRegistersToUnroll = 16;
157 
158  // We are using x0 to x7 as a register cache. Each hardware register must
159  // contain one capture, that is two 32 bit registers. We can cache at most
160  // 16 registers.
161  static const int kNumCachedRegisters = 16;
162 
163  // Load a number of characters at the given offset from the
164  // current position, into the current-character register.
165  void LoadCurrentCharacterUnchecked(int cp_offset, int character_count);
166 
167  // Check whether preemption has been requested.
168  void CheckPreemption();
169 
170  // Check whether we are exceeding the stack limit on the backtrack stack.
171  void CheckStackLimit();
172 
173  // Generate a call to CheckStackGuardState.
174  void CallCheckStackGuardState(Register scratch);
175 
176  // Location of a 32 bit position register.
177  MemOperand register_location(int register_index);
178 
179  // Location of a 64 bit capture, combining two position registers.
180  MemOperand capture_location(int register_index, Register scratch);
181 
182  // Register holding the current input position as negative offset from
183  // the end of the string.
184  Register current_input_offset() { return w21; }
185 
186  // The register containing the current character after LoadCurrentCharacter.
187  Register current_character() { return w22; }
188 
189  // Register holding address of the end of the input string.
190  Register input_end() { return x25; }
191 
192  // Register holding address of the start of the input string.
193  Register input_start() { return x26; }
194 
195  // Register holding the offset from the start of the string where we should
196  // start matching.
197  Register start_offset() { return w27; }
198 
199  // Pointer to the output array's first element.
200  Register output_array() { return x28; }
201 
202  // Register holding the frame address. Local variables, parameters and
203  // regexp registers are addressed relative to this.
204  Register frame_pointer() { return fp; }
205 
206  // The register containing the backtrack stack top. Provides a meaningful
207  // name to the register.
208  Register backtrack_stackpointer() { return x23; }
209 
210  // Register holding pointer to the current code object.
211  Register code_pointer() { return x20; }
212 
213  // Register holding the value used for clearing capture registers.
214  Register non_position_value() { return w24; }
215  // The top 32 bit of this register is used to store this value
216  // twice. This is used for clearing more than one register at a time.
217  Register twice_non_position_value() { return x24; }
218 
219  // Byte size of chars in the string to match (decided by the Mode argument)
220  int char_size() { return static_cast<int>(mode_); }
221 
222  // Equivalent to a conditional branch to the label, unless the label
223  // is NULL, in which case it is a conditional Backtrack.
224  void BranchOrBacktrack(Condition condition, Label* to);
225 
226  // Compares reg against immmediate before calling BranchOrBacktrack.
227  // It makes use of the Cbz and Cbnz instructions.
228  void CompareAndBranchOrBacktrack(Register reg,
229  int immediate,
230  Condition condition,
231  Label* to);
232 
233  inline void CallIf(Label* to, Condition condition);
234 
235  // Save and restore the link register on the stack in a way that
236  // is GC-safe.
237  inline void SaveLinkRegister();
238  inline void RestoreLinkRegister();
239 
240  // Pushes the value of a register on the backtrack stack. Decrements the
241  // stack pointer by a word size and stores the register's value there.
242  inline void Push(Register source);
243 
244  // Pops a value from the backtrack stack. Reads the word at the stack pointer
245  // and increments it by a word size.
246  inline void Pop(Register target);
247 
248  // This state indicates where the register actually is.
249  enum RegisterState {
250  STACKED, // Resides in memory.
251  CACHED_LSW, // Least Significant Word of a 64 bit hardware register.
252  CACHED_MSW // Most Significant Word of a 64 bit hardware register.
253  };
254 
255  RegisterState GetRegisterState(int register_index) {
256  ASSERT(register_index >= 0);
257  if (register_index >= kNumCachedRegisters) {
258  return STACKED;
259  } else {
260  if ((register_index % 2) == 0) {
261  return CACHED_LSW;
262  } else {
263  return CACHED_MSW;
264  }
265  }
266  }
267 
268  // Store helper that takes the state of the register into account.
269  inline void StoreRegister(int register_index, Register source);
270 
271  // Returns a hardware W register that holds the value of the capture
272  // register.
273  //
274  // This function will try to use an existing cache register (w0-w7) for the
275  // result. Otherwise, it will load the value into maybe_result.
276  //
277  // If the returned register is anything other than maybe_result, calling code
278  // must not write to it.
279  inline Register GetRegister(int register_index, Register maybe_result);
280 
281  // Returns the harware register (x0-x7) holding the value of the capture
282  // register.
283  // This assumes that the state of the register is not STACKED.
284  inline Register GetCachedRegister(int register_index);
285 
286  Isolate* isolate() const { return masm_->isolate(); }
287 
288  MacroAssembler* masm_;
289 
290  // Which mode to generate code for (ASCII or UC16).
291  Mode mode_;
292 
293  // One greater than maximal register index actually used.
294  int num_registers_;
295 
296  // Number of registers to output at the end (the saved registers
297  // are always 0..num_saved_registers_-1)
298  int num_saved_registers_;
299 
300  // Labels used internally.
301  Label entry_label_;
302  Label start_label_;
303  Label success_label_;
304  Label backtrack_label_;
305  Label exit_label_;
306  Label check_preempt_label_;
307  Label stack_overflow_label_;
308 };
309 
310 #endif // V8_INTERPRETED_REGEXP
311 
312 
313 }} // namespace v8::internal
314 
315 #endif // V8_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
byte * Address
Definition: globals.h:186
virtual void CheckNotCharacterAfterMinusAnd(uc16 c, uc16 minus, uc16 mask, Label *on_not_equal)
virtual void CheckCharacterInRange(uc16 from, uc16 to, Label *on_in_range)
virtual void PushRegister(int register_index, StackCheckFlag check_stack_limit)
virtual void CheckNotBackReferenceIgnoreCase(int start_reg, Label *on_no_match)
Isolate * isolate() const
Definition: assembler.h:62
virtual void CheckCharacters(Vector< const uc16 > str, int cp_offset, Label *on_failure, bool check_end_of_string)
virtual IrregexpImplementation Implementation()
const unsigned kWRegSize
virtual void CheckCharacter(unsigned c, Label *on_equal)
virtual void GoTo(Label *label)
virtual void CheckAtStart(Label *on_at_start)
#define ASSERT(condition)
Definition: checks.h:329
virtual bool CheckSpecialCharacterClass(uc16 type, Label *on_no_match)
virtual void PushBacktrack(Label *label)
virtual void WriteStackPointerToRegister(int reg)
virtual void CheckCharacterLT(uc16 limit, Label *on_less)
uint8_t byte
Definition: globals.h:185
virtual void LoadCurrentCharacter(int cp_offset, Label *on_end_of_input, bool check_bounds=true, int characters=1)
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 Bind(Label *label)
virtual void CheckBitInTable(Handle< ByteArray > table, Label *on_bit_set)
const int kPointerSize
Definition: globals.h:268
virtual void IfRegisterLT(int reg, int comparand, Label *if_lt)
virtual void CheckNotCharacter(unsigned c, Label *on_not_equal)
virtual void CheckCharacterNotInRange(uc16 from, uc16 to, Label *on_not_in_range)
virtual void SetCurrentPositionFromEnd(int by)
virtual void CheckPosition(int cp_offset, Label *on_outside_input)
virtual void CheckNotBackReference(int start_reg, Label *on_no_match)
virtual void ReadCurrentPositionFromRegister(int reg)
virtual void ClearRegisters(int reg_from, int reg_to)
static int CheckStackGuardState(Address *return_address, Code *re_code, Address re_frame, int start_offset, const byte **input_start, const byte **input_end)
const unsigned kXRegSize
virtual void IfRegisterEqPos(int reg, Label *if_eq)
virtual void PopRegister(int register_index)
RegExpMacroAssemblerARM64(Mode mode, int registers_to_save, Zone *zone)
uint16_t uc16
Definition: globals.h:309
virtual void IfRegisterGE(int reg, int comparand, Label *if_ge)
virtual void ReadStackPointerFromRegister(int reg)
virtual void SetRegister(int register_index, int to)
virtual void CheckNotAtStart(Label *on_not_at_start)
virtual Handle< HeapObject > GetCode(Handle< String > source)
virtual void CheckGreedyLoop(Label *on_tos_equals_current_position)
virtual void CheckCharacterAfterAnd(unsigned c, unsigned mask, Label *on_equal)
const Register fp
virtual void AdvanceRegister(int reg, int by)
virtual void AdvanceCurrentPosition(int by)
virtual void CheckCharacterGT(uc16 limit, Label *on_greater)
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset)
virtual void CheckNotCharacterAfterAnd(unsigned c, unsigned mask, Label *on_not_equal)