Skip to content

Commit

Permalink
FunctionAnalysis: Allow CacheNewObject to use new.target
Browse files Browse the repository at this point in the history
Summary:
`new.target` was considered to escape if the callee ever used
NewTargetParam, which is overly restrictive in light of CacheNewObject,
which we know won't let it escape.

Allow it to be used in FunctionAnalysis without returning `true` from
`canEscapeThroughCall`.

Reviewed By: neildhar

Differential Revision: D66395118

fbshipit-source-id: 399f029ca24a35b8171ce29fcbc203fd92e82585
  • Loading branch information
avp authored and facebook-github-bot committed Dec 4, 2024
1 parent 4ee72d0 commit 7bee3d9
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions lib/Optimizer/Scalar/FunctionAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,24 @@ bool canEscapeThroughCall(Instruction *C, Function *F, BaseCallInst *CI) {
return true;

// Check if the closure is passed as the new.target argument, and the function
// actually uses it.
// TODO: Allow certain instructions to use new.target.
if (C == CI->getNewTarget() && F->getNewTargetParam()->hasUsers())
return true;
// actually uses it in a way that can escape.
if (C == CI->getNewTarget()) {
// If NewTargetParam has no users, the closure can't escape through it.
// Check all the users to see if there's any that might let it escape.
for (auto *newTargetUser : F->getNewTargetParam()->getUsers()) {
auto *getNewTarget = llvh::dyn_cast<GetNewTargetInst>(newTargetUser);
if (!getNewTarget) {
// Unknown user of NewTargetParam.
return true;
}
for (auto *getNewTargetUser : getNewTarget->getUsers()) {
// Certain instructions are known not to leak new.target even if they
// use it.
if (!llvh::isa<CacheNewObjectInst>(getNewTargetUser))
return true;
}
}
}

return false;
}
Expand Down

0 comments on commit 7bee3d9

Please sign in to comment.