The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / v8utils.h @ f230a1cf

History | View | Annotate | Download (13 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_V8UTILS_H_
29
#define V8_V8UTILS_H_
30

    
31
#include "utils.h"
32
#include "platform.h"  // For va_list on Solaris.
33

    
34
namespace v8 {
35
namespace internal {
36

    
37
// ----------------------------------------------------------------------------
38
// I/O support.
39

    
40
#if __GNUC__ >= 4
41
// On gcc we can ask the compiler to check the types of %d-style format
42
// specifiers and their associated arguments.  TODO(erikcorry) fix this
43
// so it works on MacOSX.
44
#if defined(__MACH__) && defined(__APPLE__)
45
#define PRINTF_CHECKING
46
#define FPRINTF_CHECKING
47
#else  // MacOsX.
48
#define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
49
#define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3)))
50
#endif
51
#else
52
#define PRINTF_CHECKING
53
#define FPRINTF_CHECKING
54
#endif
55

    
56
// Our version of printf().
57
void PRINTF_CHECKING PrintF(const char* format, ...);
58
void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
59

    
60
// Prepends the current process ID to the output.
61
void PRINTF_CHECKING PrintPID(const char* format, ...);
62

    
63
// Our version of fflush.
64
void Flush(FILE* out);
65

    
66
inline void Flush() {
67
  Flush(stdout);
68
}
69

    
70

    
71
// Read a line of characters after printing the prompt to stdout. The resulting
72
// char* needs to be disposed off with DeleteArray by the caller.
73
char* ReadLine(const char* prompt);
74

    
75

    
76
// Read and return the raw bytes in a file. the size of the buffer is returned
77
// in size.
78
// The returned buffer must be freed by the caller.
79
byte* ReadBytes(const char* filename, int* size, bool verbose = true);
80

    
81

    
82
// Append size chars from str to the file given by filename.
83
// The file is overwritten. Returns the number of chars written.
84
int AppendChars(const char* filename,
85
                const char* str,
86
                int size,
87
                bool verbose = true);
88

    
89

    
90
// Write size chars from str to the file given by filename.
91
// The file is overwritten. Returns the number of chars written.
92
int WriteChars(const char* filename,
93
               const char* str,
94
               int size,
95
               bool verbose = true);
96

    
97

    
98
// Write size bytes to the file given by filename.
99
// The file is overwritten. Returns the number of bytes written.
100
int WriteBytes(const char* filename,
101
               const byte* bytes,
102
               int size,
103
               bool verbose = true);
104

    
105

    
106
// Write the C code
107
// const char* <varname> = "<str>";
108
// const int <varname>_len = <len>;
109
// to the file given by filename. Only the first len chars are written.
110
int WriteAsCFile(const char* filename, const char* varname,
111
                 const char* str, int size, bool verbose = true);
112

    
113

    
114
// ----------------------------------------------------------------------------
115
// Data structures
116

    
117
template <typename T>
118
inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
119
                                             int length) {
120
  return Vector< Handle<Object> >(
121
      reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
122
}
123

    
124

    
125
// ----------------------------------------------------------------------------
126
// Memory
127

    
128
// Copies words from |src| to |dst|. The data spans must not overlap.
129
template <typename T>
130
inline void CopyWords(T* dst, const T* src, size_t num_words) {
131
  STATIC_ASSERT(sizeof(T) == kPointerSize);
132
  ASSERT(Min(dst, const_cast<T*>(src)) + num_words <=
133
         Max(dst, const_cast<T*>(src)));
134
  ASSERT(num_words > 0);
135

    
136
  // Use block copying OS::MemCopy if the segment we're copying is
137
  // enough to justify the extra call/setup overhead.
138
  static const size_t kBlockCopyLimit = 16;
139

    
140
  if (num_words < kBlockCopyLimit) {
141
    do {
142
      num_words--;
143
      *dst++ = *src++;
144
    } while (num_words > 0);
145
  } else {
146
    OS::MemCopy(dst, src, num_words * kPointerSize);
147
  }
148
}
149

    
150

    
151
// Copies words from |src| to |dst|. No restrictions.
152
template <typename T>
153
inline void MoveWords(T* dst, const T* src, size_t num_words) {
154
  STATIC_ASSERT(sizeof(T) == kPointerSize);
155
  ASSERT(num_words > 0);
156

    
157
  // Use block copying OS::MemCopy if the segment we're copying is
158
  // enough to justify the extra call/setup overhead.
159
  static const size_t kBlockCopyLimit = 16;
160

    
161
  if (num_words < kBlockCopyLimit &&
162
      ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
163
    T* end = dst + num_words;
164
    do {
165
      num_words--;
166
      *dst++ = *src++;
167
    } while (num_words > 0);
168
  } else {
169
    OS::MemMove(dst, src, num_words * kPointerSize);
170
  }
171
}
172

    
173

    
174
// Copies data from |src| to |dst|.  The data spans must not overlap.
175
template <typename T>
176
inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
177
  STATIC_ASSERT(sizeof(T) == 1);
178
  ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <=
179
         Max(dst, const_cast<T*>(src)));
180
  if (num_bytes == 0) return;
181

    
182
  // Use block copying OS::MemCopy if the segment we're copying is
183
  // enough to justify the extra call/setup overhead.
184
  static const int kBlockCopyLimit = OS::kMinComplexMemCopy;
185

    
186
  if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
187
    do {
188
      num_bytes--;
189
      *dst++ = *src++;
190
    } while (num_bytes > 0);
191
  } else {
192
    OS::MemCopy(dst, src, num_bytes);
193
  }
194
}
195

    
196

    
197
template <typename T, typename U>
198
inline void MemsetPointer(T** dest, U* value, int counter) {
199
#ifdef DEBUG
200
  T* a = NULL;
201
  U* b = NULL;
202
  a = b;  // Fake assignment to check assignability.
203
  USE(a);
204
#endif  // DEBUG
205
#if V8_HOST_ARCH_IA32
206
#define STOS "stosl"
207
#elif V8_HOST_ARCH_X64
208
#define STOS "stosq"
209
#endif
210
#if defined(__native_client__)
211
  // This STOS sequence does not validate for x86_64 Native Client.
212
  // Here we #undef STOS to force use of the slower C version.
213
  // TODO(bradchen): Profile V8 and implement a faster REP STOS
214
  // here if the profile indicates it matters.
215
#undef STOS
216
#endif
217

    
218
#if defined(__GNUC__) && defined(STOS)
219
  asm volatile(
220
      "cld;"
221
      "rep ; " STOS
222
      : "+&c" (counter), "+&D" (dest)
223
      : "a" (value)
224
      : "memory", "cc");
225
#else
226
  for (int i = 0; i < counter; i++) {
227
    dest[i] = value;
228
  }
229
#endif
230

    
231
#undef STOS
232
}
233

    
234

    
235
// Simple wrapper that allows an ExternalString to refer to a
236
// Vector<const char>. Doesn't assume ownership of the data.
237
class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
238
 public:
