| OLD | NEW | 
 | (Empty) | 
|    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 #define PRINTF_METHOD_CHECKING |  | 
|   48 #define FPRINTF_METHOD_CHECKING |  | 
|   49 #else  // MacOsX. |  | 
|   50 #define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2))) |  | 
|   51 #define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3))) |  | 
|   52 #define PRINTF_METHOD_CHECKING __attribute__ ((format (printf, 2, 3))) |  | 
|   53 #define FPRINTF_METHOD_CHECKING __attribute__ ((format (printf, 3, 4))) |  | 
|   54 #endif |  | 
|   55 #else |  | 
|   56 #define PRINTF_CHECKING |  | 
|   57 #define FPRINTF_CHECKING |  | 
|   58 #define PRINTF_METHOD_CHECKING |  | 
|   59 #define FPRINTF_METHOD_CHECKING |  | 
|   60 #endif |  | 
|   61  |  | 
|   62 // Our version of printf(). |  | 
|   63 void PRINTF_CHECKING PrintF(const char* format, ...); |  | 
|   64 void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...); |  | 
|   65  |  | 
|   66 // Prepends the current process ID to the output. |  | 
|   67 void PRINTF_CHECKING PrintPID(const char* format, ...); |  | 
|   68  |  | 
|   69 // Our version of fflush. |  | 
|   70 void Flush(FILE* out); |  | 
|   71  |  | 
|   72 inline void Flush() { |  | 
|   73   Flush(stdout); |  | 
|   74 } |  | 
|   75  |  | 
|   76  |  | 
|   77 // Read a line of characters after printing the prompt to stdout. The resulting |  | 
|   78 // char* needs to be disposed off with DeleteArray by the caller. |  | 
|   79 char* ReadLine(const char* prompt); |  | 
|   80  |  | 
|   81  |  | 
|   82 // Read and return the raw bytes in a file. the size of the buffer is returned |  | 
|   83 // in size. |  | 
|   84 // The returned buffer must be freed by the caller. |  | 
|   85 byte* ReadBytes(const char* filename, int* size, bool verbose = true); |  | 
|   86  |  | 
|   87  |  | 
|   88 // Append size chars from str to the file given by filename. |  | 
|   89 // The file is overwritten. Returns the number of chars written. |  | 
|   90 int AppendChars(const char* filename, |  | 
|   91                 const char* str, |  | 
|   92                 int size, |  | 
|   93                 bool verbose = true); |  | 
|   94  |  | 
|   95  |  | 
|   96 // Write size chars from str to the file given by filename. |  | 
|   97 // The file is overwritten. Returns the number of chars written. |  | 
|   98 int WriteChars(const char* filename, |  | 
|   99                const char* str, |  | 
|  100                int size, |  | 
|  101                bool verbose = true); |  | 
|  102  |  | 
|  103  |  | 
|  104 // Write size bytes to the file given by filename. |  | 
|  105 // The file is overwritten. Returns the number of bytes written. |  | 
|  106 int WriteBytes(const char* filename, |  | 
|  107                const byte* bytes, |  | 
|  108                int size, |  | 
|  109                bool verbose = true); |  | 
|  110  |  | 
|  111  |  | 
|  112 // Write the C code |  | 
|  113 // const char* <varname> = "<str>"; |  | 
|  114 // const int <varname>_len = <len>; |  | 
|  115 // to the file given by filename. Only the first len chars are written. |  | 
|  116 int WriteAsCFile(const char* filename, const char* varname, |  | 
|  117                  const char* str, int size, bool verbose = true); |  | 
|  118  |  | 
|  119  |  | 
|  120 // ---------------------------------------------------------------------------- |  | 
|  121 // Data structures |  | 
|  122  |  | 
|  123 template <typename T> |  | 
|  124 inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms, |  | 
|  125                                              int length) { |  | 
|  126   return Vector< Handle<Object> >( |  | 
|  127       reinterpret_cast<v8::internal::Handle<Object>*>(elms), length); |  | 
|  128 } |  | 
|  129  |  | 
|  130  |  | 
|  131 // ---------------------------------------------------------------------------- |  | 
|  132 // Memory |  | 
|  133  |  | 
|  134 // Copies words from |src| to |dst|. The data spans must not overlap. |  | 
|  135 template <typename T> |  | 
|  136 inline void CopyWords(T* dst, const T* src, size_t num_words) { |  | 
|  137   STATIC_ASSERT(sizeof(T) == kPointerSize); |  | 
|  138   ASSERT(Min(dst, const_cast<T*>(src)) + num_words <= |  | 
|  139          Max(dst, const_cast<T*>(src))); |  | 
|  140   ASSERT(num_words > 0); |  | 
|  141  |  | 
|  142   // Use block copying OS::MemCopy if the segment we're copying is |  | 
|  143   // enough to justify the extra call/setup overhead. |  | 
|  144   static const size_t kBlockCopyLimit = 16; |  | 
|  145  |  | 
|  146   if (num_words < kBlockCopyLimit) { |  | 
|  147     do { |  | 
|  148       num_words--; |  | 
|  149       *dst++ = *src++; |  | 
|  150     } while (num_words > 0); |  | 
|  151   } else { |  | 
|  152     OS::MemCopy(dst, src, num_words * kPointerSize); |  | 
|  153   } |  | 
|  154 } |  | 
|  155  |  | 
|  156  |  | 
|  157 // Copies words from |src| to |dst|. No restrictions. |  | 
|  158 template <typename T> |  | 
|  159 inline void MoveWords(T* dst, const T* src, size_t num_words) { |  | 
|  160   STATIC_ASSERT(sizeof(T) == kPointerSize); |  | 
|  161   ASSERT(num_words > 0); |  | 
|  162  |  | 
|  163   // Use block copying OS::MemCopy if the segment we're copying is |  | 
|  164   // enough to justify the extra call/setup overhead. |  | 
|  165   static const size_t kBlockCopyLimit = 16; |  | 
|  166  |  | 
|  167   if (num_words < kBlockCopyLimit && |  | 
|  168       ((dst < src) || (dst >= (src + num_words * kPointerSize)))) { |  | 
|  169     T* end = dst + num_words; |  | 
|  170     do { |  | 
|  171       num_words--; |  | 
|  172       *dst++ = *src++; |  | 
|  173     } while (num_words > 0); |  | 
|  174   } else { |  | 
|  175     OS::MemMove(dst, src, num_words * kPointerSize); |  | 
|  176   } |  | 
|  177 } |  | 
|  178  |  | 
|  179  |  | 
|  180 // Copies data from |src| to |dst|.  The data spans must not overlap. |  | 
|  181 template <typename T> |  | 
|  182 inline void CopyBytes(T* dst, const T* src, size_t num_bytes) { |  | 
|  183   STATIC_ASSERT(sizeof(T) == 1); |  | 
|  184   ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <= |  | 
|  185          Max(dst, const_cast<T*>(src))); |  | 
|  186   if (num_bytes == 0) return; |  | 
|  187  |  | 
|  188   // Use block copying OS::MemCopy if the segment we're copying is |  | 
|  189   // enough to justify the extra call/setup overhead. |  | 
|  190   static const int kBlockCopyLimit = OS::kMinComplexMemCopy; |  | 
|  191  |  | 
|  192   if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) { |  | 
|  193     do { |  | 
|  194       num_bytes--; |  | 
|  195       *dst++ = *src++; |  | 
|  196     } while (num_bytes > 0); |  | 
|  197   } else { |  | 
|  198     OS::MemCopy(dst, src, num_bytes); |  | 
|  199   } |  | 
|  200 } |  | 
|  201  |  | 
|  202  |  | 
|  203 template <typename T, typename U> |  | 
|  204 inline void MemsetPointer(T** dest, U* value, int counter) { |  | 
|  205 #ifdef DEBUG |  | 
|  206   T* a = NULL; |  | 
|  207   U* b = NULL; |  | 
|  208   a = b;  // Fake assignment to check assignability. |  | 
|  209   USE(a); |  | 
|  210 #endif  // DEBUG |  | 
|  211 #if V8_HOST_ARCH_IA32 |  | 
|  212 #define STOS "stosl" |  | 
|  213 #elif V8_HOST_ARCH_X64 |  | 
|  214 #define STOS "stosq" |  | 
|  215 #endif |  | 
|  216 #if defined(__native_client__) |  | 
|  217   // This STOS sequence does not validate for x86_64 Native Client. |  | 
|  218   // Here we #undef STOS to force use of the slower C version. |  | 
|  219   // TODO(bradchen): Profile V8 and implement a faster REP STOS |  | 
|  220   // here if the profile indicates it matters. |  | 
|  221 #undef STOS |  | 
|  222 #endif |  | 
|  223  |  | 
|  224 #if defined(MEMORY_SANITIZER) |  | 
|  225   // MemorySanitizer does not understand inline assembly. |  | 
|  226 #undef STOS |  | 
|  227 #endif |  | 
|  228  |  | 
|  229 #if defined(__GNUC__) && defined(STOS) |  | 
|  230   asm volatile( |  | 
|  231       "cld;" |  | 
|  232       "rep ; " STOS |  | 
|  233       : "+&c" (counter), "+&D" (dest) |  | 
|  234       : "a" (value) |  | 
|  235       : "memory", "cc"); |  | 
|  236 #else |  | 
|  237   for (int i = 0; i < counter; i++) { |  | 
|  238     dest[i] = value; |  | 
|  239   } |  | 
|  240 #endif |  | 
|  241  |  | 
|  242 #undef STOS |  | 
|  243 } |  | 
|  244  |  | 
|  245  |  | 
|  246 // Simple wrapper that allows an ExternalString to refer to a |  | 
|  247 // Vector<const char>. Doesn't assume ownership of the data. |  | 
|  248 class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource { |  | 
|  249  public: |  | 
|  250   explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {} |  | 
|  251  |  | 
|  252   virtual const char* data() const { return data_.start(); } |  | 
|  253  |  | 
|  254   virtual size_t length() const { return data_.length(); } |  | 
|  255  |  | 
|  256  private: |  | 
|  257   Vector<const char> data_; |  | 
|  258 }; |  | 
|  259  |  | 
|  260  |  | 
|  261 // Simple support to read a file into a 0-terminated C-string. |  | 
|  262 // The returned buffer must be freed by the caller. |  | 
|  263 // On return, *exits tells whether the file existed. |  | 
|  264 Vector<const char> ReadFile(const char* filename, |  | 
|  265                             bool* exists, |  | 
|  266                             bool verbose = true); |  | 
|  267 Vector<const char> ReadFile(FILE* file, |  | 
|  268                             bool* exists, |  | 
|  269                             bool verbose = true); |  | 
|  270  |  | 
|  271  |  | 
|  272 template <typename sourcechar, typename sinkchar> |  | 
|  273 INLINE(static void CopyCharsUnsigned(sinkchar* dest, |  | 
|  274                                      const sourcechar* src, |  | 
|  275                                      int chars)); |  | 
|  276 #if defined(V8_HOST_ARCH_ARM) |  | 
|  277 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars)); |  | 
|  278 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars)); |  | 
|  279 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars)); |  | 
|  280 #elif defined(V8_HOST_ARCH_MIPS) |  | 
|  281 INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars)); |  | 
|  282 INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars)); |  | 
|  283 #endif |  | 
|  284  |  | 
|  285 // Copy from ASCII/16bit chars to ASCII/16bit chars. |  | 
|  286 template <typename sourcechar, typename sinkchar> |  | 
|  287 INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars)); |  | 
|  288  |  | 
|  289 template<typename sourcechar, typename sinkchar> |  | 
|  290 void CopyChars(sinkchar* dest, const sourcechar* src, int chars) { |  | 
|  291   ASSERT(sizeof(sourcechar) <= 2); |  | 
|  292   ASSERT(sizeof(sinkchar) <= 2); |  | 
|  293   if (sizeof(sinkchar) == 1) { |  | 
|  294     if (sizeof(sourcechar) == 1) { |  | 
|  295       CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), |  | 
|  296                         reinterpret_cast<const uint8_t*>(src), |  | 
|  297                         chars); |  | 
|  298     } else { |  | 
|  299       CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest), |  | 
|  300                         reinterpret_cast<const uint16_t*>(src), |  | 
|  301                         chars); |  | 
|  302     } |  | 
|  303   } else { |  | 
|  304     if (sizeof(sourcechar) == 1) { |  | 
|  305       CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest), |  | 
|  306                         reinterpret_cast<const uint8_t*>(src), |  | 
|  307                         chars); |  | 
|  308     } else { |  | 
|  309       CopyCharsUnsigned(reinterpret_cast<uint16_t*>(dest), |  | 
|  310                         reinterpret_cast<const uint16_t*>(src), |  | 
|  311                         chars); |  | 
|  312     } |  | 
|  313   } |  | 
|  314 } |  | 
|  315  |  | 
|  316 template <typename sourcechar, typename sinkchar> |  | 
|  317 void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) { |  | 
|  318   sinkchar* limit = dest + chars; |  | 
|  319 #ifdef V8_HOST_CAN_READ_UNALIGNED |  | 
|  320   if (sizeof(*dest) == sizeof(*src)) { |  | 
|  321     if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) { |  | 
|  322       OS::MemCopy(dest, src, chars * sizeof(*dest)); |  | 
|  323       return; |  | 
|  324     } |  | 
|  325     // Number of characters in a uintptr_t. |  | 
|  326     static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest);  // NOLINT |  | 
|  327     ASSERT(dest + kStepSize > dest);  // Check for overflow. |  | 
|  328     while (dest + kStepSize <= limit) { |  | 
|  329       *reinterpret_cast<uintptr_t*>(dest) = |  | 
|  330           *reinterpret_cast<const uintptr_t*>(src); |  | 
|  331       dest += kStepSize; |  | 
|  332       src += kStepSize; |  | 
|  333     } |  | 
|  334   } |  | 
|  335 #endif |  | 
|  336   while (dest < limit) { |  | 
|  337     *dest++ = static_cast<sinkchar>(*src++); |  | 
|  338   } |  | 
|  339 } |  | 
|  340  |  | 
|  341  |  | 
|  342 #if defined(V8_HOST_ARCH_ARM) |  | 
|  343 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) { |  | 
|  344   switch (static_cast<unsigned>(chars)) { |  | 
|  345     case 0: |  | 
|  346       break; |  | 
|  347     case 1: |  | 
|  348       *dest = *src; |  | 
|  349       break; |  | 
|  350     case 2: |  | 
|  351       memcpy(dest, src, 2); |  | 
|  352       break; |  | 
|  353     case 3: |  | 
|  354       memcpy(dest, src, 3); |  | 
|  355       break; |  | 
|  356     case 4: |  | 
|  357       memcpy(dest, src, 4); |  | 
|  358       break; |  | 
|  359     case 5: |  | 
|  360       memcpy(dest, src, 5); |  | 
|  361       break; |  | 
|  362     case 6: |  | 
|  363       memcpy(dest, src, 6); |  | 
|  364       break; |  | 
|  365     case 7: |  | 
|  366       memcpy(dest, src, 7); |  | 
|  367       break; |  | 
|  368     case 8: |  | 
|  369       memcpy(dest, src, 8); |  | 
|  370       break; |  | 
|  371     case 9: |  | 
|  372       memcpy(dest, src, 9); |  | 
|  373       break; |  | 
|  374     case 10: |  | 
|  375       memcpy(dest, src, 10); |  | 
|  376       break; |  | 
|  377     case 11: |  | 
|  378       memcpy(dest, src, 11); |  | 
|  379       break; |  | 
|  380     case 12: |  | 
|  381       memcpy(dest, src, 12); |  | 
|  382       break; |  | 
|  383     case 13: |  | 
|  384       memcpy(dest, src, 13); |  | 
|  385       break; |  | 
|  386     case 14: |  | 
|  387       memcpy(dest, src, 14); |  | 
|  388       break; |  | 
|  389     case 15: |  | 
|  390       memcpy(dest, src, 15); |  | 
|  391       break; |  | 
|  392     default: |  | 
|  393       OS::MemCopy(dest, src, chars); |  | 
|  394       break; |  | 
|  395   } |  | 
|  396 } |  | 
|  397  |  | 
|  398  |  | 
|  399 void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) { |  | 
|  400   if (chars >= OS::kMinComplexConvertMemCopy) { |  | 
|  401     OS::MemCopyUint16Uint8(dest, src, chars); |  | 
|  402   } else { |  | 
|  403     OS::MemCopyUint16Uint8Wrapper(dest, src, chars); |  | 
|  404   } |  | 
|  405 } |  | 
|  406  |  | 
|  407  |  | 
|  408 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) { |  | 
|  409   switch (static_cast<unsigned>(chars)) { |  | 
|  410     case 0: |  | 
|  411       break; |  | 
|  412     case 1: |  | 
|  413       *dest = *src; |  | 
|  414       break; |  | 
|  415     case 2: |  | 
|  416       memcpy(dest, src, 4); |  | 
|  417       break; |  | 
|  418     case 3: |  | 
|  419       memcpy(dest, src, 6); |  | 
|  420       break; |  | 
|  421     case 4: |  | 
|  422       memcpy(dest, src, 8); |  | 
|  423       break; |  | 
|  424     case 5: |  | 
|  425       memcpy(dest, src, 10); |  | 
|  426       break; |  | 
|  427     case 6: |  | 
|  428       memcpy(dest, src, 12); |  | 
|  429       break; |  | 
|  430     case 7: |  | 
|  431       memcpy(dest, src, 14); |  | 
|  432       break; |  | 
|  433     default: |  | 
|  434       OS::MemCopy(dest, src, chars * sizeof(*dest)); |  | 
|  435       break; |  | 
|  436   } |  | 
|  437 } |  | 
|  438  |  | 
|  439  |  | 
|  440 #elif defined(V8_HOST_ARCH_MIPS) |  | 
|  441 void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) { |  | 
|  442   if (chars < OS::kMinComplexMemCopy) { |  | 
|  443     memcpy(dest, src, chars); |  | 
|  444   } else { |  | 
|  445     OS::MemCopy(dest, src, chars); |  | 
|  446   } |  | 
|  447 } |  | 
|  448  |  | 
|  449 void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) { |  | 
|  450   if (chars < OS::kMinComplexMemCopy) { |  | 
|  451     memcpy(dest, src, chars * sizeof(*dest)); |  | 
|  452   } else { |  | 
|  453     OS::MemCopy(dest, src, chars * sizeof(*dest)); |  | 
|  454   } |  | 
|  455 } |  | 
|  456 #endif |  | 
|  457  |  | 
|  458  |  | 
|  459 class StringBuilder : public SimpleStringBuilder { |  | 
|  460  public: |  | 
|  461   explicit StringBuilder(int size) : SimpleStringBuilder(size) { } |  | 
|  462   StringBuilder(char* buffer, int size) : SimpleStringBuilder(buffer, size) { } |  | 
|  463  |  | 
|  464   // Add formatted contents to the builder just like printf(). |  | 
|  465   void AddFormatted(const char* format, ...); |  | 
|  466  |  | 
|  467   // Add formatted contents like printf based on a va_list. |  | 
|  468   void AddFormattedList(const char* format, va_list list); |  | 
|  469  private: |  | 
|  470   DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder); |  | 
|  471 }; |  | 
|  472  |  | 
|  473 } }  // namespace v8::internal |  | 
|  474  |  | 
|  475 #endif  // V8_V8UTILS_H_ |  | 
| OLD | NEW |