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
5#include "src/regexp/regexp-macro-assembler-tracer.h"
6
7#include "src/ast/ast.h"
8
9namespace v8 {
10namespace internal {
11
12RegExpMacroAssemblerTracer::RegExpMacroAssemblerTracer(
13    Isolate* isolate, RegExpMacroAssembler* assembler)
14    : RegExpMacroAssembler(isolate, assembler->zone()), assembler_(assembler) {
15  unsigned int type = assembler->Implementation();
16  DCHECK(type < 8);
17  const char* impl_names[] = {"IA32", "ARM", "ARM64", "MIPS",
18                              "PPC",  "X64", "X87",   "Bytecode"};
19  PrintF("RegExpMacroAssembler%s();\n", impl_names[type]);
20}
21
22
23RegExpMacroAssemblerTracer::~RegExpMacroAssemblerTracer() {
24}
25
26
27void RegExpMacroAssemblerTracer::AbortedCodeGeneration() {
28  PrintF(" AbortedCodeGeneration\n");
29  assembler_->AbortedCodeGeneration();
30}
31
32
33// This is used for printing out debugging information.  It makes an integer
34// that is closely related to the address of an object.
35static int LabelToInt(Label* label) {
36  return static_cast<int>(reinterpret_cast<intptr_t>(label));
37}
38
39
40void RegExpMacroAssemblerTracer::Bind(Label* label) {
41  PrintF("label[%08x]: (Bind)\n", LabelToInt(label));
42  assembler_->Bind(label);
43}
44
45
46void RegExpMacroAssemblerTracer::AdvanceCurrentPosition(int by) {
47  PrintF(" AdvanceCurrentPosition(by=%d);\n", by);
48  assembler_->AdvanceCurrentPosition(by);
49}
50
51
52void RegExpMacroAssemblerTracer::CheckGreedyLoop(Label* label) {
53  PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label));
54  assembler_->CheckGreedyLoop(label);
55}
56
57
58void RegExpMacroAssemblerTracer::PopCurrentPosition() {
59  PrintF(" PopCurrentPosition();\n");
60  assembler_->PopCurrentPosition();
61}
62
63
64void RegExpMacroAssemblerTracer::PushCurrentPosition() {
65  PrintF(" PushCurrentPosition();\n");
66  assembler_->PushCurrentPosition();
67}
68
69
70void RegExpMacroAssemblerTracer::Backtrack() {
71  PrintF(" Backtrack();\n");
72  assembler_->Backtrack();
73}
74
75
76void RegExpMacroAssemblerTracer::GoTo(Label* label) {
77  PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label));
78  assembler_->GoTo(label);
79}
80
81
82void RegExpMacroAssemblerTracer::PushBacktrack(Label* label) {
83  PrintF(" PushBacktrack(label[%08x]);\n", LabelToInt(label));
84  assembler_->PushBacktrack(label);
85}
86
87
88bool RegExpMacroAssemblerTracer::Succeed() {
89  bool restart = assembler_->Succeed();
90  PrintF(" Succeed();%s\n", restart ? " [restart for global match]" : "");
91  return restart;
92}
93
94
95void RegExpMacroAssemblerTracer::Fail() {
96  PrintF(" Fail();");
97  assembler_->Fail();
98}
99
100
101void RegExpMacroAssemblerTracer::PopRegister(int register_index) {
102  PrintF(" PopRegister(register=%d);\n", register_index);
103  assembler_->PopRegister(register_index);
104}
105
106
107void RegExpMacroAssemblerTracer::PushRegister(
108    int register_index,
109    StackCheckFlag check_stack_limit) {
110  PrintF(" PushRegister(register=%d, %s);\n",
111         register_index,
112         check_stack_limit ? "check stack limit" : "");
113  assembler_->PushRegister(register_index, check_stack_limit);
114}
115
116
117void RegExpMacroAssemblerTracer::AdvanceRegister(int reg, int by) {
118  PrintF(" AdvanceRegister(register=%d, by=%d);\n", reg, by);
119  assembler_->AdvanceRegister(reg, by);
120}
121
122
123void RegExpMacroAssemblerTracer::SetCurrentPositionFromEnd(int by) {
124  PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by);
125  assembler_->SetCurrentPositionFromEnd(by);
126}
127
128
129void RegExpMacroAssemblerTracer::SetRegister(int register_index, int to) {
130  PrintF(" SetRegister(register=%d, to=%d);\n", register_index, to);
131  assembler_->SetRegister(register_index, to);
132}
133
134
135void RegExpMacroAssemblerTracer::WriteCurrentPositionToRegister(int reg,
136                                                                int cp_offset) {
137  PrintF(" WriteCurrentPositionToRegister(register=%d,cp_offset=%d);\n",
138         reg,
139         cp_offset);
140  assembler_->WriteCurrentPositionToRegister(reg, cp_offset);
141}
142
143
144void RegExpMacroAssemblerTracer::ClearRegisters(int reg_from, int reg_to) {
145  PrintF(" ClearRegister(from=%d, to=%d);\n", reg_from, reg_to);
146  assembler_->ClearRegisters(reg_from, reg_to);
147}
148
149
150void RegExpMacroAssemblerTracer::ReadCurrentPositionFromRegister(int reg) {
151  PrintF(" ReadCurrentPositionFromRegister(register=%d);\n", reg);
152  assembler_->ReadCurrentPositionFromRegister(reg);
153}
154
155
156void RegExpMacroAssemblerTracer::WriteStackPointerToRegister(int reg) {
157  PrintF(" WriteStackPointerToRegister(register=%d);\n", reg);
158  assembler_->WriteStackPointerToRegister(reg);
159}
160
161
162void RegExpMacroAssemblerTracer::ReadStackPointerFromRegister(int reg) {
163  PrintF(" ReadStackPointerFromRegister(register=%d);\n", reg);
164  assembler_->ReadStackPointerFromRegister(reg);
165}
166
167
168void RegExpMacroAssemblerTracer::LoadCurrentCharacter(int cp_offset,
169                                                      Label* on_end_of_input,
170                                                      bool check_bounds,
171                                                      int characters) {
172  const char* check_msg = check_bounds ? "" : " (unchecked)";
173  PrintF(" LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars));\n",
174         cp_offset,
175         LabelToInt(on_end_of_input),
176         check_msg,
177         characters);
178  assembler_->LoadCurrentCharacter(cp_offset,
179                                   on_end_of_input,
180                                   check_bounds,
181                                   characters);
182}
183
184
185class PrintablePrinter {
186 public:
187  explicit PrintablePrinter(uc16 character) : character_(character) { }
188
189  const char* operator*() {
190    if (character_ >= ' ' && character_ <= '~') {
191      buffer_[0] = '(';
192      buffer_[1] = static_cast<char>(character_);
193      buffer_[2] = ')';
194      buffer_[3] = '\0';
195    } else {
196      buffer_[0] = '\0';
197    }
198    return &buffer_[0];
199  }
200
201 private:
202  uc16 character_;
203  char buffer_[4];
204};
205
206
207void RegExpMacroAssemblerTracer::CheckCharacterLT(uc16 limit, Label* on_less) {
208  PrintablePrinter printable(limit);
209  PrintF(" CheckCharacterLT(c=0x%04x%s, label[%08x]);\n",
210         limit,
211         *printable,
212         LabelToInt(on_less));
213  assembler_->CheckCharacterLT(limit, on_less);
214}
215
216
217void RegExpMacroAssemblerTracer::CheckCharacterGT(uc16 limit,
218                                                  Label* on_greater) {
219  PrintablePrinter printable(limit);
220  PrintF(" CheckCharacterGT(c=0x%04x%s, label[%08x]);\n",
221         limit,
222         *printable,
223         LabelToInt(on_greater));
224  assembler_->CheckCharacterGT(limit, on_greater);
225}
226
227
228void RegExpMacroAssemblerTracer::CheckCharacter(unsigned c, Label* on_equal) {
229  PrintablePrinter printable(c);
230  PrintF(" CheckCharacter(c=0x%04x%s, label[%08x]);\n",
231         c,
232         *printable,
233         LabelToInt(on_equal));
234  assembler_->CheckCharacter(c, on_equal);
235}
236
237
238void RegExpMacroAssemblerTracer::CheckAtStart(Label* on_at_start) {
239  PrintF(" CheckAtStart(label[%08x]);\n", LabelToInt(on_at_start));
240  assembler_->CheckAtStart(on_at_start);
241}
242
243
244void RegExpMacroAssemblerTracer::CheckNotAtStart(int cp_offset,
245                                                 Label* on_not_at_start) {
246  PrintF(" CheckNotAtStart(cp_offset=%d, label[%08x]);\n", cp_offset,
247         LabelToInt(on_not_at_start));
248  assembler_->CheckNotAtStart(cp_offset, on_not_at_start);
249}
250
251
252void RegExpMacroAssemblerTracer::CheckNotCharacter(unsigned c,
253                                                   Label* on_not_equal) {
254  PrintablePrinter printable(c);
255  PrintF(" CheckNotCharacter(c=0x%04x%s, label[%08x]);\n",
256         c,
257         *printable,
258         LabelToInt(on_not_equal));
259  assembler_->CheckNotCharacter(c, on_not_equal);
260}
261
262
263void RegExpMacroAssemblerTracer::CheckCharacterAfterAnd(
264    unsigned c,
265    unsigned mask,
266    Label* on_equal) {
267  PrintablePrinter printable(c);
268  PrintF(" CheckCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
269         c,
270         *printable,
271         mask,
272         LabelToInt(on_equal));
273  assembler_->CheckCharacterAfterAnd(c, mask, on_equal);
274}
275
276
277void RegExpMacroAssemblerTracer::CheckNotCharacterAfterAnd(
278    unsigned c,
279    unsigned mask,
280    Label* on_not_equal) {
281  PrintablePrinter printable(c);
282  PrintF(" CheckNotCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
283         c,
284         *printable,
285         mask,
286         LabelToInt(on_not_equal));
287  assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal);
288}
289
290
291void RegExpMacroAssemblerTracer::CheckNotCharacterAfterMinusAnd(
292    uc16 c,
293    uc16 minus,
294    uc16 mask,
295    Label* on_not_equal) {
296  PrintF(" CheckNotCharacterAfterMinusAnd(c=0x%04x, minus=%04x, mask=0x%04x, "
297             "label[%08x]);\n",
298         c,
299         minus,
300         mask,
301         LabelToInt(on_not_equal));
302  assembler_->CheckNotCharacterAfterMinusAnd(c, minus, mask, on_not_equal);
303}
304
305
306void RegExpMacroAssemblerTracer::CheckCharacterInRange(
307    uc16 from,
308    uc16 to,
309    Label* on_not_in_range) {
310  PrintablePrinter printable_from(from);
311  PrintablePrinter printable_to(to);
312  PrintF(" CheckCharacterInRange(from=0x%04x%s, to=0x%04x%s, label[%08x]);\n",
313         from,
314         *printable_from,
315         to,
316         *printable_to,
317         LabelToInt(on_not_in_range));
318  assembler_->CheckCharacterInRange(from, to, on_not_in_range);
319}
320
321
322void RegExpMacroAssemblerTracer::CheckCharacterNotInRange(
323    uc16 from,
324    uc16 to,
325    Label* on_in_range) {
326  PrintablePrinter printable_from(from);
327  PrintablePrinter printable_to(to);
328  PrintF(
329      " CheckCharacterNotInRange(from=0x%04x%s," " to=%04x%s, label[%08x]);\n",
330      from,
331      *printable_from,
332      to,
333      *printable_to,
334      LabelToInt(on_in_range));
335  assembler_->CheckCharacterNotInRange(from, to, on_in_range);
336}
337
338
339void RegExpMacroAssemblerTracer::CheckBitInTable(
340    Handle<ByteArray> table, Label* on_bit_set) {
341  PrintF(" CheckBitInTable(label[%08x] ", LabelToInt(on_bit_set));
342  for (int i = 0; i < kTableSize; i++) {
343    PrintF("%c", table->get(i) != 0 ? 'X' : '.');
344    if (i % 32 == 31 && i != kTableMask) {
345      PrintF("\n                                 ");
346    }
347  }
348  PrintF(");\n");
349  assembler_->CheckBitInTable(table, on_bit_set);
350}
351
352
353void RegExpMacroAssemblerTracer::CheckNotBackReference(int start_reg,
354                                                       bool read_backward,
355                                                       Label* on_no_match) {
356  PrintF(" CheckNotBackReference(register=%d, %s, label[%08x]);\n", start_reg,
357         read_backward ? "backward" : "forward", LabelToInt(on_no_match));
358  assembler_->CheckNotBackReference(start_reg, read_backward, on_no_match);
359}
360
361
362void RegExpMacroAssemblerTracer::CheckNotBackReferenceIgnoreCase(
363    int start_reg, bool read_backward, Label* on_no_match) {
364  PrintF(" CheckNotBackReferenceIgnoreCase(register=%d, %s, label[%08x]);\n",
365         start_reg, read_backward ? "backward" : "forward",
366         LabelToInt(on_no_match));
367  assembler_->CheckNotBackReferenceIgnoreCase(start_reg, read_backward,
368                                              on_no_match);
369}
370
371
372void RegExpMacroAssemblerTracer::CheckPosition(int cp_offset,
373                                               Label* on_outside_input) {
374  PrintF(" CheckPosition(cp_offset=%d, label[%08x]);\n", cp_offset,
375         LabelToInt(on_outside_input));
376  assembler_->CheckPosition(cp_offset, on_outside_input);
377}
378
379
380bool RegExpMacroAssemblerTracer::CheckSpecialCharacterClass(
381    uc16 type,
382    Label* on_no_match) {
383  bool supported = assembler_->CheckSpecialCharacterClass(type,
384                                                          on_no_match);
385  PrintF(" CheckSpecialCharacterClass(type='%c', label[%08x]): %s;\n",
386         type,
387         LabelToInt(on_no_match),
388         supported ? "true" : "false");
389  return supported;
390}
391
392
393void RegExpMacroAssemblerTracer::IfRegisterLT(int register_index,
394                                              int comparand, Label* if_lt) {
395  PrintF(" IfRegisterLT(register=%d, number=%d, label[%08x]);\n",
396         register_index, comparand, LabelToInt(if_lt));
397  assembler_->IfRegisterLT(register_index, comparand, if_lt);
398}
399
400
401void RegExpMacroAssemblerTracer::IfRegisterEqPos(int register_index,
402                                                 Label* if_eq) {
403  PrintF(" IfRegisterEqPos(register=%d, label[%08x]);\n",
404         register_index, LabelToInt(if_eq));
405  assembler_->IfRegisterEqPos(register_index, if_eq);
406}
407
408
409void RegExpMacroAssemblerTracer::IfRegisterGE(int register_index,
410                                              int comparand, Label* if_ge) {
411  PrintF(" IfRegisterGE(register=%d, number=%d, label[%08x]);\n",
412         register_index, comparand, LabelToInt(if_ge));
413  assembler_->IfRegisterGE(register_index, comparand, if_ge);
414}
415
416
417RegExpMacroAssembler::IrregexpImplementation
418    RegExpMacroAssemblerTracer::Implementation() {
419  return assembler_->Implementation();
420}
421
422
423Handle<HeapObject> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
424  PrintF(" GetCode(%s);\n", source->ToCString().get());
425  return assembler_->GetCode(source);
426}
427
428}  // namespace internal
429}  // namespace v8
430