239
  explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
240

    
241
  virtual const char* data() const { return data_.start(); }
242

    
243
  virtual size_t length() const { return data_.length(); }
244

    
245
 private:
246
  Vector<const char> data_;
247
};
248

    
249

    
250
// Simple support to read a file into a 0-terminated C-string.
251
// The returned buffer must be freed by the caller.
252
// On return, *exits tells whether the file existed.
253
Vector<const char> ReadFile(const char* filename,
254
                            bool* exists,
255
                            bool verbose = true);
256
Vector<const char> ReadFile(FILE* file,
257
                            bool* exists,
258
                            bool verbose = true);
259

    
260

    
261
template <typename sourcechar, typename sinkchar>
262
INLINE(static void CopyCharsUnsigned(sinkchar* dest,
263
                                     const sourcechar* src,
264
                                     int chars));
265
#if defined(V8_HOST_ARCH_ARM)
266
INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
267
INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
268
INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
269
#endif
270

    
271
// Copy from ASCII/16bit chars to ASCII/16bit chars.
272
template <typename sourcechar, typename sinkchar>
273
INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
274

    
275
template<typename sourcechar, typename sinkchar>
276
void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
277
  ASSERT(sizeof(sourcechar) <= 2);
278
  ASSERT(sizeof(sinkchar) <= 2);
279
  if (sizeof(sinkchar) == 1) {
280
    if (sizeof(sourcechar) == 1) {
281
      CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
282
                        reinterpret_cast<const uint8_t*>(src),
283
                        chars);
284
    } else {
285
      CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
286
                        reinterpret_cast<const uint16_t*>(src),
287
                        chars);
288
    }
