зеркало из https://github.com/electron/electron.git
Use Node's memory allocator for ArrayBuffer
For Buffers created in Node, they are usually allocated in Node and freed by Chromium's allocator, which will cause crashes when Node and Chromium are using different allocators. This commit makes Chromium use Node' allocator for ArrayBuffers.
This commit is contained in:
Родитель
8be4332765
Коммит
efe23b7595
|
@ -10,13 +10,40 @@
|
||||||
#include "base/message_loop/message_loop.h"
|
#include "base/message_loop/message_loop.h"
|
||||||
#include "base/threading/thread_task_runner_handle.h"
|
#include "base/threading/thread_task_runner_handle.h"
|
||||||
#include "content/public/common/content_switches.h"
|
#include "content/public/common/content_switches.h"
|
||||||
#include "gin/array_buffer.h"
|
|
||||||
#include "gin/v8_initializer.h"
|
#include "gin/v8_initializer.h"
|
||||||
|
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
#include "atom/node/osfhandle.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
void* ArrayBufferAllocator::Allocate(size_t length) {
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
return node::ArrayBufferCalloc(length);
|
||||||
|
#else
|
||||||
|
return calloc(1, length);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ArrayBufferAllocator::AllocateUninitialized(size_t length) {
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
return node::ArrayBufferMalloc(length);
|
||||||
|
#else
|
||||||
|
return malloc(length);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArrayBufferAllocator::Free(void* data, size_t length) {
|
||||||
|
#if defined(OS_WIN)
|
||||||
|
node::ArrayBufferFree(data, length);
|
||||||
|
#else
|
||||||
|
free(data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
JavascriptEnvironment::JavascriptEnvironment()
|
JavascriptEnvironment::JavascriptEnvironment()
|
||||||
: initialized_(Initialize()),
|
: initialized_(Initialize()),
|
||||||
isolate_holder_(base::ThreadTaskRunnerHandle::Get()),
|
isolate_holder_(base::ThreadTaskRunnerHandle::Get()),
|
||||||
|
@ -46,7 +73,7 @@ bool JavascriptEnvironment::Initialize() {
|
||||||
|
|
||||||
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
|
gin::IsolateHolder::Initialize(gin::IsolateHolder::kNonStrictMode,
|
||||||
gin::IsolateHolder::kStableV8Extras,
|
gin::IsolateHolder::kStableV8Extras,
|
||||||
gin::ArrayBufferAllocator::SharedInstance());
|
&allocator_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,14 @@ class Environment;
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
// ArrayBuffer's allocator, used on Chromium's side.
|
||||||
|
class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
|
||||||
|
public:
|
||||||
|
void* Allocate(size_t length) override;
|
||||||
|
void* AllocateUninitialized(size_t length) override;
|
||||||
|
void Free(void* data, size_t length) override;
|
||||||
|
};
|
||||||
|
|
||||||
// Manage the V8 isolate and context automatically.
|
// Manage the V8 isolate and context automatically.
|
||||||
class JavascriptEnvironment {
|
class JavascriptEnvironment {
|
||||||
public:
|
public:
|
||||||
|
@ -31,6 +39,7 @@ class JavascriptEnvironment {
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
|
ArrayBufferAllocator allocator_;
|
||||||
gin::IsolateHolder isolate_holder_;
|
gin::IsolateHolder isolate_holder_;
|
||||||
v8::Isolate* isolate_;
|
v8::Isolate* isolate_;
|
||||||
v8::Isolate::Scope isolate_scope_;
|
v8::Isolate::Scope isolate_scope_;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "third_party/icu/source/i18n/unicode/uregex.h"
|
#include "third_party/icu/source/i18n/unicode/uregex.h"
|
||||||
#include "third_party/icu/source/i18n/unicode/uspoof.h"
|
#include "third_party/icu/source/i18n/unicode/uspoof.h"
|
||||||
#include "third_party/icu/source/i18n/unicode/usearch.h"
|
#include "third_party/icu/source/i18n/unicode/usearch.h"
|
||||||
|
#include "util-inl.h"
|
||||||
#include "v8-profiler.h"
|
#include "v8-profiler.h"
|
||||||
#include "v8-inspector.h"
|
#include "v8-inspector.h"
|
||||||
|
|
||||||
|
@ -38,6 +39,18 @@ int close(int fd) {
|
||||||
return _close(fd);
|
return _close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* ArrayBufferCalloc(size_t length) {
|
||||||
|
return UncheckedCalloc(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ArrayBufferMalloc(size_t length) {
|
||||||
|
return UncheckedMalloc(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArrayBufferFree(void* data, size_t length) {
|
||||||
|
return ::free(data);
|
||||||
|
}
|
||||||
|
|
||||||
void ReferenceSymbols() {
|
void ReferenceSymbols() {
|
||||||
// Following symbols are used by electron.exe but got stripped by compiler,
|
// Following symbols are used by electron.exe but got stripped by compiler,
|
||||||
// by using the symbols we can force compiler to keep the objects in node.dll,
|
// by using the symbols we can force compiler to keep the objects in node.dll,
|
||||||
|
|
|
@ -21,6 +21,12 @@ namespace node {
|
||||||
__declspec(dllexport) int open_osfhandle(intptr_t osfhandle, int flags);
|
__declspec(dllexport) int open_osfhandle(intptr_t osfhandle, int flags);
|
||||||
__declspec(dllexport) int close(int fd);
|
__declspec(dllexport) int close(int fd);
|
||||||
|
|
||||||
|
// Memory allocation functions from Node's module, used by ArrayBuffer allocator
|
||||||
|
// to make sure memories are allocated and freed with the same allocator.
|
||||||
|
__declspec(dllexport) void* ArrayBufferCalloc(size_t length);
|
||||||
|
__declspec(dllexport) void* ArrayBufferMalloc(size_t length);
|
||||||
|
__declspec(dllexport) void ArrayBufferFree(void* data, size_t length);
|
||||||
|
|
||||||
// A trick to force referencing symbols.
|
// A trick to force referencing symbols.
|
||||||
__declspec(dllexport) void ReferenceSymbols();
|
__declspec(dllexport) void ReferenceSymbols();
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче