+void SamplingFlags::start()
+{
+ for (unsigned i = 0; i <= 32; ++i)
+ s_flagCounts[i] = 0;
+}
+void SamplingFlags::stop()
+{
+ uint64_t total = 0;
+ for (unsigned i = 0; i <= 32; ++i)
+ total += s_flagCounts[i];
+
+ if (total) {
+ dataLogF("\nSamplingFlags: sample counts with flags set: (%lld total)\n", total);
+ for (unsigned i = 0; i <= 32; ++i) {
+ if (s_flagCounts[i])
+ dataLogF(" [ %02d ] : %lld\t\t(%03.2f%%)\n", i, s_flagCounts[i], (100.0 * s_flagCounts[i]) / total);
+ }
+ dataLogF("\n");
+ } else
+ dataLogF("\nSamplingFlags: no samples.\n\n");
+}
+uint64_t SamplingFlags::s_flagCounts[33];
+
+#else
+void SamplingFlags::start() {}
+void SamplingFlags::stop() {}
+#endif
+
+#if ENABLE(SAMPLING_REGIONS)
+volatile uintptr_t SamplingRegion::s_currentOrReserved;
+Spectrum<const char*>* SamplingRegion::s_spectrum;
+unsigned long SamplingRegion::s_noneOfTheAbove;
+unsigned SamplingRegion::s_numberOfSamplesSinceDump;
+
+SamplingRegion::Locker::Locker()
+{
+ uintptr_t previous;
+ while (true) {
+ previous = s_currentOrReserved;
+ if (previous & 1) {
+#if OS(UNIX)
+ sched_yield();
+#endif
+ continue;
+ }
+ if (WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, previous | 1))
+ break;
+ }
+}
+
+SamplingRegion::Locker::~Locker()
+{
+ // We don't need the CAS, but we do it out of an
+ // abundance of caution (and because it gives us a memory fence, which is
+ // never bad).
+ uintptr_t previous;
+ do {
+ previous = s_currentOrReserved;
+ } while (!WTF::weakCompareAndSwapUIntPtr(&s_currentOrReserved, previous, previous & ~1));
+}
+
+void SamplingRegion::sample()
+{
+ // Make sure we lock s_current.
+ Locker locker;
+
+ // Create a spectrum if we don't have one already.
+ if (!s_spectrum)
+ s_spectrum = new Spectrum<const char*>();
+
+ ASSERT(s_currentOrReserved & 1);
+
+ // Walk the region stack, and record each region we see.
+ SamplingRegion* region = bitwise_cast<SamplingRegion*>(s_currentOrReserved & ~1);
+ if (region) {
+ for (; region; region = region->m_previous)
+ s_spectrum->add(region->m_name);
+ } else
+ s_noneOfTheAbove++;
+
+ if (s_numberOfSamplesSinceDump++ == SamplingThread::s_hertz) {
+ s_numberOfSamplesSinceDump = 0;
+ dumpInternal();
+ }
+}
+
+void SamplingRegion::dump()
+{
+ Locker locker;
+
+ dumpInternal();
+}
+
+void SamplingRegion::dumpInternal()
+{
+ if (!s_spectrum) {
+ dataLogF("\nSamplingRegion: was never sampled.\n\n");
+ return;