зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1196634 - Part 0: Define a JS::ubi::CoarseType enum; r=sfink
This commit defines the JS::ubi::CoarseType enum and a corresponding method coarseType() on JS::ubi::Node base and concrete classes. It implements the overrides for all concrete specializations whose referent does not belong to the default Other type.
This commit is contained in:
Родитель
8c7417603d
Коммит
ae6af42629
|
@ -437,6 +437,25 @@ bool ConstructSavedFrameStackSlow(JSContext* cx, JS::ubi::StackFrame& frame,
|
|||
|
||||
/*** ubi::Node ************************************************************************************/
|
||||
|
||||
// A concrete node specialization can claim its referent is a member of a
|
||||
// particular "coarse type" which is less specific than the actual
|
||||
// implementation type but generally more palatable for web developers. For
|
||||
// example, JitCode can be considered to have a coarse type of "Script". This is
|
||||
// used by some analyses for putting nodes into different buckets. The default,
|
||||
// if a concrete specialization does not provide its own mapping to a CoarseType
|
||||
// variant, is "Other".
|
||||
//
|
||||
// NB: the values associated with a particular enum variant must not change or
|
||||
// be reused for new variants. Doing so will cause inspecting ubi::Node's backed
|
||||
// by an offline heap snapshot from an older SpiderMonkey/Firefox version to
|
||||
// break. Consider this enum append only.
|
||||
enum class CoarseType: uint32_t {
|
||||
Object = 0,
|
||||
Script = 1,
|
||||
String = 2,
|
||||
Other = 3
|
||||
};
|
||||
|
||||
// The base class implemented by each ubi::Node referent type. Subclasses must
|
||||
// not add data members to this class.
|
||||
class Base {
|
||||
|
@ -485,6 +504,9 @@ class Base {
|
|||
// otherwise.
|
||||
virtual bool isLive() const { return true; };
|
||||
|
||||
// Return the coarse-grained type-of-thing that this node represents.
|
||||
virtual CoarseType coarseType() const { return CoarseType::Other; }
|
||||
|
||||
// Return a human-readable name for the referent's type. The result should
|
||||
// be statically allocated. (You can use MOZ_UTF16("strings") for this.)
|
||||
//
|
||||
|
@ -680,6 +702,7 @@ class Node {
|
|||
// not all!) JSObjects can be exposed.
|
||||
JS::Value exposeToJS() const;
|
||||
|
||||
CoarseType coarseType() const { return base()->coarseType(); }
|
||||
const char16_t* typeName() const { return base()->typeName(); }
|
||||
JS::Zone* zone() const { return base()->zone(); }
|
||||
JSCompartment* compartment() const { return base()->compartment(); }
|
||||
|
@ -963,7 +986,16 @@ class TracerConcreteWithCompartment : public TracerConcrete<Referent> {
|
|||
// Define specializations for some commonly-used public JSAPI types.
|
||||
// These can use the generic templates above.
|
||||
template<> struct Concrete<JS::Symbol> : TracerConcrete<JS::Symbol> { };
|
||||
template<> struct Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> { };
|
||||
|
||||
template<> struct Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> {
|
||||
CoarseType coarseType() const final { return CoarseType::Script; }
|
||||
|
||||
protected:
|
||||
explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment<JSScript>(ptr) { }
|
||||
|
||||
public:
|
||||
static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); }
|
||||
};
|
||||
|
||||
// The JSObject specialization.
|
||||
template<>
|
||||
|
@ -976,6 +1008,8 @@ class Concrete<JSObject> : public TracerConcreteWithCompartment<JSObject> {
|
|||
bool hasAllocationStack() const override;
|
||||
StackFrame allocationStack() const override;
|
||||
|
||||
CoarseType coarseType() const final { return CoarseType::Object; }
|
||||
|
||||
protected:
|
||||
explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { }
|
||||
|
||||
|
@ -989,6 +1023,8 @@ class Concrete<JSObject> : public TracerConcreteWithCompartment<JSObject> {
|
|||
template<> struct Concrete<JSString> : TracerConcrete<JSString> {
|
||||
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
|
||||
|
||||
CoarseType coarseType() const final { return CoarseType::String; }
|
||||
|
||||
protected:
|
||||
explicit Concrete(JSString *ptr) : TracerConcrete<JSString>(ptr) { }
|
||||
|
||||
|
@ -1004,6 +1040,7 @@ class Concrete<void> : public Base {
|
|||
UniquePtr<EdgeRange> edges(JSContext* cx, bool wantNames) const override;
|
||||
JS::Zone* zone() const override;
|
||||
JSCompartment* compartment() const override;
|
||||
CoarseType coarseType() const final;
|
||||
|
||||
explicit Concrete(void* ptr) : Base(ptr) { }
|
||||
|
||||
|
|
|
@ -776,7 +776,17 @@ IsMarked(const jit::VMFunction*)
|
|||
// instances with no associated compartment.
|
||||
namespace JS {
|
||||
namespace ubi {
|
||||
template<> struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> { };
|
||||
template<>
|
||||
struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> {
|
||||
CoarseType coarseType() const final { return CoarseType::Script; }
|
||||
|
||||
protected:
|
||||
explicit Concrete(js::jit::JitCode *ptr) : TracerConcrete<js::jit::JitCode>(ptr) { }
|
||||
|
||||
public:
|
||||
static void construct(void *storage, js::jit::JitCode *ptr) { new (storage) Concrete(ptr); }
|
||||
};
|
||||
|
||||
} // namespace ubi
|
||||
} // namespace JS
|
||||
|
||||
|
|
|
@ -195,3 +195,31 @@ BEGIN_TEST(test_ubiStackFrame)
|
|||
return true;
|
||||
}
|
||||
END_TEST(test_ubiStackFrame)
|
||||
|
||||
BEGIN_TEST(test_ubiCoarseType)
|
||||
{
|
||||
// Test that our explicit coarseType() overrides work as expected.
|
||||
|
||||
JSObject* obj = nullptr;
|
||||
CHECK(JS::ubi::Node(obj).coarseType() == JS::ubi::CoarseType::Object);
|
||||
|
||||
JSScript* script = nullptr;
|
||||
CHECK(JS::ubi::Node(script).coarseType() == JS::ubi::CoarseType::Script);
|
||||
|
||||
js::LazyScript* lazyScript = nullptr;
|
||||
CHECK(JS::ubi::Node(lazyScript).coarseType() == JS::ubi::CoarseType::Script);
|
||||
|
||||
js::jit::JitCode* jitCode = nullptr;
|
||||
CHECK(JS::ubi::Node(jitCode).coarseType() == JS::ubi::CoarseType::Script);
|
||||
|
||||
JSString* str = nullptr;
|
||||
CHECK(JS::ubi::Node(str).coarseType() == JS::ubi::CoarseType::String);
|
||||
|
||||
// Test that the default when coarseType() is not overridden is Other.
|
||||
|
||||
JS::Symbol* sym = nullptr;
|
||||
CHECK(JS::ubi::Node(sym).coarseType() == JS::ubi::CoarseType::Other);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(test_ubiCoarseType)
|
||||
|
|
|
@ -2408,7 +2408,16 @@ CloneGlobalScript(JSContext* cx, Handle<ScopeObject*> enclosingScope, HandleScri
|
|||
// with no associated compartment.
|
||||
namespace JS {
|
||||
namespace ubi {
|
||||
template<> struct Concrete<js::LazyScript> : TracerConcrete<js::LazyScript> { };
|
||||
template<>
|
||||
struct Concrete<js::LazyScript> : TracerConcrete<js::LazyScript> {
|
||||
CoarseType coarseType() const final { return CoarseType::Script; }
|
||||
|
||||
protected:
|
||||
explicit Concrete(js::LazyScript *ptr) : TracerConcrete<js::LazyScript>(ptr) { }
|
||||
|
||||
public:
|
||||
static void construct(void *storage, js::LazyScript *ptr) { new (storage) Concrete(ptr); }
|
||||
};
|
||||
} // namespace ubi
|
||||
} // namespace JS
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ using JS::HandleValue;
|
|||
using JS::Value;
|
||||
using JS::ZoneSet;
|
||||
using JS::ubi::AtomOrTwoByteChars;
|
||||
using JS::ubi::CoarseType;
|
||||
using JS::ubi::Concrete;
|
||||
using JS::ubi::Edge;
|
||||
using JS::ubi::EdgeRange;
|
||||
|
@ -272,6 +273,7 @@ Node::getCanonicalTypeName(const char16_t* dupe, size_t length)
|
|||
}
|
||||
|
||||
// All operations on null ubi::Nodes crash.
|
||||
CoarseType Concrete<void>::coarseType() const { MOZ_CRASH("null ubi::Node"); }
|
||||
const char16_t* Concrete<void>::typeName() const { MOZ_CRASH("null ubi::Node"); }
|
||||
JS::Zone* Concrete<void>::zone() const { MOZ_CRASH("null ubi::Node"); }
|
||||
JSCompartment* Concrete<void>::compartment() const { MOZ_CRASH("null ubi::Node"); }
|
||||
|
|
Загрузка…
Ссылка в новой задаче