using ::android::base::GetBoolProperty; using android::base::StringPrintf;
namespace art HIDDEN {
inlinebool ShouldEnableProfileCode() { if (Runtime::Current() != nullptr && Runtime::Current()->IsAotCompiler()) { // For dex2oat invocations just look at the flag passed to the dex2oat command. return Runtime::Current()->GetCompilerCallbacks()->ShouldEnableProfileCode();
} bool build_enabled = GetBoolProperty("dalvik.vm.allow_profile_code", false); return com::android::art::rw::flags::enable_profile_code_rw() && build_enabled;
}
class TimestampCounter { public: static uint64_t GetTimestamp() {
uint64_t t = 0; #ifdefined(__arm__) // On ARM 32 bit, we don't always have access to the timestamp counters from user space. There // is no easy way to check if it is safe to read the timestamp counters. There is HWCAP_EVTSTRM // which is set when generic timer is available but not necessarily from the user space. Kernel // disables access to generic timer when there are known problems on the target CPUs. Sometimes // access is disabled only for 32-bit processes even when 64-bit processes can accesses the // timer from user space. These are not reflected in the HWCAP_EVTSTRM capability.So just // fallback to clock_gettime on these processes. See b/289178149 for more discussion.
t = NanoTime(); #elifdefined(__aarch64__) // See Arm Architecture Registers Armv8 section System Registers asmvolatile("mrs %0, cntvct_el0" : "=r"(t)); #elifdefined(__i386__) || defined(__x86_64__) // rdtsc returns two 32-bit values in rax and rdx even on 64-bit architectures. unsignedint lo, hi; asmvolatile("rdtsc" : "=a"(lo), "=d"(hi));
t = (static_cast<uint64_t>(hi) << 32) | lo; #elifdefined(__riscv) asmvolatile("rdtime %0" : "=r"(t)); #else
t = NanoTime(); #endif return t;
}
staticvoid InitializeTimestampCounters() { // It is sufficient to initialize this once for the entire execution. Just return if it is // already initialized. if (tsc_to_nanosec_scaling_factor_ > 0.0) { return;
}
#ifdefined(__arm__) // On ARM 32 bit, we don't always have access to the timestamp counters from // user space. Seem comment in GetTimestamp for more details.
tsc_to_nanosec_scaling_factor_ = 1.0; #elifdefined(__aarch64__)
uint64_t freq = 0; // See Arm Architecture Registers Armv8 section System Registers asmvolatile("mrs %0, cntfrq_el0" : "=r"(freq)); if (freq == 0) { // It is expected that cntfrq_el0 is correctly setup during system initialization but some // devices don't do this. In such cases fall back to computing the frequency. See b/315139000.
tsc_to_nanosec_scaling_factor_ = computeScalingFactor();
} else {
tsc_to_nanosec_scaling_factor_ = kSecondsToNanoseconds / static_cast<double>(freq);
} #elifdefined(__i386__) || defined(__x86_64__)
tsc_to_nanosec_scaling_factor_ = GetScalingFactorForX86(); #else
tsc_to_nanosec_scaling_factor_ = 1.0; #endif
}
private: #ifdefined(__i386__) || defined(__x86_64__) || defined(__aarch64__) // Here we compute the scaling factor by sleeping for a millisecond. Alternatively, we could // generate raw timestamp counter and also time using clock_gettime at the start and the end of // the trace. We can compute the frequency of timestamp counter upadtes in the post processing // step using these two samples. However, that would require a change in Android Studio which is // the main consumer of these profiles. For now, just compute the frequency of tsc updates here. staticdouble computeScalingFactor() {
uint64_t start = NanoTime();
uint64_t start_tsc = GetTimestamp(); // Sleep for one millisecond.
usleep(1000);
uint64_t diff_tsc = GetTimestamp() - start_tsc;
uint64_t diff_time = NanoTime() - start; double scaling_factor = static_cast<double>(diff_time) / diff_tsc;
DCHECK(scaling_factor > 0.0) << scaling_factor; return scaling_factor;
} #endif
#ifdefined(__i386__) || defined(__x86_64__) staticdouble GetScalingFactorForX86() {
uint32_t eax, ebx, ecx; asmvolatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx) : "a"(0x0), "c"(0)); if (eax < 0x15) { // There is no 15H - Timestamp counter and core crystal clock information // leaf. Just compute the frequency. return computeScalingFactor();
}
// From Intel architecture-instruction-set-extensions-programming-reference: // EBX[31:0]/EAX[31:0] indicates the ratio of the TSC frequency and the // core crystal clock frequency. // If EBX[31:0] is 0, the TSC and "core crystal clock" ratio is not enumerated. // If ECX is 0, the nominal core crystal clock frequency is not enumerated. // "TSC frequency" = "core crystal clock frequency" * EBX/EAX. // The core crystal clock may differ from the reference clock, bus clock, or core clock // frequencies. // EAX Bits 31 - 00: An unsigned integer which is the denominator of the // TSC/"core crystal clock" ratio. // EBX Bits 31 - 00: An unsigned integer which is the numerator of the // TSC/"core crystal clock" ratio. // ECX Bits 31 - 00: An unsigned integer which is the nominal frequency of the core // crystal clock in Hz. // EDX Bits 31 - 00: Reserved = 0. asmvolatile("cpuid" : "=a"(eax), "=b"(ebx), "=c"(ecx) : "a"(0x15), "c"(0)); if (ebx == 0 || ecx == 0) { return computeScalingFactor();
} double coreCrystalFreq = ecx; // frequency = coreCrystalFreq * (ebx / eax) // scaling_factor = seconds_to_nanoseconds / frequency // = seconds_to_nanoseconds * eax / (coreCrystalFreq * ebx) double scaling_factor = (kSecondsToNanoseconds * eax) / (coreCrystalFreq * ebx); return scaling_factor;
} #endif
// Scaling factor to convert timestamp counter into wall clock time reported in nano seconds. // This is initialized at the start of tracing using the timestamp counter update frequency. // See InitializeTimestampCounters for more details. staticdouble tsc_to_nanosec_scaling_factor_;
};
} // namespace art
#endif// ART_RUNTIME_TRACE_COMMON_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.