Revision f230a1cf deps/v8/test/cctest/test-heap-profiler.cc

View differences:

deps/v8/test/cctest/test-heap-profiler.cc
31 31

  
32 32
#include "v8.h"
33 33

  
34
#include "allocation-tracker.h"
34 35
#include "cctest.h"
35 36
#include "hashmap.h"
36 37
#include "heap-profiler.h"
......
39 40
#include "utils-inl.h"
40 41
#include "../include/v8-profiler.h"
41 42

  
43
using i::AllocationTraceNode;
44
using i::AllocationTraceTree;
45
using i::AllocationTracker;
46
using i::HashMap;
47
using i::Vector;
48

  
42 49
namespace {
43 50

  
44 51
class NamedEntriesDetector {
......
413 420

  
414 421

  
415 422
TEST(HeapSnapshotConsString) {
416
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
423
  v8::Isolate* isolate = CcTest::isolate();
417 424
  v8::HandleScope scope(isolate);
418 425
  v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
419 426
  global_template->SetInternalFieldCount(1);
......
422 429
  v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>();
423 430
  CHECK_EQ(1, global->InternalFieldCount());
424 431

  
425
  i::Factory* factory = i::Isolate::Current()->factory();
432
  i::Factory* factory = CcTest::i_isolate()->factory();
426 433
  i::Handle<i::String> first =
427 434
      factory->NewStringFromAscii(i::CStrVector("0123456789"));
428 435
  i::Handle<i::String> second =
......
456 463

  
457 464

  
458 465
TEST(HeapSnapshotInternalReferences) {
459
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
466
  v8::Isolate* isolate = CcTest::isolate();
460 467
  v8::HandleScope scope(isolate);
461 468
  v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
462 469
  global_template->SetInternalFieldCount(2);
......
505 512
  CompileRun(
506 513
      "for (var i = 0; i < 10000; ++i)\n"
507 514
      "  a[i] = new A();\n");
508
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
515
  CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
509 516

  
510 517
  const v8::HeapSnapshot* snapshot2 =
511 518
      heap_profiler->TakeHeapSnapshot(v8_str("snapshot2"));
......
549 556
      "for (var i = 0; i < 1; ++i)\n"
550 557
      "  a.shift();\n");
551 558

  
552
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
559
  CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
553 560

  
554 561
  const v8::HeapSnapshot* snapshot2 =
555 562
      heap_profiler->TakeHeapSnapshot(v8_str("s2"));
......
594 601
      heap_profiler->TakeHeapSnapshot(s1_str);
595 602
  CHECK(ValidateSnapshot(snapshot1));
596 603

  
597
  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
604
  CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
598 605

  
599 606
  const v8::HeapSnapshot* snapshot2 =
600 607
      heap_profiler->TakeHeapSnapshot(s2_str);
......
901 908
  // We have to call GC 6 times. In other case the garbage will be
902 909
  // the reason of flakiness.
903 910
  for (int i = 0; i < 6; ++i) {
904
    HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
911
    CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
905 912
  }
906 913

  
907 914
  v8::SnapshotObjectId initial_id;
......
1482 1489
  CompileRun("document = { URL:\"abcdefgh\" };");
1483 1490

  
1484 1491
  v8::Handle<v8::String> name(v8_str("leakz"));
1485
  i::Isolate* isolate = i::Isolate::Current();
1492
  i::Isolate* isolate = CcTest::i_isolate();
1486 1493
  int count_before = i::HandleScope::NumberOfHandles(isolate);
1487 1494
  heap_profiler->TakeHeapSnapshot(name);
1488 1495
  int count_after = i::HandleScope::NumberOfHandles(isolate);
......
1738 1745

  
1739 1746

  
1740 1747
bool HasWeakGlobalHandle() {
1741
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
1748
  v8::Isolate* isolate = CcTest::isolate();
1742 1749
  v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
1743 1750
  const v8::HeapSnapshot* snapshot =
1744 1751
      heap_profiler->TakeHeapSnapshot(v8_str("weaks"));
......
1800 1807
  v8::HandleScope scope(env->GetIsolate());
1801 1808
  v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
1802 1809

  
1803
  v8::internal::Isolate::Current()->debug()->Load();
1810
  CcTest::i_isolate()->debug()->Load();
1804 1811
  CompileRun("foo = {};");
1805 1812
  const v8::HeapSnapshot* snapshot =
1806 1813
      heap_profiler->TakeHeapSnapshot(v8_str("snapshot"));
......
2005 2012
      GetProperty(foo_func, v8::HeapGraphEdge::kInternal, "code");
2006 2013
  CHECK_NE(NULL, code);
2007 2014
}
2015

  
2016

  
2017

  
2018
class HeapProfilerExtension : public v8::Extension {
2019
 public:
2020
  static const char* kName;
2021
  HeapProfilerExtension() : v8::Extension(kName, kSource) { }
2022
  virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
2023
      v8::Handle<v8::String> name);
2024
  static void FindUntrackedObjects(
2025
      const v8::FunctionCallbackInfo<v8::Value>& args);
2026
 private:
2027
  static const char* kSource;
2028
};
2029

  
2030
const char* HeapProfilerExtension::kName = "v8/heap-profiler";
2031

  
2032

  
2033
const char* HeapProfilerExtension::kSource =
2034
    "native function findUntrackedObjects();";
2035

  
2036

  
2037
v8::Handle<v8::FunctionTemplate> HeapProfilerExtension::GetNativeFunction(
2038
    v8::Handle<v8::String> name) {
2039
  if (name->Equals(v8::String::New("findUntrackedObjects"))) {
2040
    return v8::FunctionTemplate::New(
2041
        HeapProfilerExtension::FindUntrackedObjects);
2042
  } else {
2043
    CHECK(false);
2044
    return v8::Handle<v8::FunctionTemplate>();
2045
  }
2046
}
2047

  
2048

  
2049
void HeapProfilerExtension::FindUntrackedObjects(
2050
    const v8::FunctionCallbackInfo<v8::Value>& args) {
2051
  i::HeapProfiler* heap_profiler =
2052
      reinterpret_cast<i::HeapProfiler*>(args.GetIsolate()->GetHeapProfiler());
2053
  int untracked_objects = heap_profiler->FindUntrackedObjects();
2054
  args.GetReturnValue().Set(untracked_objects);
2055
  CHECK_EQ(0, untracked_objects);
2056
}
2057

  
2058

  
2059
static HeapProfilerExtension kHeapProfilerExtension;
2060
v8::DeclareExtension kHeapProfilerExtensionDeclaration(
2061
    &kHeapProfilerExtension);
2062

  
2063

  
2064
// This is an example of using checking of JS allocations tracking in a test.
2065
TEST(HeapObjectsTracker) {
2066
  const char* extensions[] = { HeapProfilerExtension::kName };
2067
  v8::ExtensionConfiguration config(1, extensions);
2068
  LocalContext env(&config);
2069
  v8::HandleScope scope(env->GetIsolate());
2070
  HeapObjectsTracker tracker;
2071
  CompileRun("var a = 1.2");
2072
  CompileRun("var a = 1.2; var b = 1.0; var c = 1.0;");
2073
  CompileRun(
2074
    "var a = [];\n"
2075
    "for (var i = 0; i < 5; ++i)\n"
2076
    "    a[i] = i;\n"
2077
    "findUntrackedObjects();\n"
2078
    "for (var i = 0; i < 3; ++i)\n"
2079
    "    a.shift();\n"
2080
    "findUntrackedObjects();\n");
2081
}
2082

  
2083

  
2084
static const char* record_trace_tree_source =
2085
"var topFunctions = [];\n"
2086
"var global = this;\n"
2087
"function generateFunctions(width, depth) {\n"
2088
"  var script = [];\n"
2089
"  for (var i = 0; i < width; i++) {\n"
2090
"    for (var j = 0; j < depth; j++) {\n"
2091
"      script.push('function f_' + i + '_' + j + '(x) {\\n');\n"
2092
"      script.push('  try {\\n');\n"
2093
"      if (j < depth-2) {\n"
2094
"        script.push('    return f_' + i + '_' + (j+1) + '(x+1);\\n');\n"
2095
"      } else if (j == depth - 2) {\n"
2096
"        script.push('    return new f_' + i + '_' + (depth - 1) + '();\\n');\n"
2097
"      } else if (j == depth - 1) {\n"
2098
"        script.push('    this.ts = Date.now();\\n');\n"
2099
"      }\n"
2100
"      script.push('  } catch (e) {}\\n');\n"
2101
"      script.push('}\\n');\n"
2102
"      \n"
2103
"    }\n"
2104
"  }\n"
2105
"  var script = script.join('');\n"
2106
"  // throw script;\n"
2107
"  global.eval(script);\n"
2108
"  for (var i = 0; i < width; i++) {\n"
2109
"    topFunctions.push(this['f_' + i + '_0']);\n"
2110
"  }\n"
2111
"}\n"
2112
"\n"
2113
"var width = 3;\n"
2114
"var depth = 3;\n"
2115
"generateFunctions(width, depth);\n"
2116
"var instances = [];\n"
2117
"function start() {\n"
2118
"  for (var i = 0; i < width; i++) {\n"
2119
"    instances.push(topFunctions[i](0));\n"
2120
"  }\n"
2121
"}\n"
2122
"\n"
2123
"for (var i = 0; i < 100; i++) start();\n";
2124

  
2125

  
2126
static i::HeapSnapshot* ToInternal(const v8::HeapSnapshot* snapshot) {
2127
  return const_cast<i::HeapSnapshot*>(
2128
      reinterpret_cast<const i::HeapSnapshot*>(snapshot));
2129
}
2130

  
2131

  
2132
static AllocationTraceNode* FindNode(
2133
    AllocationTracker* tracker, const Vector<const char*>& names) {
2134
  AllocationTraceNode* node = tracker->trace_tree()->root();
2135
  for (int i = 0; node != NULL && i < names.length(); i++) {
2136
    const char* name = names[i];
2137
    Vector<AllocationTraceNode*> children = node->children();
2138
    node = NULL;
2139
    for (int j = 0; j < children.length(); j++) {
2140
      v8::SnapshotObjectId id = children[j]->function_id();
2141
      AllocationTracker::FunctionInfo* info = tracker->GetFunctionInfo(id);
2142
      if (info && strcmp(info->name, name) == 0) {
2143
        node = children[j];
2144
        break;
2145
      }
2146
    }
2147
  }
2148
  return node;
2149
}
2150

  
2151

  
2152
TEST(TrackHeapAllocations) {
2153
  v8::HandleScope scope(v8::Isolate::GetCurrent());
2154
  LocalContext env;
2155

  
2156
  v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
2157
  heap_profiler->StartRecordingHeapAllocations();
2158

  
2159
  CompileRun(record_trace_tree_source);
2160

  
2161
  const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot(
2162
      v8::String::New("Test"));
2163
  i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection();
2164
  AllocationTracker* tracker = collection->allocation_tracker();
2165
  CHECK_NE(NULL, tracker);
2166
  // Resolve all function locations.
2167
  tracker->PrepareForSerialization();
2168
  // Print for better diagnostics in case of failure.
2169
  tracker->trace_tree()->Print(tracker);
2170

  
2171
  const char* names[] =
2172
      { "(anonymous function)", "start", "f_0_0", "f_0_1", "f_0_2" };
2173
  AllocationTraceNode* node =
2174
      FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names)));
2175
  CHECK_NE(NULL, node);
2176
  CHECK_GE(node->allocation_count(), 100);
2177
  CHECK_GE(node->allocation_size(), 4 * node->allocation_count());
2178
  heap_profiler->StopRecordingHeapAllocations();
2179
}

Also available in: Unified diff