Bug 908825 - Minor irrelevant cleanups to static rooting analysis

--HG--
extra : rebase_source : 63c13fc6817fc14b2c47357bf213d7a6615f1f35
This commit is contained in:
Steve Fink 2013-07-26 10:40:36 -07:00
parent c67629095b
commit d2a44236c2
4 changed files with 54 additions and 40 deletions

View File

@ -21,14 +21,14 @@ var numBatches = (scriptArgs[4]|0) || 1;
var tmpfile = scriptArgs[5] || "tmp.txt";
var gcFunctions = {};
var text = snarf("gcFunctions.lst").split('\n');
var text = snarf("gcFunctions.lst").split("\n");
assert(text.pop().length == 0);
for (var line of text) {
gcFunctions[line] = true;
}
var suppressedFunctions = {};
var text = snarf("suppressedFunctions.lst").split('\n');
var text = snarf(suppressedFunctionsFile).split("\n");
assert(text.pop().length == 0);
for (var line of text) {
suppressedFunctions[line] = true;
@ -39,14 +39,14 @@ var match;
var gcThings = {};
var gcPointers = {};
var gcTypesText = snarf(gcTypesFile).split('\n');
for (var line of gcTypesText) {
text = snarf(gcTypesFile).split("\n");
for (var line of text) {
if (match = /GCThing: (.*)/.exec(line))
gcThings[match[1]] = true;
if (match = /GCPointer: (.*)/.exec(line))
gcPointers[match[1]] = true;
}
gcTypesText = null;
text = null;
function isUnrootedType(type)
{
@ -246,6 +246,10 @@ function computePredecessors(body)
function variableUseFollowsGC(suppressed, variable, worklist)
{
// Scan through all edges following an unrooted variable use, using an
// explicit worklist. A worklist contains a following edge together with a
// description of where one of its predecessors GC'd (if any).
while (worklist.length) {
var entry = worklist.pop();
var body = entry.body, ppoint = entry.ppoint;
@ -263,7 +267,7 @@ function variableUseFollowsGC(suppressed, variable, worklist)
if (ppoint == body.Index[0]) {
if (body.BlockId.Kind == "Loop") {
// propagate to parents which enter the loop body.
// propagate to parents that enter the loop body.
if ("BlockPPoint" in body) {
for (var parent of body.BlockPPoint) {
var found = false;
@ -301,8 +305,8 @@ function variableUseFollowsGC(suppressed, variable, worklist)
}
var gcInfo = entry.gcInfo;
if (!gcInfo && !(edge.Index[0] in body.suppressed) && !suppressed) {
var gcName = edgeCanGC(edge);
if (!gcInfo && !(source in body.suppressed) && !suppressed) {
var gcName = edgeCanGC(edge, body);
if (gcName)
gcInfo = {name:gcName, body:body, ppoint:source};
}
@ -338,10 +342,14 @@ function variableUseFollowsGC(suppressed, variable, worklist)
function variableLiveAcrossGC(suppressed, variable)
{
// A variable is live across a GC if (1) it is used by an edge, and (2) it
// is used after a GC in a successor edge.
for (var body of functionBodies) {
body.seen = null;
body.minimumUse = 0;
}
for (var body of functionBodies) {
if (!("PEdge" in body))
continue;

View File

@ -40,62 +40,62 @@ function loadCallgraph(file)
{
var textLines = snarf(file).split('\n');
for (var line of textLines) {
var match;
var match;
if (match = /^\#(\d+) (.*)/.exec(line)) {
assert(functionNames.length == match[1]);
functionNames.push(match[2]);
continue;
}
var suppressed = false;
if (/SUPPRESS_GC/.test(line)) {
var suppressed = false;
if (/SUPPRESS_GC/.test(line)) {
match = /^(..)SUPPRESS_GC (.*)/.exec(line);
line = match[1] + match[2];
suppressed = true;
}
if (match = /^I (\d+) VARIABLE ([^\,]*)/.exec(line)) {
}
if (match = /^I (\d+) VARIABLE ([^\,]*)/.exec(line)) {
var caller = functionNames[match[1]];
var name = match[2];
if (!indirectCallCannotGC(caller, name) && !suppressed)
addGCFunction(caller, "IndirectCall: " + name);
} else if (match = /^F (\d+) CLASS (.*?) FIELD (.*)/.exec(line)) {
addGCFunction(caller, "IndirectCall: " + name);
} else if (match = /^F (\d+) CLASS (.*?) FIELD (.*)/.exec(line)) {
var caller = functionNames[match[1]];
var csu = match[2];
var fullfield = csu + "." + match[3];
if (!fieldCallCannotGC(csu, fullfield) && !suppressed)
addGCFunction(caller, "FieldCall: " + fullfield);
} else if (match = /^D (\d+) (\d+)/.exec(line)) {
addGCFunction(caller, "FieldCall: " + fullfield);
} else if (match = /^D (\d+) (\d+)/.exec(line)) {
var caller = functionNames[match[1]];
var callee = functionNames[match[2]];
addCallEdge(caller, callee, suppressed);
}
}
}
var worklist = [];
for (var name in callerGraph)
suppressedFunctions[name] = true;
suppressedFunctions[name] = true;
for (var name in calleeGraph) {
if (!(name in callerGraph)) {
if (!(name in callerGraph)) {
suppressedFunctions[name] = true;
worklist.push(name);
}
}
}
while (worklist.length) {
name = worklist.pop();
if (shouldSuppressGC(name))
name = worklist.pop();
if (shouldSuppressGC(name))
continue;
if (!(name in suppressedFunctions))
if (!(name in suppressedFunctions))
continue;
delete suppressedFunctions[name];
if (!(name in calleeGraph))
delete suppressedFunctions[name];
if (!(name in calleeGraph))
continue;
for (var entry of calleeGraph[name]) {
for (var entry of calleeGraph[name]) {
if (!entry.suppressed)
worklist.push(entry.callee);
}
worklist.push(entry.callee);
}
}
for (var name in gcFunctions) {
if (name in suppressedFunctions)
if (name in suppressedFunctions)
delete gcFunctions[name];
}
@ -108,16 +108,16 @@ function loadCallgraph(file)
var worklist = [];
for (var name in gcFunctions)
worklist.push(name);
worklist.push(name);
while (worklist.length) {
name = worklist.pop();
assert(name in gcFunctions);
if (!(name in callerGraph))
name = worklist.pop();
assert(name in gcFunctions);
if (!(name in callerGraph))
continue;
for (var entry of callerGraph[name]) {
for (var entry of callerGraph[name]) {
if (!entry.suppressed && addGCFunction(entry.caller, name))
worklist.push(entry.caller);
}
worklist.push(entry.caller);
}
}
}

View File

@ -53,6 +53,7 @@ function computeSuppressedPoints(body)
if (!("PEdge" in body))
return;
for (var edge of body.PEdge) {
var source = edge.Index[0];
if (!(source in successors))

View File

@ -2,9 +2,14 @@
"use strict";
function assert(x)
function assert(x, msg)
{
if (!x)
if (x)
return;
debugger;
if (msg)
throw "assertion failed: " + msg + "\n" + (Error().stack);
else
throw "assertion failed: " + (Error().stack);
}
@ -45,7 +50,7 @@ function sameVariable(var0, var1)
assert("Name" in var0 || var0.Kind == "This" || var0.Kind == "Return");
assert("Name" in var1 || var1.Kind == "This" || var1.Kind == "Return");
if ("Name" in var0)
return "Name" in var1 && var0.Name[0] == var1.Name[0];
return "Name" in var1 && var0.Name[0] == var1.Name[0];
return var0.Kind == var1.Kind;
}