Skip to content

Commit

Permalink
Make LeakChecker available on Android
Browse files Browse the repository at this point in the history
Summary:
Changelog: [internal]

Extend LeakChecker so it is available on Android (or any other platform as it is completely in C++ now).

Reviewed By: JoshuaGross

Differential Revision: D28600243

fbshipit-source-id: c77a003e3ffc6171e61c998508c9f34f10bb65ca
  • Loading branch information
sammy-SC authored and facebook-github-bot committed May 21, 2021
1 parent ffab8e3 commit 118489f
Show file tree
Hide file tree
Showing 9 changed files with 17 additions and 57 deletions.
2 changes: 0 additions & 2 deletions React/Base/RCTBridge+Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,4 @@ RCT_EXTERN void RCTRegisterModule(Class);

- (instancetype)initWithParentBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;

- (void)forceGarbageCollection;

@end
6 changes: 0 additions & 6 deletions React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ @interface RCTCxxBridge ()
- (instancetype)initWithParentBridge:(RCTBridge *)bridge;
- (void)partialBatchDidFlush;
- (void)batchDidComplete;
- (void)forceGarbageCollection;

@end

Expand Down Expand Up @@ -381,11 +380,6 @@ - (void)_tryAndHandleError:(dispatch_block_t)block
}

- (void)handleMemoryWarning
{
[self forceGarbageCollection];
}

- (void)forceGarbageCollection
{
// We only want to run garbage collector when the loading is finished
// and the instance is valid.
Expand Down
13 changes: 0 additions & 13 deletions React/Fabric/RCTSurfacePresenter.mm
Original file line number Diff line number Diff line change
Expand Up @@ -293,19 +293,6 @@ - (RCTScheduler *)_createScheduler
toolbox.backgroundExecutor = RCTGetBackgroundExecutor();
}

#ifdef REACT_NATIVE_DEBUG
auto optionalBridge = _contextContainer->find<std::shared_ptr<void>>("Bridge");
if (optionalBridge) {
RCTBridge *bridge = unwrapManagedObjectWeakly(optionalBridge.value());
toolbox.garbageCollectionTrigger = [bridge]() {
RCTCxxBridge *batchedBridge = (RCTCxxBridge *)([bridge batchedBridge] ?: bridge);
if ([batchedBridge respondsToSelector:@selector(forceGarbageCollection)]) {
[batchedBridge forceGarbageCollection];
}
};
}
#endif