289
  } else {
290
    if (sizeof(sourcechar) == 1) {
291
      CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
292
                        reinterpret_cast<const uint8_t*>(src),
293
                        chars);
294
    } else {
295
      CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest),
296
                        reinterpret_cast<const uint16_t*>(src),
297
                        chars);
298
    }
299
  }
300
}
301

    
302
template <typename sourcechar, typename sinkchar>
303
void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
304
  sinkchar* limit = dest + chars;
305
#ifdef V8_HOST_CAN_READ_UNALIGNED
306
  if (sizeof(*dest) == sizeof(*src)) {
307
    if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) {
308
      OS::MemCopy(dest, src, chars * sizeof(*dest));
309
      return;
310
    }
311
    // Number of characters in a uintptr_t.
312
    static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest);  // NOLINT
313
    ASSERT(dest + kStepSize > dest);  // Check for overflow.
314
    while (dest + kStepSize <= limit) {
315
      *reinterpret_cast<uintptr_t*>(dest) =
316
          *reinterpret_cast<const uintptr_t*>(src);
317
      dest += kStepSize;
318
      src += kStepSize;
319
    }
320
  }
321
#endif
322
  while (dest < limit) {
323
    *dest++ = static_cast<sinkchar>(*src++);
324
  }
325
}
326

    
327

    
328
#if defined(V8_HOST_ARCH_ARM)
329
void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
330
  switch (static_cast<unsigned>(chars)) {
331
    case 0:
332
      break;
333
    case 1:
334
      *dest = *src;
335
      break;
336
    case 2:
337
      memcpy(dest, src, 2);
338
      break;
339
    case 3:
340
      memcpy(dest, src, 3);
341
      break;
342
    case 4:
343
      memcpy(dest, src, 4);
344
      break;
345
    case 5:
346
      memcpy(dest, src, 5);
347
      break;
348
    case 6:
349
      memcpy(dest, src, 6);
350
      break;
351
    case 7:
352
      memcpy(dest, src, 7);
353
      break;
354
    case 8:
355
      memcpy(dest, src, 8);
356
      break;
357
    case 9:
358
      memcpy(dest, src, 9);
359
      break;
360
    case 10:
361
      memcpy(dest, src, 10);
362
      break;
363
    case 11:
364
      memcpy(dest, src, 11);
365
      break;
366
    case 12:
367
      memcpy(dest, src, 12);
368
      break;
369
    case 13:
370
      memcpy(dest, src, 13);
371
      break;
372
    case 14:
373
      memcpy(dest, src, 14);
374
      break;
375
    case 15:
376
      memcpy(dest, src, 15);
377
      break;
378
    default:
379
      OS::MemCopy(dest, src, chars);
380
      break;
381
  }
382
}
383

    
384

    
385
void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
386
  if (chars >= OS::kMinComplexConvertMemCopy) {
387
    OS::MemCopyUint16Uint8(dest, src, chars);
388
  } else {
389
    OS::MemCopyUint16Uint8Wrapper(dest, src, chars);
390
  }
391
}
392

    
393

    
394
void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
395
  switch (static_cast<unsigned>(chars)) {
396
    case 0:
397
      break;
398
    case 1:
399
      *dest = *src;
400
      break;
401
    case 2:
402
      memcpy(dest, src, 4);
403
      break;
404
    case 3:
405
      memcpy(dest, src, 6);
406
      break;
407
    case 4:
408
      memcpy(dest, src, 8);
409
      break;
410
    case 5:
411
      memcpy(dest, src, 10);
412
      break;
413
    case 6:
414
      memcpy(dest, src, 12);
415
      break;
416
    case 7:
417
      memcpy(dest, src, 14);
418
      break;
419
    default:
420
      OS::MemCopy(dest, src, chars * sizeof(*dest));
421
      break;
422
  }
423
}
424
#endif
425

    
426

    
427
class StringBuilder : public SimpleStringBuilder {
428
 public:
429
  explicit StringBuilder(int size) : SimpleStringBuilder(size) { }
430
  StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { }
431

    
432
  // Add formatted contents to the builder just like printf().
433
  void AddFormatted(const char* format, ...);
434

    
435
  // Add formatted contents like printf based on a va_list.
436
  void AddFormattedList(const char* format, va_list list);
437
 private:
438
  DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
439
};
440

    
441
} }  // namespace v8::internal
442

    
443
#endif  // V8_V8UTILS_H_