Bug 1199216 - Implement JS::ubi::Node::size for JSScript referents; r=sfink

This commit is contained in:
Nick Fitzgerald 2015-09-22 12:15:23 -07:00
parent 44fa198fb1
commit d856feb452
4 changed files with 99 additions and 0 deletions

View File

@ -1020,6 +1020,7 @@ struct Concrete<JS::Symbol> : TracerConcrete<JS::Symbol> {
template<> struct Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> {
CoarseType coarseType() const final { return CoarseType::Script; }
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
protected:
explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment<JSScript>(ptr) { }

View File

@ -2463,6 +2463,34 @@ ByteSize(JSContext* cx, unsigned argc, Value* vp)
return true;
}
static bool
ByteSizeOfScript(JSContext*cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.requireAtLeast(cx, "byteSizeOfScript", 1))
return false;
if (!args[0].isObject() || !args[0].toObject().is<JSFunction>()) {
JS_ReportError(cx, "Argument must be a Function object");
return false;
}
RootedScript script(cx, args[0].toObject().as<JSFunction>().getOrCreateScript(cx));
mozilla::MallocSizeOf mallocSizeOf = cx->runtime()->debuggerMallocSizeOf;
{
// We can't tolerate the GC moving things around while we're using a
// ubi::Node. Check that nothing we do causes a GC.
JS::AutoCheckCannotGC autoCannotGC;
JS::ubi::Node node = script;
if (node)
args.rval().setNumber(uint32_t(node.size(mallocSizeOf)));
else
args.rval().setUndefined();
}
return true;
}
static bool
ImmutablePrototypesEnabled(JSContext* cx, unsigned argc, Value* vp)
{
@ -3224,6 +3252,10 @@ gc::ZealModeHelpText),
" Return the size in bytes occupied by |value|, or |undefined| if value\n"
" is not allocated in memory.\n"),
JS_FN_HELP("byteSizeOfScript", ByteSizeOfScript, 1, 0,
"byteSizeOfScript(f)",
" Return the size in bytes occupied by the function |f|'s JSScript.\n"),
JS_FN_HELP("immutablePrototypesEnabled", ImmutablePrototypesEnabled, 0, 0,
"immutablePrototypesEnabled()",
" Returns true if immutable-prototype behavior (triggered by setImmutablePrototype)\n"

View File

@ -0,0 +1,46 @@
// Check JS::ubi::Node::size results for scripts. We don't attempt to check
// exact sizes in this test (deemed to difficult and non-deterministic), just
// some sanity checks.
function f1() {
return 42;
}
print("byteSizeOfScript(f1) = " + byteSizeOfScript(f1));
assertEq(byteSizeOfScript(f1) > 1, true);
function f2(n) {
var obj = {
x: 1,
y: 2,
z: 3,
};
if (i % 2 == 0) {
for (var i = 0; i < n; i++) {
this.x += i;
print(uneval(i));
obj[i] = i * i;
if (i > 10) {
f2(i / f1());
}
}
}
if (i % 3 == 0) {
for (var i = 0; i < n; i++) {
this.x *= i;
print(uneval(i));
obj[i] = i * i;
if (i > 10) {
f2(i / f1());
}
}
}
return this.x;
}
print("byteSizeOfScript(f2) = " + byteSizeOfScript(f2));
assertEq(byteSizeOfScript(f2) > 1, true);
assertEq(byteSizeOfScript(f2) > byteSizeOfScript(f1), true);

View File

@ -4319,3 +4319,23 @@ JSScript::AutoDelazify::dropScript()
script_->setDoNotRelazify(oldDoNotRelazify_);
script_ = nullptr;
}
JS::ubi::Node::Size
JS::ubi::Concrete<JSScript>::size(mozilla::MallocSizeOf mallocSizeOf) const
{
Size size = Arena::thingSize(get().asTenured().getAllocKind());
size += get().sizeOfData(mallocSizeOf);
size += get().sizeOfTypeScript(mallocSizeOf);
size_t baselineSize = 0;
size_t baselineStubsSize = 0;
jit::AddSizeOfBaselineData(&get(), mallocSizeOf, &baselineSize, &baselineStubsSize);
size += baselineSize;
size += baselineStubsSize;
size += jit::SizeOfIonData(&get(), mallocSizeOf);
MOZ_ASSERT(size > 0);
return size;
}