|
52 | 52 | #include <atomic> |
53 | 53 | #include <dlfcn.h> |
54 | 54 | #include <llvm/InitializeLLVM.h> |
| 55 | +#include <unordered_set> |
55 | 56 | #include <wtf/ProcessID.h> |
56 | 57 |
|
57 | 58 | #if ENABLE(FTL_NATIVE_CALL_INLINING) |
@@ -6476,6 +6477,8 @@ class LowerDFGToLLVM { |
6476 | 6477 |
|
6477 | 6478 | Vector<SwitchCase> switchCases; |
6478 | 6479 | for (unsigned i = 0; i < characterCases.size(); ++i) { |
| 6480 | + if (i) |
| 6481 | + DFG_ASSERT(m_graph, m_node, characterCases[i - 1].character < characterCases[i].character); |
6479 | 6482 | switchCases.append(SwitchCase( |
6480 | 6483 | m_out.constInt8(characterCases[i].character), characterBlocks[i], Weight())); |
6481 | 6484 | } |
@@ -6506,12 +6509,47 @@ class LowerDFGToLLVM { |
6506 | 6509 | StringJumpTable& table = codeBlock()->stringSwitchJumpTable(data->switchTableIndex); |
6507 | 6510 |
|
6508 | 6511 | Vector<SwitchCase> cases; |
| 6512 | + std::unordered_set<int32_t> alreadyHandled; // These may be negative, or zero, or probably other stuff, too. We don't want to mess with HashSet's corner cases and we don't really care about throughput here. |
6509 | 6513 | for (unsigned i = 0; i < data->cases.size(); ++i) { |
| 6514 | + // FIXME: The fact that we're using the bytecode's switch table means that the |
| 6515 | + // following DFG IR transformation would be invalid. |
| 6516 | + // |
| 6517 | + // Original code: |
| 6518 | + // switch (v) { |
| 6519 | + // case "foo": |
| 6520 | + // case "bar": |
| 6521 | + // things(); |
| 6522 | + // break; |
| 6523 | + // default: |
| 6524 | + // break; |
| 6525 | + // } |
| 6526 | + // |
| 6527 | + // New code: |
| 6528 | + // switch (v) { |
| 6529 | + // case "foo": |
| 6530 | + // instrumentFoo(); |
| 6531 | + // goto _things; |
| 6532 | + // case "bar": |
| 6533 | + // instrumentBar(); |
| 6534 | + // _things: |
| 6535 | + // things(); |
| 6536 | + // break; |
| 6537 | + // default: |
| 6538 | + // break; |
| 6539 | + // } |
| 6540 | + // |
| 6541 | + // Luckily, we don't currently do any such transformation. But it's kind of silly that |
| 6542 | + // this is an issue. |
| 6543 | + // https://bugs.webkit.org/show_bug.cgi?id=144635 |
| 6544 | + |
6510 | 6545 | DFG::SwitchCase myCase = data->cases[i]; |
6511 | 6546 | StringJumpTable::StringOffsetTable::iterator iter = |
6512 | 6547 | table.offsetTable.find(myCase.value.stringImpl()); |
6513 | 6548 | DFG_ASSERT(m_graph, m_node, iter != table.offsetTable.end()); |
6514 | 6549 |
|
| 6550 | + if (!alreadyHandled.insert(iter->value.branchOffset).second) |
| 6551 | + continue; |
| 6552 | + |
6515 | 6553 | cases.append(SwitchCase( |
6516 | 6554 | m_out.constInt32(iter->value.branchOffset), |
6517 | 6555 | lowBlock(myCase.target.block), Weight(myCase.target.count))); |
|
0 commit comments