diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-02-18 22:58:19 +0100 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-02-25 02:01:05 +0100 |
commit | 6c257cdf271384555d0ced77104a1d6b0480e246 (patch) | |
tree | 3b44f52c44ed83ecb5f0e5f98231e0f1c6fc1c1e /src/env-inl.h | |
parent | 376735345088d4b37e0e289c2eb7720419ed37ee (diff) | |
download | android-node-v8-6c257cdf271384555d0ced77104a1d6b0480e246.tar.gz android-node-v8-6c257cdf271384555d0ced77104a1d6b0480e246.tar.bz2 android-node-v8-6c257cdf271384555d0ced77104a1d6b0480e246.zip |
src: add allocation utils to env
Add a RAII utility for managing blocks of memory that have
been allocated with the `ArrayBuffer::Allocator` for a given
`Isolate`.
PR-URL: https://github.com/nodejs/node/pull/26207
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'src/env-inl.h')
-rw-r--r-- | src/env-inl.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/env-inl.h b/src/env-inl.h index 51c7e0d7b0..63b71daf15 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -715,6 +715,104 @@ inline IsolateData* Environment::isolate_data() const { return isolate_data_; } +inline char* Environment::AllocateUnchecked(size_t size) { + return static_cast<char*>( + isolate_data()->allocator()->AllocateUninitialized(size)); +} + +inline char* Environment::Allocate(size_t size) { + char* ret = AllocateUnchecked(size); + CHECK_NE(ret, nullptr); + return ret; +} + +inline void Environment::Free(char* data, size_t size) { + if (data != nullptr) + isolate_data()->allocator()->Free(data, size); +} + +inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) { + char* data = checked ? Allocate(size) : AllocateUnchecked(size); + if (data == nullptr) size = 0; + return AllocatedBuffer(this, uv_buf_init(data, size)); +} + +inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf) + : env_(env), buffer_(buf) {} + +inline void AllocatedBuffer::Resize(size_t len) { + char* new_data = env_->Reallocate(buffer_.base, buffer_.len, len); + CHECK_IMPLIES(len > 0, new_data != nullptr); + buffer_ = uv_buf_init(new_data, len); +} + +inline uv_buf_t AllocatedBuffer::release() { + uv_buf_t ret = buffer_; + buffer_ = uv_buf_init(nullptr, 0); + return ret; +} + +inline char* AllocatedBuffer::data() { + return buffer_.base; +} + +inline const char* AllocatedBuffer::data() const { + return buffer_.base; +} + +inline size_t AllocatedBuffer::size() const { + return buffer_.len; +} + +inline AllocatedBuffer::AllocatedBuffer(Environment* env) + : env_(env), buffer_(uv_buf_init(nullptr, 0)) {} + +inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other) + : AllocatedBuffer() { + *this = std::move(other); +} + +inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) { + clear(); + env_ = other.env_; + buffer_ = other.release(); + return *this; +} + +inline AllocatedBuffer::~AllocatedBuffer() { + clear(); +} + +inline void AllocatedBuffer::clear() { + uv_buf_t buf = release(); + env_->Free(buf.base, buf.len); +} + +// It's a bit awkward to define this Buffer::New() overload here, but it +// avoids a circular dependency with node_internals.h. +namespace Buffer { +v8::MaybeLocal<v8::Object> New(Environment* env, + char* data, + size_t length, + bool uses_malloc); +} + +inline v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() { + CHECK_NOT_NULL(env_); + v8::MaybeLocal<v8::Object> obj = Buffer::New(env_, data(), size(), false); + if (!obj.IsEmpty()) release(); + return obj; +} + +inline v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() { + CHECK_NOT_NULL(env_); + uv_buf_t buf = release(); + return v8::ArrayBuffer::New(env_->isolate(), + buf.base, + buf.len, + v8::ArrayBufferCreationMode::kInternalized); +} + inline void Environment::ThrowError(const char* errmsg) { ThrowError(v8::Exception::Error, errmsg); } |