Chromium Code Reviews

Side by Side Diff: test/cctest/test-heap-profiler.cc

Issue 1555553002: [profiler] Implement POC Sampling Heap Profiler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: increase sampling frequency in tests to reduce random chance failure likelihood Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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 2834 matching lines...)
2845 map.AddRange(ToAddress(0x180), 0x80, 6U); 2845 map.AddRange(ToAddress(0x180), 0x80, 6U);
2846 map.AddRange(ToAddress(0x180), 0x80, 7U); 2846 map.AddRange(ToAddress(0x180), 0x80, 7U);
2847 CHECK_EQ(7u, map.GetTraceNodeId(ToAddress(0x180))); 2847 CHECK_EQ(7u, map.GetTraceNodeId(ToAddress(0x180)));
2848 CHECK_EQ(5u, map.GetTraceNodeId(ToAddress(0x200))); 2848 CHECK_EQ(5u, map.GetTraceNodeId(ToAddress(0x200)));
2849 CHECK_EQ(3u, map.size()); 2849 CHECK_EQ(3u, map.size());
2850 2850
2851 map.Clear(); 2851 map.Clear();
2852 CHECK_EQ(0u, map.size()); 2852 CHECK_EQ(0u, map.size());
2853 CHECK_EQ(0u, map.GetTraceNodeId(ToAddress(0x400))); 2853 CHECK_EQ(0u, map.GetTraceNodeId(ToAddress(0x400)));
2854 } 2854 }
2855
2856
2857 static const v8::AllocationProfile::Node* FindAllocationProfileNode(
2858 v8::AllocationProfile& profile, const Vector<const char*>& names) {
2859 v8::AllocationProfile::Node* node = profile.GetRootNode();
2860 for (int i = 0; node != nullptr && i < names.length(); ++i) {
2861 const char* name = names[i];
2862 auto children = node->children;
2863 node = nullptr;
2864 for (v8::AllocationProfile::Node* child : children) {
2865 v8::String::Utf8Value child_name(child->name);
2866 if (strcmp(*child_name, name) == 0) {
2867 node = child;
2868 break;
2869 }
2870 }
2871 }
2872 return node;
2873 }
2874
2875
2876 TEST(SamplingHeapProfiler) {
2877 v8::HandleScope scope(v8::Isolate::GetCurrent());
2878 LocalContext env;
2879 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
2880
2881 // Turn off always_opt. Inlining can cause stack traces to be shorter than
2882 // what we expect in this test.
2883 v8::internal::FLAG_always_opt = false;
2884
2885 const char* script_source =
2886 "var A = [];\n"
2887 "function bar(size) { return new Array(size); }\n"
2888 "var foo = function() {\n"
2889 " for (var i = 0; i < 1024; ++i) {\n"
2890 " A[i] = bar(1024);\n"
2891 " }\n"
2892 "}\n"
2893 "foo();";
2894
2895 // Sample should be empty if requested before sampling has started.
2896 {
2897 v8::AllocationProfile* profile = heap_profiler->GetAllocationProfile();
2898 CHECK(profile == nullptr);
2899 }
2900
2901 int count_512kb = 0;
2902 {
2903 heap_profiler->StartSamplingHeapProfiler(512 * 1024);
alph 2016/01/20 23:13:01 This is a source for flakiness, as the interval is
ofrobots 2016/01/21 03:03:28 I like the idea to suppress randomness some of the
alph 2016/01/21 03:21:55 oh yes, it's 2 multiplies by sizeof(intptr_t) = 16
2904 CompileRun(script_source);
2905
2906 v8::AllocationProfile* profile = heap_profiler->GetAllocationProfile();
alph 2016/01/20 23:13:01 Please use SmartPointer wherever possible.
ofrobots 2016/01/21 03:03:28 Done.
2907 CHECK(profile);
2908
2909 const char* names[] = {"", "foo", "bar"};
2910 auto node_bar = FindAllocationProfileNode(
2911 *profile, Vector<const char*>(names, arraysize(names)));
2912 CHECK(node_bar);
2913
2914 // Count the number of allocations we sampled from bar.
2915 for (auto allocation : node_bar->allocations) {
2916 count_512kb += allocation.count;
2917 }
2918
2919 heap_profiler->StopSamplingHeapProfiler();
2920 delete profile;
2921 }
2922
2923 // Samples should get cleared once sampling is stopped.
2924 {
2925 v8::AllocationProfile* profile = heap_profiler->GetAllocationProfile();
2926 CHECK(profile == nullptr);
2927 }
2928
2929 // Sampling at a higher rate should give us more sampled objects.
2930 {
2931 heap_profiler->StartSamplingHeapProfiler(32 * 1024);
2932 CompileRun(script_source);
2933
2934 v8::AllocationProfile* profile = heap_profiler->GetAllocationProfile();
2935 CHECK(profile);
2936
2937 const char* names[] = {"", "foo", "bar"};
2938 auto node_bar = FindAllocationProfileNode(
2939 *profile, Vector<const char*>(names, arraysize(names)));
2940 CHECK(node_bar);
2941
2942 // Count the number of allocations we sampled from bar.
2943 int count_32kb = 0;
2944 for (auto allocation : node_bar->allocations) {
2945 count_32kb += allocation.count;
2946 }
2947
2948 // We should have roughly 16x as many sampled allocations. However, since
2949 // sampling is a randomized process, we use a weaker test.
2950 CHECK_GT(count_32kb, count_512kb);
alph 2016/01/20 23:13:01 Again, this seems to be a source for the test flak
ofrobots 2016/01/21 03:03:28 I am intentionally using a weak test here to avoid
2951
2952 heap_profiler->StopSamplingHeapProfiler();
2953 delete profile;
2954 }
2955
2956 // A more complicated test cases with deeper call graph and dynamically
2957 // generated function names.
2958 {
2959 heap_profiler->StartSamplingHeapProfiler(128);
2960 CompileRun(record_trace_tree_source);
2961
2962 v8::AllocationProfile* profile = heap_profiler->GetAllocationProfile();
2963 CHECK(profile);
2964
2965 const char* names1[] = {"", "start", "f_0_0", "f_0_1", "f_0_2"};
2966 auto node1 = FindAllocationProfileNode(
2967 *profile, Vector<const char*>(names1, arraysize(names1)));
2968 CHECK(node1);
2969
2970 const char* names2[] = {"", "generateFunctions"};
2971 auto node2 = FindAllocationProfileNode(
2972 *profile, Vector<const char*>(names2, arraysize(names2)));
2973 CHECK(node2);
2974
2975 heap_profiler->StopSamplingHeapProfiler();
2976 delete profile;
2977 }
2978 }
2979
2980
2981 TEST(SamplingHeapProfilerApiAllocation) {
2982 v8::HandleScope scope(v8::Isolate::GetCurrent());
2983 LocalContext env;
2984 v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
2985
2986 heap_profiler->StartSamplingHeapProfiler(256);
2987
2988 for (int i = 0; i < 8 * 1024; ++i) v8::Object::New(env->GetIsolate());
2989
2990 v8::AllocationProfile* profile = heap_profiler->GetAllocationProfile();
2991 CHECK(profile);
2992 const char* names[] = {"(V8 API)"};
2993 auto node = FindAllocationProfileNode(
2994 *profile, Vector<const char*>(names, arraysize(names)));
2995 CHECK(node);
2996
2997 heap_profiler->StopSamplingHeapProfiler();
2998 delete profile;
2999 }
OLDNEW

Powered by Google App Engine