Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/devtools/shared/heapsnapshot/DeserializedNode.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*-  Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "mozilla/devtools/DeserializedNode.h"
7
#include "mozilla/devtools/HeapSnapshot.h"
8
#include "nsCRTGlue.h"
9
10
namespace mozilla {
11
namespace devtools {
12
13
DeserializedEdge::DeserializedEdge(DeserializedEdge&& rhs)
14
0
{
15
0
  referent = rhs.referent;
16
0
  name = rhs.name;
17
0
}
18
19
DeserializedEdge& DeserializedEdge::operator=(DeserializedEdge&& rhs)
20
0
{
21
0
  MOZ_ASSERT(&rhs != this);
22
0
  this->~DeserializedEdge();
23
0
  new(this) DeserializedEdge(std::move(rhs));
24
0
  return *this;
25
0
}
26
27
JS::ubi::Node
28
DeserializedNode::getEdgeReferent(const DeserializedEdge& edge)
29
0
{
30
0
  auto ptr = owner->nodes.lookup(edge.referent);
31
0
  MOZ_ASSERT(ptr);
32
0
33
0
  // `HashSets` only provide const access to their values, because mutating a
34
0
  // value might change its hash, rendering it unfindable in the set.
35
0
  // Unfortunately, the `ubi::Node` constructor requires a non-const pointer to
36
0
  // its referent.  However, the only aspect of a `DeserializedNode` we hash on
37
0
  // is its id, which can't be changed via `ubi::Node`, so this cast can't cause
38
0
  // the trouble `HashSet` is concerned a non-const reference would cause.
39
0
  return JS::ubi::Node(const_cast<DeserializedNode*>(&*ptr));
40
0
}
41
42
JS::ubi::StackFrame
43
DeserializedStackFrame::getParentStackFrame() const
44
0
{
45
0
  MOZ_ASSERT(parent.isSome());
46
0
  auto ptr = owner->frames.lookup(parent.ref());
47
0
  MOZ_ASSERT(ptr);
48
0
  // See above comment in DeserializedNode::getEdgeReferent about why this
49
0
  // const_cast is needed and safe.
50
0
  return JS::ubi::StackFrame(const_cast<DeserializedStackFrame*>(&*ptr));
51
0
}
52
53
} // namespace devtools
54
} // namespace mozilla
55
56
namespace JS {
57
namespace ubi {
58
59
using mozilla::devtools::DeserializedEdge;
60
61
const char16_t Concrete<DeserializedNode>::concreteTypeName[] =
62
  u"mozilla::devtools::DeserializedNode";
63
64
const char16_t*
65
Concrete<DeserializedNode>::typeName() const
66
0
{
67
0
  return get().typeName;
68
0
}
69
70
Node::Size
71
Concrete<DeserializedNode>::size(mozilla::MallocSizeOf mallocSizeof) const
72
0
{
73
0
  return get().size;
74
0
}
75
76
class DeserializedEdgeRange : public EdgeRange
77
{
78
  DeserializedNode* node;
79
  Edge              currentEdge;
80
  size_t            i;
81
82
0
  void settle() {
83
0
    if (i >= node->edges.length()) {
84
0
      front_ = nullptr;
85
0
      return;
86
0
    }
87
0
88
0
    auto& edge = node->edges[i];
89
0
    auto referent = node->getEdgeReferent(edge);
90
0
    currentEdge = Edge(edge.name ? NS_xstrdup(edge.name) : nullptr, referent);
91
0
    front_ = &currentEdge;
92
0
  }
93
94
public:
95
  explicit DeserializedEdgeRange(DeserializedNode& node)
96
    : node(&node)
97
    , i(0)
98
0
  {
99
0
    settle();
100
0
  }
101
102
  void popFront() override
103
0
  {
104
0
    i++;
105
0
    settle();
106
0
  }
107
};
108
109
StackFrame
110
Concrete<DeserializedNode>::allocationStack() const
111
0
{
112
0
  MOZ_ASSERT(hasAllocationStack());
113
0
  auto id = get().allocationStack.ref();
114
0
  auto ptr = get().owner->frames.lookup(id);
115
0
  MOZ_ASSERT(ptr);
116
0
  // See above comment in DeserializedNode::getEdgeReferent about why this
117
0
  // const_cast is needed and safe.
118
0
  return JS::ubi::StackFrame(const_cast<DeserializedStackFrame*>(&*ptr));
119
0
}
120
121
122
js::UniquePtr<EdgeRange>
123
Concrete<DeserializedNode>::edges(JSContext* cx, bool) const
124
0
{
125
0
  js::UniquePtr<DeserializedEdgeRange> range(js_new<DeserializedEdgeRange>(get()));
126
0
127
0
  if (!range)
128
0
    return nullptr;
129
0
130
0
  return js::UniquePtr<EdgeRange>(range.release());
131
0
}
132
133
StackFrame
134
ConcreteStackFrame<DeserializedStackFrame>::parent() const
135
0
{
136
0
  return get().parent.isNothing() ? StackFrame() : get().getParentStackFrame();
137
0
}
138
139
bool
140
ConcreteStackFrame<DeserializedStackFrame>::constructSavedFrameStack(
141
  JSContext* cx,
142
  MutableHandleObject outSavedFrameStack) const
143
0
{
144
0
  StackFrame f(&get());
145
0
  return ConstructSavedFrameStackSlow(cx, f, outSavedFrameStack);
146
0
}
147
148
} // namespace ubi
149
} // namespace JS