Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-12200] Provide profiler data via communication channel #3910

Merged
merged 5 commits into from Mar 8, 2013
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -27,6 +27,8 @@ public class TiDeployData

protected static final String DEBUGGER_ENABLED = "debuggerEnabled";
protected static final String DEBUGGER_PORT = "debuggerPort";
protected static final String PROFILER_ENABLED = "profilerEnabled";
protected static final String PROFILER_PORT = "profilerPort";
protected static final String FASTDEV_PORT = "fastdevPort";
protected static final String FASTDEV_LISTEN = "fastdevListen";

Expand Down Expand Up @@ -84,6 +86,30 @@ public int getDebuggerPort()
return deployData.optInt(DEBUGGER_PORT, -1);
}

/**
* @return Whether or not the profiler server is enabled
*/
public boolean isProfilerEnabled()
{
if (deployData == null) {
return false;
}

return deployData.optBoolean(PROFILER_ENABLED, false);
}

/**
* @return The profiler server port, or -1
*/
public int getProfilerPort()
{
if (deployData == null) {
return -1;
}

return deployData.optInt(PROFILER_PORT, -1);
}

/**
* @return The "fastdev" http server port, or -1
*/
Expand Down
Expand Up @@ -6,6 +6,7 @@
*/
package org.appcelerator.kroll.runtime.v8;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;
Expand Down Expand Up @@ -67,6 +68,14 @@ public void initRuntime()

if (deployData.isDebuggerEnabled()) {
dispatchDebugMessages();
} else if (deployData.isProfilerEnabled()) {
try {
Class<?> clazz = Class.forName("org.appcelerator.titanium.profiler.TiProfiler");
Method method = clazz.getMethod("startProfiler", new Class[0]);
method.invoke(clazz, new Object[0]);
} catch (Exception e) {
Log.e(TAG, "Unable to load profiler.", e);
}
}

loadExternalModules();
Expand Down Expand Up @@ -131,6 +140,16 @@ private void loadExternalCommonJsModules()
@Override
public void doDispose()
{
TiDeployData deployData = getKrollApplication().getDeployData();
if (deployData.isProfilerEnabled()) {
try {
Class<?> clazz = Class.forName("org.appcelerator.titanium.profiler.TiProfiler");
Method method = clazz.getMethod("stopProfiler", new Class[0]);
method.invoke(clazz, new Object[0]);
} catch (Exception e) {
Log.e(TAG, "Unable to stop profiler.", e);
}
}
nativeDispose();
}

