| 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 if (strcmp(contents, *node_name) == 0) return true; | 122 if (strcmp(contents, *node_name) == 0) return true; |
| 123 } | 123 } |
| 124 } | 124 } |
| 125 return false; | 125 return false; |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 TEST(HeapSnapshot) { | 129 TEST(HeapSnapshot) { |
| 130 LocalContext env2; | 130 LocalContext env2; |
| 131 v8::HandleScope scope(env2->GetIsolate()); | 131 v8::HandleScope scope(env2->GetIsolate()); |
| 132 v8::HeapProfiler* heap_profiler = env2->GetIsolate()->GetHeapProfiler(); |
| 132 | 133 |
| 133 CompileRun( | 134 CompileRun( |
| 134 "function A2() {}\n" | 135 "function A2() {}\n" |
| 135 "function B2(x) { return function() { return typeof x; }; }\n" | 136 "function B2(x) { return function() { return typeof x; }; }\n" |
| 136 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" | 137 "function C2(x) { this.x1 = x; this.x2 = x; this[1] = x; }\n" |
| 137 "var a2 = new A2();\n" | 138 "var a2 = new A2();\n" |
| 138 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" | 139 "var b2_1 = new B2(a2), b2_2 = new B2(a2);\n" |
| 139 "var c2 = new C2(a2);"); | 140 "var c2 = new C2(a2);"); |
| 140 const v8::HeapSnapshot* snapshot_env2 = | 141 const v8::HeapSnapshot* snapshot_env2 = |
| 141 v8::HeapProfiler::TakeSnapshot(v8_str("env2")); | 142 heap_profiler->TakeHeapSnapshot(v8_str("env2")); |
| 142 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); | 143 const v8::HeapGraphNode* global_env2 = GetGlobalObject(snapshot_env2); |
| 143 | 144 |
| 144 // Verify, that JS global object of env2 has '..2' properties. | 145 // Verify, that JS global object of env2 has '..2' properties. |
| 145 const v8::HeapGraphNode* a2_node = | 146 const v8::HeapGraphNode* a2_node = |
| 146 GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2"); | 147 GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2"); |
| 147 CHECK_NE(NULL, a2_node); | 148 CHECK_NE(NULL, a2_node); |
| 148 CHECK_NE( | 149 CHECK_NE( |
| 149 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1")); | 150 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1")); |
| 150 CHECK_NE( | 151 CHECK_NE( |
| 151 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2")); | 152 NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2")); |
| 152 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2")); | 153 CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2")); |
| 153 | 154 |
| 154 NamedEntriesDetector det; | 155 NamedEntriesDetector det; |
| 155 det.CheckAllReachables(const_cast<i::HeapEntry*>( | 156 det.CheckAllReachables(const_cast<i::HeapEntry*>( |
| 156 reinterpret_cast<const i::HeapEntry*>(global_env2))); | 157 reinterpret_cast<const i::HeapEntry*>(global_env2))); |
| 157 CHECK(det.has_A2); | 158 CHECK(det.has_A2); |
| 158 CHECK(det.has_B2); | 159 CHECK(det.has_B2); |
| 159 CHECK(det.has_C2); | 160 CHECK(det.has_C2); |
| 160 } | 161 } |
| 161 | 162 |
| 162 | 163 |
| 163 TEST(HeapSnapshotObjectSizes) { | 164 TEST(HeapSnapshotObjectSizes) { |
| 164 LocalContext env; | 165 LocalContext env; |
| 165 v8::HandleScope scope(env->GetIsolate()); | 166 v8::HandleScope scope(env->GetIsolate()); |
| 167 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 166 | 168 |
| 167 // -a-> X1 --a | 169 // -a-> X1 --a |
| 168 // x -b-> X2 <-| | 170 // x -b-> X2 <-| |
| 169 CompileRun( | 171 CompileRun( |
| 170 "function X(a, b) { this.a = a; this.b = b; }\n" | 172 "function X(a, b) { this.a = a; this.b = b; }\n" |
| 171 "x = new X(new X(), new X());\n" | 173 "x = new X(new X(), new X());\n" |
| 172 "dummy = new X();\n" | 174 "dummy = new X();\n" |
| 173 "(function() { x.a.a = x.b; })();"); | 175 "(function() { x.a.a = x.b; })();"); |
| 174 const v8::HeapSnapshot* snapshot = | 176 const v8::HeapSnapshot* snapshot = |
| 175 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); | 177 heap_profiler->TakeHeapSnapshot(v8_str("sizes")); |
| 176 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 178 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 177 const v8::HeapGraphNode* x = | 179 const v8::HeapGraphNode* x = |
| 178 GetProperty(global, v8::HeapGraphEdge::kProperty, "x"); | 180 GetProperty(global, v8::HeapGraphEdge::kProperty, "x"); |
| 179 CHECK_NE(NULL, x); | 181 CHECK_NE(NULL, x); |
| 180 const v8::HeapGraphNode* x1 = | 182 const v8::HeapGraphNode* x1 = |
| 181 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); | 183 GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); |
| 182 CHECK_NE(NULL, x1); | 184 CHECK_NE(NULL, x1); |
| 183 const v8::HeapGraphNode* x2 = | 185 const v8::HeapGraphNode* x2 = |
| 184 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); | 186 GetProperty(x, v8::HeapGraphEdge::kProperty, "b"); |
| 185 CHECK_NE(NULL, x2); | 187 CHECK_NE(NULL, x2); |
| 186 | 188 |
| 187 // Test sizes. | 189 // Test sizes. |
| 188 CHECK_NE(0, x->GetSelfSize()); | 190 CHECK_NE(0, x->GetSelfSize()); |
| 189 CHECK_NE(0, x1->GetSelfSize()); | 191 CHECK_NE(0, x1->GetSelfSize()); |
| 190 CHECK_NE(0, x2->GetSelfSize()); | 192 CHECK_NE(0, x2->GetSelfSize()); |
| 191 } | 193 } |
| 192 | 194 |
| 193 | 195 |
| 194 TEST(BoundFunctionInSnapshot) { | 196 TEST(BoundFunctionInSnapshot) { |
| 195 LocalContext env; | 197 LocalContext env; |
| 196 v8::HandleScope scope(env->GetIsolate()); | 198 v8::HandleScope scope(env->GetIsolate()); |
| 199 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 197 CompileRun( | 200 CompileRun( |
| 198 "function myFunction(a, b) { this.a = a; this.b = b; }\n" | 201 "function myFunction(a, b) { this.a = a; this.b = b; }\n" |
| 199 "function AAAAA() {}\n" | 202 "function AAAAA() {}\n" |
| 200 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); | 203 "boundFunction = myFunction.bind(new AAAAA(), 20, new Number(12)); \n"); |
| 201 const v8::HeapSnapshot* snapshot = | 204 const v8::HeapSnapshot* snapshot = |
| 202 v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); | 205 heap_profiler->TakeHeapSnapshot(v8_str("sizes")); |
| 203 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 206 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 204 const v8::HeapGraphNode* f = | 207 const v8::HeapGraphNode* f = |
| 205 GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); | 208 GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction"); |
| 206 CHECK(f); | 209 CHECK(f); |
| 207 CHECK_EQ(v8::String::New("native_bind"), f->GetName()); | 210 CHECK_EQ(v8::String::New("native_bind"), f->GetName()); |
| 208 const v8::HeapGraphNode* bindings = | 211 const v8::HeapGraphNode* bindings = |
| 209 GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); | 212 GetProperty(f, v8::HeapGraphEdge::kInternal, "bindings"); |
| 210 CHECK_NE(NULL, bindings); | 213 CHECK_NE(NULL, bindings); |
| 211 CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); | 214 CHECK_EQ(v8::HeapGraphNode::kArray, bindings->GetType()); |
| 212 CHECK_EQ(4, bindings->GetChildrenCount()); | 215 CHECK_EQ(4, bindings->GetChildrenCount()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 224 const v8::HeapGraphNode* bound_argument = GetProperty( | 227 const v8::HeapGraphNode* bound_argument = GetProperty( |
| 225 f, v8::HeapGraphEdge::kShortcut, "bound_argument_1"); | 228 f, v8::HeapGraphEdge::kShortcut, "bound_argument_1"); |
| 226 CHECK(bound_argument); | 229 CHECK(bound_argument); |
| 227 CHECK_EQ(v8::HeapGraphNode::kObject, bound_argument->GetType()); | 230 CHECK_EQ(v8::HeapGraphNode::kObject, bound_argument->GetType()); |
| 228 } | 231 } |
| 229 | 232 |
| 230 | 233 |
| 231 TEST(HeapSnapshotEntryChildren) { | 234 TEST(HeapSnapshotEntryChildren) { |
| 232 LocalContext env; | 235 LocalContext env; |
| 233 v8::HandleScope scope(env->GetIsolate()); | 236 v8::HandleScope scope(env->GetIsolate()); |
| 237 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 234 | 238 |
| 235 CompileRun( | 239 CompileRun( |
| 236 "function A() { }\n" | 240 "function A() { }\n" |
| 237 "a = new A;"); | 241 "a = new A;"); |
| 238 const v8::HeapSnapshot* snapshot = | 242 const v8::HeapSnapshot* snapshot = |
| 239 v8::HeapProfiler::TakeSnapshot(v8_str("children")); | 243 heap_profiler->TakeHeapSnapshot(v8_str("children")); |
| 240 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 244 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 241 for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) { | 245 for (int i = 0, count = global->GetChildrenCount(); i < count; ++i) { |
| 242 const v8::HeapGraphEdge* prop = global->GetChild(i); | 246 const v8::HeapGraphEdge* prop = global->GetChild(i); |
| 243 CHECK_EQ(global, prop->GetFromNode()); | 247 CHECK_EQ(global, prop->GetFromNode()); |
| 244 } | 248 } |
| 245 const v8::HeapGraphNode* a = | 249 const v8::HeapGraphNode* a = |
| 246 GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); | 250 GetProperty(global, v8::HeapGraphEdge::kProperty, "a"); |
| 247 CHECK_NE(NULL, a); | 251 CHECK_NE(NULL, a); |
| 248 for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) { | 252 for (int i = 0, count = a->GetChildrenCount(); i < count; ++i) { |
| 249 const v8::HeapGraphEdge* prop = a->GetChild(i); | 253 const v8::HeapGraphEdge* prop = a->GetChild(i); |
| 250 CHECK_EQ(a, prop->GetFromNode()); | 254 CHECK_EQ(a, prop->GetFromNode()); |
| 251 } | 255 } |
| 252 } | 256 } |
| 253 | 257 |
| 254 | 258 |
| 255 TEST(HeapSnapshotCodeObjects) { | 259 TEST(HeapSnapshotCodeObjects) { |
| 256 LocalContext env; | 260 LocalContext env; |
| 257 v8::HandleScope scope(env->GetIsolate()); | 261 v8::HandleScope scope(env->GetIsolate()); |
| 262 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 258 | 263 |
| 259 CompileRun( | 264 CompileRun( |
| 260 "function lazy(x) { return x - 1; }\n" | 265 "function lazy(x) { return x - 1; }\n" |
| 261 "function compiled(x) { return x + 1; }\n" | 266 "function compiled(x) { return x + 1; }\n" |
| 262 "var anonymous = (function() { return function() { return 0; } })();\n" | 267 "var anonymous = (function() { return function() { return 0; } })();\n" |
| 263 "compiled(1)"); | 268 "compiled(1)"); |
| 264 const v8::HeapSnapshot* snapshot = | 269 const v8::HeapSnapshot* snapshot = |
| 265 v8::HeapProfiler::TakeSnapshot(v8_str("code")); | 270 heap_profiler->TakeHeapSnapshot(v8_str("code")); |
| 266 | 271 |
| 267 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 272 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 268 const v8::HeapGraphNode* compiled = | 273 const v8::HeapGraphNode* compiled = |
| 269 GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled"); | 274 GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled"); |
| 270 CHECK_NE(NULL, compiled); | 275 CHECK_NE(NULL, compiled); |
| 271 CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); | 276 CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); |
| 272 const v8::HeapGraphNode* lazy = | 277 const v8::HeapGraphNode* lazy = |
| 273 GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy"); | 278 GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy"); |
| 274 CHECK_NE(NULL, lazy); | 279 CHECK_NE(NULL, lazy); |
| 275 CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); | 280 CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 } | 318 } |
| 314 } | 319 } |
| 315 CHECK(compiled_references_x); | 320 CHECK(compiled_references_x); |
| 316 CHECK(!lazy_references_x); | 321 CHECK(!lazy_references_x); |
| 317 } | 322 } |
| 318 | 323 |
| 319 | 324 |
| 320 TEST(HeapSnapshotHeapNumbers) { | 325 TEST(HeapSnapshotHeapNumbers) { |
| 321 LocalContext env; | 326 LocalContext env; |
| 322 v8::HandleScope scope(env->GetIsolate()); | 327 v8::HandleScope scope(env->GetIsolate()); |
| 328 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 323 CompileRun( | 329 CompileRun( |
| 324 "a = 1; // a is Smi\n" | 330 "a = 1; // a is Smi\n" |
| 325 "b = 2.5; // b is HeapNumber"); | 331 "b = 2.5; // b is HeapNumber"); |
| 326 const v8::HeapSnapshot* snapshot = | 332 const v8::HeapSnapshot* snapshot = |
| 327 v8::HeapProfiler::TakeSnapshot(v8_str("numbers")); | 333 heap_profiler->TakeHeapSnapshot(v8_str("numbers")); |
| 328 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 334 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 329 CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a")); | 335 CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a")); |
| 330 const v8::HeapGraphNode* b = | 336 const v8::HeapGraphNode* b = |
| 331 GetProperty(global, v8::HeapGraphEdge::kProperty, "b"); | 337 GetProperty(global, v8::HeapGraphEdge::kProperty, "b"); |
| 332 CHECK_NE(NULL, b); | 338 CHECK_NE(NULL, b); |
| 333 CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); | 339 CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); |
| 334 } | 340 } |
| 335 | 341 |
| 336 TEST(HeapSnapshotSlicedString) { | 342 TEST(HeapSnapshotSlicedString) { |
| 337 LocalContext env; | 343 LocalContext env; |
| 338 v8::HandleScope scope(env->GetIsolate()); | 344 v8::HandleScope scope(env->GetIsolate()); |
| 345 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 339 CompileRun( | 346 CompileRun( |
| 340 "parent_string = \"123456789.123456789.123456789.123456789.123456789." | 347 "parent_string = \"123456789.123456789.123456789.123456789.123456789." |
| 341 "123456789.123456789.123456789.123456789.123456789." | 348 "123456789.123456789.123456789.123456789.123456789." |
| 342 "123456789.123456789.123456789.123456789.123456789." | 349 "123456789.123456789.123456789.123456789.123456789." |
| 343 "123456789.123456789.123456789.123456789.123456789.\";" | 350 "123456789.123456789.123456789.123456789.123456789.\";" |
| 344 "child_string = parent_string.slice(100);"); | 351 "child_string = parent_string.slice(100);"); |
| 345 const v8::HeapSnapshot* snapshot = | 352 const v8::HeapSnapshot* snapshot = |
| 346 v8::HeapProfiler::TakeSnapshot(v8_str("strings")); | 353 heap_profiler->TakeHeapSnapshot(v8_str("strings")); |
| 347 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 354 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 348 const v8::HeapGraphNode* parent_string = | 355 const v8::HeapGraphNode* parent_string = |
| 349 GetProperty(global, v8::HeapGraphEdge::kProperty, "parent_string"); | 356 GetProperty(global, v8::HeapGraphEdge::kProperty, "parent_string"); |
| 350 CHECK_NE(NULL, parent_string); | 357 CHECK_NE(NULL, parent_string); |
| 351 const v8::HeapGraphNode* child_string = | 358 const v8::HeapGraphNode* child_string = |
| 352 GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string"); | 359 GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string"); |
| 353 CHECK_NE(NULL, child_string); | 360 CHECK_NE(NULL, child_string); |
| 354 const v8::HeapGraphNode* parent = | 361 const v8::HeapGraphNode* parent = |
| 355 GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent"); | 362 GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent"); |
| 356 CHECK_EQ(parent_string, parent); | 363 CHECK_EQ(parent_string, parent); |
| 357 } | 364 } |
| 358 | 365 |
| 359 TEST(HeapSnapshotInternalReferences) { | 366 TEST(HeapSnapshotInternalReferences) { |
| 360 v8::HandleScope scope(v8::Isolate::GetCurrent()); | 367 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 368 v8::HandleScope scope(isolate); |
| 361 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); | 369 v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 362 global_template->SetInternalFieldCount(2); | 370 global_template->SetInternalFieldCount(2); |
| 363 LocalContext env(NULL, global_template); | 371 LocalContext env(NULL, global_template); |
| 364 v8::Handle<v8::Object> global_proxy = env->Global(); | 372 v8::Handle<v8::Object> global_proxy = env->Global(); |
| 365 v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); | 373 v8::Handle<v8::Object> global = global_proxy->GetPrototype().As<v8::Object>(); |
| 366 CHECK_EQ(2, global->InternalFieldCount()); | 374 CHECK_EQ(2, global->InternalFieldCount()); |
| 367 v8::Local<v8::Object> obj = v8::Object::New(); | 375 v8::Local<v8::Object> obj = v8::Object::New(); |
| 368 global->SetInternalField(0, v8_num(17)); | 376 global->SetInternalField(0, v8_num(17)); |
| 369 global->SetInternalField(1, obj); | 377 global->SetInternalField(1, obj); |
| 378 v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); |
| 370 const v8::HeapSnapshot* snapshot = | 379 const v8::HeapSnapshot* snapshot = |
| 371 v8::HeapProfiler::TakeSnapshot(v8_str("internals")); | 380 heap_profiler->TakeHeapSnapshot(v8_str("internals")); |
| 372 const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); | 381 const v8::HeapGraphNode* global_node = GetGlobalObject(snapshot); |
| 373 // The first reference will not present, because it's a Smi. | 382 // The first reference will not present, because it's a Smi. |
| 374 CHECK_EQ(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0")); | 383 CHECK_EQ(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "0")); |
| 375 // The second reference is to an object. | 384 // The second reference is to an object. |
| 376 CHECK_NE(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "1")); | 385 CHECK_NE(NULL, GetProperty(global_node, v8::HeapGraphEdge::kInternal, "1")); |
| 377 } | 386 } |
| 378 | 387 |
| 379 | 388 |
| 380 // Trying to introduce a check helper for uint32_t causes many | 389 // Trying to introduce a check helper for uint32_t causes many |
| 381 // overloading ambiguities, so it seems easier just to cast | 390 // overloading ambiguities, so it seems easier just to cast |
| 382 // them to a signed type. | 391 // them to a signed type. |
| 383 #define CHECK_EQ_SNAPSHOT_OBJECT_ID(a, b) \ | 392 #define CHECK_EQ_SNAPSHOT_OBJECT_ID(a, b) \ |
| 384 CHECK_EQ(static_cast<int32_t>(a), static_cast<int32_t>(b)) | 393 CHECK_EQ(static_cast<int32_t>(a), static_cast<int32_t>(b)) |
| 385 #define CHECK_NE_SNAPSHOT_OBJECT_ID(a, b) \ | 394 #define CHECK_NE_SNAPSHOT_OBJECT_ID(a, b) \ |
| 386 CHECK((a) != (b)) // NOLINT | 395 CHECK((a) != (b)) // NOLINT |
| 387 | 396 |
| 388 TEST(HeapSnapshotAddressReuse) { | 397 TEST(HeapSnapshotAddressReuse) { |
| 389 LocalContext env; | 398 LocalContext env; |
| 390 v8::HandleScope scope(env->GetIsolate()); | 399 v8::HandleScope scope(env->GetIsolate()); |
| 400 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 391 | 401 |
| 392 CompileRun( | 402 CompileRun( |
| 393 "function A() {}\n" | 403 "function A() {}\n" |
| 394 "var a = [];\n" | 404 "var a = [];\n" |
| 395 "for (var i = 0; i < 10000; ++i)\n" | 405 "for (var i = 0; i < 10000; ++i)\n" |
| 396 " a[i] = new A();\n"); | 406 " a[i] = new A();\n"); |
| 397 const v8::HeapSnapshot* snapshot1 = | 407 const v8::HeapSnapshot* snapshot1 = |
| 398 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot1")); | 408 heap_profiler->TakeHeapSnapshot(v8_str("snapshot1")); |
| 399 v8::SnapshotObjectId maxId1 = snapshot1->GetMaxSnapshotJSObjectId(); | 409 v8::SnapshotObjectId maxId1 = snapshot1->GetMaxSnapshotJSObjectId(); |
| 400 | 410 |
| 401 CompileRun( | 411 CompileRun( |
| 402 "for (var i = 0; i < 10000; ++i)\n" | 412 "for (var i = 0; i < 10000; ++i)\n" |
| 403 " a[i] = new A();\n"); | 413 " a[i] = new A();\n"); |
| 404 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 414 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 405 | 415 |
| 406 const v8::HeapSnapshot* snapshot2 = | 416 const v8::HeapSnapshot* snapshot2 = |
| 407 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot2")); | 417 heap_profiler->TakeHeapSnapshot(v8_str("snapshot2")); |
| 408 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); | 418 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); |
| 409 | 419 |
| 410 const v8::HeapGraphNode* array_node = | 420 const v8::HeapGraphNode* array_node = |
| 411 GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); | 421 GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); |
| 412 CHECK_NE(NULL, array_node); | 422 CHECK_NE(NULL, array_node); |
| 413 int wrong_count = 0; | 423 int wrong_count = 0; |
| 414 for (int i = 0, count = array_node->GetChildrenCount(); i < count; ++i) { | 424 for (int i = 0, count = array_node->GetChildrenCount(); i < count; ++i) { |
| 415 const v8::HeapGraphEdge* prop = array_node->GetChild(i); | 425 const v8::HeapGraphEdge* prop = array_node->GetChild(i); |
| 416 if (prop->GetType() != v8::HeapGraphEdge::kElement) | 426 if (prop->GetType() != v8::HeapGraphEdge::kElement) |
| 417 continue; | 427 continue; |
| 418 v8::SnapshotObjectId id = prop->GetToNode()->GetId(); | 428 v8::SnapshotObjectId id = prop->GetToNode()->GetId(); |
| 419 if (id < maxId1) | 429 if (id < maxId1) |
| 420 ++wrong_count; | 430 ++wrong_count; |
| 421 } | 431 } |
| 422 CHECK_EQ(0, wrong_count); | 432 CHECK_EQ(0, wrong_count); |
| 423 } | 433 } |
| 424 | 434 |
| 425 | 435 |
| 426 TEST(HeapEntryIdsAndArrayShift) { | 436 TEST(HeapEntryIdsAndArrayShift) { |
| 427 LocalContext env; | 437 LocalContext env; |
| 428 v8::HandleScope scope(env->GetIsolate()); | 438 v8::HandleScope scope(env->GetIsolate()); |
| 439 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 429 | 440 |
| 430 CompileRun( | 441 CompileRun( |
| 431 "function AnObject() {\n" | 442 "function AnObject() {\n" |
| 432 " this.first = 'first';\n" | 443 " this.first = 'first';\n" |
| 433 " this.second = 'second';\n" | 444 " this.second = 'second';\n" |
| 434 "}\n" | 445 "}\n" |
| 435 "var a = new Array();\n" | 446 "var a = new Array();\n" |
| 436 "for (var i = 0; i < 10; ++i)\n" | 447 "for (var i = 0; i < 10; ++i)\n" |
| 437 " a.push(new AnObject());\n"); | 448 " a.push(new AnObject());\n"); |
| 438 const v8::HeapSnapshot* snapshot1 = | 449 const v8::HeapSnapshot* snapshot1 = |
| 439 v8::HeapProfiler::TakeSnapshot(v8_str("s1")); | 450 heap_profiler->TakeHeapSnapshot(v8_str("s1")); |
| 440 | 451 |
| 441 CompileRun( | 452 CompileRun( |
| 442 "for (var i = 0; i < 1; ++i)\n" | 453 "for (var i = 0; i < 1; ++i)\n" |
| 443 " a.shift();\n"); | 454 " a.shift();\n"); |
| 444 | 455 |
| 445 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 456 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 446 | 457 |
| 447 const v8::HeapSnapshot* snapshot2 = | 458 const v8::HeapSnapshot* snapshot2 = |
| 448 v8::HeapProfiler::TakeSnapshot(v8_str("s2")); | 459 heap_profiler->TakeHeapSnapshot(v8_str("s2")); |
| 449 | 460 |
| 450 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); | 461 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); |
| 451 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); | 462 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); |
| 452 CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); | 463 CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); |
| 453 CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); | 464 CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); |
| 454 | 465 |
| 455 const v8::HeapGraphNode* a1 = | 466 const v8::HeapGraphNode* a1 = |
| 456 GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); | 467 GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); |
| 457 CHECK_NE(NULL, a1); | 468 CHECK_NE(NULL, a1); |
| 458 const v8::HeapGraphNode* k1 = | 469 const v8::HeapGraphNode* k1 = |
| 459 GetProperty(a1, v8::HeapGraphEdge::kInternal, "elements"); | 470 GetProperty(a1, v8::HeapGraphEdge::kInternal, "elements"); |
| 460 CHECK_NE(NULL, k1); | 471 CHECK_NE(NULL, k1); |
| 461 const v8::HeapGraphNode* a2 = | 472 const v8::HeapGraphNode* a2 = |
| 462 GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); | 473 GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); |
| 463 CHECK_NE(NULL, a2); | 474 CHECK_NE(NULL, a2); |
| 464 const v8::HeapGraphNode* k2 = | 475 const v8::HeapGraphNode* k2 = |
| 465 GetProperty(a2, v8::HeapGraphEdge::kInternal, "elements"); | 476 GetProperty(a2, v8::HeapGraphEdge::kInternal, "elements"); |
| 466 CHECK_NE(NULL, k2); | 477 CHECK_NE(NULL, k2); |
| 467 | 478 |
| 468 CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); | 479 CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); |
| 469 CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId()); | 480 CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId()); |
| 470 } | 481 } |
| 471 | 482 |
| 472 TEST(HeapEntryIdsAndGC) { | 483 TEST(HeapEntryIdsAndGC) { |
| 473 LocalContext env; | 484 LocalContext env; |
| 474 v8::HandleScope scope(env->GetIsolate()); | 485 v8::HandleScope scope(env->GetIsolate()); |
| 486 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 475 | 487 |
| 476 CompileRun( | 488 CompileRun( |
| 477 "function A() {}\n" | 489 "function A() {}\n" |
| 478 "function B(x) { this.x = x; }\n" | 490 "function B(x) { this.x = x; }\n" |
| 479 "var a = new A();\n" | 491 "var a = new A();\n" |
| 480 "var b = new B(a);"); | 492 "var b = new B(a);"); |
| 481 v8::Local<v8::String> s1_str = v8_str("s1"); | 493 v8::Local<v8::String> s1_str = v8_str("s1"); |
| 482 v8::Local<v8::String> s2_str = v8_str("s2"); | 494 v8::Local<v8::String> s2_str = v8_str("s2"); |
| 483 const v8::HeapSnapshot* snapshot1 = | 495 const v8::HeapSnapshot* snapshot1 = |
| 484 v8::HeapProfiler::TakeSnapshot(s1_str); | 496 heap_profiler->TakeHeapSnapshot(s1_str); |
| 485 | 497 |
| 486 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 498 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 487 | 499 |
| 488 const v8::HeapSnapshot* snapshot2 = | 500 const v8::HeapSnapshot* snapshot2 = |
| 489 v8::HeapProfiler::TakeSnapshot(s2_str); | 501 heap_profiler->TakeHeapSnapshot(s2_str); |
| 490 | 502 |
| 491 CHECK_GT(snapshot1->GetMaxSnapshotJSObjectId(), 7000); | 503 CHECK_GT(snapshot1->GetMaxSnapshotJSObjectId(), 7000); |
| 492 CHECK(snapshot1->GetMaxSnapshotJSObjectId() <= | 504 CHECK(snapshot1->GetMaxSnapshotJSObjectId() <= |
| 493 snapshot2->GetMaxSnapshotJSObjectId()); | 505 snapshot2->GetMaxSnapshotJSObjectId()); |
| 494 | 506 |
| 495 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); | 507 const v8::HeapGraphNode* global1 = GetGlobalObject(snapshot1); |
| 496 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); | 508 const v8::HeapGraphNode* global2 = GetGlobalObject(snapshot2); |
| 497 CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); | 509 CHECK_NE_SNAPSHOT_OBJECT_ID(0, global1->GetId()); |
| 498 CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); | 510 CHECK_EQ_SNAPSHOT_OBJECT_ID(global1->GetId(), global2->GetId()); |
| 499 const v8::HeapGraphNode* A1 = | 511 const v8::HeapGraphNode* A1 = |
| (...skipping 27 matching lines...) Expand all Loading... |
| 527 GetProperty(global2, v8::HeapGraphEdge::kProperty, "b"); | 539 GetProperty(global2, v8::HeapGraphEdge::kProperty, "b"); |
| 528 CHECK_NE(NULL, b2); | 540 CHECK_NE(NULL, b2); |
| 529 CHECK_NE_SNAPSHOT_OBJECT_ID(0, b1->GetId()); | 541 CHECK_NE_SNAPSHOT_OBJECT_ID(0, b1->GetId()); |
| 530 CHECK_EQ_SNAPSHOT_OBJECT_ID(b1->GetId(), b2->GetId()); | 542 CHECK_EQ_SNAPSHOT_OBJECT_ID(b1->GetId(), b2->GetId()); |
| 531 } | 543 } |
| 532 | 544 |
| 533 | 545 |
| 534 TEST(HeapSnapshotRootPreservedAfterSorting) { | 546 TEST(HeapSnapshotRootPreservedAfterSorting) { |
| 535 LocalContext env; | 547 LocalContext env; |
| 536 v8::HandleScope scope(env->GetIsolate()); | 548 v8::HandleScope scope(env->GetIsolate()); |
| 549 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 537 const v8::HeapSnapshot* snapshot = | 550 const v8::HeapSnapshot* snapshot = |
| 538 v8::HeapProfiler::TakeSnapshot(v8_str("s")); | 551 heap_profiler->TakeHeapSnapshot(v8_str("s")); |
| 539 const v8::HeapGraphNode* root1 = snapshot->GetRoot(); | 552 const v8::HeapGraphNode* root1 = snapshot->GetRoot(); |
| 540 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( | 553 const_cast<i::HeapSnapshot*>(reinterpret_cast<const i::HeapSnapshot*>( |
| 541 snapshot))->GetSortedEntriesList(); | 554 snapshot))->GetSortedEntriesList(); |
| 542 const v8::HeapGraphNode* root2 = snapshot->GetRoot(); | 555 const v8::HeapGraphNode* root2 = snapshot->GetRoot(); |
| 543 CHECK_EQ(root1, root2); | 556 CHECK_EQ(root1, root2); |
| 544 } | 557 } |
| 545 | 558 |
| 546 | 559 |
| 547 namespace { | 560 namespace { |
| 548 | 561 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 private: | 598 private: |
| 586 const char* data_; | 599 const char* data_; |
| 587 size_t length_; | 600 size_t length_; |
| 588 }; | 601 }; |
| 589 | 602 |
| 590 } // namespace | 603 } // namespace |
| 591 | 604 |
| 592 TEST(HeapSnapshotJSONSerialization) { | 605 TEST(HeapSnapshotJSONSerialization) { |
| 593 LocalContext env; | 606 LocalContext env; |
| 594 v8::HandleScope scope(env->GetIsolate()); | 607 v8::HandleScope scope(env->GetIsolate()); |
| 608 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 595 | 609 |
| 596 #define STRING_LITERAL_FOR_TEST \ | 610 #define STRING_LITERAL_FOR_TEST \ |
| 597 "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\"" | 611 "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\"" |
| 598 CompileRun( | 612 CompileRun( |
| 599 "function A(s) { this.s = s; }\n" | 613 "function A(s) { this.s = s; }\n" |
| 600 "function B(x) { this.x = x; }\n" | 614 "function B(x) { this.x = x; }\n" |
| 601 "var a = new A(" STRING_LITERAL_FOR_TEST ");\n" | 615 "var a = new A(" STRING_LITERAL_FOR_TEST ");\n" |
| 602 "var b = new B(a);"); | 616 "var b = new B(a);"); |
| 603 const v8::HeapSnapshot* snapshot = | 617 const v8::HeapSnapshot* snapshot = |
| 604 v8::HeapProfiler::TakeSnapshot(v8_str("json")); | 618 heap_profiler->TakeHeapSnapshot(v8_str("json")); |
| 605 TestJSONStream stream; | 619 TestJSONStream stream; |
| 606 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 620 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
| 607 CHECK_GT(stream.size(), 0); | 621 CHECK_GT(stream.size(), 0); |
| 608 CHECK_EQ(1, stream.eos_signaled()); | 622 CHECK_EQ(1, stream.eos_signaled()); |
| 609 i::ScopedVector<char> json(stream.size()); | 623 i::ScopedVector<char> json(stream.size()); |
| 610 stream.WriteTo(json); | 624 stream.WriteTo(json); |
| 611 | 625 |
| 612 // Verify that snapshot string is valid JSON. | 626 // Verify that snapshot string is valid JSON. |
| 613 AsciiResource json_res(json); | 627 AsciiResource json_res(json); |
| 614 v8::Local<v8::String> json_string = v8::String::NewExternal(&json_res); | 628 v8::Local<v8::String> json_string = v8::String::NewExternal(&json_res); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 CompileRun(STRING_LITERAL_FOR_TEST)->ToString(); | 701 CompileRun(STRING_LITERAL_FOR_TEST)->ToString(); |
| 688 #undef STRING_LITERAL_FOR_TEST | 702 #undef STRING_LITERAL_FOR_TEST |
| 689 CHECK_EQ(*v8::String::Utf8Value(ref_string), | 703 CHECK_EQ(*v8::String::Utf8Value(ref_string), |
| 690 *v8::String::Utf8Value(string)); | 704 *v8::String::Utf8Value(string)); |
| 691 } | 705 } |
| 692 | 706 |
| 693 | 707 |
| 694 TEST(HeapSnapshotJSONSerializationAborting) { | 708 TEST(HeapSnapshotJSONSerializationAborting) { |
| 695 LocalContext env; | 709 LocalContext env; |
| 696 v8::HandleScope scope(env->GetIsolate()); | 710 v8::HandleScope scope(env->GetIsolate()); |
| 711 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 697 const v8::HeapSnapshot* snapshot = | 712 const v8::HeapSnapshot* snapshot = |
| 698 v8::HeapProfiler::TakeSnapshot(v8_str("abort")); | 713 heap_profiler->TakeHeapSnapshot(v8_str("abort")); |
| 699 TestJSONStream stream(5); | 714 TestJSONStream stream(5); |
| 700 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); | 715 snapshot->Serialize(&stream, v8::HeapSnapshot::kJSON); |
| 701 CHECK_GT(stream.size(), 0); | 716 CHECK_GT(stream.size(), 0); |
| 702 CHECK_EQ(0, stream.eos_signaled()); | 717 CHECK_EQ(0, stream.eos_signaled()); |
| 703 } | 718 } |
| 704 | 719 |
| 705 namespace { | 720 namespace { |
| 706 | 721 |
| 707 class TestStatsStream : public v8::OutputStream { | 722 class TestStatsStream : public v8::OutputStream { |
| 708 public: | 723 public: |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 int updates_written_; | 769 int updates_written_; |
| 755 uint32_t entries_count_; | 770 uint32_t entries_count_; |
| 756 uint32_t entries_size_; | 771 uint32_t entries_size_; |
| 757 int intervals_count_; | 772 int intervals_count_; |
| 758 int first_interval_index_; | 773 int first_interval_index_; |
| 759 }; | 774 }; |
| 760 | 775 |
| 761 } // namespace | 776 } // namespace |
| 762 | 777 |
| 763 static TestStatsStream GetHeapStatsUpdate( | 778 static TestStatsStream GetHeapStatsUpdate( |
| 779 v8::HeapProfiler* heap_profiler, |
| 764 v8::SnapshotObjectId* object_id = NULL) { | 780 v8::SnapshotObjectId* object_id = NULL) { |
| 765 TestStatsStream stream; | 781 TestStatsStream stream; |
| 766 v8::SnapshotObjectId last_seen_id = | 782 v8::SnapshotObjectId last_seen_id = heap_profiler->GetHeapStats(&stream); |
| 767 v8::HeapProfiler::PushHeapObjectsStats(&stream); | |
| 768 if (object_id) | 783 if (object_id) |
| 769 *object_id = last_seen_id; | 784 *object_id = last_seen_id; |
| 770 CHECK_EQ(1, stream.eos_signaled()); | 785 CHECK_EQ(1, stream.eos_signaled()); |
| 771 return stream; | 786 return stream; |
| 772 } | 787 } |
| 773 | 788 |
| 774 | 789 |
| 775 TEST(HeapSnapshotObjectsStats) { | 790 TEST(HeapSnapshotObjectsStats) { |
| 776 LocalContext env; | 791 LocalContext env; |
| 777 v8::HandleScope scope(env->GetIsolate()); | 792 v8::HandleScope scope(env->GetIsolate()); |
| 793 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 778 | 794 |
| 779 v8::HeapProfiler::StartHeapObjectsTracking(); | 795 heap_profiler->StartTrackingHeapObjects(); |
| 780 // We have to call GC 6 times. In other case the garbage will be | 796 // We have to call GC 6 times. In other case the garbage will be |
| 781 // the reason of flakiness. | 797 // the reason of flakiness. |
| 782 for (int i = 0; i < 6; ++i) { | 798 for (int i = 0; i < 6; ++i) { |
| 783 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 799 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 784 } | 800 } |
| 785 | 801 |
| 786 v8::SnapshotObjectId initial_id; | 802 v8::SnapshotObjectId initial_id; |
| 787 { | 803 { |
| 788 // Single chunk of data expected in update. Initial data. | 804 // Single chunk of data expected in update. Initial data. |
| 789 TestStatsStream stats_update = GetHeapStatsUpdate(&initial_id); | 805 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler, |
| 806 &initial_id); |
| 790 CHECK_EQ(1, stats_update.intervals_count()); | 807 CHECK_EQ(1, stats_update.intervals_count()); |
| 791 CHECK_EQ(1, stats_update.updates_written()); | 808 CHECK_EQ(1, stats_update.updates_written()); |
| 792 CHECK_LT(0, stats_update.entries_size()); | 809 CHECK_LT(0, stats_update.entries_size()); |
| 793 CHECK_EQ(0, stats_update.first_interval_index()); | 810 CHECK_EQ(0, stats_update.first_interval_index()); |
| 794 } | 811 } |
| 795 | 812 |
| 796 // No data expected in update because nothing has happened. | 813 // No data expected in update because nothing has happened. |
| 797 v8::SnapshotObjectId same_id; | 814 v8::SnapshotObjectId same_id; |
| 798 CHECK_EQ(0, GetHeapStatsUpdate(&same_id).updates_written()); | 815 CHECK_EQ(0, GetHeapStatsUpdate(heap_profiler, &same_id).updates_written()); |
| 799 CHECK_EQ_SNAPSHOT_OBJECT_ID(initial_id, same_id); | 816 CHECK_EQ_SNAPSHOT_OBJECT_ID(initial_id, same_id); |
| 800 | 817 |
| 801 { | 818 { |
| 802 v8::SnapshotObjectId additional_string_id; | 819 v8::SnapshotObjectId additional_string_id; |
| 803 v8::HandleScope inner_scope_1(env->GetIsolate()); | 820 v8::HandleScope inner_scope_1(env->GetIsolate()); |
| 804 v8_str("string1"); | 821 v8_str("string1"); |
| 805 { | 822 { |
| 806 // Single chunk of data with one new entry expected in update. | 823 // Single chunk of data with one new entry expected in update. |
| 807 TestStatsStream stats_update = GetHeapStatsUpdate(&additional_string_id); | 824 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler, |
| 825 &additional_string_id); |
| 808 CHECK_LT(same_id, additional_string_id); | 826 CHECK_LT(same_id, additional_string_id); |
| 809 CHECK_EQ(1, stats_update.intervals_count()); | 827 CHECK_EQ(1, stats_update.intervals_count()); |
| 810 CHECK_EQ(1, stats_update.updates_written()); | 828 CHECK_EQ(1, stats_update.updates_written()); |
| 811 CHECK_LT(0, stats_update.entries_size()); | 829 CHECK_LT(0, stats_update.entries_size()); |
| 812 CHECK_EQ(1, stats_update.entries_count()); | 830 CHECK_EQ(1, stats_update.entries_count()); |
| 813 CHECK_EQ(2, stats_update.first_interval_index()); | 831 CHECK_EQ(2, stats_update.first_interval_index()); |
| 814 } | 832 } |
| 815 | 833 |
| 816 // No data expected in update because nothing happened. | 834 // No data expected in update because nothing happened. |
| 817 v8::SnapshotObjectId last_id; | 835 v8::SnapshotObjectId last_id; |
| 818 CHECK_EQ(0, GetHeapStatsUpdate(&last_id).updates_written()); | 836 CHECK_EQ(0, GetHeapStatsUpdate(heap_profiler, &last_id).updates_written()); |
| 819 CHECK_EQ_SNAPSHOT_OBJECT_ID(additional_string_id, last_id); | 837 CHECK_EQ_SNAPSHOT_OBJECT_ID(additional_string_id, last_id); |
| 820 | 838 |
| 821 { | 839 { |
| 822 v8::HandleScope inner_scope_2(env->GetIsolate()); | 840 v8::HandleScope inner_scope_2(env->GetIsolate()); |
| 823 v8_str("string2"); | 841 v8_str("string2"); |
| 824 | 842 |
| 825 uint32_t entries_size; | 843 uint32_t entries_size; |
| 826 { | 844 { |
| 827 v8::HandleScope inner_scope_3(env->GetIsolate()); | 845 v8::HandleScope inner_scope_3(env->GetIsolate()); |
| 828 v8_str("string3"); | 846 v8_str("string3"); |
| 829 v8_str("string4"); | 847 v8_str("string4"); |
| 830 | 848 |
| 831 { | 849 { |
| 832 // Single chunk of data with three new entries expected in update. | 850 // Single chunk of data with three new entries expected in update. |
| 833 TestStatsStream stats_update = GetHeapStatsUpdate(); | 851 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); |
| 834 CHECK_EQ(1, stats_update.intervals_count()); | 852 CHECK_EQ(1, stats_update.intervals_count()); |
| 835 CHECK_EQ(1, stats_update.updates_written()); | 853 CHECK_EQ(1, stats_update.updates_written()); |
| 836 CHECK_LT(0, entries_size = stats_update.entries_size()); | 854 CHECK_LT(0, entries_size = stats_update.entries_size()); |
| 837 CHECK_EQ(3, stats_update.entries_count()); | 855 CHECK_EQ(3, stats_update.entries_count()); |
| 838 CHECK_EQ(4, stats_update.first_interval_index()); | 856 CHECK_EQ(4, stats_update.first_interval_index()); |
| 839 } | 857 } |
| 840 } | 858 } |
| 841 | 859 |
| 842 { | 860 { |
| 843 // Single chunk of data with two left entries expected in update. | 861 // Single chunk of data with two left entries expected in update. |
| 844 TestStatsStream stats_update = GetHeapStatsUpdate(); | 862 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); |
| 845 CHECK_EQ(1, stats_update.intervals_count()); | 863 CHECK_EQ(1, stats_update.intervals_count()); |
| 846 CHECK_EQ(1, stats_update.updates_written()); | 864 CHECK_EQ(1, stats_update.updates_written()); |
| 847 CHECK_GT(entries_size, stats_update.entries_size()); | 865 CHECK_GT(entries_size, stats_update.entries_size()); |
| 848 CHECK_EQ(1, stats_update.entries_count()); | 866 CHECK_EQ(1, stats_update.entries_count()); |
| 849 // Two strings from forth interval were released. | 867 // Two strings from forth interval were released. |
| 850 CHECK_EQ(4, stats_update.first_interval_index()); | 868 CHECK_EQ(4, stats_update.first_interval_index()); |
| 851 } | 869 } |
| 852 } | 870 } |
| 853 | 871 |
| 854 { | 872 { |
| 855 // Single chunk of data with 0 left entries expected in update. | 873 // Single chunk of data with 0 left entries expected in update. |
| 856 TestStatsStream stats_update = GetHeapStatsUpdate(); | 874 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); |
| 857 CHECK_EQ(1, stats_update.intervals_count()); | 875 CHECK_EQ(1, stats_update.intervals_count()); |
| 858 CHECK_EQ(1, stats_update.updates_written()); | 876 CHECK_EQ(1, stats_update.updates_written()); |
| 859 CHECK_EQ(0, stats_update.entries_size()); | 877 CHECK_EQ(0, stats_update.entries_size()); |
| 860 CHECK_EQ(0, stats_update.entries_count()); | 878 CHECK_EQ(0, stats_update.entries_count()); |
| 861 // The last string from forth interval was released. | 879 // The last string from forth interval was released. |
| 862 CHECK_EQ(4, stats_update.first_interval_index()); | 880 CHECK_EQ(4, stats_update.first_interval_index()); |
| 863 } | 881 } |
| 864 } | 882 } |
| 865 { | 883 { |
| 866 // Single chunk of data with 0 left entries expected in update. | 884 // Single chunk of data with 0 left entries expected in update. |
| 867 TestStatsStream stats_update = GetHeapStatsUpdate(); | 885 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); |
| 868 CHECK_EQ(1, stats_update.intervals_count()); | 886 CHECK_EQ(1, stats_update.intervals_count()); |
| 869 CHECK_EQ(1, stats_update.updates_written()); | 887 CHECK_EQ(1, stats_update.updates_written()); |
| 870 CHECK_EQ(0, stats_update.entries_size()); | 888 CHECK_EQ(0, stats_update.entries_size()); |
| 871 CHECK_EQ(0, stats_update.entries_count()); | 889 CHECK_EQ(0, stats_update.entries_count()); |
| 872 // The only string from the second interval was released. | 890 // The only string from the second interval was released. |
| 873 CHECK_EQ(2, stats_update.first_interval_index()); | 891 CHECK_EQ(2, stats_update.first_interval_index()); |
| 874 } | 892 } |
| 875 | 893 |
| 876 v8::Local<v8::Array> array = v8::Array::New(); | 894 v8::Local<v8::Array> array = v8::Array::New(); |
| 877 CHECK_EQ(0, array->Length()); | 895 CHECK_EQ(0, array->Length()); |
| 878 // Force array's buffer allocation. | 896 // Force array's buffer allocation. |
| 879 array->Set(2, v8_num(7)); | 897 array->Set(2, v8_num(7)); |
| 880 | 898 |
| 881 uint32_t entries_size; | 899 uint32_t entries_size; |
| 882 { | 900 { |
| 883 // Single chunk of data with 2 entries expected in update. | 901 // Single chunk of data with 2 entries expected in update. |
| 884 TestStatsStream stats_update = GetHeapStatsUpdate(); | 902 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); |
| 885 CHECK_EQ(1, stats_update.intervals_count()); | 903 CHECK_EQ(1, stats_update.intervals_count()); |
| 886 CHECK_EQ(1, stats_update.updates_written()); | 904 CHECK_EQ(1, stats_update.updates_written()); |
| 887 CHECK_LT(0, entries_size = stats_update.entries_size()); | 905 CHECK_LT(0, entries_size = stats_update.entries_size()); |
| 888 // They are the array and its buffer. | 906 // They are the array and its buffer. |
| 889 CHECK_EQ(2, stats_update.entries_count()); | 907 CHECK_EQ(2, stats_update.entries_count()); |
| 890 CHECK_EQ(8, stats_update.first_interval_index()); | 908 CHECK_EQ(8, stats_update.first_interval_index()); |
| 891 } | 909 } |
| 892 | 910 |
| 893 for (int i = 0; i < 100; ++i) | 911 for (int i = 0; i < 100; ++i) |
| 894 array->Set(i, v8_num(i)); | 912 array->Set(i, v8_num(i)); |
| 895 | 913 |
| 896 { | 914 { |
| 897 // Single chunk of data with 1 entry expected in update. | 915 // Single chunk of data with 1 entry expected in update. |
| 898 TestStatsStream stats_update = GetHeapStatsUpdate(); | 916 TestStatsStream stats_update = GetHeapStatsUpdate(heap_profiler); |
| 899 CHECK_EQ(1, stats_update.intervals_count()); | 917 CHECK_EQ(1, stats_update.intervals_count()); |
| 900 // The first interval was changed because old buffer was collected. | 918 // The first interval was changed because old buffer was collected. |
| 901 // The second interval was changed because new buffer was allocated. | 919 // The second interval was changed because new buffer was allocated. |
| 902 CHECK_EQ(2, stats_update.updates_written()); | 920 CHECK_EQ(2, stats_update.updates_written()); |
| 903 CHECK_LT(entries_size, stats_update.entries_size()); | 921 CHECK_LT(entries_size, stats_update.entries_size()); |
| 904 CHECK_EQ(2, stats_update.entries_count()); | 922 CHECK_EQ(2, stats_update.entries_count()); |
| 905 CHECK_EQ(8, stats_update.first_interval_index()); | 923 CHECK_EQ(8, stats_update.first_interval_index()); |
| 906 } | 924 } |
| 907 | 925 |
| 908 v8::HeapProfiler::StopHeapObjectsTracking(); | 926 heap_profiler->StopTrackingHeapObjects(); |
| 909 } | 927 } |
| 910 | 928 |
| 911 | 929 |
| 912 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, | 930 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, |
| 913 const v8::HeapGraphNode* node, | 931 const v8::HeapGraphNode* node, |
| 914 int level, int max_level) { | 932 int level, int max_level) { |
| 915 if (level > max_level) return; | 933 if (level > max_level) return; |
| 916 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); | 934 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); |
| 917 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { | 935 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { |
| 918 const v8::HeapGraphEdge* prop = node->GetChild(i); | 936 const v8::HeapGraphEdge* prop = node->GetChild(i); |
| 919 const v8::HeapGraphNode* child = | 937 const v8::HeapGraphNode* child = |
| 920 snapshot->GetNodeById(prop->GetToNode()->GetId()); | 938 snapshot->GetNodeById(prop->GetToNode()->GetId()); |
| 921 CHECK_EQ_SNAPSHOT_OBJECT_ID(prop->GetToNode()->GetId(), child->GetId()); | 939 CHECK_EQ_SNAPSHOT_OBJECT_ID(prop->GetToNode()->GetId(), child->GetId()); |
| 922 CHECK_EQ(prop->GetToNode(), child); | 940 CHECK_EQ(prop->GetToNode(), child); |
| 923 CheckChildrenIds(snapshot, child, level + 1, max_level); | 941 CheckChildrenIds(snapshot, child, level + 1, max_level); |
| 924 } | 942 } |
| 925 } | 943 } |
| 926 | 944 |
| 927 | 945 |
| 928 TEST(HeapSnapshotGetNodeById) { | 946 TEST(HeapSnapshotGetNodeById) { |
| 929 LocalContext env; | 947 LocalContext env; |
| 930 v8::HandleScope scope(env->GetIsolate()); | 948 v8::HandleScope scope(env->GetIsolate()); |
| 949 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 931 | 950 |
| 932 const v8::HeapSnapshot* snapshot = | 951 const v8::HeapSnapshot* snapshot = |
| 933 v8::HeapProfiler::TakeSnapshot(v8_str("id")); | 952 heap_profiler->TakeHeapSnapshot(v8_str("id")); |
| 934 const v8::HeapGraphNode* root = snapshot->GetRoot(); | 953 const v8::HeapGraphNode* root = snapshot->GetRoot(); |
| 935 CheckChildrenIds(snapshot, root, 0, 3); | 954 CheckChildrenIds(snapshot, root, 0, 3); |
| 936 // Check a big id, which should not exist yet. | 955 // Check a big id, which should not exist yet. |
| 937 CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); | 956 CHECK_EQ(NULL, snapshot->GetNodeById(0x1000000UL)); |
| 938 } | 957 } |
| 939 | 958 |
| 940 | 959 |
| 941 TEST(HeapSnapshotGetSnapshotObjectId) { | 960 TEST(HeapSnapshotGetSnapshotObjectId) { |
| 942 LocalContext env; | 961 LocalContext env; |
| 943 v8::HandleScope scope(env->GetIsolate()); | 962 v8::HandleScope scope(env->GetIsolate()); |
| 963 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 944 CompileRun("globalObject = {};\n"); | 964 CompileRun("globalObject = {};\n"); |
| 945 const v8::HeapSnapshot* snapshot = | 965 const v8::HeapSnapshot* snapshot = |
| 946 v8::HeapProfiler::TakeSnapshot(v8_str("get_snapshot_object_id")); | 966 heap_profiler->TakeHeapSnapshot(v8_str("get_snapshot_object_id")); |
| 947 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 967 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 948 const v8::HeapGraphNode* global_object = | 968 const v8::HeapGraphNode* global_object = |
| 949 GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); | 969 GetProperty(global, v8::HeapGraphEdge::kProperty, "globalObject"); |
| 950 CHECK(global_object); | 970 CHECK(global_object); |
| 951 | 971 |
| 952 v8::Local<v8::Value> globalObjectHandle = | 972 v8::Local<v8::Value> globalObjectHandle = |
| 953 env->Global()->Get(v8::String::New("globalObject")); | 973 env->Global()->Get(v8::String::New("globalObject")); |
| 954 CHECK(!globalObjectHandle.IsEmpty()); | 974 CHECK(!globalObjectHandle.IsEmpty()); |
| 955 CHECK(globalObjectHandle->IsObject()); | 975 CHECK(globalObjectHandle->IsObject()); |
| 956 | 976 |
| 957 v8::SnapshotObjectId id = | 977 v8::SnapshotObjectId id = heap_profiler->GetObjectId(globalObjectHandle); |
| 958 v8::HeapProfiler::GetSnapshotObjectId(globalObjectHandle); | |
| 959 CHECK_NE(static_cast<int>(v8::HeapProfiler::kUnknownObjectId), | 978 CHECK_NE(static_cast<int>(v8::HeapProfiler::kUnknownObjectId), |
| 960 id); | 979 id); |
| 961 CHECK_EQ(static_cast<int>(id), global_object->GetId()); | 980 CHECK_EQ(static_cast<int>(id), global_object->GetId()); |
| 962 } | 981 } |
| 963 | 982 |
| 964 | 983 |
| 965 TEST(HeapSnapshotUnknownSnapshotObjectId) { | 984 TEST(HeapSnapshotUnknownSnapshotObjectId) { |
| 966 LocalContext env; | 985 LocalContext env; |
| 967 v8::HandleScope scope(env->GetIsolate()); | 986 v8::HandleScope scope(env->GetIsolate()); |
| 987 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 968 CompileRun("globalObject = {};\n"); | 988 CompileRun("globalObject = {};\n"); |
| 969 const v8::HeapSnapshot* snapshot = | 989 const v8::HeapSnapshot* snapshot = |
| 970 v8::HeapProfiler::TakeSnapshot(v8_str("unknown_object_id")); | 990 heap_profiler->TakeHeapSnapshot(v8_str("unknown_object_id")); |
| 971 const v8::HeapGraphNode* node = | 991 const v8::HeapGraphNode* node = |
| 972 snapshot->GetNodeById(v8::HeapProfiler::kUnknownObjectId); | 992 snapshot->GetNodeById(v8::HeapProfiler::kUnknownObjectId); |
| 973 CHECK_EQ(NULL, node); | 993 CHECK_EQ(NULL, node); |
| 974 } | 994 } |
| 975 | 995 |
| 976 | 996 |
| 977 namespace { | 997 namespace { |
| 978 | 998 |
| 979 class TestActivityControl : public v8::ActivityControl { | 999 class TestActivityControl : public v8::ActivityControl { |
| 980 public: | 1000 public: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 992 int done_; | 1012 int done_; |
| 993 int total_; | 1013 int total_; |
| 994 int abort_count_; | 1014 int abort_count_; |
| 995 }; | 1015 }; |
| 996 } | 1016 } |
| 997 | 1017 |
| 998 TEST(TakeHeapSnapshotAborting) { | 1018 TEST(TakeHeapSnapshotAborting) { |
| 999 LocalContext env; | 1019 LocalContext env; |
| 1000 v8::HandleScope scope(env->GetIsolate()); | 1020 v8::HandleScope scope(env->GetIsolate()); |
| 1001 | 1021 |
| 1002 const int snapshots_count = v8::HeapProfiler::GetSnapshotsCount(); | 1022 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1023 const int snapshots_count = heap_profiler->GetSnapshotCount(); |
| 1003 TestActivityControl aborting_control(1); | 1024 TestActivityControl aborting_control(1); |
| 1004 const v8::HeapSnapshot* no_snapshot = | 1025 const v8::HeapSnapshot* no_snapshot = |
| 1005 v8::HeapProfiler::TakeSnapshot(v8_str("abort"), | 1026 heap_profiler->TakeHeapSnapshot(v8_str("abort"), |
| 1006 v8::HeapSnapshot::kFull, | |
| 1007 &aborting_control); | 1027 &aborting_control); |
| 1008 CHECK_EQ(NULL, no_snapshot); | 1028 CHECK_EQ(NULL, no_snapshot); |
| 1009 CHECK_EQ(snapshots_count, v8::HeapProfiler::GetSnapshotsCount()); | 1029 CHECK_EQ(snapshots_count, heap_profiler->GetSnapshotCount()); |
| 1010 CHECK_GT(aborting_control.total(), aborting_control.done()); | 1030 CHECK_GT(aborting_control.total(), aborting_control.done()); |
| 1011 | 1031 |
| 1012 TestActivityControl control(-1); // Don't abort. | 1032 TestActivityControl control(-1); // Don't abort. |
| 1013 const v8::HeapSnapshot* snapshot = | 1033 const v8::HeapSnapshot* snapshot = |
| 1014 v8::HeapProfiler::TakeSnapshot(v8_str("full"), | 1034 heap_profiler->TakeHeapSnapshot(v8_str("full"), |
| 1015 v8::HeapSnapshot::kFull, | |
| 1016 &control); | 1035 &control); |
| 1017 CHECK_NE(NULL, snapshot); | 1036 CHECK_NE(NULL, snapshot); |
| 1018 CHECK_EQ(snapshots_count + 1, v8::HeapProfiler::GetSnapshotsCount()); | 1037 CHECK_EQ(snapshots_count + 1, heap_profiler->GetSnapshotCount()); |
| 1019 CHECK_EQ(control.total(), control.done()); | 1038 CHECK_EQ(control.total(), control.done()); |
| 1020 CHECK_GT(control.total(), 0); | 1039 CHECK_GT(control.total(), 0); |
| 1021 } | 1040 } |
| 1022 | 1041 |
| 1023 | 1042 |
| 1024 namespace { | 1043 namespace { |
| 1025 | 1044 |
| 1026 class TestRetainedObjectInfo : public v8::RetainedObjectInfo { | 1045 class TestRetainedObjectInfo : public v8::RetainedObjectInfo { |
| 1027 public: | 1046 public: |
| 1028 TestRetainedObjectInfo(int hash, | 1047 TestRetainedObjectInfo(int hash, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1102 } | 1121 } |
| 1103 } | 1122 } |
| 1104 return NULL; | 1123 return NULL; |
| 1105 } | 1124 } |
| 1106 | 1125 |
| 1107 | 1126 |
| 1108 TEST(HeapSnapshotRetainedObjectInfo) { | 1127 TEST(HeapSnapshotRetainedObjectInfo) { |
| 1109 LocalContext env; | 1128 LocalContext env; |
| 1110 v8::Isolate* isolate = env->GetIsolate(); | 1129 v8::Isolate* isolate = env->GetIsolate(); |
| 1111 v8::HandleScope scope(isolate); | 1130 v8::HandleScope scope(isolate); |
| 1131 v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); |
| 1112 | 1132 |
| 1113 v8::HeapProfiler::DefineWrapperClass( | 1133 heap_profiler->SetWrapperClassInfoProvider( |
| 1114 1, TestRetainedObjectInfo::WrapperInfoCallback); | 1134 1, TestRetainedObjectInfo::WrapperInfoCallback); |
| 1115 v8::HeapProfiler::DefineWrapperClass( | 1135 heap_profiler->SetWrapperClassInfoProvider( |
| 1116 2, TestRetainedObjectInfo::WrapperInfoCallback); | 1136 2, TestRetainedObjectInfo::WrapperInfoCallback); |
| 1117 v8::Persistent<v8::String> p_AAA = | 1137 v8::Persistent<v8::String> p_AAA = |
| 1118 v8::Persistent<v8::String>::New(isolate, v8_str("AAA")); | 1138 v8::Persistent<v8::String>::New(isolate, v8_str("AAA")); |
| 1119 p_AAA.SetWrapperClassId(isolate, 1); | 1139 p_AAA.SetWrapperClassId(isolate, 1); |
| 1120 v8::Persistent<v8::String> p_BBB = | 1140 v8::Persistent<v8::String> p_BBB = |
| 1121 v8::Persistent<v8::String>::New(isolate, v8_str("BBB")); | 1141 v8::Persistent<v8::String>::New(isolate, v8_str("BBB")); |
| 1122 p_BBB.SetWrapperClassId(isolate, 1); | 1142 p_BBB.SetWrapperClassId(isolate, 1); |
| 1123 v8::Persistent<v8::String> p_CCC = | 1143 v8::Persistent<v8::String> p_CCC = |
| 1124 v8::Persistent<v8::String>::New(isolate, v8_str("CCC")); | 1144 v8::Persistent<v8::String>::New(isolate, v8_str("CCC")); |
| 1125 p_CCC.SetWrapperClassId(isolate, 2); | 1145 p_CCC.SetWrapperClassId(isolate, 2); |
| 1126 CHECK_EQ(0, TestRetainedObjectInfo::instances.length()); | 1146 CHECK_EQ(0, TestRetainedObjectInfo::instances.length()); |
| 1127 const v8::HeapSnapshot* snapshot = | 1147 const v8::HeapSnapshot* snapshot = |
| 1128 v8::HeapProfiler::TakeSnapshot(v8_str("retained")); | 1148 heap_profiler->TakeHeapSnapshot(v8_str("retained")); |
| 1129 | 1149 |
| 1130 CHECK_EQ(3, TestRetainedObjectInfo::instances.length()); | 1150 CHECK_EQ(3, TestRetainedObjectInfo::instances.length()); |
| 1131 for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) { | 1151 for (int i = 0; i < TestRetainedObjectInfo::instances.length(); ++i) { |
| 1132 CHECK(TestRetainedObjectInfo::instances[i]->disposed()); | 1152 CHECK(TestRetainedObjectInfo::instances[i]->disposed()); |
| 1133 delete TestRetainedObjectInfo::instances[i]; | 1153 delete TestRetainedObjectInfo::instances[i]; |
| 1134 } | 1154 } |
| 1135 | 1155 |
| 1136 const v8::HeapGraphNode* native_group_aaa = GetNode( | 1156 const v8::HeapGraphNode* native_group_aaa = GetNode( |
| 1137 snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "aaa-group"); | 1157 snapshot->GetRoot(), v8::HeapGraphNode::kSynthetic, "aaa-group"); |
| 1138 CHECK_NE(NULL, native_group_aaa); | 1158 CHECK_NE(NULL, native_group_aaa); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1198 v8::Persistent<v8::Value> objects_[kObjectsCount]; | 1218 v8::Persistent<v8::Value> objects_[kObjectsCount]; |
| 1199 static GraphWithImplicitRefs* instance_; | 1219 static GraphWithImplicitRefs* instance_; |
| 1200 }; | 1220 }; |
| 1201 | 1221 |
| 1202 GraphWithImplicitRefs* GraphWithImplicitRefs::instance_ = NULL; | 1222 GraphWithImplicitRefs* GraphWithImplicitRefs::instance_ = NULL; |
| 1203 | 1223 |
| 1204 | 1224 |
| 1205 TEST(HeapSnapshotImplicitReferences) { | 1225 TEST(HeapSnapshotImplicitReferences) { |
| 1206 LocalContext env; | 1226 LocalContext env; |
| 1207 v8::HandleScope scope(env->GetIsolate()); | 1227 v8::HandleScope scope(env->GetIsolate()); |
| 1228 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1208 | 1229 |
| 1209 GraphWithImplicitRefs graph(&env); | 1230 GraphWithImplicitRefs graph(&env); |
| 1210 v8::V8::AddGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); | 1231 v8::V8::AddGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); |
| 1211 | 1232 |
| 1212 const v8::HeapSnapshot* snapshot = | 1233 const v8::HeapSnapshot* snapshot = |
| 1213 v8::HeapProfiler::TakeSnapshot(v8_str("implicit_refs")); | 1234 heap_profiler->TakeHeapSnapshot(v8_str("implicit_refs")); |
| 1214 | 1235 |
| 1215 const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot); | 1236 const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot); |
| 1216 const v8::HeapGraphNode* obj0 = GetProperty( | 1237 const v8::HeapGraphNode* obj0 = GetProperty( |
| 1217 global_object, v8::HeapGraphEdge::kProperty, "root_object"); | 1238 global_object, v8::HeapGraphEdge::kProperty, "root_object"); |
| 1218 CHECK(obj0); | 1239 CHECK(obj0); |
| 1219 CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType()); | 1240 CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType()); |
| 1220 const v8::HeapGraphNode* obj1 = GetProperty( | 1241 const v8::HeapGraphNode* obj1 = GetProperty( |
| 1221 obj0, v8::HeapGraphEdge::kInternal, "native"); | 1242 obj0, v8::HeapGraphEdge::kInternal, "native"); |
| 1222 CHECK(obj1); | 1243 CHECK(obj1); |
| 1223 int implicit_targets_count = 0; | 1244 int implicit_targets_count = 0; |
| 1224 for (int i = 0, count = obj1->GetChildrenCount(); i < count; ++i) { | 1245 for (int i = 0, count = obj1->GetChildrenCount(); i < count; ++i) { |
| 1225 const v8::HeapGraphEdge* prop = obj1->GetChild(i); | 1246 const v8::HeapGraphEdge* prop = obj1->GetChild(i); |
| 1226 v8::String::AsciiValue prop_name(prop->GetName()); | 1247 v8::String::AsciiValue prop_name(prop->GetName()); |
| 1227 if (prop->GetType() == v8::HeapGraphEdge::kInternal && | 1248 if (prop->GetType() == v8::HeapGraphEdge::kInternal && |
| 1228 strcmp("native", *prop_name) == 0) { | 1249 strcmp("native", *prop_name) == 0) { |
| 1229 ++implicit_targets_count; | 1250 ++implicit_targets_count; |
| 1230 } | 1251 } |
| 1231 } | 1252 } |
| 1232 CHECK_EQ(2, implicit_targets_count); | 1253 CHECK_EQ(2, implicit_targets_count); |
| 1233 v8::V8::RemoveGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); | 1254 v8::V8::RemoveGCPrologueCallback(&GraphWithImplicitRefs::gcPrologue); |
| 1234 } | 1255 } |
| 1235 | 1256 |
| 1236 | 1257 |
| 1237 TEST(DeleteAllHeapSnapshots) { | 1258 TEST(DeleteAllHeapSnapshots) { |
| 1238 LocalContext env; | 1259 LocalContext env; |
| 1239 v8::HandleScope scope(env->GetIsolate()); | 1260 v8::HandleScope scope(env->GetIsolate()); |
| 1261 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1240 | 1262 |
| 1241 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 1263 CHECK_EQ(0, heap_profiler->GetSnapshotCount()); |
| 1242 v8::HeapProfiler::DeleteAllSnapshots(); | 1264 heap_profiler->DeleteAllHeapSnapshots(); |
| 1243 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 1265 CHECK_EQ(0, heap_profiler->GetSnapshotCount()); |
| 1244 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("1"))); | 1266 CHECK_NE(NULL, heap_profiler->TakeHeapSnapshot(v8_str("1"))); |
| 1245 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 1267 CHECK_EQ(1, heap_profiler->GetSnapshotCount()); |
| 1246 v8::HeapProfiler::DeleteAllSnapshots(); | 1268 heap_profiler->DeleteAllHeapSnapshots(); |
| 1247 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 1269 CHECK_EQ(0, heap_profiler->GetSnapshotCount()); |
| 1248 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("1"))); | 1270 CHECK_NE(NULL, heap_profiler->TakeHeapSnapshot(v8_str("1"))); |
| 1249 CHECK_NE(NULL, v8::HeapProfiler::TakeSnapshot(v8_str("2"))); | 1271 CHECK_NE(NULL, heap_profiler->TakeHeapSnapshot(v8_str("2"))); |
| 1250 CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); | 1272 CHECK_EQ(2, heap_profiler->GetSnapshotCount()); |
| 1251 v8::HeapProfiler::DeleteAllSnapshots(); | 1273 heap_profiler->DeleteAllHeapSnapshots(); |
| 1252 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 1274 CHECK_EQ(0, heap_profiler->GetSnapshotCount()); |
| 1253 } | 1275 } |
| 1254 | 1276 |
| 1255 | 1277 |
| 1256 TEST(DeleteHeapSnapshot) { | 1278 TEST(DeleteHeapSnapshot) { |
| 1257 LocalContext env; | 1279 LocalContext env; |
| 1258 v8::HandleScope scope(env->GetIsolate()); | 1280 v8::HandleScope scope(env->GetIsolate()); |
| 1281 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1259 | 1282 |
| 1260 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 1283 CHECK_EQ(0, heap_profiler->GetSnapshotCount()); |
| 1261 const v8::HeapSnapshot* s1 = | 1284 const v8::HeapSnapshot* s1 = |
| 1262 v8::HeapProfiler::TakeSnapshot(v8_str("1")); | 1285 heap_profiler->TakeHeapSnapshot(v8_str("1")); |
| 1263 CHECK_NE(NULL, s1); | 1286 CHECK_NE(NULL, s1); |
| 1264 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 1287 CHECK_EQ(1, heap_profiler->GetSnapshotCount()); |
| 1265 unsigned uid1 = s1->GetUid(); | 1288 unsigned uid1 = s1->GetUid(); |
| 1266 CHECK_EQ(s1, v8::HeapProfiler::FindSnapshot(uid1)); | 1289 CHECK_EQ(s1, heap_profiler->FindHeapSnapshot(uid1)); |
| 1267 const_cast<v8::HeapSnapshot*>(s1)->Delete(); | 1290 const_cast<v8::HeapSnapshot*>(s1)->Delete(); |
| 1268 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 1291 CHECK_EQ(0, heap_profiler->GetSnapshotCount()); |
| 1269 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid1)); | 1292 CHECK_EQ(NULL, heap_profiler->FindHeapSnapshot(uid1)); |
| 1270 | 1293 |
| 1271 const v8::HeapSnapshot* s2 = | 1294 const v8::HeapSnapshot* s2 = |
| 1272 v8::HeapProfiler::TakeSnapshot(v8_str("2")); | 1295 heap_profiler->TakeHeapSnapshot(v8_str("2")); |
| 1273 CHECK_NE(NULL, s2); | 1296 CHECK_NE(NULL, s2); |
| 1274 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 1297 CHECK_EQ(1, heap_profiler->GetSnapshotCount()); |
| 1275 unsigned uid2 = s2->GetUid(); | 1298 unsigned uid2 = s2->GetUid(); |
| 1276 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2)); | 1299 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid2)); |
| 1277 CHECK_EQ(s2, v8::HeapProfiler::FindSnapshot(uid2)); | 1300 CHECK_EQ(s2, heap_profiler->FindHeapSnapshot(uid2)); |
| 1278 const v8::HeapSnapshot* s3 = | 1301 const v8::HeapSnapshot* s3 = |
| 1279 v8::HeapProfiler::TakeSnapshot(v8_str("3")); | 1302 heap_profiler->TakeHeapSnapshot(v8_str("3")); |
| 1280 CHECK_NE(NULL, s3); | 1303 CHECK_NE(NULL, s3); |
| 1281 CHECK_EQ(2, v8::HeapProfiler::GetSnapshotsCount()); | 1304 CHECK_EQ(2, heap_profiler->GetSnapshotCount()); |
| 1282 unsigned uid3 = s3->GetUid(); | 1305 unsigned uid3 = s3->GetUid(); |
| 1283 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3)); | 1306 CHECK_NE(static_cast<int>(uid1), static_cast<int>(uid3)); |
| 1284 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); | 1307 CHECK_EQ(s3, heap_profiler->FindHeapSnapshot(uid3)); |
| 1285 const_cast<v8::HeapSnapshot*>(s2)->Delete(); | 1308 const_cast<v8::HeapSnapshot*>(s2)->Delete(); |
| 1286 CHECK_EQ(1, v8::HeapProfiler::GetSnapshotsCount()); | 1309 CHECK_EQ(1, heap_profiler->GetSnapshotCount()); |
| 1287 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid2)); | 1310 CHECK_EQ(NULL, heap_profiler->FindHeapSnapshot(uid2)); |
| 1288 CHECK_EQ(s3, v8::HeapProfiler::FindSnapshot(uid3)); | 1311 CHECK_EQ(s3, heap_profiler->FindHeapSnapshot(uid3)); |
| 1289 const_cast<v8::HeapSnapshot*>(s3)->Delete(); | 1312 const_cast<v8::HeapSnapshot*>(s3)->Delete(); |
| 1290 CHECK_EQ(0, v8::HeapProfiler::GetSnapshotsCount()); | 1313 CHECK_EQ(0, heap_profiler->GetSnapshotCount()); |
| 1291 CHECK_EQ(NULL, v8::HeapProfiler::FindSnapshot(uid3)); | 1314 CHECK_EQ(NULL, heap_profiler->FindHeapSnapshot(uid3)); |
| 1292 } | 1315 } |
| 1293 | 1316 |
| 1294 | 1317 |
| 1295 class NameResolver : public v8::HeapProfiler::ObjectNameResolver { | 1318 class NameResolver : public v8::HeapProfiler::ObjectNameResolver { |
| 1296 public: | 1319 public: |
| 1297 virtual const char* GetName(v8::Handle<v8::Object> object) { | 1320 virtual const char* GetName(v8::Handle<v8::Object> object) { |
| 1298 return "Global object name"; | 1321 return "Global object name"; |
| 1299 } | 1322 } |
| 1300 }; | 1323 }; |
| 1301 | 1324 |
| 1302 TEST(GlobalObjectName) { | 1325 TEST(GlobalObjectName) { |
| 1303 LocalContext env; | 1326 LocalContext env; |
| 1304 v8::HandleScope scope(env->GetIsolate()); | 1327 v8::HandleScope scope(env->GetIsolate()); |
| 1328 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1305 | 1329 |
| 1306 CompileRun("document = { URL:\"abcdefgh\" };"); | 1330 CompileRun("document = { URL:\"abcdefgh\" };"); |
| 1307 | 1331 |
| 1308 NameResolver name_resolver; | 1332 NameResolver name_resolver; |
| 1309 const v8::HeapSnapshot* snapshot = | 1333 const v8::HeapSnapshot* snapshot = |
| 1310 v8::HeapProfiler::TakeSnapshot(v8_str("document"), | 1334 heap_profiler->TakeHeapSnapshot(v8_str("document"), |
| 1311 v8::HeapSnapshot::kFull, | |
| 1312 NULL, | 1335 NULL, |
| 1313 &name_resolver); | 1336 &name_resolver); |
| 1314 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1337 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1315 CHECK_NE(NULL, global); | 1338 CHECK_NE(NULL, global); |
| 1316 CHECK_EQ("Object / Global object name" , | 1339 CHECK_EQ("Object / Global object name" , |
| 1317 const_cast<i::HeapEntry*>( | 1340 const_cast<i::HeapEntry*>( |
| 1318 reinterpret_cast<const i::HeapEntry*>(global))->name()); | 1341 reinterpret_cast<const i::HeapEntry*>(global))->name()); |
| 1319 } | 1342 } |
| 1320 | 1343 |
| 1321 | 1344 |
| 1322 TEST(NoHandleLeaks) { | 1345 TEST(NoHandleLeaks) { |
| 1323 LocalContext env; | 1346 LocalContext env; |
| 1324 v8::HandleScope scope(env->GetIsolate()); | 1347 v8::HandleScope scope(env->GetIsolate()); |
| 1348 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1325 | 1349 |
| 1326 CompileRun("document = { URL:\"abcdefgh\" };"); | 1350 CompileRun("document = { URL:\"abcdefgh\" };"); |
| 1327 | 1351 |
| 1328 v8::Handle<v8::String> name(v8_str("leakz")); | 1352 v8::Handle<v8::String> name(v8_str("leakz")); |
| 1329 i::Isolate* isolate = i::Isolate::Current(); | 1353 i::Isolate* isolate = i::Isolate::Current(); |
| 1330 int count_before = i::HandleScope::NumberOfHandles(isolate); | 1354 int count_before = i::HandleScope::NumberOfHandles(isolate); |
| 1331 v8::HeapProfiler::TakeSnapshot(name); | 1355 heap_profiler->TakeHeapSnapshot(name); |
| 1332 int count_after = i::HandleScope::NumberOfHandles(isolate); | 1356 int count_after = i::HandleScope::NumberOfHandles(isolate); |
| 1333 CHECK_EQ(count_before, count_after); | 1357 CHECK_EQ(count_before, count_after); |
| 1334 } | 1358 } |
| 1335 | 1359 |
| 1336 | 1360 |
| 1337 TEST(NodesIteration) { | 1361 TEST(NodesIteration) { |
| 1338 LocalContext env; | 1362 LocalContext env; |
| 1339 v8::HandleScope scope(env->GetIsolate()); | 1363 v8::HandleScope scope(env->GetIsolate()); |
| 1364 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1340 const v8::HeapSnapshot* snapshot = | 1365 const v8::HeapSnapshot* snapshot = |
| 1341 v8::HeapProfiler::TakeSnapshot(v8_str("iteration")); | 1366 heap_profiler->TakeHeapSnapshot(v8_str("iteration")); |
| 1342 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1367 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1343 CHECK_NE(NULL, global); | 1368 CHECK_NE(NULL, global); |
| 1344 // Verify that we can find this object by iteration. | 1369 // Verify that we can find this object by iteration. |
| 1345 const int nodes_count = snapshot->GetNodesCount(); | 1370 const int nodes_count = snapshot->GetNodesCount(); |
| 1346 int count = 0; | 1371 int count = 0; |
| 1347 for (int i = 0; i < nodes_count; ++i) { | 1372 for (int i = 0; i < nodes_count; ++i) { |
| 1348 if (snapshot->GetNode(i) == global) | 1373 if (snapshot->GetNode(i) == global) |
| 1349 ++count; | 1374 ++count; |
| 1350 } | 1375 } |
| 1351 CHECK_EQ(1, count); | 1376 CHECK_EQ(1, count); |
| 1352 } | 1377 } |
| 1353 | 1378 |
| 1354 | 1379 |
| 1355 TEST(GetHeapValue) { | 1380 TEST(GetHeapValue) { |
| 1356 LocalContext env; | 1381 LocalContext env; |
| 1357 v8::HandleScope scope(env->GetIsolate()); | 1382 v8::HandleScope scope(env->GetIsolate()); |
| 1383 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1358 | 1384 |
| 1359 CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); | 1385 CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); |
| 1360 const v8::HeapSnapshot* snapshot = | 1386 const v8::HeapSnapshot* snapshot = |
| 1361 v8::HeapProfiler::TakeSnapshot(v8_str("value")); | 1387 heap_profiler->TakeHeapSnapshot(v8_str("value")); |
| 1362 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1388 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1363 CHECK(global->GetHeapValue()->IsObject()); | 1389 CHECK(global->GetHeapValue()->IsObject()); |
| 1364 v8::Local<v8::Object> js_global = | 1390 v8::Local<v8::Object> js_global = |
| 1365 env->Global()->GetPrototype().As<v8::Object>(); | 1391 env->Global()->GetPrototype().As<v8::Object>(); |
| 1366 CHECK(js_global == global->GetHeapValue()); | 1392 CHECK(js_global == global->GetHeapValue()); |
| 1367 const v8::HeapGraphNode* obj = GetProperty( | 1393 const v8::HeapGraphNode* obj = GetProperty( |
| 1368 global, v8::HeapGraphEdge::kProperty, "a"); | 1394 global, v8::HeapGraphEdge::kProperty, "a"); |
| 1369 CHECK(obj->GetHeapValue()->IsObject()); | 1395 CHECK(obj->GetHeapValue()->IsObject()); |
| 1370 v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); | 1396 v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); |
| 1371 CHECK(js_obj == obj->GetHeapValue()); | 1397 CHECK(js_obj == obj->GetHeapValue()); |
| 1372 const v8::HeapGraphNode* s_prop = | 1398 const v8::HeapGraphNode* s_prop = |
| 1373 GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); | 1399 GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); |
| 1374 v8::Local<v8::String> js_s_prop = | 1400 v8::Local<v8::String> js_s_prop = |
| 1375 js_obj->Get(v8_str("s_prop")).As<v8::String>(); | 1401 js_obj->Get(v8_str("s_prop")).As<v8::String>(); |
| 1376 CHECK(js_s_prop == s_prop->GetHeapValue()); | 1402 CHECK(js_s_prop == s_prop->GetHeapValue()); |
| 1377 const v8::HeapGraphNode* n_prop = | 1403 const v8::HeapGraphNode* n_prop = |
| 1378 GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); | 1404 GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); |
| 1379 v8::Local<v8::Number> js_n_prop = | 1405 v8::Local<v8::Number> js_n_prop = |
| 1380 js_obj->Get(v8_str("n_prop")).As<v8::Number>(); | 1406 js_obj->Get(v8_str("n_prop")).As<v8::Number>(); |
| 1381 CHECK(js_n_prop == n_prop->GetHeapValue()); | 1407 CHECK(js_n_prop == n_prop->GetHeapValue()); |
| 1382 } | 1408 } |
| 1383 | 1409 |
| 1384 | 1410 |
| 1385 TEST(GetHeapValueForDeletedObject) { | 1411 TEST(GetHeapValueForDeletedObject) { |
| 1386 LocalContext env; | 1412 LocalContext env; |
| 1387 v8::HandleScope scope(env->GetIsolate()); | 1413 v8::HandleScope scope(env->GetIsolate()); |
| 1414 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1388 | 1415 |
| 1389 // It is impossible to delete a global property, so we are about to delete a | 1416 // It is impossible to delete a global property, so we are about to delete a |
| 1390 // property of the "a" object. Also, the "p" object can't be an empty one | 1417 // property of the "a" object. Also, the "p" object can't be an empty one |
| 1391 // because the empty object is static and isn't actually deleted. | 1418 // because the empty object is static and isn't actually deleted. |
| 1392 CompileRun("a = { p: { r: {} } };"); | 1419 CompileRun("a = { p: { r: {} } };"); |
| 1393 const v8::HeapSnapshot* snapshot = | 1420 const v8::HeapSnapshot* snapshot = |
| 1394 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); | 1421 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1395 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1422 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1396 const v8::HeapGraphNode* obj = GetProperty( | 1423 const v8::HeapGraphNode* obj = GetProperty( |
| 1397 global, v8::HeapGraphEdge::kProperty, "a"); | 1424 global, v8::HeapGraphEdge::kProperty, "a"); |
| 1398 const v8::HeapGraphNode* prop = GetProperty( | 1425 const v8::HeapGraphNode* prop = GetProperty( |
| 1399 obj, v8::HeapGraphEdge::kProperty, "p"); | 1426 obj, v8::HeapGraphEdge::kProperty, "p"); |
| 1400 { | 1427 { |
| 1401 // Perform the check inside a nested local scope to avoid creating a | 1428 // Perform the check inside a nested local scope to avoid creating a |
| 1402 // reference to the object we are deleting. | 1429 // reference to the object we are deleting. |
| 1403 v8::HandleScope scope(env->GetIsolate()); | 1430 v8::HandleScope scope(env->GetIsolate()); |
| 1404 CHECK(prop->GetHeapValue()->IsObject()); | 1431 CHECK(prop->GetHeapValue()->IsObject()); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1460 v8::Local<v8::Object> obj6 = js_global->Get(v8_str("obj6")).As<v8::Object>(); | 1487 v8::Local<v8::Object> obj6 = js_global->Get(v8_str("obj6")).As<v8::Object>(); |
| 1461 i::Handle<i::JSObject> js_obj6 = v8::Utils::OpenHandle(*obj6); | 1488 i::Handle<i::JSObject> js_obj6 = v8::Utils::OpenHandle(*obj6); |
| 1462 CHECK_EQ(0, StringCmp( | 1489 CHECK_EQ(0, StringCmp( |
| 1463 "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); | 1490 "Object", i::V8HeapExplorer::GetConstructorName(*js_obj6))); |
| 1464 } | 1491 } |
| 1465 | 1492 |
| 1466 | 1493 |
| 1467 TEST(FastCaseGetter) { | 1494 TEST(FastCaseGetter) { |
| 1468 LocalContext env; | 1495 LocalContext env; |
| 1469 v8::HandleScope scope(env->GetIsolate()); | 1496 v8::HandleScope scope(env->GetIsolate()); |
| 1497 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1470 | 1498 |
| 1471 CompileRun("var obj1 = {};\n" | 1499 CompileRun("var obj1 = {};\n" |
| 1472 "obj1.__defineGetter__('propWithGetter', function Y() {\n" | 1500 "obj1.__defineGetter__('propWithGetter', function Y() {\n" |
| 1473 " return 42;\n" | 1501 " return 42;\n" |
| 1474 "});\n" | 1502 "});\n" |
| 1475 "obj1.__defineSetter__('propWithSetter', function Z(value) {\n" | 1503 "obj1.__defineSetter__('propWithSetter', function Z(value) {\n" |
| 1476 " return this.value_ = value;\n" | 1504 " return this.value_ = value;\n" |
| 1477 "});\n"); | 1505 "});\n"); |
| 1478 const v8::HeapSnapshot* snapshot = | 1506 const v8::HeapSnapshot* snapshot = |
| 1479 v8::HeapProfiler::TakeSnapshot(v8_str("fastCaseGetter")); | 1507 heap_profiler->TakeHeapSnapshot(v8_str("fastCaseGetter")); |
| 1480 | 1508 |
| 1481 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1509 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1482 CHECK_NE(NULL, global); | 1510 CHECK_NE(NULL, global); |
| 1483 const v8::HeapGraphNode* obj1 = | 1511 const v8::HeapGraphNode* obj1 = |
| 1484 GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1"); | 1512 GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1"); |
| 1485 CHECK_NE(NULL, obj1); | 1513 CHECK_NE(NULL, obj1); |
| 1486 const v8::HeapGraphNode* getterFunction = | 1514 const v8::HeapGraphNode* getterFunction = |
| 1487 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); | 1515 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); |
| 1488 CHECK_NE(NULL, getterFunction); | 1516 CHECK_NE(NULL, getterFunction); |
| 1489 const v8::HeapGraphNode* setterFunction = | 1517 const v8::HeapGraphNode* setterFunction = |
| 1490 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter"); | 1518 GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set-propWithSetter"); |
| 1491 CHECK_NE(NULL, setterFunction); | 1519 CHECK_NE(NULL, setterFunction); |
| 1492 } | 1520 } |
| 1493 | 1521 |
| 1494 TEST(HiddenPropertiesFastCase) { | 1522 TEST(HiddenPropertiesFastCase) { |
| 1495 LocalContext env; | 1523 LocalContext env; |
| 1496 v8::HandleScope scope(env->GetIsolate()); | 1524 v8::HandleScope scope(env->GetIsolate()); |
| 1525 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1497 | 1526 |
| 1498 CompileRun( | 1527 CompileRun( |
| 1499 "function C(x) { this.a = this; this.b = x; }\n" | 1528 "function C(x) { this.a = this; this.b = x; }\n" |
| 1500 "c = new C(2012);\n"); | 1529 "c = new C(2012);\n"); |
| 1501 const v8::HeapSnapshot* snapshot = | 1530 const v8::HeapSnapshot* snapshot = |
| 1502 v8::HeapProfiler::TakeSnapshot(v8_str("HiddenPropertiesFastCase1")); | 1531 heap_profiler->TakeHeapSnapshot(v8_str("HiddenPropertiesFastCase1")); |
| 1503 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1532 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1504 const v8::HeapGraphNode* c = | 1533 const v8::HeapGraphNode* c = |
| 1505 GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); | 1534 GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); |
| 1506 CHECK_NE(NULL, c); | 1535 CHECK_NE(NULL, c); |
| 1507 const v8::HeapGraphNode* hidden_props = | 1536 const v8::HeapGraphNode* hidden_props = |
| 1508 GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties"); | 1537 GetProperty(c, v8::HeapGraphEdge::kInternal, "hidden_properties"); |
| 1509 CHECK_EQ(NULL, hidden_props); | 1538 CHECK_EQ(NULL, hidden_props); |
| 1510 | 1539 |
| 1511 v8::Handle<v8::Value> cHandle = env->Global()->Get(v8::String::New("c")); | 1540 v8::Handle<v8::Value> cHandle = env->Global()->Get(v8::String::New("c")); |
| 1512 CHECK(!cHandle.IsEmpty() && cHandle->IsObject()); | 1541 CHECK(!cHandle.IsEmpty() && cHandle->IsObject()); |
| 1513 cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val")); | 1542 cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val")); |
| 1514 | 1543 |
| 1515 snapshot = v8::HeapProfiler::TakeSnapshot( | 1544 snapshot = heap_profiler->TakeHeapSnapshot( |
| 1516 v8_str("HiddenPropertiesFastCase2")); | 1545 v8_str("HiddenPropertiesFastCase2")); |
| 1517 global = GetGlobalObject(snapshot); | 1546 global = GetGlobalObject(snapshot); |
| 1518 c = GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); | 1547 c = GetProperty(global, v8::HeapGraphEdge::kProperty, "c"); |
| 1519 CHECK_NE(NULL, c); | 1548 CHECK_NE(NULL, c); |
| 1520 hidden_props = GetProperty(c, v8::HeapGraphEdge::kInternal, | 1549 hidden_props = GetProperty(c, v8::HeapGraphEdge::kInternal, |
| 1521 "hidden_properties"); | 1550 "hidden_properties"); |
| 1522 CHECK_NE(NULL, hidden_props); | 1551 CHECK_NE(NULL, hidden_props); |
| 1523 } | 1552 } |
| 1524 | 1553 |
| 1525 bool HasWeakEdge(const v8::HeapGraphNode* node) { | 1554 bool HasWeakEdge(const v8::HeapGraphNode* node) { |
| 1526 for (int i = 0; i < node->GetChildrenCount(); ++i) { | 1555 for (int i = 0; i < node->GetChildrenCount(); ++i) { |
| 1527 const v8::HeapGraphEdge* handle_edge = node->GetChild(i); | 1556 const v8::HeapGraphEdge* handle_edge = node->GetChild(i); |
| 1528 if (handle_edge->GetType() == v8::HeapGraphEdge::kWeak) return true; | 1557 if (handle_edge->GetType() == v8::HeapGraphEdge::kWeak) return true; |
| 1529 } | 1558 } |
| 1530 return false; | 1559 return false; |
| 1531 } | 1560 } |
| 1532 | 1561 |
| 1533 | 1562 |
| 1534 bool HasWeakGlobalHandle() { | 1563 bool HasWeakGlobalHandle() { |
| 1564 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 1565 v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler(); |
| 1535 const v8::HeapSnapshot* snapshot = | 1566 const v8::HeapSnapshot* snapshot = |
| 1536 v8::HeapProfiler::TakeSnapshot(v8_str("weaks")); | 1567 heap_profiler->TakeHeapSnapshot(v8_str("weaks")); |
| 1537 const v8::HeapGraphNode* gc_roots = GetNode( | 1568 const v8::HeapGraphNode* gc_roots = GetNode( |
| 1538 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); | 1569 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); |
| 1539 CHECK_NE(NULL, gc_roots); | 1570 CHECK_NE(NULL, gc_roots); |
| 1540 const v8::HeapGraphNode* global_handles = GetNode( | 1571 const v8::HeapGraphNode* global_handles = GetNode( |
| 1541 gc_roots, v8::HeapGraphNode::kObject, "(Global handles)"); | 1572 gc_roots, v8::HeapGraphNode::kObject, "(Global handles)"); |
| 1542 CHECK_NE(NULL, global_handles); | 1573 CHECK_NE(NULL, global_handles); |
| 1543 return HasWeakEdge(global_handles); | 1574 return HasWeakEdge(global_handles); |
| 1544 } | 1575 } |
| 1545 | 1576 |
| 1546 | 1577 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1561 v8::Persistent<v8::Object>::New(env->GetIsolate(), v8::Object::New()); | 1592 v8::Persistent<v8::Object>::New(env->GetIsolate(), v8::Object::New()); |
| 1562 handle.MakeWeak(env->GetIsolate(), NULL, PersistentHandleCallback); | 1593 handle.MakeWeak(env->GetIsolate(), NULL, PersistentHandleCallback); |
| 1563 | 1594 |
| 1564 CHECK(HasWeakGlobalHandle()); | 1595 CHECK(HasWeakGlobalHandle()); |
| 1565 } | 1596 } |
| 1566 | 1597 |
| 1567 | 1598 |
| 1568 TEST(WeakNativeContextRefs) { | 1599 TEST(WeakNativeContextRefs) { |
| 1569 LocalContext env; | 1600 LocalContext env; |
| 1570 v8::HandleScope scope(env->GetIsolate()); | 1601 v8::HandleScope scope(env->GetIsolate()); |
| 1602 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1571 | 1603 |
| 1572 const v8::HeapSnapshot* snapshot = | 1604 const v8::HeapSnapshot* snapshot = |
| 1573 v8::HeapProfiler::TakeSnapshot(v8_str("weaks")); | 1605 heap_profiler->TakeHeapSnapshot(v8_str("weaks")); |
| 1574 const v8::HeapGraphNode* gc_roots = GetNode( | 1606 const v8::HeapGraphNode* gc_roots = GetNode( |
| 1575 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); | 1607 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); |
| 1576 CHECK_NE(NULL, gc_roots); | 1608 CHECK_NE(NULL, gc_roots); |
| 1577 const v8::HeapGraphNode* global_handles = GetNode( | 1609 const v8::HeapGraphNode* global_handles = GetNode( |
| 1578 gc_roots, v8::HeapGraphNode::kObject, "(Global handles)"); | 1610 gc_roots, v8::HeapGraphNode::kObject, "(Global handles)"); |
| 1579 CHECK_NE(NULL, global_handles); | 1611 CHECK_NE(NULL, global_handles); |
| 1580 const v8::HeapGraphNode* native_context = GetNode( | 1612 const v8::HeapGraphNode* native_context = GetNode( |
| 1581 global_handles, v8::HeapGraphNode::kHidden, "system / NativeContext"); | 1613 global_handles, v8::HeapGraphNode::kHidden, "system / NativeContext"); |
| 1582 CHECK_NE(NULL, native_context); | 1614 CHECK_NE(NULL, native_context); |
| 1583 CHECK(HasWeakEdge(native_context)); | 1615 CHECK(HasWeakEdge(native_context)); |
| 1584 } | 1616 } |
| 1585 | 1617 |
| 1586 | 1618 |
| 1587 TEST(SfiAndJsFunctionWeakRefs) { | 1619 TEST(SfiAndJsFunctionWeakRefs) { |
| 1588 LocalContext env; | 1620 LocalContext env; |
| 1589 v8::HandleScope scope(env->GetIsolate()); | 1621 v8::HandleScope scope(env->GetIsolate()); |
| 1622 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1590 | 1623 |
| 1591 CompileRun( | 1624 CompileRun( |
| 1592 "fun = (function (x) { return function () { return x + 1; } })(1);"); | 1625 "fun = (function (x) { return function () { return x + 1; } })(1);"); |
| 1593 const v8::HeapSnapshot* snapshot = | 1626 const v8::HeapSnapshot* snapshot = |
| 1594 v8::HeapProfiler::TakeSnapshot(v8_str("fun")); | 1627 heap_profiler->TakeHeapSnapshot(v8_str("fun")); |
| 1595 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1628 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1596 CHECK_NE(NULL, global); | 1629 CHECK_NE(NULL, global); |
| 1597 const v8::HeapGraphNode* fun = | 1630 const v8::HeapGraphNode* fun = |
| 1598 GetProperty(global, v8::HeapGraphEdge::kProperty, "fun"); | 1631 GetProperty(global, v8::HeapGraphEdge::kProperty, "fun"); |
| 1599 CHECK(HasWeakEdge(fun)); | 1632 CHECK(HasWeakEdge(fun)); |
| 1600 const v8::HeapGraphNode* shared = | 1633 const v8::HeapGraphNode* shared = |
| 1601 GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); | 1634 GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); |
| 1602 CHECK(HasWeakEdge(shared)); | 1635 CHECK(HasWeakEdge(shared)); |
| 1603 } | 1636 } |
| 1604 | 1637 |
| 1605 | 1638 |
| 1606 #ifdef ENABLE_DEBUGGER_SUPPORT | 1639 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1607 TEST(NoDebugObjectInSnapshot) { | 1640 TEST(NoDebugObjectInSnapshot) { |
| 1608 LocalContext env; | 1641 LocalContext env; |
| 1609 v8::HandleScope scope(env->GetIsolate()); | 1642 v8::HandleScope scope(env->GetIsolate()); |
| 1643 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1610 | 1644 |
| 1611 v8::internal::Isolate::Current()->debug()->Load(); | 1645 v8::internal::Isolate::Current()->debug()->Load(); |
| 1612 CompileRun("foo = {};"); | 1646 CompileRun("foo = {};"); |
| 1613 const v8::HeapSnapshot* snapshot = | 1647 const v8::HeapSnapshot* snapshot = |
| 1614 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); | 1648 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1615 const v8::HeapGraphNode* root = snapshot->GetRoot(); | 1649 const v8::HeapGraphNode* root = snapshot->GetRoot(); |
| 1616 int globals_count = 0; | 1650 int globals_count = 0; |
| 1617 for (int i = 0; i < root->GetChildrenCount(); ++i) { | 1651 for (int i = 0; i < root->GetChildrenCount(); ++i) { |
| 1618 const v8::HeapGraphEdge* edge = root->GetChild(i); | 1652 const v8::HeapGraphEdge* edge = root->GetChild(i); |
| 1619 if (edge->GetType() == v8::HeapGraphEdge::kShortcut) { | 1653 if (edge->GetType() == v8::HeapGraphEdge::kShortcut) { |
| 1620 ++globals_count; | 1654 ++globals_count; |
| 1621 const v8::HeapGraphNode* global = edge->GetToNode(); | 1655 const v8::HeapGraphNode* global = edge->GetToNode(); |
| 1622 const v8::HeapGraphNode* foo = | 1656 const v8::HeapGraphNode* foo = |
| 1623 GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); | 1657 GetProperty(global, v8::HeapGraphEdge::kProperty, "foo"); |
| 1624 CHECK_NE(NULL, foo); | 1658 CHECK_NE(NULL, foo); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1660 CHECK_EQ(global_handle_count + 1, | 1694 CHECK_EQ(global_handle_count + 1, |
| 1661 v8::HeapProfiler::GetPersistentHandleCount()); | 1695 v8::HeapProfiler::GetPersistentHandleCount()); |
| 1662 p_BBB.Dispose(env->GetIsolate()); | 1696 p_BBB.Dispose(env->GetIsolate()); |
| 1663 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); | 1697 CHECK_EQ(global_handle_count, v8::HeapProfiler::GetPersistentHandleCount()); |
| 1664 } | 1698 } |
| 1665 | 1699 |
| 1666 | 1700 |
| 1667 TEST(AllStrongGcRootsHaveNames) { | 1701 TEST(AllStrongGcRootsHaveNames) { |
| 1668 LocalContext env; | 1702 LocalContext env; |
| 1669 v8::HandleScope scope(env->GetIsolate()); | 1703 v8::HandleScope scope(env->GetIsolate()); |
| 1704 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1670 | 1705 |
| 1671 CompileRun("foo = {};"); | 1706 CompileRun("foo = {};"); |
| 1672 const v8::HeapSnapshot* snapshot = | 1707 const v8::HeapSnapshot* snapshot = |
| 1673 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); | 1708 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1674 const v8::HeapGraphNode* gc_roots = GetNode( | 1709 const v8::HeapGraphNode* gc_roots = GetNode( |
| 1675 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); | 1710 snapshot->GetRoot(), v8::HeapGraphNode::kObject, "(GC roots)"); |
| 1676 CHECK_NE(NULL, gc_roots); | 1711 CHECK_NE(NULL, gc_roots); |
| 1677 const v8::HeapGraphNode* strong_roots = GetNode( | 1712 const v8::HeapGraphNode* strong_roots = GetNode( |
| 1678 gc_roots, v8::HeapGraphNode::kObject, "(Strong roots)"); | 1713 gc_roots, v8::HeapGraphNode::kObject, "(Strong roots)"); |
| 1679 CHECK_NE(NULL, strong_roots); | 1714 CHECK_NE(NULL, strong_roots); |
| 1680 for (int i = 0; i < strong_roots->GetChildrenCount(); ++i) { | 1715 for (int i = 0; i < strong_roots->GetChildrenCount(); ++i) { |
| 1681 const v8::HeapGraphEdge* edge = strong_roots->GetChild(i); | 1716 const v8::HeapGraphEdge* edge = strong_roots->GetChild(i); |
| 1682 CHECK_EQ(v8::HeapGraphEdge::kInternal, edge->GetType()); | 1717 CHECK_EQ(v8::HeapGraphEdge::kInternal, edge->GetType()); |
| 1683 v8::String::AsciiValue name(edge->GetName()); | 1718 v8::String::AsciiValue name(edge->GetName()); |
| 1684 CHECK(isalpha(**name)); | 1719 CHECK(isalpha(**name)); |
| 1685 } | 1720 } |
| 1686 } | 1721 } |
| 1687 | 1722 |
| 1688 | 1723 |
| 1689 TEST(NoRefsToNonEssentialEntries) { | 1724 TEST(NoRefsToNonEssentialEntries) { |
| 1690 LocalContext env; | 1725 LocalContext env; |
| 1691 v8::HandleScope scope(env->GetIsolate()); | 1726 v8::HandleScope scope(env->GetIsolate()); |
| 1727 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1692 CompileRun("global_object = {};\n"); | 1728 CompileRun("global_object = {};\n"); |
| 1693 const v8::HeapSnapshot* snapshot = | 1729 const v8::HeapSnapshot* snapshot = |
| 1694 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); | 1730 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1695 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1731 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1696 const v8::HeapGraphNode* global_object = | 1732 const v8::HeapGraphNode* global_object = |
| 1697 GetProperty(global, v8::HeapGraphEdge::kProperty, "global_object"); | 1733 GetProperty(global, v8::HeapGraphEdge::kProperty, "global_object"); |
| 1698 CHECK_NE(NULL, global_object); | 1734 CHECK_NE(NULL, global_object); |
| 1699 const v8::HeapGraphNode* properties = | 1735 const v8::HeapGraphNode* properties = |
| 1700 GetProperty(global_object, v8::HeapGraphEdge::kInternal, "properties"); | 1736 GetProperty(global_object, v8::HeapGraphEdge::kInternal, "properties"); |
| 1701 CHECK_EQ(NULL, properties); | 1737 CHECK_EQ(NULL, properties); |
| 1702 const v8::HeapGraphNode* elements = | 1738 const v8::HeapGraphNode* elements = |
| 1703 GetProperty(global_object, v8::HeapGraphEdge::kInternal, "elements"); | 1739 GetProperty(global_object, v8::HeapGraphEdge::kInternal, "elements"); |
| 1704 CHECK_EQ(NULL, elements); | 1740 CHECK_EQ(NULL, elements); |
| 1705 } | 1741 } |
| 1706 | 1742 |
| 1707 | 1743 |
| 1708 TEST(MapHasDescriptorsAndTransitions) { | 1744 TEST(MapHasDescriptorsAndTransitions) { |
| 1709 LocalContext env; | 1745 LocalContext env; |
| 1710 v8::HandleScope scope(env->GetIsolate()); | 1746 v8::HandleScope scope(env->GetIsolate()); |
| 1747 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1711 CompileRun("obj = { a: 10 };\n"); | 1748 CompileRun("obj = { a: 10 };\n"); |
| 1712 const v8::HeapSnapshot* snapshot = | 1749 const v8::HeapSnapshot* snapshot = |
| 1713 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); | 1750 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1714 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1751 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1715 const v8::HeapGraphNode* global_object = | 1752 const v8::HeapGraphNode* global_object = |
| 1716 GetProperty(global, v8::HeapGraphEdge::kProperty, "obj"); | 1753 GetProperty(global, v8::HeapGraphEdge::kProperty, "obj"); |
| 1717 CHECK_NE(NULL, global_object); | 1754 CHECK_NE(NULL, global_object); |
| 1718 | 1755 |
| 1719 const v8::HeapGraphNode* map = | 1756 const v8::HeapGraphNode* map = |
| 1720 GetProperty(global_object, v8::HeapGraphEdge::kInternal, "map"); | 1757 GetProperty(global_object, v8::HeapGraphEdge::kInternal, "map"); |
| 1721 CHECK_NE(NULL, map); | 1758 CHECK_NE(NULL, map); |
| 1722 const v8::HeapGraphNode* own_descriptors = GetProperty( | 1759 const v8::HeapGraphNode* own_descriptors = GetProperty( |
| 1723 map, v8::HeapGraphEdge::kInternal, "descriptors"); | 1760 map, v8::HeapGraphEdge::kInternal, "descriptors"); |
| 1724 CHECK_NE(NULL, own_descriptors); | 1761 CHECK_NE(NULL, own_descriptors); |
| 1725 const v8::HeapGraphNode* own_transitions = GetProperty( | 1762 const v8::HeapGraphNode* own_transitions = GetProperty( |
| 1726 map, v8::HeapGraphEdge::kInternal, "transitions"); | 1763 map, v8::HeapGraphEdge::kInternal, "transitions"); |
| 1727 CHECK_EQ(NULL, own_transitions); | 1764 CHECK_EQ(NULL, own_transitions); |
| 1728 } | 1765 } |
| 1729 | 1766 |
| 1730 | 1767 |
| 1731 TEST(ManyLocalsInSharedContext) { | 1768 TEST(ManyLocalsInSharedContext) { |
| 1732 v8::HandleScope scope; | |
| 1733 LocalContext env; | 1769 LocalContext env; |
| 1770 v8::HandleScope scope(env->GetIsolate()); |
| 1771 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1734 int num_objects = 6000; | 1772 int num_objects = 6000; |
| 1735 CompileRun( | 1773 CompileRun( |
| 1736 "var n = 6000;" | 1774 "var n = 6000;" |
| 1737 "var result = [];" | 1775 "var result = [];" |
| 1738 "result.push('(function outer() {');" | 1776 "result.push('(function outer() {');" |
| 1739 "for (var i = 0; i < n; i++) {" | 1777 "for (var i = 0; i < n; i++) {" |
| 1740 " var f = 'function f_' + i + '() { ';" | 1778 " var f = 'function f_' + i + '() { ';" |
| 1741 " if (i > 0)" | 1779 " if (i > 0)" |
| 1742 " f += 'f_' + (i - 1) + '();';" | 1780 " f += 'f_' + (i - 1) + '();';" |
| 1743 " f += ' }';" | 1781 " f += ' }';" |
| 1744 " result.push(f);" | 1782 " result.push(f);" |
| 1745 "}" | 1783 "}" |
| 1746 "result.push('return f_' + (n - 1) + ';');" | 1784 "result.push('return f_' + (n - 1) + ';');" |
| 1747 "result.push('})()');" | 1785 "result.push('})()');" |
| 1748 "var ok = eval(result.join('\\n'));"); | 1786 "var ok = eval(result.join('\\n'));"); |
| 1749 const v8::HeapSnapshot* snapshot = | 1787 const v8::HeapSnapshot* snapshot = |
| 1750 v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); | 1788 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1751 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1789 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1752 CHECK_NE(NULL, global); | 1790 CHECK_NE(NULL, global); |
| 1753 const v8::HeapGraphNode* ok_object = | 1791 const v8::HeapGraphNode* ok_object = |
| 1754 GetProperty(global, v8::HeapGraphEdge::kProperty, "ok"); | 1792 GetProperty(global, v8::HeapGraphEdge::kProperty, "ok"); |
| 1755 CHECK_NE(NULL, ok_object); | 1793 CHECK_NE(NULL, ok_object); |
| 1756 const v8::HeapGraphNode* context_object = | 1794 const v8::HeapGraphNode* context_object = |
| 1757 GetProperty(ok_object, v8::HeapGraphEdge::kInternal, "context"); | 1795 GetProperty(ok_object, v8::HeapGraphEdge::kInternal, "context"); |
| 1758 CHECK_NE(NULL, context_object); | 1796 CHECK_NE(NULL, context_object); |
| 1759 // Check the objects are not duplicated in the context. | 1797 // Check the objects are not duplicated in the context. |
| 1760 CHECK_EQ(v8::internal::Context::MIN_CONTEXT_SLOTS + num_objects - 1, | 1798 CHECK_EQ(v8::internal::Context::MIN_CONTEXT_SLOTS + num_objects - 1, |
| 1761 context_object->GetChildrenCount()); | 1799 context_object->GetChildrenCount()); |
| 1762 // Check all the objects have got their names. | 1800 // Check all the objects have got their names. |
| 1763 // ... well check just every 8th because otherwise it's too slow in debug. | 1801 // ... well check just every 8th because otherwise it's too slow in debug. |
| 1764 for (int i = 0; i < num_objects - 1; i += 8) { | 1802 for (int i = 0; i < num_objects - 1; i += 8) { |
| 1765 i::EmbeddedVector<char, 100> var_name; | 1803 i::EmbeddedVector<char, 100> var_name; |
| 1766 i::OS::SNPrintF(var_name, "f_%d", i); | 1804 i::OS::SNPrintF(var_name, "f_%d", i); |
| 1767 const v8::HeapGraphNode* f_object = GetProperty( | 1805 const v8::HeapGraphNode* f_object = GetProperty( |
| 1768 context_object, v8::HeapGraphEdge::kContextVariable, var_name.start()); | 1806 context_object, v8::HeapGraphEdge::kContextVariable, var_name.start()); |
| 1769 CHECK_NE(NULL, f_object); | 1807 CHECK_NE(NULL, f_object); |
| 1770 } | 1808 } |
| 1771 } | 1809 } |
| OLD | NEW |