mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 734302 - Part 1: Enable the Gecko Profiler on native Fennec; r=BenWa,khuey
--HG-- extra : rebase_source : 050443e4850aac78551ed985aa81522d808bcb6b
This commit is contained in:
parent
ff45f86f4f
commit
5fc5ba4b3e
36
configure.in
36
configure.in
@ -8893,6 +8893,42 @@ if test "$CAIRO_FEATURES_H"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Build libunwind for Android profiling builds
|
||||
if test "$OS_TARGET" = "Android" -a "$MOZ_PROFILING"; then
|
||||
old_ac_configure_arg="$ac_configure_args"
|
||||
ac_configure_args="--build=${build} --host=${target_alias} --disable-shared --enable-block-signals=no"
|
||||
if test "$MOZ_DEBUG"; then
|
||||
ac_configure_args="$ac_configure_args --enable-debug"
|
||||
fi
|
||||
if test "$DSO_PIC_CFLAGS"; then
|
||||
ac_configure_args="$ac_configure_args --with-pic"
|
||||
fi
|
||||
ac_configure_args="$ac_configure_args \
|
||||
CC=\"$CC\" \
|
||||
CXX=\"$CXX\" \
|
||||
CPP=\"$CPP\" \
|
||||
CFLAGS=\"$CFLAGS\" \
|
||||
CXXFLAGS=\"$CXXFLAGS\" \
|
||||
CPPFLAGS=\"$CPPFLAGS\" \
|
||||
LD=\"$LD\" \
|
||||
LDFLAGS=\"$LDFLAGS\" \
|
||||
AR=\"$AR\" \
|
||||
RANLIB=\"$RANLIB\" \
|
||||
STRIP=\"$STRIP\" \
|
||||
LIBS=\"$LIBS\""
|
||||
|
||||
# Use a separate cache file for libunwind, since it does not use caching.
|
||||
mkdir -p $_objdir/tools/profiler/libunwind/src
|
||||
old_cache_file=$cache_file
|
||||
cache_file=$_objdir/tools/profiler/libunwind/src/config.cache
|
||||
old_config_files=$CONFIG_FILES
|
||||
unset CONFIG_FILES
|
||||
AC_OUTPUT_SUBDIRS(tools/profiler/libunwind/src)
|
||||
cache_file=$old_cache_file
|
||||
ac_configure_args="$old_ac_configure_args"
|
||||
CONFIG_FILES=$old_config_files
|
||||
fi
|
||||
|
||||
# Run freetype configure script
|
||||
|
||||
if test "$MOZ_TREE_FREETYPE"; then
|
||||
|
@ -84,6 +84,7 @@
|
||||
<li><a href="about:license#libevent">libevent License</a></li>
|
||||
<li><a href="about:license#libffi">libffi License</a></li>
|
||||
<li><a href="about:license#libnestegg">libnestegg License</a></li>
|
||||
<li><a href="about:license#libunwind">libunwind License</a></li>
|
||||
<li><a href="about:license#hunspell-lt">Lithuanian Spellchecking Dictionary License</a></li>
|
||||
<li><a href="about:license#maattachedwindow">MAAttachedWindow License</a></li>
|
||||
<li><a href="about:license#msstdint">msstdint License</a></li>
|
||||
@ -1865,6 +1866,35 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h1><a id="libunwind"></a>libunwind License</h1>
|
||||
|
||||
<p>This license applies to files in the directory
|
||||
<span class="path">tools/profiler/libunwind</span>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
@ -57,6 +57,25 @@ LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/ipc/chromium/src \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(MOZ_PROFILING))
|
||||
ifneq (,$(filter Android,$(OS_TARGET)))
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/tools/profiler/libunwind/src/include \
|
||||
-I$(DEPTH)/tools/profiler/libunwind/src/include \
|
||||
$(NULL)
|
||||
|
||||
SHARED_LIBRARY_LIBS += \
|
||||
$(DEPTH)/tools/profiler/libunwind/src/src/.libs/libunwind-arm.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
export::
|
||||
$(call SUBMAKE,,libunwind/src)
|
||||
|
||||
distclean::
|
||||
$(call SUBMAKE,$@,libunwind/src)
|
||||
endif
|
||||
endif
|
||||
|
||||
MODULE = profiler
|
||||
MODULE_NAME = nsProfilerModule
|
||||
LIBRARY_NAME = profiler
|
||||
|
@ -65,6 +65,12 @@
|
||||
#include "nsStackWalk.h"
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_PROFILING) && defined(ANDROID)
|
||||
#define USE_LIBUNWIND
|
||||
#include <libunwind.h>
|
||||
#include "android-signal-defs.h"
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
using namespace mozilla;
|
||||
|
||||
@ -347,7 +353,14 @@ class TableTicker: public Sampler {
|
||||
, mPrimaryThreadProfile(aEntrySize, aStack)
|
||||
, mSaveRequested(false)
|
||||
{
|
||||
#if defined(USE_LIBUNWIND) && defined(ANDROID)
|
||||
// We don't have the Gecko Profiler add-on on Android, but we know that
|
||||
// libunwind is available, so we can always walk the stacks.
|
||||
mUseStackWalk = true;
|
||||
#else
|
||||
mUseStackWalk = hasFeature(aFeatures, aFeatureCount, "stackwalk");
|
||||
#endif
|
||||
|
||||
//XXX: It's probably worth splitting the jank profiler out from the regular profiler at some point
|
||||
mJankOnly = hasFeature(aFeatures, aFeatureCount, "jank");
|
||||
mPrimaryThreadProfile.addTag(ProfileEntry('m', "Start"));
|
||||
@ -377,7 +390,7 @@ class TableTicker: public Sampler {
|
||||
|
||||
private:
|
||||
// Not implemented on platforms which do not support backtracing
|
||||
void doBacktrace(ThreadProfile &aProfile, Address pc);
|
||||
static void doBacktrace(ThreadProfile &aProfile, TickSample* aSample);
|
||||
|
||||
private:
|
||||
// This represent the application's main thread (SAMPLER_INIT)
|
||||
@ -465,7 +478,7 @@ JSObject* TableTicker::ToJSObject(JSContext *aCx)
|
||||
|
||||
|
||||
#ifdef USE_BACKTRACE
|
||||
void TableTicker::doBacktrace(ThreadProfile &aProfile, Address pc)
|
||||
void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
{
|
||||
void *array[100];
|
||||
int count = backtrace (array, 100);
|
||||
@ -498,7 +511,7 @@ void StackWalkCallback(void* aPC, void* aClosure)
|
||||
array->array[array->count++] = aPC;
|
||||
}
|
||||
|
||||
void TableTicker::doBacktrace(ThreadProfile &aProfile, Address fp)
|
||||
void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
{
|
||||
#ifndef XP_MACOSX
|
||||
uintptr_t thread = GetThreadHandle(platform_data());
|
||||
@ -515,7 +528,7 @@ void TableTicker::doBacktrace(ThreadProfile &aProfile, Address fp)
|
||||
void *stackEnd = reinterpret_cast<void*>(-1);
|
||||
if (pt)
|
||||
stackEnd = static_cast<char*>(pthread_get_stackaddr_np(pt));
|
||||
nsresult rv = FramePointerStackWalk(StackWalkCallback, 1, &array, reinterpret_cast<void**>(fp), stackEnd);
|
||||
nsresult rv = FramePointerStackWalk(StackWalkCallback, 1, &array, reinterpret_cast<void**>(aSample->fp), stackEnd);
|
||||
#else
|
||||
nsresult rv = NS_StackWalk(StackWalkCallback, 0, &array, thread);
|
||||
#endif
|
||||
@ -529,6 +542,54 @@ void TableTicker::doBacktrace(ThreadProfile &aProfile, Address fp)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIBUNWIND) && defined(ANDROID)
|
||||
void TableTicker::doBacktrace(ThreadProfile &aProfile, TickSample* aSample)
|
||||
{
|
||||
void* pc_array[1000];
|
||||
size_t count = 0;
|
||||
|
||||
unw_cursor_t cursor; unw_context_t uc;
|
||||
unw_word_t ip;
|
||||
unw_getcontext(&uc);
|
||||
|
||||
// Dirty hack: replace the registers with values from the signal handler
|
||||
// We do this in order to avoid the overhead of walking up to reach the
|
||||
// signal handler frame, and the possibility that libunwind fails to
|
||||
// handle it correctly.
|
||||
unw_tdep_context_t *unw_ctx = reinterpret_cast<unw_tdep_context_t*> (&uc);
|
||||
mcontext_t& mcontext = reinterpret_cast<ucontext_t*> (aSample->context)->uc_mcontext;
|
||||
#define REPLACE_REG(num) unw_ctx->regs[num] = mcontext.gregs[R##num]
|
||||
REPLACE_REG(0);
|
||||
REPLACE_REG(1);
|
||||
REPLACE_REG(2);
|
||||
REPLACE_REG(3);
|
||||
REPLACE_REG(4);
|
||||
REPLACE_REG(5);
|
||||
REPLACE_REG(6);
|
||||
REPLACE_REG(7);
|
||||
REPLACE_REG(8);
|
||||
REPLACE_REG(9);
|
||||
REPLACE_REG(10);
|
||||
REPLACE_REG(11);
|
||||
REPLACE_REG(12);
|
||||
REPLACE_REG(13);
|
||||
REPLACE_REG(14);
|
||||
REPLACE_REG(15);
|
||||
#undef REPLACE_REG
|
||||
unw_init_local(&cursor, &uc);
|
||||
while (count < ArrayLength(pc_array) &&
|
||||
unw_step(&cursor) > 0) {
|
||||
unw_get_reg(&cursor, UNW_REG_IP, &ip);
|
||||
pc_array[count++] = reinterpret_cast<void*> (ip);
|
||||
}
|
||||
|
||||
aProfile.addTag(ProfileEntry('s', "(root)", 0));
|
||||
for (size_t i = count; i > 0; --i) {
|
||||
aProfile.addTag(ProfileEntry('l', reinterpret_cast<const char*>(pc_array[i - 1])));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static
|
||||
void doSampleStackTrace(ProfileStack *aStack, ThreadProfile &aProfile, TickSample *sample)
|
||||
{
|
||||
@ -591,9 +652,9 @@ void TableTicker::Tick(TickSample* sample)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_BACKTRACE) || defined(USE_NS_STACKWALK)
|
||||
#if defined(USE_BACKTRACE) || defined(USE_NS_STACKWALK) || defined(USE_LIBUNWIND)
|
||||
if (mUseStackWalk) {
|
||||
doBacktrace(mPrimaryThreadProfile, sample->fp);
|
||||
doBacktrace(mPrimaryThreadProfile, sample);
|
||||
} else {
|
||||
doSampleStackTrace(stack, mPrimaryThreadProfile, sample);
|
||||
}
|
||||
@ -637,11 +698,6 @@ string ProfileEntry::TagToString(ThreadProfile *profile)
|
||||
return tag;
|
||||
}
|
||||
|
||||
#define PROFILE_DEFAULT_ENTRY 100000
|
||||
#define PROFILE_DEFAULT_INTERVAL 10
|
||||
#define PROFILE_DEFAULT_FEATURES NULL
|
||||
#define PROFILE_DEFAULT_FEATURE_COUNT 0
|
||||
|
||||
void mozilla_sampler_init()
|
||||
{
|
||||
// TODO linux port: Use TLS with ifdefs
|
||||
@ -655,6 +711,18 @@ void mozilla_sampler_init()
|
||||
ProfileStack *stack = new ProfileStack();
|
||||
mozilla::tls::set(pkey_stack, stack);
|
||||
|
||||
#if defined(USE_LIBUNWIND) && defined(ANDROID)
|
||||
// Only try debug_frame and exidx unwinding
|
||||
putenv("UNW_ARM_UNWIND_METHOD=5");
|
||||
|
||||
// Allow the profiler to be started and stopped using signals
|
||||
OS::RegisterStartStopHandlers();
|
||||
|
||||
// On Android, this is too soon in order to start up the
|
||||
// profiler.
|
||||
return;
|
||||
#endif
|
||||
|
||||
// We can't open pref so we use an environment variable
|
||||
// to know if we should trigger the profiler on startup
|
||||
// NOTE: Default
|
||||
@ -717,7 +785,7 @@ JSObject *mozilla_sampler_get_profile_data(JSContext *aCx)
|
||||
const char** mozilla_sampler_get_features()
|
||||
{
|
||||
static const char* features[] = {
|
||||
#if defined(MOZ_PROFILING) && (defined(USE_BACKTRACE) || defined(USE_NS_STACKWALK))
|
||||
#if defined(MOZ_PROFILING) && (defined(USE_BACKTRACE) || defined(USE_NS_STACKWALK) || defined(USE_LIBUNWIND))
|
||||
"stackwalk",
|
||||
#endif
|
||||
"jank",
|
||||
|
61
tools/profiler/android-signal-defs.h
Normal file
61
tools/profiler/android-signal-defs.h
Normal file
@ -0,0 +1,61 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2012
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Android runs a fairly new Linux kernel, so signal info is there,
|
||||
// but the C library doesn't have the structs defined.
|
||||
|
||||
struct sigcontext {
|
||||
uint32_t trap_no;
|
||||
uint32_t error_code;
|
||||
uint32_t oldmask;
|
||||
uint32_t gregs[16];
|
||||
uint32_t arm_cpsr;
|
||||
uint32_t fault_address;
|
||||
};
|
||||
typedef uint32_t __sigset_t;
|
||||
typedef struct sigcontext mcontext_t;
|
||||
typedef struct ucontext {
|
||||
uint32_t uc_flags;
|
||||
struct ucontext* uc_link;
|
||||
stack_t uc_stack;
|
||||
mcontext_t uc_mcontext;
|
||||
__sigset_t uc_sigmask;
|
||||
} ucontext_t;
|
||||
enum ArmRegisters {R0 = 0, R1 = 1, R2 = 2, R3 = 3, R4 = 4, R5 = 5,
|
||||
R6 = 6, R7 = 7, R8 = 8, R9 = 9, R10 = 10,
|
||||
R11 = 11, R12 = 12, R13 = 13, R14 = 14, R15 = 15};
|
||||
|
12
tools/profiler/libunwind/README.mozilla
Normal file
12
tools/profiler/libunwind/README.mozilla
Normal file
@ -0,0 +1,12 @@
|
||||
This is a copy of the libunwind source code, tailored for stack walking on ARM
|
||||
Android.
|
||||
|
||||
This code includes patches to libunwind which have not been upstreamed yet.
|
||||
Please note that this copy of the code is READ-ONLY, and is owned by
|
||||
Ehsan Akhgari. Modifications to this code without coordinating with the
|
||||
owner are unacceptable, and will be reverted.
|
||||
|
||||
The canonical repository for this source code is https://github.com/ehsan/libunwind.
|
||||
The information about the upstream repository and revision lives in upstream.info.
|
||||
In order to update the code, you can run the update.sh script located in
|
||||
the same directory.
|
19
tools/profiler/libunwind/update.sh
Executable file
19
tools/profiler/libunwind/update.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
cd `dirname $0`
|
||||
|
||||
source upstream.info
|
||||
|
||||
hg rm -f src
|
||||
rm -rf src
|
||||
git clone "$UPSTREAM_REPO" src
|
||||
cd src
|
||||
git checkout "$UPSTREAM_COMMIT"
|
||||
autoreconf -i
|
||||
rm -rf .git .gitignore
|
||||
cd ..
|
||||
hg add src
|
||||
|
||||
echo "libunwind has now been updated. Don't forget to run hg commit!"
|
2
tools/profiler/libunwind/upstream.info
Normal file
2
tools/profiler/libunwind/upstream.info
Normal file
@ -0,0 +1,2 @@
|
||||
UPSTREAM_REPO=git://github.com/ehsan/libunwind.git
|
||||
UPSTREAM_COMMIT=bf6079087f2901e55d737e517a4225e905913e81
|
@ -35,6 +35,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include "platform.h"
|
||||
#include "sps_sampler.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -54,28 +55,7 @@ static Sampler* sActiveSampler = NULL;
|
||||
|
||||
|
||||
#if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__))
|
||||
// Android runs a fairly new Linux kernel, so signal info is there,
|
||||
// but the C library doesn't have the structs defined.
|
||||
|
||||
struct sigcontext {
|
||||
uint32_t trap_no;
|
||||
uint32_t error_code;
|
||||
uint32_t oldmask;
|
||||
uint32_t gregs[16];
|
||||
uint32_t arm_cpsr;
|
||||
uint32_t fault_address;
|
||||
};
|
||||
typedef uint32_t __sigset_t;
|
||||
typedef struct sigcontext mcontext_t;
|
||||
typedef struct ucontext {
|
||||
uint32_t uc_flags;
|
||||
struct ucontext* uc_link;
|
||||
stack_t uc_stack;
|
||||
mcontext_t uc_mcontext;
|
||||
__sigset_t uc_sigmask;
|
||||
} ucontext_t;
|
||||
enum ArmRegisters {R15 = 15, R13 = 13, R11 = 11};
|
||||
|
||||
#include "android-signal-defs.h"
|
||||
#endif
|
||||
|
||||
static void ProfilerSaveSignalHandler(int signal, siginfo_t* info, void* context) {
|
||||
@ -95,7 +75,7 @@ static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) {
|
||||
|
||||
TickSample sample_obj;
|
||||
TickSample* sample = &sample_obj;
|
||||
sample->pc = 0;
|
||||
sample->context = context;
|
||||
|
||||
#ifdef ENABLE_SPS_LEAF_DATA
|
||||
// If profiling, we extract the current pc and sp.
|
||||
@ -282,3 +262,23 @@ void Sampler::Stop() {
|
||||
sActiveSampler = NULL;
|
||||
}
|
||||
|
||||
static struct sigaction old_sigstartstop_signal_handler;
|
||||
const int SIGSTARTSTOP = SIGUSR1;
|
||||
|
||||
static void StartStopSignalHandler(int signal, siginfo_t* info, void* context) {
|
||||
mozilla_sampler_start(PROFILE_DEFAULT_ENTRY, PROFILE_DEFAULT_INTERVAL,
|
||||
PROFILE_DEFAULT_FEATURES, PROFILE_DEFAULT_FEATURE_COUNT);
|
||||
}
|
||||
|
||||
void OS::RegisterStartStopHandlers()
|
||||
{
|
||||
LOG("Registering start/stop signal");
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = StartStopSignalHandler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
if (sigaction(SIGSTARTSTOP, &sa, &old_sigstartstop_signal_handler) != 0) {
|
||||
LOG("Error installing signal");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <vector>
|
||||
#define ASSERT(a) MOZ_ASSERT(a)
|
||||
#ifdef ANDROID
|
||||
#ifdef defined(__arm__) || defined(__thumb__)
|
||||
#if defined(__arm__) || defined(__thumb__)
|
||||
#define ENABLE_SPS_LEAF_DATA
|
||||
#endif
|
||||
#define LOG(text) __android_log_print(ANDROID_LOG_ERROR, "profiler", "%s", text);
|
||||
@ -90,6 +90,10 @@ class OS {
|
||||
// Please use delete to reclaim the storage for the returned Mutex.
|
||||
static Mutex* CreateMutex();
|
||||
|
||||
// On supported platforms, setup a signal handler which would start
|
||||
// and stop the profiler.
|
||||
static void RegisterStartStopHandlers();
|
||||
|
||||
private:
|
||||
static const int msPerSecond = 1000;
|
||||
|
||||
@ -160,11 +164,13 @@ class TickSample {
|
||||
sp(NULL),
|
||||
fp(NULL),
|
||||
function(NULL),
|
||||
context(NULL),
|
||||
frames_count(0) {}
|
||||
Address pc; // Instruction pointer.
|
||||
Address sp; // Stack pointer.
|
||||
Address fp; // Frame pointer.
|
||||
Address function; // The last called JS function.
|
||||
void* context; // The context from the signal handler, if available
|
||||
static const int kMaxFramesCount = 64;
|
||||
Address stack[kMaxFramesCount]; // Call stack.
|
||||
int frames_count; // Number of captured frames.
|
||||
|
@ -89,6 +89,20 @@ extern bool stack_key_initialized;
|
||||
#warning Please add support for your architecture in chromium_types.h
|
||||
#endif
|
||||
|
||||
#define PROFILE_DEFAULT_ENTRY 100000
|
||||
#ifdef ANDROID
|
||||
// We use a lower frequency on Android, in order to make things work
|
||||
// more smoothly on phones. This value can be adjusted later with
|
||||
// some libunwind optimizations.
|
||||
// In one sample measurement on Galaxy Nexus, out of about 700 backtraces,
|
||||
// 60 of them took more than 25ms, and the average and standard deviation
|
||||
// were 6.17ms and 9.71ms respectively.
|
||||
#define PROFILE_DEFAULT_INTERVAL 25
|
||||
#else
|
||||
#define PROFILE_DEFAULT_INTERVAL 10
|
||||
#endif
|
||||
#define PROFILE_DEFAULT_FEATURES NULL
|
||||
#define PROFILE_DEFAULT_FEATURE_COUNT 0
|
||||
|
||||
// STORE_SEQUENCER: Because signals can interrupt our profile modification
|
||||
// we need to make stores are not re-ordered by the compiler
|
||||
|
Loading…
Reference in New Issue
Block a user