Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1204)

Side by Side Diff: src/utils.h

Issue 4485001: Split utils.h into utils.h and v8utils.h where the former is independent of V8. (Closed)
Patch Set: Addressed review comments. Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/utils.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_UTILS_H_ 28 #ifndef V8_UTILS_H_
29 #define V8_UTILS_H_ 29 #define V8_UTILS_H_
30 30
31 #include <stdlib.h> 31 #include <stdlib.h>
32 #include <string.h> 32 #include <string.h>
33 33
34 #include "checks.h"
35
34 namespace v8 { 36 namespace v8 {
35 namespace internal { 37 namespace internal {
36 38
37 // ---------------------------------------------------------------------------- 39 // ----------------------------------------------------------------------------
38 // General helper functions 40 // General helper functions
39 41
40 #define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0) 42 #define IS_POWER_OF_TWO(x) (((x) & ((x) - 1)) == 0)
41 43
42 // Returns true iff x is a power of 2 (or zero). Cannot be used with the 44 // Returns true iff x is a power of 2 (or zero). Cannot be used with the
43 // maximally negative value of the type T (the -1 overflows). 45 // maximally negative value of the type T (the -1 overflows).
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 137
136 138
137 template <typename T> 139 template <typename T>
138 static int PointerValueCompare(const T* a, const T* b) { 140 static int PointerValueCompare(const T* a, const T* b) {
139 return Compare<T>(*a, *b); 141 return Compare<T>(*a, *b);
140 } 142 }
141 143
142 144
143 // Returns the smallest power of two which is >= x. If you pass in a 145 // Returns the smallest power of two which is >= x. If you pass in a
144 // number that is already a power of two, it is returned as is. 146 // number that is already a power of two, it is returned as is.
145 uint32_t RoundUpToPowerOf2(uint32_t x); 147 // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
148 // figure 3-3, page 48, where the function is called clp2.
149 static inline uint32_t RoundUpToPowerOf2(uint32_t x) {
150 ASSERT(x <= 0x80000000u);
151 x = x - 1;
152 x = x | (x >> 1);
153 x = x | (x >> 2);
154 x = x | (x >> 4);
155 x = x | (x >> 8);
156 x = x | (x >> 16);
157 return x + 1;
158 }
159
146 160
147 161
148 template <typename T> 162 template <typename T>
149 static inline bool IsAligned(T value, T alignment) { 163 static inline bool IsAligned(T value, T alignment) {
150 ASSERT(IsPowerOf2(alignment)); 164 ASSERT(IsPowerOf2(alignment));
151 return (value & (alignment - 1)) == 0; 165 return (value & (alignment - 1)) == 0;
152 } 166 }
153 167
154 168
155 // Returns true if (addr + offset) is aligned. 169 // Returns true if (addr + offset) is aligned.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 // Extracts the bit field from the value. 223 // Extracts the bit field from the value.
210 static T decode(uint32_t value) { 224 static T decode(uint32_t value) {
211 return static_cast<T>((value & mask()) >> shift); 225 return static_cast<T>((value & mask()) >> shift);
212 } 226 }
213 }; 227 };
214 228
215 229
216 // ---------------------------------------------------------------------------- 230 // ----------------------------------------------------------------------------
217 // Hash function. 231 // Hash function.
218 232
219 uint32_t ComputeIntegerHash(uint32_t key); 233 // Thomas Wang, Integer Hash Functions.
234 // http://www.concentric.net/~Ttwang/tech/inthash.htm
235 static inline uint32_t ComputeIntegerHash(uint32_t key) {
236 uint32_t hash = key;
237 hash = ~hash + (hash << 15); // hash = (hash << 15) - hash - 1;
238 hash = hash ^ (hash >> 12);
239 hash = hash + (hash << 2);
240 hash = hash ^ (hash >> 4);
241 hash = hash * 2057; // hash = (hash + (hash << 3)) + (hash << 11);
242 hash = hash ^ (hash >> 16);
243 return hash;
244 }
220 245
221 246
222 // ---------------------------------------------------------------------------- 247 // ----------------------------------------------------------------------------
223 // I/O support.
224
225 #if __GNUC__ >= 4
226 // On gcc we can ask the compiler to check the types of %d-style format
227 // specifiers and their associated arguments. TODO(erikcorry) fix this
228 // so it works on MacOSX.
229 #if defined(__MACH__) && defined(__APPLE__)
230 #define PRINTF_CHECKING
231 #else // MacOsX.
232 #define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
233 #endif
234 #else
235 #define PRINTF_CHECKING
236 #endif
237
238 // Our version of printf().
239 void PRINTF_CHECKING PrintF(const char* format, ...);
240
241 // Our version of fflush.
242 void Flush();
243
244
245 // Read a line of characters after printing the prompt to stdout. The resulting
246 // char* needs to be disposed off with DeleteArray by the caller.
247 char* ReadLine(const char* prompt);
248
249
250 // Read and return the raw bytes in a file. the size of the buffer is returned
251 // in size.
252 // The returned buffer must be freed by the caller.
253 byte* ReadBytes(const char* filename, int* size, bool verbose = true);
254
255
256 // Write size chars from str to the file given by filename.
257 // The file is overwritten. Returns the number of chars written.
258 int WriteChars(const char* filename,
259 const char* str,
260 int size,
261 bool verbose = true);
262
263
264 // Write size bytes to the file given by filename.
265 // The file is overwritten. Returns the number of bytes written.
266 int WriteBytes(const char* filename,
267 const byte* bytes,
268 int size,
269 bool verbose = true);
270
271
272 // Write the C code
273 // const char* <varname> = "<str>";
274 // const int <varname>_len = <len>;
275 // to the file given by filename. Only the first len chars are written.
276 int WriteAsCFile(const char* filename, const char* varname,
277 const char* str, int size, bool verbose = true);
278
279
280 // ----------------------------------------------------------------------------
281 // Miscellaneous 248 // Miscellaneous
282 249
283 // A static resource holds a static instance that can be reserved in 250 // A static resource holds a static instance that can be reserved in
284 // a local scope using an instance of Access. Attempts to re-reserve 251 // a local scope using an instance of Access. Attempts to re-reserve
285 // the instance will cause an error. 252 // the instance will cause an error.
286 template <typename T> 253 template <typename T>
287 class StaticResource { 254 class StaticResource {
288 public: 255 public:
289 StaticResource() : is_reserved_(false) {} 256 StaticResource() : is_reserved_(false) {}
290 257
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 376
410 protected: 377 protected:
411 void set_start(T* start) { start_ = start; } 378 void set_start(T* start) { start_ = start; }
412 379
413 private: 380 private:
414 T* start_; 381 T* start_;
415 int length_; 382 int length_;
416 }; 383 };
417 384
418 385
419 // A temporary assignment sets a (non-local) variable to a value on
420 // construction and resets it the value on destruction.
421 template <typename T>
422 class TempAssign {
423 public:
424 TempAssign(T* var, T value): var_(var), old_value_(*var) {
425 *var = value;
426 }
427
428 ~TempAssign() { *var_ = old_value_; }
429
430 private:
431 T* var_;
432 T old_value_;
433 };
434
435
436 template <typename T, int kSize> 386 template <typename T, int kSize>
437 class EmbeddedVector : public Vector<T> { 387 class EmbeddedVector : public Vector<T> {
438 public: 388 public:
439 EmbeddedVector() : Vector<T>(buffer_, kSize) { } 389 EmbeddedVector() : Vector<T>(buffer_, kSize) { }
440 390
441 // When copying, make underlying Vector to reference our buffer. 391 // When copying, make underlying Vector to reference our buffer.
442 EmbeddedVector(const EmbeddedVector& rhs) 392 EmbeddedVector(const EmbeddedVector& rhs)
443 : Vector<T>(rhs) { 393 : Vector<T>(rhs) {
444 memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize); 394 memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
445 set_start(buffer_); 395 set_start(buffer_);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 427
478 inline Vector<char> MutableCStrVector(char* data) { 428 inline Vector<char> MutableCStrVector(char* data) {
479 return Vector<char>(data, StrLength(data)); 429 return Vector<char>(data, StrLength(data));
480 } 430 }
481 431
482 inline Vector<char> MutableCStrVector(char* data, int max) { 432 inline Vector<char> MutableCStrVector(char* data, int max) {
483 int length = StrLength(data); 433 int length = StrLength(data);
484 return Vector<char>(data, (length < max) ? length : max); 434 return Vector<char>(data, (length < max) ? length : max);
485 } 435 }
486 436
487 template <typename T>
488 inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
489 int length) {
490 return Vector< Handle<Object> >(
491 reinterpret_cast<v8::internal::Handle<Object>*>(elms), length);
492 }
493
494 437
495 /* 438 /*
496 * A class that collects values into a backing store. 439 * A class that collects values into a backing store.
497 * Specialized versions of the class can allow access to the backing store 440 * Specialized versions of the class can allow access to the backing store
498 * in different ways. 441 * in different ways.
499 * There is no guarantee that the backing store is contiguous (and, as a 442 * There is no guarantee that the backing store is contiguous (and, as a
500 * consequence, no guarantees that consecutively added elements are adjacent 443 * consequence, no guarantees that consecutively added elements are adjacent
501 * in memory). The collector may move elements unless it has guaranteed not 444 * in memory). The collector may move elements unless it has guaranteed not
502 * to. 445 * to.
503 */ 446 */
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 635 }
693 this->index_ = sequence_start_; 636 this->index_ = sequence_start_;
694 sequence_start_ = 0; 637 sequence_start_ = 0;
695 return sequence_length; 638 return sequence_length;
696 } 639 }
697 return 0; 640 return 0;
698 } 641 }
699 }; 642 };
700 643
701 644
702 // Simple support to read a file into a 0-terminated C-string.
703 // The returned buffer must be freed by the caller.
704 // On return, *exits tells whether the file existed.
705 Vector<const char> ReadFile(const char* filename,
706 bool* exists,
707 bool verbose = true);
708
709
710 // Simple wrapper that allows an ExternalString to refer to a
711 // Vector<const char>. Doesn't assume ownership of the data.
712 class AsciiStringAdapter: public v8::String::ExternalAsciiStringResource {
713 public:
714 explicit AsciiStringAdapter(Vector<const char> data) : data_(data) {}
715
716 virtual const char* data() const { return data_.start(); }
717
718 virtual size_t length() const { return data_.length(); }
719
720 private:
721 Vector<const char> data_;
722 };
723
724
725 // Helper class for building result strings in a character buffer. The
726 // purpose of the class is to use safe operations that checks the
727 // buffer bounds on all operations in debug mode.
728 class StringBuilder {
729 public:
730 // Create a string builder with a buffer of the given size. The
731 // buffer is allocated through NewArray<char> and must be
732 // deallocated by the caller of Finalize().
733 explicit StringBuilder(int size);
734
735 StringBuilder(char* buffer, int size)
736 : buffer_(buffer, size), position_(0) { }
737
738 ~StringBuilder() { if (!is_finalized()) Finalize(); }
739
740 int size() const { return buffer_.length(); }
741
742 // Get the current position in the builder.
743 int position() const {
744 ASSERT(!is_finalized());
745 return position_;
746 }
747
748 // Reset the position.
749 void Reset() { position_ = 0; }
750
751 // Add a single character to the builder. It is not allowed to add
752 // 0-characters; use the Finalize() method to terminate the string
753 // instead.
754 void AddCharacter(char c) {
755 ASSERT(c != '\0');
756 ASSERT(!is_finalized() && position_ < buffer_.length());
757 buffer_[position_++] = c;
758 }
759
760 // Add an entire string to the builder. Uses strlen() internally to
761 // compute the length of the input string.
762 void AddString(const char* s);
763
764 // Add the first 'n' characters of the given string 's' to the
765 // builder. The input string must have enough characters.
766 void AddSubstring(const char* s, int n);
767
768 // Add formatted contents to the builder just like printf().
769 void AddFormatted(const char* format, ...);
770
771 // Add character padding to the builder. If count is non-positive,
772 // nothing is added to the builder.
773 void AddPadding(char c, int count);
774
775 // Finalize the string by 0-terminating it and returning the buffer.
776 char* Finalize();
777
778 private:
779 Vector<char> buffer_;
780 int position_;
781
782 bool is_finalized() const { return position_ < 0; }
783
784 DISALLOW_IMPLICIT_CONSTRUCTORS(StringBuilder);
785 };
786
787
788 // Custom memcpy implementation for platforms where the standard version
789 // may not be good enough.
790 // TODO(lrn): Check whether some IA32 platforms should be excluded.
791 #if defined(V8_TARGET_ARCH_IA32)
792
793 // TODO(lrn): Extend to other platforms as needed.
794
795 typedef void (*MemCopyFunction)(void* dest, const void* src, size_t size);
796
797 // Implemented in codegen-<arch>.cc.
798 MemCopyFunction CreateMemCopyFunction();
799
800 // Copy memory area to disjoint memory area.
801 static inline void MemCopy(void* dest, const void* src, size_t size) {
802 static MemCopyFunction memcopy = CreateMemCopyFunction();
803 (*memcopy)(dest, src, size);
804 #ifdef DEBUG
805 CHECK_EQ(0, memcmp(dest, src, size));
806 #endif
807 }
808
809
810 // Limit below which the extra overhead of the MemCopy function is likely
811 // to outweigh the benefits of faster copying.
812 // TODO(lrn): Try to find a more precise value.
813 static const int kMinComplexMemCopy = 64;
814
815 #else // V8_TARGET_ARCH_IA32
816
817 static inline void MemCopy(void* dest, const void* src, size_t size) {
818 memcpy(dest, src, size);
819 }
820
821 static const int kMinComplexMemCopy = 256;
822
823 #endif // V8_TARGET_ARCH_IA32
824
825
826 // Copy from ASCII/16bit chars to ASCII/16bit chars.
827 template <typename sourcechar, typename sinkchar>
828 static inline void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
829 sinkchar* limit = dest + chars;
830 #ifdef V8_HOST_CAN_READ_UNALIGNED
831 if (sizeof(*dest) == sizeof(*src)) {
832 if (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest))) {
833 MemCopy(dest, src, chars * sizeof(*dest));
834 return;
835 }
836 // Number of characters in a uintptr_t.
837 static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT
838 while (dest <= limit - kStepSize) {
839 *reinterpret_cast<uintptr_t*>(dest) =
840 *reinterpret_cast<const uintptr_t*>(src);
841 dest += kStepSize;
842 src += kStepSize;
843 }
844 }
845 #endif
846 while (dest < limit) {
847 *dest++ = static_cast<sinkchar>(*src++);
848 }
849 }
850
851
852 // Compare ASCII/16bit chars to ASCII/16bit chars. 645 // Compare ASCII/16bit chars to ASCII/16bit chars.
853 template <typename lchar, typename rchar> 646 template <typename lchar, typename rchar>
854 static inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) { 647 static inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
855 const lchar* limit = lhs + chars; 648 const lchar* limit = lhs + chars;
856 #ifdef V8_HOST_CAN_READ_UNALIGNED 649 #ifdef V8_HOST_CAN_READ_UNALIGNED
857 if (sizeof(*lhs) == sizeof(*rhs)) { 650 if (sizeof(*lhs) == sizeof(*rhs)) {
858 // Number of characters in a uintptr_t. 651 // Number of characters in a uintptr_t.
859 static const int kStepSize = sizeof(uintptr_t) / sizeof(*lhs); // NOLINT 652 static const int kStepSize = sizeof(uintptr_t) / sizeof(*lhs); // NOLINT
860 while (lhs <= limit - kStepSize) { 653 while (lhs <= limit - kStepSize) {
861 if (*reinterpret_cast<const uintptr_t*>(lhs) != 654 if (*reinterpret_cast<const uintptr_t*>(lhs) !=
862 *reinterpret_cast<const uintptr_t*>(rhs)) { 655 *reinterpret_cast<const uintptr_t*>(rhs)) {
863 break; 656 break;
864 } 657 }
865 lhs += kStepSize; 658 lhs += kStepSize;
866 rhs += kStepSize; 659 rhs += kStepSize;
867 } 660 }
868 } 661 }
869 #endif 662 #endif
870 while (lhs < limit) { 663 while (lhs < limit) {
871 int r = static_cast<int>(*lhs) - static_cast<int>(*rhs); 664 int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
872 if (r != 0) return r; 665 if (r != 0) return r;
873 ++lhs; 666 ++lhs;
874 ++rhs; 667 ++rhs;
875 } 668 }
876 return 0; 669 return 0;
877 } 670 }
878 671
879 672
880 template <typename T>
881 static inline void MemsetPointer(T** dest, T* value, int counter) {
882 #if defined(V8_HOST_ARCH_IA32)
883 #define STOS "stosl"
884 #elif defined(V8_HOST_ARCH_X64)
885 #define STOS "stosq"
886 #endif
887
888 #if defined(__GNUC__) && defined(STOS)
889 asm volatile(
890 "cld;"
891 "rep ; " STOS
892 : "+&c" (counter), "+&D" (dest)
893 : "a" (value)
894 : "memory", "cc");
895 #else
896 for (int i = 0; i < counter; i++) {
897 dest[i] = value;
898 }
899 #endif
900
901 #undef STOS
902 }
903
904
905 // Copies data from |src| to |dst|. The data spans MUST not overlap.
906 inline void CopyWords(Object** dst, Object** src, int num_words) {
907 ASSERT(Min(dst, src) + num_words <= Max(dst, src));
908 ASSERT(num_words > 0);
909
910 // Use block copying memcpy if the segment we're copying is
911 // enough to justify the extra call/setup overhead.
912 static const int kBlockCopyLimit = 16;
913
914 if (num_words >= kBlockCopyLimit) {
915 memcpy(dst, src, num_words * kPointerSize);
916 } else {
917 int remaining = num_words;
918 do {
919 remaining--;
920 *dst++ = *src++;
921 } while (remaining > 0);
922 }
923 }
924
925
926 // Calculate 10^exponent. 673 // Calculate 10^exponent.
927 int TenToThe(int exponent); 674 static inline int TenToThe(int exponent) {
675 ASSERT(exponent <= 9);
676 ASSERT(exponent >= 1);
677 int answer = 10;
678 for (int i = 1; i < exponent; i++) answer *= 10;
679 return answer;
680 }
928 681
929 682
930 // The type-based aliasing rule allows the compiler to assume that pointers of 683 // The type-based aliasing rule allows the compiler to assume that pointers of
931 // different types (for some definition of different) never alias each other. 684 // different types (for some definition of different) never alias each other.
932 // Thus the following code does not work: 685 // Thus the following code does not work:
933 // 686 //
934 // float f = foo(); 687 // float f = foo();
935 // int fbits = *(int*)(&f); 688 // int fbits = *(int*)(&f);
936 // 689 //
937 // The compiler 'knows' that the int pointer can't refer to f since the types 690 // The compiler 'knows' that the int pointer can't refer to f since the types
(...skipping 25 matching lines...) Expand all
963 } 716 }
964 717
965 template <class Dest, class Source> 718 template <class Dest, class Source>
966 inline Dest BitCast(Source* source) { 719 inline Dest BitCast(Source* source) {
967 return BitCast<Dest>(reinterpret_cast<uintptr_t>(source)); 720 return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
968 } 721 }
969 722
970 } } // namespace v8::internal 723 } } // namespace v8::internal
971 724
972 #endif // V8_UTILS_H_ 725 #endif // V8_UTILS_H_
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/utils.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698