aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/scripts/generate-jssink.js
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-20 06:58:29 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-20 06:58:29 -0800
commit5ff2cd3418c339409c33c63f7777ee9a93837414 (patch)
tree7a9e1738b89792a93168e820629f81a5178a57c9 /src/bun.js/scripts/generate-jssink.js
parentf56eec6fa379b3db524091731e580909fe06a165 (diff)
downloadbun-5ff2cd3418c339409c33c63f7777ee9a93837414.tar.gz
bun-5ff2cd3418c339409c33c63f7777ee9a93837414.tar.zst
bun-5ff2cd3418c339409c33c63f7777ee9a93837414.zip
[streams] Fix memory leak affecting React SSR and more
Diffstat (limited to 'src/bun.js/scripts/generate-jssink.js')
-rw-r--r--src/bun.js/scripts/generate-jssink.js46
1 files changed, 19 insertions, 27 deletions
diff --git a/src/bun.js/scripts/generate-jssink.js b/src/bun.js/scripts/generate-jssink.js
index 0e9d3bb50..174efcb06 100644
--- a/src/bun.js/scripts/generate-jssink.js
+++ b/src/bun.js/scripts/generate-jssink.js
@@ -96,7 +96,8 @@ function header() {
~${className}();
- void* wrapped() const { return m_sinkPtr; }
+ void* wrapped() const { return m_sinkPtr; }
+ DECLARE_VISIT_CHILDREN;
void detach() {
m_sinkPtr = nullptr;
@@ -154,41 +155,19 @@ function header() {
DECLARE_VISIT_CHILDREN;
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
-
- bool hasPendingActivity() { return m_hasPendingActivity; }
void* m_sinkPtr;
- bool m_hasPendingActivity;
mutable WriteBarrier<JSC::JSFunction> m_onPull;
mutable WriteBarrier<JSC::JSFunction> m_onClose;
mutable JSC::Weak<JSObject> m_weakReadableStream;
- JSC::Weak<${controller}> m_weakThis;
${controller}(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr)
: Base(vm, structure)
{
m_sinkPtr = sinkPtr;
- m_hasPendingActivity = true;
- m_weakThis = JSC::Weak<${controller}>(this, getOwner());
}
void finishCreation(JSC::VM&);
-
- class Owner final : public JSC::WeakHandleOwner {
- public:
- bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void* context, JSC::AbstractSlotVisitor&, const char**) final
- {
- auto* controller = JSC::jsCast<${controller}*>(handle.slot()->asCell());
- return controller->hasPendingActivity();
- }
- void finalize(JSC::Handle<JSC::Unknown>, void* context) final {}
- };
-
- static JSC::WeakHandleOwner* getOwner()
- {
- static NeverDestroyed<Owner> m_owner;
- return &m_owner.get();
- }
};
JSC_DECLARE_CUSTOM_GETTER(function${name}__getter);
@@ -405,8 +384,6 @@ JSC_DEFINE_HOST_FUNCTION(${controller}__close, (JSC::JSGlobalObject * lexicalGlo
controller->detach();
${name}__close(lexicalGlobalObject, ptr);
- // Release the controller right before close.
- controller->m_hasPendingActivity = false;
return JSC::JSValue::encode(JSC::jsUndefined());
}
@@ -643,7 +620,7 @@ void JS${controllerName}::detach() {
auto readableStream = m_weakReadableStream.get();
auto onClose = m_onClose.get();
m_onClose.clear();
-
+
if (readableStream && onClose) {
JSC::JSGlobalObject *globalObject = this->globalObject();
auto callData = JSC::getCallData(onClose);
@@ -760,11 +737,26 @@ void ${controller}::visitChildrenImpl(JSCell* cell, Visitor& visitor)
Base::visitChildren(thisObject, visitor);
visitor.append(thisObject->m_onPull);
visitor.append(thisObject->m_onClose);
- visitor.append(thisObject->m_weakReadableStream);
+ void* ptr = thisObject->m_sinkPtr;
+ if (ptr)
+ visitor.addOpaqueRoot(ptr);
}
DEFINE_VISIT_CHILDREN(${controller});
+template<typename Visitor>
+void ${className}::visitChildrenImpl(JSCell* cell, Visitor& visitor)
+{
+ ${className}* thisObject = jsCast<${className}*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+ Base::visitChildren(thisObject, visitor);
+ void* ptr = thisObject->m_sinkPtr;
+ if (ptr)
+ visitor.addOpaqueRoot(ptr);
+}
+
+DEFINE_VISIT_CHILDREN(${className});
+
void ${controller}::start(JSC::JSGlobalObject *globalObject, JSC::JSValue readableStream, JSC::JSFunction *onPull, JSC::JSFunction *onClose) {
this->m_weakReadableStream = JSC::Weak<JSC::JSObject>(readableStream.getObject());