Skip to content

Commit

Permalink
fix(ios): fix context leak when using shared engine (#3451)
Browse files Browse the repository at this point in the history
* chore(ios): fix demo release build error

* fix(ios): js context leak when using shared engine

---------

Co-authored-by: OpenHippy <[email protected]>
  • Loading branch information
2 people authored and zealotchen0 committed Oct 27, 2023
1 parent 5fad881 commit 66d516b
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 13 deletions.
2 changes: 1 addition & 1 deletion examples/ios-demo/HippyDemo/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#import "HippyLog.h"
#import "HippyBundleURLProvider.h"
#import "DemoConfigs.h"
#import <hippy/HippyBridge.h>
#import "HippyBridge.h"
#import <sys/utsname.h>


Expand Down
26 changes: 14 additions & 12 deletions ios/sdk/base/executors/HippyJSCExecutor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,9 @@ - (void)setBridge:(HippyBridge *)bridge {
- (instancetype)initWithExecurotKey:(NSString *)execurotkey bridge:(HippyBridge *)bridge {
if (self = [super init]) {
_valid = YES;
// maybe bug in JavaScriptCore:
// JSContextRef held by JSContextGroupRef cannot be deallocated,
// unless JSContextGroupRef is deallocated
self.executorkey = execurotkey;
self.bridge = bridge;
std::shared_ptr<Engine> engine = [[HippyJSEnginesMapper defaultInstance] createJSEngineForKey:self.executorkey];
std::shared_ptr<Engine> engine = [[HippyJSEnginesMapper defaultInstance] createJSEngineForKey:self.uniqueExecutorkeyForEngine];
std::unique_ptr<Engine::RegisterMap> map = [self registerMap];
const char *pName = [execurotkey UTF8String] ?: "";
std::shared_ptr<Scope> scope = engine->AsyncCreateScope(pName, {}, std::move(map));
Expand Down Expand Up @@ -216,7 +213,7 @@ static unicode_string_view NSStringToU8(NSString* str) {
std::shared_ptr<Scope> scope = wrapper->scope.lock();
if (scope) {
std::shared_ptr<hippy::napi::JSCCtx> context = std::static_pointer_cast<hippy::napi::JSCCtx>(scope->GetContext());
JSContext *jsContext = [JSContext contextWithJSGlobalContextRef:context->GetCtxRef()];
JSContext *jsContext = [strongSelf JSContext];
auto global_object = context->GetGlobalObject();
auto user_global_object_key = context->CreateString("global");
context->SetProperty(global_object, user_global_object_key, global_object, hippy::napi::PropertyAttribute::DontDelete);
Expand Down Expand Up @@ -455,12 +452,10 @@ - (void)invalidate {
_JSContext.name = @"HippyJSContext(delete)";
_JSContext = nil;
_JSGlobalContextRef = NULL;
NSString *executorKey = self.executorkey;
NSString *uniqueExecutorKey = self.uniqueExecutorkeyForEngine;
dispatch_async(dispatch_get_main_queue(), ^{
HippyLogInfo(@"[Hippy_OC_Log][Life_Circle],HippyJSCExecutor remove engine %@", executorKey);
if (executorKey) {
[[HippyJSEnginesMapper defaultInstance] removeEngineForKey:executorKey];
}
HippyLogInfo(@"[Hippy_OC_Log][Life_Circle],HippyJSCExecutor remove engine %@", uniqueExecutorKey);
[[HippyJSEnginesMapper defaultInstance] removeEngineForKey:uniqueExecutorKey];
});
}

Expand All @@ -472,6 +467,13 @@ - (NSString *)executorkey {
return _executorkey ?: [NSString stringWithFormat:@"%p", self];
}

- (NSString *)uniqueExecutorkeyForEngine {
// core-engine reuse can lead to leak of context,
// which we avoid by using a unique executor key.
return [NSString stringWithFormat:@"%@%p", self.executorkey, self];
}


HIPPY_EXPORT_METHOD(setContextName:(NSString *)contextName) {
__weak HippyJSCExecutor *weakSelf = self;
[self executeBlockOnJavaScriptQueue:^{
Expand Down Expand Up @@ -778,7 +780,7 @@ static void handleJsExcepiton(std::shared_ptr<Scope> scope) {
}

- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block {
auto engine = [[HippyJSEnginesMapper defaultInstance] JSEngineForKey:self.executorkey];
auto engine = [[HippyJSEnginesMapper defaultInstance] JSEngineForKey:self.uniqueExecutorkeyForEngine];
if (engine) {
dispatch_block_t autoReleaseBlock = ^(void){
if (block) {
Expand All @@ -798,7 +800,7 @@ - (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block {
}

- (void)executeAsyncBlockOnJavaScriptQueue:(dispatch_block_t)block {
auto engine = [[HippyJSEnginesMapper defaultInstance] JSEngineForKey:self.executorkey];
auto engine = [[HippyJSEnginesMapper defaultInstance] JSEngineForKey:self.uniqueExecutorkeyForEngine];
if (engine) {
std::shared_ptr<JavaScriptTask> task = std::make_shared<JavaScriptTask>();
dispatch_block_t autoReleaseBlock = ^(void){
Expand Down

0 comments on commit 66d516b

Please sign in to comment.