Bug 1198980 - Make JS::ubi::*::identifier be uint64_t instead of uintptr_t. r=sfink
authorNick Fitzgerald <fitzgen@gmail.com>
Thu, 27 Aug 2015 09:17:00 -0400
changeset 259696 a45c3750a16c2fd3ec84e1ab9db00d0de5b46485
parent 259695 461098c64803456b37018d44a7b7c4f9586c053b
child 259697 10592387dea48e4495fd0ad970ad5e859829620e
push id29287
push userryanvm@gmail.com
push dateFri, 28 Aug 2015 01:31:40 +0000
treeherdermozilla-central@87e23922be37 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1198980
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1198980 - Make JS::ubi::*::identifier be uint64_t instead of uintptr_t. r=sfink
js/public/UbiNode.h
js/src/jsobj.cpp
js/src/vm/String.cpp
js/src/vm/UbiNode.cpp
toolkit/devtools/server/DeserializedNode.cpp
toolkit/devtools/server/DeserializedNode.h
toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp
toolkit/devtools/server/tests/gtest/DeserializedStackFrameUbiStackFrames.cpp
toolkit/devtools/server/tests/gtest/DevTools.h
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -196,17 +196,17 @@ class BaseStackFrame {
     explicit BaseStackFrame(void* ptr) : ptr(ptr) { }
 
   public:
     // This is a value type that should not have a virtual destructor. Don't add
     // destructors in subclasses!
 
     // Get a unique identifier for this StackFrame. The identifier is not valid
     // across garbage collections.
-    virtual uintptr_t identifier() const { return reinterpret_cast<uintptr_t>(ptr); }
+    virtual uint64_t identifier() const { return reinterpret_cast<uint64_t>(ptr); }
 
     // Get this frame's parent frame.
     virtual StackFrame parent() const = 0;
 
     // Get this frame's line number.
     virtual uint32_t line() const = 0;
 
     // Get this frame's column number.
@@ -371,17 +371,17 @@ class StackFrame : public JS::Traceable 
     static void trace(StackFrame* frame, JSTracer* trc) {
         if (frame)
             frame->trace(trc);
     }
 
     // Methods that forward to virtual calls through BaseStackFrame.
 
     void trace(JSTracer* trc) { base()->trace(trc); }
-    uintptr_t identifier() const { return base()->identifier(); }
+    uint64_t identifier() const { return base()->identifier(); }
     uint32_t line() const { return base()->line(); }
     uint32_t column() const { return base()->column(); }
     AtomOrTwoByteChars source() const { return base()->source(); }
     AtomOrTwoByteChars functionDisplayName() const { return base()->functionDisplayName(); }
     StackFrame parent() const { return base()->parent(); }
     bool isSystem() const { return base()->isSystem(); }
     bool isSelfHosted() const { return base()->isSelfHosted(); }
     bool constructSavedFrameStack(JSContext* cx,
@@ -410,17 +410,17 @@ class StackFrame : public JS::Traceable 
 // ubi::StackFrame crashes.
 template<>
 class ConcreteStackFrame<void> : public BaseStackFrame {
     explicit ConcreteStackFrame(void* ptr) : BaseStackFrame(ptr) { }
 
   public:
     static void construct(void* storage, void*) { new (storage) ConcreteStackFrame(nullptr); }
 
-    uintptr_t identifier() const override { return 0; }
+    uint64_t identifier() const override { return 0; }
     void trace(JSTracer* trc) override { }
     bool constructSavedFrameStack(JSContext* cx, MutableHandleObject out) const override {
         out.set(nullptr);
         return true;
     }
 
     uint32_t line() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
     uint32_t column() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
@@ -465,24 +465,24 @@ class Base {
     }
     bool operator!=(const Base& rhs) const { return !(*this == rhs); }
 
     // An identifier for this node, guaranteed to be stable and unique for as
     // long as this ubi::Node's referent is alive and at the same address.
     //
     // This is probably suitable for use in serializations, as it is an integral
     // type. It may also help save memory when constructing HashSets of
-    // ubi::Nodes: since a uintptr_t will always be smaller than a ubi::Node, a
-    // HashSet<ubi::Node::Id> will use less space per element than a
-    // HashSet<ubi::Node>.
+    // ubi::Nodes: since a uint64_t will always be smaller-or-equal-to the size
+    // of a ubi::Node, a HashSet<ubi::Node::Id> may use less space per element
+    // than a HashSet<ubi::Node>.
     //
     // (Note that 'unique' only means 'up to equality on ubi::Node'; see the
     // caveats about multiple objects allocated at the same address for
     // 'ubi::Node::operator=='.)
-    typedef uintptr_t Id;
+    using Id = uint64_t;
     virtual Id identifier() const { return reinterpret_cast<Id>(ptr); }
 
     // Returns true if this node is pointing to something on the live heap, as
     // opposed to something from a deserialized core dump. Returns false,
     // otherwise.
     virtual bool isLive() const { return true; };
 
     // Return a human-readable name for the referent's type. The result should
@@ -491,17 +491,18 @@ class Base {
     // This must always return Concrete<T>::concreteTypeName; we use that
     // pointer as a tag for this particular referent type.
     virtual const char16_t* typeName() const = 0;
 
     // Return the size of this node, in bytes. Include any structures that this
     // node owns exclusively that are not exposed as their own ubi::Nodes.
     // |mallocSizeOf| should be a malloc block sizing function; see
     // |mfbt/MemoryReporting.h|.
-    virtual size_t size(mozilla::MallocSizeOf mallocSizeof) const { return 1; }
+    using Size = uint64_t;
+    virtual Size size(mozilla::MallocSizeOf mallocSizeof) const { return 1; }
 
     // Return an EdgeRange that initially contains all the referent's outgoing
     // edges. The caller takes ownership of the EdgeRange.
     //
     // If wantNames is true, compute names for edges. Doing so can be expensive
     // in time and memory.
     virtual UniquePtr<EdgeRange> edges(JSContext* cx, bool wantNames) const = 0;
 
@@ -683,30 +684,31 @@ class Node {
     JS::Zone* zone()                const { return base()->zone(); }
     JSCompartment* compartment()    const { return base()->compartment(); }
     const char* jsObjectClassName() const { return base()->jsObjectClassName(); }
     bool jsObjectConstructorName(JSContext* cx,
                                  UniquePtr<char16_t[], JS::FreePolicy>& outName) const {
         return base()->jsObjectConstructorName(cx, outName);
     }
 
-    size_t size(mozilla::MallocSizeOf mallocSizeof) const {
+    using Size = Base::Size;
+    Size size(mozilla::MallocSizeOf mallocSizeof) const {
         return base()->size(mallocSizeof);
     }
 
     UniquePtr<EdgeRange> edges(JSContext* cx, bool wantNames = true) const {
         return base()->edges(cx, wantNames);
     }
 
     bool hasAllocationStack() const { return base()->hasAllocationStack(); }
     StackFrame allocationStack() const {
         return base()->allocationStack();
     }
 
-    typedef Base::Id Id;
+    using Id = Base::Id;
     Id identifier() const { return base()->identifier(); }
 
     // A hash policy for ubi::Nodes.
     // This simply uses the stock PointerHasher on the ubi::Node's pointer.
     // We specialize DefaultHasher below to make this the default.
     class HashPolicy {
         typedef js::PointerHasher<void*, mozilla::tl::FloorLog2<sizeof(void*)>::value> PtrHash;
 
@@ -964,46 +966,46 @@ template<> struct Concrete<JS::Symbol> :
 template<> struct Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> { };
 
 // The JSObject specialization.
 template<>
 class Concrete<JSObject> : public TracerConcreteWithCompartment<JSObject> {
     const char* jsObjectClassName() const override;
     bool jsObjectConstructorName(JSContext* cx,
                                  UniquePtr<char16_t[], JS::FreePolicy>& outName) const override;
-    size_t size(mozilla::MallocSizeOf mallocSizeOf) const override;
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
 
     bool hasAllocationStack() const override;
     StackFrame allocationStack() const override;
 
   protected:
     explicit Concrete(JSObject* ptr) : TracerConcreteWithCompartment(ptr) { }
 
   public:
     static void construct(void* storage, JSObject* ptr) {
         new (storage) Concrete(ptr);
     }
 };
 
 // For JSString, we extend the generic template with a 'size' implementation.
 template<> struct Concrete<JSString> : TracerConcrete<JSString> {
-    size_t size(mozilla::MallocSizeOf mallocSizeOf) const override;
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
 
   protected:
     explicit Concrete(JSString *ptr) : TracerConcrete<JSString>(ptr) { }
 
   public:
     static void construct(void *storage, JSString *ptr) { new (storage) Concrete(ptr); }
 };
 
 // The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts.
 template<>
 class Concrete<void> : public Base {
     const char16_t* typeName() const override;
-    size_t size(mozilla::MallocSizeOf mallocSizeOf) const override;
+    Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
     UniquePtr<EdgeRange> edges(JSContext* cx, bool wantNames) const override;
     JS::Zone* zone() const override;
     JSCompartment* compartment() const override;
 
     explicit Concrete(void* ptr) : Base(ptr) { }
 
   public:
     static void construct(void* storage, void* ptr) { new (storage) Concrete(ptr); }
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3620,17 +3620,17 @@ JSObject::sizeOfIncludingThisInNursery()
 
         if (is<ArgumentsObject>())
             size += as<ArgumentsObject>().sizeOfData();
     }
 
     return size;
 }
 
-size_t
+JS::ubi::Node::Size
 JS::ubi::Concrete<JSObject>::size(mozilla::MallocSizeOf mallocSizeOf) const
 {
     JSObject& obj = get();
 
     if (!obj.isTenured())
         return obj.sizeOfIncludingThisInNursery();
 
     JS::ClassInfo info;
--- a/js/src/vm/String.cpp
+++ b/js/src/vm/String.cpp
@@ -62,17 +62,17 @@ JSString::sizeOfExcludingThis(mozilla::M
     // JSUndependedString, there is no need to count the base string, for the
     // same reason as JSDependentString above.
     JSFlatString& flat = asFlat();
     return flat.hasLatin1Chars()
            ? mallocSizeOf(flat.rawLatin1Chars())
            : mallocSizeOf(flat.rawTwoByteChars());
 }
 
-size_t
+JS::ubi::Node::Size
 JS::ubi::Concrete<JSString>::size(mozilla::MallocSizeOf mallocSizeOf) const
 {
     JSString &str = get();
     size_t size = str.isFatInline() ? sizeof(JSFatInlineString) : sizeof(JSString);
 
     // We can't use mallocSizeof on things in the nursery. At the moment,
     // strings are never in the nursery, but that may change.
     MOZ_ASSERT(!IsInsideNursery(&str));
--- a/js/src/vm/UbiNode.cpp
+++ b/js/src/vm/UbiNode.cpp
@@ -276,17 +276,17 @@ const char16_t* Concrete<void>::typeName
 JS::Zone* Concrete<void>::zone() const             { MOZ_CRASH("null ubi::Node"); }
 JSCompartment* Concrete<void>::compartment() const { MOZ_CRASH("null ubi::Node"); }
 
 UniquePtr<EdgeRange>
 Concrete<void>::edges(JSContext*, bool) const {
     MOZ_CRASH("null ubi::Node");
 }
 
-size_t
+Node::Size
 Concrete<void>::size(mozilla::MallocSizeOf mallocSizeof) const
 {
     MOZ_CRASH("null ubi::Node");
 }
 
 struct Node::ConstructFunctor : public js::BoolDefaultAdaptor<Value, false> {
     template <typename T> bool operator()(T* t, Node* node) { node->construct(t); return true; }
 };
--- a/toolkit/devtools/server/DeserializedNode.cpp
+++ b/toolkit/devtools/server/DeserializedNode.cpp
@@ -113,17 +113,17 @@ const char16_t Concrete<DeserializedNode
   MOZ_UTF16("mozilla::devtools::DeserializedNode");
 
 const char16_t*
 Concrete<DeserializedNode>::typeName() const
 {
   return get().typeName;
 }
 
-size_t
+Node::Size
 Concrete<DeserializedNode>::size(mozilla::MallocSizeOf mallocSizeof) const
 {
   return get().size;
 }
 
 class DeserializedEdgeRange : public EdgeRange
 {
   SimpleEdgeVector edges;
--- a/toolkit/devtools/server/DeserializedNode.h
+++ b/toolkit/devtools/server/DeserializedNode.h
@@ -223,17 +223,17 @@ public:
 
   static void construct(void* storage, DeserializedNode* ptr) {
     new (storage) Concrete(ptr);
   }
 
   Id identifier() const override { return get().id; }
   bool isLive() const override { return false; }
   const char16_t* typeName() const override;
-  size_t size(mozilla::MallocSizeOf mallocSizeof) const override;
+  Node::Size size(mozilla::MallocSizeOf mallocSizeof) const override;
   const char* jsObjectClassName() const override { return get().jsObjectClassName.get(); }
 
   bool hasAllocationStack() const override { return get().allocationStack.isSome(); }
   StackFrame allocationStack() const override;
 
   // We ignore the `bool wantNames` parameter because we can't control whether
   // the core dump was serialized with edge names or not.
   UniquePtr<EdgeRange> edges(JSContext* cx, bool) const override;
@@ -251,17 +251,17 @@ protected:
     return *static_cast<DeserializedStackFrame*>(ptr);
   }
 
 public:
   static void construct(void* storage, DeserializedStackFrame* ptr) {
     new (storage) ConcreteStackFrame(ptr);
   }
 
-  uintptr_t identifier() const override { return get().id; }
+  uint64_t identifier() const override { return get().id; }
   uint32_t line() const override { return get().line; }
   uint32_t column() const override { return get().column; }
   bool isSystem() const override { return get().isSystem; }
   bool isSelfHosted() const override { return get().isSelfHosted; }
   void trace(JSTracer* trc) override { }
   AtomOrTwoByteChars source() const override {
     return AtomOrTwoByteChars(get().source);
   }
--- a/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp
+++ b/toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp
@@ -35,18 +35,18 @@ size_t fakeMallocSizeOf(const void*) {
                          "DeserializedNodes report the deserialized size.");
   return 0;
 }
 
 DEF_TEST(DeserializedNodeUbiNodes, {
     const char16_t* typeName = MOZ_UTF16("TestTypeName");
     const char* className = "MyObjectClassName";
 
-    NodeId id = 1L << 33;
-    uint64_t size = 1L << 60;
+    NodeId id = uint64_t(1) << 33;
+    uint64_t size = uint64_t(1) << 60;
     MockDeserializedNode mocked(id, typeName, size);
     mocked.jsObjectClassName = mozilla::UniquePtr<char[]>(strdup(className));
     ASSERT_TRUE(!!mocked.jsObjectClassName);
 
     DeserializedNode& deserialized = mocked;
     JS::ubi::Node ubi(&deserialized);
 
     // Test the ubi::Node accessors.
--- a/toolkit/devtools/server/tests/gtest/DeserializedStackFrameUbiStackFrames.cpp
+++ b/toolkit/devtools/server/tests/gtest/DeserializedStackFrameUbiStackFrames.cpp
@@ -16,17 +16,17 @@ using testing::ReturnRef;
 
 // A mock DeserializedStackFrame for testing.
 struct MockDeserializedStackFrame : public DeserializedStackFrame
 {
   MockDeserializedStackFrame() : DeserializedStackFrame() { }
 };
 
 DEF_TEST(DeserializedStackFrameUbiStackFrames, {
-    StackFrameId id = 1L << 42;
+    StackFrameId id = uint64_t(1) << 42;
     uint32_t line = 1337;
     uint32_t column = 9; // 3 space tabs!?
     const char16_t* source = MOZ_UTF16("my-javascript-file.js");
     const char16_t* functionDisplayName = MOZ_UTF16("myFunctionName");
 
     MockDeserializedStackFrame mocked;
     mocked.id = id;
     mocked.line = line;
--- a/toolkit/devtools/server/tests/gtest/DevTools.h
+++ b/toolkit/devtools/server/tests/gtest/DevTools.h
@@ -181,17 +181,17 @@ class Concrete<FakeNode> : public Base
   const char16_t* typeName() const override {
     return concreteTypeName;
   }
 
   UniquePtr<EdgeRange> edges(JSContext* cx, bool wantNames) const override {
     return UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(cx, get().edges));
   }
 
-  size_t size(mozilla::MallocSizeOf) const override {
+  Size size(mozilla::MallocSizeOf) const override {
     return get().size;
   }
 
   JS::Zone* zone() const override {
     return get().zone;
   }
 
   JSCompartment* compartment() const override {