11#include " stream_base.h"
2+ #include " stream_base-inl.h"
23#include " stream_wrap.h"
34
45#include " node.h"
@@ -108,6 +109,8 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
108109 // Determine storage size first
109110 size_t storage_size = 0 ;
110111 for (size_t i = 0 ; i < count; i++) {
112+ storage_size = ROUND_UP (storage_size, WriteWrap::kAlignSize );
113+
111114 Handle<Value> chunk = chunks->Get (i * 2 );
112115
113116 if (Buffer::HasInstance (chunk))
@@ -124,7 +127,7 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
124127 else
125128 chunk_size = StringBytes::StorageSize (env->isolate (), string, encoding);
126129
127- storage_size += chunk_size + 15 ;
130+ storage_size += chunk_size;
128131 }
129132
130133 if (storage_size > INT_MAX)
@@ -133,13 +136,14 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
133136 if (ARRAY_SIZE (bufs_) < count)
134137 bufs = new uv_buf_t [count];
135138
136- storage_size += sizeof (WriteWrap);
137- char * storage = new char [storage_size];
138- WriteWrap* req_wrap =
139- new (storage) WriteWrap (env, req_wrap_obj, this , AfterWrite);
139+ WriteWrap* req_wrap = WriteWrap::New (env,
140+ req_wrap_obj,
141+ this ,
142+ AfterWrite,
143+ storage_size);
140144
141145 uint32_t bytes = 0 ;
142- size_t offset = sizeof (WriteWrap) ;
146+ size_t offset = 0 ;
143147 for (size_t i = 0 ; i < count; i++) {
144148 Handle<Value> chunk = chunks->Get (i * 2 );
145149
@@ -152,9 +156,9 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
152156 }
153157
154158 // Write string
155- offset = ROUND_UP (offset, 16 );
159+ offset = ROUND_UP (offset, WriteWrap:: kAlignSize );
156160 CHECK_LT (offset, storage_size);
157- char * str_storage = storage + offset;
161+ char * str_storage = req_wrap-> Extra ( offset) ;
158162 size_t str_size = storage_size - offset;
159163
160164 Handle<String> string = chunk->ToString (env->isolate ());
@@ -187,10 +191,8 @@ int StreamBase::Writev(const FunctionCallbackInfo<Value>& args) {
187191 ClearError ();
188192 }
189193
190- if (err) {
191- req_wrap->~WriteWrap ();
192- delete[] storage;
193- }
194+ if (err)
195+ req_wrap->Dispose ();
194196
195197 return err;
196198}
@@ -207,7 +209,6 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
207209 const char * data = Buffer::Data (args[1 ]);
208210 size_t length = Buffer::Length (args[1 ]);
209211
210- char * storage;
211212 WriteWrap* req_wrap;
212213 uv_buf_t buf;
213214 buf.base = const_cast <char *>(data);
@@ -224,17 +225,14 @@ int StreamBase::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
224225 CHECK_EQ (count, 1 );
225226
226227 // Allocate, or write rest
227- storage = new char [sizeof (WriteWrap)];
228- req_wrap = new (storage) WriteWrap (env, req_wrap_obj, this , AfterWrite);
228+ req_wrap = WriteWrap::New (env, req_wrap_obj, this , AfterWrite);
229229
230230 err = DoWrite (req_wrap, bufs, count, nullptr );
231231 req_wrap->Dispatched ();
232232 req_wrap_obj->Set (env->async (), True (env->isolate ()));
233233
234- if (err) {
235- req_wrap->~WriteWrap ();
236- delete[] storage;
237- }
234+ if (err)
235+ req_wrap->Dispose ();
238236
239237 done:
240238 const char * msg = Error ();
@@ -275,14 +273,13 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
275273 return UV_ENOBUFS;
276274
277275 // Try writing immediately if write size isn't too big
278- char * storage;
279276 WriteWrap* req_wrap;
280277 char * data;
281278 char stack_storage[16384 ]; // 16kb
282279 size_t data_size;
283280 uv_buf_t buf;
284281
285- bool try_write = storage_size + 15 <= sizeof (stack_storage) &&
282+ bool try_write = storage_size <= sizeof (stack_storage) &&
286283 (!IsIPCPipe () || send_handle_obj.IsEmpty ());
287284 if (try_write) {
288285 data_size = StringBytes::Write (env->isolate (),
@@ -308,11 +305,9 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
308305 CHECK_EQ (count, 1 );
309306 }
310307
311- storage = new char [sizeof (WriteWrap) + storage_size + 15 ];
312- req_wrap = new (storage) WriteWrap (env, req_wrap_obj, this , AfterWrite);
308+ req_wrap = WriteWrap::New (env, req_wrap_obj, this , AfterWrite, storage_size);
313309
314- data = reinterpret_cast <char *>(ROUND_UP (
315- reinterpret_cast <uintptr_t >(storage) + sizeof (WriteWrap), 16 ));
310+ data = req_wrap->Extra ();
316311
317312 if (try_write) {
318313 // Copy partial data
@@ -355,10 +350,8 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
355350 req_wrap->Dispatched ();
356351 req_wrap->object ()->Set (env->async (), True (env->isolate ()));
357352
358- if (err) {
359- req_wrap->~WriteWrap ();
360- delete[] storage;
361- }
353+ if (err)
354+ req_wrap->Dispose ();
362355
363356 done:
364357 const char * msg = Error ();
@@ -404,8 +397,7 @@ void StreamBase::AfterWrite(WriteWrap* req_wrap, int status) {
404397 if (req_wrap->object ()->Has (env->oncomplete_string ()))
405398 req_wrap->MakeCallback (env->oncomplete_string (), ARRAY_SIZE (argv), argv);
406399
407- req_wrap->~WriteWrap ();
408- delete[] reinterpret_cast <char *>(req_wrap);
400+ req_wrap->Dispose ();
409401}
410402
411403
0 commit comments