LCOV - code coverage report
Current view: top level - src - utils.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 102 183 55.7 %
Date: 2019-02-19 Functions: 24 34 70.6 %

          Line data    Source code
       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
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/utils.h"
       6             : 
       7             : #include <stdarg.h>
       8             : #include <sys/stat.h>
       9             : #include <vector>
      10             : 
      11             : #include "src/base/functional.h"
      12             : #include "src/base/logging.h"
      13             : #include "src/base/platform/platform.h"
      14             : #include "src/memcopy.h"
      15             : 
      16             : namespace v8 {
      17             : namespace internal {
      18             : 
      19       12792 : SimpleStringBuilder::SimpleStringBuilder(int size) {
      20       12792 :   buffer_ = Vector<char>::New(size);
      21       12792 :   position_ = 0;
      22       12792 : }
      23             : 
      24             : 
      25     1159194 : void SimpleStringBuilder::AddString(const char* s) {
      26             :   AddSubstring(s, StrLength(s));
      27     1159194 : }
      28             : 
      29             : 
      30      706769 : void SimpleStringBuilder::AddSubstring(const char* s, int n) {
      31             :   DCHECK(!is_finalized() && position_ + n <= buffer_.length());
      32             :   DCHECK(static_cast<size_t>(n) <= strlen(s));
      33     1865963 :   MemCopy(&buffer_[position_], s, n * kCharSize);
      34     1865963 :   position_ += n;
      35      706769 : }
      36             : 
      37             : 
      38      160001 : void SimpleStringBuilder::AddPadding(char c, int count) {
      39      302078 :   for (int i = 0; i < count; i++) {
      40             :     AddCharacter(c);
      41             :   }
      42      160001 : }
      43             : 
      44             : 
      45      291221 : void SimpleStringBuilder::AddDecimalInteger(int32_t value) {
      46      291221 :   uint32_t number = static_cast<uint32_t>(value);
      47      291221 :   if (value < 0) {
      48             :     AddCharacter('-');
      49           0 :     number = static_cast<uint32_t>(-value);
      50             :   }
      51             :   int digits = 1;
      52      699922 :   for (uint32_t factor = 10; digits < 10; digits++, factor *= 10) {
      53      699922 :     if (factor > number) break;
      54             :   }
      55      291221 :   position_ += digits;
      56      991143 :   for (int i = 1; i <= digits; i++) {
      57     1399844 :     buffer_[position_ - i] = '0' + static_cast<char>(number % 10);
      58      699922 :     number /= 10;
      59             :   }
      60      291221 : }
      61             : 
      62             : 
      63     1144901 : char* SimpleStringBuilder::Finalize() {
      64             :   DCHECK(!is_finalized() && position_ <= buffer_.length());
      65             :   // If there is no space for null termination, overwrite last character.
      66     4579604 :   if (position_ == buffer_.length()) {
      67           0 :     position_--;
      68             :     // Print ellipsis.
      69           0 :     for (int i = 3; i > 0 && position_ > i; --i) buffer_[position_ - i] = '.';
      70             :   }
      71     2289802 :   buffer_[position_] = '\0';
      72             :   // Make sure nobody managed to add a 0-character to the
      73             :   // buffer while building the string.
      74             :   DCHECK(strlen(buffer_.start()) == static_cast<size_t>(position_));
      75     1144901 :   position_ = -1;
      76             :   DCHECK(is_finalized());
      77     1144901 :   return buffer_.start();
      78             : }
      79             : 
      80         266 : std::ostream& operator<<(std::ostream& os, FeedbackSlot slot) {
      81         266 :   return os << "#" << slot.id_;
      82             : }
      83             : 
      84             : 
      85    29578554 : size_t hash_value(BailoutId id) {
      86             :   base::hash<int> h;
      87    59157030 :   return h(id.id_);
      88             : }
      89             : 
      90             : 
      91          74 : std::ostream& operator<<(std::ostream& os, BailoutId id) {
      92          74 :   return os << id.id_;
      93             : }
      94             : 
      95             : 
      96      141064 : void PrintF(const char* format, ...) {
      97             :   va_list arguments;
      98      141064 :   va_start(arguments, format);
      99      141064 :   base::OS::VPrint(format, arguments);
     100      141064 :   va_end(arguments);
     101      141064 : }
     102             : 
     103             : 
     104     3490944 : void PrintF(FILE* out, const char* format, ...) {
     105             :   va_list arguments;
     106     3490944 :   va_start(arguments, format);
     107     3490944 :   base::OS::VFPrint(out, format, arguments);
     108     3490944 :   va_end(arguments);
     109     3490944 : }
     110             : 
     111             : 
     112           0 : void PrintPID(const char* format, ...) {
     113           0 :   base::OS::Print("[%d] ", base::OS::GetCurrentProcessId());
     114             :   va_list arguments;
     115           0 :   va_start(arguments, format);
     116           0 :   base::OS::VPrint(format, arguments);
     117           0 :   va_end(arguments);
     118           0 : }
     119             : 
     120             : 
     121           0 : void PrintIsolate(void* isolate, const char* format, ...) {
     122           0 :   base::OS::Print("[%d:%p] ", base::OS::GetCurrentProcessId(), isolate);
     123             :   va_list arguments;
     124           0 :   va_start(arguments, format);
     125           0 :   base::OS::VPrint(format, arguments);
     126           0 :   va_end(arguments);
     127           0 : }
     128             : 
     129             : 
     130     1708568 : int SNPrintF(Vector<char> str, const char* format, ...) {
     131             :   va_list args;
     132     1708568 :   va_start(args, format);
     133             :   int result = VSNPrintF(str, format, args);
     134     1708631 :   va_end(args);
     135     1708631 :   return result;
     136             : }
     137             : 
     138             : 
     139     4547367 : int VSNPrintF(Vector<char> str, const char* format, va_list args) {
     140    10803302 :   return base::OS::VSNPrintF(str.start(), str.length(), format, args);
     141             : }
     142             : 
     143             : 
     144       25836 : void StrNCpy(Vector<char> dest, const char* src, size_t n) {
     145       51672 :   base::OS::StrNCpy(dest.start(), dest.length(), src, n);
     146       25836 : }
     147             : 
     148             : 
     149           0 : void Flush(FILE* out) {
     150           0 :   fflush(out);
     151           0 : }
     152             : 
     153             : 
     154           0 : char* ReadLine(const char* prompt) {
     155             :   char* result = nullptr;
     156             :   char line_buf[256];
     157             :   int offset = 0;
     158             :   bool keep_going = true;
     159           0 :   fprintf(stdout, "%s", prompt);
     160           0 :   fflush(stdout);
     161           0 :   while (keep_going) {
     162           0 :     if (fgets(line_buf, sizeof(line_buf), stdin) == nullptr) {
     163             :       // fgets got an error. Just give up.
     164           0 :       if (result != nullptr) {
     165             :         DeleteArray(result);
     166             :       }
     167             :       return nullptr;
     168             :     }
     169             :     int len = StrLength(line_buf);
     170           0 :     if (len > 1 &&
     171           0 :         line_buf[len - 2] == '\\' &&
     172           0 :         line_buf[len - 1] == '\n') {
     173             :       // When we read a line that ends with a "\" we remove the escape and
     174             :       // append the remainder.
     175           0 :       line_buf[len - 2] = '\n';
     176           0 :       line_buf[len - 1] = 0;
     177           0 :       len -= 1;
     178           0 :     } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
     179             :       // Since we read a new line we are done reading the line. This
     180             :       // will exit the loop after copying this buffer into the result.
     181             :       keep_going = false;
     182             :     }
     183           0 :     if (result == nullptr) {
     184             :       // Allocate the initial result and make room for the terminating '\0'
     185           0 :       result = NewArray<char>(len + 1);
     186             :     } else {
     187             :       // Allocate a new result with enough room for the new addition.
     188           0 :       int new_len = offset + len + 1;
     189           0 :       char* new_result = NewArray<char>(new_len);
     190             :       // Copy the existing input into the new array and set the new
     191             :       // array as the result.
     192           0 :       MemCopy(new_result, result, offset * kCharSize);
     193             :       DeleteArray(result);
     194             :       result = new_result;
     195             :     }
     196             :     // Copy the newly read line into the result.
     197           0 :     MemCopy(result + offset, line_buf, len * kCharSize);
     198           0 :     offset += len;
     199             :   }
     200             :   DCHECK_NOT_NULL(result);
     201           0 :   result[offset] = '\0';
     202           0 :   return result;
     203             : }
     204             : 
     205             : namespace {
     206             : 
     207        2298 : std::vector<char> ReadCharsFromFile(FILE* file, bool* exists, bool verbose,
     208             :                                     const char* filename) {
     209        2298 :   if (file == nullptr || fseek(file, 0, SEEK_END) != 0) {
     210           0 :     if (verbose) {
     211           0 :       base::OS::PrintError("Cannot read from file %s.\n", filename);
     212             :     }
     213           0 :     *exists = false;
     214             :     return std::vector<char>();
     215             :   }
     216             : 
     217             :   // Get the size of the file and rewind it.
     218        2298 :   ptrdiff_t size = ftell(file);
     219        2298 :   rewind(file);
     220             : 
     221        2298 :   std::vector<char> result(size);
     222        6894 :   for (ptrdiff_t i = 0; i < size && feof(file) == 0;) {
     223        6894 :     ptrdiff_t read = fread(result.data() + i, 1, size - i, file);
     224        2298 :     if (read != (size - i) && ferror(file) != 0) {
     225           0 :       fclose(file);
     226           0 :       *exists = false;
     227             :       return std::vector<char>();
     228             :     }
     229        2298 :     i += read;
     230             :   }
     231        2298 :   *exists = true;
     232             :   return result;
     233             : }
     234             : 
     235        2243 : std::vector<char> ReadCharsFromFile(const char* filename, bool* exists,
     236             :                                     bool verbose) {
     237        2243 :   FILE* file = base::OS::FOpen(filename, "rb");
     238        2243 :   std::vector<char> result = ReadCharsFromFile(file, exists, verbose, filename);
     239        2243 :   if (file != nullptr) fclose(file);
     240        2243 :   return result;
     241             : }
     242             : 
     243        2298 : std::string VectorToString(const std::vector<char>& chars) {
     244        2298 :   if (chars.size() == 0) {
     245             :     return std::string();
     246             :   }
     247        2298 :   return std::string(chars.begin(), chars.end());
     248             : }
     249             : 
     250             : }  // namespace
     251             : 
     252        2243 : std::string ReadFile(const char* filename, bool* exists, bool verbose) {
     253        2243 :   std::vector<char> result = ReadCharsFromFile(filename, exists, verbose);
     254        4486 :   return VectorToString(result);
     255             : }
     256             : 
     257          55 : std::string ReadFile(FILE* file, bool* exists, bool verbose) {
     258          55 :   std::vector<char> result = ReadCharsFromFile(file, exists, verbose, "");
     259         110 :   return VectorToString(result);
     260             : }
     261             : 
     262             : 
     263           0 : int WriteCharsToFile(const char* str, int size, FILE* f) {
     264             :   int total = 0;
     265           0 :   while (total < size) {
     266           0 :     int write = static_cast<int>(fwrite(str, 1, size - total, f));
     267           0 :     if (write == 0) {
     268             :       return total;
     269             :     }
     270           0 :     total += write;
     271           0 :     str += write;
     272             :   }
     273             :   return total;
     274             : }
     275             : 
     276             : 
     277           0 : int AppendChars(const char* filename,
     278             :                 const char* str,
     279             :                 int size,
     280             :                 bool verbose) {
     281           0 :   FILE* f = base::OS::FOpen(filename, "ab");
     282           0 :   if (f == nullptr) {
     283           0 :     if (verbose) {
     284           0 :       base::OS::PrintError("Cannot open file %s for writing.\n", filename);
     285             :     }
     286             :     return 0;
     287             :   }
     288           0 :   int written = WriteCharsToFile(str, size, f);
     289           0 :   fclose(f);
     290           0 :   return written;
     291             : }
     292             : 
     293             : 
     294           0 : int WriteChars(const char* filename,
     295             :                const char* str,
     296             :                int size,
     297             :                bool verbose) {
     298           0 :   FILE* f = base::OS::FOpen(filename, "wb");
     299           0 :   if (f == nullptr) {
     300           0 :     if (verbose) {
     301           0 :       base::OS::PrintError("Cannot open file %s for writing.\n", filename);
     302             :     }
     303             :     return 0;
     304             :   }
     305           0 :   int written = WriteCharsToFile(str, size, f);
     306           0 :   fclose(f);
     307           0 :   return written;
     308             : }
     309             : 
     310             : 
     311           0 : int WriteBytes(const char* filename,
     312             :                const byte* bytes,
     313             :                int size,
     314             :                bool verbose) {
     315             :   const char* str = reinterpret_cast<const char*>(bytes);
     316           0 :   return WriteChars(filename, str, size, verbose);
     317             : }
     318             : 
     319             : 
     320             : 
     321           0 : void StringBuilder::AddFormatted(const char* format, ...) {
     322             :   va_list arguments;
     323           0 :   va_start(arguments, format);
     324           0 :   AddFormattedList(format, arguments);
     325           0 :   va_end(arguments);
     326           0 : }
     327             : 
     328             : 
     329           0 : void StringBuilder::AddFormattedList(const char* format, va_list list) {
     330             :   DCHECK(!is_finalized() && position_ <= buffer_.length());
     331           0 :   int n = VSNPrintF(buffer_ + position_, format, list);
     332           0 :   if (n < 0 || n >= (buffer_.length() - position_)) {
     333           0 :     position_ = buffer_.length();
     334             :   } else {
     335           0 :     position_ += n;
     336             :   }
     337           0 : }
     338             : 
     339             : // Returns false iff d is NaN, +0, or -0.
     340      462703 : bool DoubleToBoolean(double d) {
     341             :   IeeeDoubleArchType u;
     342      462703 :   u.d = d;
     343      462703 :   if (u.bits.exp == 2047) {
     344             :     // Detect NaN for IEEE double precision floating point.
     345        2862 :     if ((u.bits.man_low | u.bits.man_high) != 0) return false;
     346             :   }
     347      459848 :   if (u.bits.exp == 0) {
     348             :     // Detect +0, and -0 for IEEE double precision floating point.
     349      459566 :     if ((u.bits.man_low | u.bits.man_high) == 0) return false;
     350             :   }
     351         282 :   return true;
     352             : }
     353             : 
     354   710471593 : uintptr_t GetCurrentStackPosition() {
     355             : #if V8_CC_MSVC
     356             :   return reinterpret_cast<uintptr_t>(_AddressOfReturnAddress());
     357             : #else
     358   710471593 :   return reinterpret_cast<uintptr_t>(__builtin_frame_address(0));
     359             : #endif
     360             : }
     361             : 
     362             : // The filter is a pattern that matches function names in this way:
     363             : //   "*"      all; the default
     364             : //   "-"      all but the top-level function
     365             : //   "-name"  all but the function "name"
     366             : //   ""       only the top-level function
     367             : //   "name"   only the function "name"
     368             : //   "name*"  only functions starting with "name"
     369             : //   "~"      none; the tilde is not an identifier
     370     2563955 : bool PassesFilter(Vector<const char> name, Vector<const char> filter) {
     371     2563955 :   if (filter.size() == 0) return name.size() == 0;
     372             :   auto filter_it = filter.begin();
     373             :   bool positive_filter = true;
     374     2563919 :   if (*filter_it == '-') {
     375         162 :     ++filter_it;
     376             :     positive_filter = false;
     377             :   }
     378     2563919 :   if (filter_it == filter.end()) return name.size() != 0;
     379     2563883 :   if (*filter_it == '*') return positive_filter;
     380         398 :   if (*filter_it == '~') return !positive_filter;
     381             : 
     382         724 :   bool prefix_match = filter[filter.size() - 1] == '*';
     383             :   size_t min_match_length = filter.size();
     384         362 :   if (!positive_filter) min_match_length--;  // Subtract 1 for leading '-'.
     385         362 :   if (prefix_match) min_match_length--;      // Subtract 1 for trailing '*'.
     386             : 
     387         362 :   if (name.size() < min_match_length) return !positive_filter;
     388             : 
     389             :   // TODO(sigurds): Use the new version of std::mismatch here, once we
     390             :   // can assume C++14.
     391             :   auto res = std::mismatch(filter_it, filter.end(), name.begin());
     392         240 :   if (res.first == filter.end()) {
     393         112 :     if (res.second == name.end()) {
     394             :       // The strings match, so {name} passes if we have a {positive_filter}.
     395             :       return positive_filter;
     396             :     }
     397             :     // {name} is longer than the filter, so {name} passes if we don't have a
     398             :     // {positive_filter}.
     399           0 :     return !positive_filter;
     400             :   }
     401         128 :   if (*res.first == '*') {
     402             :     // We matched up to the wildcard, so {name} passes if we have a
     403             :     // {positive_filter}.
     404             :     return positive_filter;
     405             :   }
     406             :   // We don't match, so {name} passes if we don't have a {positive_filter}.
     407          40 :   return !positive_filter;
     408             : }
     409             : 
     410             : }  // namespace internal
     411      178779 : }  // namespace v8

Generated by: LCOV version 1.10