Skip to content

Commit ff74931

Browse files
committed
smalloc: do not track external memory
The memory that was allocated outside of the `smalloc.cc` should not be tracked using `AdjustAmountOfExternalAllocatedMemory`. There are no potential issues except triggering V8's GC way too often. In fact, `heap.js` is creating a buffer out of the pointer, and since it doesn't know the size of the pointer - it just creates the maximum possible `Buffer` instance with a no-op free callback and no hint. PR-URL: #1375 Reviewed-By: Ben Noordhuis <[email protected]>
1 parent 264a8f3 commit ff74931

File tree

1 file changed

+44
-15
lines changed

1 file changed

+44
-15
lines changed

src/smalloc.cc

+44-15
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,14 @@ using v8::kExternalUint8Array;
4848

4949
class CallbackInfo {
5050
public:
51+
enum Ownership {
52+
kInternal,
53+
kExternal
54+
};
55+
5156
static inline void Free(char* data, void* hint);
5257
static inline CallbackInfo* New(Isolate* isolate,
58+
Ownership ownership,
5359
Handle<Object> object,
5460
FreeCallback callback,
5561
void* hint = 0);
@@ -59,10 +65,12 @@ class CallbackInfo {
5965
static void WeakCallback(const WeakCallbackData<Object, CallbackInfo>&);
6066
inline void WeakCallback(Isolate* isolate, Local<Object> object);
6167
inline CallbackInfo(Isolate* isolate,
68+
Ownership ownership,
6269
Handle<Object> object,
6370
FreeCallback callback,
6471
void* hint);
6572
~CallbackInfo();
73+
const Ownership ownership_;
6674
Persistent<Object> persistent_;
6775
FreeCallback const callback_;
6876
void* const hint_;
@@ -76,10 +84,11 @@ void CallbackInfo::Free(char* data, void*) {
7684

7785

7886
CallbackInfo* CallbackInfo::New(Isolate* isolate,
87+
CallbackInfo::Ownership ownership,
7988
Handle<Object> object,
8089
FreeCallback callback,
8190
void* hint) {
82-
return new CallbackInfo(isolate, object, callback, hint);
91+
return new CallbackInfo(isolate, ownership, object, callback, hint);
8392
}
8493

8594

@@ -94,15 +103,18 @@ Persistent<Object>* CallbackInfo::persistent() {
94103

95104

96105
CallbackInfo::CallbackInfo(Isolate* isolate,
106+
CallbackInfo::Ownership ownership,
97107
Handle<Object> object,
98108
FreeCallback callback,
99109
void* hint)
100-
: persistent_(isolate, object),
110+
: ownership_(ownership),
111+
persistent_(isolate, object),
101112
callback_(callback),
102113
hint_(hint) {
103114
persistent_.SetWeak(this, WeakCallback);
104115
persistent_.SetWrapperClassId(ALLOC_ID);
105116
persistent_.MarkIndependent();
117+
isolate->AdjustAmountOfExternalAllocatedMemory(sizeof(*this));
106118
}
107119

108120

@@ -129,9 +141,11 @@ void CallbackInfo::WeakCallback(Isolate* isolate, Local<Object> object) {
129141
array_length *= array_size;
130142
}
131143
object->SetIndexedPropertiesToExternalArrayData(nullptr, array_type, 0);
132-
int64_t change_in_bytes = -static_cast<int64_t>(array_length + sizeof(*this));
133-
isolate->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
134144
callback_(static_cast<char*>(array_data), hint_);
145+
int64_t change_in_bytes = -static_cast<int64_t>(sizeof(*this));
146+
if (ownership_ == kInternal)
147+
change_in_bytes -= static_cast<int64_t>(array_length);
148+
isolate->AdjustAmountOfExternalAllocatedMemory(change_in_bytes);
135149
delete this;
136150
}
137151

@@ -333,7 +347,10 @@ void Alloc(Environment* env,
333347
env->isolate()->AdjustAmountOfExternalAllocatedMemory(length);
334348
size_t size = length / ExternalArraySize(type);
335349
obj->SetIndexedPropertiesToExternalArrayData(data, type, size);
336-
CallbackInfo::New(env->isolate(), obj, CallbackInfo::Free);
350+
CallbackInfo::New(env->isolate(),
351+
CallbackInfo::kInternal,
352+
obj,
353+
CallbackInfo::Free);
337354
}
338355

339356

@@ -381,6 +398,25 @@ void AllocDispose(Environment* env, Handle<Object> obj) {
381398
}
382399

383400

401+
static void Alloc(Environment* env,
402+
CallbackInfo::Ownership ownership,
403+
Handle<Object> obj,
404+
char* data,
405+
size_t length,
406+
FreeCallback fn,
407+
void* hint,
408+
enum ExternalArrayType type) {
409+
CHECK_EQ(false, obj->HasIndexedPropertiesInExternalArrayData());
410+
Isolate* isolate = env->isolate();
411+
HandleScope handle_scope(isolate);
412+
env->set_using_smalloc_alloc_cb(true);
413+
CallbackInfo* info = CallbackInfo::New(isolate, ownership, obj, fn, hint);
414+
obj->SetHiddenValue(env->smalloc_p_string(), External::New(isolate, info));
415+
size_t size = length / ExternalArraySize(type);
416+
obj->SetIndexedPropertiesToExternalArrayData(data, type, size);
417+
}
418+
419+
384420
void Alloc(Environment* env,
385421
Handle<Object> obj,
386422
size_t length,
@@ -404,7 +440,8 @@ void Alloc(Environment* env,
404440
UNREACHABLE();
405441
}
406442

407-
Alloc(env, obj, data, length, fn, hint, type);
443+
env->isolate()->AdjustAmountOfExternalAllocatedMemory(length);
444+
Alloc(env, CallbackInfo::kInternal, obj, data, length, fn, hint, type);
408445
}
409446

410447

@@ -415,15 +452,7 @@ void Alloc(Environment* env,
415452
FreeCallback fn,
416453
void* hint,
417454
enum ExternalArrayType type) {
418-
CHECK_EQ(false, obj->HasIndexedPropertiesInExternalArrayData());
419-
Isolate* isolate = env->isolate();
420-
HandleScope handle_scope(isolate);
421-
env->set_using_smalloc_alloc_cb(true);
422-
CallbackInfo* info = CallbackInfo::New(isolate, obj, fn, hint);
423-
obj->SetHiddenValue(env->smalloc_p_string(), External::New(isolate, info));
424-
isolate->AdjustAmountOfExternalAllocatedMemory(length + sizeof(*info));
425-
size_t size = length / ExternalArraySize(type);
426-
obj->SetIndexedPropertiesToExternalArrayData(data, type, size);
455+
Alloc(env, CallbackInfo::kExternal, obj, data, length, fn, hint, type);
427456
}
428457

429458

0 commit comments

Comments
 (0)