LCOV - code coverage report
Current view: top level - src/heap - code-stats.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1 28 3.6 %
Date: 2019-01-20 Functions: 2 6 33.3 %

          Line data    Source code
       1             : // Copyright 2016 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/heap/code-stats.h"
       6             : 
       7             : #include "src/code-comments.h"
       8             : #include "src/objects-inl.h"
       9             : #include "src/reloc-info.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : // Record code statisitcs.
      15           0 : void CodeStatistics::RecordCodeAndMetadataStatistics(HeapObject object,
      16           0 :                                                      Isolate* isolate) {
      17           0 :   if (object->IsScript()) {
      18           0 :     Script script = Script::cast(object);
      19             :     // Log the size of external source code.
      20           0 :     Object source = script->source();
      21           0 :     if (source->IsExternalString()) {
      22           0 :       ExternalString external_source_string = ExternalString::cast(source);
      23             :       int size = isolate->external_script_source_size();
      24           0 :       size += external_source_string->ExternalPayloadSize();
      25             :       isolate->set_external_script_source_size(size);
      26             :     }
      27           0 :   } else if (object->IsAbstractCode()) {
      28             :     // Record code+metadata statisitcs.
      29           0 :     AbstractCode abstract_code = AbstractCode::cast(object);
      30           0 :     int size = abstract_code->SizeIncludingMetadata();
      31           0 :     if (abstract_code->IsCode()) {
      32           0 :       size += isolate->code_and_metadata_size();
      33             :       isolate->set_code_and_metadata_size(size);
      34             :     } else {
      35           0 :       size += isolate->bytecode_and_metadata_size();
      36             :       isolate->set_bytecode_and_metadata_size(size);
      37             :     }
      38             : 
      39             : #ifdef DEBUG
      40             :     // Record code kind and code comment statistics.
      41             :     isolate->code_kind_statistics()[abstract_code->kind()] +=
      42             :         abstract_code->Size();
      43             :     CodeStatistics::CollectCodeCommentStatistics(object, isolate);
      44             : #endif
      45             :   }
      46           0 : }
      47             : 
      48           0 : void CodeStatistics::ResetCodeAndMetadataStatistics(Isolate* isolate) {
      49             :   isolate->set_code_and_metadata_size(0);
      50             :   isolate->set_bytecode_and_metadata_size(0);
      51             :   isolate->set_external_script_source_size(0);
      52             : #ifdef DEBUG
      53             :   ResetCodeStatistics(isolate);
      54             : #endif
      55           0 : }
      56             : 
      57             : // Collects code size statistics:
      58             : // - code and metadata size
      59             : // - by code kind (only in debug mode)
      60             : // - by code comment (only in debug mode)
      61           0 : void CodeStatistics::CollectCodeStatistics(PagedSpace* space,
      62             :                                            Isolate* isolate) {
      63           0 :   HeapObjectIterator obj_it(space);
      64           0 :   for (HeapObject obj = obj_it.Next(); !obj.is_null(); obj = obj_it.Next()) {
      65           0 :     RecordCodeAndMetadataStatistics(obj, isolate);
      66             :   }
      67           0 : }
      68             : 
      69             : // Collects code size statistics in LargeObjectSpace:
      70             : // - code and metadata size
      71             : // - by code kind (only in debug mode)
      72             : // - by code comment (only in debug mode)
      73           0 : void CodeStatistics::CollectCodeStatistics(LargeObjectSpace* space,
      74             :                                            Isolate* isolate) {
      75           0 :   LargeObjectIterator obj_it(space);
      76           0 :   for (HeapObject obj = obj_it.Next(); !obj.is_null(); obj = obj_it.Next()) {
      77           0 :     RecordCodeAndMetadataStatistics(obj, isolate);
      78             :   }
      79           0 : }
      80             : 
      81             : #ifdef DEBUG
      82             : void CodeStatistics::ReportCodeStatistics(Isolate* isolate) {
      83             :   // Report code kind statistics
      84             :   int* code_kind_statistics = isolate->code_kind_statistics();
      85             :   PrintF("\n   Code kind histograms: \n");
      86             :   for (int i = 0; i < AbstractCode::NUMBER_OF_KINDS; i++) {
      87             :     if (code_kind_statistics[i] > 0) {
      88             :       PrintF("     %-20s: %10d bytes\n",
      89             :              AbstractCode::Kind2String(static_cast<AbstractCode::Kind>(i)),
      90             :              code_kind_statistics[i]);
      91             :     }
      92             :   }
      93             :   PrintF("\n");
      94             : 
      95             :   // Report code and metadata statisitcs
      96             :   if (isolate->code_and_metadata_size() > 0) {
      97             :     PrintF("Code size including metadata    : %10d bytes\n",
      98             :            isolate->code_and_metadata_size());
      99             :   }
     100             :   if (isolate->bytecode_and_metadata_size() > 0) {
     101             :     PrintF("Bytecode size including metadata: %10d bytes\n",
     102             :            isolate->bytecode_and_metadata_size());
     103             :   }
     104             : 
     105             :   // Report code comment statistics
     106             :   CommentStatistic* comments_statistics =
     107             :       isolate->paged_space_comments_statistics();
     108             :   PrintF(
     109             :       "Code comment statistics (\"   [ comment-txt   :    size/   "
     110             :       "count  (average)\"):\n");
     111             :   for (int i = 0; i <= CommentStatistic::kMaxComments; i++) {
     112             :     const CommentStatistic& cs = comments_statistics[i];
     113             :     if (cs.size > 0) {
     114             :       PrintF("   %-30s: %10d/%6d     (%d)\n", cs.comment, cs.size, cs.count,
     115             :              cs.size / cs.count);
     116             :     }
     117             :   }
     118             :   PrintF("\n");
     119             : }
     120             : 
     121             : void CodeStatistics::ResetCodeStatistics(Isolate* isolate) {
     122             :   // Clear code kind statistics
     123             :   int* code_kind_statistics = isolate->code_kind_statistics();
     124             :   for (int i = 0; i < AbstractCode::NUMBER_OF_KINDS; i++) {
     125             :     code_kind_statistics[i] = 0;
     126             :   }
     127             : 
     128             :   // Clear code comment statistics
     129             :   CommentStatistic* comments_statistics =
     130             :       isolate->paged_space_comments_statistics();
     131             :   for (int i = 0; i < CommentStatistic::kMaxComments; i++) {
     132             :     comments_statistics[i].Clear();
     133             :   }
     134             :   comments_statistics[CommentStatistic::kMaxComments].comment = "Unknown";
     135             :   comments_statistics[CommentStatistic::kMaxComments].size = 0;
     136             :   comments_statistics[CommentStatistic::kMaxComments].count = 0;
     137             : }
     138             : 
     139             : // Adds comment to 'comment_statistics' table. Performance OK as long as
     140             : // 'kMaxComments' is small
     141             : void CodeStatistics::EnterComment(Isolate* isolate, const char* comment,
     142             :                                   int delta) {
     143             :   CommentStatistic* comments_statistics =
     144             :       isolate->paged_space_comments_statistics();
     145             :   // Do not count empty comments
     146             :   if (delta <= 0) return;
     147             :   CommentStatistic* cs = &comments_statistics[CommentStatistic::kMaxComments];
     148             :   // Search for a free or matching entry in 'comments_statistics': 'cs'
     149             :   // points to result.
     150             :   for (int i = 0; i < CommentStatistic::kMaxComments; i++) {
     151             :     if (comments_statistics[i].comment == nullptr) {
     152             :       cs = &comments_statistics[i];
     153             :       cs->comment = comment;
     154             :       break;
     155             :     } else if (strcmp(comments_statistics[i].comment, comment) == 0) {
     156             :       cs = &comments_statistics[i];
     157             :       break;
     158             :     }
     159             :   }
     160             :   // Update entry for 'comment'
     161             :   cs->size += delta;
     162             :   cs->count += 1;
     163             : }
     164             : 
     165             : // Call for each nested comment start (start marked with '[ xxx', end marked
     166             : // with ']'.  RelocIterator 'it' must point to a comment reloc info.
     167             : void CodeStatistics::CollectCommentStatistics(Isolate* isolate,
     168             :                                               CodeCommentsIterator* cit) {
     169             :   DCHECK(cit->HasCurrent());
     170             :   const char* comment_txt = cit->GetComment();
     171             :   if (comment_txt[0] != '[') {
     172             :     // Not a nested comment; skip
     173             :     return;
     174             :   }
     175             : 
     176             :   // Search for end of nested comment or a new nested comment
     177             :   int prev_pc_offset = cit->GetPCOffset();
     178             :   int flat_delta = 0;
     179             :   cit->Next();
     180             :   for (; cit->HasCurrent(); cit->Next()) {
     181             :     // All nested comments must be terminated properly, and therefore exit
     182             :     // from loop.
     183             :     const char* const txt = cit->GetComment();
     184             :     flat_delta += cit->GetPCOffset() - prev_pc_offset;
     185             :     if (txt[0] == ']') break;  // End of nested  comment
     186             :     // A new comment
     187             :     CollectCommentStatistics(isolate, cit);
     188             :     // Skip code that was covered with previous comment
     189             :     prev_pc_offset = cit->GetPCOffset();
     190             :   }
     191             :   EnterComment(isolate, comment_txt, flat_delta);
     192             : }
     193             : 
     194             : // Collects code comment statistics
     195             : void CodeStatistics::CollectCodeCommentStatistics(HeapObject obj,
     196             :                                                   Isolate* isolate) {
     197             :   // Bytecode objects do not contain RelocInfo. Only process code objects
     198             :   // for code comment statistics.
     199             :   if (!obj->IsCode()) {
     200             :     return;
     201             :   }
     202             : 
     203             :   Code code = Code::cast(obj);
     204             :   CodeCommentsIterator cit(code->code_comments());
     205             :   int delta = 0;
     206             :   int prev_pc_offset = 0;
     207             :   while (cit.HasCurrent()) {
     208             :     delta += static_cast<int>(cit.GetPCOffset() - prev_pc_offset);
     209             :     CollectCommentStatistics(isolate, &cit);
     210             :     prev_pc_offset = cit.GetPCOffset();
     211             :     cit.Next();
     212             :   }
     213             : 
     214             :   DCHECK(0 <= prev_pc_offset && prev_pc_offset <= code->raw_instruction_size());
     215             :   delta += static_cast<int>(code->raw_instruction_size() - prev_pc_offset);
     216             :   EnterComment(isolate, "NoComment", delta);
     217             : }
     218             : #endif
     219             : 
     220             : }  // namespace internal
     221      183867 : }  // namespace v8

Generated by: LCOV version 1.10