LCOV - code coverage report
Current view: top level - src/heap - code-stats.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 0 20 0.0 %
Date: 2017-04-26 Functions: 0 4 0.0 %

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

Generated by: LCOV version 1.10