summaryrefslogtreecommitdiff
path: root/deps/v8/src/utils.h
diff options
context:
space:
mode:
authorRefael Ackermann <refack@gmail.com>2014-09-29 13:20:04 +0400
committerFedor Indutny <fedor@indutny.com>2014-10-08 15:44:38 +0400
commit9116b240c924d37627313416b7ee038d0580afbc (patch)
tree86c586915a96d308b1b04de679a8ae293caf3e41 /deps/v8/src/utils.h
parenta2a3fd48934f36d94575dd33d2a2cb732f937f77 (diff)
downloadnode-9116b240c924d37627313416b7ee038d0580afbc.tar.gz
deps: update v8 to 3.28.73
Reviewed-By: Fedor Indutny <fedor@indutny.com> PR-URL: https://github.com/joyent/node/pull/8476
Diffstat (limited to 'deps/v8/src/utils.h')
-rw-r--r--deps/v8/src/utils.h359
1 files changed, 211 insertions, 148 deletions
diff --git a/deps/v8/src/utils.h b/deps/v8/src/utils.h
index 115f78475..c5012bbc2 100644
--- a/deps/v8/src/utils.h
+++ b/deps/v8/src/utils.h
@@ -8,12 +8,16 @@
#include <limits.h>
#include <stdlib.h>
#include <string.h>
+#include <cmath>
-#include "allocation.h"
-#include "checks.h"
-#include "globals.h"
-#include "platform.h"
-#include "vector.h"
+#include "include/v8.h"
+#include "src/allocation.h"
+#include "src/base/logging.h"
+#include "src/base/macros.h"
+#include "src/base/platform/platform.h"
+#include "src/globals.h"
+#include "src/list.h"
+#include "src/vector.h"
namespace v8 {
namespace internal {
@@ -21,19 +25,9 @@ namespace internal {
// ----------------------------------------------------------------------------
// General helper functions
-#define IS_POWER_OF_TWO(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
-
-// Returns true iff x is a power of 2. Cannot be used with the maximally
-// negative value of the type T (the -1 overflows).
-template <typename T>
-inline bool IsPowerOf2(T x) {
- return IS_POWER_OF_TWO(x);
-}
-
-
// X must be a power of 2. Returns the number of trailing zeros.
inline int WhichPowerOf2(uint32_t x) {
- ASSERT(IsPowerOf2(x));
+ DCHECK(IsPowerOf2(x));
int bits = 0;
#ifdef DEBUG
int original_x = x;
@@ -57,7 +51,7 @@ inline int WhichPowerOf2(uint32_t x) {
case 2: bits++; // Fall through.
case 1: break;
}
- ASSERT_EQ(1 << bits, original_x);
+ DCHECK_EQ(1 << bits, original_x);
return bits;
return 0;
}
@@ -90,50 +84,6 @@ inline int ArithmeticShiftRight(int x, int s) {
}
-// Compute the 0-relative offset of some absolute value x of type T.
-// This allows conversion of Addresses and integral types into
-// 0-relative int offsets.
-template <typename T>
-inline intptr_t OffsetFrom(T x) {
- return x - static_cast<T>(0);
-}
-
-
-// Compute the absolute value of type T for some 0-relative offset x.
-// This allows conversion of 0-relative int offsets into Addresses and
-// integral types.
-template <typename T>
-inline T AddressFrom(intptr_t x) {
- return static_cast<T>(static_cast<T>(0) + x);
-}
-
-
-// Return the largest multiple of m which is <= x.
-template <typename T>
-inline T RoundDown(T x, intptr_t m) {
- ASSERT(IsPowerOf2(m));
- return AddressFrom<T>(OffsetFrom(x) & -m);
-}
-
-
-// Return the smallest multiple of m which is >= x.
-template <typename T>
-inline T RoundUp(T x, intptr_t m) {
- return RoundDown<T>(static_cast<T>(x + m - 1), m);
-}
-
-
-// Increment a pointer until it has the specified alignment.
-// This works like RoundUp, but it works correctly on pointer types where
-// sizeof(*pointer) might not be 1.
-template<class T>
-T AlignUp(T pointer, size_t alignment) {
- ASSERT(sizeof(pointer) == sizeof(uintptr_t));
- uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
- return reinterpret_cast<T>(RoundUp(pointer_raw, alignment));
-}
-
-
template <typename T>
int Compare(const T& a, const T& b) {
if (a == b)
@@ -161,35 +111,6 @@ int HandleObjectPointerCompare(const Handle<T>* a, const Handle<T>* b) {
}
-// Returns the smallest power of two which is >= x. If you pass in a
-// number that is already a power of two, it is returned as is.
-// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
-// figure 3-3, page 48, where the function is called clp2.
-inline uint32_t RoundUpToPowerOf2(uint32_t x) {
- ASSERT(x <= 0x80000000u);
- x = x - 1;
- x = x | (x >> 1);
- x = x | (x >> 2);
- x = x | (x >> 4);
- x = x | (x >> 8);
- x = x | (x >> 16);
- return x + 1;
-}
-
-
-inline uint32_t RoundDownToPowerOf2(uint32_t x) {
- uint32_t rounded_up = RoundUpToPowerOf2(x);
- if (rounded_up > x) return rounded_up >> 1;
- return rounded_up;
-}
-
-
-template <typename T, typename U>
-inline bool IsAligned(T value, U alignment) {
- return (value & (alignment - 1)) == 0;
-}
-
-
// Returns true if (addr + offset) is aligned.
inline bool IsAddressAligned(Address addr,
intptr_t alignment,
@@ -220,10 +141,12 @@ T Abs(T a) {
}
-// Returns the negative absolute value of its argument.
-template <typename T>
-T NegAbs(T a) {
- return a < 0 ? a : -a;
+// Floor(-0.0) == 0.0
+inline double Floor(double x) {
+#ifdef _MSC_VER
+ if (x == 0) return x; // Fix for issue 3477.
+#endif
+ return std::floor(x);
}
@@ -233,6 +156,25 @@ inline int32_t WhichPowerOf2Abs(int32_t x) {
}
+// Obtains the unsigned type corresponding to T
+// available in C++11 as std::make_unsigned
+template<typename T>
+struct make_unsigned {
+ typedef T type;
+};
+
+
+// Template specializations necessary to have make_unsigned work
+template<> struct make_unsigned<int32_t> {
+ typedef uint32_t type;
+};
+
+
+template<> struct make_unsigned<int64_t> {
+ typedef uint64_t type;
+};
+
+
// ----------------------------------------------------------------------------
// BitField is a help template for encoding and decode bitfield with
// unsigned content.
@@ -247,6 +189,7 @@ class BitFieldBase {
static const U kMask = ((kOne << shift) << size) - (kOne << shift);
static const U kShift = shift;
static const U kSize = size;
+ static const U kNext = kShift + kSize;
// Value for the field with all bits set.
static const T kMax = static_cast<T>((1U << size) - 1);
@@ -258,7 +201,7 @@ class BitFieldBase {
// Returns a type U with the bit field value encoded.
static U encode(T value) {
- ASSERT(is_valid(value));
+ DCHECK(is_valid(value));
return static_cast<U>(value) << shift;
}
@@ -322,6 +265,85 @@ inline uint32_t ComputePointerHash(void* ptr) {
// ----------------------------------------------------------------------------
+// Generated memcpy/memmove
+
+// Initializes the codegen support that depends on CPU features. This is
+// called after CPU initialization.
+void init_memcopy_functions();
+
+#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X87)
+// Limit below which the extra overhead of the MemCopy function is likely
+// to outweigh the benefits of faster copying.
+const int kMinComplexMemCopy = 64;
+
+// Copy memory area. No restrictions.
+void MemMove(void* dest, const void* src, size_t size);
+typedef void (*MemMoveFunction)(void* dest, const void* src, size_t size);
+
+// Keep the distinction of "move" vs. "copy" for the benefit of other
+// architectures.
+V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
+ MemMove(dest, src, size);
+}
+#elif defined(V8_HOST_ARCH_ARM)
+typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
+ size_t size);
+extern MemCopyUint8Function memcopy_uint8_function;
+V8_INLINE void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src,
+ size_t chars) {
+ memcpy(dest, src, chars);
+}
+// For values < 16, the assembler function is slower than the inlined C code.
+const int kMinComplexMemCopy = 16;
+V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
+ (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
+ reinterpret_cast<const uint8_t*>(src), size);
+}
+V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
+ memmove(dest, src, size);
+}
+
+typedef void (*MemCopyUint16Uint8Function)(uint16_t* dest, const uint8_t* src,
+ size_t size);
+extern MemCopyUint16Uint8Function memcopy_uint16_uint8_function;
+void MemCopyUint16Uint8Wrapper(uint16_t* dest, const uint8_t* src,
+ size_t chars);
+// For values < 12, the assembler function is slower than the inlined C code.
+const int kMinComplexConvertMemCopy = 12;
+V8_INLINE void MemCopyUint16Uint8(uint16_t* dest, const uint8_t* src,
+ size_t size) {
+ (*memcopy_uint16_uint8_function)(dest, src, size);
+}
+#elif defined(V8_HOST_ARCH_MIPS)
+typedef void (*MemCopyUint8Function)(uint8_t* dest, const uint8_t* src,
+ size_t size);
+extern MemCopyUint8Function memcopy_uint8_function;
+V8_INLINE void MemCopyUint8Wrapper(uint8_t* dest, const uint8_t* src,
+ size_t chars) {
+ memcpy(dest, src, chars);
+}
+// For values < 16, the assembler function is slower than the inlined C code.
+const int kMinComplexMemCopy = 16;
+V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
+ (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
+ reinterpret_cast<const uint8_t*>(src), size);
+}
+V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
+ memmove(dest, src, size);
+}
+#else
+// Copy memory area to disjoint memory area.
+V8_INLINE void MemCopy(void* dest, const void* src, size_t size) {
+ memcpy(dest, src, size);
+}
+V8_INLINE void MemMove(void* dest, const void* src, size_t size) {
+ memmove(dest, src, size);
+}
+const int kMinComplexMemCopy = 16 * kPointerSize;
+#endif // V8_TARGET_ARCH_IA32
+
+
+// ----------------------------------------------------------------------------
// Miscellaneous
// A static resource holds a static instance that can be reserved in
@@ -346,7 +368,7 @@ class Access {
explicit Access(StaticResource<T>* resource)
: resource_(resource)
, instance_(&resource->instance_) {
- ASSERT(!resource->is_reserved_);
+ DCHECK(!resource->is_reserved_);
resource->is_reserved_ = true;
}
@@ -374,12 +396,12 @@ class SetOncePointer {
bool is_set() const { return pointer_ != NULL; }
T* get() const {
- ASSERT(pointer_ != NULL);
+ DCHECK(pointer_ != NULL);
return pointer_;
}
void set(T* value) {
- ASSERT(pointer_ == NULL && value != NULL);
+ DCHECK(pointer_ == NULL && value != NULL);
pointer_ = value;
}
@@ -402,14 +424,14 @@ class EmbeddedVector : public Vector<T> {
// When copying, make underlying Vector to reference our buffer.
EmbeddedVector(const EmbeddedVector& rhs)
: Vector<T>(rhs) {
- OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
- set_start(buffer_);
+ MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
+ this->set_start(buffer_);
}
EmbeddedVector& operator=(const EmbeddedVector& rhs) {
if (this == &rhs) return *this;
Vector<T>::operator=(rhs);
- OS::MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
+ MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize);
this->set_start(buffer_);
return *this;
}
@@ -459,7 +481,7 @@ class Collector {
// A basic Collector will keep this vector valid as long as the Collector
// is alive.
inline Vector<T> AddBlock(int size, T initial_value) {
- ASSERT(size > 0);
+ DCHECK(size > 0);
if (size > current_chunk_.length() - index_) {
Grow(size);
}
@@ -493,7 +515,7 @@ class Collector {
// Write the contents of the collector into the provided vector.
void WriteTo(Vector<T> destination) {
- ASSERT(size_ <= destination.length());
+ DCHECK(size_ <= destination.length());
int position = 0;
for (int i = 0; i < chunks_.length(); i++) {
Vector<T> chunk = chunks_.at(i);
@@ -533,7 +555,7 @@ class Collector {
// Creates a new current chunk, and stores the old chunk in the chunks_ list.
void Grow(int min_capacity) {
- ASSERT(growth_factor > 1);
+ DCHECK(growth_factor > 1);
int new_capacity;
int current_length = current_chunk_.length();
if (current_length < kMinCapacity) {
@@ -551,7 +573,7 @@ class Collector {
}
}
NewChunk(new_capacity);
- ASSERT(index_ + min_capacity <= current_chunk_.length());
+ DCHECK(index_ + min_capacity <= current_chunk_.length());
}
// Before replacing the current chunk, give a subclass the option to move
@@ -590,12 +612,12 @@ class SequenceCollector : public Collector<T, growth_factor, max_growth> {
virtual ~SequenceCollector() {}
void StartSequence() {
- ASSERT(sequence_start_ == kNoSequence);
+ DCHECK(sequence_start_ == kNoSequence);
sequence_start_ = this->index_;
}
Vector<T> EndSequence() {
- ASSERT(sequence_start_ != kNoSequence);
+ DCHECK(sequence_start_ != kNoSequence);
int sequence_start = sequence_start_;
sequence_start_ = kNoSequence;
if (sequence_start == this->index_) return Vector<T>();
@@ -604,7 +626,7 @@ class SequenceCollector : public Collector<T, growth_factor, max_growth> {
// Drops the currently added sequence, and all collected elements in it.
void DropSequence() {
- ASSERT(sequence_start_ != kNoSequence);
+ DCHECK(sequence_start_ != kNoSequence);
int sequence_length = this->index_ - sequence_start_;
this->index_ = sequence_start_;
this->size_ -= sequence_length;
@@ -629,7 +651,7 @@ class SequenceCollector : public Collector<T, growth_factor, max_growth> {
}
int sequence_length = this->index_ - sequence_start_;
Vector<T> new_chunk = Vector<T>::New(sequence_length + new_capacity);
- ASSERT(sequence_length < new_chunk.length());
+ DCHECK(sequence_length < new_chunk.length());
for (int i = 0; i < sequence_length; i++) {
new_chunk[i] = this->current_chunk_[sequence_start_ + i];
}
@@ -676,8 +698,8 @@ inline int CompareCharsUnsigned(const lchar* lhs,
template<typename lchar, typename rchar>
inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
- ASSERT(sizeof(lchar) <= 2);
- ASSERT(sizeof(rchar) <= 2);
+ DCHECK(sizeof(lchar) <= 2);
+ DCHECK(sizeof(rchar) <= 2);
if (sizeof(lchar) == 1) {
if (sizeof(rchar) == 1) {
return CompareCharsUnsigned(reinterpret_cast<const uint8_t*>(lhs),
@@ -704,8 +726,8 @@ inline int CompareChars(const lchar* lhs, const rchar* rhs, int chars) {
// Calculate 10^exponent.
inline int TenToThe(int exponent) {
- ASSERT(exponent <= 9);
- ASSERT(exponent >= 1);
+ DCHECK(exponent <= 9);
+ DCHECK(exponent >= 1);
int answer = 10;
for (int i = 1; i < exponent; i++) answer *= 10;
return answer;
@@ -775,11 +797,11 @@ class EmbeddedContainer {
int length() const { return NumElements; }
const ElementType& operator[](int i) const {
- ASSERT(i < length());
+ DCHECK(i < length());
return elems_[i];
}
ElementType& operator[](int i) {
- ASSERT(i < length());
+ DCHECK(i < length());
return elems_[i];
}
@@ -825,7 +847,7 @@ class SimpleStringBuilder {
// Get the current position in the builder.
int position() const {
- ASSERT(!is_finalized());
+ DCHECK(!is_finalized());
return position_;
}
@@ -836,8 +858,8 @@ class SimpleStringBuilder {
// 0-characters; use the Finalize() method to terminate the string
// instead.
void AddCharacter(char c) {
- ASSERT(c != '\0');
- ASSERT(!is_finalized() && position_ < buffer_.length());
+ DCHECK(c != '\0');
+ DCHECK(!is_finalized() && position_ < buffer_.length());
buffer_[position_++] = c;
}
@@ -896,9 +918,9 @@ class EnumSet {
private:
T Mask(E element) const {
- // The strange typing in ASSERT is necessary to avoid stupid warnings, see:
+ // The strange typing in DCHECK is necessary to avoid stupid warnings, see:
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43680
- ASSERT(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT));
+ DCHECK(static_cast<int>(element) < static_cast<int>(sizeof(T) * CHAR_BIT));
return static_cast<T>(1) << element;
}
@@ -925,19 +947,19 @@ inline int signed_bitextract_64(int msb, int lsb, int x) {
// Check number width.
inline bool is_intn(int64_t x, unsigned n) {
- ASSERT((0 < n) && (n < 64));
+ DCHECK((0 < n) && (n < 64));
int64_t limit = static_cast<int64_t>(1) << (n - 1);
return (-limit <= x) && (x < limit);
}
inline bool is_uintn(int64_t x, unsigned n) {
- ASSERT((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
+ DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
return !(x >> n);
}
template <class T>
inline T truncate_to_intn(T x, unsigned n) {
- ASSERT((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
+ DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
return (x & ((static_cast<T>(1) << n) - 1));
}
@@ -1064,6 +1086,13 @@ void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
// Prepends the current process ID to the output.
void PRINTF_CHECKING PrintPID(const char* format, ...);
+// Safe formatting print. Ensures that str is always null-terminated.
+// Returns the number of chars written, or -1 if output was truncated.
+int FPRINTF_CHECKING SNPrintF(Vector<char> str, const char* format, ...);
+int VSNPrintF(Vector<char> str, const char* format, va_list args);
+
+void StrNCpy(Vector<char> dest, const char* src, size_t n);
+
// Our version of fflush.
void Flush(FILE* out);
@@ -1136,11 +1165,11 @@ inline void CopyWords(T* dst, const T* src, size_t num_words) {
// TODO(mvstanton): disabled because mac builds are bogus failing on this
// assert. They are doing a signed comparison. Investigate in
// the morning.
- // ASSERT(Min(dst, const_cast<T*>(src)) + num_words <=
+ // DCHECK(Min(dst, const_cast<T*>(src)) + num_words <=
// Max(dst, const_cast<T*>(src)));
- ASSERT(num_words > 0);
+ DCHECK(num_words > 0);
- // Use block copying OS::MemCopy if the segment we're copying is
+ // Use block copying MemCopy if the segment we're copying is
// enough to justify the extra call/setup overhead.
static const size_t kBlockCopyLimit = 16;
@@ -1150,7 +1179,7 @@ inline void CopyWords(T* dst, const T* src, size_t num_words) {
*dst++ = *src++;
} while (num_words > 0);
} else {
- OS::MemCopy(dst, src, num_words * kPointerSize);
+ MemCopy(dst, src, num_words * kPointerSize);
}
}
@@ -1159,9 +1188,9 @@ inline void CopyWords(T* dst, const T* src, size_t num_words) {
template <typename T>
inline void MoveWords(T* dst, const T* src, size_t num_words) {
STATIC_ASSERT(sizeof(T) == kPointerSize);
- ASSERT(num_words > 0);
+ DCHECK(num_words > 0);
- // Use block copying OS::MemCopy if the segment we're copying is
+ // Use block copying MemCopy if the segment we're copying is
// enough to justify the extra call/setup overhead.
static const size_t kBlockCopyLimit = 16;
@@ -1173,7 +1202,7 @@ inline void MoveWords(T* dst, const T* src, size_t num_words) {
*dst++ = *src++;
} while (num_words > 0);
} else {
- OS::MemMove(dst, src, num_words * kPointerSize);
+ MemMove(dst, src, num_words * kPointerSize);
}
}
@@ -1182,13 +1211,13 @@ inline void MoveWords(T* dst, const T* src, size_t num_words) {
template <typename T>
inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
STATIC_ASSERT(sizeof(T) == 1);
- ASSERT(Min(dst, const_cast<T*>(src)) + num_bytes <=
+ DCHECK(Min(dst, const_cast<T*>(src)) + num_bytes <=
Max(dst, const_cast<T*>(src)));
if (num_bytes == 0) return;
- // Use block copying OS::MemCopy if the segment we're copying is
+ // Use block copying MemCopy if the segment we're copying is
// enough to justify the extra call/setup overhead.
- static const int kBlockCopyLimit = OS::kMinComplexMemCopy;
+ static const int kBlockCopyLimit = kMinComplexMemCopy;
if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
do {
@@ -1196,7 +1225,7 @@ inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
*dst++ = *src++;
} while (num_bytes > 0);
} else {
- OS::MemCopy(dst, src, num_bytes);
+ MemCopy(dst, src, num_bytes);
}
}
@@ -1212,8 +1241,12 @@ inline void MemsetPointer(T** dest, U* value, int counter) {
#if V8_HOST_ARCH_IA32
#define STOS "stosl"
#elif V8_HOST_ARCH_X64
+#if V8_HOST_ARCH_32_BIT
+#define STOS "addr32 stosl"
+#else
#define STOS "stosq"
#endif
+#endif
#if defined(__native_client__)
// This STOS sequence does not validate for x86_64 Native Client.
// Here we #undef STOS to force use of the slower C version.
@@ -1289,8 +1322,8 @@ INLINE(void CopyChars(sinkchar* dest, const sourcechar* src, int chars));
template<typename sourcechar, typename sinkchar>
void CopyChars(sinkchar* dest, const sourcechar* src, int chars) {
- ASSERT(sizeof(sourcechar) <= 2);
- ASSERT(sizeof(sinkchar) <= 2);
+ DCHECK(sizeof(sourcechar) <= 2);
+ DCHECK(sizeof(sinkchar) <= 2);
if (sizeof(sinkchar) == 1) {
if (sizeof(sourcechar) == 1) {
CopyCharsUnsigned(reinterpret_cast<uint8_t*>(dest),
@@ -1319,13 +1352,13 @@ void CopyCharsUnsigned(sinkchar* dest, const sourcechar* src, int chars) {
sinkchar* limit = dest + chars;
#ifdef V8_HOST_CAN_READ_UNALIGNED
if (sizeof(*dest) == sizeof(*src)) {
- if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest))) {
- OS::MemCopy(dest, src, chars * sizeof(*dest));
+ if (chars >= static_cast<int>(kMinComplexMemCopy / sizeof(*dest))) {
+ MemCopy(dest, src, chars * sizeof(*dest));
return;
}
// Number of characters in a uintptr_t.
static const int kStepSize = sizeof(uintptr_t) / sizeof(*dest); // NOLINT
- ASSERT(dest + kStepSize > dest); // Check for overflow.
+ DCHECK(dest + kStepSize > dest); // Check for overflow.
while (dest + kStepSize <= limit) {
*reinterpret_cast<uintptr_t*>(dest) =
*reinterpret_cast<const uintptr_t*>(src);
@@ -1391,17 +1424,17 @@ void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
memcpy(dest, src, 15);
break;
default:
- OS::MemCopy(dest, src, chars);
+ MemCopy(dest, src, chars);
break;
}
}
void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars) {
- if (chars >= OS::kMinComplexConvertMemCopy) {
- OS::MemCopyUint16Uint8(dest, src, chars);
+ if (chars >= kMinComplexConvertMemCopy) {
+ MemCopyUint16Uint8(dest, src, chars);
} else {
- OS::MemCopyUint16Uint8Wrapper(dest, src, chars);
+ MemCopyUint16Uint8Wrapper(dest, src, chars);
}
}
@@ -1432,7 +1465,7 @@ void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
memcpy(dest, src, 14);
break;
default:
- OS::MemCopy(dest, src, chars * sizeof(*dest));
+ MemCopy(dest, src, chars * sizeof(*dest));
break;
}
}
@@ -1440,18 +1473,18 @@ void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
#elif defined(V8_HOST_ARCH_MIPS)
void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
- if (chars < OS::kMinComplexMemCopy) {
+ if (chars < kMinComplexMemCopy) {
memcpy(dest, src, chars);
} else {
- OS::MemCopy(dest, src, chars);
+ MemCopy(dest, src, chars);
}
}
void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
- if (chars < OS::kMinComplexMemCopy) {
+ if (chars < kMinComplexMemCopy) {
memcpy(dest, src, chars * sizeof(*dest));
} else {
- OS::MemCopy(dest, src, chars * sizeof(*dest));
+ MemCopy(dest, src, chars * sizeof(*dest));
}
}
#endif
@@ -1472,6 +1505,36 @@ class StringBuilder : public SimpleStringBuilder {
};
+bool DoubleToBoolean(double d);
+
+template <typename Stream>
+bool StringToArrayIndex(Stream* stream, uint32_t* index) {
+ uint16_t ch = stream->GetNext();
+
+ // If the string begins with a '0' character, it must only consist
+ // of it to be a legal array index.
+ if (ch == '0') {
+ *index = 0;
+ return !stream->HasMore();
+ }
+
+ // Convert string to uint32 array index; character by character.
+ int d = ch - '0';
+ if (d < 0 || d > 9) return false;
+ uint32_t result = d;
+ while (stream->HasMore()) {
+ d = stream->GetNext() - '0';
+ if (d < 0 || d > 9) return false;
+ // Check that the new result is below the 32 bit limit.
+ if (result > 429496729U - ((d > 5) ? 1 : 0)) return false;
+ result = (result * 10) + d;
+ }
+
+ *index = result;
+ return true;
+}
+
+
} } // namespace v8::internal
#endif // V8_UTILS_H_