Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v6.x backport] src: simplify memory management using node::Malloc() and friends #16587

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions src/cares_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,7 @@ static void ares_poll_close_cb(uv_handle_t* watcher) {

/* Allocates and returns a new node_ares_task */
static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) {
node_ares_task* task =
static_cast<node_ares_task*>(node::Malloc(sizeof(*task)));
auto task = node::UncheckedMalloc<node_ares_task>(1);

if (task == nullptr) {
/* Out of memory. */
Expand Down Expand Up @@ -329,11 +328,10 @@ void cares_wrap_hostent_cpy(struct hostent* dest, struct hostent* src) {
alias_count++) {
}

dest->h_aliases = static_cast<char**>(node::Malloc((alias_count + 1) *
sizeof(char*)));
dest->h_aliases = node::Malloc<char*>(alias_count + 1);
for (size_t i = 0; i < alias_count; i++) {
cur_alias_length = strlen(src->h_aliases[i]);
dest->h_aliases[i] = static_cast<char*>(node::Malloc(cur_alias_length + 1));
dest->h_aliases[i] = node::Malloc(cur_alias_length + 1);
memcpy(dest->h_aliases[i], src->h_aliases[i], cur_alias_length + 1);
}
dest->h_aliases[alias_count] = nullptr;
Expand All @@ -345,10 +343,9 @@ void cares_wrap_hostent_cpy(struct hostent* dest, struct hostent* src) {
list_count++) {
}

dest->h_addr_list = static_cast<char**>(node::Malloc((list_count + 1) *
sizeof(char*)));
dest->h_addr_list = node::Malloc<char*>(list_count + 1);
for (size_t i = 0; i < list_count; i++) {
dest->h_addr_list[i] = static_cast<char*>(node::Malloc(src->h_length));
dest->h_addr_list[i] = node::Malloc(src->h_length);
memcpy(dest->h_addr_list[i], src->h_addr_list[i], src->h_length);
}
dest->h_addr_list[list_count] = nullptr;
Expand Down Expand Up @@ -507,7 +504,7 @@ class QueryWrap : public AsyncWrap {

unsigned char* buf_copy = nullptr;
if (status == ARES_SUCCESS) {
buf_copy = static_cast<unsigned char*>(node::Malloc(answer_len));
buf_copy = node::Malloc<unsigned char>(answer_len);
memcpy(buf_copy, answer_buf, answer_len);
}

Expand All @@ -534,7 +531,7 @@ class QueryWrap : public AsyncWrap {

struct hostent* host_copy = nullptr;
if (status == ARES_SUCCESS) {
host_copy = static_cast<hostent*>(node::Malloc(sizeof(hostent)));
host_copy = node::Malloc<hostent>(1);
cares_wrap_hostent_cpy(host_copy, host);
}

Expand Down
7 changes: 5 additions & 2 deletions src/node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ bool trace_warnings = false;
// that is used by lib/module.js
bool config_preserve_symlinks = false;

bool v8_initialized = false;

// Set in node.cc by ParseArgs when --expose-internals or --expose_internals is
// used.
Expand Down Expand Up @@ -1054,9 +1055,9 @@ void* ArrayBufferAllocator::Allocate(size_t size) {
if (env_ == nullptr ||
!env_->array_buffer_allocator_info()->no_zero_fill() ||
zero_fill_all_buffers)
return node::Calloc(size, 1);
return node::UncheckedCalloc(size);
env_->array_buffer_allocator_info()->reset_fill_flag();
return node::Malloc(size);
return node::UncheckedMalloc(size);
}

static bool DomainHasErrorHandler(const Environment* env,
Expand Down Expand Up @@ -4895,6 +4896,7 @@ int Start(int argc, char** argv) {

v8_platform.Initialize(v8_thread_pool_size);
V8::Initialize();
v8_initialized = true;

int exit_code = 1;
{
Expand All @@ -4908,6 +4910,7 @@ int Start(int argc, char** argv) {
StartNodeInstance(&instance_data);
exit_code = instance_data.exit_code();
}
v8_initialized = false;
V8::Dispose();

v8_platform.Dispose();
Expand Down
23 changes: 14 additions & 9 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,20 @@
THROW_AND_RETURN_IF_OOB(end <= end_max); \
size_t length = end - start;

#define BUFFER_MALLOC(length) \
zero_fill_all_buffers ? node::Calloc(length, 1) : node::Malloc(length)

namespace node {

// if true, all Buffer and SlowBuffer instances will automatically zero-fill
bool zero_fill_all_buffers = false;

namespace {

inline void* BufferMalloc(size_t length) {
return zero_fill_all_buffers ? node::UncheckedCalloc(length) :
node::UncheckedMalloc(length);
}

} // namespace

namespace Buffer {

using v8::ArrayBuffer;
Expand Down Expand Up @@ -234,7 +240,7 @@ MaybeLocal<Object> New(Isolate* isolate,
char* data = nullptr;

if (length > 0) {
data = static_cast<char*>(BUFFER_MALLOC(length));
data = static_cast<char*>(BufferMalloc(length));

if (data == nullptr)
return Local<Object>();
Expand All @@ -246,8 +252,7 @@ MaybeLocal<Object> New(Isolate* isolate,
free(data);
data = nullptr;
} else if (actual < length) {
data = static_cast<char*>(node::Realloc(data, actual));
CHECK_NE(data, nullptr);
data = node::Realloc(data, actual);
}
}

Expand Down Expand Up @@ -280,7 +285,7 @@ MaybeLocal<Object> New(Environment* env, size_t length) {

void* data;
if (length > 0) {
data = BUFFER_MALLOC(length);
data = BufferMalloc(length);
if (data == nullptr)
return Local<Object>();
} else {
Expand Down Expand Up @@ -325,7 +330,7 @@ MaybeLocal<Object> Copy(Environment* env, const char* data, size_t length) {
void* new_data;
if (length > 0) {
CHECK_NE(data, nullptr);
new_data = node::Malloc(length);
new_data = node::UncheckedMalloc(length);
if (new_data == nullptr)
return Local<Object>();
memcpy(new_data, data, length);
Expand Down Expand Up @@ -1063,7 +1068,7 @@ void IndexOfString(const FunctionCallbackInfo<Value>& args) {
offset,
is_forward);
} else if (enc == LATIN1) {
uint8_t* needle_data = static_cast<uint8_t*>(node::Malloc(needle_length));
uint8_t* needle_data = node::UncheckedMalloc<uint8_t>(needle_length);
if (needle_data == nullptr) {
return args.GetReturnValue().Set(-1);
}
Expand Down
39 changes: 10 additions & 29 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2386,8 +2386,7 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
size_t len = Buffer::Length(obj);

// OpenSSL takes control of the pointer after accepting it
char* data = reinterpret_cast<char*>(node::Malloc(len));
CHECK_NE(data, nullptr);
char* data = node::Malloc(len);
memcpy(data, resp, len);

if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
Expand Down Expand Up @@ -3466,8 +3465,7 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const {
if (initialised_ || kind_ != kCipher || !auth_tag_)
return false;
*out_len = auth_tag_len_;
*out = static_cast<char*>(node::Malloc(auth_tag_len_));
CHECK_NE(*out, nullptr);
*out = node::Malloc(auth_tag_len_);
memcpy(*out, auth_tag_, auth_tag_len_);
return true;
}
Expand Down Expand Up @@ -5138,8 +5136,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo<Value>& args) {
// NOTE: field_size is in bits
int field_size = EC_GROUP_get_degree(ecdh->group_);
size_t out_len = (field_size + 7) / 8;
char* out = static_cast<char*>(node::Malloc(out_len));
CHECK_NE(out, nullptr);
char* out = node::Malloc(out_len);

int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr);
EC_POINT_free(pub);
Expand Down Expand Up @@ -5174,8 +5171,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo<Value>& args) {
if (size == 0)
return env->ThrowError("Failed to get public key length");

unsigned char* out = static_cast<unsigned char*>(node::Malloc(size));
CHECK_NE(out, nullptr);
unsigned char* out = node::Malloc<unsigned char>(size);

int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr);
if (r != size) {
Expand All @@ -5200,8 +5196,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo<Value>& args) {
return env->ThrowError("Failed to get ECDH private key");

int size = BN_num_bytes(b);
unsigned char* out = static_cast<unsigned char*>(node::Malloc(size));
CHECK_NE(out, nullptr);
unsigned char* out = node::Malloc<unsigned char>(size);

if (size != BN_bn2bin(b, out)) {
free(out);
Expand Down Expand Up @@ -5333,10 +5328,8 @@ class PBKDF2Request : public AsyncWrap {
saltlen_(saltlen),
salt_(salt),
keylen_(keylen),
key_(static_cast<char*>(node::Malloc(keylen))),
key_(node::Malloc(keylen)),
iter_(iter) {
if (key() == nullptr)
FatalError("node::PBKDF2Request()", "Out of Memory");
Wrap(object, this);
}

Expand Down Expand Up @@ -5496,10 +5489,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {

THROW_AND_RETURN_IF_NOT_BUFFER(args[1], "Salt");

pass = static_cast<char*>(node::Malloc(passlen));
if (pass == nullptr) {
FatalError("node::PBKDF2()", "Out of Memory");
}
pass = node::Malloc(passlen);
memcpy(pass, Buffer::Data(args[0]), passlen);

saltlen = Buffer::Length(args[1]);
Expand All @@ -5508,10 +5498,7 @@ void PBKDF2(const FunctionCallbackInfo<Value>& args) {
goto err;
}

salt = static_cast<char*>(node::Malloc(saltlen));
if (salt == nullptr) {
FatalError("node::PBKDF2()", "Out of Memory");
}
salt = node::Malloc(saltlen);
memcpy(salt, Buffer::Data(args[1]), saltlen);

if (!args[2]->IsNumber()) {
Expand Down Expand Up @@ -5601,9 +5588,7 @@ class RandomBytesRequest : public AsyncWrap {
: AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO),
error_(0),
size_(size),
data_(static_cast<char*>(node::Malloc(size))) {
if (data() == nullptr)
FatalError("node::RandomBytesRequest()", "Out of Memory");
data_(node::Malloc(size)) {
Wrap(object, this);
}

Expand Down Expand Up @@ -5826,13 +5811,9 @@ void GetCurves(const FunctionCallbackInfo<Value>& args) {
const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
Local<Array> arr = Array::New(env->isolate(), num_curves);
EC_builtin_curve* curves;
size_t alloc_size;

if (num_curves) {
alloc_size = sizeof(*curves) * num_curves;
curves = static_cast<EC_builtin_curve*>(node::Malloc(alloc_size));

CHECK_NE(curves, nullptr);
curves = node::Malloc<EC_builtin_curve>(num_curves);

if (EC_get_builtin_curves(curves, num_curves)) {
for (size_t i = 0; i < num_curves; i++) {
Expand Down
5 changes: 4 additions & 1 deletion src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ extern std::string openssl_config;
// that is used by lib/module.js
extern bool config_preserve_symlinks;

// Tells whether it is safe to call v8::Isolate::GetCurrent().
extern bool v8_initialized;

// Set in node.cc by ParseArgs when --expose-internals or --expose_internals is
// used.
// Used in node_config.cc to set a constant on process.binding('config')
Expand Down Expand Up @@ -199,7 +202,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {

virtual void* Allocate(size_t size); // Defined in src/node.cc
virtual void* AllocateUninitialized(size_t size)
{ return node::Malloc(size); }
{ return node::UncheckedMalloc(size); }
virtual void Free(void* data, size_t) { free(data); }

private:
Expand Down
10 changes: 2 additions & 8 deletions src/stream_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,8 @@ void StreamWrap::OnAlloc(uv_handle_t* handle,


void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) {
buf->base = static_cast<char*>(node::Malloc(size));
buf->base = node::Malloc(size);
buf->len = size;

if (buf->base == nullptr && size > 0) {
FatalError(
"node::StreamWrap::DoAlloc(size_t, uv_buf_t*, void*)",
"Out Of Memory");
}
}


Expand Down Expand Up @@ -204,8 +198,8 @@ void StreamWrap::OnReadImpl(ssize_t nread,
return;
}

char* base = static_cast<char*>(node::Realloc(buf->base, nread));
CHECK_LE(static_cast<size_t>(nread), buf->len);
char* base = node::Realloc(buf->base, nread);

if (pending == UV_TCP) {
pending_obj = AcceptHandle<TCPWrap, uv_tcp_t>(env, wrap);
Expand Down
9 changes: 4 additions & 5 deletions src/string_bytes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ class ExternString: public ResourceType {
if (length == 0)
return scope.Escape(String::Empty(isolate));

TypeName* new_data =
static_cast<TypeName*>(node::Malloc(length * sizeof(*new_data)));
TypeName* new_data = node::UncheckedMalloc<TypeName>(length);
if (new_data == nullptr) {
return Local<String>();
}
Expand Down Expand Up @@ -610,7 +609,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,

case ASCII:
if (contains_non_ascii(buf, buflen)) {
char* out = static_cast<char*>(node::Malloc(buflen));
char* out = node::UncheckedMalloc(buflen);
if (out == nullptr) {
return Local<String>();
}
Expand Down Expand Up @@ -645,7 +644,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,

case BASE64: {
size_t dlen = base64_encoded_size(buflen);
char* dst = static_cast<char*>(node::Malloc(dlen));
char* dst = node::UncheckedMalloc(dlen);
if (dst == nullptr) {
return Local<String>();
}
Expand All @@ -664,7 +663,7 @@ Local<Value> StringBytes::Encode(Isolate* isolate,

case HEX: {
size_t dlen = buflen * 2;
char* dst = static_cast<char*>(node::Malloc(dlen));
char* dst = node::UncheckedMalloc(dlen);
if (dst == nullptr) {
return Local<String>();
}
Expand Down
3 changes: 1 addition & 2 deletions src/tls_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -663,8 +663,7 @@ void TLSWrap::OnDestructImpl(void* ctx) {


void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) {
buf->base = static_cast<char*>(node::Malloc(suggested_size));
CHECK_NE(buf->base, nullptr);
buf->base = node::Malloc(suggested_size);
buf->len = suggested_size;
}

Expand Down
9 changes: 2 additions & 7 deletions src/udp_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -373,13 +373,8 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
void UDPWrap::OnAlloc(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
buf->base = static_cast<char*>(node::Malloc(suggested_size));
buf->base = node::Malloc(suggested_size);
buf->len = suggested_size;

if (buf->base == nullptr && suggested_size > 0) {
FatalError("node::UDPWrap::OnAlloc(uv_handle_t*, size_t, uv_buf_t*)",
"Out Of Memory");
}
}


Expand Down Expand Up @@ -415,7 +410,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
return;
}

char* base = static_cast<char*>(node::Realloc(buf->base, nread));
char* base = node::UncheckedRealloc(buf->base, nread);
argv[2] = Buffer::New(env, base, nread).ToLocalChecked();
argv[3] = AddressToJS(env, addr);
wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv);
Expand Down
Loading