Bug 1820855 - [hazards] Extract out a function matcher r=jonco

Differential Revision: https://phabricator.services.mozilla.com/D171896
This commit is contained in:
Steve Fink 2023-04-11 23:08:44 +00:00
Родитель 523c84d23b
Коммит 61bc9951f6
1 изменённых файлов: 49 добавлений и 18 удалений

Просмотреть файл

@ -699,6 +699,45 @@ function edgeStartsValueLiveRange(edge, variable)
return false;
}
// Return the result of a `matcher` callback on the call found in the given
// `edge`, if the edge is a direct call to a named function (if not, return false).
// `matcher` is given the name of the callee (actually, a tuple
// [fully qualified name, base name]), an array of expressions containing the
// arguments, and if the result of the call is assigned to a variable,
// the expression representing that variable(the lhs).
//
// https://firefox-source-docs.mozilla.org/js/HazardAnalysis/CFG.html for
// documentation of the data structure used here.
function matchEdgeCall(edge, matcher) {
if (edge.Kind != "Call") {
return false;
}
const callee = edge.Exp[0];
if (edge.Type.Kind == 'Function' &&
edge.Exp[0].Kind == 'Var' &&
edge.Exp[0].Variable.Kind == 'Func') {
const calleeName = edge.Exp[0].Variable.Name;
const args = edge.PEdgeCallArguments;
const argExprs = args ? args.Exp : [];
const lhs = edge.Exp[1]; // May be undefined
return matcher(calleeName, argExprs, lhs);
}
return false;
}
function edgeMarksVariableGCSafe(edge, variable) {
return matchEdgeCall(edge, (calleeName, argExprs, _lhs) => {
// explicit JS_HAZ_VARIABLE_IS_GC_SAFE annotation
return (calleeName[1] == 'MarkVariableAsGCSafe' &&
calleeName[0].includes("JS::detail::MarkVariableAsGCSafe") &&
argExprs.length == 1 &&
expressionIsVariable(argExprs[0], variable));
});
}
// Match an optional <namespace>:: followed by the class name,
// and then an optional template parameter marker.
//
@ -748,30 +787,20 @@ function edgeEndsValueLiveRange(edge, variable, body)
if (edge.Kind != "Call")
return false;
var callee = edge.Exp[0];
if (edge.Type.Kind == 'Function' &&
edge.Exp[0].Kind == 'Var' &&
edge.Exp[0].Variable.Kind == 'Func' &&
edge.Exp[0].Variable.Name[1] == 'MarkVariableAsGCSafe' &&
edge.Exp[0].Variable.Name[0].includes("JS::detail::MarkVariableAsGCSafe") &&
expressionIsVariable(edge.PEdgeCallArguments.Exp[0], variable))
{
if (edgeMarksVariableGCSafe(edge, variable)) {
// explicit JS_HAZ_VARIABLE_IS_GC_SAFE annotation
return true;
}
const decl = lookupVariable(body, variable);
if (edge.Type.Kind == 'Function' &&
edge.Exp[0].Kind == 'Var' &&
edge.Exp[0].Variable.Kind == 'Func' &&
edge.Exp[0].Variable.Name[1] == 'move' &&
edge.Exp[0].Variable.Name[0].includes('std::move(') &&
expressionIsDeclaredVariable(edge.PEdgeCallArguments.Exp[0], decl) &&
edge.Exp[1].Kind == 'Var' &&
edge.Exp[1].Variable.Kind == 'Temp')
{
if (matchEdgeCall(edge, (calleeName, argExprs, lhs) => {
return calleeName[1] == 'move' && calleeName[0].includes('std::move(') &&
expressionIsDeclaredVariable(argExprs[0], decl) &&
lhs &&
lhs.Kind == 'Var' &&
lhs.Variable.Kind == 'Temp';
})) {
// temp = std::move(var)
//
// If var is a UniquePtr, and we pass it into something that takes
@ -808,6 +837,8 @@ function edgeEndsValueLiveRange(edge, variable, body)
return true;
}
const callee = edge.Exp[0];
if (edge.Type.Kind == 'Function' &&
edge.Type.TypeFunctionCSU &&
edge.PEdgeCallInstance &&