| 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 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 CHECK_EQ(2, stats_update.updates_written()); | 1034 CHECK_EQ(2, stats_update.updates_written()); |
| 1035 CHECK_LT(entries_size, stats_update.entries_size()); | 1035 CHECK_LT(entries_size, stats_update.entries_size()); |
| 1036 CHECK_EQ(2, stats_update.entries_count()); | 1036 CHECK_EQ(2, stats_update.entries_count()); |
| 1037 CHECK_EQ(8, stats_update.first_interval_index()); | 1037 CHECK_EQ(8, stats_update.first_interval_index()); |
| 1038 } | 1038 } |
| 1039 | 1039 |
| 1040 heap_profiler->StopTrackingHeapObjects(); | 1040 heap_profiler->StopTrackingHeapObjects(); |
| 1041 } | 1041 } |
| 1042 | 1042 |
| 1043 | 1043 |
| 1044 TEST(HeapObjectIds) { |
| 1045 LocalContext env; |
| 1046 v8::Isolate* isolate = env->GetIsolate(); |
| 1047 v8::HandleScope scope(isolate); |
| 1048 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1049 |
| 1050 const int kLength = 10; |
| 1051 v8::Handle<v8::Object> objects[kLength]; |
| 1052 v8::SnapshotObjectId ids[kLength]; |
| 1053 |
| 1054 heap_profiler->StartTrackingHeapObjects(false); |
| 1055 |
| 1056 for (int i = 0; i < kLength; i++) { |
| 1057 objects[i] = v8::Object::New(isolate); |
| 1058 } |
| 1059 GetHeapStatsUpdate(heap_profiler); |
| 1060 |
| 1061 for (int i = 0; i < kLength; i++) { |
| 1062 v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); |
| 1063 CHECK_NE(v8::HeapProfiler::kUnknownObjectId, static_cast<int>(id)); |
| 1064 ids[i] = id; |
| 1065 } |
| 1066 |
| 1067 heap_profiler->StopTrackingHeapObjects(); |
| 1068 CcTest::heap()->CollectAllAvailableGarbage(); |
| 1069 |
| 1070 for (int i = 0; i < kLength; i++) { |
| 1071 v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); |
| 1072 CHECK_EQ(static_cast<int>(ids[i]), static_cast<int>(id)); |
| 1073 v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); |
| 1074 CHECK_EQ(objects[i], obj); |
| 1075 } |
| 1076 |
| 1077 heap_profiler->ClearObjectIds(); |
| 1078 for (int i = 0; i < kLength; i++) { |
| 1079 v8::SnapshotObjectId id = heap_profiler->GetObjectId(objects[i]); |
| 1080 CHECK_EQ(v8::HeapProfiler::kUnknownObjectId, static_cast<int>(id)); |
| 1081 v8::Handle<v8::Value> obj = heap_profiler->FindObjectById(ids[i]); |
| 1082 CHECK(obj.IsEmpty()); |
| 1083 } |
| 1084 } |
| 1085 |
| 1086 |
| 1044 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, | 1087 static void CheckChildrenIds(const v8::HeapSnapshot* snapshot, |
| 1045 const v8::HeapGraphNode* node, | 1088 const v8::HeapGraphNode* node, |
| 1046 int level, int max_level) { | 1089 int level, int max_level) { |
| 1047 if (level > max_level) return; | 1090 if (level > max_level) return; |
| 1048 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); | 1091 CHECK_EQ(node, snapshot->GetNodeById(node->GetId())); |
| 1049 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { | 1092 for (int i = 0, count = node->GetChildrenCount(); i < count; ++i) { |
| 1050 const v8::HeapGraphEdge* prop = node->GetChild(i); | 1093 const v8::HeapGraphEdge* prop = node->GetChild(i); |
| 1051 const v8::HeapGraphNode* child = | 1094 const v8::HeapGraphNode* child = |
| 1052 snapshot->GetNodeById(prop->GetToNode()->GetId()); | 1095 snapshot->GetNodeById(prop->GetToNode()->GetId()); |
| 1053 CHECK_EQ_SNAPSHOT_OBJECT_ID(prop->GetToNode()->GetId(), child->GetId()); | 1096 CHECK_EQ_SNAPSHOT_OBJECT_ID(prop->GetToNode()->GetId(), child->GetId()); |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 const int nodes_count = snapshot->GetNodesCount(); | 1555 const int nodes_count = snapshot->GetNodesCount(); |
| 1513 int count = 0; | 1556 int count = 0; |
| 1514 for (int i = 0; i < nodes_count; ++i) { | 1557 for (int i = 0; i < nodes_count; ++i) { |
| 1515 if (snapshot->GetNode(i) == global) | 1558 if (snapshot->GetNode(i) == global) |
| 1516 ++count; | 1559 ++count; |
| 1517 } | 1560 } |
| 1518 CHECK_EQ(1, count); | 1561 CHECK_EQ(1, count); |
| 1519 } | 1562 } |
| 1520 | 1563 |
| 1521 | 1564 |
| 1522 TEST(GetHeapValue) { | 1565 TEST(GetHeapValueForNode) { |
| 1523 LocalContext env; | 1566 LocalContext env; |
| 1524 v8::HandleScope scope(env->GetIsolate()); | 1567 v8::HandleScope scope(env->GetIsolate()); |
| 1525 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); | 1568 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1526 | 1569 |
| 1527 CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); | 1570 CompileRun("a = { s_prop: \'value\', n_prop: 0.1 };"); |
| 1528 const v8::HeapSnapshot* snapshot = | 1571 const v8::HeapSnapshot* snapshot = |
| 1529 heap_profiler->TakeHeapSnapshot(v8_str("value")); | 1572 heap_profiler->TakeHeapSnapshot(v8_str("value")); |
| 1530 CHECK(ValidateSnapshot(snapshot)); | 1573 CHECK(ValidateSnapshot(snapshot)); |
| 1531 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1574 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1532 CHECK(global->GetHeapValue()->IsObject()); | 1575 CHECK(heap_profiler->FindObjectById(global->GetId())->IsObject()); |
| 1533 v8::Local<v8::Object> js_global = | 1576 v8::Local<v8::Object> js_global = |
| 1534 env->Global()->GetPrototype().As<v8::Object>(); | 1577 env->Global()->GetPrototype().As<v8::Object>(); |
| 1535 CHECK(js_global == global->GetHeapValue()); | 1578 CHECK(js_global == heap_profiler->FindObjectById(global->GetId())); |
| 1536 const v8::HeapGraphNode* obj = GetProperty( | 1579 const v8::HeapGraphNode* obj = GetProperty( |
| 1537 global, v8::HeapGraphEdge::kProperty, "a"); | 1580 global, v8::HeapGraphEdge::kProperty, "a"); |
| 1538 CHECK(obj->GetHeapValue()->IsObject()); | 1581 CHECK(heap_profiler->FindObjectById(obj->GetId())->IsObject()); |
| 1539 v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); | 1582 v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); |
| 1540 CHECK(js_obj == obj->GetHeapValue()); | 1583 CHECK(js_obj == heap_profiler->FindObjectById(obj->GetId())); |
| 1541 const v8::HeapGraphNode* s_prop = | 1584 const v8::HeapGraphNode* s_prop = |
| 1542 GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); | 1585 GetProperty(obj, v8::HeapGraphEdge::kProperty, "s_prop"); |
| 1543 v8::Local<v8::String> js_s_prop = | 1586 v8::Local<v8::String> js_s_prop = |
| 1544 js_obj->Get(v8_str("s_prop")).As<v8::String>(); | 1587 js_obj->Get(v8_str("s_prop")).As<v8::String>(); |
| 1545 CHECK(js_s_prop == s_prop->GetHeapValue()); | 1588 CHECK(js_s_prop == heap_profiler->FindObjectById(s_prop->GetId())); |
| 1546 const v8::HeapGraphNode* n_prop = | 1589 const v8::HeapGraphNode* n_prop = |
| 1547 GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); | 1590 GetProperty(obj, v8::HeapGraphEdge::kProperty, "n_prop"); |
| 1548 v8::Local<v8::Number> js_n_prop = | 1591 v8::Local<v8::Number> js_n_prop = |
| 1549 js_obj->Get(v8_str("n_prop")).As<v8::Number>(); | 1592 js_obj->Get(v8_str("n_prop")).As<v8::Number>(); |
| 1550 CHECK(js_n_prop->NumberValue() == n_prop->GetHeapValue()->NumberValue()); | 1593 CHECK(js_n_prop->NumberValue() == |
| 1594 heap_profiler->FindObjectById(n_prop->GetId())->NumberValue()); |
| 1551 } | 1595 } |
| 1552 | 1596 |
| 1553 | 1597 |
| 1554 TEST(GetHeapValueForDeletedObject) { | 1598 TEST(GetHeapValueForDeletedObject) { |
| 1555 LocalContext env; | 1599 LocalContext env; |
| 1556 v8::HandleScope scope(env->GetIsolate()); | 1600 v8::HandleScope scope(env->GetIsolate()); |
| 1557 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); | 1601 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler(); |
| 1558 | 1602 |
| 1559 // It is impossible to delete a global property, so we are about to delete a | 1603 // It is impossible to delete a global property, so we are about to delete a |
| 1560 // property of the "a" object. Also, the "p" object can't be an empty one | 1604 // property of the "a" object. Also, the "p" object can't be an empty one |
| 1561 // because the empty object is static and isn't actually deleted. | 1605 // because the empty object is static and isn't actually deleted. |
| 1562 CompileRun("a = { p: { r: {} } };"); | 1606 CompileRun("a = { p: { r: {} } };"); |
| 1563 const v8::HeapSnapshot* snapshot = | 1607 const v8::HeapSnapshot* snapshot = |
| 1564 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); | 1608 heap_profiler->TakeHeapSnapshot(v8_str("snapshot")); |
| 1565 CHECK(ValidateSnapshot(snapshot)); | 1609 CHECK(ValidateSnapshot(snapshot)); |
| 1566 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); | 1610 const v8::HeapGraphNode* global = GetGlobalObject(snapshot); |
| 1567 const v8::HeapGraphNode* obj = GetProperty( | 1611 const v8::HeapGraphNode* obj = GetProperty( |
| 1568 global, v8::HeapGraphEdge::kProperty, "a"); | 1612 global, v8::HeapGraphEdge::kProperty, "a"); |
| 1569 const v8::HeapGraphNode* prop = GetProperty( | 1613 const v8::HeapGraphNode* prop = GetProperty( |
| 1570 obj, v8::HeapGraphEdge::kProperty, "p"); | 1614 obj, v8::HeapGraphEdge::kProperty, "p"); |
| 1571 { | 1615 { |
| 1572 // Perform the check inside a nested local scope to avoid creating a | 1616 // Perform the check inside a nested local scope to avoid creating a |
| 1573 // reference to the object we are deleting. | 1617 // reference to the object we are deleting. |
| 1574 v8::HandleScope scope(env->GetIsolate()); | 1618 v8::HandleScope scope(env->GetIsolate()); |
| 1575 CHECK(prop->GetHeapValue()->IsObject()); | 1619 CHECK(heap_profiler->FindObjectById(prop->GetId())->IsObject()); |
| 1576 } | 1620 } |
| 1577 CompileRun("delete a.p;"); | 1621 CompileRun("delete a.p;"); |
| 1578 CHECK(prop->GetHeapValue()->IsUndefined()); | 1622 CHECK(heap_profiler->FindObjectById(prop->GetId()).IsEmpty()); |
| 1579 } | 1623 } |
| 1580 | 1624 |
| 1581 | 1625 |
| 1582 static int StringCmp(const char* ref, i::String* act) { | 1626 static int StringCmp(const char* ref, i::String* act) { |
| 1583 i::SmartArrayPointer<char> s_act = act->ToCString(); | 1627 i::SmartArrayPointer<char> s_act = act->ToCString(); |
| 1584 int result = strcmp(ref, *s_act); | 1628 int result = strcmp(ref, s_act.get()); |
| 1585 if (result != 0) | 1629 if (result != 0) |
| 1586 fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, *s_act); | 1630 fprintf(stderr, "Expected: \"%s\", Actual: \"%s\"\n", ref, s_act.get()); |
| 1587 return result; | 1631 return result; |
| 1588 } | 1632 } |
| 1589 | 1633 |
| 1590 | 1634 |
| 1591 TEST(GetConstructorName) { | 1635 TEST(GetConstructorName) { |
| 1592 LocalContext env; | 1636 LocalContext env; |
| 1593 v8::HandleScope scope(env->GetIsolate()); | 1637 v8::HandleScope scope(env->GetIsolate()); |
| 1594 | 1638 |
| 1595 CompileRun( | 1639 CompileRun( |
| 1596 "function Constructor1() {};\n" | 1640 "function Constructor1() {};\n" |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1982 "transition_info"); | 2026 "transition_info"); |
| 1983 CHECK_NE(NULL, transition_info); | 2027 CHECK_NE(NULL, transition_info); |
| 1984 | 2028 |
| 1985 const v8::HeapGraphNode* elements = | 2029 const v8::HeapGraphNode* elements = |
| 1986 GetProperty(transition_info, v8::HeapGraphEdge::kInternal, | 2030 GetProperty(transition_info, v8::HeapGraphEdge::kInternal, |
| 1987 "elements"); | 2031 "elements"); |
| 1988 CHECK_NE(NULL, elements); | 2032 CHECK_NE(NULL, elements); |
| 1989 CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); | 2033 CHECK_EQ(v8::HeapGraphNode::kArray, elements->GetType()); |
| 1990 CHECK_EQ(v8::internal::FixedArray::SizeFor(3), elements->GetSelfSize()); | 2034 CHECK_EQ(v8::internal::FixedArray::SizeFor(3), elements->GetSelfSize()); |
| 1991 | 2035 |
| 1992 CHECK(transition_info->GetHeapValue()->IsArray()); | 2036 v8::Handle<v8::Value> array_val = |
| 1993 v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast( | 2037 heap_profiler->FindObjectById(transition_info->GetId()); |
| 1994 transition_info->GetHeapValue()); | 2038 CHECK(array_val->IsArray()); |
| 2039 v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(array_val); |
| 1995 // Verify the array is "a" in the code above. | 2040 // Verify the array is "a" in the code above. |
| 1996 CHECK_EQ(3, array->Length()); | 2041 CHECK_EQ(3, array->Length()); |
| 1997 CHECK_EQ(v8::Integer::New(3), array->Get(v8::Integer::New(0))); | 2042 CHECK_EQ(v8::Integer::New(3), array->Get(v8::Integer::New(0))); |
| 1998 CHECK_EQ(v8::Integer::New(2), array->Get(v8::Integer::New(1))); | 2043 CHECK_EQ(v8::Integer::New(2), array->Get(v8::Integer::New(1))); |
| 1999 CHECK_EQ(v8::Integer::New(1), array->Get(v8::Integer::New(2))); | 2044 CHECK_EQ(v8::Integer::New(1), array->Get(v8::Integer::New(2))); |
| 2000 } | 2045 } |
| 2001 | 2046 |
| 2002 | 2047 |
| 2003 TEST(JSFunctionHasCodeLink) { | 2048 TEST(JSFunctionHasCodeLink) { |
| 2004 LocalContext env; | 2049 LocalContext env; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2037 | 2082 |
| 2038 const char* HeapProfilerExtension::kSource = | 2083 const char* HeapProfilerExtension::kSource = |
| 2039 "native function findUntrackedObjects();"; | 2084 "native function findUntrackedObjects();"; |
| 2040 | 2085 |
| 2041 | 2086 |
| 2042 v8::Handle<v8::FunctionTemplate> | 2087 v8::Handle<v8::FunctionTemplate> |
| 2043 HeapProfilerExtension::GetNativeFunctionTemplate(v8::Isolate* isolate, | 2088 HeapProfilerExtension::GetNativeFunctionTemplate(v8::Isolate* isolate, |
| 2044 v8::Handle<v8::String> name) { | 2089 v8::Handle<v8::String> name) { |
| 2045 if (name->Equals(v8::String::NewFromUtf8(isolate, "findUntrackedObjects"))) { | 2090 if (name->Equals(v8::String::NewFromUtf8(isolate, "findUntrackedObjects"))) { |
| 2046 return v8::FunctionTemplate::New( | 2091 return v8::FunctionTemplate::New( |
| 2092 isolate, |
| 2047 HeapProfilerExtension::FindUntrackedObjects); | 2093 HeapProfilerExtension::FindUntrackedObjects); |
| 2048 } else { | 2094 } else { |
| 2049 CHECK(false); | 2095 CHECK(false); |
| 2050 return v8::Handle<v8::FunctionTemplate>(); | 2096 return v8::Handle<v8::FunctionTemplate>(); |
| 2051 } | 2097 } |
| 2052 } | 2098 } |
| 2053 | 2099 |
| 2054 | 2100 |
| 2055 void HeapProfilerExtension::FindUntrackedObjects( | 2101 void HeapProfilerExtension::FindUntrackedObjects( |
| 2056 const v8::FunctionCallbackInfo<v8::Value>& args) { | 2102 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2310 | 2356 |
| 2311 AllocationTraceNode* node = | 2357 AllocationTraceNode* node = |
| 2312 FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); | 2358 FindNode(tracker, Vector<const char*>(names, ARRAY_SIZE(names))); |
| 2313 CHECK_NE(NULL, node); | 2359 CHECK_NE(NULL, node); |
| 2314 CHECK_LT(node->allocation_count(), 100); | 2360 CHECK_LT(node->allocation_count(), 100); |
| 2315 | 2361 |
| 2316 CcTest::heap()->DisableInlineAllocation(); | 2362 CcTest::heap()->DisableInlineAllocation(); |
| 2317 heap_profiler->StopTrackingHeapObjects(); | 2363 heap_profiler->StopTrackingHeapObjects(); |
| 2318 } | 2364 } |
| 2319 } | 2365 } |
| OLD | NEW |