toolbox.synchronousEventBeatFactory = [runtimeExecutor](EventBeat::SharedOwnerBox const &ownerBox) {
auto runLoopObserver =
std::make_unique<MainRunLoopObserver const>(RunLoopObserver::Activity::BeforeWaiting, ownerBox->owner);
Expand Down
13 changes: 5 additions & 8 deletions ReactCommon/react/renderer/leakchecker/LeakChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,26 @@
#include "LeakChecker.h"

#include <glog/logging.h>
#include <jsi/instrumentation.h>

namespace facebook {
namespace react {

LeakChecker::LeakChecker(
RuntimeExecutor const &runtimeExecutor,
GarbageCollectionTrigger const &garbageCollectionTrigger)
: runtimeExecutor_(runtimeExecutor),
garbageCollectionTrigger_(garbageCollectionTrigger) {}
LeakChecker::LeakChecker(RuntimeExecutor const &runtimeExecutor)
: runtimeExecutor_(runtimeExecutor) {}

void LeakChecker::uiManagerDidCreateShadowNodeFamily(
ShadowNodeFamily::Shared const &shadowNodeFamily) const {
registry_.add(shadowNodeFamily);
}

void LeakChecker::stopSurface(SurfaceId surfaceId) {
garbageCollectionTrigger_();

if (previouslyStoppedSurface_ > 0) {
// Dispatch the check onto JavaScript thread to make sure all other
// cleanup code has had chance to run.
runtimeExecutor_([previouslySoppedSurface = previouslyStoppedSurface_,
this](jsi::Runtime &) {
this](jsi::Runtime &runtime) {
runtime.instrumentation().collectGarbage("LeakChecker");
// For now check the previous surface because React uses double
// buffering which keeps the surface that was just stopped in
// memory. This is a documented problem in the last point of
Expand Down
5 changes: 1 addition & 4 deletions ReactCommon/react/renderer/leakchecker/LeakChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ using GarbageCollectionTrigger = std::function<void()>;

class LeakChecker final {
public:
LeakChecker(
RuntimeExecutor const &runtimeExecutor,
GarbageCollectionTrigger const &garbageCollectionTrigger);
LeakChecker(RuntimeExecutor const &runtimeExecutor);

void uiManagerDidCreateShadowNodeFamily(
ShadowNodeFamily::Shared const &shadowNodeFamily) const;
Expand All @@ -32,7 +30,6 @@ class LeakChecker final {
void checkSurfaceForLeaks(SurfaceId surfaceId) const;

RuntimeExecutor const runtimeExecutor_{};
GarbageCollectionTrigger const garbageCollectionTrigger_{};

WeakFamilyRegistry registry_{};
SurfaceId previouslyStoppedSurface_;
Expand Down
4 changes: 1 addition & 3 deletions ReactCommon/react/renderer/scheduler/Scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,7 @@ Scheduler::Scheduler(
std::make_shared<better::optional<EventDispatcher const>>();

auto uiManager = std::make_shared<UIManager>(
runtimeExecutor_,
schedulerToolbox.backgroundExecutor,
schedulerToolbox.garbageCollectionTrigger);
runtimeExecutor_, schedulerToolbox.backgroundExecutor);
auto eventOwnerBox = std::make_shared<EventBeat::OwnerBox>();
eventOwnerBox->owner = eventDispatcher_;

Expand Down
6 changes: 0 additions & 6 deletions ReactCommon/react/renderer/scheduler/SchedulerToolbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,6 @@ struct SchedulerToolbox final {
*/
BackgroundExecutor backgroundExecutor;

/*
* Triggers garbage collection. Used when checking if all Fabric's HostObjects
* have been properly cleaned up from JavaScript.
*/
GarbageCollectionTrigger garbageCollectionTrigger;

/*
* A list of `UIManagerCommitHook`s that should be registered in `UIManager`.
*/
Expand Down
22 changes: 9 additions & 13 deletions ReactCommon/react/renderer/uimanager/UIManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,21 @@

namespace facebook::react {

static std::unique_ptr<LeakChecker> constructLeakChecker(
RuntimeExecutor const &runtimeExecutor,
GarbageCollectionTrigger const &garbageCollectionTrigger) {
if (garbageCollectionTrigger) {
return std::make_unique<LeakChecker>(
runtimeExecutor, garbageCollectionTrigger);
} else {
return {};
}
static std::unique_ptr<LeakChecker> constructLeakCheckerIfNeeded(
RuntimeExecutor const &runtimeExecutor) {
#ifdef REACT_NATIVE_DEBUG
return std::make_unique<LeakChecker>(runtimeExecutor);
#else
return {};
#endif
}

UIManager::UIManager(
RuntimeExecutor const &runtimeExecutor,
BackgroundExecutor const &backgroundExecutor,
GarbageCollectionTrigger const &garbageCollectionTrigger)
BackgroundExecutor const &backgroundExecutor)
: runtimeExecutor_(runtimeExecutor),
backgroundExecutor_(backgroundExecutor),
leakChecker_(
constructLeakChecker(runtimeExecutor, garbageCollectionTrigger)) {}
leakChecker_(constructLeakCheckerIfNeeded(runtimeExecutor)) {}

UIManager::~UIManager() {
LOG(WARNING) << "UIManager::~UIManager() was called (address: " << this
Expand Down
3 changes: 1 addition & 2 deletions ReactCommon/react/renderer/uimanager/UIManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ class UIManager final : public ShadowTreeDelegate {
public:
UIManager(
RuntimeExecutor const &runtimeExecutor,
BackgroundExecutor const &backgroundExecutor,
GarbageCollectionTrigger const &garbageCollectionTrigger);
BackgroundExecutor const &backgroundExecutor);

~UIManager();

Expand Down

0 comments on commit 118489f

Please sign in to comment.