author | Steve Fink <sfink@mozilla.com> |
Fri, 04 Jan 2019 13:18:00 -0800 | |
changeset 458987 | 5e40a711ed0a |
parent 458986 | 2a8867abaa0f |
child 458988 | 7e7f4d97d178 |
push id | 35553 |
push user | shindli@mozilla.com |
push date | Thu, 14 Feb 2019 04:41:18 +0000 |
treeherder | mozilla-central@f0ea53f47215 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jonco |
bugs | 1500247 |
milestone | 67.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/devtools/rootAnalysis/analyzeRoots.js +++ b/js/src/devtools/rootAnalysis/analyzeRoots.js @@ -448,36 +448,38 @@ function edgeInvalidatesVariable(edge, v if (edge.Type.Kind == 'Function' && edge.Type.TypeFunctionCSU && edge.PEdgeCallInstance && edge.PEdgeCallInstance.Exp.Kind == 'Var' && expressionIsVariable(edge.PEdgeCallInstance.Exp, variable)) do { const typeName = edge.Type.TypeFunctionCSU.Type.Name; - const m = typeName.match(/^mozilla::(\w+)</); + const m = typeName.match(/^(((\w|::)+?)(\w+))</); if (!m) break; - const type = m[1]; - if (!["Maybe", "UniquePtr"].includes(type)) - break; + const [, type, namespace,, classname] = m; - // special-case: (type)::reset() + // special-case: the initial constructor that doesn't provide a value. + // Useful for things like Maybe<T>. if (callee.Kind == 'Var' && - callee.Variable.Name[1] == 'reset') + typesWithSafeConstructors.has(type) && + callee.Variable.Name[0].includes(`${namespace}${classname}<T>::${classname}()`)) { return true; } - // special-case: the initial constructor that doesn't provide a value. + // special-case: UniquePtr::reset() and similar. if (callee.Kind == 'Var' && - callee.Variable.Name[0].includes(`mozilla::${type}<T>::${type}()`)) + type in resetterMethods && + resetterMethods[type].has(callee.Variable.Name[1])) { return true; } + } while(0); // special-case: passing UniquePtr<T> by value. if (edge.Type.Kind == 'Function' && edge.Type.TypeFunctionArgument && edge.PEdgeCallArguments) { for (const i in edge.Type.TypeFunctionArgument) {
--- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -7,16 +7,33 @@ var ignoreIndirectCalls = { "mallocSizeOf" : true, "aMallocSizeOf" : true, "__conv" : true, "__convf" : true, "prerrortable.c:callback_newtable" : true, "mozalloc_oom.cpp:void (* gAbortHandler)(size_t)" : true, }; +// Types that when constructed with no arguments, are "safe" values (they do +// not contain GC pointers). +var typesWithSafeConstructors = new Set([ + "mozilla::Maybe", + "mozilla::dom::Nullable", + "mozilla::dom::Optional", + "mozilla::UniquePtr", + "js::UniquePtr" +]); + +var resetterMethods = { + 'mozilla::Maybe': new Set(["reset"]), + 'mozilla::UniquePtr': new Set(["reset"]), + 'js::UniquePtr': new Set(["reset"]), + 'mozilla::dom::Nullable': new Set(["SetNull"]), +}; + function indirectCallCannotGC(fullCaller, fullVariable) { var caller = readable(fullCaller); // This is usually a simple variable name, but sometimes a full name gets // passed through. And sometimes that name is truncated. Examples: // _ZL13gAbortHandler|mozalloc_oom.cpp:void (* gAbortHandler)(size_t) // _ZL14pMutexUnlockFn|umutex.cpp:void (* pMutexUnlockFn)(const void*
--- a/js/src/devtools/rootAnalysis/t/hazards/source.cpp +++ b/js/src/devtools/rootAnalysis/t/hazards/source.cpp @@ -244,16 +244,23 @@ void safevals() { // Unsafe because it may not be nullptr. Cell* unsafe3 = &cell; if (reinterpret_cast<long>(&cell) & 0x100) { unsafe3 = nullptr; } GC(); use(unsafe3); + // Unsafe because it's not nullptr anymore. + Cell* unsafe3b = &cell; + unsafe3b = nullptr; + unsafe3b = &cell; + GC(); + use(unsafe3b); + // Hazard involving UniquePtr. { mozilla::UniquePtr<Cell> unsafe4(&cell); GC(); // Destructor uses unsafe4. } // reset() to safe value before the GC.
--- a/js/src/devtools/rootAnalysis/t/hazards/test.py +++ b/js/src/devtools/rootAnalysis/t/hazards/test.py @@ -51,15 +51,16 @@ assert('haz5' in hazmap) assert('haz6' not in hazmap) assert('haz7' not in hazmap) assert('haz8' in hazmap) # safevals hazards. See comments in source. assert('unsafe1' in hazmap) assert('safe2' not in hazmap) assert('unsafe3' in hazmap) +assert('unsafe3b' in hazmap) assert('unsafe4' in hazmap) assert('safe5' not in hazmap) assert('safe6' not in hazmap) assert('unsafe7' in hazmap) assert('safe8' not in hazmap) assert('safe9' not in hazmap) assert('safe10' not in hazmap)