Replace OS::MemCopy with OS::MemMove (just as fast but more flexible).
authorjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Apr 2013 12:30:51 +0000 (12:30 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 16 Apr 2013 12:30:51 +0000 (12:30 +0000)
Review URL: https://codereview.chromium.org/13932006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14280 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

58 files changed:
src/allocation.cc
src/api.cc
src/arm/assembler-arm.cc
src/arm/constants-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm/simulator-arm.cc
src/atomicops_internals_x86_gcc.cc
src/builtins.cc
src/conversions-inl.h
src/debug.cc
src/deoptimizer.cc
src/elements.cc
src/execution.cc
src/flags.cc
src/gdb-jit.cc
src/global-handles.h
src/heap-inl.h
src/heap-snapshot-generator.cc
src/heap.cc
src/hydrogen.cc
src/ia32/assembler-ia32.cc
src/ia32/assembler-ia32.h
src/ia32/codegen-ia32.cc
src/ia32/deoptimizer-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/isolate.cc
src/jsregexp.cc
src/list-inl.h
src/liveedit.cc
src/log-utils.cc
src/log.cc
src/mips/assembler-mips.cc
src/mips/lithium-codegen-mips.cc
src/mips/simulator-mips.cc
src/objects.cc
src/platform-posix.cc
src/platform-win32.cc
src/platform.h
src/preparse-data.cc
src/preparser-api.cc
src/prettyprinter.cc
src/regexp-macro-assembler-irregexp.cc
src/regexp-stack.cc
src/scanner.h
src/serialize.h
src/string-stream.cc
src/unicode-inl.h
src/utils.cc
src/utils.h
src/v8utils.cc
src/v8utils.h
src/x64/assembler-x64.cc
src/x64/lithium-codegen-x64.cc
test/cctest/test-api.cc
test/cctest/test-compiler.cc
test/cctest/test-heap-profiler.cc
test/cctest/test-parsing.cc
test/cctest/test-utils.cc

index 6c7a08cec8008b3f0675e25d7c422beb5ca20c15..94aaad3fd42e8aac7a99d19658b45bb95adbe0f0 100644 (file)
@@ -28,8 +28,8 @@
 #include "allocation.h"
 
 #include <stdlib.h>  // For free, malloc.
-#include <string.h>  // For memcpy.
 #include "checks.h"
+#include "platform.h"
 #include "utils.h"
 
 namespace v8 {
@@ -85,7 +85,7 @@ void AllStatic::operator delete(void* p) {
 char* StrDup(const char* str) {
   int length = StrLength(str);
   char* result = NewArray<char>(length + 1);
-  memcpy(result, str, length);
+  OS::MemCopy(result, str, length);
   result[length] = '\0';
   return result;
 }
@@ -95,7 +95,7 @@ char* StrNDup(const char* str, int n) {
   int length = StrLength(str);
   if (n < length) length = n;
   char* result = NewArray<char>(length + 1);
-  memcpy(result, str, length);
+  OS::MemCopy(result, str, length);
   result[length] = '\0';
   return result;
 }
index e43073c1e8465186c8dfafef1c64b84f1285bf8c..077fff57624177e79155b1885d743329b739f616 100644 (file)
@@ -1686,7 +1686,8 @@ ScriptData* ScriptData::New(const char* data, int length) {
   }
   // Copy the data to align it.
   unsigned* deserialized_data = i::NewArray<unsigned>(deserialized_data_length);
-  i::OS::MemCopy(deserialized_data, data, length);
+  i::CopyBytes(reinterpret_cast<char*>(deserialized_data),
+               data, static_cast<size_t>(length));
 
   return new i::ScriptDataImpl(
       i::Vector<unsigned>(deserialized_data, deserialized_data_length));
@@ -3278,7 +3279,7 @@ Local<String> v8::Object::ObjectProtoToString() {
 
       // Write prefix.
       char* ptr = buf.start();
-      memcpy(ptr, prefix, prefix_len * v8::internal::kCharSize);
+      i::OS::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
       ptr += prefix_len;
 
       // Write real content.
@@ -3286,7 +3287,7 @@ Local<String> v8::Object::ObjectProtoToString() {
       ptr += str_len;
 
       // Write postfix.
-      memcpy(ptr, postfix, postfix_len * v8::internal::kCharSize);
+      i::OS::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
 
       // Copy the buffer into a heap-allocated string and return it.
       Local<String> result = v8::String::New(buf.start(), buf_len);
@@ -7267,7 +7268,7 @@ char* HandleScopeImplementer::ArchiveThread(char* storage) {
   v8::ImplementationUtilities::HandleScopeData* current =
       isolate_->handle_scope_data();
   handle_scope_data_ = *current;
-  memcpy(storage, this, sizeof(*this));
+  OS::MemCopy(storage, this, sizeof(*this));
 
   ResetAfterArchive();
   current->Initialize();
@@ -7282,7 +7283,7 @@ int HandleScopeImplementer::ArchiveSpacePerThread() {
 
 
 char* HandleScopeImplementer::RestoreThread(char* storage) {
-  memcpy(this, storage, sizeof(*this));
+  OS::MemCopy(this, storage, sizeof(*this));
   *isolate_->handle_scope_data() = handle_scope_data_;
   return storage + ArchiveSpacePerThread();
 }
index 3741ac2cbc1d28b05600eafa1394ca1f99c0fafc..b0dbe061e2024cc69c24f164478b021ceb720868 100644 (file)
@@ -1996,7 +1996,7 @@ void  Assembler::vstm(BlockAddrMode am,
 
 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
   uint64_t i;
-  memcpy(&i, &d, 8);
+  OS::MemCopy(&i, &d, 8);
 
   *lo = i & 0xffffffff;
   *hi = i >> 32;
@@ -2700,9 +2700,9 @@ void Assembler::GrowBuffer() {
   // Copy the data.
   int pc_delta = desc.buffer - buffer_;
   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
-  memmove(desc.buffer, buffer_, desc.instr_size);
-  memmove(reloc_info_writer.pos() + rc_delta,
-          reloc_info_writer.pos(), desc.reloc_size);
+  OS::MemMove(desc.buffer, buffer_, desc.instr_size);
+  OS::MemMove(reloc_info_writer.pos() + rc_delta,
+              reloc_info_writer.pos(), desc.reloc_size);
 
   // Switch buffers.
   DeleteArray(buffer_);
@@ -2951,7 +2951,7 @@ void Assembler::CheckConstPool(bool force_emit, bool require_jump) {
 
       const double double_data = rinfo.data64();
       uint64_t uint_data = 0;
-      memcpy(&uint_data, &double_data, sizeof(double_data));
+      OS::MemCopy(&uint_data, &double_data, sizeof(double_data));
       emit(uint_data & 0xFFFFFFFF);
       emit(uint_data >> 32);
     }
index cdca1f5310c636a803e8934a2b5a291d94e414a7..a13048476d88e58cc2f6c3e708a7824b7d7b44bd 100644 (file)
@@ -51,7 +51,7 @@ double Instruction::DoubleImmedVmov() const {
 
   uint64_t imm = high16 << 48;
   double d;
-  memcpy(&d, &imm, 8);
+  OS::MemCopy(&d, &imm, 8);
   return d;
 }
 
index ec63d8460b0dc63a660189babc68564acaa77731..f5e8d3a77f205408eedb7b7d8196a7f23bcf0b46 100644 (file)
@@ -113,7 +113,7 @@ void LCodeGen::Comment(const char* format, ...) {
   // issues when the stack allocated buffer goes out of scope.
   size_t length = builder.position();
   Vector<char> copy = Vector<char>::New(length + 1);
-  memcpy(copy.start(), builder.Finalize(), copy.length());
+  OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
   masm()->RecordComment(copy.start());
 }
 
index 750cc23cca288989770a39dc8b025e8e55e15d09..ad4d77df28d0209484dcd635ca44b8e786eb24e9 100644 (file)
@@ -721,7 +721,7 @@ void Simulator::CheckICache(v8::internal::HashMap* i_cache,
                  Instruction::kInstrSize) == 0);
   } else {
     // Cache miss.  Load memory into the cache.
-    memcpy(cached_line, line, CachePage::kLineLength);
+    OS::MemCopy(cached_line, line, CachePage::kLineLength);
     *cache_valid_byte = CachePage::LINE_VALID;
   }
 }
@@ -903,8 +903,8 @@ double Simulator::get_double_from_register_pair(int reg) {
   // Read the bits from the unsigned integer register_[] array
   // into the double precision floating point value and return it.
   char buffer[2 * sizeof(vfp_registers_[0])];
-  memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
-  memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
+  OS::MemCopy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
+  OS::MemCopy(&dm_val, buffer, 2 * sizeof(registers_[0]));
   return(dm_val);
 }
 
@@ -954,9 +954,9 @@ void Simulator::SetVFPRegister(int reg_index, const InputType& value) {
   if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters());
 
   char buffer[register_size * sizeof(vfp_registers_[0])];
-  memcpy(buffer, &value, register_size * sizeof(vfp_registers_[0]));
-  memcpy(&vfp_registers_[reg_index * register_size], buffer,
-         register_size * sizeof(vfp_registers_[0]));
+  OS::MemCopy(buffer, &value, register_size * sizeof(vfp_registers_[0]));
+  OS::MemCopy(&vfp_registers_[reg_index * register_size], buffer,
+              register_size * sizeof(vfp_registers_[0]));
 }
 
 
@@ -968,9 +968,9 @@ ReturnType Simulator::GetFromVFPRegister(int reg_index) {
 
   ReturnType value = 0;
   char buffer[register_size * sizeof(vfp_registers_[0])];
-  memcpy(buffer, &vfp_registers_[register_size * reg_index],
-         register_size * sizeof(vfp_registers_[0]));
-  memcpy(&value, buffer, register_size * sizeof(vfp_registers_[0]));
+  OS::MemCopy(buffer, &vfp_registers_[register_size * reg_index],
+              register_size * sizeof(vfp_registers_[0]));
+  OS::MemCopy(&value, buffer, register_size * sizeof(vfp_registers_[0]));
   return value;
 }
 
@@ -988,14 +988,14 @@ void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
     // otherwise allow the compiler to optimize away the copy.
     char buffer[sizeof(*x)];
     // Registers 0 and 1 -> x.
-    memcpy(buffer, registers_, sizeof(*x));
-    memcpy(x, buffer, sizeof(*x));
+    OS::MemCopy(buffer, registers_, sizeof(*x));
+    OS::MemCopy(x, buffer, sizeof(*x));
     // Registers 2 and 3 -> y.
-    memcpy(buffer, registers_ + 2, sizeof(*y));
-    memcpy(y, buffer, sizeof(*y));
+    OS::MemCopy(buffer, registers_ + 2, sizeof(*y));
+    OS::MemCopy(y, buffer, sizeof(*y));
     // Register 2 -> z.
-    memcpy(buffer, registers_ + 2, sizeof(*z));
-    memcpy(z, buffer, sizeof(*z));
+    OS::MemCopy(buffer, registers_ + 2, sizeof(*z));
+    OS::MemCopy(z, buffer, sizeof(*z));
   }
 }
 
@@ -1004,14 +1004,14 @@ void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
 void Simulator::SetFpResult(const double& result) {
   if (use_eabi_hardfloat()) {
     char buffer[2 * sizeof(vfp_registers_[0])];
-    memcpy(buffer, &result, sizeof(buffer));
+    OS::MemCopy(buffer, &result, sizeof(buffer));
     // Copy result to d0.
-    memcpy(vfp_registers_, buffer, sizeof(buffer));
+    OS::MemCopy(vfp_registers_, buffer, sizeof(buffer));
   } else {
     char buffer[2 * sizeof(registers_[0])];
-    memcpy(buffer, &result, sizeof(buffer));
+    OS::MemCopy(buffer, &result, sizeof(buffer));
     // Copy result to r0 and r1.
-    memcpy(registers_, buffer, sizeof(buffer));
+    OS::MemCopy(registers_, buffer, sizeof(buffer));
   }
 }
 
@@ -1590,12 +1590,12 @@ void Simulator::HandleVList(Instruction* instr) {
           ReadW(reinterpret_cast<int32_t>(address + 1), instr)
         };
         double d;
-        memcpy(&d, data, 8);
+        OS::MemCopy(&d, data, 8);
         set_d_register_from_double(reg, d);
       } else {
         int32_t data[2];
         double d = get_double_from_d_register(reg);
-        memcpy(data, &d, 8);
+        OS::MemCopy(data, &d, 8);
         WriteW(reinterpret_cast<int32_t>(address), data[0], instr);
         WriteW(reinterpret_cast<int32_t>(address + 1), data[1], instr);
       }
@@ -2849,9 +2849,9 @@ void Simulator::DecodeTypeVFP(Instruction* instr) {
       int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4);
       double dd_value = get_double_from_d_register(vd);
       int32_t data[2];
-      memcpy(data, &dd_value, 8);
+      OS::MemCopy(data, &dd_value, 8);
       data[instr->Bit(21)] = get_register(instr->RtValue());
-      memcpy(&dd_value, data, 8);
+      OS::MemCopy(&dd_value, data, 8);
       set_d_register_from_double(vd, dd_value);
     } else if ((instr->VLValue() == 0x1) &&
                (instr->VCValue() == 0x0) &&
@@ -3202,13 +3202,13 @@ void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
           if (instr->HasL()) {
             int32_t data[2];
             double d = get_double_from_d_register(vm);
-            memcpy(data, &d, 8);
+            OS::MemCopy(data, &d, 8);
             set_register(rt, data[0]);
             set_register(rn, data[1]);
           } else {
             int32_t data[] = { get_register(rt), get_register(rn) };
             double d;
-            memcpy(&d, data, 8);
+            OS::MemCopy(&d, data, 8);
             set_d_register_from_double(vm, d);
           }
         }
@@ -3231,13 +3231,13 @@ void Simulator::DecodeType6CoprocessorIns(Instruction* instr) {
             ReadW(address + 4, instr)
           };
           double val;
-          memcpy(&val, data, 8);
+          OS::MemCopy(&val, data, 8);
           set_d_register_from_double(vd, val);
         } else {
           // Store double to memory: vstr.
           int32_t data[2];
           double val = get_double_from_d_register(vd);
-          memcpy(data, &val, 8);
+          OS::MemCopy(data, &val, 8);
           WriteW(address, data[0], instr);
           WriteW(address + 4, data[1], instr);
         }
