v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
regexp-macro-assembler-arm64.h
Go to the documentation of this file.
1// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_REGEXP_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
6#define V8_REGEXP_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
7
8#include "src/base/strings.h"
12
13namespace v8 {
14namespace internal {
15
18 public:
20 int registers_to_save);
22 void AbortedCodeGeneration() override;
24 void AdvanceCurrentPosition(int by) override;
25 void AdvanceRegister(int reg, int by) override;
26 void Backtrack() override;
27 void Bind(Label* label) override;
28 void CheckAtStart(int cp_offset, Label* on_at_start) override;
29 void CheckCharacter(unsigned c, Label* on_equal) override;
30 void CheckCharacterAfterAnd(unsigned c, unsigned mask,
31 Label* on_equal) override;
32 void CheckCharacterGT(base::uc16 limit, Label* on_greater) override;
33 void CheckCharacterLT(base::uc16 limit, Label* on_less) override;
35 Label* on_failure, bool check_end_of_string);
36 // A "greedy loop" is a loop that is both greedy and with a simple
37 // body. It has a particularly simple implementation.
38 void CheckGreedyLoop(Label* on_tos_equals_current_position) override;
39 void CheckNotAtStart(int cp_offset, Label* on_not_at_start) override;
40 void CheckNotBackReference(int start_reg, bool read_backward,
41 Label* on_no_match) override;
42 void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
43 bool unicode,
44 Label* on_no_match) override;
45 void CheckNotCharacter(unsigned c, Label* on_not_equal) override;
46 void CheckNotCharacterAfterAnd(unsigned c, unsigned mask,
47 Label* on_not_equal) override;
50 Label* on_not_equal) override;
52 Label* on_in_range) override;
54 Label* on_not_in_range) override;
56 Label* on_in_range) override;
58 Label* on_not_in_range) override;
59 void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set) override;
60 void SkipUntilBitInTable(int cp_offset, Handle<ByteArray> table,
61 Handle<ByteArray> nibble_table,
62 int advance_by) override;
63 bool SkipUntilBitInTableUseSimd(int advance_by) override;
64
65 // Checks whether the given offset from the current position is before
66 // the end of the string.
67 void CheckPosition(int cp_offset, Label* on_outside_input) override;
69 Label* on_no_match) override;
70 void BindJumpTarget(Label* label = nullptr) override;
71 void Fail() override;
73 RegExpFlags flags) override;
74 void GoTo(Label* label) override;
75 void IfRegisterGE(int reg, int comparand, Label* if_ge) override;
76 void IfRegisterLT(int reg, int comparand, Label* if_lt) override;
77 void IfRegisterEqPos(int reg, Label* if_eq) override;
80 int character_count) override;
81 void PopCurrentPosition() override;
82 void PopRegister(int register_index) override;
83 void PushBacktrack(Label* label) override;
84 void PushCurrentPosition() override;
85 void PushRegister(int register_index,
86 StackCheckFlag check_stack_limit) override;
89 void SetCurrentPositionFromEnd(int by) override;
90 void SetRegister(int register_index, int to) override;
91 bool Succeed() override;
92 void WriteCurrentPositionToRegister(int reg, int cp_offset) override;
93 void ClearRegisters(int reg_from, int reg_to) override;
94 void WriteStackPointerToRegister(int reg) override;
95
96 // Called from RegExp if the stack-guard is triggered.
97 // If the code object is relocated, the return address is fixed before
98 // returning.
99 // {raw_code} is an Address because this is called via ExternalReference.
100 static int CheckStackGuardState(Address* return_address, Address raw_code,
101 Address re_frame, int start_offset,
102 const uint8_t** input_start,
103 const uint8_t** input_end,
104 uintptr_t extra_space);
105
106 private:
107 static constexpr int kFramePointerOffset = 0;
108
109 // Above the frame pointer - Stored registers and stack passed parameters.
110 static constexpr int kReturnAddressOffset =
111 kFramePointerOffset + kSystemPointerSize;
112 // Callee-saved registers (x19-x28).
113 static constexpr int kNumCalleeSavedRegisters = 10;
114 static constexpr int kCalleeSavedRegistersOffset =
115 kReturnAddressOffset + kSystemPointerSize;
116
117 // Below the frame pointer - the stack frame type marker and locals.
118 static constexpr int kFrameTypeOffset =
119 kFramePointerOffset - kSystemPointerSize;
120 static_assert(kFrameTypeOffset ==
121 CommonFrameConstants::kContextOrFrameTypeOffset);
122 static constexpr int kPaddingAfterFrameType = kSystemPointerSize;
123 // Register parameters stored by setup code.
124 static constexpr int kIsolateOffset =
125 kFrameTypeOffset - kPaddingAfterFrameType - kSystemPointerSize;
126 static constexpr int kDirectCallOffset = kIsolateOffset - kSystemPointerSize;
127 // For the case of global regular expression, we have room to store at least
128 // one set of capture results. For the case of non-global regexp, we ignore
129 // this value.
130 static constexpr int kNumOutputRegistersOffset =
131 kDirectCallOffset - kSystemPointerSize;
132 static constexpr int kInputStringOffset =
133 kNumOutputRegistersOffset - kSystemPointerSize;
134 // When adding local variables remember to push space for them in
135 // the frame in GetCode.
136 static constexpr int kSuccessfulCapturesOffset =
137 kInputStringOffset - kSystemPointerSize;
138 static constexpr int kBacktrackCountOffset =
139 kSuccessfulCapturesOffset - kSystemPointerSize;
140 // Stores the initial value of the regexp stack pointer in a
141 // position-independent representation (in case the regexp stack grows and
142 // thus moves).
143 static constexpr int kRegExpStackBasePointerOffset =
144 kBacktrackCountOffset - kSystemPointerSize;
145 // A padding slot to preserve alignment.
146 static constexpr int kStackLocalPadding =
147 kRegExpStackBasePointerOffset - kSystemPointerSize;
148 static constexpr int kNumberOfStackLocals = 4;
149
150 // First position register address on the stack. Following positions are
151 // below it. A position is a 32 bit value.
152 static constexpr int kFirstRegisterOnStackOffset =
153 kStackLocalPadding - kWRegSize;
154 // A capture is a 64 bit value holding two position.
155 static constexpr int kFirstCaptureOnStackOffset =
156 kStackLocalPadding - kXRegSize;
157
158 static constexpr int kInitialBufferSize = 1024;
159
160 // Registers x0 to x7 are used to store the first captures, they need to be
161 // retained over calls to C++ code.
164
165 // When initializing registers to a non-position value we can unroll
166 // the loop. Set the limit of registers to unroll.
167 static constexpr int kNumRegistersToUnroll = 16;
168
169 // We are using x0 to x7 as a register cache. Each hardware register must
170 // contain one capture, that is two 32 bit registers. We can cache at most
171 // 16 registers.
172 static constexpr int kNumCachedRegisters = 16;
173
175 int num_arguments);
176
177 // Check whether preemption has been requested.
179
180 // Check whether we are exceeding the stack limit on the backtrack stack.
183
185 Operand extra_space = Operand(0));
187
188 // Location of a 32 bit position register.
189 MemOperand register_location(int register_index);
190
191 // Location of a 64 bit capture, combining two position registers.
192 MemOperand capture_location(int register_index, Register scratch);
193
194 // Register holding the current input position as negative offset from
195 // the end of the string.
196 static constexpr Register current_input_offset() { return w21; }
197
198 // The register containing the current character after LoadCurrentCharacter.
199 static constexpr Register current_character() { return w22; }
200
201 // Register holding address of the end of the input string.
202 static constexpr Register input_end() { return x25; }
203
204 // Register holding address of the start of the input string.
205 static constexpr Register input_start() { return x26; }
206
207 // Register holding the offset from the start of the string where we should
208 // start matching.
209 static constexpr Register start_offset() { return w27; }
210
211 // Pointer to the output array's first element.
212 static constexpr Register output_array() { return x28; }
213
214 // Register holding the frame address. Local variables, parameters and
215 // regexp registers are addressed relative to this.
216 static constexpr Register frame_pointer() { return fp; }
217
218 // The register containing the backtrack stack top. Provides a meaningful
219 // name to the register.
220 static constexpr Register backtrack_stackpointer() { return x23; }
221
222 // Register holding pointer to the current code object.
223 static constexpr Register code_pointer() { return x20; }
224
225 // Register holding the value used for clearing capture registers.
226 static constexpr Register string_start_minus_one() { return w24; }
227 // The top 32 bit of this register is used to store this value
228 // twice. This is used for clearing more than one register at a time.
229 static constexpr Register twice_non_position_value() { return x24; }
230
231 // Byte size of chars in the string to match (decided by the Mode argument)
232 int char_size() const { return static_cast<int>(mode_); }
233
234 // Equivalent to a conditional branch to the label, unless the label
235 // is nullptr, in which case it is a conditional Backtrack.
237
238 // Compares reg against immediate before calling BranchOrBacktrack.
239 // It makes use of the Cbz and Cbnz instructions.
241 int immediate,
243 Label* to);
244
245 inline void CallIf(Label* to, Condition condition);
246
247 // Save and restore the link register on the stack in a way that
248 // is GC-safe.
249 inline void SaveLinkRegister();
250 inline void RestoreLinkRegister();
251
252 // Pushes the value of a register on the backtrack stack. Decrements the
253 // stack pointer by a word size and stores the register's value there.
254 inline void Push(Register source);
255
256 // Pops a value from the backtrack stack. Reads the word at the stack pointer
257 // and increments it by a word size.
258 inline void Pop(Register target);
259
260 // This state indicates where the register actually is.
262 STACKED, // Resides in memory.
263 CACHED_LSW, // Least Significant Word of a 64 bit hardware register.
264 CACHED_MSW // Most Significant Word of a 64 bit hardware register.
265 };
266
267 RegisterState GetRegisterState(int register_index) {
268 DCHECK_LE(0, register_index);
269 if (register_index >= kNumCachedRegisters) {
270 return STACKED;
271 } else {
272 if ((register_index % 2) == 0) {
273 return CACHED_LSW;
274 } else {
275 return CACHED_MSW;
276 }
277 }
278 }
279
280 // Store helper that takes the state of the register into account.
281 inline void StoreRegister(int register_index, Register source);
282
283 // Returns a hardware W register that holds the value of the capture
284 // register.
285 //
286 // This function will try to use an existing cache register (w0-w7) for the
287 // result. Otherwise, it will load the value into maybe_result.
288 //
289 // If the returned register is anything other than maybe_result, calling code
290 // must not write to it.
291 inline Register GetRegister(int register_index, Register maybe_result);
292
293 // Returns the harware register (x0-x7) holding the value of the capture
294 // register.
295 // This assumes that the state of the register is not STACKED.
296 inline Register GetCachedRegister(int register_index);
297
300 void PushRegExpBasePointer(Register stack_pointer, Register scratch);
301 void PopRegExpBasePointer(Register stack_pointer_out, Register scratch);
302
303 Isolate* isolate() const { return masm_->isolate(); }
304
305 const std::unique_ptr<MacroAssembler> masm_;
307
308 // Which mode to generate code for (LATIN1 or UC16).
309 const Mode mode_;
310
311 // One greater than maximal register index actually used.
313
314 // Number of registers to output at the end (the saved registers
315 // are always 0..num_saved_registers_-1)
317
318 // Labels used internally.
327};
328
329} // namespace internal
330} // namespace v8
331
332#endif // V8_REGEXP_ARM64_REGEXP_MACRO_ASSEMBLER_ARM64_H_
void CheckCharacter(unsigned c, Label *on_equal) override
void ReadStackPointerFromRegister(int reg) override
void AdvanceRegister(int reg, int by) override
bool SkipUntilBitInTableUseSimd(int advance_by) override
void WriteStackPointerToRegister(int reg) override
RegisterState GetRegisterState(int register_index)
IrregexpImplementation Implementation() override
void AdvanceCurrentPosition(int by) override
void StoreRegister(int register_index, Register source)
const std::unique_ptr< MacroAssembler > masm_
void LoadRegExpStackPointerFromMemory(Register dst)
void CheckNotAtStart(int cp_offset, Label *on_not_at_start) override
void Bind(Label *label) override
void IfRegisterEqPos(int reg, Label *if_eq) override
void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward, bool unicode, Label *on_no_match) override
bool CheckCharacterNotInRangeArray(const ZoneList< CharacterRange > *ranges, Label *on_not_in_range) override
void WriteCurrentPositionToRegister(int reg, int cp_offset) override
DirectHandle< HeapObject > GetCode(DirectHandle< String > source, RegExpFlags flags) override
MemOperand register_location(int register_index)
void CheckCharacters(base::Vector< const base::uc16 > str, int cp_offset, Label *on_failure, bool check_end_of_string)
void PopRegExpBasePointer(Register stack_pointer_out, Register scratch)
void CheckNotBackReference(int start_reg, bool read_backward, Label *on_no_match) override
void PushRegister(int register_index, StackCheckFlag check_stack_limit) override
MemOperand capture_location(int register_index, Register scratch)
void CheckGreedyLoop(Label *on_tos_equals_current_position) override
bool CheckCharacterInRangeArray(const ZoneList< CharacterRange > *ranges, Label *on_in_range) override
Register GetCachedRegister(int register_index)
bool CheckSpecialClassRanges(StandardCharacterSet type, Label *on_no_match) override
void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus, base::uc16 mask, Label *on_not_equal) override
void GoTo(Label *label) override
void CheckNotCharacter(unsigned c, Label *on_not_equal) override
void CheckPosition(int cp_offset, Label *on_outside_input) override
void CheckAtStart(int cp_offset, Label *on_at_start) override
RegExpMacroAssemblerARM64(Isolate *isolate, Zone *zone, Mode mode, int registers_to_save)
void IfRegisterLT(int reg, int comparand, Label *if_lt) override
Register GetRegister(int register_index, Register maybe_result)
void CallCheckStackGuardState(Register scratch, Operand extra_space=Operand(0))
void SetRegister(int register_index, int to) override
void SetCurrentPositionFromEnd(int by) override
void PushBacktrack(Label *label) override
void CheckCharacterAfterAnd(unsigned c, unsigned mask, Label *on_equal) override
void CheckCharacterGT(base::uc16 limit, Label *on_greater) override
void LoadCurrentCharacterUnchecked(int cp_offset, int character_count) override
void ReadCurrentPositionFromRegister(int reg) override
void BindJumpTarget(Label *label=nullptr) override
void StoreRegExpStackPointerToMemory(Register src, Register scratch)
void PopRegister(int register_index) override
void CheckCharacterInRange(base::uc16 from, base::uc16 to, Label *on_in_range) override
void CallIf(Label *to, Condition condition)
void ClearRegisters(int reg_from, int reg_to) override
void CheckCharacterNotInRange(base::uc16 from, base::uc16 to, Label *on_not_in_range) override
void CheckBitInTable(Handle< ByteArray > table, Label *on_bit_set) override
void CompareAndBranchOrBacktrack(Register reg, int immediate, Condition condition, Label *to)
void SkipUntilBitInTable(int cp_offset, Handle< ByteArray > table, Handle< ByteArray > nibble_table, int advance_by) override
void CallIsCharacterInRangeArray(const ZoneList< CharacterRange > *ranges)
void BranchOrBacktrack(Condition condition, Label *to)
void PushRegExpBasePointer(Register stack_pointer, Register scratch)
void CheckCharacterLT(base::uc16 limit, Label *on_less) override
void IfRegisterGE(int reg, int comparand, Label *if_ge) override
static int CheckStackGuardState(Address *return_address, Address raw_code, Address re_frame, int start_offset, const uint8_t **input_start, const uint8_t **input_end, uintptr_t extra_space)
void CheckNotCharacterAfterAnd(unsigned c, unsigned mask, Label *on_not_equal) override
void CallCFunctionFromIrregexpCode(ExternalReference function, int num_arguments)
RecordWriteMode const mode_
Label label
LiftoffRegister reg
uint32_t const mask
MaglevAssembler *const masm_
uint16_t uc16
Definition strings.h:18
constexpr int kSystemPointerSize
Definition globals.h:410
constexpr int kWRegSize
constexpr int kXRegSize
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define V8_EXPORT_PRIVATE
Definition macros.h:460