зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1820855 - [hazards] Extract out a function matcher r=jonco
Differential Revision: https://phabricator.services.mozilla.com/D171896
This commit is contained in:
Родитель
523c84d23b
Коммит
61bc9951f6
|
@ -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 &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче