1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "regexp-macro-assembler.h"
31 #include "regexp-macro-assembler-tracer.h"
36 RegExpMacroAssemblerTracer::RegExpMacroAssemblerTracer(
37 RegExpMacroAssembler* assembler) :
38 assembler_(assembler) {
39 unsigned int type = assembler->Implementation();
41 const char* impl_names[] = {"IA32", "ARM", "MIPS", "X64", "Bytecode"};
42 PrintF("RegExpMacroAssembler%s();\n", impl_names[type]);
46 RegExpMacroAssemblerTracer::~RegExpMacroAssemblerTracer() {
50 // This is used for printing out debugging information. It makes an integer
51 // that is closely related to the address of an object.
52 static int LabelToInt(Label* label) {
53 return static_cast<int>(reinterpret_cast<intptr_t>(label));
57 void RegExpMacroAssemblerTracer::Bind(Label* label) {
58 PrintF("label[%08x]: (Bind)\n", LabelToInt(label));
59 assembler_->Bind(label);
63 void RegExpMacroAssemblerTracer::AdvanceCurrentPosition(int by) {
64 PrintF(" AdvanceCurrentPosition(by=%d);\n", by);
65 assembler_->AdvanceCurrentPosition(by);
69 void RegExpMacroAssemblerTracer::CheckGreedyLoop(Label* label) {
70 PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label));
71 assembler_->CheckGreedyLoop(label);
75 void RegExpMacroAssemblerTracer::PopCurrentPosition() {
76 PrintF(" PopCurrentPosition();\n");
77 assembler_->PopCurrentPosition();
81 void RegExpMacroAssemblerTracer::PushCurrentPosition() {
82 PrintF(" PushCurrentPosition();\n");
83 assembler_->PushCurrentPosition();
87 void RegExpMacroAssemblerTracer::Backtrack() {
88 PrintF(" Backtrack();\n");
89 assembler_->Backtrack();
93 void RegExpMacroAssemblerTracer::GoTo(Label* label) {
94 PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label));
95 assembler_->GoTo(label);
99 void RegExpMacroAssemblerTracer::PushBacktrack(Label* label) {
100 PrintF(" PushBacktrack(label[%08x]);\n", LabelToInt(label));
101 assembler_->PushBacktrack(label);
105 void RegExpMacroAssemblerTracer::Succeed() {
106 PrintF(" Succeed();\n");
107 assembler_->Succeed();
111 void RegExpMacroAssemblerTracer::Fail() {
112 PrintF(" Fail();\n");
117 void RegExpMacroAssemblerTracer::PopRegister(int register_index) {
118 PrintF(" PopRegister(register=%d);\n", register_index);
119 assembler_->PopRegister(register_index);
123 void RegExpMacroAssemblerTracer::PushRegister(
125 StackCheckFlag check_stack_limit) {
126 PrintF(" PushRegister(register=%d, %s);\n",
128 check_stack_limit ? "check stack limit" : "");
129 assembler_->PushRegister(register_index, check_stack_limit);
133 void RegExpMacroAssemblerTracer::AdvanceRegister(int reg, int by) {
134 PrintF(" AdvanceRegister(register=%d, by=%d);\n", reg, by);
135 assembler_->AdvanceRegister(reg, by);
139 void RegExpMacroAssemblerTracer::SetCurrentPositionFromEnd(int by) {
140 PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by);
141 assembler_->SetCurrentPositionFromEnd(by);
145 void RegExpMacroAssemblerTracer::SetRegister(int register_index, int to) {
146 PrintF(" SetRegister(register=%d, to=%d);\n", register_index, to);
147 assembler_->SetRegister(register_index, to);
151 void RegExpMacroAssemblerTracer::WriteCurrentPositionToRegister(int reg,
153 PrintF(" WriteCurrentPositionToRegister(register=%d,cp_offset=%d);\n",
156 assembler_->WriteCurrentPositionToRegister(reg, cp_offset);
160 void RegExpMacroAssemblerTracer::ClearRegisters(int reg_from, int reg_to) {
161 PrintF(" ClearRegister(from=%d, to=%d);\n", reg_from, reg_to);
162 assembler_->ClearRegisters(reg_from, reg_to);
166 void RegExpMacroAssemblerTracer::ReadCurrentPositionFromRegister(int reg) {
167 PrintF(" ReadCurrentPositionFromRegister(register=%d);\n", reg);
168 assembler_->ReadCurrentPositionFromRegister(reg);
172 void RegExpMacroAssemblerTracer::WriteStackPointerToRegister(int reg) {
173 PrintF(" WriteStackPointerToRegister(register=%d);\n", reg);
174 assembler_->WriteStackPointerToRegister(reg);
178 void RegExpMacroAssemblerTracer::ReadStackPointerFromRegister(int reg) {
179 PrintF(" ReadStackPointerFromRegister(register=%d);\n", reg);
180 assembler_->ReadStackPointerFromRegister(reg);
184 void RegExpMacroAssemblerTracer::LoadCurrentCharacter(int cp_offset,
185 Label* on_end_of_input,
188 const char* check_msg = check_bounds ? "" : " (unchecked)";
189 PrintF(" LoadCurrentCharacter(cp_offset=%d, label[%08x]%s (%d chars));\n",
191 LabelToInt(on_end_of_input),
194 assembler_->LoadCurrentCharacter(cp_offset,
201 class PrintablePrinter {
203 explicit PrintablePrinter(uc16 character) : character_(character) { }
205 const char* operator*() {
206 if (character_ >= ' ' && character_ <= '~') {
208 buffer_[1] = static_cast<char>(character_);
223 void RegExpMacroAssemblerTracer::CheckCharacterLT(uc16 limit, Label* on_less) {
224 PrintablePrinter printable(limit);
225 PrintF(" CheckCharacterLT(c=0x%04x%s, label[%08x]);\n",
228 LabelToInt(on_less));
229 assembler_->CheckCharacterLT(limit, on_less);
233 void RegExpMacroAssemblerTracer::CheckCharacterGT(uc16 limit,
235 PrintablePrinter printable(limit);
236 PrintF(" CheckCharacterGT(c=0x%04x%s, label[%08x]);\n",
239 LabelToInt(on_greater));
240 assembler_->CheckCharacterGT(limit, on_greater);
244 void RegExpMacroAssemblerTracer::CheckCharacter(unsigned c, Label* on_equal) {
245 PrintablePrinter printable(c);
246 PrintF(" CheckCharacter(c=0x%04x%s, label[%08x]);\n",
249 LabelToInt(on_equal));
250 assembler_->CheckCharacter(c, on_equal);
254 void RegExpMacroAssemblerTracer::CheckAtStart(Label* on_at_start) {
255 PrintF(" CheckAtStart(label[%08x]);\n", LabelToInt(on_at_start));
256 assembler_->CheckAtStart(on_at_start);
260 void RegExpMacroAssemblerTracer::CheckNotAtStart(Label* on_not_at_start) {
261 PrintF(" CheckNotAtStart(label[%08x]);\n", LabelToInt(on_not_at_start));
262 assembler_->CheckNotAtStart(on_not_at_start);
266 void RegExpMacroAssemblerTracer::CheckNotCharacter(unsigned c,
267 Label* on_not_equal) {
268 PrintablePrinter printable(c);
269 PrintF(" CheckNotCharacter(c=0x%04x%s, label[%08x]);\n",
272 LabelToInt(on_not_equal));
273 assembler_->CheckNotCharacter(c, on_not_equal);
277 void RegExpMacroAssemblerTracer::CheckCharacterAfterAnd(
281 PrintablePrinter printable(c);
282 PrintF(" CheckCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
286 LabelToInt(on_equal));
287 assembler_->CheckCharacterAfterAnd(c, mask, on_equal);
291 void RegExpMacroAssemblerTracer::CheckNotCharacterAfterAnd(
294 Label* on_not_equal) {
295 PrintablePrinter printable(c);
296 PrintF(" CheckNotCharacterAfterAnd(c=0x%04x%s, mask=0x%04x, label[%08x]);\n",
300 LabelToInt(on_not_equal));
301 assembler_->CheckNotCharacterAfterAnd(c, mask, on_not_equal);
305 void RegExpMacroAssemblerTracer::CheckNotCharacterAfterMinusAnd(
309 Label* on_not_equal) {
310 PrintF(" CheckNotCharacterAfterMinusAnd(c=0x%04x, minus=%04x, mask=0x%04x, "
315 LabelToInt(on_not_equal));
316 assembler_->CheckNotCharacterAfterMinusAnd(c, minus, mask, on_not_equal);
320 void RegExpMacroAssemblerTracer::CheckCharacterInRange(
323 Label* on_not_in_range) {
324 PrintablePrinter printable_from(from);
325 PrintablePrinter printable_to(to);
326 PrintF(" CheckCharacterInRange(from=0x%04x%s, to=0x%04x%s, label[%08x]);\n",
331 LabelToInt(on_not_in_range));
332 assembler_->CheckCharacterInRange(from, to, on_not_in_range);
336 void RegExpMacroAssemblerTracer::CheckCharacterNotInRange(
339 Label* on_in_range) {
340 PrintablePrinter printable_from(from);
341 PrintablePrinter printable_to(to);
343 " CheckCharacterNotInRange(from=0x%04x%s," " to=%04x%s, label[%08x]);\n",
348 LabelToInt(on_in_range));
349 assembler_->CheckCharacterNotInRange(from, to, on_in_range);
353 void RegExpMacroAssemblerTracer::CheckBitInTable(
354 Handle<ByteArray> table, Label* on_bit_set) {
355 PrintF(" CheckBitInTable(label[%08x] ", LabelToInt(on_bit_set));
356 for (int i = 0; i < kTableSize; i++) {
357 PrintF("%c", table->get(i) != 0 ? 'X' : '.');
358 if (i % 32 == 31 && i != kTableMask) {
363 assembler_->CheckBitInTable(table, on_bit_set);
367 void RegExpMacroAssemblerTracer::CheckNotBackReference(int start_reg,
368 Label* on_no_match) {
369 PrintF(" CheckNotBackReference(register=%d, label[%08x]);\n", start_reg,
370 LabelToInt(on_no_match));
371 assembler_->CheckNotBackReference(start_reg, on_no_match);
375 void RegExpMacroAssemblerTracer::CheckNotBackReferenceIgnoreCase(
377 Label* on_no_match) {
378 PrintF(" CheckNotBackReferenceIgnoreCase(register=%d, label[%08x]);\n",
379 start_reg, LabelToInt(on_no_match));
380 assembler_->CheckNotBackReferenceIgnoreCase(start_reg, on_no_match);
384 void RegExpMacroAssemblerTracer::CheckNotRegistersEqual(int reg1,
386 Label* on_not_equal) {
387 PrintF(" CheckNotRegistersEqual(reg1=%d, reg2=%d, label[%08x]);\n",
390 LabelToInt(on_not_equal));
391 assembler_->CheckNotRegistersEqual(reg1, reg2, on_not_equal);
395 void RegExpMacroAssemblerTracer::CheckCharacters(Vector<const uc16> str,
398 bool check_end_of_string) {
400 check_end_of_string ? "CheckCharacters" : "CheckCharactersUnchecked");
401 for (int i = 0; i < str.length(); i++) {
402 PrintF("0x%04x", str[i]);
404 PrintF("\", cp_offset=%d, label[%08x])\n",
405 cp_offset, LabelToInt(on_failure));
406 assembler_->CheckCharacters(str, cp_offset, on_failure, check_end_of_string);
410 bool RegExpMacroAssemblerTracer::CheckSpecialCharacterClass(
412 Label* on_no_match) {
413 bool supported = assembler_->CheckSpecialCharacterClass(type,
415 PrintF(" CheckSpecialCharacterClass(type='%c', label[%08x]): %s;\n",
417 LabelToInt(on_no_match),
418 supported ? "true" : "false");
423 void RegExpMacroAssemblerTracer::IfRegisterLT(int register_index,
424 int comparand, Label* if_lt) {
425 PrintF(" IfRegisterLT(register=%d, number=%d, label[%08x]);\n",
426 register_index, comparand, LabelToInt(if_lt));
427 assembler_->IfRegisterLT(register_index, comparand, if_lt);
431 void RegExpMacroAssemblerTracer::IfRegisterEqPos(int register_index,
433 PrintF(" IfRegisterEqPos(register=%d, label[%08x]);\n",
434 register_index, LabelToInt(if_eq));
435 assembler_->IfRegisterEqPos(register_index, if_eq);
439 void RegExpMacroAssemblerTracer::IfRegisterGE(int register_index,
440 int comparand, Label* if_ge) {
441 PrintF(" IfRegisterGE(register=%d, number=%d, label[%08x]);\n",
442 register_index, comparand, LabelToInt(if_ge));
443 assembler_->IfRegisterGE(register_index, comparand, if_ge);
447 RegExpMacroAssembler::IrregexpImplementation
448 RegExpMacroAssemblerTracer::Implementation() {
449 return assembler_->Implementation();
453 Handle<HeapObject> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
454 PrintF(" GetCode(%s);\n", *(source->ToCString()));
455 return assembler_->GetCode(source);
458 }} // namespace v8::internal