From fa10b757f50acc4330bffa11ad12ac46be89cbd5 Mon Sep 17 00:00:00 2001 From: Trevor Norris Date: Thu, 20 Jun 2013 16:44:02 -0700 Subject: [PATCH] smalloc: use malloc instead of new To use realloc the implementation had to be changed to use malloc/free. --- src/node.cc | 7 +++++++ src/node_buffer.cc | 27 ++++++++++++++++++++++++--- src/node_internals.h | 4 ++++ src/smalloc.cc | 13 ++++++++----- src/stream_wrap.cc | 13 ++++++++----- src/udp_wrap.cc | 12 ++++++++---- 6 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/node.cc b/src/node.cc index 38ecbb836c..08843cbaf6 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1872,6 +1872,13 @@ static void OnFatalError(const char* location, const char* message) { } +NO_RETURN void FatalError(const char* location, const char* message) { + OnFatalError(location, message); + // to supress compiler warning + abort(); +} + + void FatalException(Handle error, Handle message) { HandleScope scope(node_isolate); diff --git a/src/node_buffer.cc b/src/node_buffer.cc index f9317c479d..4560daa706 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -142,7 +142,18 @@ Local New(size_t length) { argv[1] = Uint32::New(length, node_isolate); Local obj = p_buffer_fn->NewInstance(2, argv); - smalloc::Alloc(obj, new char[length], length); + // TODO(trevnorris): done like this to handle HasInstance since only checks + // if external array data has been set, but would like to use a better + // approach if v8 provided one. + char* data; + if (length > 0) { + data = static_cast(malloc(length)); + if (data == NULL) + FatalError("node::Buffer::New(size_t)", "Out Of Memory"); + } else { + data = NULL; + } + smalloc::Alloc(obj, data, length); return scope.Close(obj); } @@ -163,8 +174,18 @@ Local New(const char* data, size_t length) { argv[1] = Uint32::New(length, node_isolate); Local obj = p_buffer_fn->NewInstance(2, argv); - char* new_data = new char[length]; - memcpy(new_data, data, length); + // TODO(trevnorris): done like this to handle HasInstance since only checks + // if external array data has been set, but would like to use a better + // approach if v8 provided one. + char* new_data; + if (length > 0) { + new_data = static_cast(malloc(length)); + if (new_data == NULL) + FatalError("node::Buffer::New(const char*, size_t)", "Out Of Memory"); + memcpy(new_data, data, length); + } else { + new_data = NULL; + } smalloc::Alloc(obj, new_data, length); diff --git a/src/node_internals.h b/src/node_internals.h index 9e2491a200..9e5e0bf92d 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -76,8 +76,10 @@ inline static int snprintf(char* buf, unsigned int len, const char* fmt, ...) { #if defined(__GNUC__) && __GNUC__ >= 4 # define MUST_USE_RESULT __attribute__((warn_unused_result)) +# define NO_RETURN __attribute__((noreturn)) #else # define MUST_USE_RESULT +# define NO_RETURN #endif // this would have been a template function were it not for the fact that g++ @@ -101,6 +103,8 @@ inline static v8::Handle ThrowRangeError(const char* errmsg) { THROW_ERROR(v8::Exception::RangeError); } +NO_RETURN void FatalError(const char* location, const char* message); + #define UNWRAP(type) \ assert(!args.This().IsEmpty()); \ assert(args.This()->InternalFieldCount() > 0); \ diff --git a/src/smalloc.cc b/src/smalloc.cc index 7d5c5d4984..11e8e55e96 100644 --- a/src/smalloc.cc +++ b/src/smalloc.cc @@ -142,14 +142,17 @@ Handle Alloc(const Arguments& args) { void Alloc(Handle obj, size_t length) { assert(length <= kMaxLength); - char* data = new char[length]; + if (length == 0) + return Alloc(obj, NULL, length); + + char* data = static_cast(malloc(length)); + if (data == NULL) + FatalError("node::smalloc::Alloc(Handle, size_t)", "Out Of Memory"); Alloc(obj, data, length); } void Alloc(Handle obj, char* data, size_t length) { - assert(data != NULL); - Persistent p_obj(node_isolate, obj); node_isolate->AdjustAmountOfExternalAllocatedMemory(length); @@ -166,7 +169,7 @@ void TargetCallback(Isolate* isolate, Persistent* target, char* data) { int len = (*target)->GetIndexedPropertiesExternalArrayDataLength(); if (data != NULL && len > 0) { isolate->AdjustAmountOfExternalAllocatedMemory(-len); - delete[] data; + free(data); } (*target).Dispose(); (*target).Clear(); @@ -189,7 +192,7 @@ void AllocDispose(Handle obj) { obj->SetIndexedPropertiesToExternalArrayData(NULL, kExternalUnsignedByteArray, 0); - delete[] data; + free(data); node_isolate->AdjustAmountOfExternalAllocatedMemory(-length); } diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 9b33d62b56..455ebe983a 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -580,7 +580,12 @@ void StreamWrapCallbacks::AfterWrite(WriteWrap* w) { uv_buf_t StreamWrapCallbacks::DoAlloc(uv_handle_t* handle, size_t suggested_size) { - return uv_buf_init(new char[suggested_size], suggested_size); + char* data = static_cast(malloc(suggested_size)); + if (data == NULL && suggested_size > 0) { + FatalError("node::StreamWrapCallbacks::DoAlloc(uv_handle_t*, size_t)", + "Out Of Memory"); + } + return uv_buf_init(data, suggested_size); } @@ -592,8 +597,7 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle, if (nread < 0) { if (buf.base != NULL) - delete[] buf.base; - + free(buf.base); SetErrno(uv_last_error(uv_default_loop())); MakeCallback(Self(), onread_sym, 0, NULL); return; @@ -601,11 +605,10 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle, if (nread == 0) { if (buf.base != NULL) - delete[] buf.base; + free(buf.base); return; } - // TODO(trevnorris): not kosher to use new/delete w/ realloc buf.base = static_cast(realloc(buf.base, nread)); assert(static_cast(nread) <= buf.len); diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index db759e6ed5..db5c8db734 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -371,7 +371,12 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) { uv_buf_t UDPWrap::OnAlloc(uv_handle_t* handle, size_t suggested_size) { - return uv_buf_init(new char[suggested_size], suggested_size); + char* data = static_cast(malloc(suggested_size)); + if (data == NULL && suggested_size > 0) { + FatalError("node::UDPWrap::OnAlloc(uv_handle_t*, size_t)", + "Out Of Memory"); + } + return uv_buf_init(data, suggested_size); } @@ -386,7 +391,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle, if (nread < 0) { if (buf.base != NULL) - delete[] buf.base; + free(buf.base); Local argv[] = { Local::New(node_isolate, wrap->object_) }; SetErrno(uv_last_error(uv_default_loop())); MakeCallback(wrap->object_, onmessage_sym, ARRAY_SIZE(argv), argv); @@ -395,11 +400,10 @@ void UDPWrap::OnRecv(uv_udp_t* handle, if (nread == 0) { if (buf.base != NULL) - delete[] buf.base; + free(buf.base); return; } - // TODO(trevnorris): not kosher to use new/delete w/ realloc buf.base = static_cast(realloc(buf.base, nread)); Local argv[] = {