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