com.facebook.react.devsupport.JSCSamplingProfiler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of react-native Show documentation
Show all versions of react-native Show documentation
A framework for building native apps with React
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.devsupport;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
@ReactModule(name = "JSCSamplingProfiler")
public class JSCSamplingProfiler extends ReactContextBaseJavaModule {
public interface SamplingProfiler extends JavaScriptModule {
void poke(int token);
}
public static class ProfilerException extends Exception {
ProfilerException(String message) {
super(message);
}
}
private @Nullable SamplingProfiler mSamplingProfiler;
private boolean mOperationInProgress;
private int mOperationToken;
private @Nullable String mOperationError;
private @Nullable String mSamplingProfilerResult;
private static final HashSet sRegisteredDumpers =
new HashSet<>();
private static synchronized void registerSamplingProfiler(
JSCSamplingProfiler dumper) {
if (sRegisteredDumpers.contains(dumper)) {
throw new RuntimeException(
"a JSCSamplingProfiler registered more than once");
}
sRegisteredDumpers.add(dumper);
}
private static synchronized void unregisterSamplingProfiler(
JSCSamplingProfiler dumper) {
sRegisteredDumpers.remove(dumper);
}
public static synchronized List poke(long timeout)
throws ProfilerException {
LinkedList results = new LinkedList<>();
if (sRegisteredDumpers.isEmpty()) {
throw new ProfilerException("No JSC registered");
}
for (JSCSamplingProfiler dumper : sRegisteredDumpers) {
dumper.pokeHelper(timeout);
results.add(dumper.mSamplingProfilerResult);
}
return results;
}
public JSCSamplingProfiler(ReactApplicationContext reactContext) {
super(reactContext);
mSamplingProfiler = null;
mOperationInProgress = false;
mOperationToken = 0;
mOperationError = null;
mSamplingProfilerResult = null;
}
private synchronized void pokeHelper(long timeout) throws ProfilerException {
if (mSamplingProfiler == null) {
throw new ProfilerException("SamplingProfiler.js module not connected");
}
mSamplingProfiler.poke(getOperationToken());
waitForOperation(timeout);
}
private int getOperationToken() throws ProfilerException {
if (mOperationInProgress) {
throw new ProfilerException("Another operation already in progress.");
}
mOperationInProgress = true;
return ++mOperationToken;
}
private void waitForOperation(long timeout) throws ProfilerException {
try {
wait(timeout);
} catch (InterruptedException e) {
throw new ProfilerException(
"Waiting for heap capture failed: " + e.getMessage());
}
if (mOperationInProgress) {
mOperationInProgress = false;
throw new ProfilerException("heap capture timed out.");
}
if (mOperationError != null) {
throw new ProfilerException(mOperationError);
}
}
@ReactMethod
public synchronized void operationComplete(
int token, String result, String error) {
if (token == mOperationToken) {
mOperationInProgress = false;
mSamplingProfilerResult = result;
mOperationError = error;
this.notify();
} else {
throw new RuntimeException("Completed operation is not in progress.");
}
}
@Override
public String getName() {
return "JSCSamplingProfiler";
}
@Override
public void initialize() {
super.initialize();
mSamplingProfiler =
getReactApplicationContext().getJSModule(SamplingProfiler.class);
registerSamplingProfiler(this);
}
@Override
public void onCatalystInstanceDestroy() {
super.onCatalystInstanceDestroy();
unregisterSamplingProfiler(this);
mSamplingProfiler = null;
}
}