Revision: 7437
Author: [email protected]
Date: Wed Mar 30 07:04:26 2011
Log: Add thread-safety to creation of MemCopy and modulo functions.
BUG=
TEST=release test-api MultipleIsolatesOnIndividualThreads on Windows X64
build.
Review URL: http://codereview.chromium.org/6777007
http://code.google.com/p/v8/source/detail?r=7437
Modified:
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/platform-posix.cc
/branches/bleeding_edge/src/platform-win32.cc
/branches/bleeding_edge/src/platform.h
/branches/bleeding_edge/src/v8utils.h
/branches/bleeding_edge/src/x64/codegen-x64.cc
/branches/bleeding_edge/test/cctest/test-utils.cc
=======================================
--- /branches/bleeding_edge/src/api.cc Wed Mar 30 03:46:55 2011
+++ /branches/bleeding_edge/src/api.cc Wed Mar 30 07:04:26 2011
@@ -1302,7 +1302,7 @@
}
// Copy the data to align it.
unsigned* deserialized_data =
i::NewArray<unsigned>(deserialized_data_length);
- i::MemCopy(deserialized_data, data, length);
+ i::OS::MemCopy(deserialized_data, data, length);
return new i::ScriptDataImpl(
i::Vector<unsigned>(deserialized_data, deserialized_data_length));
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Mar 23 06:40:07
2011
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Mar 30 07:04:26
2011
@@ -10174,7 +10174,7 @@
}
-MemCopyFunction CreateMemCopyFunction() {
+OS::MemCopyFunction CreateMemCopyFunction() {
HandleScope scope;
MacroAssembler masm(NULL, 1 * KB);
@@ -10198,7 +10198,7 @@
if (FLAG_debug_code) {
__ cmp(Operand(esp, kSizeOffset + stack_offset),
- Immediate(kMinComplexMemCopy));
+ Immediate(OS::kMinComplexMemCopy));
Label ok;
__ j(greater_equal, &ok);
__ int3();
@@ -10377,7 +10377,8 @@
if (chunk == NULL) return &MemCopyWrapper;
memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size);
CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size);
- return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress());
+ MemoryBarrier();
+ return FUNCTION_CAST<OS::MemCopyFunction>(chunk->GetStartAddress());
}
#undef __
=======================================
--- /branches/bleeding_edge/src/platform-posix.cc Fri Mar 18 13:35:07 2011
+++ /branches/bleeding_edge/src/platform-posix.cc Wed Mar 30 07:04:26 2011
@@ -1,4 +1,4 @@
-// Copyright 2009 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -205,6 +205,29 @@
}
+#if defined(V8_TARGET_ARCH_IA32)
+static OS::MemCopyFunction memcopy_function = NULL;
+static Mutex* memcopy_function_mutex = OS::CreateMutex();
+// Defined in codegen-ia32.cc.
+OS::MemCopyFunction CreateMemCopyFunction();
+
+// Copy memory area to disjoint memory area.
+void OS::MemCopy(void* dest, const void* src, size_t size) {
+ if (memcopy_function == NULL) {
+ ScopedLock lock(memcopy_function_mutex);
+ Isolate::EnsureDefaultIsolate();
+ if (memcopy_function == NULL) {
+ Release_Store(reinterpret_cast<AtomicWord*>(&memcopy_function),
+ reinterpret_cast<AtomicWord>(CreateMemCopyFunction()));
+ }
+ }
+ (*memcopy_function)(dest, src, size);
+#ifdef DEBUG
+ CHECK_EQ(0, memcmp(dest, src, size));
+#endif
+}
+#endif // V8_TARGET_ARCH_IA32
+
//
----------------------------------------------------------------------------
// POSIX string support.
//
=======================================
--- /branches/bleeding_edge/src/platform-win32.cc Mon Mar 21 16:44:14 2011
+++ /branches/bleeding_edge/src/platform-win32.cc Wed Mar 30 07:04:26 2011
@@ -176,16 +176,45 @@
static Mutex* limit_mutex = NULL;
+#if defined(V8_TARGET_ARCH_IA32)
+static OS::MemCopyFunction memcopy_function = NULL;
+static Mutex* memcopy_function_mutex = OS::CreateMutex();
+// Defined in codegen-ia32.cc.
+OS::MemCopyFunction CreateMemCopyFunction();
+
+// Copy memory area to disjoint memory area.
+void OS::MemCopy(void* dest, const void* src, size_t size) {
+ if (memcopy_function == NULL) {
+ ScopedLock lock(memcopy_function_mutex);
+ Isolate::EnsureDefaultIsolate();
+ if (memcopy_function == NULL) {
+ memcopy_function = CreateMemCopyFunction();
+ }
+ }
+ (*memcopy_function)(dest, src, size);
+#ifdef DEBUG
+ CHECK_EQ(0, memcmp(dest, src, size));
+#endif
+}
+#endif // V8_TARGET_ARCH_IA32
#ifdef _WIN64
typedef double (*ModuloFunction)(double, double);
-
+static ModuloFunction modulo_function = NULL;
+static Mutex* modulo_function_mutex = OS::CreateMutex();
// Defined in codegen-x64.cc.
ModuloFunction CreateModuloFunction();
double modulo(double x, double y) {
- static ModuloFunction function = CreateModuloFunction();
- return function(x, y);
+ if (modulo_function == NULL) {
+ ScopedLock lock(modulo_function_mutex);
+ Isolate::EnsureDefaultIsolate();
+ if (modulo_function == NULL) {
+ Release_Store(reinterpret_cast<AtomicWord*>(&modulo_function),
+ reinterpret_cast<AtomicWord>(CreateModuloFunction()));
+ }
+ }
+ return (*modulo_function)(x, y);
}
#else // Win32
=======================================
--- /branches/bleeding_edge/src/platform.h Wed Mar 30 06:30:52 2011
+++ /branches/bleeding_edge/src/platform.h Wed Mar 30 07:04:26 2011
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -303,6 +303,21 @@
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);
+
+#else // V8_TARGET_ARCH_IA32
+ static void MemCopy(void* dest, const void* src, size_t size) {
+ memcpy(dest, src, size);
+ }
+ static const int kMinComplexMemCopy = 256;
+#endif // V8_TARGET_ARCH_IA32
+
private:
static const int msPerSecond = 1000;
=======================================
--- /branches/bleeding_edge/src/v8utils.h Fri Mar 18 12:41:05 2011
+++ /branches/bleeding_edge/src/v8utils.h Wed Mar 30 07:04:26 2011
@@ -254,51 +254,14 @@
};
-// Custom memcpy implementation for platforms where the standard version
-// may not be good enough.
-#if defined(V8_TARGET_ARCH_IA32)
-
-// The default memcpy on ia32 architectures is generally not as efficient
-// as possible. (If any further ia32 platforms are introduced where the
-// memcpy function is efficient, exclude them from this branch).
-
-typedef void (*MemCopyFunction)(void* dest, const void* src, size_t size);
-
-// Implemented in codegen-<arch>.cc.
-MemCopyFunction CreateMemCopyFunction();
-
-// Copy memory area to disjoint memory area.
-static inline void MemCopy(void* dest, const void* src, size_t size) {
- static MemCopyFunction memcopy = CreateMemCopyFunction();
- (*memcopy)(dest, src, size);
-#ifdef DEBUG
- CHECK_EQ(0, memcmp(dest, src, size));
-#endif
-}
-
-// Limit below which the extra overhead of the MemCopy function is likely
-// to outweigh the benefits of faster copying.
-static const int kMinComplexMemCopy = 64;
-
-#else // V8_TARGET_ARCH_IA32
-
-static inline void MemCopy(void* dest, const void* src, size_t size) {
- memcpy(dest, src, size);
-}
-
-static const int kMinComplexMemCopy = 256;
-
-#endif // V8_TARGET_ARCH_IA32
-
-
// Copy from ASCII/16bit chars to ASCII/16bit chars.
template <typename sourcechar, typename sinkchar>
static inline void CopyChars(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>(kMinComplexMemCopy / sizeof(*dest))) {
- MemCopy(dest, src, chars * sizeof(*dest));
+ if (chars >= static_cast<int>(OS::kMinComplexMemCopy / sizeof(*dest)))
{
+ OS::MemCopy(dest, src, chars * sizeof(*dest));
return;
}
// Number of characters in a uintptr_t.
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Wed Mar 30 03:38:25 2011
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Wed Mar 30 07:04:26 2011
@@ -8824,7 +8824,10 @@
CodeDesc desc;
masm.GetCode(&desc);
- // Call the function from C++.
+ // Make sure that the compiled code is visible to all threads before
+ // returning the pointer to it.
+ MemoryBarrier();
+ // Call the function from C++ through this pointer.
return FUNCTION_CAST<ModuloFunction>(buffer);
}
=======================================
--- /branches/bleeding_edge/test/cctest/test-utils.cc Fri Mar 18 13:35:07
2011
+++ /branches/bleeding_edge/test/cctest/test-utils.cc Wed Mar 30 07:04:26
2011
@@ -89,8 +89,8 @@
memset(dst.start(), 0xFF, dst.length());
byte* to = dst.start() + 32 + destination_alignment;
byte* from = src.start() + source_alignment;
- int length = kMinComplexMemCopy + length_alignment;
- MemCopy(to, from, static_cast<size_t>(length));
+ 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++) {
@@ -104,7 +104,7 @@
TEST(MemCopy) {
OS::Setup();
- const int N = kMinComplexMemCopy + 128;
+ const int N = OS::kMinComplexMemCopy + 128;
Vector<byte> buffer1 = Vector<byte>::New(N);
Vector<byte> buffer2 = Vector<byte>::New(N);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev