| /* -*- Mode: Javascript; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| |
| "use strict"; |
| |
| load('utility.js'); |
| load('annotations.js'); |
| |
| function processCSU(csu, body) |
| { |
| if (!("DataField" in body)) |
| return; |
| for (var field of body.DataField) { |
| var type = field.Field.Type; |
| if (type.Kind == "Pointer") { |
| var target = type.Type; |
| if (target.Kind == "CSU") |
| addNestedPointer(csu, target.Name); |
| } |
| 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; |
| addNestedStructure(csu, type.Name); |
| } |
| } |
| } |
| |
| function addNestedStructure(csu, inner) |
| { |
| if (!(inner in structureParents)) |
| structureParents[inner] = []; |
| structureParents[inner].push(csu); |
| } |
| |
| function addNestedPointer(csu, inner) |
| { |
| if (!(inner in pointerParents)) |
| pointerParents[inner] = []; |
| pointerParents[inner].push(csu); |
| } |
| |
| var structureParents = {}; |
| var pointerParents = {}; |
| |
| var xdb = xdbLibrary(); |
| xdb.open("src_comp.xdb"); |
| |
| var minStream = xdb.min_data_stream(); |
| var maxStream = xdb.max_data_stream(); |
| |
| for (var csuIndex = minStream; csuIndex <= maxStream; csuIndex++) { |
| var csu = xdb.read_key(csuIndex); |
| var data = xdb.read_entry(csu); |
| var json = JSON.parse(data.readString()); |
| assert(json.length == 1); |
| processCSU(csu.readString(), json[0]); |
| |
| xdb.free_string(csu); |
| xdb.free_string(data); |
| } |
| |
| function addGCType(name) |
| { |
| if (isRootedTypeName(name)) |
| return; |
| |
| print("GCThing: " + name); |
| if (name in structureParents) { |
| for (var nested of structureParents[name]) |
| addGCType(nested); |
| } |
| if (name in pointerParents) { |
| for (var nested of pointerParents[name]) |
| addGCPointer(nested); |
| } |
| } |
| |
| function addGCPointer(name) |
| { |
| // Ignore types which are properly rooted. |
| if (isRootedPointerTypeName(name)) |
| return; |
| |
| print("GCPointer: " + name); |
| if (name in structureParents) { |
| for (var nested of structureParents[name]) |
| addGCPointer(nested); |
| } |
| } |
| |
| addGCType('js::ObjectImpl'); |
| addGCType('JSString'); |
| addGCType('js::Shape'); |
| addGCType('js::BaseShape'); |
| addGCType('JSScript'); |
| addGCType('js::ion::IonCode'); |
| addGCPointer('JS::Value'); |
| addGCPointer('jsid'); |