| Index: test/cctest/test-heap-profiler.cc
|
| diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
|
| index a3e14cb74fbf6bdc6924ae7eafed12087e0c9be9..a2426cc0fe7cf80be3845b597f6221165261b691 100644
|
| --- a/test/cctest/test-heap-profiler.cc
|
| +++ b/test/cctest/test-heap-profiler.cc
|
| @@ -9,381 +9,10 @@
|
| #include "cctest.h"
|
| #include "heap-profiler.h"
|
| #include "snapshot.h"
|
| -#include "string-stream.h"
|
| #include "utils-inl.h"
|
| -#include "zone-inl.h"
|
| #include "../include/v8-profiler.h"
|
|
|
| namespace i = v8::internal;
|
| -using i::ClustersCoarser;
|
| -using i::JSObjectsCluster;
|
| -using i::JSObjectsRetainerTree;
|
| -using i::JSObjectsClusterTree;
|
| -using i::RetainerHeapProfile;
|
| -
|
| -
|
| -namespace {
|
| -
|
| -class ConstructorHeapProfileTestHelper : public i::ConstructorHeapProfile {
|
| - public:
|
| - ConstructorHeapProfileTestHelper()
|
| - : i::ConstructorHeapProfile(),
|
| - f_name_(FACTORY->NewStringFromAscii(i::CStrVector("F"))),
|
| - f_count_(0) {
|
| - }
|
| -
|
| - void Call(const JSObjectsCluster& cluster,
|
| - const i::NumberAndSizeInfo& number_and_size) {
|
| - if (f_name_->Equals(cluster.constructor())) {
|
| - CHECK_EQ(f_count_, 0);
|
| - f_count_ = number_and_size.number();
|
| - CHECK_GT(f_count_, 0);
|
| - }
|
| - }
|
| -
|
| - int f_count() { return f_count_; }
|
| -
|
| - private:
|
| - i::Handle<i::String> f_name_;
|
| - int f_count_;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -
|
| -TEST(ConstructorProfile) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - CompileRun(
|
| - "function F() {} // A constructor\n"
|
| - "var f1 = new F();\n"
|
| - "var f2 = new F();\n");
|
| -
|
| - ConstructorHeapProfileTestHelper cons_profile;
|
| - i::AssertNoAllocation no_alloc;
|
| - i::HeapIterator iterator;
|
| - for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
|
| - cons_profile.CollectStats(obj);
|
| - CHECK_EQ(0, cons_profile.f_count());
|
| - cons_profile.PrintStats();
|
| - CHECK_EQ(2, cons_profile.f_count());
|
| -}
|
| -
|
| -
|
| -static JSObjectsCluster AddHeapObjectToTree(JSObjectsRetainerTree* tree,
|
| - i::String* constructor,
|
| - int instance,
|
| - JSObjectsCluster* ref1 = NULL,
|
| - JSObjectsCluster* ref2 = NULL,
|
| - JSObjectsCluster* ref3 = NULL) {
|
| - JSObjectsCluster o(constructor, reinterpret_cast<i::Object*>(instance));
|
| - JSObjectsClusterTree* o_tree = new JSObjectsClusterTree();
|
| - JSObjectsClusterTree::Locator o_loc;
|
| - if (ref1 != NULL) o_tree->Insert(*ref1, &o_loc);
|
| - if (ref2 != NULL) o_tree->Insert(*ref2, &o_loc);
|
| - if (ref3 != NULL) o_tree->Insert(*ref3, &o_loc);
|
| - JSObjectsRetainerTree::Locator loc;
|
| - tree->Insert(o, &loc);
|
| - loc.set_value(o_tree);
|
| - return o;
|
| -}
|
| -
|
| -
|
| -static void AddSelfReferenceToTree(JSObjectsRetainerTree* tree,
|
| - JSObjectsCluster* self_ref) {
|
| - JSObjectsRetainerTree::Locator loc;
|
| - CHECK(tree->Find(*self_ref, &loc));
|
| - JSObjectsClusterTree::Locator o_loc;
|
| - CHECK_NE(NULL, loc.value());
|
| - loc.value()->Insert(*self_ref, &o_loc);
|
| -}
|
| -
|
| -
|
| -static inline void CheckEqualsHelper(const char* file, int line,
|
| - const char* expected_source,
|
| - const JSObjectsCluster& expected,
|
| - const char* value_source,
|
| - const JSObjectsCluster& value) {
|
| - if (JSObjectsCluster::Compare(expected, value) != 0) {
|
| - i::HeapStringAllocator allocator;
|
| - i::StringStream stream(&allocator);
|
| - stream.Add("# Expected: ");
|
| - expected.DebugPrint(&stream);
|
| - stream.Add("\n# Found: ");
|
| - value.DebugPrint(&stream);
|
| - V8_Fatal(file, line, "CHECK_EQ(%s, %s) failed\n%s",
|
| - expected_source, value_source,
|
| - *stream.ToCString());
|
| - }
|
| -}
|
| -
|
| -
|
| -static inline void CheckNonEqualsHelper(const char* file, int line,
|
| - const char* expected_source,
|
| - const JSObjectsCluster& expected,
|
| - const char* value_source,
|
| - const JSObjectsCluster& value) {
|
| - if (JSObjectsCluster::Compare(expected, value) == 0) {
|
| - i::HeapStringAllocator allocator;
|
| - i::StringStream stream(&allocator);
|
| - stream.Add("# !Expected: ");
|
| - expected.DebugPrint(&stream);
|
| - stream.Add("\n# Found: ");
|
| - value.DebugPrint(&stream);
|
| - V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n%s",
|
| - expected_source, value_source,
|
| - *stream.ToCString());
|
| - }
|
| -}
|
| -
|
| -
|
| -TEST(ClustersCoarserSimple) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
|
| -
|
| - JSObjectsRetainerTree tree;
|
| - JSObjectsCluster function(HEAP->function_class_symbol());
|
| - JSObjectsCluster a(*FACTORY->NewStringFromAscii(i::CStrVector("A")));
|
| - JSObjectsCluster b(*FACTORY->NewStringFromAscii(i::CStrVector("B")));
|
| -
|
| - // o1 <- Function
|
| - JSObjectsCluster o1 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function);
|
| - // o2 <- Function
|
| - JSObjectsCluster o2 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function);
|
| - // o3 <- A, B
|
| - JSObjectsCluster o3 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &a, &b);
|
| - // o4 <- B, A
|
| - JSObjectsCluster o4 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x400, &b, &a);
|
| - // o5 <- A, B, Function
|
| - JSObjectsCluster o5 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x500,
|
| - &a, &b, &function);
|
| -
|
| - ClustersCoarser coarser;
|
| - coarser.Process(&tree);
|
| -
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(o3), coarser.GetCoarseEquivalent(o4));
|
| - CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o3));
|
| - CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o5));
|
| -}
|
| -
|
| -
|
| -TEST(ClustersCoarserMultipleConstructors) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
|
| -
|
| - JSObjectsRetainerTree tree;
|
| - JSObjectsCluster function(HEAP->function_class_symbol());
|
| -
|
| - // o1 <- Function
|
| - JSObjectsCluster o1 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100, &function);
|
| - // a1 <- Function
|
| - JSObjectsCluster a1 =
|
| - AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x1000, &function);
|
| - // o2 <- Function
|
| - JSObjectsCluster o2 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x200, &function);
|
| - // a2 <- Function
|
| - JSObjectsCluster a2 =
|
| - AddHeapObjectToTree(&tree, HEAP->Array_symbol(), 0x2000, &function);
|
| -
|
| - ClustersCoarser coarser;
|
| - coarser.Process(&tree);
|
| -
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(a1), coarser.GetCoarseEquivalent(a2));
|
| -}
|
| -
|
| -
|
| -TEST(ClustersCoarserPathsTraversal) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
|
| -
|
| - JSObjectsRetainerTree tree;
|
| -
|
| - // On the following graph:
|
| - //
|
| - // p
|
| - // <- o21 <- o11 <-
|
| - // q o
|
| - // <- o22 <- o12 <-
|
| - // r
|
| - //
|
| - // we expect that coarser will deduce equivalences: p ~ q ~ r,
|
| - // o21 ~ o22, and o11 ~ o12.
|
| -
|
| - JSObjectsCluster o =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100);
|
| - JSObjectsCluster o11 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o);
|
| - JSObjectsCluster o12 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o);
|
| - JSObjectsCluster o21 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x210, &o11);
|
| - JSObjectsCluster o22 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x220, &o12);
|
| - JSObjectsCluster p =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o21);
|
| - JSObjectsCluster q =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o21, &o22);
|
| - JSObjectsCluster r =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o22);
|
| -
|
| - ClustersCoarser coarser;
|
| - coarser.Process(&tree);
|
| -
|
| - CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
|
| - CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o11));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o12));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(o22));
|
| - CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(o21));
|
| - CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
|
| - CHECK_NE(coarser.GetCoarseEquivalent(o11), coarser.GetCoarseEquivalent(p));
|
| - CHECK_NE(coarser.GetCoarseEquivalent(o21), coarser.GetCoarseEquivalent(p));
|
| -}
|
| -
|
| -
|
| -TEST(ClustersCoarserSelf) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - i::ZoneScope zn_scope(i::Isolate::Current(), i::DELETE_ON_EXIT);
|
| -
|
| - JSObjectsRetainerTree tree;
|
| -
|
| - // On the following graph:
|
| - //
|
| - // p (self-referencing)
|
| - // <- o1 <-
|
| - // q (self-referencing) o
|
| - // <- o2 <-
|
| - // r (self-referencing)
|
| - //
|
| - // we expect that coarser will deduce equivalences: p ~ q ~ r, o1 ~ o2;
|
| -
|
| - JSObjectsCluster o =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x100);
|
| - JSObjectsCluster o1 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x110, &o);
|
| - JSObjectsCluster o2 =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x120, &o);
|
| - JSObjectsCluster p =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x300, &o1);
|
| - AddSelfReferenceToTree(&tree, &p);
|
| - JSObjectsCluster q =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x310, &o1, &o2);
|
| - AddSelfReferenceToTree(&tree, &q);
|
| - JSObjectsCluster r =
|
| - AddHeapObjectToTree(&tree, HEAP->Object_symbol(), 0x320, &o2);
|
| - AddSelfReferenceToTree(&tree, &r);
|
| -
|
| - ClustersCoarser coarser;
|
| - coarser.Process(&tree);
|
| -
|
| - CHECK_EQ(JSObjectsCluster(), coarser.GetCoarseEquivalent(o));
|
| - CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(o1));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(o2));
|
| - CHECK_NE(JSObjectsCluster(), coarser.GetCoarseEquivalent(p));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(p), coarser.GetCoarseEquivalent(q));
|
| - CHECK_EQ(coarser.GetCoarseEquivalent(q), coarser.GetCoarseEquivalent(r));
|
| - CHECK_NE(coarser.GetCoarseEquivalent(o1), coarser.GetCoarseEquivalent(p));
|
| -}
|
| -
|
| -
|
| -namespace {
|
| -
|
| -class RetainerProfilePrinter : public RetainerHeapProfile::Printer {
|
| - public:
|
| - RetainerProfilePrinter() : stream_(&allocator_), lines_(100) {}
|
| -
|
| - void PrintRetainers(const JSObjectsCluster& cluster,
|
| - const i::StringStream& retainers) {
|
| - cluster.Print(&stream_);
|
| - stream_.Add("%s", *(retainers.ToCString()));
|
| - stream_.Put('\0');
|
| - }
|
| -
|
| - const char* GetRetainers(const char* constructor) {
|
| - FillLines();
|
| - const size_t cons_len = strlen(constructor);
|
| - for (int i = 0; i < lines_.length(); ++i) {
|
| - if (strncmp(constructor, lines_[i], cons_len) == 0 &&
|
| - lines_[i][cons_len] == ',') {
|
| - return lines_[i] + cons_len + 1;
|
| - }
|
| - }
|
| - return NULL;
|
| - }
|
| -
|
| - private:
|
| - void FillLines() {
|
| - if (lines_.length() > 0) return;
|
| - stream_.Put('\0');
|
| - stream_str_ = stream_.ToCString();
|
| - const char* pos = *stream_str_;
|
| - while (pos != NULL && *pos != '\0') {
|
| - lines_.Add(pos);
|
| - pos = strchr(pos, '\0');
|
| - if (pos != NULL) ++pos;
|
| - }
|
| - }
|
| -
|
| - i::HeapStringAllocator allocator_;
|
| - i::StringStream stream_;
|
| - i::SmartPointer<const char> stream_str_;
|
| - i::List<const char*> lines_;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -
|
| -TEST(RetainerProfile) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - CompileRun(
|
| - "function A() {}\n"
|
| - "function B(x) { this.x = x; }\n"
|
| - "function C(x) { this.x1 = x; this.x2 = x; }\n"
|
| - "var a = new A();\n"
|
| - "var b1 = new B(a), b2 = new B(a);\n"
|
| - "var c = new C(a);");
|
| -
|
| - RetainerHeapProfile ret_profile;
|
| - i::AssertNoAllocation no_alloc;
|
| - i::HeapIterator iterator;
|
| - for (i::HeapObject* obj = iterator.next(); obj != NULL; obj = iterator.next())
|
| - ret_profile.CollectStats(obj);
|
| - ret_profile.CoarseAndAggregate();
|
| - RetainerProfilePrinter printer;
|
| - ret_profile.DebugPrintStats(&printer);
|
| - const char* retainers_of_a = printer.GetRetainers("A");
|
| - // The order of retainers is unspecified, so we check string length, and
|
| - // verify each retainer separately.
|
| - CHECK_EQ(i::StrLength("(global property);1,B;2,C;2"),
|
| - i::StrLength(retainers_of_a));
|
| - CHECK(strstr(retainers_of_a, "(global property);1") != NULL);
|
| - CHECK(strstr(retainers_of_a, "B;2") != NULL);
|
| - CHECK(strstr(retainers_of_a, "C;2") != NULL);
|
| - CHECK_EQ("(global property);2", printer.GetRetainers("B"));
|
| - CHECK_EQ("(global property);1", printer.GetRetainers("C"));
|
| -}
|
| -
|
|
|
| namespace {
|
|
|
| @@ -726,116 +355,6 @@ TEST(HeapSnapshotRootPreservedAfterSorting) {
|
| }
|
|
|
|
|
| -static const v8::HeapGraphNode* GetChild(
|
| - const v8::HeapGraphNode* node,
|
| - v8::HeapGraphNode::Type type,
|
| - const char* name,
|
| - const v8::HeapGraphNode* after = NULL) {
|
| - bool ignore_child = after == NULL ? false : true;
|
| - for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) {
|
| - const v8::HeapGraphEdge* prop = node->GetChild(i);
|
| - const v8::HeapGraphNode* child = prop->GetToNode();
|
| - v8::String::AsciiValue child_name(child->GetName());
|
| - if (!ignore_child
|
| - && child->GetType() == type
|
| - && strcmp(name, *child_name) == 0)
|
| - return child;
|
| - if (after != NULL && child == after) ignore_child = false;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| -static bool IsNodeRetainedAs(const v8::HeapGraphNode* node,
|
| - int element) {
|
| - for (int i = 0, count = node->GetRetainersCount(); i < count; ++i) {
|
| - const v8::HeapGraphEdge* prop = node->GetRetainer(i);
|
| - if (prop->GetType() == v8::HeapGraphEdge::kElement
|
| - && element == prop->GetName()->Int32Value())
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -TEST(AggregatedHeapSnapshot) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - CompileRun(
|
| - "function A() {}\n"
|
| - "function B(x) { this.x = x; }\n"
|
| - "var a = new A();\n"
|
| - "var b = new B(a);");
|
| - const v8::HeapSnapshot* snapshot =
|
| - v8::HeapProfiler::TakeSnapshot(
|
| - v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
|
| - const v8::HeapGraphNode* strings = GetChild(snapshot->GetRoot(),
|
| - v8::HeapGraphNode::kHidden,
|
| - "STRING_TYPE");
|
| - CHECK_NE(NULL, strings);
|
| - CHECK_NE(0, strings->GetSelfSize());
|
| - CHECK_NE(0, strings->GetInstancesCount());
|
| - const v8::HeapGraphNode* maps = GetChild(snapshot->GetRoot(),
|
| - v8::HeapGraphNode::kHidden,
|
| - "MAP_TYPE");
|
| - CHECK_NE(NULL, maps);
|
| - CHECK_NE(0, maps->GetSelfSize());
|
| - CHECK_NE(0, maps->GetInstancesCount());
|
| -
|
| - const v8::HeapGraphNode* a = GetChild(snapshot->GetRoot(),
|
| - v8::HeapGraphNode::kObject,
|
| - "A");
|
| - CHECK_NE(NULL, a);
|
| - CHECK_NE(0, a->GetSelfSize());
|
| - CHECK_EQ(1, a->GetInstancesCount());
|
| -
|
| - const v8::HeapGraphNode* b = GetChild(snapshot->GetRoot(),
|
| - v8::HeapGraphNode::kObject,
|
| - "B");
|
| - CHECK_NE(NULL, b);
|
| - CHECK_NE(0, b->GetSelfSize());
|
| - CHECK_EQ(1, b->GetInstancesCount());
|
| -
|
| - const v8::HeapGraphNode* glob_prop = GetChild(snapshot->GetRoot(),
|
| - v8::HeapGraphNode::kObject,
|
| - "(global property)",
|
| - b);
|
| - CHECK_NE(NULL, glob_prop);
|
| - CHECK_EQ(0, glob_prop->GetSelfSize());
|
| - CHECK_EQ(0, glob_prop->GetInstancesCount());
|
| - CHECK_NE(0, glob_prop->GetChildrenCount());
|
| -
|
| - const v8::HeapGraphNode* a_from_glob_prop = GetChild(
|
| - glob_prop,
|
| - v8::HeapGraphNode::kObject,
|
| - "A");
|
| - CHECK_NE(NULL, a_from_glob_prop);
|
| - CHECK_EQ(0, a_from_glob_prop->GetSelfSize());
|
| - CHECK_EQ(0, a_from_glob_prop->GetInstancesCount());
|
| - CHECK_EQ(0, a_from_glob_prop->GetChildrenCount()); // Retains nothing.
|
| - CHECK(IsNodeRetainedAs(a_from_glob_prop, 1)); // (global propery) has 1 ref.
|
| -
|
| - const v8::HeapGraphNode* b_with_children = GetChild(
|
| - snapshot->GetRoot(),
|
| - v8::HeapGraphNode::kObject,
|
| - "B",
|
| - b);
|
| - CHECK_NE(NULL, b_with_children);
|
| - CHECK_EQ(0, b_with_children->GetSelfSize());
|
| - CHECK_EQ(0, b_with_children->GetInstancesCount());
|
| - CHECK_NE(0, b_with_children->GetChildrenCount());
|
| -
|
| - const v8::HeapGraphNode* a_from_b = GetChild(
|
| - b_with_children,
|
| - v8::HeapGraphNode::kObject,
|
| - "A");
|
| - CHECK_NE(NULL, a_from_b);
|
| - CHECK_EQ(0, a_from_b->GetSelfSize());
|
| - CHECK_EQ(0, a_from_b->GetInstancesCount());
|
| - CHECK_EQ(0, a_from_b->GetChildrenCount()); // Retains nothing.
|
| - CHECK(IsNodeRetainedAs(a_from_b, 1)); // B has 1 ref to A.
|
| -}
|
| -
|
| -
|
| TEST(HeapEntryDominator) {
|
| // The graph looks like this:
|
| //
|
| @@ -1048,21 +567,6 @@ TEST(HeapSnapshotJSONSerializationAborting) {
|
| }
|
|
|
|
|
| -// Must not crash in debug mode.
|
| -TEST(AggregatedHeapSnapshotJSONSerialization) {
|
| - v8::HandleScope scope;
|
| - LocalContext env;
|
| -
|
| - const v8::HeapSnapshot* snapshot =
|
| - v8::HeapProfiler::TakeSnapshot(
|
| - v8::String::New("agg"), v8::HeapSnapshot::kAggregated);
|
| - TestJSONStream stream;
|
| - snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON);
|
| - CHECK_GT(stream.size(), 0);
|
| - CHECK_EQ(1, stream.eos_signaled());
|
| -}
|
| -
|
| -
|
| TEST(HeapSnapshotGetNodeById) {
|
| v8::HandleScope scope;
|
| LocalContext env;
|
|
|