зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1479962 - Add JS_HAZ_ROOTED_BASE for AutoGCRooter, which assumes all descendants are rooted, r=jonco
--HG-- extra : topic : hazard extra : rebase_source : a75561cdf2f71e34a630737dcf832d05d95974b0
This commit is contained in:
Родитель
45873100f5
Коммит
b0006a2c76
|
@ -26,6 +26,12 @@
|
|||
// is not itself a GC pointer.
|
||||
# define JS_HAZ_GC_INVALIDATED __attribute__((tag("Invalidated by GC")))
|
||||
|
||||
// Mark a class as a base class of rooted types, eg CustomAutoRooter. All
|
||||
// descendants of this class will be considered rooted, though classes that
|
||||
// merely contain these as a field member will not be. "Inherited" by
|
||||
// templatized types with MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS
|
||||
# define JS_HAZ_ROOTED_BASE __attribute__((tag("Rooted Base")))
|
||||
|
||||
// Mark a type that would otherwise be considered a GC Pointer (eg because it
|
||||
// contains a JS::Value field) as a non-GC pointer. It is handled almost the
|
||||
// same in the analysis as a rooted pointer, except it will not be reported as
|
||||
|
@ -52,6 +58,7 @@
|
|||
# define JS_HAZ_GC_POINTER
|
||||
# define JS_HAZ_ROOTED
|
||||
# define JS_HAZ_GC_INVALIDATED
|
||||
# define JS_HAZ_ROOTED_BASE
|
||||
# define JS_HAZ_NON_GC_POINTER
|
||||
# define JS_HAZ_GC_CALL
|
||||
# define JS_HAZ_GC_SUPPRESSED
|
||||
|
|
|
@ -945,7 +945,7 @@ class JS_PUBLIC_API(AutoGCRooter)
|
|||
/* No copy or assignment semantics. */
|
||||
AutoGCRooter(AutoGCRooter& ida) = delete;
|
||||
void operator=(AutoGCRooter& ida) = delete;
|
||||
};
|
||||
} JS_HAZ_ROOTED_BASE;
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ var typeInfo = {
|
|||
'NonGCPointers': {},
|
||||
'RootedGCThings': {},
|
||||
'RootedPointers': {},
|
||||
'RootedBases': {'JS::AutoGCRooter': true},
|
||||
|
||||
// RAII types within which we should assume GC is suppressed, eg
|
||||
// AutoSuppressGC.
|
||||
|
@ -36,6 +37,26 @@ var rootedPointers = {};
|
|||
|
||||
function processCSU(csu, body)
|
||||
{
|
||||
for (let { 'Name': [ annType, tag ] } of (body.Annotation || [])) {
|
||||
if (annType != 'Tag')
|
||||
continue;
|
||||
|
||||
if (tag == 'GC Pointer')
|
||||
typeInfo.GCPointers.push(csu);
|
||||
else if (tag == 'Invalidated by GC')
|
||||
typeInfo.GCPointers.push(csu);
|
||||
else if (tag == 'GC Thing')
|
||||
typeInfo.GCThings.push(csu);
|
||||
else if (tag == 'Suppressed GC Pointer')
|
||||
typeInfo.NonGCPointers[csu] = true;
|
||||
else if (tag == 'Rooted Pointer')
|
||||
typeInfo.RootedPointers[csu] = true;
|
||||
else if (tag == 'Rooted Base')
|
||||
typeInfo.RootedBases[csu] = true;
|
||||
else if (tag == 'Suppress GC')
|
||||
typeInfo.GCSuppressors[csu] = true;
|
||||
}
|
||||
|
||||
for (let { 'Base': base } of (body.CSUBaseClass || []))
|
||||
addBaseClass(csu, base);
|
||||
|
||||
|
@ -52,31 +73,8 @@ function processCSU(csu, body)
|
|||
if (target.Kind == "CSU")
|
||||
addNestedStructure(csu, target.Name, fieldName);
|
||||
}
|
||||
if (type.Kind == "CSU") {
|
||||
// Ignore nesting in classes which are AutoGCRooters. We only consider
|
||||
// types with fields that may not be properly rooted.
|
||||
if (type.Name == "JS::AutoGCRooter" || type.Name == "JS::CustomAutoRooter")
|
||||
return;
|
||||
if (type.Kind == "CSU")
|
||||
addNestedStructure(csu, type.Name, fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
for (let { 'Name': [ annType, tag ] } of (body.Annotation || [])) {
|
||||
if (annType != 'Tag')
|
||||
continue;
|
||||
|
||||
if (tag == 'GC Pointer')
|
||||
typeInfo.GCPointers.push(csu);
|
||||
else if (tag == 'Invalidated by GC')
|
||||
typeInfo.GCPointers.push(csu);
|
||||
else if (tag == 'GC Thing')
|
||||
typeInfo.GCThings.push(csu);
|
||||
else if (tag == 'Suppressed GC Pointer')
|
||||
typeInfo.NonGCPointers[csu] = true;
|
||||
else if (tag == 'Rooted Pointer')
|
||||
typeInfo.RootedPointers[csu] = true;
|
||||
else if (tag == 'Suppress GC')
|
||||
typeInfo.GCSuppressors[csu] = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,6 +84,8 @@ function addNestedStructure(csu, inner, field)
|
|||
if (!(inner in structureParents))
|
||||
structureParents[inner] = [];
|
||||
|
||||
// Skip fields that are really base classes, to avoid duplicating the base
|
||||
// fields; addBaseClass already added a "base-N" name.
|
||||
if (field.match(/^field:\d+$/) && (csu in baseClasses) && (baseClasses[csu].indexOf(inner) != -1))
|
||||
return;
|
||||
|
||||
|
@ -140,6 +140,16 @@ for (const csu of typeInfo.GCThings)
|
|||
for (const csu of typeInfo.GCPointers)
|
||||
addGCPointer(csu);
|
||||
|
||||
// Everything that inherits from a "Rooted Base" is considered to be rooted.
|
||||
// This is for things like CustomAutoRooter and its subclasses.
|
||||
var basework = Object.keys(typeInfo.RootedBases);
|
||||
while (basework.length) {
|
||||
const base = basework.pop();
|
||||
typeInfo.RootedPointers[base] = true;
|
||||
if (base in subClasses)
|
||||
basework.push(...subClasses[base]);
|
||||
}
|
||||
|
||||
// "typeName is a (pointer to a)^'typePtrLevel' GC type because it contains a field
|
||||
// named 'child' of type 'why' (or pointer to 'why' if fieldPtrLevel == 1), which is
|
||||
// itself a GCThing or GCPointer."
|
||||
|
@ -230,7 +240,7 @@ function addGCPointer(typeName)
|
|||
|
||||
// Call a function for a type and every type that contains the type in a field
|
||||
// or as a base class (which internally is pretty much the same thing --
|
||||
// sublcasses are structs beginning with the base class and adding on their
|
||||
// subclasses are structs beginning with the base class and adding on their
|
||||
// local fields.)
|
||||
function foreachContainingStruct(typeName, func, seen = new Set())
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче