Bug 1038544: Implement ubi::Node::zone, to return the JS::Zone to which the node's referent belongs. r=terrence

This commit is contained in:
Jim Blandy 2014-07-31 17:29:40 -07:00
parent 47390ee814
commit e0641ae185
4 changed files with 64 additions and 0 deletions

View File

@ -200,6 +200,10 @@ class Base {
// on |cx| and return nullptr.
virtual EdgeRange *edges(JSContext *cx) const = 0;
// Return the Zone to which this node's referent belongs, or nullptr if the
// referent is not of a type allocated in SpiderMonkey Zones.
virtual JS::Zone *zone() const = 0;
private:
Base(const Base &rhs) MOZ_DELETE;
Base &operator=(const Base &rhs) MOZ_DELETE;
@ -324,6 +328,7 @@ class Node {
const jschar *typeName() const { return base()->typeName(); }
size_t size() const { return base()->size(); }
EdgeRange *edges(JSContext *cx) const { return base()->edges(cx); }
JS::Zone *zone() const { return base()->zone(); }
// A hash policy for ubi::Nodes.
// This simply uses the stock PointerHasher on the ubi::Node's pointer.
@ -417,8 +422,10 @@ class TracerConcrete : public Base {
const jschar *typeName() const MOZ_OVERRIDE { return concreteTypeName; }
size_t size() const MOZ_OVERRIDE { return 0; } // not implemented yet; bug 1011300
EdgeRange *edges(JSContext *) const MOZ_OVERRIDE;
JS::Zone *zone() const MOZ_OVERRIDE { return get().zone(); }
TracerConcrete(Referent *ptr) : Base(ptr) { }
Referent &get() const { return *static_cast<Referent *>(ptr); }
public:
static const jschar concreteTypeName[];
@ -441,6 +448,7 @@ class Concrete<void> : public Base {
const jschar *typeName() const MOZ_OVERRIDE;
size_t size() const MOZ_OVERRIDE;
EdgeRange *edges(JSContext *cx) const MOZ_OVERRIDE;
JS::Zone *zone() const MOZ_OVERRIDE;
Concrete(void *ptr) : Base(ptr) { }

View File

@ -72,6 +72,7 @@ UNIFIED_SOURCES += [
'testSymbol.cpp',
'testToIntWidth.cpp',
'testTypedArrays.cpp',
'testUbiNode.cpp',
'testUncaughtError.cpp',
'testUTF8.cpp',
'testWeakMap.cpp',

View File

@ -0,0 +1,54 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "js/UbiNode.h"
#include "jsapi-tests/tests.h"
using JS::RootedObject;
using JS::RootedScript;
using JS::RootedString;
// ubi::Node::zone works
BEGIN_TEST(test_ubiNodeZone)
{
RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
CHECK(global1);
CHECK(JS::ubi::Node(global1).zone() == cx->zone());
RootedObject global2(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
JS::FireOnNewGlobalHook));
CHECK(global2);
CHECK(global1->zone() != global2->zone());
CHECK(JS::ubi::Node(global2).zone() == global2->zone());
CHECK(JS::ubi::Node(global2).zone() != global1->zone());
JS::CompileOptions options(cx);
// Create a string and a script in the original zone...
RootedString string1(cx, JS_NewStringCopyZ(cx, "Simpson's Individual Stringettes!"));
CHECK(string1);
RootedScript script1(cx);
CHECK(JS::Compile(cx, global1, options, "", 0, &script1));
{
// ... and then enter global2's zone and create a string and script
// there, too.
JSAutoCompartment ac(cx, global2);
RootedString string2(cx, JS_NewStringCopyZ(cx, "A million household uses!"));
CHECK(string2);
RootedScript script2(cx);
CHECK(JS::Compile(cx, global2, options, "", 0, &script2));
CHECK(JS::ubi::Node(string1).zone() == global1->zone());
CHECK(JS::ubi::Node(script1).zone() == global1->zone());
CHECK(JS::ubi::Node(string2).zone() == global2->zone());
CHECK(JS::ubi::Node(script2).zone() == global2->zone());
}
return true;
}
END_TEST(test_ubiNodeZone)

View File

@ -31,6 +31,7 @@ using JS::ubi::TracerConcrete;
const jschar *Concrete<void>::typeName() const { MOZ_CRASH("null ubi::Node"); }
size_t Concrete<void>::size() const { MOZ_CRASH("null ubi::Node"); }
EdgeRange *Concrete<void>::edges(JSContext *) const { MOZ_CRASH("null ubi::Node"); }
JS::Zone *Concrete<void>::zone() const { MOZ_CRASH("null ubi::Node"); }
Node::Node(JSGCTraceKind kind, void *ptr)
{