Skip to content

Commit 7029bde

Browse files
ricklavoiemeta-codesync[bot]
authored andcommitted
Stop speculate from infinite looping in HHBBC
Summary: If we optimize a block, HHBBC will then speculate to the next block, seeing if we can replace the jump to the next block with a further block. The logic was not taking into account that we might speculate the same block recursively. If this happens (see attached test case for simple example), then hhbbc will infinite loop. Prevent this by keeping a "seen" set during speculating, and bailing out if we hit a block we already hit. Reviewed By: jano Differential Revision: D93157056 fbshipit-source-id: 0888761b31f826e94c803d54f6eec04ca47b9edf
1 parent bef5880 commit 7029bde

3 files changed

Lines changed: 20 additions & 2 deletions

File tree

hphp/hhbbc/interp.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6406,8 +6406,10 @@ BlockId speculateHelper(ISS& env, BlockId orig, bool updateTaken) {
64066406

64076407
auto const& func = env.ctx.func;
64086408

6409+
hphp_fast_set<BlockId> seen;
6410+
64096411
State temp{env.state, State::Compact{}};
6410-
while (true) {
6412+
do {
64116413
auto const targetBlk = func.blocks()[target].get();
64126414
if (!targetBlk->multiPred) break;
64136415
auto const ok = [&] {
@@ -6439,7 +6441,7 @@ BlockId speculateHelper(ISS& env, BlockId orig, bool updateTaken) {
64396441
pops += delta;
64406442
target = new_target;
64416443
temp.stack.compact();
6442-
}
6444+
} while (seen.emplace(target).second);
64436445

64446446
if (endsInControlFlow && updateTaken) {
64456447
assertx(!pops);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?hh
2+
3+
function blah() {
4+
while (1 !== 0) {}
5+
}
6+
7+
<<__EntryPoint>>
8+
function main() {
9+
if (__hhvm_intrinsics\launder_value(false)) {
10+
blah();
11+
echo "not reached\n";
12+
} else {
13+
echo "DONE\n";
14+
}
15+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DONE

0 commit comments

Comments
 (0)