| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 // | 27 // |
| 28 // Tests for heap profiler | 28 // Tests for heap profiler |
| 29 | 29 |
| 30 #include <ctype.h> | 30 #include <ctype.h> |
| 31 | 31 |
| 32 #include "v8.h" | 32 #include "v8.h" |
| 33 | 33 |
| 34 #include "allocation-tracker.h" |
| 34 #include "cctest.h" | 35 #include "cctest.h" |
| 35 #include "hashmap.h" | 36 #include "hashmap.h" |
| 36 #include "heap-profiler.h" | 37 #include "heap-profiler.h" |
| 37 #include "snapshot.h" | 38 #include "snapshot.h" |
| 38 #include "debug.h" | 39 #include "debug.h" |
| 39 #include "utils-inl.h" | 40 #include "utils-inl.h" |
| 40 #include "../include/v8-profiler.h" | 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 namespace { | 49 namespace { |
| 43 | 50 |
| 44 class NamedEntriesDetector { | 51 class NamedEntriesDetector { |
| 45 public: | 52 public: |
| 46 NamedEntriesDetector() | 53 NamedEntriesDetector() |
| 47 : has_A2(false), has_B2(false), has_C2(false) { | 54 : has_A2(false), has_B2(false), has_C2(false) { |
| 48 } | 55 } |
| 49 | 56 |
| 50 void CheckEntry(i::HeapEntry* entry) { | 57 void CheckEntry(i::HeapEntry* entry) { |
| 51 if (strcmp(entry->name(), "A2") == 0) has_A2 = true; | 58 if (strcmp(entry->name(), "A2") == 0) has_A2 = true; |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 "function myFunction(a, b) { this.a = a; this.b = b; }\n" | 248 "function myFunction(a, b) { this.a = a; this.b = b; }\n" |
| 242 "function AAAAA() {}\n" | 249 "function AAAAA() {}\n" |
| 243 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); | 250 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); |
| 244 const v8::HeapSnapshot* snapshot = | 251 const v8::HeapSnapshot* snapshot = |
| 245 heap_profiler->TakeHeapSnapshot(v8_str("sizes")); | 252 heap_profiler->TakeHeapSnapshot(v8_str("sizes")); |
| 246 CHECK(ValidateSnapshot(snapshot)); | 253 CHECK(ValidateSnapshot(snapshot)); |
| 247 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 254 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 248 const v8::HeapGraphNode* f = | 255 const v8::HeapGraphNode* f = |
| 249 GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); | 256 GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); |
| 250 CHECK(f); | 257 CHECK(f); |
| 251 CHECK_EQ(v8::String::New("native_bind"), f->GetName()); | 258 CHECK_EQ(v8::String::NewFromUtf8(env->GetIsolate(), "native_bind"), |
| 259 f->GetName()); |
| 252 const v8::HeapGraphNode* bindings = | 260 const v8::HeapGraphNode* bindings = |
| 253 GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); | 261 GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); |
| 254 CHECK_NE(NULL, bindings); | 262 CHECK_NE(NULL, bindings); |
| 255 CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); | 263 CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); |
| 256 CHECK_EQ(4, bindings->GetChildrenCount()); | 264 CHECK_EQ(4, bindings->GetChildrenCount()); |
| 257 | 265 |
| 258 const v8::HeapGraphNode* bound_this = GetProperty( | 266 const v8::HeapGraphNode* bound_this = GetProperty( |
| 259 f, v8::HeapGraphEdge::kShortcut, "bound_this"); | 267 f, v8::HeapGraphEdge::kShortcut, "bound_this"); |
| 260 CHECK(bound_this); | 268 CHECK(bound_this); |
| 261 CHECK_EQ(v8::HeapGraphNode::kObject, bound_this->GetType()); | 269 CHECK_EQ(v8::HeapGraphNode::kObject, bound_this->GetType()); |
| (...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1069 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); | 1077 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1070 CompileRun("globalObject = {};\n"); | 1078 CompileRun("globalObject = {};\n"); |
| 1071 const v8::HeapSnapshot* snapshot = | 1079 const v8::HeapSnapshot* snapshot = |
| 1072 heap_profiler->TakeHeapSnapshot(v8_str("get_snapshot_object_id")); | 1080 heap_profiler->TakeHeapSnapshot(v8_str("get_snapshot_object_id")); |
| 1073 CHECK(ValidateSnapshot(snapshot)); | 1081 CHECK(ValidateSnapshot(snapshot)); |
| 1074 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1082 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1075 const v8::HeapGraphNode* global_object = | 1083 const v8::HeapGraphNode* global_object = |
| 1076 GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); | 1084 GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); |
| 1077 CHECK(global_object); | 1085 CHECK(global_object); |
| 1078 | 1086 |
| 1079 v8::Local<v8::Value> globalObjectHandle = | 1087 v8::Local<v8::Value> globalObjectHandle = env->Global()->Get( |
| 1080 env->Global()->Get(v8::String::New("globalObject")); | 1088 v8::String::NewFromUtf8(env->GetIsolate(), "globalObject")); |
| 1081 CHECK(!globalObjectHandle.IsEmpty()); | 1089 CHECK(!globalObjectHandle.IsEmpty()); |
| 1082 CHECK(globalObjectHandle->IsObject()); | 1090 CHECK(globalObjectHandle->IsObject()); |
| 1083 | 1091 |
| 1084 v8::SnapshotObjectId id = heap_profiler->GetObjectId(globalObjectHandle); | 1092 v8::SnapshotObjectId id = heap_profiler->GetObjectId(globalObjectHandle); |
| 1085 CHECK_NE(static_cast<int>(v8::HeapProfiler::kUnknownObjectId), | 1093 CHECK_NE(static_cast<int>(v8::HeapProfiler::kUnknownObjectId), |
| 1086 id); | 1094 id); |
| 1087 CHECK_EQ(static_cast<int>(id), global_object->GetId()); | 1095 CHECK_EQ(static_cast<int>(id), global_object->GetId()); |
| 1088 } | 1096 } |
| 1089 | 1097 |
| 1090 | 1098 |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1705 heap_profiler->TakeHeapSnapshot(v8_str("HiddenPropertiesFastCase1")); | 1713 heap_profiler->TakeHeapSnapshot(v8_str("HiddenPropertiesFastCase1")); |
| 1706 CHECK(ValidateSnapshot(snapshot)); | 1714 CHECK(ValidateSnapshot(snapshot)); |
| 1707 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1715 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1708 const v8::HeapGraphNode* c = | 1716 const v8::HeapGraphNode* c = |
| 1709 GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); | 1717 GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); |
| 1710 CHECK_NE(NULL, c); | 1718 CHECK_NE(NULL, c); |
| 1711 const v8::HeapGraphNode* hidden_props = | 1719 const v8::HeapGraphNode* hidden_props = |
| 1712 GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties"); | 1720 GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties"); |
| 1713 CHECK_EQ(NULL, hidden_props); | 1721 CHECK_EQ(NULL, hidden_props); |
| 1714 | 1722 |
| 1715 v8::Handle<v8::Value> cHandle = env->Global()->Get(v8::String::New("c")); | 1723 v8::Handle<v8::Value> cHandle = |
| 1724 env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c")); |
| 1716 CHECK(!cHandle.IsEmpty() && cHandle->IsObject()); | 1725 CHECK(!cHandle.IsEmpty() && cHandle->IsObject()); |
| 1717 cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val")); | 1726 cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val")); |
| 1718 | 1727 |
| 1719 snapshot = heap_profiler->TakeHeapSnapshot( | 1728 snapshot = heap_profiler->TakeHeapSnapshot( |
| 1720 v8_str("HiddenPropertiesFastCase2")); | 1729 v8_str("HiddenPropertiesFastCase2")); |
| 1721 CHECK(ValidateSnapshot(snapshot)); | 1730 CHECK(ValidateSnapshot(snapshot)); |
| 1722 global = GetGlobalObject(snapshot); | 1731 global = GetGlobalObject(snapshot); |
| 1723 c = GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); | 1732 c = GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); |
| 1724 CHECK_NE(NULL, c); | 1733 CHECK_NE(NULL, c); |
| 1725 hidden_props = GetProperty(c, v8::HeapGraphEdge::kInternal, | 1734 hidden_props = GetProperty(c, v8::HeapGraphEdge::kInternal, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1749 const v8::HeapGraphNode* global_handles = GetNode( | 1758 const v8::HeapGraphNode* global_handles = GetNode( |
| 1750 gc_roots, v8::HeapGraphNode::kSynthetic, "(Global handles)"); | 1759 gc_roots, v8::HeapGraphNode::kSynthetic, "(Global handles)"); |
| 1751 CHECK_NE(NULL, global_handles); | 1760 CHECK_NE(NULL, global_handles); |
| 1752 return HasWeakEdge(global_handles); | 1761 return HasWeakEdge(global_handles); |
| 1753 } | 1762 } |
| 1754 | 1763 |
| 1755 | 1764 |
| 1756 static void PersistentHandleCallback(v8::Isolate* isolate, | 1765 static void PersistentHandleCallback(v8::Isolate* isolate, |
| 1757 v8::Persistent<v8::Value>* handle, | 1766 v8::Persistent<v8::Value>* handle, |
| 1758 void*) { | 1767 void*) { |
| 1759 handle->Dispose(); | 1768 handle->Reset(); |
| 1760 } | 1769 } |
| 1761 | 1770 |
| 1762 | 1771 |
| 1763 TEST(WeakGlobalHandle) { | 1772 TEST(WeakGlobalHandle) { |
| 1764 LocalContext env; | 1773 LocalContext env; |
| 1765 v8::HandleScope scope(env->GetIsolate()); | 1774 v8::HandleScope scope(env->GetIsolate()); |
| 1766 | 1775 |
| 1767 CHECK(!HasWeakGlobalHandle()); | 1776 CHECK(!HasWeakGlobalHandle()); |
| 1768 | 1777 |
| 1769 v8::Persistent<v8::Object> handle(env->GetIsolate(), v8::Object::New()); | 1778 v8::Persistent<v8::Object> handle(env->GetIsolate(), v8::Object::New()); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 | 2031 |
| 2023 const char* HeapProfilerExtension::kName = "v8/heap-profiler"; | 2032 const char* HeapProfilerExtension::kName = "v8/heap-profiler"; |
| 2024 | 2033 |
| 2025 | 2034 |
| 2026 const char* HeapProfilerExtension::kSource = | 2035 const char* HeapProfilerExtension::kSource = |
| 2027 "native function findUntrackedObjects();"; | 2036 "native function findUntrackedObjects();"; |
| 2028 | 2037 |
| 2029 | 2038 |
| 2030 v8::Handle<v8::FunctionTemplate> HeapProfilerExtension::GetNativeFunction( | 2039 v8::Handle<v8::FunctionTemplate> HeapProfilerExtension::GetNativeFunction( |
| 2031 v8::Handle<v8::String> name) { | 2040 v8::Handle<v8::String> name) { |
| 2032 if (name->Equals(v8::String::New("findUntrackedObjects"))) { | 2041 if (name->Equals(v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), |
| 2042 "findUntrackedObjects"))) { |
| 2033 return v8::FunctionTemplate::New( | 2043 return v8::FunctionTemplate::New( |
| 2034 HeapProfilerExtension::FindUntrackedObjects); | 2044 HeapProfilerExtension::FindUntrackedObjects); |
| 2035 } else { | 2045 } else { |
| 2036 CHECK(false); | 2046 CHECK(false); |
| 2037 return v8::Handle<v8::FunctionTemplate>(); | 2047 return v8::Handle<v8::FunctionTemplate>(); |
| 2038 } | 2048 } |
| 2039 } | 2049 } |
| 2040 | 2050 |
| 2041 | 2051 |
| 2042 void HeapProfilerExtension::FindUntrackedObjects( | 2052 void HeapProfilerExtension::FindUntrackedObjects( |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2118 CHECK_NE(NULL, node); | 2128 CHECK_NE(NULL, node); |
| 2119 | 2129 |
| 2120 const char* builtin_path[] = { | 2130 const char* builtin_path[] = { |
| 2121 "::(GC roots)", | 2131 "::(GC roots)", |
| 2122 "::(Builtins)", | 2132 "::(Builtins)", |
| 2123 "::(KeyedLoadIC_Generic code)" | 2133 "::(KeyedLoadIC_Generic code)" |
| 2124 }; | 2134 }; |
| 2125 node = GetNodeByPath(snapshot, builtin_path, ARRAY_SIZE(builtin_path)); | 2135 node = GetNodeByPath(snapshot, builtin_path, ARRAY_SIZE(builtin_path)); |
| 2126 CHECK_NE(NULL, node); | 2136 CHECK_NE(NULL, node); |
| 2127 } | 2137 } |
| 2138 |
| 2139 |
| 2140 static const char* record_trace_tree_source = |
| 2141 "var topFunctions = [];\n" |
| 2142 "var global = this;\n" |
| 2143 "function generateFunctions(width, depth) {\n" |
| 2144 " var script = [];\n" |
| 2145 " for (var i = 0; i < width; i++) {\n" |
| 2146 " for (var j = 0; j < depth; j++) {\n" |
| 2147 " script.push('function f_' + i + '_' + j + '(x) {\\n');\n" |
| 2148 " script.push(' try {\\n');\n" |
| 2149 " if (j < depth-2) {\n" |
| 2150 " script.push(' return f_' + i + '_' + (j+1) + '(x+1);\\n');\n" |
| 2151 " } else if (j == depth - 2) {\n" |
| 2152 " script.push(' return new f_' + i + '_' + (depth - 1) + '();\\n');\n" |
| 2153 " } else if (j == depth - 1) {\n" |
| 2154 " script.push(' this.ts = Date.now();\\n');\n" |
| 2155 " }\n" |
| 2156 " script.push(' } catch (e) {}\\n');\n" |
| 2157 " script.push('}\\n');\n" |
| 2158 " \n" |
| 2159 " }\n" |
| 2160 " }\n" |
| 2161 " var script = script.join('');\n" |
| 2162 " // throw script;\n" |
| 2163 " global.eval(script);\n" |
| 2164 " for (var i = 0; i < width; i++) {\n" |
| 2165 " topFunctions.push(this['f_' + i + '_0']);\n" |
| 2166 " }\n" |
| 2167 "}\n" |
| 2168 "\n" |
| 2169 "var width = 3;\n" |
| 2170 "var depth = 3;\n" |
| 2171 "generateFunctions(width, depth);\n" |
| 2172 "var instances = [];\n" |
| 2173 "function start() {\n" |
| 2174 " for (var i = 0; i < width; i++) {\n" |
| 2175 " instances.push(topFunctions[i](0));\n" |
| 2176 " }\n" |
| 2177 "}\n" |
| 2178 "\n" |
| 2179 "for (var i = 0; i < 100; i++) start();\n"; |
| 2180 |
| 2181 |
| 2182 static i::HeapSnapshot* ToInternal(const v8::HeapSnapshot* snapshot) { |
| 2183 return const_cast<i::HeapSnapshot*>( |
| 2184 reinterpret_cast<const i::HeapSnapshot*>(snapshot)); |
| 2185 } |
| 2186 |
| 2187 |
| 2188 static AllocationTraceNode* FindNode( |
| 2189 AllocationTracker* tracker, const Vector<const char*>& names) { |
| 2190 AllocationTraceNode* node = tracker->trace_tree()->root(); |
| 2191 for (int i = 0; node != NULL && i < names.length(); i++) { |
| 2192 const char* name = names[i]; |
| 2193 Vector<AllocationTraceNode*> children = node->children(); |
| 2194 node = NULL; |
| 2195 for (int j = 0; j < children.length(); j++) { |
| 2196 v8::SnapshotObjectId id = children[j]->function_id(); |
| 2197 AllocationTracker::FunctionInfo* info = tracker->GetFunctionInfo(id); |
| 2198 if (info && strcmp(info->name, name) == 0) { |
| 2199 node = children[j]; |
| 2200 break; |
| 2201 } |
| 2202 } |
| 2203 } |
| 2204 return node; |
| 2205 } |
| 2206 |
| 2207 |
| 2208 TEST(TrackHeapAllocations) { |
| 2209 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| 2210 LocalContext env; |
| 2211 |
| 2212 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 2213 heap_profiler->StartRecordingHeapAllocations(); |
| 2214 |
| 2215 CompileRun(record_trace_tree_source); |
| 2216 |
| 2217 const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( |
| 2218 v8::String::NewFromUtf8(env->GetIsolate(), "Test")); |
| 2219 i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection(); |
| 2220 AllocationTracker* tracker = collection->allocation_tracker(); |
| 2221 CHECK_NE(NULL, tracker); |
| 2222 // Resolve all function locations. |
| 2223 tracker->PrepareForSerialization(); |
| 2224 // Print for better diagnostics in case of failure. |
| 2225 tracker->trace_tree()->Print(tracker); |
| 2226 |
| 2227 const char* names[] = |
| 2228 { "(anonymous function)", "start", "f_0_0", "f_0_1", "f_0_2" }; |
| 2229 AllocationTraceNode* node = |
| 2230 FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); |
| 2231 CHECK_NE(NULL, node); |
| 2232 CHECK_GE(node->allocation_count(), 100); |
| 2233 CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); |
| 2234 heap_profiler->StopRecordingHeapAllocations(); |
| 2235 } |
| 2236 |
| 2237 |
| 2238 static const char* inline_heap_allocation_source = |
| 2239 "function f_0(x) {\n" |
| 2240 " return f_1(x+1);\n" |
| 2241 "}\n" |
| 2242 "%NeverOptimizeFunction(f_0);\n" |
| 2243 "function f_1(x) {\n" |
| 2244 " return new f_2(x+1);\n" |
| 2245 "}\n" |
| 2246 "function f_2(x) {\n" |
| 2247 " this.foo = x;\n" |
| 2248 "}\n" |
| 2249 "var instances = [];\n" |
| 2250 "function start() {\n" |
| 2251 " instances.push(f_0(0));\n" |
| 2252 "}\n" |
| 2253 "\n" |
| 2254 "for (var i = 0; i < 100; i++) start();\n"; |
| 2255 |
| 2256 |
| 2257 TEST(TrackBumpPointerAllocations) { |
| 2258 i::FLAG_allow_natives_syntax = true; |
| 2259 v8::HandleScope scope(v8::Isolate::GetCurrent()); |
| 2260 LocalContext env; |
| 2261 |
| 2262 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 2263 const char* names[] = { "(anonymous function)", "start", "f_0", "f_1" }; |
| 2264 // First check that normally all allocations are recorded. |
| 2265 { |
| 2266 heap_profiler->StartRecordingHeapAllocations(); |
| 2267 |
| 2268 CompileRun(inline_heap_allocation_source); |
| 2269 |
| 2270 const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( |
| 2271 v8::String::NewFromUtf8(env->GetIsolate(), "Test2")); |
| 2272 i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection(); |
| 2273 AllocationTracker* tracker = collection->allocation_tracker(); |
| 2274 CHECK_NE(NULL, tracker); |
| 2275 // Resolve all function locations. |
| 2276 tracker->PrepareForSerialization(); |
| 2277 // Print for better diagnostics in case of failure. |
| 2278 tracker->trace_tree()->Print(tracker); |
| 2279 |
| 2280 AllocationTraceNode* node = |
| 2281 FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); |
| 2282 CHECK_NE(NULL, node); |
| 2283 CHECK_GE(node->allocation_count(), 100); |
| 2284 CHECK_GE(node->allocation_size(), 4 * node->allocation_count()); |
| 2285 heap_profiler->StopRecordingHeapAllocations(); |
| 2286 } |
| 2287 |
| 2288 { |
| 2289 heap_profiler->StartRecordingHeapAllocations(); |
| 2290 |
| 2291 // Now check that not all allocations are tracked if we manually reenable |
| 2292 // inline allocations. |
| 2293 CHECK(CcTest::heap()->inline_allocation_disabled()); |
| 2294 CcTest::heap()->EnableInlineAllocation(); |
| 2295 |
| 2296 CompileRun(inline_heap_allocation_source); |
| 2297 |
| 2298 const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot( |
| 2299 v8::String::NewFromUtf8(env->GetIsolate(), "Test1")); |
| 2300 i::HeapSnapshotsCollection* collection = ToInternal(snapshot)->collection(); |
| 2301 AllocationTracker* tracker = collection->allocation_tracker(); |
| 2302 CHECK_NE(NULL, tracker); |
| 2303 // Resolve all function locations. |
| 2304 tracker->PrepareForSerialization(); |
| 2305 // Print for better diagnostics in case of failure. |
| 2306 tracker->trace_tree()->Print(tracker); |
| 2307 |
| 2308 AllocationTraceNode* node = |
| 2309 FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); |
| 2310 CHECK_NE(NULL, node); |
| 2311 CHECK_LT(node->allocation_count(), 100); |
| 2312 |
| 2313 CcTest::heap()->DisableInlineAllocation(); |
| 2314 heap_profiler->StopRecordingHeapAllocations(); |
| 2315 } |
| 2316 } |
| OLD | NEW |