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 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 24 RegExpMacroAssemblerTracer::~RegExpMacroAssemblerTracer() { 25 } 26 27 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. 36 static int LabelToInt(Label* label) { 37 return static_cast<int>(reinterpret_cast<intptr_t>(label)); 38 } 39 40 41 void RegExpMacroAssemblerTracer::Bind(Label* label) { 42 PrintF("label[%08x]: (Bind)\n", LabelToInt(label)); 43 assembler_->Bind(label); 44 } 45 46 47 void RegExpMacroAssemblerTracer::AdvanceCurrentPosition(int by) { 48 PrintF(" AdvanceCurrentPosition(by=%d);\n", by); 49 assembler_->AdvanceCurrentPosition(by); 50 } 51 52 53 void RegExpMacroAssemblerTracer::CheckGreedyLoop(Label* label) { 54 PrintF(" CheckGreedyLoop(label[%08x]);\n\n", LabelToInt(label)); 55 assembler_->CheckGreedyLoop(label); 56 } 57 58 59 void RegExpMacroAssemblerTracer::PopCurrentPosition() { 60 PrintF(" PopCurrentPosition();\n"); 61 assembler_->PopCurrentPosition(); 62 } 63 64 65 void RegExpMacroAssemblerTracer::PushCurrentPosition() { 66 PrintF(" PushCurrentPosition();\n"); 67 assembler_->PushCurrentPosition(); 68 } 69 70 71 void RegExpMacroAssemblerTracer::Backtrack() { 72 PrintF(" Backtrack();\n"); 73 assembler_->Backtrack(); 74 } 75 76 77 void RegExpMacroAssemblerTracer::GoTo(Label* label) { 78 PrintF(" GoTo(label[%08x]);\n\n", LabelToInt(label)); 79 assembler_->GoTo(label); 80 } 81 82 83 void RegExpMacroAssemblerTracer::PushBacktrack(Label* label) { 84 PrintF(" PushBacktrack(label[%08x]);\n", LabelToInt(label)); 85 assembler_->PushBacktrack(label); 86 } 87 88 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 96 void RegExpMacroAssemblerTracer::Fail() { 97 PrintF(" Fail();"); 98 assembler_->Fail(); 99 } 100 101 102 void RegExpMacroAssemblerTracer::PopRegister(int register_index) { 103 PrintF(" PopRegister(register=%d);\n", register_index); 104 assembler_->PopRegister(register_index); 105 } 106 107 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 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 124 void RegExpMacroAssemblerTracer::SetCurrentPositionFromEnd(int by) { 125 PrintF(" SetCurrentPositionFromEnd(by=%d);\n", by); 126 assembler_->SetCurrentPositionFromEnd(by); 127 } 128 129 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 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 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 151 void RegExpMacroAssemblerTracer::ReadCurrentPositionFromRegister(int reg) { 152 PrintF(" ReadCurrentPositionFromRegister(register=%d);\n", reg); 153 assembler_->ReadCurrentPositionFromRegister(reg); 154 } 155 156 157 void RegExpMacroAssemblerTracer::WriteStackPointerToRegister(int reg) { 158 PrintF(" WriteStackPointerToRegister(register=%d);\n", reg); 159 assembler_->WriteStackPointerToRegister(reg); 160 } 161 162 163 void RegExpMacroAssemblerTracer::ReadStackPointerFromRegister(int reg) { 164 PrintF(" ReadStackPointerFromRegister(register=%d);\n", reg); 165 assembler_->ReadStackPointerFromRegister(reg); 166 } 167 168 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: 188 explicit PrintablePrinter(uc16 character) : character_(character) { } 189 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 419 RegExpMacroAssemblerTracer::Implementation() { 420 return assembler_->Implementation(); 421 } 422 423 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