Expand Down
4 changes: 4 additions & 0 deletions android/runtime/v8/src/native/V8Runtime.cpp
Expand Up @@ -150,6 +150,10 @@ using namespace titanium;
*/
JNIEXPORT void JNICALL Java_org_appcelerator_kroll_runtime_v8_V8Runtime_nativeInit(JNIEnv *env, jobject self, jboolean useGlobalRefs, jint debuggerPort, jboolean DBG)
{
char* argv[] = { "", "--expose-gc" };
int argc = sizeof(argv)/sizeof(*argv);
V8::SetFlagsFromCommandLine(&argc, argv, false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we expose GC?

Also using SetFlagsFromString() would probably be easier. Not sure why you are computing argc that way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could either way.
About argc computing - I hate constants. But sizeof(argv)/sizeof(*argv) has a compile time value of 2.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay.


HandleScope scope;
titanium::JNIScope jniScope(env);

Expand Down
38 changes: 33 additions & 5 deletions support/android/builder.py
Expand Up @@ -347,6 +347,8 @@ def __init__(self, name, sdk, project_dir, support_dir, app_id):
self.force_rebuild = False
self.debugger_host = None
self.debugger_port = -1
self.profiler_host = None
self.profiler_port = -1
self.fastdev_port = -1
self.fastdev = False
self.compile_js = False
Expand Down Expand Up @@ -1531,6 +1533,7 @@ def build_generated_classes(self):
classpath = os.pathsep.join([classpath, os.path.join(self.support_dir, 'lib', 'titanium-verify.jar')])
if self.deploy_type != 'production':
classpath = os.pathsep.join([classpath, os.path.join(self.support_dir, 'lib', 'titanium-debug.jar')])
classpath = os.pathsep.join([classpath, os.path.join(self.support_dir, 'lib', 'titanium-profiler.jar')])

debug("Building Java Sources: " + " ".join(src_list))
javac_command = [self.javac, '-encoding', 'utf8',
Expand Down Expand Up @@ -1679,6 +1682,8 @@ def add_native_libs(libs_dir, exclude=[]):

# libtiverify is always included, even if targeting rhino.
apk_zip.write(os.path.join(lib_source_dir, 'libtiverify.so'), lib_dest_dir + 'libtiverify.so')
# profiler
apk_zip.write(os.path.join(lib_source_dir, 'libtiprofiler.so'), lib_dest_dir + 'libtiprofiler.so')

if self.runtime == 'v8':
for fname in ('libkroll-v8.so', 'libstlport_shared.so'):
Expand Down Expand Up @@ -1924,6 +1929,8 @@ def push_deploy_json(self):
deploy_data = {
"debuggerEnabled": self.debugger_host != None,
"debuggerPort": self.debugger_port,
"profilerEnabled": self.profiler_host != None,
"profilerPort": self.profiler_port,
"fastdevPort": self.fastdev_port
}
deploy_json = os.path.join(self.project_dir, 'bin', 'deploy.json')
Expand Down Expand Up @@ -1974,7 +1981,7 @@ def merge_internal_module_resources(self):
finally:
res_zip_file.close()

def build_and_run(self, install, avd_id, keystore=None, keystore_pass='tirocks', keystore_alias='tidev', dist_dir=None, build_only=False, device_args=None, debugger_host=None):
def build_and_run(self, install, avd_id, keystore=None, keystore_pass='tirocks', keystore_alias='tidev', dist_dir=None, build_only=False, device_args=None, debugger_host=None, profiler_host=None):
deploy_type = 'development'
self.build_only = build_only
self.device_args = device_args
Expand Down Expand Up @@ -2154,6 +2161,12 @@ def build_and_run(self, install, avd_id, keystore=None, keystore_pass='tirocks',
self.debugger_port = int(hostport[1])
debugger_enabled = self.debugger_host != None and len(self.debugger_host) > 0

if (not profiler_host is None) and len(profiler_host) > 0:
hostport = profiler_host.split(":")
self.profiler_host = hostport[0]
self.profiler_port = int(hostport[1])
profiler_enabled = self.profiler_host != None and len(self.profiler_host) > 0

# Detect which modules are being used.
# We need to know this info in a few places, so the info is saved
# in self.missing_modules and self.modules
Expand Down Expand Up @@ -2277,6 +2290,7 @@ def jar_includer(path, isfile):
dex_args.append(os.path.join(self.support_dir, 'lib', 'titanium-verify.jar'))
if self.deploy_type != 'production':
dex_args.append(os.path.join(self.support_dir, 'lib', 'titanium-debug.jar'))
dex_args.append(os.path.join(self.support_dir, 'lib', 'titanium-profiler.jar'))
# the verifier depends on Ti.Network classes, so we may need to inject it
has_network_jar = False
for jar in self.android_jars:
Expand Down Expand Up @@ -2339,6 +2353,12 @@ def jar_includer(path, isfile):
forwardPort = 'tcp:%s' % self.debugger_port
self.sdk.run_adb(['forward', forwardPort, forwardPort])

# Enable port forwarding for profiler
if profiler_enabled and self.runtime == 'v8':
info('Forwarding host port %s to device for profiling.' % self.profiler_port)
forwardPort = 'tcp:%s' % self.profiler_port
self.sdk.run_adb(['forward', forwardPort, forwardPort])

#intermediary code for on-device debugging (later)
#if debugger_host != None:
#import debugger
Expand Down Expand Up @@ -2481,9 +2501,12 @@ def usage():
info("Building %s for Android ... one moment" % project_name)
avd_id = dequote(sys.argv[6])
debugger_host = None
if len(sys.argv) > 8:
profiler_host = None
if len(sys.argv) > 9 and sys.argv[9] == 'profiler':
profiler_host = dequote(sys.argv[8])
elif len(sys.argv) > 8:
debugger_host = dequote(sys.argv[8])
builder.build_and_run(False, avd_id, debugger_host=debugger_host)
builder.build_and_run(False, avd_id, debugger_host=debugger_host, profiler_host=profiler_host)
elif command == 'install':
avd_id = dequote(sys.argv[6])
device_args = ['-d']
Expand All @@ -2493,7 +2516,12 @@ def usage():
# to Windows it just looks like a serial number is passed in (the debugger_host
# argument shifts left to take over the empty argument.)
debugger_host = None
if len(sys.argv) >= 9 and len(sys.argv[8]) > 0:
profiler_host = None
if len(sys.argv) >= 10 and sys.argv[9] == 'profiler':
profiler_host = dequote(sys.argv[8])
if len(sys.argv[7]) > 0:
device_args = ['-s', sys.argv[7]]
elif len(sys.argv) >= 9 and len(sys.argv[8]) > 0:
debugger_host = dequote(sys.argv[8])
if len(sys.argv[7]) > 0:
device_args = ['-s', sys.argv[7]]
Expand All @@ -2503,7 +2531,7 @@ def usage():
debugger_host = arg7
else:
device_args = ['-s', arg7]
builder.build_and_run(True, avd_id, device_args=device_args, debugger_host=debugger_host)
builder.build_and_run(True, avd_id, device_args=device_args, debugger_host=debugger_host, profiler_host=profiler_host)
elif command == 'distribute':
key = os.path.abspath(os.path.expanduser(dequote(sys.argv[6])))
password = dequote(sys.argv[7])
Expand Down
Binary file added support/android/lib/titanium-profiler.jar
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added support/android/native/libs/x86/libtiprofiler.so
Binary file not shown.