6#if defined(DART_HOST_OS_ANDROID)
10#include <android/log.h>
16#include <sys/resource.h>
33 android_log_to_stderr,
35 "Send Dart VM logs to stdout and stderr instead of the Android "
43 generate_perf_events_symbols,
45 "Generate events symbols for profiling with perf");
47class PerfCodeObserver :
public CodeObserver {
49 PerfCodeObserver() : out_file_(nullptr) {
51 if (file_open ==
nullptr) {
54 intptr_t pid = getpid();
55 char* filename =
OS::SCreate(
nullptr,
"/tmp/perf-%" Pd ".map", pid);
56 out_file_ = (*file_open)(filename,
true);
62 if ((file_close ==
nullptr) || (out_file_ ==
nullptr)) {
65 (*file_close)(out_file_);
68 virtual bool IsActive()
const {
69 return FLAG_generate_perf_events_symbols && (out_file_ !=
nullptr);
72 virtual void Notify(
const char*
name,
74 uword prologue_offset,
77 const CodeComments* comments) {
79 if ((file_write ==
nullptr) || (out_file_ ==
nullptr)) {
82 const char*
marker = optimized ?
"*" :
"";
98 return static_cast<intptr_t
>(getpid());
101static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
102 time_t seconds =
static_cast<time_t
>(seconds_since_epoch);
103 if (seconds != seconds_since_epoch)
return false;
104 struct tm* error_code = localtime_r(&seconds, tm_result);
105 return error_code !=
nullptr;
110 bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
112 return (succeeded && (decomposed.tm_zone !=
nullptr)) ? decomposed.tm_zone
118 bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
121 return succeeded ?
static_cast<int>(decomposed.tm_gmtoff) : 0;
131 if (gettimeofday(&tv,
nullptr) < 0) {
135 return (
static_cast<int64_t
>(tv.tv_sec) * 1000000) + tv.tv_usec;
140 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
145 int64_t
result = ts.tv_sec;
163 if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
167 int64_t
result = ts.tv_sec;
174#if defined(SUPPORT_TIMELINE)
175 if (Timeline::recorder_discards_clock_values())
return -1;
185#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) || \
186 defined(TARGET_ARCH_ARM64) || defined(TARGET_ARCH_RISCV64)
187 const int kMinimumAlignment = 16;
188#elif defined(TARGET_ARCH_ARM)
189 const int kMinimumAlignment = 8;
191#error Unsupported architecture.
193 intptr_t alignment = kMinimumAlignment;
198 ASSERT(alignment >= kMinimumAlignment);
203 return sysconf(_SC_NPROCESSORS_ONLN);
217 req.tv_sec = seconds;
220 int r = nanosleep(&req, &rem);
236 return reinterpret_cast<uintptr_t
>(
237 __builtin_extract_return_addr(__builtin_return_address(0)));
243 if (FLAG_android_log_to_stderr) {
247 __android_log_vprint(ANDROID_LOG_INFO,
"DartVM",
format,
args);
267 va_list measure_args;
268 va_copy(measure_args,
args);
282 va_copy(print_args,
args);
289 ASSERT(str !=
nullptr && strlen(str) > 0 &&
value !=
nullptr);
295 }
else if (str[0] ==
'+') {
298 if ((str[
i] ==
'0') && (str[
i + 1] ==
'x' || str[
i + 1] ==
'X') &&
299 (str[
i + 2] !=
'\0')) {
306 *
value =
static_cast<int64_t
>(strtoull(str, &endptr,
base));
310 return ((errno == 0) && (endptr != str) && (*endptr == 0));
315 if (FLAG_generate_perf_events_symbols) {
324 if (FLAG_android_log_to_stderr) {
328 __android_log_vprint(ANDROID_LOG_ERROR,
"DartVM",
format,
args);
349#if defined(ARCH_IS_64_BIT)
350#define ElfW(Type) Elf64_##Type
352#define ElfW(Type) Elf32_##Type
358 const Image instructions_image(snapshot_instructions);
359 if (
auto*
const image_build_id = instructions_image.build_id()) {
360 return {instructions_image.build_id_length(), image_build_id};
362 const uint8_t* dso_base =
GetAppDSOBase(snapshot_instructions);
363 const ElfW(Ehdr)& elf_header = *
reinterpret_cast<const ElfW(Ehdr)*
>(dso_base);
364 const ElfW(Phdr)*
const phdr_array =
365 reinterpret_cast<const ElfW(Phdr)*
>(dso_base + elf_header.e_phoff);
366 for (intptr_t
i = 0;
i < elf_header.e_phnum;
i++) {
367 const ElfW(Phdr)&
header = phdr_array[
i];
368 if (
header.p_type != PT_NOTE)
continue;
370 const uint8_t*
const note_addr = dso_base +
header.p_vaddr;
371 const Elf32_Nhdr& note_header =
372 *
reinterpret_cast<const Elf32_Nhdr*
>(note_addr);
373 if (note_header.n_type != NT_GNU_BUILD_ID)
continue;
374 const char*
const note_contents =
375 reinterpret_cast<const char*
>(note_addr +
sizeof(Elf32_Nhdr));
377 if (note_header.n_namesz != strlen(
ELF_NOTE_GNU) + 1)
continue;
378 if (strncmp(
ELF_NOTE_GNU, note_contents, note_header.n_namesz) == 0) {
379 return {
static_cast<intptr_t
>(note_header.n_descsz),
380 reinterpret_cast<const uint8_t*
>(note_contents +
381 note_header.n_namesz)};
static const char marker[]
static void Register(CodeObserver *observer)
static Dart_FileWriteCallback file_write_callback()
static Dart_FileOpenCallback file_open_callback()
static Dart_FileCloseCallback file_close_callback()
static DART_NORETURN void Exit(int code)
static int NumberOfAvailableProcessors()
static const char * GetTimeZoneName(int64_t seconds_since_epoch)
static void SleepMicros(int64_t micros)
static int64_t GetCurrentTimeMillis()
static void RegisterCodeObservers()
static int64_t GetCurrentMonotonicMicros()
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static void Sleep(int64_t millis)
static void Print(const char *format,...) PRINTF_ATTRIBUTE(1
static bool StringToInt64(const char *str, int64_t *value)
static BuildId GetAppBuildId(const uint8_t *snapshot_instructions)
static const uint8_t * GetAppDSOBase(const uint8_t *snapshot_instructions)
static int64_t GetCurrentTimeMicros()
static intptr_t ActivationFrameAlignment()
static void static void static void VFPrint(FILE *stream, const char *format, va_list args)
static DART_NORETURN void Abort()
static char static char * VSCreate(Zone *zone, const char *format, va_list args)
static int64_t GetCurrentThreadCPUMicros()
static uintptr_t GetProgramCounter()
static intptr_t ProcessId()
static void PrepareToAbort()
static int64_t GetCurrentMonotonicFrequency()
static char * SCreate(Zone *zone, const char *format,...) PRINTF_ATTRIBUTE(2
static int64_t GetCurrentMonotonicTicks()
static int64_t GetCurrentMonotonicMicrosForTimeline()
static int GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch)
static Thread * Current()
static int static int VSNPrint(char *str, size_t size, const char *format, va_list args)
static constexpr bool IsPowerOfTwo(T x)
void(* Dart_FileWriteCallback)(const void *data, intptr_t length, void *stream)
void(* Dart_FileCloseCallback)(void *stream)
void *(* Dart_FileOpenCallback)(const char *name, bool write)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint32_t uint32_t * format
static constexpr intptr_t PF_R
static constexpr const char ELF_NOTE_GNU[]
constexpr intptr_t kMicrosecondsPerMillisecond
constexpr intptr_t kMicrosecondsPerSecond
constexpr intptr_t kNanosecondsPerMicrosecond
void * malloc(size_t size)
constexpr intptr_t kNanosecondsPerSecond
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static const char header[]