-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#15 Add a button in devtools to start/stop the Sampling Profiler
Differential Revision: D3555704 fbshipit-source-id: 4add16c923fcfd306892efec4630c24ae438d6dd
- Loading branch information
1 parent
e762d96
commit ec0ccf5
Showing
7 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* 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. | ||
* | ||
* @providesModule SamplingProfiler | ||
* @flow | ||
*/ | ||
'use strict'; | ||
|
||
var SamplingProfiler = { | ||
poke: function (token: number): void { | ||
var error = null; | ||
var result = null; | ||
try { | ||
result = global.pokeSamplingProfiler(); | ||
if (result === null) { | ||
console.log('The JSC Sampling Profiler has started'); | ||
} else { | ||
console.log('The JSC Sampling Profiler has stopped'); | ||
} | ||
} catch (e) { | ||
console.log( | ||
'Error occured when restarting Sampling Profiler: ' + e.toString()); | ||
error = e.toString(); | ||
} | ||
require('NativeModules').JSCSamplingProfiler.operationComplete( | ||
token, result, error); | ||
}, | ||
}; | ||
|
||
module.exports = SamplingProfiler; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 147 additions & 0 deletions
147
ReactAndroid/src/main/java/com/facebook/react/devsupport/JSCSamplingProfiler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
/** | ||
* 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.io.File; | ||
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; | ||
|
||
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<JSCSamplingProfiler> 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<String> poke(long timeout) | ||
throws ProfilerException { | ||
LinkedList<String> 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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters