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