Skip to content

Commit bcd8e41

Browse files
committed
buffer: implement Uint8Array backed Buffer
With V8 4.4 removing the external array data API currently used by Buffer, the new implementation uses the Uint8Array to back Buffer. Buffers now have a maximum size of Smi::kMaxLength, as defined by V8. Which is ~2 GB on 64 bit and ~1 GB on 32 bit. The flag --use-old-buffer allows using the old Buffer implementation. This flag will be removed once V8 4.4 has landed.
1 parent 266526c commit bcd8e41

File tree

8 files changed

+624
-223
lines changed

8 files changed

+624
-223
lines changed

lib/buffer.js

Lines changed: 281 additions & 118 deletions
Large diffs are not rendered by default.

src/env.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ namespace node {
231231
V(async_hooks_post_function, v8::Function) \
232232
V(binding_cache_object, v8::Object) \
233233
V(buffer_constructor_function, v8::Function) \
234+
V(buffer_prototype_object, v8::Object) \
234235
V(context, v8::Context) \
235236
V(domain_array, v8::Array) \
236237
V(fs_stats_constructor_function, v8::Function) \

src/node.cc

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "node_http_parser.h"
66
#include "node_javascript.h"
77
#include "node_version.h"
8+
#include "node_internals.h"
89

910
#if defined HAVE_PERFCTR
1011
#include "node_counters.h"
@@ -146,6 +147,8 @@ static uv_async_t dispatch_debug_messages_async;
146147
static Isolate* node_isolate = nullptr;
147148
static v8::Platform* default_platform;
148149

150+
bool using_old_buffer = false;
151+
149152
class ArrayBufferAllocator : public ArrayBuffer::Allocator {
150153
public:
151154
// Impose an upper limit to avoid out of memory errors that bring down
@@ -165,23 +168,21 @@ ArrayBufferAllocator ArrayBufferAllocator::the_singleton;
165168

166169

167170
void* ArrayBufferAllocator::Allocate(size_t length) {
168-
if (length > kMaxLength)
171+
void* data = malloc(length);
172+
if (data == nullptr)
169173
return nullptr;
170-
char* data = new char[length];
171174
memset(data, 0, length);
172175
return data;
173176
}
174177

175178

176179
void* ArrayBufferAllocator::AllocateUninitialized(size_t length) {
177-
if (length > kMaxLength)
178-
return nullptr;
179-
return new char[length];
180+
return malloc(length);
180181
}
181182

182183

183184
void ArrayBufferAllocator::Free(void* data, size_t length) {
184-
delete[] static_cast<char*>(data);
185+
free(data);
185186
}
186187

187188

@@ -2844,6 +2845,11 @@ void SetupProcessObject(Environment* env,
28442845
// after LoadEnvironment() has run.
28452846
}
28462847

2848+
// --use-old_buffer
2849+
if (using_old_buffer) {
2850+
READONLY_PROPERTY(process, "useOldBuffer", True(env->isolate()));
2851+
}
2852+
28472853
size_t exec_path_len = 2 * PATH_MAX;
28482854
char* exec_path = new char[exec_path_len];
28492855
Local<String> exec_path_value;
@@ -3072,6 +3078,7 @@ static void PrintHelp() {
30723078
" --trace-deprecation show stack traces on deprecations\n"
30733079
" --trace-sync-io show stack trace when use of sync IO\n"
30743080
" is detected after the first tick\n"
3081+
" --use-old-buffer Revert to old Buffer implementation\n"
30753082
" --v8-options print v8 command line options\n"
30763083
#if defined(NODE_HAVE_I18N_SUPPORT)
30773084
" --icu-data-dir=dir set ICU data load path to dir\n"
@@ -3208,6 +3215,9 @@ static void ParseArgs(int* argc,
32083215
#endif
32093216
} else if (strcmp(arg, "--expose-internals") == 0 ||
32103217
strcmp(arg, "--expose_internals") == 0) {
3218+
} else if (strcmp(arg, "--use-old-buffer") == 0) {
3219+
using_old_buffer = true;
3220+
32113221
// consumed in js
32123222
} else {
32133223
// V8 option. Pass through as-is.

0 commit comments

Comments
 (0)