v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
regexp-macro-assembler-tracer.cc
Go to the documentation of this file.
1// Copyright 2012 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
6
9
10namespace v8 {
11namespace internal {
12
14 Isolate* isolate, RegExpMacroAssembler* assembler)
15 : RegExpMacroAssembler(isolate, assembler->zone()), assembler_(assembler) {
16 PrintF("RegExpMacroAssembler%s();\n",
17 ImplementationToString(assembler->Implementation()));
18}
19
21
26
27
28// This is used for printing out debugging information. It makes an integer
29// that is closely related to the address of an object.
30static int LabelToInt(Label* label) {
31 return static_cast<int>(reinterpret_cast<intptr_t>(label));
32}
33
34
36 PrintF("label[%08x]: (Bind)\n", LabelToInt(label));
38}
39
40
42 PrintF(" AdvanceCurrentPosition(by=%d);\n", by);
44}
45
46
48 PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label));
50}
51
52
54 PrintF(" PopCurrentPosition();\n");
56}
57
58
60 PrintF(" PushCurrentPosition();\n");
62}
63
64
66 PrintF(" Backtrack();\n");
68}
69
70
72 PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label));
74}
75
76
81
82
84 bool restart = assembler_->Succeed();
85 PrintF(" Succeed();%s\n", restart ? " [restart for global match]" : "");
86 return restart;
87}
88
89
91 PrintF(" Fail();");
93}
94
95
97 PrintF(" PopRegister(register=%d);\n", register_index);
98 assembler_->PopRegister(register_index);
99}
100
101
103 int register_index,
104 StackCheckFlag check_stack_limit) {
105 PrintF(" PushRegister(register=%d, %s);\n",
106 register_index,
107 check_stack_limit ? "check stack limit" : "");
108 assembler_->PushRegister(register_index, check_stack_limit);
109}
110
111
113 PrintF(" AdvanceRegister(register=%d, by=%d);\n", reg, by);
115}
116
117
119 PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by);
121}
122
123
124void RegExpMacroAssemblerTracer::SetRegister(int register_index, int to) {
125 PrintF(" SetRegister(register=%d, to=%d);\n", register_index, to);
126 assembler_->SetRegister(register_index, to);
127}
128
129
131 int cp_offset) {
132 PrintF(" WriteCurrentPositionToRegister(register=%d,cp_offset=%d);\n",
133 reg,
134 cp_offset);
136}
137
138
139void RegExpMacroAssemblerTracer::ClearRegisters(int reg_from, int reg_to) {
140 PrintF(" ClearRegister(from=%d, to=%d);\n", reg_from, reg_to);
141 assembler_->ClearRegisters(reg_from, reg_to);
142}
143
144
146 PrintF(" ReadCurrentPositionFromRegister(register=%d);\n", reg);
148}
149
150
152 PrintF(" WriteStackPointerToRegister(register=%d);\n", reg);
154}
155
156
158 PrintF(" ReadStackPointerFromRegister(register=%d);\n", reg);
160}
161
163 int cp_offset, Label* on_end_of_input, bool check_bounds, int characters,
164 int eats_at_least) {
165 const char* check_msg = check_bounds ? "" : " (unchecked)";
166 PrintF(
167 " LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars) (eats at "
168 "least %d));\n",
169 cp_offset, LabelToInt(on_end_of_input), check_msg, characters,
170 eats_at_least);
171 assembler_->LoadCurrentCharacter(cp_offset, on_end_of_input, check_bounds,
172 characters, eats_at_least);
173}
174
175namespace {
176
177class PrintablePrinter {
178 public:
179 explicit PrintablePrinter(base::uc16 character) : character_(character) {}
180
181 const char* operator*() {
182 if (character_ >= ' ' && character_ <= '~') {
183 buffer_[0] = '(';
184 buffer_[1] = static_cast<char>(character_);
185 buffer_[2] = ')';
186 buffer_[3] = '\0';
187 } else {
188 buffer_[0] = '\0';
189 }
190 return &buffer_[0];
191 }
192
193 private:
195 char buffer_[4];
196};
197
198} // namespace
199
201 Label* on_less) {
202 PrintablePrinter printable(limit);
203 PrintF(" CheckCharacterLT(c=0x%04x%s, label[%08x]);\n",
204 limit,
205 *printable,
206 LabelToInt(on_less));
207 assembler_->CheckCharacterLT(limit, on_less);
208}
209
211 Label* on_greater) {
212 PrintablePrinter printable(limit);
213 PrintF(" CheckCharacterGT(c=0x%04x%s, label[%08x]);\n",
214 limit,
215 *printable,
216 LabelToInt(on_greater));
217 assembler_->CheckCharacterGT(limit, on_greater);
218}
219
221 PrintablePrinter printable(c);
222 PrintF(" CheckCharacter(c=0x%04x%s, label[%08x]);\n",
223 c,
224 *printable,
225 LabelToInt(on_equal));
226 assembler_->CheckCharacter(c, on_equal);
227}
228
230 Label* on_at_start) {
231 PrintF(" CheckAtStart(cp_offset=%d, label[%08x]);\n", cp_offset,
232 LabelToInt(on_at_start));
233 assembler_->CheckAtStart(cp_offset, on_at_start);
234}
235
237 Label* on_not_at_start) {
238 PrintF(" CheckNotAtStart(cp_offset=%d, label[%08x]);\n", cp_offset,
239 LabelToInt(on_not_at_start));
240 assembler_->CheckNotAtStart(cp_offset, on_not_at_start);
241}
242
243
245 Label* on_not_equal) {
246 PrintablePrinter printable(c);
247 PrintF(" CheckNotCharacter(c=0x%04x%s, label[%08x]);\n",
248 c,
249 *printable,
250 LabelToInt(on_not_equal));
251 assembler_->CheckNotCharacter(c, on_not_equal);
252}
253
254
256 unsigned c,
257 unsigned mask,
258 Label* on_equal) {
259 PrintablePrinter printable(c);
260 PrintF(" CheckCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
261 c,
262 *printable,
263 mask,
264 LabelToInt(on_equal));
266}
267
268
270 unsigned c,
271 unsigned mask,
272 Label* on_not_equal) {
273 PrintablePrinter printable(c);
274 PrintF(" CheckNotCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
275 c,
276 *printable,
277 mask,
278 LabelToInt(on_not_equal));
279 assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal);
280}
281
283 base::uc16 c, base::uc16 minus, base::uc16 mask, Label* on_not_equal) {
284 PrintF(" CheckNotCharacterAfterMinusAnd(c=0x%04x, minus=%04x, mask=0x%04x, "
285 "label[%08x]);\n",
286 c,
287 minus,
288 mask,
289 LabelToInt(on_not_equal));
290 assembler_->CheckNotCharacterAfterMinusAnd(c, minus, mask, on_not_equal);
291}
292
294 base::uc16 to,
295 Label* on_not_in_range) {
296 PrintablePrinter printable_from(from);
297 PrintablePrinter printable_to(to);
298 PrintF(" CheckCharacterInRange(from=0x%04x%s, to=0x%04x%s, label[%08x]);\n",
299 from,
300 *printable_from,
301 to,
302 *printable_to,
303 LabelToInt(on_not_in_range));
304 assembler_->CheckCharacterInRange(from, to, on_not_in_range);
305}
306
308 base::uc16 to,
309 Label* on_in_range) {
310 PrintablePrinter printable_from(from);
311 PrintablePrinter printable_to(to);
312 PrintF(
313 " CheckCharacterNotInRange(from=0x%04x%s," " to=%04x%s, label[%08x]);\n",
314 from,
315 *printable_from,
316 to,
317 *printable_to,
318 LabelToInt(on_in_range));
319 assembler_->CheckCharacterNotInRange(from, to, on_in_range);
320}
321
322namespace {
323
324void PrintRangeArray(const ZoneList<CharacterRange>* ranges) {
325 for (int i = 0; i < ranges->length(); i++) {
326 base::uc16 from = ranges->at(i).from();
327 base::uc16 to = ranges->at(i).to();
328 PrintablePrinter printable_from(from);
329 PrintablePrinter printable_to(to);
330 PrintF(" [from=0x%04x%s, to=%04x%s],\n", from, *printable_from, to,
331 *printable_to);
332 }
333}
334
335} // namespace
336
338 const ZoneList<CharacterRange>* ranges, Label* on_in_range) {
339 PrintF(
340 " CheckCharacterInRangeArray(\n"
341 " label[%08x]);\n",
342 LabelToInt(on_in_range));
343 PrintRangeArray(ranges);
344 return assembler_->CheckCharacterInRangeArray(ranges, on_in_range);
345}
346
348 const ZoneList<CharacterRange>* ranges, Label* on_not_in_range) {
349 bool emitted =
350 assembler_->CheckCharacterNotInRangeArray(ranges, on_not_in_range);
351 if (emitted) {
352 PrintF(
353 " CheckCharacterNotInRangeArray(\n"
354 " label[%08x]);\n",
355 LabelToInt(on_not_in_range));
356 PrintRangeArray(ranges);
357 }
358 return emitted;
359}
360
362 Handle<ByteArray> table, Label* on_bit_set) {
363 PrintF(" CheckBitInTable(label[%08x] ", LabelToInt(on_bit_set));
364 for (int i = 0; i < kTableSize; i++) {
365 PrintF("%c", table->get(i) != 0 ? 'X' : '.');
366 if (i % 32 == 31 && i != kTableMask) {
367 PrintF("\n ");
368 }
369 }
370 PrintF(");\n");
371 assembler_->CheckBitInTable(table, on_bit_set);
372}
373
375 int cp_offset, Handle<ByteArray> table, Handle<ByteArray> nibble_table,
376 int advance_by) {
377 PrintF("SkipUntilBitInTable(cp_offset=%d, advance_by=%d\n ", cp_offset,
378 advance_by);
379 for (int i = 0; i < kTableSize; i++) {
380 PrintF("%c", table->get(i) != 0 ? 'X' : '.');
381 if (i % 32 == 31 && i != kTableMask) {
382 PrintF("\n ");
383 }
384 }
385 static_assert(kTableSize == 128);
386 static constexpr int kRows = 16;
387 static_assert(kRows * kBitsPerByte == kTableSize);
388 if (!nibble_table.is_null()) {
389 PrintF("\n");
390 PrintF(" +----------------\n");
391 PrintF(" |");
392 for (int j = 0; j < kBitsPerByte; j++) {
393 PrintF(" %x", j);
394 }
395 PrintF("\n--+----------------");
396 for (int i = 0; i < kRows; i++) {
397 int r = nibble_table->get(i);
398 PrintF("\n%x |", i);
399 for (int j = 0; j < kBitsPerByte; j++) {
400 PrintF(" %c", (r & (1 << j)) == 0 ? '.' : 'X');
401 }
402 }
403 }
404 PrintF(");\n");
405 assembler_->SkipUntilBitInTable(cp_offset, table, nibble_table, advance_by);
406}
407
409 bool read_backward,
410 Label* on_no_match) {
411 PrintF(" CheckNotBackReference(register=%d, %s, label[%08x]);\n", start_reg,
412 read_backward ? "backward" : "forward", LabelToInt(on_no_match));
413 assembler_->CheckNotBackReference(start_reg, read_backward, on_no_match);
414}
415
417 int start_reg, bool read_backward, bool unicode, Label* on_no_match) {
418 PrintF(" CheckNotBackReferenceIgnoreCase(register=%d, %s %s, label[%08x]);\n",
419 start_reg, read_backward ? "backward" : "forward",
420 unicode ? "unicode" : "non-unicode", LabelToInt(on_no_match));
421 assembler_->CheckNotBackReferenceIgnoreCase(start_reg, read_backward, unicode,
422 on_no_match);
423}
424
426 Label* on_outside_input) {
427 PrintF(" CheckPosition(cp_offset=%d, label[%08x]);\n", cp_offset,
428 LabelToInt(on_outside_input));
429 assembler_->CheckPosition(cp_offset, on_outside_input);
430}
431
433 StandardCharacterSet type, Label* on_no_match) {
434 bool supported = assembler_->CheckSpecialClassRanges(type, on_no_match);
435 PrintF(" CheckSpecialClassRanges(type='%c', label[%08x]): %s;\n",
436 static_cast<char>(type), LabelToInt(on_no_match),
437 supported ? "true" : "false");
438 return supported;
439}
440
442 int comparand, Label* if_lt) {
443 PrintF(" IfRegisterLT(register=%d, number=%d, label[%08x]);\n",
444 register_index, comparand, LabelToInt(if_lt));
445 assembler_->IfRegisterLT(register_index, comparand, if_lt);
446}
447
448
450 Label* if_eq) {
451 PrintF(" IfRegisterEqPos(register=%d, label[%08x]);\n",
452 register_index, LabelToInt(if_eq));
453 assembler_->IfRegisterEqPos(register_index, if_eq);
454}
455
456
458 int comparand, Label* if_ge) {
459 PrintF(" IfRegisterGE(register=%d, number=%d, label[%08x]);\n",
460 register_index, comparand, LabelToInt(if_ge));
461 assembler_->IfRegisterGE(register_index, comparand, if_ge);
462}
463
464
469
471 DirectHandle<String> source, RegExpFlags flags) {
472 DirectHandle<String> flags_str =
474 PrintF(" GetCode('%s', '%s');\n", source->ToCString().get(),
475 flags_str->ToCString().get());
476 return assembler_->GetCode(source, flags);
477}
478
479} // namespace internal
480} // namespace v8
V8_INLINE bool is_null() const
Definition handles.h:69
static V8_EXPORT_PRIVATE DirectHandle< String > StringFromFlags(Isolate *isolate, Flags flags)
Definition js-regexp.cc:144
static constexpr Flags AsJSRegExpFlags(RegExpFlags f)
Definition js-regexp.h:54
bool CheckCharacterInRangeArray(const ZoneList< CharacterRange > *ranges, Label *on_in_range) override
void IfRegisterGE(int reg, int comparand, Label *if_ge) override
void SetRegister(int register_index, int to) override
void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward, bool unicode, Label *on_no_match) override
void CheckCharacterLT(base::uc16 limit, Label *on_less) override
void WriteCurrentPositionToRegister(int reg, int cp_offset) override
void CheckCharacterAfterAnd(unsigned c, unsigned and_with, Label *on_equal) override
void CheckNotAtStart(int cp_offset, Label *on_not_at_start) override
void ClearRegisters(int reg_from, int reg_to) override
void CheckPosition(int cp_offset, Label *on_outside_input) override
bool CheckCharacterNotInRangeArray(const ZoneList< CharacterRange > *ranges, Label *on_not_in_range) override
void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus, base::uc16 and_with, Label *on_not_equal) override
void CheckCharacterInRange(base::uc16 from, base::uc16 to, Label *on_in_range) override
RegExpMacroAssemblerTracer(Isolate *isolate, RegExpMacroAssembler *assembler)
void CheckCharacterGT(base::uc16 limit, Label *on_greater) override
void CheckAtStart(int cp_offset, Label *on_at_start) override
void CheckNotBackReference(int start_reg, bool read_backward, Label *on_no_match) override
void IfRegisterEqPos(int reg, Label *if_eq) override
void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, Label *on_not_equal) override
void CheckCharacterNotInRange(base::uc16 from, base::uc16 to, Label *on_not_in_range) override
DirectHandle< HeapObject > GetCode(DirectHandle< String > source, RegExpFlags flags) override
void PushRegister(int register_index, StackCheckFlag check_stack_limit) override
void CheckGreedyLoop(Label *on_tos_equals_current_position) override
void CheckBitInTable(Handle< ByteArray > table, Label *on_bit_set) override
void CheckNotCharacter(unsigned c, Label *on_not_equal) override
void CheckCharacter(unsigned c, Label *on_equal) override
void SkipUntilBitInTable(int cp_offset, Handle< ByteArray > table, Handle< ByteArray > nibble_table, int advance_by) override
void LoadCurrentCharacterImpl(int cp_offset, Label *on_end_of_input, bool check_bounds, int characters, int eats_at_least) override
void IfRegisterLT(int reg, int comparand, Label *if_lt) override
bool CheckSpecialClassRanges(StandardCharacterSet type, Label *on_no_match) override
virtual void SkipUntilBitInTable(int cp_offset, Handle< ByteArray > table, Handle< ByteArray > nibble_table, int advance_by)=0
virtual bool CheckCharacterInRangeArray(const ZoneList< CharacterRange > *ranges, Label *on_in_range)=0
virtual void CheckNotAtStart(int cp_offset, Label *on_not_at_start)=0
virtual void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward, bool unicode, Label *on_no_match)=0
virtual void CheckCharacterInRange(base::uc16 from, base::uc16 to, Label *on_in_range)=0
virtual void CheckBitInTable(Handle< ByteArray > table, Label *on_bit_set)=0
virtual void PushRegister(int register_index, StackCheckFlag check_stack_limit)=0
virtual void Bind(Label *label)=0
virtual void PushBacktrack(Label *label)=0
virtual void CheckNotBackReference(int start_reg, bool read_backward, Label *on_no_match)=0
virtual void IfRegisterEqPos(int reg, Label *if_eq)=0
virtual bool CheckSpecialClassRanges(StandardCharacterSet type, Label *on_no_match)
virtual void CheckCharacterLT(base::uc16 limit, Label *on_less)=0
virtual void SetRegister(int register_index, int to)=0
virtual void CheckCharacterAfterAnd(unsigned c, unsigned and_with, Label *on_equal)=0
virtual void SetCurrentPositionFromEnd(int by)=0
virtual void CheckCharacter(unsigned c, Label *on_equal)=0
virtual void ReadCurrentPositionFromRegister(int reg)=0
virtual DirectHandle< HeapObject > GetCode(DirectHandle< String > source, RegExpFlags flags)=0
virtual void IfRegisterLT(int reg, int comparand, Label *if_lt)=0
virtual IrregexpImplementation Implementation()=0
virtual void ReadStackPointerFromRegister(int reg)=0
virtual void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus, base::uc16 and_with, Label *on_not_equal)=0
virtual void CheckPosition(int cp_offset, Label *on_outside_input)
virtual void CheckAtStart(int cp_offset, Label *on_at_start)=0
virtual void WriteStackPointerToRegister(int reg)=0
virtual void WriteCurrentPositionToRegister(int reg, int cp_offset)=0
virtual void CheckGreedyLoop(Label *on_tos_equals_current_position)=0
virtual void AdvanceCurrentPosition(int by)=0
V8_EXPORT_PRIVATE void LoadCurrentCharacter(int cp_offset, Label *on_end_of_input, bool check_bounds=true, int characters=1, int eats_at_least=kUseCharactersValue)
virtual void PopRegister(int register_index)=0
virtual void CheckCharacterNotInRange(base::uc16 from, base::uc16 to, Label *on_not_in_range)=0
const char * ImplementationToString(IrregexpImplementation impl)
virtual void CheckNotCharacter(unsigned c, Label *on_not_equal)=0
virtual void GoTo(Label *label)=0
virtual bool CheckCharacterNotInRangeArray(const ZoneList< CharacterRange > *ranges, Label *on_not_in_range)=0
virtual void AdvanceRegister(int reg, int by)=0
virtual void ClearRegisters(int reg_from, int reg_to)=0
virtual void CheckCharacterGT(base::uc16 limit, Label *on_greater)=0
virtual void IfRegisterGE(int reg, int comparand, Label *if_ge)=0
virtual void CheckNotCharacterAfterAnd(unsigned c, unsigned and_with, Label *on_not_equal)=0
base::OwnedVector< uint8_t > buffer_
Definition assembler.cc:111
Label label
BytecodeAssembler & assembler_
LiftoffRegister reg
uint32_t const mask
int r
Definition mul-fft.cc:298
uint16_t uc16
Definition strings.h:18
constexpr int kBitsPerByte
Definition globals.h:682
void PrintF(const char *format,...)
Definition utils.cc:39
BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL BUILTIN_FP_CALL int character
static int LabelToInt(Label *label)
base::uc16 character_