V8 Project
utils.cc
Go to the documentation of this file.
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 <stdarg.h>
6 #include <sys/stat.h>
7 
8 #include "src/v8.h"
9 
10 #include "src/base/logging.h"
12 #include "src/utils.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 
20  position_ = 0;
21 }
22 
23 
24 void SimpleStringBuilder::AddString(const char* s) {
25  AddSubstring(s, StrLength(s));
26 }
27 
28 
29 void SimpleStringBuilder::AddSubstring(const char* s, int n) {
30  DCHECK(!is_finalized() && position_ + n <= buffer_.length());
31  DCHECK(static_cast<size_t>(n) <= strlen(s));
33  position_ += n;
34 }
35 
36 
37 void SimpleStringBuilder::AddPadding(char c, int count) {
38  for (int i = 0; i < count; i++) {
39  AddCharacter(c);
40  }
41 }
42 
43 
45  uint32_t number = static_cast<uint32_t>(value);
46  if (value < 0) {
47  AddCharacter('-');
48  number = static_cast<uint32_t>(-value);
49  }
50  int digits = 1;
51  for (uint32_t factor = 10; digits < 10; digits++, factor *= 10) {
52  if (factor > number) break;
53  }
54  position_ += digits;
55  for (int i = 1; i <= digits; i++) {
56  buffer_[position_ - i] = '0' + static_cast<char>(number % 10);
57  number /= 10;
58  }
59 }
60 
61 
64  // If there is no space for null termination, overwrite last character.
65  if (position_ == buffer_.length()) {
66  position_--;
67  // Print ellipsis.
68  for (int i = 3; i > 0 && position_ > i; --i) buffer_[position_ - i] = '.';
69  }
70  buffer_[position_] = '\0';
71  // Make sure nobody managed to add a 0-character to the
72  // buffer while building the string.
73  DCHECK(strlen(buffer_.start()) == static_cast<size_t>(position_));
74  position_ = -1;
76  return buffer_.start();
77 }
78 
79 
80 void PrintF(const char* format, ...) {
81  va_list arguments;
82  va_start(arguments, format);
83  base::OS::VPrint(format, arguments);
84  va_end(arguments);
85 }
86 
87 
88 void PrintF(FILE* out, const char* format, ...) {
89  va_list arguments;
90  va_start(arguments, format);
91  base::OS::VFPrint(out, format, arguments);
92  va_end(arguments);
93 }
94 
95 
96 void PrintPID(const char* format, ...) {
98  va_list arguments;
99  va_start(arguments, format);
100  base::OS::VPrint(format, arguments);
101  va_end(arguments);
102 }
103 
104 
105 int SNPrintF(Vector<char> str, const char* format, ...) {
106  va_list args;
107  va_start(args, format);
108  int result = VSNPrintF(str, format, args);
109  va_end(args);
110  return result;
111 }
112 
113 
114 int VSNPrintF(Vector<char> str, const char* format, va_list args) {
115  return base::OS::VSNPrintF(str.start(), str.length(), format, args);
116 }
117 
118 
119 void StrNCpy(Vector<char> dest, const char* src, size_t n) {
120  base::OS::StrNCpy(dest.start(), dest.length(), src, n);
121 }
122 
123 
124 void Flush(FILE* out) {
125  fflush(out);
126 }
127 
128 
129 char* ReadLine(const char* prompt) {
130  char* result = NULL;
131  char line_buf[256];
132  int offset = 0;
133  bool keep_going = true;
134  fprintf(stdout, "%s", prompt);
135  fflush(stdout);
136  while (keep_going) {
137  if (fgets(line_buf, sizeof(line_buf), stdin) == NULL) {
138  // fgets got an error. Just give up.
139  if (result != NULL) {
140  DeleteArray(result);
141  }
142  return NULL;
143  }
144  int len = StrLength(line_buf);
145  if (len > 1 &&
146  line_buf[len - 2] == '\\' &&
147  line_buf[len - 1] == '\n') {
148  // When we read a line that ends with a "\" we remove the escape and
149  // append the remainder.
150  line_buf[len - 2] = '\n';
151  line_buf[len - 1] = 0;
152  len -= 1;
153  } else if ((len > 0) && (line_buf[len - 1] == '\n')) {
154  // Since we read a new line we are done reading the line. This
155  // will exit the loop after copying this buffer into the result.
156  keep_going = false;
157  }
158  if (result == NULL) {
159  // Allocate the initial result and make room for the terminating '\0'
160  result = NewArray<char>(len + 1);
161  } else {
162  // Allocate a new result with enough room for the new addition.
163  int new_len = offset + len + 1;
164  char* new_result = NewArray<char>(new_len);
165  // Copy the existing input into the new array and set the new
166  // array as the result.
167  MemCopy(new_result, result, offset * kCharSize);
168  DeleteArray(result);
169  result = new_result;
170  }
171  // Copy the newly read line into the result.
172  MemCopy(result + offset, line_buf, len * kCharSize);
173  offset += len;
174  }
175  DCHECK(result != NULL);
176  result[offset] = '\0';
177  return result;
178 }
179 
180 
182  int* size,
183  int extra_space,
184  bool verbose,
185  const char* filename) {
186  if (file == NULL || fseek(file, 0, SEEK_END) != 0) {
187  if (verbose) {
188  base::OS::PrintError("Cannot read from file %s.\n", filename);
189  }
190  return NULL;
191  }
192 
193  // Get the size of the file and rewind it.
194  *size = ftell(file);
195  rewind(file);
196 
197  char* result = NewArray<char>(*size + extra_space);
198  for (int i = 0; i < *size && feof(file) == 0;) {
199  int read = static_cast<int>(fread(&result[i], 1, *size - i, file));
200  if (read != (*size - i) && ferror(file) != 0) {
201  fclose(file);
202  DeleteArray(result);
203  return NULL;
204  }
205  i += read;
206  }
207  return result;
208 }
209 
210 
211 char* ReadCharsFromFile(const char* filename,
212  int* size,
213  int extra_space,
214  bool verbose) {
215  FILE* file = base::OS::FOpen(filename, "rb");
216  char* result = ReadCharsFromFile(file, size, extra_space, verbose, filename);
217  if (file != NULL) fclose(file);
218  return result;
219 }
220 
221 
222 byte* ReadBytes(const char* filename, int* size, bool verbose) {
223  char* chars = ReadCharsFromFile(filename, size, 0, verbose);
224  return reinterpret_cast<byte*>(chars);
225 }
226 
227 
229  int size,
230  bool* exists) {
231  if (!chars) {
232  *exists = false;
233  return Vector<const char>::empty();
234  }
235  chars[size] = '\0';
236  *exists = true;
237  return Vector<const char>(chars, size);
238 }
239 
240 
241 Vector<const char> ReadFile(const char* filename,
242  bool* exists,
243  bool verbose) {
244  int size;
245  char* result = ReadCharsFromFile(filename, &size, 1, verbose);
246  return SetVectorContents(result, size, exists);
247 }
248 
249 
251  bool* exists,
252  bool verbose) {
253  int size;
254  char* result = ReadCharsFromFile(file, &size, 1, verbose, "");
255  return SetVectorContents(result, size, exists);
256 }
257 
258 
259 int WriteCharsToFile(const char* str, int size, FILE* f) {
260  int total = 0;
261  while (total < size) {
262  int write = static_cast<int>(fwrite(str, 1, size - total, f));
263  if (write == 0) {
264  return total;
265  }
266  total += write;
267  str += write;
268  }
269  return total;
270 }
271 
272 
273 int AppendChars(const char* filename,
274  const char* str,
275  int size,
276  bool verbose) {
277  FILE* f = base::OS::FOpen(filename, "ab");
278  if (f == NULL) {
279  if (verbose) {
280  base::OS::PrintError("Cannot open file %s for writing.\n", filename);
281  }
282  return 0;
283  }
284  int written = WriteCharsToFile(str, size, f);
285  fclose(f);
286  return written;
287 }
288 
289 
290 int WriteChars(const char* filename,
291  const char* str,
292  int size,
293  bool verbose) {
294  FILE* f = base::OS::FOpen(filename, "wb");
295  if (f == NULL) {
296  if (verbose) {
297  base::OS::PrintError("Cannot open file %s for writing.\n", filename);
298  }
299  return 0;
300  }
301  int written = WriteCharsToFile(str, size, f);
302  fclose(f);
303  return written;
304 }
305 
306 
307 int WriteBytes(const char* filename,
308  const byte* bytes,
309  int size,
310  bool verbose) {
311  const char* str = reinterpret_cast<const char*>(bytes);
312  return WriteChars(filename, str, size, verbose);
313 }
314 
315 
316 
317 void StringBuilder::AddFormatted(const char* format, ...) {
318  va_list arguments;
319  va_start(arguments, format);
320  AddFormattedList(format, arguments);
321  va_end(arguments);
322 }
323 
324 
325 void StringBuilder::AddFormattedList(const char* format, va_list list) {
327  int n = VSNPrintF(buffer_ + position_, format, list);
328  if (n < 0 || n >= (buffer_.length() - position_)) {
330  } else {
331  position_ += n;
332  }
333 }
334 
335 
336 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
337 static void MemMoveWrapper(void* dest, const void* src, size_t size) {
338  memmove(dest, src, size);
339 }
340 
341 
342 // Initialize to library version so we can call this at any time during startup.
343 static MemMoveFunction memmove_function = &MemMoveWrapper;
344 
345 // Defined in codegen-ia32.cc.
346 MemMoveFunction CreateMemMoveFunction();
347 
348 // Copy memory area to disjoint memory area.
349 void MemMove(void* dest, const void* src, size_t size) {
350  if (size == 0) return;
351  // Note: here we rely on dependent reads being ordered. This is true
352  // on all architectures we currently support.
353  (*memmove_function)(dest, src, size);
354 }
355 
356 #elif V8_OS_POSIX && V8_HOST_ARCH_ARM
357 void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src,
358  size_t chars) {
359  uint16_t* limit = dest + chars;
360  while (dest < limit) {
361  *dest++ = static_cast<uint16_t>(*src++);
362  }
363 }
364 
365 
366 MemCopyUint8Function memcopy_uint8_function = &MemCopyUint8Wrapper;
367 MemCopyUint16Uint8Function memcopy_uint16_uint8_function =
368  &MemCopyUint16Uint8Wrapper;
369 // Defined in codegen-arm.cc.
370 MemCopyUint8Function CreateMemCopyUint8Function(MemCopyUint8Function stub);
371 MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
372  MemCopyUint16Uint8Function stub);
373 
374 #elif V8_OS_POSIX && V8_HOST_ARCH_MIPS
375 MemCopyUint8Function memcopy_uint8_function = &MemCopyUint8Wrapper;
376 // Defined in codegen-mips.cc.
377 MemCopyUint8Function CreateMemCopyUint8Function(MemCopyUint8Function stub);
378 #endif
379 
380 
382 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
383  MemMoveFunction generated_memmove = CreateMemMoveFunction();
384  if (generated_memmove != NULL) {
385  memmove_function = generated_memmove;
386  }
387 #elif V8_OS_POSIX && V8_HOST_ARCH_ARM
388  memcopy_uint8_function = CreateMemCopyUint8Function(&MemCopyUint8Wrapper);
389  memcopy_uint16_uint8_function =
390  CreateMemCopyUint16Uint8Function(&MemCopyUint16Uint8Wrapper);
391 #elif V8_OS_POSIX && V8_HOST_ARCH_MIPS
392  memcopy_uint8_function = CreateMemCopyUint8Function(&MemCopyUint8Wrapper);
393 #endif
394 }
395 
396 
397 bool DoubleToBoolean(double d) {
398  // NaN, +0, and -0 should return the false object
399 #if __BYTE_ORDER == __LITTLE_ENDIAN
401 #elif __BYTE_ORDER == __BIG_ENDIAN
403 #endif
404  u.d = d;
405  if (u.bits.exp == 2047) {
406  // Detect NaN for IEEE double precision floating point.
407  if ((u.bits.man_low | u.bits.man_high) != 0) return false;
408  }
409  if (u.bits.exp == 0) {
410  // Detect +0, and -0 for IEEE double precision floating point.
411  if ((u.bits.man_low | u.bits.man_high) == 0) return false;
412  }
413  return true;
414 }
415 
416 
417 } } // namespace v8::internal
static void VPrint(const char *format, va_list args)
static FILE * FOpen(const char *path, const char *mode)
static int GetCurrentProcessId()
static void Print(const char *format,...)
static void StrNCpy(char *dest, int length, const char *src, size_t n)
static void PrintError(const char *format,...)
static void VFPrint(FILE *out, const char *format, va_list args)
static int VSNPrintF(char *str, int length, const char *format, va_list args)
void AddDecimalInteger(int value)
Definition: utils.cc:44
void AddPadding(char c, int count)
Definition: utils.cc:37
void AddSubstring(const char *s, int n)
Definition: utils.cc:29
void AddString(const char *s)
Definition: utils.cc:24
void AddFormattedList(const char *format, va_list list)
Definition: utils.cc:325
void AddFormatted(const char *format,...)
Definition: utils.cc:317
static Vector< T > empty()
Definition: vector.h:95
T * start() const
Definition: vector.h:47
int length() const
Definition: vector.h:41
static Vector< T > New(int length)
Definition: vector.h:27
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in only print modified registers Trace simulator debug messages Implied by trace sim abort randomize hashes to avoid predictable hash Fixed seed to use to hash property Print the time it takes to deserialize the snapshot A filename with extra code to be included in the A file to write the raw snapshot bytes A file to write the raw context snapshot bytes Write V8 startup blob file(mksnapshot only)") DEFINE_BOOL(profile_hydrogen_code_stub_compilation
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
unsigned short uint16_t
Definition: unicode.cc:23
int int32_t
Definition: unicode.cc:24
void DeleteArray(T *array)
Definition: allocation.h:68
char * ReadLine(const char *prompt)
Definition: utils.cc:129
void StrNCpy(Vector< char > dest, const char *src, size_t n)
Definition: utils.cc:119
void PrintPID(const char *format,...)
Definition: utils.cc:96
bool DoubleToBoolean(double d)
Definition: utils.cc:397
static Vector< const char > SetVectorContents(char *chars, int size, bool *exists)
Definition: utils.cc:228
int SNPrintF(Vector< char > str, const char *format,...)
Definition: utils.cc:105
void MemMove(void *dest, const void *src, size_t size)
Definition: utils.h:353
void Flush(FILE *out)
Definition: utils.cc:124
int AppendChars(const char *filename, const char *str, int size, bool verbose)
Definition: utils.cc:273
int WriteChars(const char *filename, const char *str, int size, bool verbose)
Definition: utils.cc:290
void PrintF(const char *format,...)
Definition: utils.cc:80
int VSNPrintF(Vector< char > str, const char *format, va_list args)
Definition: utils.cc:114
char * ReadCharsFromFile(FILE *file, int *size, int extra_space, bool verbose, const char *filename)
Definition: utils.cc:181
byte * ReadBytes(const char *filename, int *size, bool verbose)
Definition: utils.cc:222
Vector< const char > ReadFile(const char *filename, bool *exists, bool verbose)
Definition: utils.cc:241
int WriteBytes(const char *filename, const byte *bytes, int size, bool verbose)
Definition: utils.cc:307
const int kCharSize
Definition: globals.h:122
int StrLength(const char *string)
Definition: vector.h:147
void MemCopy(void *dest, const void *src, size_t size)
Definition: utils.h:350
int WriteCharsToFile(const char *str, int size, FILE *f)
Definition: utils.cc:259
void init_memcopy_functions()
Definition: utils.cc:381
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
struct v8::internal::IeeeDoubleLittleEndianArchType::@15 bits