@@ -3460,9 +3460,9 @@ double Simulator::CallFP(byte* entry, double d0, double d1) {
   } else {
     int buffer[2];
     ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0));
-    memcpy(buffer, &d0, sizeof(d0));
+    OS::MemCopy(buffer, &d0, sizeof(d0));
     set_dw_register(0, buffer);
-    memcpy(buffer, &d1, sizeof(d1));
+    OS::MemCopy(buffer, &d1, sizeof(d1));
     set_dw_register(2, buffer);
   }
   CallInternal(entry);
index 181c2024788f86092821ff09b0543588ad217cc6..b5078cf4a50ba69308808ea36cbd89cdfbf64f74 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 
 #include "atomicops.h"
+#include "platform.h"
 
 // This file only makes sense with atomicops_internals_x86_gcc.h -- it
 // depends on structs that are defined in that file.  If atomicops.h
@@ -84,9 +85,9 @@ void AtomicOps_Internalx86CPUFeaturesInit() {
   // Get vendor string (issue CPUID with eax = 0)
   cpuid(eax, ebx, ecx, edx, 0);
   char vendor[13];
-  memcpy(vendor, &ebx, 4);
-  memcpy(vendor + 4, &edx, 4);
-  memcpy(vendor + 8, &ecx, 4);
+  v8::internal::OS::MemCopy(vendor, &ebx, 4);
+  v8::internal::OS::MemCopy(vendor + 4, &edx, 4);
+  v8::internal::OS::MemCopy(vendor + 8, &ecx, 4);
   vendor[12] = 0;
 
   // get feature flags in ecx/edx, and family/model in eax
index e593d5c2c971b6378149790c71ada2501dfe2abf..56c0501e57523861a7b690ee252a1649f85a3237 100644 (file)
@@ -331,9 +331,9 @@ static void MoveDoubleElements(FixedDoubleArray* dst,
                                int src_index,
                                int len) {
   if (len == 0) return;
-  memmove(dst->data_start() + dst_index,
-          src->data_start() + src_index,
-          len * kDoubleSize);
+  OS::MemMove(dst->data_start() + dst_index,
+              src->data_start() + src_index,
+              len * kDoubleSize);
 }
 
 
index 7edaf224072124437cab688b59bf36302bd066a2..eb718d684dfa4de811f93e6d4ae62329705a59c8 100644 (file)
@@ -77,7 +77,7 @@ inline unsigned int FastD2UI(double x) {
     uint32_t result;
     Address mantissa_ptr = reinterpret_cast<Address>(&x);
     // Copy least significant 32 bits of mantissa.
-    memcpy(&result, mantissa_ptr, sizeof(result));
+    OS::MemCopy(&result, mantissa_ptr, sizeof(result));
     return negative ? ~result + 1 : result;
   }
   // Large number (outside uint32 range), Infinity or NaN.
index b862c51b0f26a5308f5bbe1266b0b21f6cf31c33..4af2194ea5f7455a6c0e7b2166b53755cc294130 100644 (file)
@@ -551,9 +551,9 @@ void Debug::ThreadInit() {
 
 char* Debug::ArchiveDebug(char* storage) {
   char* to = storage;
-  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
+  OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
   to += sizeof(ThreadLocal);
-  memcpy(to, reinterpret_cast<char*>(&registers_), sizeof(registers_));
+  OS::MemCopy(to, reinterpret_cast<char*>(&registers_), sizeof(registers_));
   ThreadInit();
   ASSERT(to <= storage + ArchiveSpacePerThread());
   return storage + ArchiveSpacePerThread();
@@ -562,9 +562,10 @@ char* Debug::ArchiveDebug(char* storage) {
 
 char* Debug::RestoreDebug(char* storage) {
   char* from = storage;
-  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
+  OS::MemCopy(
+      reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
   from += sizeof(ThreadLocal);
-  memcpy(reinterpret_cast<char*>(&registers_), from, sizeof(registers_));
+  OS::MemCopy(reinterpret_cast<char*>(&registers_), from, sizeof(registers_));
   ASSERT(from <= storage + ArchiveSpacePerThread());
   return storage + ArchiveSpacePerThread();
 }
index 49c8641dbd4e2d720d8e6fc18454a6a191472e31..1af736575b059ecf5c4e7599ce3578cc21412366 100644 (file)
@@ -2372,7 +2372,8 @@ int32_t TranslationIterator::Next() {
 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
   int length = contents_.length();
   Handle<ByteArray> result = factory->NewByteArray(length, TENURED);
-  memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length);
+  OS::MemCopy(
+      result->GetDataStartAddress(), contents_.ToVector().start(), length);
   return result;
 }
 
index 9deef60619312c58e03cca5d3f8e9c63aff54dfa..7c2b56851bc665facad23ce86620fb54ae8f8edd 100644 (file)
@@ -183,7 +183,7 @@ static void CopyObjectToObjectElements(FixedArrayBase* from_base,
   Address from_address = from->address() + FixedArray::kHeaderSize;
   CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
             reinterpret_cast<Object**>(from_address) + from_start,
-            copy_size);
+            static_cast<size_t>(copy_size));
   if (IsFastObjectElementsKind(from_kind) &&
       IsFastObjectElementsKind(to_kind)) {
     Heap* heap = from->GetHeap();
@@ -339,7 +339,7 @@ static void CopyDoubleToDoubleElements(FixedArrayBase* from_base,
   int words_per_double = (kDoubleSize / kPointerSize);
   CopyWords(reinterpret_cast<Object**>(to_address),
             reinterpret_cast<Object**>(from_address),
-            words_per_double * copy_size);
+            static_cast<size_t>(words_per_double * copy_size));
 }
 
 
index f343868060da516624815c727dbe526ebc116c7a..025a25619f3f1fdbbd5f933b1471c6db56e5fa7c 100644 (file)
@@ -502,7 +502,7 @@ void StackGuard::Continue(InterruptFlag after_what) {
 
 char* StackGuard::ArchiveStackGuard(char* to) {
   ExecutionAccess access(isolate_);
-  memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
+  OS::MemCopy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal));
   ThreadLocal blank;
 
   // Set the stack limits using the old thread_local_.
@@ -519,7 +519,8 @@ char* StackGuard::ArchiveStackGuard(char* to) {
 
 char* StackGuard::RestoreStackGuard(char* from) {
   ExecutionAccess access(isolate_);
-  memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
+  OS::MemCopy(
+      reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal));
   isolate_->heap()->SetStackLimits();
   return from + sizeof(ThreadLocal);
 }
index 59a7a52746aa5ac04c371b122130034444474017..a7fae681ae91d6bc173432521fa28088ad9ae4f9 100644 (file)
@@ -305,7 +305,7 @@ static void SplitArgument(const char* arg,
       // make a copy so we can NUL-terminate flag name
       size_t n = arg - *name;
       CHECK(n < static_cast<size_t>(buffer_size));  // buffer is too small
-      memcpy(buffer, *name, n);
+      OS::MemCopy(buffer, *name, n);
       buffer[n] = '\0';
       *name = buffer;
       // get the value
@@ -475,7 +475,7 @@ static char* SkipBlackSpace(char* p) {
 int FlagList::SetFlagsFromString(const char* str, int len) {
   // make a 0-terminated copy of str
   ScopedVector<char> copy0(len + 1);
-  memcpy(copy0.start(), str, len);
+  OS::MemCopy(copy0.start(), str, len);
   copy0[len] = '\0';
 
   // strip leading white space
index 83bd1a1d6a11c02e808dc48b199e831f08ded198..d08f2fe41862dda46f6107e9e2eecd576a3a7cc4 100644 (file)
@@ -681,7 +681,7 @@ class ELF BASE_EMBEDDED {
 #else
 #error Unsupported target architecture.
 #endif
-    memcpy(header->ident, ident, 16);
+    OS::MemCopy(header->ident, ident, 16);
     header->type = 1;
 #if defined(V8_TARGET_ARCH_IA32)
     header->machine = 3;
@@ -1855,7 +1855,7 @@ static JITCodeEntry* CreateCodeEntry(Address symfile_addr,
 
   entry->symfile_addr_ = reinterpret_cast<Address>(entry + 1);
   entry->symfile_size_ = symfile_size;
-  memcpy(entry->symfile_addr_, symfile_addr, symfile_size);
+  OS::MemCopy(entry->symfile_addr_, symfile_addr, symfile_size);
 
   entry->prev_ = entry->next_ = NULL;
 
index d4041ae394a2b381dd754e0859e69809990b707b..de934105572ed37d9f1eae1df2c73c4cf33b79e7 100644 (file)
@@ -98,7 +98,7 @@ class ImplicitRefGroup {
         malloc(OFFSET_OF(ImplicitRefGroup, children_[length])));
     group->parent_ = parent;
     group->length_ = length;
-    CopyWords(group->children_, children, static_cast<int>(length));
+    CopyWords(group->children_, children, length);
     return group;
   }
 
index 9df5135d529e7d351d56deff87c46eaf07baef95..28e50aa8bc48d5b12a037d067017bb0f0be89425 100644 (file)
@@ -159,8 +159,8 @@ MaybeObject* Heap::AllocateOneByteInternalizedString(Vector<const uint8_t> str,
   ASSERT_EQ(size, answer->Size());
 
   // Fill in the characters.
-  memcpy(answer->address() + SeqOneByteString::kHeaderSize,
-         str.start(), str.length());
+  OS::MemCopy(answer->address() + SeqOneByteString::kHeaderSize,
+              str.start(), str.length());
 
   return answer;
 }
@@ -192,8 +192,8 @@ MaybeObject* Heap::AllocateTwoByteInternalizedString(Vector<const uc16> str,
   ASSERT_EQ(size, answer->Size());
 
   // Fill in the characters.
-  memcpy(answer->address() + SeqTwoByteString::kHeaderSize,
-         str.start(), str.length() * kUC16Size);
+  OS::MemCopy(answer->address() + SeqTwoByteString::kHeaderSize,
+              str.start(), str.length() * kUC16Size);
 
   return answer;
 }
@@ -427,7 +427,7 @@ AllocationSpace Heap::TargetSpaceId(InstanceType type) {
 void Heap::CopyBlock(Address dst, Address src, int byte_size) {
   CopyWords(reinterpret_cast<Object**>(dst),
             reinterpret_cast<Object**>(src),
-            byte_size / kPointerSize);
+            static_cast<size_t>(byte_size / kPointerSize));
 }
 
 
@@ -445,7 +445,7 @@ void Heap::MoveBlock(Address dst, Address src, int byte_size) {
       *dst_slot++ = *src_slot++;
     }
   } else {
-    memmove(dst, src, byte_size);
+    OS::MemMove(dst, src, static_cast<size_t>(byte_size));
   }
 }
 
index cfa2ad31251658be6e6e3222e7be431539435c69..4588094dde384e90f953cdead38c35402fdaa82a 100644 (file)
@@ -2345,7 +2345,7 @@ class OutputStreamWriter {
       int s_chunk_size = Min(
           chunk_size_ - chunk_pos_, static_cast<int>(s_end - s));
       ASSERT(s_chunk_size > 0);
-      memcpy(chunk_.start() + chunk_pos_, s, s_chunk_size);
+      OS::MemCopy(chunk_.start() + chunk_pos_, s, s_chunk_size);
       s += s_chunk_size;
       chunk_pos_ += s_chunk_size;
       MaybeWriteChunk();
index 697261fe78dcb0fdce6c7d00b2e6a2a31d4525da..453d985647e40cc061e12ea18f414c30484bf96a 100644 (file)
@@ -687,9 +687,9 @@ void Heap::MoveElements(FixedArray* array,
 
   ASSERT(array->map() != HEAP->fixed_cow_array_map());
   Object** dst_objects = array->data_start() + dst_index;
-  memmove(dst_objects,
-          array->data_start() + src_index,
-          len * kPointerSize);
+  OS::MemMove(dst_objects,
+              array->data_start() + src_index,
+              len * kPointerSize);
   if (!InNewSpace(array)) {
     for (int i = 0; i < len; i++) {
       // TODO(hpayer): check store buffer for entries
@@ -4982,7 +4982,7 @@ static inline void WriteOneByteData(Vector<const char> vector,
                                     int len) {
   // Only works for ascii.
   ASSERT(vector.length() == len);
-  memcpy(chars, vector.start(), len);
+  OS::MemCopy(chars, vector.start(), len);
 }
 
 static inline void WriteTwoByteData(Vector<const char> vector,
@@ -7851,8 +7851,8 @@ void Heap::CheckpointObjectStats() {
   FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(ADJUST_LAST_TIME_OBJECT_COUNT)
 #undef ADJUST_LAST_TIME_OBJECT_COUNT
 
-  memcpy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
-  memcpy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
+  OS::MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
+  OS::MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
   ClearObjectStats();
 }
 
index ee6e3465431e71e231826d2f61ccb2a9a21f17d8..127d7a9aa1ed13943d558e7096ec35ca15ae3818 100644 (file)
@@ -2500,8 +2500,10 @@ HValueMap::HValueMap(Zone* zone, const HValueMap* other)
       array_(zone->NewArray<HValueMapListElement>(other->array_size_)),
       lists_(zone->NewArray<HValueMapListElement>(other->lists_size_)),
       free_list_head_(other->free_list_head_) {
-  memcpy(array_, other->array_, array_size_ * sizeof(HValueMapListElement));
-  memcpy(lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement));
+  OS::MemCopy(
+      array_, other->array_, array_size_ * sizeof(HValueMapListElement));
+  OS::MemCopy(
+      lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement));
 }
 
 
@@ -2627,7 +2629,7 @@ void HValueMap::ResizeLists(int new_size, Zone* zone) {
   lists_ = new_lists;
 
   if (old_lists != NULL) {
-    memcpy(lists_, old_lists, old_size * sizeof(HValueMapListElement));
+    OS::MemCopy(lists_, old_lists, old_size * sizeof(HValueMapListElement));
   }
   for (int i = old_size; i < lists_size_; ++i) {
     lists_[i].next = free_list_head_;
@@ -2673,7 +2675,7 @@ HSideEffectMap::HSideEffectMap(HSideEffectMap* other) : count_(other->count_) {
 
 HSideEffectMap& HSideEffectMap::operator= (const HSideEffectMap& other) {
   if (this != &other) {
-    memcpy(data_, other.data_, kNumberOfTrackedSideEffects * kPointerSize);
+    OS::MemCopy(data_, other.data_, kNumberOfTrackedSideEffects * kPointerSize);
   }
   return *this;
 }
@@ -2971,7 +2973,7 @@ GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
   size_t string_len = strlen(underlying_buffer) + 1;
   ASSERT(string_len <= sizeof(underlying_buffer));
   char* result = new char[strlen(underlying_buffer) + 1];
-  memcpy(result, underlying_buffer, string_len);
+  OS::MemCopy(result, underlying_buffer, string_len);
   return SmartArrayPointer<char>(result);
 }
 
index b48906e70614ac930327856b8eec9afb3822a3f3..32fe6a9c1052e94522b24129808531c277928cea 100644 (file)
@@ -2556,9 +2556,9 @@ void Assembler::GrowBuffer() {
   // Copy the data.
   int pc_delta = desc.buffer - buffer_;
   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
-  memmove(desc.buffer, buffer_, desc.instr_size);
-  memmove(rc_delta + reloc_info_writer.pos(),
-          reloc_info_writer.pos(), desc.reloc_size);
+  OS::MemMove(desc.buffer, buffer_, desc.instr_size);
+  OS::MemMove(rc_delta + reloc_info_writer.pos(),
+              reloc_info_writer.pos(), desc.reloc_size);
 
   // Switch buffers.
   if (isolate()->assembler_spare_buffer() == NULL &&
index a3da9af43362dd37176d2df7767e1cff263ceb35..d1c1fbf00389acb2b99ef3c552ef578e2131f35a 100644 (file)
@@ -1026,6 +1026,13 @@ class Assembler : public AssemblerBase {
   void movdqa(const Operand& dst, XMMRegister src);
   void movdqu(XMMRegister dst, const Operand& src);
   void movdqu(const Operand& dst, XMMRegister src);
+  void movdq(bool aligned, XMMRegister dst, const Operand& src) {
+    if (aligned) {
+      movdqa(dst, src);
+    } else {
+      movdqu(dst, src);
+    }
+  }
 
   // Use either movsd or movlpd.
   void movdbl(XMMRegister dst, const Operand& src);
index 550c83d51adad7225b995218a43e0ccf2c5327dc..fc02458753613386c96680bf5e53ffefa6d5611f 100644 (file)
@@ -173,21 +173,94 @@ UnaryMathFunction CreateSqrtFunction() {
 }
 
 
-static void MemCopyWrapper(void* dest, const void* src, size_t size) {
-  memcpy(dest, src, size);
+// Helper functions for CreateMemMoveFunction.
+#undef __
+#define __ ACCESS_MASM(masm)
+
+// Keep around global pointers to these objects so that Valgrind won't complain.
+static size_t* medium_handlers = NULL;
+static size_t* small_handlers = NULL;
+
+
+enum Direction { FORWARD, BACKWARD };
+enum Alignment { ALIGNED, UNALIGNED };
+
+// Expects registers:
+// esi - source, aligned if alignment == ALIGNED
+// edi - destination, always aligned
+// ecx - count (copy size in bytes)
+// edx - loop count (number of 64 byte chunks)
+void MemMoveEmitMainLoop(MacroAssembler* masm,
+                         Label* move_last_15,
+                         Direction direction,
+                         Alignment alignment) {
+  Register src = esi;
+  Register dst = edi;
+  Register count = ecx;
+  Register loop_count = edx;
+  Label loop, move_last_31, move_last_63;
+  __ cmp(loop_count, 0);
+  __ j(equal, &move_last_63);
+  __ bind(&loop);
+  // Main loop. Copy in 64 byte chunks.
+  if (direction == BACKWARD) __ sub(src, Immediate(0x40));
+  __ movdq(alignment == ALIGNED, xmm0, Operand(src, 0x00));
+  __ movdq(alignment == ALIGNED, xmm1, Operand(src, 0x10));
+  __ movdq(alignment == ALIGNED, xmm2, Operand(src, 0x20));
+  __ movdq(alignment == ALIGNED, xmm3, Operand(src, 0x30));
+  if (direction == FORWARD) __ add(src, Immediate(0x40));
+  if (direction == BACKWARD) __ sub(dst, Immediate(0x40));
+  __ movdqa(Operand(dst, 0x00), xmm0);
+  __ movdqa(Operand(dst, 0x10), xmm1);
+  __ movdqa(Operand(dst, 0x20), xmm2);
+  __ movdqa(Operand(dst, 0x30), xmm3);
+  if (direction == FORWARD) __ add(dst, Immediate(0x40));
+  __ dec(loop_count);
+  __ j(not_zero, &loop);
+  // At most 63 bytes left to copy.
+  __ bind(&move_last_63);
+  __ test(count, Immediate(0x20));
+  __ j(zero, &move_last_31);
+  if (direction == BACKWARD) __ sub(src, Immediate(0x20));
+  __ movdq(alignment == ALIGNED, xmm0, Operand(src, 0x00));
+  __ movdq(alignment == ALIGNED, xmm1, Operand(src, 0x10));
+  if (direction == FORWARD) __ add(src, Immediate(0x20));
+  if (direction == BACKWARD) __ sub(dst, Immediate(0x20));
+  __ movdqa(Operand(dst, 0x00), xmm0);
+  __ movdqa(Operand(dst, 0x10), xmm1);
+  if (direction == FORWARD) __ add(dst, Immediate(0x20));
+  // At most 31 bytes left to copy.
+  __ bind(&move_last_31);
+  __ test(count, Immediate(0x10));
+  __ j(zero, move_last_15);
+  if (direction == BACKWARD) __ sub(src, Immediate(0x10));
+  __ movdq(alignment == ALIGNED, xmm0, Operand(src, 0));
+  if (direction == FORWARD) __ add(src, Immediate(0x10));
+  if (direction == BACKWARD) __ sub(dst, Immediate(0x10));
+  __ movdqa(Operand(dst, 0), xmm0);
+  if (direction == FORWARD) __ add(dst, Immediate(0x10));
+}
+
+
+void MemMoveEmitPopAndReturn(MacroAssembler* masm) {
+  __ pop(esi);
+  __ pop(edi);
+  __ ret(0);
 }
 
 
-OS::MemCopyFunction CreateMemCopyFunction() {
+#undef __
+#define __ masm.
+
+
+OS::MemMoveFunction CreateMemMoveFunction() {
   size_t actual_size;
   // Allocate buffer in executable space.
-  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB,
-                                                 &actual_size,
-                                                 true));
-  if (buffer == NULL) return &MemCopyWrapper;
+  byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true));
+  if (buffer == NULL) return NULL;
   MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
 
-  // Generated code is put into a fixed, unmovable, buffer, and not into
+  // Generated code is put into a fixed, unmovable buffer, and not into
   // the V8 heap. We can't, and don't, refer to any relocatable addresses
   // (e.g. the JavaScript nan-object).
 
@@ -203,185 +276,367 @@ OS::MemCopyFunction CreateMemCopyFunction() {
   const int kSourceOffset = 2 * kPointerSize;
   const int kSizeOffset = 3 * kPointerSize;
 
+  // When copying up to this many bytes, use special "small" handlers.
+  const size_t kSmallCopySize = 8;
+  // When copying up to this many bytes, use special "medium" handlers.
+  const size_t kMediumCopySize = 63;
+  // When non-overlapping region of src and dst is less than this,
+  // use a more careful implementation (slightly slower).
+  const size_t kMinMoveDistance = 16;
+  // Note that these values are dictated by the implementation below,
+  // do not just change them and hope things will work!
+
   int stack_offset = 0;  // Update if we change the stack height.
 
-  if (FLAG_debug_code) {
-    __ cmp(Operand(esp, kSizeOffset + stack_offset),
-           Immediate(OS::kMinComplexMemCopy));
-    Label ok;
-    __ j(greater_equal, &ok);
-    __ int3();
-    __ bind(&ok);
-  }
+  Label backward, backward_much_overlap;
+  Label forward_much_overlap, small_size, medium_size, pop_and_return;
+  __ push(edi);
+  __ push(esi);
+  stack_offset += 2 * kPointerSize;
+  Register dst = edi;
+  Register src = esi;
+  Register count = ecx;
+  Register loop_count = edx;
+  __ mov(dst, Operand(esp, stack_offset + kDestinationOffset));
+  __ mov(src, Operand(esp, stack_offset + kSourceOffset));
+  __ mov(count, Operand(esp, stack_offset + kSizeOffset));
+
+  __ cmp(dst, src);
+  __ j(equal, &pop_and_return);
+
   if (CpuFeatures::IsSupported(SSE2)) {
-    CpuFeatureScope enable(&masm, SSE2);
-    __ push(edi);
-    __ push(esi);
-    stack_offset += 2 * kPointerSize;
-    Register dst = edi;
-    Register src = esi;
-    Register count = ecx;
-    __ mov(dst, Operand(esp, stack_offset + kDestinationOffset));
-    __ mov(src, Operand(esp, stack_offset + kSourceOffset));
-    __ mov(count, Operand(esp, stack_offset + kSizeOffset));
-
-
-    __ movdqu(xmm0, Operand(src, 0));
-    __ movdqu(Operand(dst, 0), xmm0);
-    __ mov(edx, dst);
-    __ and_(edx, 0xF);
-    __ neg(edx);
-    __ add(edx, Immediate(16));
-    __ add(dst, edx);
-    __ add(src, edx);
-    __ sub(count, edx);
-
-    // edi is now aligned. Check if esi is also aligned.
-    Label unaligned_source;
-    __ test(src, Immediate(0x0F));
-    __ j(not_zero, &unaligned_source);
+    CpuFeatureScope sse2_scope(&masm, SSE2);
+    __ prefetch(Operand(src, 0), 1);
+    __ cmp(count, kSmallCopySize);
+    __ j(below_equal, &small_size);
+    __ cmp(count, kMediumCopySize);
+    __ j(below_equal, &medium_size);
+    __ cmp(dst, src);
+    __ j(above, &backward);
+
     {
+      // |dst| is a lower address than |src|. Copy front-to-back.
+      Label unaligned_source, move_last_15, skip_last_move;
+      __ mov(eax, src);
+      __ sub(eax, dst);
+      __ cmp(eax, kMinMoveDistance);
+      __ j(below, &forward_much_overlap);
+      // Copy first 16 bytes.
+      __ movdqu(xmm0, Operand(src, 0));
+      __ movdqu(Operand(dst, 0), xmm0);
+      // Determine distance to alignment: 16 - (dst & 0xF).
+      __ mov(edx, dst);
+      __ and_(edx, 0xF);
+      __ neg(edx);
+      __ add(edx, Immediate(16));
+      __ add(dst, edx);
+      __ add(src, edx);
+      __ sub(count, edx);
+      // dst is now aligned. Main copy loop.
+      __ mov(loop_count, count);
+      __ shr(loop_count, 6);
+      // Check if src is also aligned.
+      __ test(src, Immediate(0xF));
+      __ j(not_zero, &unaligned_source);
       // Copy loop for aligned source and destination.
-      __ mov(edx, count);
-      Register loop_count = ecx;
-      Register count = edx;
-      __ shr(loop_count, 5);
-      {
-        // Main copy loop.
-        Label loop;
-        __ bind(&loop);
-        __ prefetch(Operand(src, 0x20), 1);
-        __ movdqa(xmm0, Operand(src, 0x00));
-        __ movdqa(xmm1, Operand(src, 0x10));
-        __ add(src, Immediate(0x20));
-
-        __ movdqa(Operand(dst, 0x00), xmm0);
-        __ movdqa(Operand(dst, 0x10), xmm1);
-        __ add(dst, Immediate(0x20));
-
-        __ dec(loop_count);
-        __ j(not_zero, &loop);
-      }
-
-      // At most 31 bytes to copy.
-      Label move_less_16;
-      __ test(count, Immediate(0x10));
-      __ j(zero, &move_less_16);
-      __ movdqa(xmm0, Operand(src, 0));
-      __ add(src, Immediate(0x10));
-      __ movdqa(Operand(dst, 0), xmm0);
-      __ add(dst, Immediate(0x10));
-      __ bind(&move_less_16);
-
+      MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, ALIGNED);
       // At most 15 bytes to copy. Copy 16 bytes at end of string.
+      __ bind(&move_last_15);
       __ and_(count, 0xF);
+      __ j(zero, &skip_last_move, Label::kNear);
       __ movdqu(xmm0, Operand(src, count, times_1, -0x10));
       __ movdqu(Operand(dst, count, times_1, -0x10), xmm0);
+      __ bind(&skip_last_move);
+      MemMoveEmitPopAndReturn(&masm);
 
-      __ mov(eax, Operand(esp, stack_offset + kDestinationOffset));
-      __ pop(esi);
-      __ pop(edi);
-      __ ret(0);
-    }
-    __ Align(16);
-    {
       // Copy loop for unaligned source and aligned destination.
-      // If source is not aligned, we can't read it as efficiently.
       __ bind(&unaligned_source);
-      __ mov(edx, ecx);
-      Register loop_count = ecx;
-      Register count = edx;
-      __ shr(loop_count, 5);
-      {
-        // Main copy loop
-        Label loop;
-        __ bind(&loop);
-        __ prefetch(Operand(src, 0x20), 1);
-        __ movdqu(xmm0, Operand(src, 0x00));
-        __ movdqu(xmm1, Operand(src, 0x10));
-        __ add(src, Immediate(0x20));
-
-        __ movdqa(Operand(dst, 0x00), xmm0);
-        __ movdqa(Operand(dst, 0x10), xmm1);
-        __ add(dst, Immediate(0x20));
-
-        __ dec(loop_count);
-        __ j(not_zero, &loop);
-      }
+      MemMoveEmitMainLoop(&masm, &move_last_15, FORWARD, UNALIGNED);
+      __ jmp(&move_last_15);
+
+      // Less than kMinMoveDistance offset between dst and src.
+      Label loop_until_aligned, last_15_much_overlap;
+      __ bind(&loop_until_aligned);
+      __ mov_b(eax, Operand(src, 0));
+      __ inc(src);
+      __ mov_b(Operand(dst, 0), eax);
+      __ inc(dst);
+      __ dec(count);
+      __ bind(&forward_much_overlap);  // Entry point into this block.
+      __ test(dst, Immediate(0xF));
+      __ j(not_zero, &loop_until_aligned);
+      // dst is now aligned, src can't be. Main copy loop.
+      __ mov(loop_count, count);
+      __ shr(loop_count, 6);
+      MemMoveEmitMainLoop(&masm, &last_15_much_overlap, FORWARD, UNALIGNED);
+      __ bind(&last_15_much_overlap);
+      __ and_(count, 0xF);
+      __ j(zero, &pop_and_return);
+      __ cmp(count, kSmallCopySize);
+      __ j(below_equal, &small_size);
+      __ jmp(&medium_size);
+    }
 
-      // At most 31 bytes to copy.
-      Label move_less_16;
-      __ test(count, Immediate(0x10));
-      __ j(zero, &move_less_16);
+    {
+      // |dst| is a higher address than |src|. Copy backwards.
+      Label unaligned_source, move_first_15, skip_last_move;
+      __ bind(&backward);
+      // |dst| and |src| always point to the end of what's left to copy.
+      __ add(dst, count);
+      __ add(src, count);
+      __ mov(eax, dst);
+      __ sub(eax, src);
+      __ cmp(eax, kMinMoveDistance);
+      __ j(below, &backward_much_overlap);
+      // Copy last 16 bytes.
+      __ movdqu(xmm0, Operand(src, -0x10));
+      __ movdqu(Operand(dst, -0x10), xmm0);
+      // Find distance to alignment: dst & 0xF
+      __ mov(edx, dst);
+      __ and_(edx, 0xF);
+      __ sub(dst, edx);
+      __ sub(src, edx);
+      __ sub(count, edx);
+      // dst is now aligned. Main copy loop.
+      __ mov(loop_count, count);
+      __ shr(loop_count, 6);
+      // Check if src is also aligned.
+      __ test(src, Immediate(0xF));
+      __ j(not_zero, &unaligned_source);
+      // Copy loop for aligned source and destination.
+      MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, ALIGNED);
+      // At most 15 bytes to copy. Copy 16 bytes at beginning of string.
+      __ bind(&move_first_15);
+      __ and_(count, 0xF);
+      __ j(zero, &skip_last_move, Label::kNear);
+      __ sub(src, count);
+      __ sub(dst, count);
       __ movdqu(xmm0, Operand(src, 0));
-      __ add(src, Immediate(0x10));
-      __ movdqa(Operand(dst, 0), xmm0);
-      __ add(dst, Immediate(0x10));
-      __ bind(&move_less_16);
-
-      // At most 15 bytes to copy. Copy 16 bytes at end of string.
-      __ and_(count, 0x0F);
-      __ movdqu(xmm0, Operand(src, count, times_1, -0x10));
-      __ movdqu(Operand(dst, count, times_1, -0x10), xmm0);
+      __ movdqu(Operand(dst, 0), xmm0);
+      __ bind(&skip_last_move);
+      MemMoveEmitPopAndReturn(&masm);
 
-      __ mov(eax, Operand(esp, stack_offset + kDestinationOffset));
-      __ pop(esi);
-      __ pop(edi);
-      __ ret(0);
+      // Copy loop for unaligned source and aligned destination.
+      __ bind(&unaligned_source);
+      MemMoveEmitMainLoop(&masm, &move_first_15, BACKWARD, UNALIGNED);
+      __ jmp(&move_first_15);
+
+      // Less than kMinMoveDistance offset between dst and src.
+      Label loop_until_aligned, first_15_much_overlap;
+      __ bind(&loop_until_aligned);
+      __ dec(src);
+      __ dec(dst);
+      __ mov_b(eax, Operand(src, 0));
+      __ mov_b(Operand(dst, 0), eax);
+      __ dec(count);
+      __ bind(&backward_much_overlap);  // Entry point into this block.
+      __ test(dst, Immediate(0xF));
+      __ j(not_zero, &loop_until_aligned);
+      // dst is now aligned, src can't be. Main copy loop.
+      __ mov(loop_count, count);
+      __ shr(loop_count, 6);
+      MemMoveEmitMainLoop(&masm, &first_15_much_overlap, BACKWARD, UNALIGNED);
+      __ bind(&first_15_much_overlap);
+      __ and_(count, 0xF);
+      __ j(zero, &pop_and_return);
+      // Small/medium handlers expect dst/src to point to the beginning.
+      __ sub(dst, count);
+      __ sub(src, count);
+      __ cmp(count, kSmallCopySize);
+      __ j(below_equal, &small_size);
+      __ jmp(&medium_size);
+    }
+    {
+      // Special handlers for 9 <= copy_size < 64. No assumptions about
+      // alignment or move distance, so all reads must be unaligned and
+      // must happen before any writes.
+      Label f9_16, f17_32, f33_48, f49_63;
+
+      __ bind(&f9_16);
+      __ movdbl(xmm0, Operand(src, 0));
+      __ movdbl(xmm1, Operand(src, count, times_1, -8));
+      __ movdbl(Operand(dst, 0), xmm0);
+      __ movdbl(Operand(dst, count, times_1, -8), xmm1);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f17_32);
+      __ movdqu(xmm0, Operand(src, 0));
+      __ movdqu(xmm1, Operand(src, count, times_1, -0x10));
+      __ movdqu(Operand(dst, 0x00), xmm0);
+      __ movdqu(Operand(dst, count, times_1, -0x10), xmm1);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f33_48);
+      __ movdqu(xmm0, Operand(src, 0x00));
+      __ movdqu(xmm1, Operand(src, 0x10));
+      __ movdqu(xmm2, Operand(src, count, times_1, -0x10));
+      __ movdqu(Operand(dst, 0x00), xmm0);
+      __ movdqu(Operand(dst, 0x10), xmm1);
+      __ movdqu(Operand(dst, count, times_1, -0x10), xmm2);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f49_63);
+      __ movdqu(xmm0, Operand(src, 0x00));
+      __ movdqu(xmm1, Operand(src, 0x10));
+      __ movdqu(xmm2, Operand(src, 0x20));
+      __ movdqu(xmm3, Operand(src, count, times_1, -0x10));
+      __ movdqu(Operand(dst, 0x00), xmm0);
+      __ movdqu(Operand(dst, 0x10), xmm1);
+      __ movdqu(Operand(dst, 0x20), xmm2);
+      __ movdqu(Operand(dst, count, times_1, -0x10), xmm3);
+      MemMoveEmitPopAndReturn(&masm);
+
+      medium_handlers = new size_t[4];
+      medium_handlers[0] = reinterpret_cast<intptr_t>(buffer) + f9_16.pos();
+      medium_handlers[1] = reinterpret_cast<intptr_t>(buffer) + f17_32.pos();
+      medium_handlers[2] = reinterpret_cast<intptr_t>(buffer) + f33_48.pos();
+      medium_handlers[3] = reinterpret_cast<intptr_t>(buffer) + f49_63.pos();
+
+      __ bind(&medium_size);  // Entry point into this block.
+      __ mov(eax, count);
+      __ dec(eax);
+      __ shr(eax, 4);
+      if (FLAG_debug_code) {
+        Label ok;
+        __ cmp(eax, 3);
+        __ j(below_equal, &ok);
+        __ int3();
+        __ bind(&ok);
+      }
+      __ mov(eax, Operand(eax, times_4,
+                          reinterpret_cast<intptr_t>(medium_handlers)));
+      __ jmp(eax);
+    }
+    {
+      // Specialized copiers for copy_size <= 8 bytes.
+      Label f0, f1, f2, f3, f4, f5_8;
+      __ bind(&f0);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f1);
+      __ mov_b(eax, Operand(src, 0));
+      __ mov_b(Operand(dst, 0), eax);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f2);
+      __ mov_w(eax, Operand(src, 0));
+      __ mov_w(Operand(dst, 0), eax);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f3);
+      __ mov_w(eax, Operand(src, 0));
+      __ mov_b(edx, Operand(src, 2));
+      __ mov_w(Operand(dst, 0), eax);
+      __ mov_b(Operand(dst, 2), edx);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f4);
+      __ mov(eax, Operand(src, 0));
+      __ mov(Operand(dst, 0), eax);
+      MemMoveEmitPopAndReturn(&masm);
+
+      __ bind(&f5_8);
+      __ mov(eax, Operand(src, 0));
+      __ mov(edx, Operand(src, count, times_1, -4));
+      __ mov(Operand(dst, 0), eax);
+      __ mov(Operand(dst, count, times_1, -4), edx);
+      MemMoveEmitPopAndReturn(&masm);
+
+      small_handlers = new size_t[9];
+      small_handlers[0] = reinterpret_cast<intptr_t>(buffer) + f0.pos();
+      small_handlers[1] = reinterpret_cast<intptr_t>(buffer) + f1.pos();
+      small_handlers[2] = reinterpret_cast<intptr_t>(buffer) + f2.pos();
+      small_handlers[3] = reinterpret_cast<intptr_t>(buffer) + f3.pos();
+      small_handlers[4] = reinterpret_cast<intptr_t>(buffer) + f4.pos();
+      small_handlers[5] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
+      small_handlers[6] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
+      small_handlers[7] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
+      small_handlers[8] = reinterpret_cast<intptr_t>(buffer) + f5_8.pos();
+
+      __ bind(&small_size);  // Entry point into this block.
+      if (FLAG_debug_code) {
+        Label ok;
+        __ cmp(count, 8);
+        __ j(below_equal, &ok);
+        __ int3();
+        __ bind(&ok);
+      }
+      __ mov(eax, Operand(count, times_4,
+                          reinterpret_cast<intptr_t>(small_handlers)));
+      __ jmp(eax);
     }
-
   } else {
-    // SSE2 not supported. Unlikely to happen in practice.
-    __ push(edi);
-    __ push(esi);
-    stack_offset += 2 * kPointerSize;
-    __ cld();
-    Register dst = edi;
-    Register src = esi;
-    Register count = ecx;
-    __ mov(dst, Operand(esp, stack_offset + kDestinationOffset));
-    __ mov(src, Operand(esp, stack_offset + kSourceOffset));
-    __ mov(count, Operand(esp, stack_offset + kSizeOffset));
-
-    // Copy the first word.
-    __ mov(eax, Operand(src, 0));
-    __ mov(Operand(dst, 0), eax);
-
-    // Increment src,dstso that dst is aligned.
-    __ mov(edx, dst);
-    __ and_(edx, 0x03);
-    __ neg(edx);
-    __ add(edx, Immediate(4));  // edx = 4 - (dst & 3)
-    __ add(dst, edx);
-    __ add(src, edx);
-    __ sub(count, edx);
-    // edi is now aligned, ecx holds number of remaning bytes to copy.
-
-    __ mov(edx, count);
-    count = edx;
-    __ shr(ecx, 2);  // Make word count instead of byte count.
-    __ rep_movs();
-
-    // At most 3 bytes left to copy. Copy 4 bytes at end of string.
-    __ and_(count, 3);
-    __ mov(eax, Operand(src, count, times_1, -4));
-    __ mov(Operand(dst, count, times_1, -4), eax);
-
-    __ mov(eax, Operand(esp, stack_offset + kDestinationOffset));
-    __ pop(esi);
-    __ pop(edi);
-    __ ret(0);
+    // No SSE2.
+    Label forward;
+    __ cmp(count, 0);
+    __ j(equal, &pop_and_return);
+    __ cmp(dst, src);
+    __ j(above, &backward);
+    __ jmp(&forward);
+    {
+      // Simple forward copier.
+      Label forward_loop_1byte, forward_loop_4byte;
+      __ bind(&forward_loop_4byte);
+      __ mov(eax, Operand(src, 0));
+      __ sub(count, Immediate(4));
+      __ add(src, Immediate(4));
+      __ mov(Operand(dst, 0), eax);
+      __ add(dst, Immediate(4));
+      __ bind(&forward);  // Entry point.
+      __ cmp(count, 3);
+      __ j(above, &forward_loop_4byte);
+      __ bind(&forward_loop_1byte);
+      __ cmp(count, 0);
+      __ j(below_equal, &pop_and_return);
+      __ mov_b(eax, Operand(src, 0));
+      __ dec(count);
+      __ inc(src);
+      __ mov_b(Operand(dst, 0), eax);
+      __ inc(dst);
+      __ jmp(&forward_loop_1byte);
+    }
+    {
+      // Simple backward copier.
+      Label backward_loop_1byte, backward_loop_4byte, entry_shortcut;
+      __ bind(&backward);
+      __ add(src, count);
+      __ add(dst, count);
+      __ cmp(count, 3);
+      __ j(below_equal, &entry_shortcut);
+
+      __ bind(&backward_loop_4byte);
+      __ sub(src, Immediate(4));
+      __ sub(count, Immediate(4));
+      __ mov(eax, Operand(src, 0));
+      __ sub(dst, Immediate(4));
+      __ mov(Operand(dst, 0), eax);
+      __ cmp(count, 3);
+      __ j(above, &backward_loop_4byte);
+      __ bind(&backward_loop_1byte);
+      __ cmp(count, 0);
+      __ j(below_equal, &pop_and_return);
+      __ bind(&entry_shortcut);
+      __ dec(src);
+      __ dec(count);
+      __ mov_b(eax, Operand(src, 0));
+      __ dec(dst);
+      __ mov_b(Operand(dst, 0), eax);
+      __ jmp(&backward_loop_1byte);
+    }
   }
 
+  __ bind(&pop_and_return);
+  MemMoveEmitPopAndReturn(&masm);
+
   CodeDesc desc;
   masm.GetCode(&desc);
   ASSERT(!RelocInfo::RequiresRelocation(desc));
-
   CPU::FlushICache(buffer, actual_size);
   OS::ProtectCode(buffer, actual_size);
-  return FUNCTION_CAST<OS::MemCopyFunction>(buffer);
+  return FUNCTION_CAST<OS::MemMoveFunction>(buffer);
 }
 
+
 #undef __
 
 // -------------------------------------------------------------------------
index 1c1b3a0ba30f6273d64dae70973eb045f418a9cb..f0436225c51b033150300df9a432717ed7b01ac5 100644 (file)
@@ -90,9 +90,9 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
     Factory* factory = isolate->factory();
     Handle<ByteArray> new_reloc =
         factory->NewByteArray(reloc_length + padding, TENURED);
-    memcpy(new_reloc->GetDataStartAddress() + padding,
-           code->relocation_info()->GetDataStartAddress(),
-           reloc_length);
+    OS::MemCopy(new_reloc->GetDataStartAddress() + padding,
+                code->relocation_info()->GetDataStartAddress(),
+                reloc_length);
     // Create a relocation writer to write the comments in the padding
     // space. Use position 0 for everything to ensure short encoding.
     RelocInfoWriter reloc_info_writer(
@@ -177,7 +177,8 @@ void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList(
 
   // Move the relocation info to the beginning of the byte array.
   int new_reloc_size = reloc_end_address - reloc_info_writer.pos();
-  memmove(code->relocation_start(), reloc_info_writer.pos(), new_reloc_size);
+  OS::MemMove(
+      code->relocation_start(), reloc_info_writer.pos(), new_reloc_size);
 
   // The relocation info is in place, update the size.
   reloc_info->set_length(new_reloc_size);
index bc1173b131550b03833f482610ee0a0932232a1a..1dcad043e6067d53ad6a74885ebd28ceec05bb1b 100644 (file)
@@ -135,7 +135,7 @@ void LCodeGen::Comment(const char* format, ...) {
   // issues when the stack allocated buffer goes out of scope.
   size_t length = builder.position();
   Vector<char> copy = Vector<char>::New(length + 1);
-  memcpy(copy.start(), builder.Finalize(), copy.length());
+  OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
   masm()->RecordComment(copy.start());
 }
 
index fc5a225dd38ac792428d4183e4e4662a94d2aff9..ca2c0257f63aa7f101a1abbc61a9ddc06ecd71d3 100644 (file)
@@ -1562,8 +1562,8 @@ Handle<Context> Isolate::GetCallingNativeContext() {
 
 
 char* Isolate::ArchiveThread(char* to) {
-  memcpy(to, reinterpret_cast<char*>(thread_local_top()),
-         sizeof(ThreadLocalTop));
+  OS::MemCopy(to, reinterpret_cast<char*>(thread_local_top()),
+              sizeof(ThreadLocalTop));
   InitializeThreadLocal();
   clear_pending_exception();
   clear_pending_message();
@@ -1573,8 +1573,8 @@ char* Isolate::ArchiveThread(char* to) {
 
 
 char* Isolate::RestoreThread(char* from) {
-  memcpy(reinterpret_cast<char*>(thread_local_top()), from,
-         sizeof(ThreadLocalTop));
+  OS::MemCopy(reinterpret_cast<char*>(thread_local_top()), from,
+              sizeof(ThreadLocalTop));
   // This might be just paranoia, but it seems to be needed in case a
   // thread_local_top_ is restored on a separate OS thread.
 #ifdef USE_SIMULATOR
index b490521bc07635d85c048efa94a112570695373e..fd87a805399409d6afe12ab38bbc87649f84b451 100644 (file)
@@ -624,7 +624,8 @@ int RegExpImpl::IrregexpExecRaw(Handle<JSRegExp> regexp,
                                                      index);
   if (result == RE_SUCCESS) {
     // Copy capture results to the start of the registers array.
-    memcpy(output, raw_output, number_of_capture_registers * sizeof(int32_t));
+    OS::MemCopy(
+        output, raw_output, number_of_capture_registers * sizeof(int32_t));
   }
   if (result == RE_EXCEPTION) {
     ASSERT(!isolate->has_pending_exception());
index 7a84313cd6ad5ed5235b97c5442ef3f520a1cc1a..408859e45668adcc5e64a38df09159ac92b61ab4 100644 (file)
@@ -29,6 +29,7 @@
 #define V8_LIST_INL_H_
 
 #include "list.h"
+#include "platform.h"
 
 namespace v8 {
 namespace internal {
@@ -87,7 +88,7 @@ template<typename T, class P>
 void List<T, P>::Resize(int new_capacity, P alloc) {
   ASSERT_LE(length_, new_capacity);
   T* new_data = NewData(new_capacity, alloc);
-  memcpy(new_data, data_, length_ * sizeof(T));
+  OS::MemCopy(new_data, data_, length_ * sizeof(T));
   List<T, P>::DeleteData(data_);
   data_ = new_data;
   capacity_ = new_capacity;
index fc708e67ec318686918522d28a61aa16b4ccfbb8..b28cd3e8727fee79309ccd550b148b5cc7ca3db7 100644 (file)
@@ -1435,8 +1435,8 @@ class RelocInfoBuffer {
     // Copy the data.
     int curently_used_size =
         static_cast<int>(buffer_ + buffer_size_ - reloc_info_writer_.pos());
-    memmove(new_buffer + new_buffer_size - curently_used_size,
-            reloc_info_writer_.pos(), curently_used_size);
+    OS::MemMove(new_buffer + new_buffer_size - curently_used_size,
+                reloc_info_writer_.pos(), curently_used_size);
 
     reloc_info_writer_.Reposition(
         new_buffer + new_buffer_size - curently_used_size,
@@ -1488,7 +1488,7 @@ static Handle<Code> PatchPositionsInCode(
 
   if (buffer.length() == code->relocation_size()) {
     // Simply patch relocation area of code.
-    memcpy(code->relocation_start(), buffer.start(), buffer.length());
+    OS::MemCopy(code->relocation_start(), buffer.start(), buffer.length());
     return code;
   } else {
     // Relocation info section now has different size. We cannot simply
@@ -1761,9 +1761,9 @@ static const char* DropFrames(Vector<StackFrame*> frames,
 
       StackFrame* pre_pre_frame = frames[top_frame_index - 2];
 
-      memmove(padding_start + kPointerSize - shortage_bytes,
-          padding_start + kPointerSize,
-          Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize);
+      OS::MemMove(padding_start + kPointerSize - shortage_bytes,
+                  padding_start + kPointerSize,
+                  Debug::FramePaddingLayout::kFrameBaseSize * kPointerSize);
 
       pre_top_frame->UpdateFp(pre_top_frame->fp() - shortage_bytes);
       pre_pre_frame->SetCallerFp(pre_top_frame->fp());
index 45ac403a6e9070b66717bb13f389e8bcb62ac87b..cef7dbab24decb47f1ce3d9fa7233149113a119d 100644 (file)
@@ -167,8 +167,9 @@ void Log::OpenFile(const char* name) {
     // Open the low-level log file.
     size_t len = strlen(name);
     ScopedVector<char> ll_name(static_cast<int>(len + sizeof(kLowLevelLogExt)));
-    memcpy(ll_name.start(), name, len);
-    memcpy(ll_name.start() + len, kLowLevelLogExt, sizeof(kLowLevelLogExt));
+    OS::MemCopy(ll_name.start(), name, len);
+    OS::MemCopy(ll_name.start() + len,
+                kLowLevelLogExt, sizeof(kLowLevelLogExt));
     ll_output_handle_ = OS::FOpen(ll_name.start(), OS::LogFileOpenMode);
     setvbuf(ll_output_handle_, NULL, _IOFBF, kLowLevelLogBufferSize);
   }
index 3984d01213e55fe7258f1234a5a2d9d51a0701ff..3a182ec672eabbcb976d0d3a6907ee2c1be66d76 100644 (file)
@@ -393,7 +393,7 @@ class Logger::NameBuffer {
 
   void AppendBytes(const char* bytes, int size) {
     size = Min(size, kUtf8BufferSize - utf8_pos_);
-    memcpy(utf8_buffer_ + utf8_pos_, bytes, size);
+    OS::MemCopy(utf8_buffer_ + utf8_pos_, bytes, size);
     utf8_pos_ += size;
   }
 
index fcb8819c2b5e71034fa83c568dfa3ea6f6b38935..e36b97f180aee4fffa01ff677084a77441ca7d50 100644 (file)
@@ -1667,7 +1667,7 @@ void Assembler::cfc1(Register rt, FPUControlRegister fs) {
 
 void Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
   uint64_t i;
-  memcpy(&i, &d, 8);
+  OS::MemCopy(&i, &d, 8);
 
   *lo = i & 0xffffffff;
   *hi = i >> 32;
@@ -1981,9 +1981,9 @@ void Assembler::GrowBuffer() {
   // Copy the data.
   int pc_delta = desc.buffer - buffer_;
   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
-  memmove(desc.buffer, buffer_, desc.instr_size);
-  memmove(reloc_info_writer.pos() + rc_delta,
-          reloc_info_writer.pos(), desc.reloc_size);
+  OS::MemMove(desc.buffer, buffer_, desc.instr_size);
+  OS::MemMove(reloc_info_writer.pos() + rc_delta,
+              reloc_info_writer.pos(), desc.reloc_size);
 
   // Switch buffers.
   DeleteArray(buffer_);
index 194edefd6bc38e87c3ea3384f33b7cca8c1a1ee0..59cfcd900025d3a42e02a691c9b5651d7697c613 100644 (file)
@@ -113,7 +113,7 @@ void LCodeGen::Comment(const char* format, ...) {
   // issues when the stack allocated buffer goes out of scope.
   size_t length = builder.position();
   Vector<char> copy = Vector<char>::New(length + 1);
-  memcpy(copy.start(), builder.Finalize(), copy.length());
+  OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
   masm()->RecordComment(copy.start());
 }
 
index 0a2f075cf737b4c0107b56ccc58be2712242dffc..bc384357c2b348ccbfb76633d019bd644c9f1227 100644 (file)
@@ -867,7 +867,7 @@ void Simulator::CheckICache(v8::internal::HashMap* i_cache,
                  Instruction::kInstrSize) == 0);
   } else {
     // Cache miss.  Load memory into the cache.
-    memcpy(cached_line, line, CachePage::kLineLength);
+    OS::MemCopy(cached_line, line, CachePage::kLineLength);
     *cache_valid_byte = CachePage::LINE_VALID;
   }
 }
@@ -1059,8 +1059,8 @@ double Simulator::get_double_from_register_pair(int reg) {
   // Read the bits from the unsigned integer register_[] array
   // into the double precision floating point value and return it.
   char buffer[2 * sizeof(registers_[0])];
-  memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
-  memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
+  OS::MemCopy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
+  OS::MemCopy(&dm_val, buffer, 2 * sizeof(registers_[0]));
   return(dm_val);
 }
 
@@ -1108,14 +1108,14 @@ void Simulator::GetFpArgs(double* x, double* y, int32_t* z) {
     // Registers a0 and a1 -> x.
     reg_buffer[0] = get_register(a0);
     reg_buffer[1] = get_register(a1);
-    memcpy(x, buffer, sizeof(buffer));
+    OS::MemCopy(x, buffer, sizeof(buffer));
     // Registers a2 and a3 -> y.
     reg_buffer[0] = get_register(a2);
     reg_buffer[1] = get_register(a3);
-    memcpy(y, buffer, sizeof(buffer));
+    OS::MemCopy(y, buffer, sizeof(buffer));
     // Register 2 -> z.
     reg_buffer[0] = get_register(a2);
-    memcpy(z, buffer, sizeof(*z));
+    OS::MemCopy(z, buffer, sizeof(*z));
   }
 }
 
@@ -1127,7 +1127,7 @@ void Simulator::SetFpResult(const double& result) {
   } else {
     char buffer[2 * sizeof(registers_[0])];
     int32_t* reg_buffer = reinterpret_cast<int32_t*>(buffer);
-    memcpy(buffer, &result, sizeof(buffer));
+    OS::MemCopy(buffer, &result, sizeof(buffer));
     // Copy result to v0 and v1.
     set_register(v0, reg_buffer[0]);
     set_register(v1, reg_buffer[1]);
@@ -2867,9 +2867,9 @@ double Simulator::CallFP(byte* entry, double d0, double d1) {
   } else {
     int buffer[2];
     ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0));
-    memcpy(buffer, &d0, sizeof(d0));
+    OS::MemCopy(buffer, &d0, sizeof(d0));
     set_dw_register(a0, buffer);
-    memcpy(buffer, &d1, sizeof(d1));
+    OS::MemCopy(buffer, &d1, sizeof(d1));
     set_dw_register(a2, buffer);
   }
   CallInternal(entry);
index cd5bbf40abad07a12afa5e6f45f359bbe8dc2908..a39c75b5d33ec37d594faeeaca302919fabfa596 100644 (file)
@@ -14088,7 +14088,7 @@ Handle<DeclaredAccessorDescriptor> DeclaredAccessorDescriptor::Create(
     if (previous_length != 0) {
       uint8_t* previous_array =
           previous->serialized_data()->GetDataStartAddress();
-      memcpy(array, previous_array, previous_length);
+      OS::MemCopy(array, previous_array, previous_length);
       array += previous_length;
     }
     ASSERT(reinterpret_cast<uintptr_t>(array) % sizeof(uintptr_t) == 0);
index 1b6c1c8352d73350c12ab0d0dcdff70dd40b727b..48898ed9aad0acdb4cc06ccba4b01c9818f26de4 100644 (file)
@@ -322,25 +322,32 @@ int OS::VSNPrintF(Vector<char> str,
 
 
 #if defined(V8_TARGET_ARCH_IA32)
-static OS::MemCopyFunction memcopy_function = NULL;
+static void MemMoveWrapper(void* dest, const void* src, size_t size) {
+  memmove(dest, src, size);
+}
+
+// Initialize to library version so we can call this at any time during startup.
+static OS::MemMoveFunction memmove_function = &MemMoveWrapper;
+
 // Defined in codegen-ia32.cc.
-OS::MemCopyFunction CreateMemCopyFunction();
+OS::MemMoveFunction CreateMemMoveFunction();
 
-// Copy memory area to disjoint memory area.
-void OS::MemCopy(void* dest, const void* src, size_t size) {
+// Copy memory area. No restrictions.
+void OS::MemMove(void* dest, const void* src, size_t size) {
   // Note: here we rely on dependent reads being ordered. This is true
   // on all architectures we currently support.
-  (*memcopy_function)(dest, src, size);
-#ifdef DEBUG
-  CHECK_EQ(0, memcmp(dest, src, size));
-#endif
+  (*memmove_function)(dest, src, size);
 }
+
 #endif  // V8_TARGET_ARCH_IA32
 
 
 void POSIXPostSetUp() {
 #if defined(V8_TARGET_ARCH_IA32)
-  memcopy_function = CreateMemCopyFunction();
+  OS::MemMoveFunction generated_memmove = CreateMemMoveFunction();
+  if (generated_memmove != NULL) {
+    memmove_function = generated_memmove;
+  }
 #endif
   init_fast_sin_function();
   init_fast_cos_function();
index 78d1ac5f68dd6bf9510a0e1a81127883e492b3f2..272678fe649294017e9758000823da0706ab376c 100644 (file)
@@ -148,19 +148,23 @@ double ceiling(double x) {
 static Mutex* limit_mutex = NULL;
 
 #if defined(V8_TARGET_ARCH_IA32)
-static OS::MemCopyFunction memcopy_function = NULL;
+static void MemMoveWrapper(void* dest, const void* src, size_t size) {
+  memmove(dest, src, size);
+}
+
+// Initialize to library version so we can call this at any time during startup.
+static OS::MemMoveFunction memmove_function = &MemMoveWrapper;
+
 // Defined in codegen-ia32.cc.
-OS::MemCopyFunction CreateMemCopyFunction();
+OS::MemMoveFunction CreateMemMoveFunction();
 
 // Copy memory area to disjoint memory area.
-void OS::MemCopy(void* dest, const void* src, size_t size) {
+void OS::MemMove(void* dest, const void* src, size_t size) {
   // Note: here we rely on dependent reads being ordered. This is true
   // on all architectures we currently support.
-  (*memcopy_function)(dest, src, size);
-#ifdef DEBUG
-  CHECK_EQ(0, memcmp(dest, src, size));
-#endif
+  (*memmove_function)(dest, src, size);
 }
+
 #endif  // V8_TARGET_ARCH_IA32
 
 #ifdef _WIN64
@@ -576,7 +580,10 @@ void OS::PostSetUp() {
   // CPU.
   MathSetup();
 #if defined(V8_TARGET_ARCH_IA32)
-  memcopy_function = CreateMemCopyFunction();
+  OS::MemMoveFunction generated_memmove = CreateMemMoveFunction();
+  if (generated_memmove != NULL) {
+    memmove_function = generated_memmove;
+  }
 #endif
 }
 
@@ -1062,7 +1069,7 @@ OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
   if (file_mapping == NULL) return NULL;
   // Map a view of the file into memory
   void* memory = MapViewOfFile(file_mapping, FILE_MAP_ALL_ACCESS, 0, 0, size);
-  if (memory) memmove(memory, initial, size);
+  if (memory) OS::MemMove(memory, initial, size);
   return new Win32MemoryMappedFile(file, file_mapping, memory, size);
 }
 
index 266c13aa058ad8ed4066642030d122f84f70b66b..736889c9122271a588241593143f6ae63dade793 100644 (file)
@@ -329,17 +329,27 @@ class OS {
   static void ReleaseStore(volatile AtomicWord* ptr, AtomicWord value);
 
 #if defined(V8_TARGET_ARCH_IA32)
-  // Copy memory area to disjoint memory area.
-  static void MemCopy(void* dest, const void* src, size_t size);
   // Limit below which the extra overhead of the MemCopy function is likely
   // to outweigh the benefits of faster copying.
   static const int kMinComplexMemCopy = 64;
-  typedef void (*MemCopyFunction)(void* dest, const void* src, size_t size);
 
+  // Copy memory area. No restrictions.
+  static 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.
+  static void MemCopy(void* dest, const void* src, size_t size) {
+    MemMove(dest, src, size);
+  }
 #else  // V8_TARGET_ARCH_IA32
+  // Copy memory area to disjoint memory area.
   static void MemCopy(void* dest, const void* src, size_t size) {
     memcpy(dest, src, size);
   }
+  static void MemMove(void* dest, const void* src, size_t size) {
+    memmove(dest, src, size);
+  }
   static const int kMinComplexMemCopy = 16 * kPointerSize;
 #endif  // V8_TARGET_ARCH_IA32
 
index d0425b4b22cd1cf1e0d4734b51c5773b5b3fda04..287ad6698aceb9bc3913f48f52fdde25dd2d92ec 100644 (file)
@@ -95,7 +95,7 @@ Vector<unsigned> PartialParserRecorder::ExtractData() {
   Vector<unsigned> data = Vector<unsigned>::New(total_size);
   preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size;
   preamble_[PreparseDataConstants::kSymbolCountOffset] = 0;
-  memcpy(data.start(), preamble_, sizeof(preamble_));
+  OS::MemCopy(data.start(), preamble_, sizeof(preamble_));
   int symbol_start = PreparseDataConstants::kHeaderSize + function_size;
   if (function_size > 0) {
     function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize,
@@ -151,7 +151,7 @@ Vector<unsigned> CompleteParserRecorder::ExtractData() {
   Vector<unsigned> data = Vector<unsigned>::New(total_size);
   preamble_[PreparseDataConstants::kFunctionsSizeOffset] = function_size;
   preamble_[PreparseDataConstants::kSymbolCountOffset] = symbol_id_;
-  memcpy(data.start(), preamble_, sizeof(preamble_));
+  OS::MemCopy(data.start(), preamble_, sizeof(preamble_));
   int symbol_start = PreparseDataConstants::kHeaderSize + function_size;
   if (function_size > 0) {
     function_store_.WriteTo(data.SubVector(PreparseDataConstants::kHeaderSize,
index f9c26c0e90a7b8093907a86c28801673f03c7592..462dfe2290fb562171eda39a7aeb96bd601c3543 100644 (file)
@@ -100,9 +100,9 @@ class InputStreamUtf16Buffer : public Utf16CharacterStream {
         // Hit the bottom of the allocated pushback buffer.
         // Double the buffer and continue.
         uc16* new_buffer = NewArray<uc16>(pushback_buffer_backing_size_ * 2);
-        memcpy(new_buffer + pushback_buffer_backing_size_,
-               pushback_buffer_backing_,
-               pushback_buffer_backing_size_);
+        OS::MemCopy(new_buffer + pushback_buffer_backing_size_,
+                    pushback_buffer_backing_,
+                    pushback_buffer_backing_size_);
         DeleteArray(pushback_buffer_backing_);
         buffer_cursor_ = new_buffer + pushback_buffer_backing_size_;
         pushback_buffer_backing_ = pushback_buffer_ = new_buffer;
index 50a71ced3d2998fd9c4fad68ceb606e206f2beb8..4660c0fde11ef8d8e496d72d291d989877b60dbc 100644 (file)
@@ -505,7 +505,7 @@ void PrettyPrinter::Print(const char* format, ...) {
       const int slack = 32;
       int new_size = size_ + (size_ >> 1) + slack;
       char* new_output = NewArray<char>(new_size);
-      memcpy(new_output, output_, pos_);
+      OS::MemCopy(new_output, output_, pos_);
       DeleteArray(output_);
       output_ = new_output;
       size_ = new_size;
index 16766cab0985a1712119edf513a753495c77cc74..e678d607ada0d343ccf041bf9e9bd913a52b1c88 100644 (file)
@@ -479,7 +479,7 @@ int RegExpMacroAssemblerIrregexp::length() {
 
 
 void RegExpMacroAssemblerIrregexp::Copy(Address a) {
-  memcpy(a, buffer_.start(), length());
+  OS::MemCopy(a, buffer_.start(), length());
 }
 
 
@@ -488,7 +488,7 @@ void RegExpMacroAssemblerIrregexp::Expand() {
   Vector<byte> old_buffer = buffer_;
   buffer_ = Vector<byte>::New(old_buffer.length() * 2);
   own_buffer_ = true;
-  memcpy(buffer_.start(), old_buffer.start(), old_buffer.length());
+  OS::MemCopy(buffer_.start(), old_buffer.start(), old_buffer.length());
   if (old_buffer_was_our_own) {
     old_buffer.Dispose();
   }
index 325a1496c98c9a26d05c9fffc1c97be132e401f0..fc4114af5de202d49507b9be3a1902c43b3d1881 100644 (file)
@@ -57,9 +57,7 @@ RegExpStack::~RegExpStack() {
 
 char* RegExpStack::ArchiveStack(char* to) {
   size_t size = sizeof(thread_local_);
-  memcpy(reinterpret_cast<void*>(to),
-         &thread_local_,
-         size);
+  OS::MemCopy(reinterpret_cast<void*>(to), &thread_local_, size);
   thread_local_ = ThreadLocal();
   return to + size;
 }
@@ -67,7 +65,7 @@ char* RegExpStack::ArchiveStack(char* to) {
 
 char* RegExpStack::RestoreStack(char* from) {
   size_t size = sizeof(thread_local_);
-  memcpy(&thread_local_, reinterpret_cast<void*>(from), size);
+  OS::MemCopy(&thread_local_, reinterpret_cast<void*>(from), size);
   return from + size;
 }
 
@@ -95,10 +93,11 @@ Address RegExpStack::EnsureCapacity(size_t size) {
     Address new_memory = NewArray<byte>(static_cast<int>(size));
     if (thread_local_.memory_size_ > 0) {
       // Copy original memory into top of new memory.
-      memcpy(reinterpret_cast<void*>(
-          new_memory + size - thread_local_.memory_size_),
-             reinterpret_cast<void*>(thread_local_.memory_),
-             thread_local_.memory_size_);
+      OS::MemCopy(
+          reinterpret_cast<void*>(
+              new_memory + size - thread_local_.memory_size_),
+          reinterpret_cast<void*>(thread_local_.memory_),
+          thread_local_.memory_size_);
       DeleteArray(thread_local_.memory_);
     }
     thread_local_.memory_ = new_memory;
index e897f79872049205f762d0066e6a1de05057dfa0..92418f72b1b365ff94723df5a8d04f0072365b1e 100644 (file)
@@ -215,7 +215,7 @@ class LiteralBuffer {
 
   void ExpandBuffer() {
     Vector<byte> new_store = Vector<byte>::New(NewCapacity(kInitialCapacity));
-    memcpy(new_store.start(), backing_store_.start(), position_);
+    OS::MemCopy(new_store.start(), backing_store_.start(), position_);
     backing_store_.Dispose();
     backing_store_ = new_store;
   }
index e0bcf4e18706be56363be70269c4b96b85af3c55..dc9ffd62b10230e9d0af59c7b2dee79b5df36ad3 100644 (file)
@@ -311,7 +311,7 @@ int SnapshotByteSource::GetInt() {
 
 
 void SnapshotByteSource::CopyRaw(byte* to, int number_of_bytes) {
-  memcpy(to, data_ + position_, number_of_bytes);
+  OS::MemCopy(to, data_ + position_, number_of_bytes);
   position_ += number_of_bytes;
 }
 
index bcc30f9ab372dd46605c95fe9bf3faf9d914840d..61eec0d696d52fa10a0a439d38fdfd8640efa936 100644 (file)
@@ -254,7 +254,7 @@ void StringStream::Add(const char* format, FmtElm arg0, FmtElm arg1,
 
 SmartArrayPointer<const char> StringStream::ToCString() const {
   char* str = NewArray<char>(length_ + 1);
-  memcpy(str, buffer_, length_);
+  OS::MemCopy(str, buffer_, length_);
   str[length_] = '\0';
   return SmartArrayPointer<const char>(str);
 }
@@ -575,7 +575,7 @@ char* HeapStringAllocator::grow(unsigned* bytes) {
   if (new_space == NULL) {
     return space_;
   }
-  memcpy(new_space, space_, *bytes);
+  OS::MemCopy(new_space, space_, *bytes);
   *bytes = new_bytes;
   DeleteArray(space_);
   space_ = new_space;
index 02be45768883804d8136f66bf6c5a67023b73bc8..f861f9f2d47449945d62a6fbc8044abbcd0b2a2b 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "unicode.h"
 #include "checks.h"
+#include "platform.h"
 
 namespace unibrow {
 
@@ -202,7 +203,7 @@ unsigned Utf8Decoder<kBufferSize>::WriteUtf16(uint16_t* data,
   unsigned buffer_length =
       last_byte_of_buffer_unused_ ? kBufferSize - 1 : kBufferSize;
   unsigned memcpy_length = length <= buffer_length  ? length : buffer_length;
-  memcpy(data, buffer_, memcpy_length*sizeof(uint16_t));
+  v8::internal::OS::MemCopy(data, buffer_, memcpy_length*sizeof(uint16_t));
   if (length <= buffer_length) return length;
   ASSERT(unbuffered_start_ != NULL);
   // Copy the rest the slow way.
index 71eaea55d261989a58af4381e20b147fc1b3ddb0..8462615200abb254ce490e159f327e1c50b45e6d 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdarg.h>
 #include "../include/v8stdint.h"
 #include "checks.h"
+#include "platform.h"
 #include "utils.h"
 
 namespace v8 {
@@ -48,7 +49,7 @@ void SimpleStringBuilder::AddString(const char* s) {
 void SimpleStringBuilder::AddSubstring(const char* s, int n) {
   ASSERT(!is_finalized() && position_ + n <= buffer_.length());
   ASSERT(static_cast<size_t>(n) <= strlen(s));
-  memcpy(&buffer_[position_], s, n * kCharSize);
+  OS::MemCopy(&buffer_[position_], s, n * kCharSize);
   position_ += n;
 }
 
index 0781c37bd1433f5abc8f8786dd05c2baccfba537..b84d59238653ce5dad71b3f12d23a2133a9456c8 100644 (file)
@@ -32,9 +32,9 @@
 #include <string.h>
 #include <climits>
 
-#include "globals.h"
-#include "checks.h"
 #include "allocation.h"
+#include "checks.h"
+#include "globals.h"
 
 namespace v8 {
 namespace internal {
@@ -494,6 +494,7 @@ class EmbeddedVector : public Vector<T> {
   // When copying, make underlying Vector to reference our buffer.
   EmbeddedVector(const EmbeddedVector& rhs)
       : Vector<T>(rhs) {
+    // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead.
     memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
     set_start(buffer_);
   }
@@ -501,6 +502,7 @@ class EmbeddedVector : public Vector<T> {
   EmbeddedVector& operator=(const EmbeddedVector& rhs) {
     if (this == &rhs) return *this;
     Vector<T>::operator=(rhs);
+    // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead.
     memcpy(buffer_, rhs.buffer_, sizeof(T) * kSize);
     this->set_start(buffer_);
     return *this;
@@ -876,6 +878,7 @@ struct BitCastHelper {
 
   INLINE(static Dest cast(const Source& source)) {
     Dest dest;
+    // TODO(jkummerow): Refactor #includes and use OS::MemCopy() instead.
     memcpy(&dest, &source, sizeof(dest));
     return dest;
   }
index 8d97f54b81f40765b900310da4c120116846397f..7390d854e63eb850adffe1ecca53138ebcdd5a6a 100644 (file)
@@ -105,12 +105,12 @@ char* ReadLine(const char* prompt) {
       char* new_result = NewArray<char>(new_len);
       // Copy the existing input into the new array and set the new
       // array as the result.
-      memcpy(new_result, result, offset * kCharSize);
+      OS::MemCopy(new_result, result, offset * kCharSize);
       DeleteArray(result);
       result = new_result;
     }
     // Copy the newly read line into the result.
-    memcpy(result + offset, line_buf, len * kCharSize);
+    OS::MemCopy(result + offset, line_buf, len * kCharSize);
     offset += len;
   }
   ASSERT(result != NULL);
index 0dbd60e21448d21712501007b7103aebb7b5d083..8661f9b88c2baba1cc3c656ab727a703d55887b8 100644 (file)
@@ -125,49 +125,126 @@ inline Vector< Handle<Object> > HandleVector(v8::internal::Handle<T>* elms,
 // ----------------------------------------------------------------------------
 // Memory
 
-// Copies data from |src| to |dst|.  The data spans must not overlap.
+// Copies words from |src| to |dst|. The data spans must not overlap.
 template <typename T>
-inline void CopyWords(T* dst, T* src, int num_words) {
+inline void CopyWords(T* dst, const T* src, size_t num_words) {
   STATIC_ASSERT(sizeof(T) == kPointerSize);
-  ASSERT(Min(dst, src) + num_words <= Max(dst, src));
+  ASSERT(Min(dst, const_cast<T*>(src)) + num_words <=
+         Max(dst, const_cast<T*>(src)));
   ASSERT(num_words > 0);
 
   // Use block copying OS::MemCopy if the segment we're copying is
   // enough to justify the extra call/setup overhead.
-  static const int kBlockCopyLimit = 16;
-  STATIC_ASSERT(kBlockCopyLimit * kPointerSize >= OS::kMinComplexMemCopy);
+  static const size_t kBlockCopyLimit = 16;
 
-  if (num_words >= kBlockCopyLimit) {
-    OS::MemCopy(dst, src, num_words * kPointerSize);
+  if (num_words < kBlockCopyLimit) {
+    do {
+      num_words--;
+      *dst++ = *src++;
+    } while (num_words > 0);
   } else {
-    int remaining = num_words;
+    OS::MemCopy(dst, src, num_words * kPointerSize);
+  }
+}
+
+
+// Copies words from |src| to |dst|. No restrictions.
+template <typename T>
+inline void MoveWords(T* dst, const T* src, size_t num_words) {
+  STATIC_ASSERT(sizeof(T) == kPointerSize);
+  ASSERT(num_words > 0);
+
+  // Use block copying OS::MemCopy if the segment we're copying is
+  // enough to justify the extra call/setup overhead.
+  static const size_t kBlockCopyLimit = 16;
+
+  if (num_words < kBlockCopyLimit &&
+      ((dst < src) || (dst >= (src + num_words * kPointerSize)))) {
+    T* end = dst + num_words;
     do {
-      remaining--;
+      num_words--;
       *dst++ = *src++;
-    } while (remaining > 0);
+    } while (num_words > 0);
+  } else {
+    OS::MemMove(dst, src, num_words * kPointerSize);
   }
 }
 
 
 // Copies data from |src| to |dst|.  The data spans must not overlap.
 template <typename T>
-inline void CopyBytes(T* dst, T* src, size_t num_bytes) {
+inline void CopyBytes(T* dst, const T* src, size_t num_bytes) {
   STATIC_ASSERT(sizeof(T) == 1);
-  ASSERT(Min(dst, src) + num_bytes <= Max(dst, src));
+  ASSERT(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
   // enough to justify the extra call/setup overhead.
   static const int kBlockCopyLimit = OS::kMinComplexMemCopy;
 
-  if (num_bytes >= static_cast<size_t>(kBlockCopyLimit)) {
-    OS::MemCopy(dst, src, num_bytes);
-  } else {
-    size_t remaining = num_bytes;
+  if (num_bytes < static_cast<size_t>(kBlockCopyLimit)) {
     do {
-      remaining--;
+      num_bytes--;
       *dst++ = *src++;
-    } while (remaining > 0);
+    } while (num_bytes > 0);
+  } else {
+    OS::MemCopy(dst, src, num_bytes);
+  }
+}
+
+
+// Copies data from |src| to |dst|. No restrictions.
+template <typename T>
+inline void MoveBytes(T* dst, const T* src, size_t num_bytes) {
+  STATIC_ASSERT(sizeof(T) == 1);
+  switch (num_bytes) {
+  case 0: return;
+  case 1:
+    *dst = *src;
+    return;
+#ifdef V8_HOST_CAN_READ_UNALIGNED
+  case 2:
+    *reinterpret_cast<uint16_t*>(dst) = *reinterpret_cast<const uint16_t*>(src);
+    return;
+  case 3: {
+    uint16_t part1 = *reinterpret_cast<const uint16_t*>(src);
+    byte part2 = *(src + 2);
+    *reinterpret_cast<uint16_t*>(dst) = part1;
+    *(dst + 2) = part2;
+    return;
+  }
+  case 4:
+    *reinterpret_cast<uint32_t*>(dst) = *reinterpret_cast<const uint32_t*>(src);
+    return;
+  case 5:
+  case 6:
+  case 7:
+  case 8: {
+    uint32_t part1 = *reinterpret_cast<const uint32_t*>(src);
+    uint32_t part2 = *reinterpret_cast<const uint32_t*>(src + num_bytes - 4);
+    *reinterpret_cast<uint32_t*>(dst) = part1;
+    *reinterpret_cast<uint32_t*>(dst + num_bytes - 4) = part2;
+    return;
+  }
+  case 9:
+  case 10:
+  case 11:
+  case 12:
+  case 13:
+  case 14:
+  case 15:
+  case 16: {
+    double part1 = *reinterpret_cast<const double*>(src);
+    double part2 = *reinterpret_cast<const double*>(src + num_bytes - 8);
+    *reinterpret_cast<double*>(dst) = part1;
+    *reinterpret_cast<double*>(dst + num_bytes - 8) = part2;
+    return;
+  }
+#endif
+  default:
+    OS::MemMove(dst, src, num_bytes);
+    return;
   }
 }
 
index eee1584cf1fa5c34e870568f8b58b8672a47b0a1..20d801bd8868f29ceb72df7a1643d0f38f566ebe 100644 (file)
@@ -485,9 +485,9 @@ void Assembler::GrowBuffer() {
   intptr_t pc_delta = desc.buffer - buffer_;
   intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
       (buffer_ + buffer_size_);
-  memmove(desc.buffer, buffer_, desc.instr_size);
-  memmove(rc_delta + reloc_info_writer.pos(),
-          reloc_info_writer.pos(), desc.reloc_size);
+  OS::MemMove(desc.buffer, buffer_, desc.instr_size);
+  OS::MemMove(rc_delta + reloc_info_writer.pos(),
+              reloc_info_writer.pos(), desc.reloc_size);
 
   // Switch buffers.
   if (isolate() != NULL &&
index d2325b821f41a43a6d138924cf6275eec97aeb52..6fc56ed1eb75e59975b0599e231d1f49363dac46 100644 (file)
@@ -118,7 +118,7 @@ void LCodeGen::Comment(const char* format, ...) {
   // issues when the stack allocated buffer goes out of scope.
   int length = builder.position();
   Vector<char> copy = Vector<char>::New(length + 1);
-  memcpy(copy.start(), builder.Finalize(), copy.length());
+  OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
   masm()->RecordComment(copy.start());
 }
 
index 378968a32737b6c7a659377dd26ceead0f98626f..1bd14ee299b9814a50cd6c99904e194136ae9b76 100644 (file)
@@ -12795,7 +12795,7 @@ TEST(PreCompileSerialization) {
   // Serialize.
   int serialized_data_length = sd->Length();
   char* serialized_data = i::NewArray<char>(serialized_data_length);
-  memcpy(serialized_data, sd->Data(), serialized_data_length);
+  i::OS::MemCopy(serialized_data, sd->Data(), serialized_data_length);
 
   // Deserialize.
   v8::ScriptData* deserialized_sd =
@@ -15735,14 +15735,14 @@ TEST(VisitExternalStrings) {
 
 static double DoubleFromBits(uint64_t value) {
   double target;
-  memcpy(&target, &value, sizeof(target));
+  i::OS::MemCopy(&target, &value, sizeof(target));
   return target;
 }
 
 
 static uint64_t DoubleToBits(double value) {
   uint64_t target;
-  memcpy(&target, &value, sizeof(target));
+  i::OS::MemCopy(&target, &value, sizeof(target));
   return target;
 }
 
index b81c1695de34a64926cac5605b233bf5c1c3538c..f200435489c48b97686e3daf53e3a6becbf534a1 100644 (file)
@@ -330,7 +330,7 @@ TEST(GetScriptLineNumber) {
   for (int i = 0; i < max_rows; ++i) {
     if (i > 0)
       buffer[i - 1] = '\n';
-    memcpy(&buffer[i], function_f, sizeof(function_f) - 1);
+    OS::MemCopy(&buffer[i], function_f, sizeof(function_f) - 1);
     v8::Handle<v8::String> script_body = v8::String::New(buffer.start());
     v8::Script::Compile(script_body, &origin)->Run();
     v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
index 32344420f4ae918af4ab66bb13b5ce338d691394..59e7b8f25498896a962ae736a1af8a335cdc21ba 100644 (file)
@@ -571,7 +571,7 @@ class TestJSONStream : public v8::OutputStream {
     if (abort_countdown_ == 0) return kAbort;
     CHECK_GT(chars_written, 0);
     i::Vector<char> chunk = buffer_.AddBlock(chars_written, '\0');
-    memcpy(chunk.start(), buffer, chars_written);
+    i::OS::MemCopy(chunk.start(), buffer, chars_written);
     return kContinue;
   }
   virtual WriteResult WriteUint32Chunk(uint32_t* buffer, int chars_written) {
index 610b8ceb60406d733ff170c99cbb041f09c4ab13..c7331bdb91b33bb5af60316343331b629d7547f5 100644 (file)
@@ -83,7 +83,7 @@ TEST(ScanKeywords) {
     // Adding characters will make keyword matching fail.
     static const char chars_to_append[] = { 'z', '0', '_' };
     for (int j = 0; j < static_cast<int>(ARRAY_SIZE(chars_to_append)); ++j) {
-      memmove(buffer, keyword, length);
+      i::OS::MemMove(buffer, keyword, length);
       buffer[length] = chars_to_append[j];
       i::Utf8ToUtf16CharacterStream stream(buffer, length + 1);
       i::Scanner scanner(&unicode_cache);
@@ -93,7 +93,7 @@ TEST(ScanKeywords) {
     }
     // Replacing characters will make keyword matching fail.
     {
-      memmove(buffer, keyword, length);
+      i::OS::MemMove(buffer, keyword, length);
       buffer[length - 1] = '_';
       i::Utf8ToUtf16CharacterStream stream(buffer, length);
       i::Scanner scanner(&unicode_cache);
index c83acb909ab466a427b35252f2f8378950051679..541c42338c9dae8871ade0fac962f94df11b59a6 100644 (file)
@@ -98,57 +98,68 @@ TEST(SNPrintF) {
 }
 
 
-void TestMemCopy(Vector<byte> src,
-                 Vector<byte> dst,
-                 int source_alignment,
-                 int destination_alignment,
-                 int length_alignment) {
-  memset(dst.start(), 0xFF, dst.length());
-  byte* to = dst.start() + 32 + destination_alignment;
-  byte* from = src.start() + source_alignment;
-  int length = OS::kMinComplexMemCopy + length_alignment;
-  OS::MemCopy(to, from, static_cast<size_t>(length));
-  printf("[%d,%d,%d]\n",
-         source_alignment, destination_alignment, length_alignment);
-  for (int i = 0; i < length; i++) {
-    CHECK_EQ(from[i], to[i]);
+static const int kAreaSize = 512;
+
+
+void TestMemMove(byte* area1,
+                 byte* area2,
+                 byte* area3,
+                 int src_offset,
+                 int dest_offset,
+                 int length) {
+  for (int i = 0; i < kAreaSize; i++) {
+    area1[i] = i & 0xFF;
+    area2[i] = i & 0xFF;
+    area3[i] = i & 0xFF;
+  }
+  OS::MemMove(area1 + dest_offset, area1 + src_offset, length);
+  MoveBytes(area2 + dest_offset, area2 + src_offset, length);
+  memmove(area3 + dest_offset, area3 + src_offset, length);
+  if (memcmp(area1, area3, kAreaSize) != 0) {
+    printf("OS::MemMove(): src_offset: %d, dest_offset: %d, length: %d\n",
+           src_offset, dest_offset, length);
+    for (int i = 0; i < kAreaSize; i++) {
+      if (area1[i] == area3[i]) continue;
+      printf("diff at offset %d (%p): is %d, should be %d\n",
+             i, reinterpret_cast<void*>(area1 + i), area1[i], area3[i]);
+    }
+    CHECK(false);
+  }
+  if (memcmp(area2, area3, kAreaSize) != 0) {
+    printf("MoveBytes(): src_offset: %d, dest_offset: %d, length: %d\n",
+           src_offset, dest_offset, length);
+    for (int i = 0; i < kAreaSize; i++) {
+      if (area2[i] == area3[i]) continue;
+      printf("diff at offset %d (%p): is %d, should be %d\n",
+             i, reinterpret_cast<void*>(area2 + i), area2[i], area3[i]);
+    }
+    CHECK(false);
   }
-  CHECK_EQ(0xFF, to[-1]);
-  CHECK_EQ(0xFF, to[length]);
 }
 
 
-
-TEST(MemCopy) {
+TEST(MemMove) {
   v8::V8::Initialize();
   OS::SetUp();
-  const int N = OS::kMinComplexMemCopy + 128;
-  Vector<byte> buffer1 = Vector<byte>::New(N);
-  Vector<byte> buffer2 = Vector<byte>::New(N);
-
-  for (int i = 0; i < N; i++) {
-    buffer1[i] = static_cast<byte>(i & 0x7F);
-  }
-
-  // Same alignment.
-  for (int i = 0; i < 32; i++) {
-    TestMemCopy(buffer1, buffer2, i, i, i * 2);
-  }
-
-  // Different alignment.
-  for (int i = 0; i < 32; i++) {
-    for (int j = 1; j < 32; j++) {
-      TestMemCopy(buffer1, buffer2, i, (i + j) & 0x1F , 0);
+  byte* area1 = new byte[kAreaSize];
+  byte* area2 = new byte[kAreaSize];
+  byte* area3 = new byte[kAreaSize];
+
+  static const int kMinOffset = 32;
+  static const int kMaxOffset = 64;
+  static const int kMaxLength = 128;
+  STATIC_ASSERT(kMaxOffset + kMaxLength < kAreaSize);
+
+  for (int src_offset = kMinOffset; src_offset <= kMaxOffset; src_offset++) {
+    for (int dst_offset = kMinOffset; dst_offset <= kMaxOffset; dst_offset++) {
+      for (int length = 0; length <= kMaxLength; length++) {
+        TestMemMove(area1, area2, area3, src_offset, dst_offset, length);
+      }
     }
   }
-
-  // Different lengths
-  for (int i = 0; i < 32; i++) {
-    TestMemCopy(buffer1, buffer2, 3, 7, i);
-  }
-
-  buffer2.Dispose();
-  buffer1.Dispose();
+  delete[] area1;
+  delete[] area2;
+  delete[] area3;
 }