зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1024774
- Part 11: Implement a JS::ubi::Node specialization for DeserializedNode; r=jimb
This commit is contained in:
Родитель
d000a5ce40
Коммит
b9bae0d887
|
@ -187,6 +187,21 @@ 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>.
|
||||
//
|
||||
// (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;
|
||||
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.
|
||||
|
@ -365,20 +380,8 @@ class Node {
|
|||
return base()->edges(cx, wantNames);
|
||||
}
|
||||
|
||||
// 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>.
|
||||
//
|
||||
// (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;
|
||||
Id identifier() const { return reinterpret_cast<Id>(base()->ptr); }
|
||||
typedef Base::Id 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.
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/devtools/DeserializedNode.h"
|
||||
#include "mozilla/devtools/HeapSnapshot.h"
|
||||
#include "nsCRTGlue.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace devtools {
|
||||
|
@ -107,3 +109,86 @@ DeserializedNode::getEdgeReferent(const DeserializedEdge &edge)
|
|||
|
||||
} // namespace devtools
|
||||
} // namespace mozilla
|
||||
|
||||
namespace JS {
|
||||
namespace ubi {
|
||||
|
||||
using mozilla::devtools::DeserializedEdge;
|
||||
|
||||
const char16_t Concrete<DeserializedNode>::concreteTypeName[] =
|
||||
MOZ_UTF16("mozilla::devtools::DeserializedNode");
|
||||
|
||||
const char16_t *
|
||||
Concrete<DeserializedNode>::typeName() const
|
||||
{
|
||||
return get().typeName;
|
||||
}
|
||||
|
||||
size_t
|
||||
Concrete<DeserializedNode>::size(mozilla::MallocSizeOf mallocSizeof) const
|
||||
{
|
||||
return get().size;
|
||||
}
|
||||
|
||||
class DeserializedEdgeRange : public EdgeRange
|
||||
{
|
||||
SimpleEdgeVector edges;
|
||||
size_t i;
|
||||
|
||||
void settle() {
|
||||
front_ = i < edges.length() ? &edges[i] : nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit DeserializedEdgeRange(JSContext* cx)
|
||||
: edges(cx)
|
||||
, i(0)
|
||||
{
|
||||
settle();
|
||||
}
|
||||
|
||||
bool init(DeserializedNode &node)
|
||||
{
|
||||
if (!edges.reserve(node.edges.length()))
|
||||
return false;
|
||||
|
||||
for (DeserializedEdge *edgep = node.edges.begin();
|
||||
edgep != node.edges.end();
|
||||
edgep++)
|
||||
{
|
||||
char16_t *name = nullptr;
|
||||
if (edgep->name) {
|
||||
name = NS_strdup(edgep->name);
|
||||
if (!name)
|
||||
return false;
|
||||
}
|
||||
|
||||
DeserializedNode &referent = node.getEdgeReferent(*edgep);
|
||||
edges.infallibleAppend(mozilla::Move(SimpleEdge(name, Node(&referent))));
|
||||
}
|
||||
|
||||
settle();
|
||||
return true;
|
||||
}
|
||||
|
||||
void popFront() override
|
||||
{
|
||||
i++;
|
||||
settle();
|
||||
}
|
||||
};
|
||||
|
||||
UniquePtr<EdgeRange>
|
||||
Concrete<DeserializedNode>::edges(JSContext* cx, bool) const
|
||||
{
|
||||
UniquePtr<DeserializedEdgeRange, JS::DeletePolicy<DeserializedEdgeRange>> range(
|
||||
js_new<DeserializedEdgeRange>(cx));
|
||||
|
||||
if (!range || !range->init(get()))
|
||||
return nullptr;
|
||||
|
||||
return UniquePtr<EdgeRange>(range.release());
|
||||
}
|
||||
|
||||
} // namespace JS
|
||||
} // namespace ubi
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef mozilla_devtools_DeserializedNode__
|
||||
#define mozilla_devtools_DeserializedNode__
|
||||
|
||||
#include "js/UbiNode.h"
|
||||
#include "mozilla/devtools/CoreDump.pb.h"
|
||||
#include "mozilla/MaybeOneOf.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
@ -88,4 +89,39 @@ private:
|
|||
} // namespace devtools
|
||||
} // namespace mozilla
|
||||
|
||||
namespace JS {
|
||||
namespace ubi {
|
||||
|
||||
using mozilla::devtools::DeserializedNode;
|
||||
using mozilla::UniquePtr;
|
||||
|
||||
template<>
|
||||
struct Concrete<DeserializedNode> : public Base
|
||||
{
|
||||
protected:
|
||||
explicit Concrete(DeserializedNode *ptr) : Base(ptr) { }
|
||||
DeserializedNode &get() const {
|
||||
return *static_cast<DeserializedNode *>(ptr);
|
||||
}
|
||||
|
||||
public:
|
||||
static const char16_t concreteTypeName[];
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
} // namespace JS
|
||||
} // namespace ubi
|
||||
|
||||
#endif // mozilla_devtools_DeserializedNode__
|
||||
|
|
Загрузка…
Ссылка в новой задаче