Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: src/heap/spaces.cc

Issue 2082863003: Refactor the functions related to collecting code statistics to a new class. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/heap/spaces.h ('k') | src/v8.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/heap/spaces.h" 5 #include "src/heap/spaces.h"
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/platform/platform.h" 8 #include "src/base/platform/platform.h"
9 #include "src/base/platform/semaphore.h" 9 #include "src/base/platform/semaphore.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 2028 matching lines...) Expand 10 before | Expand all | Expand 10 after
2039 INSTANCE_TYPE_LIST(DEF_TYPE_NAME) 2039 INSTANCE_TYPE_LIST(DEF_TYPE_NAME)
2040 #undef DEF_TYPE_NAME 2040 #undef DEF_TYPE_NAME
2041 2041
2042 #define CLEAR_HISTOGRAM(name) isolate->heap_histograms()[name].clear(); 2042 #define CLEAR_HISTOGRAM(name) isolate->heap_histograms()[name].clear();
2043 INSTANCE_TYPE_LIST(CLEAR_HISTOGRAM) 2043 INSTANCE_TYPE_LIST(CLEAR_HISTOGRAM)
2044 #undef CLEAR_HISTOGRAM 2044 #undef CLEAR_HISTOGRAM
2045 2045
2046 isolate->js_spill_information()->Clear(); 2046 isolate->js_spill_information()->Clear();
2047 } 2047 }
2048 2048
2049
2050 static void ClearCodeKindStatistics(int* code_kind_statistics) {
2051 for (int i = 0; i < AbstractCode::NUMBER_OF_KINDS; i++) {
2052 code_kind_statistics[i] = 0;
2053 }
2054 }
2055 static void ReportCodeKindStatistics(int* code_kind_statistics) {
2056 PrintF("\n Code kind histograms: \n");
2057 for (int i = 0; i < AbstractCode::NUMBER_OF_KINDS; i++) {
2058 if (code_kind_statistics[i] > 0) {
2059 PrintF(" %-20s: %10d bytes\n",
2060 AbstractCode::Kind2String(static_cast<AbstractCode::Kind>(i)),
2061 code_kind_statistics[i]);
2062 }
2063 }
2064 PrintF("\n");
2065 }
2066
2067 static int CollectHistogramInfo(HeapObject* obj) { 2049 static int CollectHistogramInfo(HeapObject* obj) {
2068 Isolate* isolate = obj->GetIsolate(); 2050 Isolate* isolate = obj->GetIsolate();
2069 InstanceType type = obj->map()->instance_type(); 2051 InstanceType type = obj->map()->instance_type();
2070 DCHECK(0 <= type && type <= LAST_TYPE); 2052 DCHECK(0 <= type && type <= LAST_TYPE);
2071 DCHECK(isolate->heap_histograms()[type].name() != NULL); 2053 DCHECK(isolate->heap_histograms()[type].name() != NULL);
2072 isolate->heap_histograms()[type].increment_number(1); 2054 isolate->heap_histograms()[type].increment_number(1);
2073 isolate->heap_histograms()[type].increment_bytes(obj->Size()); 2055 isolate->heap_histograms()[type].increment_bytes(obj->Size());
2074 2056
2075 if (FLAG_collect_heap_spill_statistics && obj->IsJSObject()) { 2057 if (FLAG_collect_heap_spill_statistics && obj->IsJSObject()) {
2076 JSObject::cast(obj) 2058 JSObject::cast(obj)
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
2754 return free_list_.Allocate(size_in_bytes); 2736 return free_list_.Allocate(size_in_bytes);
2755 } 2737 }
2756 2738
2757 // If sweeper threads are active, wait for them at that point and steal 2739 // If sweeper threads are active, wait for them at that point and steal
2758 // elements form their free-lists. Allocation may still fail their which 2740 // elements form their free-lists. Allocation may still fail their which
2759 // would indicate that there is not enough memory for the given allocation. 2741 // would indicate that there is not enough memory for the given allocation.
2760 return SweepAndRetryAllocation(size_in_bytes); 2742 return SweepAndRetryAllocation(size_in_bytes);
2761 } 2743 }
2762 2744
2763 #ifdef DEBUG 2745 #ifdef DEBUG
2764 void PagedSpace::ReportCodeStatistics(Isolate* isolate) {
2765 CommentStatistic* comments_statistics =
2766 isolate->paged_space_comments_statistics();
2767 ReportCodeKindStatistics(isolate->code_kind_statistics());
2768 PrintF("Code size including metadata : %10d bytes\n",
2769 isolate->code_and_metadata_size());
2770 PrintF("Bytecode size including metadata: %10d bytes\n",
2771 isolate->bytecode_and_metadata_size());
2772 PrintF(
2773 "Code comment statistics (\" [ comment-txt : size/ "
2774 "count (average)\"):\n");
2775 for (int i = 0; i <= CommentStatistic::kMaxComments; i++) {
2776 const CommentStatistic& cs = comments_statistics[i];
2777 if (cs.size > 0) {
2778 PrintF(" %-30s: %10d/%6d (%d)\n", cs.comment, cs.size, cs.count,
2779 cs.size / cs.count);
2780 }
2781 }
2782 PrintF("\n");
2783 }
2784
2785 void PagedSpace::ResetCodeStatistics(Isolate* isolate) {
2786 CommentStatistic* comments_statistics =
2787 isolate->paged_space_comments_statistics();
2788 ClearCodeKindStatistics(isolate->code_kind_statistics());
2789 for (int i = 0; i < CommentStatistic::kMaxComments; i++) {
2790 comments_statistics[i].Clear();
2791 }
2792 comments_statistics[CommentStatistic::kMaxComments].comment = "Unknown";
2793 comments_statistics[CommentStatistic::kMaxComments].size = 0;
2794 comments_statistics[CommentStatistic::kMaxComments].count = 0;
2795 }
2796
2797
2798 // Adds comment to 'comment_statistics' table. Performance OK as long as
2799 // 'kMaxComments' is small
2800 static void EnterComment(Isolate* isolate, const char* comment, int delta) {
2801 CommentStatistic* comments_statistics =
2802 isolate->paged_space_comments_statistics();
2803 // Do not count empty comments
2804 if (delta <= 0) return;
2805 CommentStatistic* cs = &comments_statistics[CommentStatistic::kMaxComments];
2806 // Search for a free or matching entry in 'comments_statistics': 'cs'
2807 // points to result.
2808 for (int i = 0; i < CommentStatistic::kMaxComments; i++) {
2809 if (comments_statistics[i].comment == NULL) {
2810 cs = &comments_statistics[i];
2811 cs->comment = comment;
2812 break;
2813 } else if (strcmp(comments_statistics[i].comment, comment) == 0) {
2814 cs = &comments_statistics[i];
2815 break;
2816 }
2817 }
2818 // Update entry for 'comment'
2819 cs->size += delta;
2820 cs->count += 1;
2821 }
2822
2823
2824 // Call for each nested comment start (start marked with '[ xxx', end marked
2825 // with ']'. RelocIterator 'it' must point to a comment reloc info.
2826 static void CollectCommentStatistics(Isolate* isolate, RelocIterator* it) {
2827 DCHECK(!it->done());
2828 DCHECK(it->rinfo()->rmode() == RelocInfo::COMMENT);
2829 const char* tmp = reinterpret_cast<const char*>(it->rinfo()->data());
2830 if (tmp[0] != '[') {
2831 // Not a nested comment; skip
2832 return;
2833 }
2834
2835 // Search for end of nested comment or a new nested comment
2836 const char* const comment_txt =
2837 reinterpret_cast<const char*>(it->rinfo()->data());
2838 const byte* prev_pc = it->rinfo()->pc();
2839 int flat_delta = 0;
2840 it->next();
2841 while (true) {
2842 // All nested comments must be terminated properly, and therefore exit
2843 // from loop.
2844 DCHECK(!it->done());
2845 if (it->rinfo()->rmode() == RelocInfo::COMMENT) {
2846 const char* const txt =
2847 reinterpret_cast<const char*>(it->rinfo()->data());
2848 flat_delta += static_cast<int>(it->rinfo()->pc() - prev_pc);
2849 if (txt[0] == ']') break; // End of nested comment
2850 // A new comment
2851 CollectCommentStatistics(isolate, it);
2852 // Skip code that was covered with previous comment
2853 prev_pc = it->rinfo()->pc();
2854 }
2855 it->next();
2856 }
2857 EnterComment(isolate, comment_txt, flat_delta);
2858 }
2859
2860 // Collects code comment statistics
2861 static void CollectCodeCommentStatistics(HeapObject* obj, Isolate* isolate) {
2862 if (!obj->IsCode()) {
2863 return;
2864 }
2865 Code* code = Code::cast(obj);
2866 RelocIterator it(code);
2867 int delta = 0;
2868 const byte* prev_pc = code->instruction_start();
2869 while (!it.done()) {
2870 if (it.rinfo()->rmode() == RelocInfo::COMMENT) {
2871 delta += static_cast<int>(it.rinfo()->pc() - prev_pc);
2872 CollectCommentStatistics(isolate, &it);
2873 prev_pc = it.rinfo()->pc();
2874 }
2875 it.next();
2876 }
2877
2878 DCHECK(code->instruction_start() <= prev_pc &&
2879 prev_pc <= code->instruction_end());
2880 delta += static_cast<int>(code->instruction_end() - prev_pc);
2881 EnterComment(isolate, "NoComment", delta);
2882 }
2883
2884
2885 void PagedSpace::ReportStatistics() { 2746 void PagedSpace::ReportStatistics() {
2886 int pct = static_cast<int>(Available() * 100 / Capacity()); 2747 int pct = static_cast<int>(Available() * 100 / Capacity());
2887 PrintF(" capacity: %" V8PRIdPTR ", waste: %" V8PRIdPTR 2748 PrintF(" capacity: %" V8PRIdPTR ", waste: %" V8PRIdPTR
2888 ", available: %" V8PRIdPTR ", %%%d\n", 2749 ", available: %" V8PRIdPTR ", %%%d\n",
2889 Capacity(), Waste(), Available(), pct); 2750 Capacity(), Waste(), Available(), pct);
2890 2751
2891 if (heap()->mark_compact_collector()->sweeping_in_progress()) { 2752 if (heap()->mark_compact_collector()->sweeping_in_progress()) {
2892 heap()->mark_compact_collector()->EnsureSweepingCompleted(); 2753 heap()->mark_compact_collector()->EnsureSweepingCompleted();
2893 } 2754 }
2894 ClearHistograms(heap()->isolate()); 2755 ClearHistograms(heap()->isolate());
2895 HeapObjectIterator obj_it(this); 2756 HeapObjectIterator obj_it(this);
2896 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) 2757 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next())
2897 CollectHistogramInfo(obj); 2758 CollectHistogramInfo(obj);
2898 ReportHistogram(heap()->isolate(), true); 2759 ReportHistogram(heap()->isolate(), true);
2899 } 2760 }
2900 #endif 2761 #endif
2901 2762
2902 static void RecordCodeSizeIncludingMetadata(AbstractCode* abstract_code,
2903 Isolate* isolate) {
2904 int size = abstract_code->SizeIncludingMetadata();
2905 if (abstract_code->IsCode()) {
2906 size += isolate->code_and_metadata_size();
2907 isolate->set_code_and_metadata_size(size);
2908 } else {
2909 size += isolate->bytecode_and_metadata_size();
2910 isolate->set_bytecode_and_metadata_size(size);
2911 }
2912 }
2913
2914 // Collects code size statistics:
2915 // - code and metadata size
2916 // - by code kind (only in debug mode)
2917 // - by code comment (only in debug mode)
2918 void PagedSpace::CollectCodeStatistics() {
2919 Isolate* isolate = heap()->isolate();
2920 HeapObjectIterator obj_it(this);
2921 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) {
2922 if (obj->IsAbstractCode()) {
2923 AbstractCode* code = AbstractCode::cast(obj);
2924 RecordCodeSizeIncludingMetadata(code, isolate);
2925 #ifdef DEBUG
2926 isolate->code_kind_statistics()[code->kind()] += code->Size();
2927 CollectCodeCommentStatistics(obj, isolate);
2928 #endif
2929 }
2930 }
2931 }
2932
2933 void PagedSpace::ResetCodeAndMetadataStatistics(Isolate* isolate) {
2934 isolate->set_code_and_metadata_size(0);
2935 isolate->set_bytecode_and_metadata_size(0);
2936 #ifdef DEBUG
2937 ResetCodeStatistics(isolate);
2938 #endif
2939 }
2940 2763
2941 // ----------------------------------------------------------------------------- 2764 // -----------------------------------------------------------------------------
2942 // MapSpace implementation 2765 // MapSpace implementation
2943 2766
2944 #ifdef VERIFY_HEAP 2767 #ifdef VERIFY_HEAP
2945 void MapSpace::VerifyObject(HeapObject* object) { CHECK(object->IsMap()); } 2768 void MapSpace::VerifyObject(HeapObject* object) { CHECK(object->IsMap()); }
2946 #endif 2769 #endif
2947 2770
2948 2771
2949 // ----------------------------------------------------------------------------- 2772 // -----------------------------------------------------------------------------
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
3190 HeapObject* element_object = HeapObject::cast(element); 3013 HeapObject* element_object = HeapObject::cast(element);
3191 CHECK(heap()->Contains(element_object)); 3014 CHECK(heap()->Contains(element_object));
3192 CHECK(element_object->map()->IsMap()); 3015 CHECK(element_object->map()->IsMap());
3193 } 3016 }
3194 } 3017 }
3195 } 3018 }
3196 } 3019 }
3197 } 3020 }
3198 #endif 3021 #endif
3199 3022
3200 void LargeObjectSpace::CollectCodeStatistics() {
3201 Isolate* isolate = heap()->isolate();
3202 LargeObjectIterator obj_it(this);
3203 for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) {
3204 if (obj->IsAbstractCode()) {
3205 AbstractCode* code = AbstractCode::cast(obj);
3206 RecordCodeSizeIncludingMetadata(code, isolate);
3207 #ifdef DEBUG
3208 isolate->code_kind_statistics()[code->kind()] += code->Size();
3209 CollectCodeCommentStatistics(obj, isolate);
3210 #endif
3211 }
3212 }
3213 }
3214
3215 #ifdef DEBUG 3023 #ifdef DEBUG
3216 void LargeObjectSpace::Print() { 3024 void LargeObjectSpace::Print() {
3217 OFStream os(stdout); 3025 OFStream os(stdout);
3218 LargeObjectIterator it(this); 3026 LargeObjectIterator it(this);
3219 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) { 3027 for (HeapObject* obj = it.Next(); obj != NULL; obj = it.Next()) {
3220 obj->Print(os); 3028 obj->Print(os);
3221 } 3029 }
3222 } 3030 }
3223 3031
3224 3032
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3257 object->ShortPrint(); 3065 object->ShortPrint();
3258 PrintF("\n"); 3066 PrintF("\n");
3259 } 3067 }
3260 printf(" --------------------------------------\n"); 3068 printf(" --------------------------------------\n");
3261 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes()); 3069 printf(" Marked: %x, LiveCount: %x\n", mark_size, LiveBytes());
3262 } 3070 }
3263 3071
3264 #endif // DEBUG 3072 #endif // DEBUG
3265 } // namespace internal 3073 } // namespace internal
3266 } // namespace v8 3074 } // namespace v8
OLDNEW
« no previous file with comments | « src/heap/spaces.h ('k') | src/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698