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