diff --git a/tools/profiler/core/ProfileEntry.cpp b/tools/profiler/core/ProfileEntry.cpp index 346d0f2fb392..3c24c3ce1ac3 100644 --- a/tools/profiler/core/ProfileEntry.cpp +++ b/tools/profiler/core/ProfileEntry.cpp @@ -31,67 +31,50 @@ using mozilla::JSONWriter; ProfileEntry::ProfileEntry() : mTagData(nullptr) - , mTagName(0) + , mKind(Kind::INVALID) { } // aTagData must not need release (i.e. be a string from the text segment) -ProfileEntry::ProfileEntry(char aTagName, const char *aTagData) +ProfileEntry::ProfileEntry(Kind aKind, const char *aTagData) : mTagData(aTagData) - , mTagName(aTagName) + , mKind(aKind) { } -ProfileEntry::ProfileEntry(char aTagName, ProfilerMarker *aTagMarker) +ProfileEntry::ProfileEntry(Kind aKind, ProfilerMarker *aTagMarker) : mTagMarker(aTagMarker) - , mTagName(aTagName) + , mKind(aKind) { } -ProfileEntry::ProfileEntry(char aTagName, void *aTagPtr) +ProfileEntry::ProfileEntry(Kind aKind, void *aTagPtr) : mTagPtr(aTagPtr) - , mTagName(aTagName) + , mKind(aKind) { } -ProfileEntry::ProfileEntry(char aTagName, double aTagDouble) +ProfileEntry::ProfileEntry(Kind aKind, double aTagDouble) : mTagDouble(aTagDouble) - , mTagName(aTagName) + , mKind(aKind) { } -ProfileEntry::ProfileEntry(char aTagName, uintptr_t aTagOffset) +ProfileEntry::ProfileEntry(Kind aKind, uintptr_t aTagOffset) : mTagOffset(aTagOffset) - , mTagName(aTagName) + , mKind(aKind) { } -ProfileEntry::ProfileEntry(char aTagName, Address aTagAddress) +ProfileEntry::ProfileEntry(Kind aKind, Address aTagAddress) : mTagAddress(aTagAddress) - , mTagName(aTagName) + , mKind(aKind) { } -ProfileEntry::ProfileEntry(char aTagName, int aTagInt) +ProfileEntry::ProfileEntry(Kind aKind, int aTagInt) : mTagInt(aTagInt) - , mTagName(aTagName) + , mKind(aKind) { } -ProfileEntry::ProfileEntry(char aTagName, char aTagChar) +ProfileEntry::ProfileEntry(Kind aKind, char aTagChar) : mTagChar(aTagChar) - , mTagName(aTagName) + , mKind(aKind) { } -bool ProfileEntry::is_ent_hint(char hintChar) { - return mTagName == 'h' && mTagChar == hintChar; -} - -bool ProfileEntry::is_ent_hint() { - return mTagName == 'h'; -} - -bool ProfileEntry::is_ent(char tagChar) { - return mTagName == tagChar; -} - -void* ProfileEntry::get_tagPtr() { - // No consistency checking. Oh well. - return mTagPtr; -} - // END ProfileEntry //////////////////////////////////////////////////////////////////////// @@ -607,40 +590,40 @@ void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThre while (readPos != mWritePos) { ProfileEntry entry = mEntries[readPos]; - if (entry.mTagName == 'T') { + if (entry.isThreadId()) { currentThreadID = entry.mTagInt; currentTime.reset(); int readAheadPos = (readPos + 1) % mEntrySize; if (readAheadPos != mWritePos) { ProfileEntry readAheadEntry = mEntries[readAheadPos]; - if (readAheadEntry.mTagName == 't') { + if (readAheadEntry.isTime()) { currentTime = Some(readAheadEntry.mTagDouble); } } } if (currentThreadID == aThreadId && (currentTime.isNothing() || *currentTime >= aSinceTime)) { - switch (entry.mTagName) { - case 'r': + switch (entry.kind()) { + case ProfileEntry::Kind::Responsiveness: if (sample.isSome()) { sample->mResponsiveness = Some(entry.mTagDouble); } break; - case 'R': + case ProfileEntry::Kind::ResidentMemory: if (sample.isSome()) { sample->mRSS = Some(entry.mTagDouble); } break; - case 'U': + case ProfileEntry::Kind::UnsharedMemory: if (sample.isSome()) { sample->mUSS = Some(entry.mTagDouble); } break; - case 'f': + case ProfileEntry::Kind::FrameNumber: if (sample.isSome()) { sample->mFrameNumber = Some(entry.mTagInt); } break; - case 's': + case ProfileEntry::Kind::Sample: { // end the previous sample if there was one if (sample.isSome()) { @@ -660,49 +643,51 @@ void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThre int framePos = (readPos + 1) % mEntrySize; ProfileEntry frame = mEntries[framePos]; - while (framePos != mWritePos && frame.mTagName != 's' && frame.mTagName != 'T') { + while (framePos != mWritePos && !frame.isSample() && !frame.isThreadId()) { int incBy = 1; frame = mEntries[framePos]; - // Read ahead to the next tag, if it's a 'd' tag process it now + // Read ahead to the next tag, if it's an EmbeddedString + // tag process it now const char* tagStringData = frame.mTagData; int readAheadPos = (framePos + 1) % mEntrySize; // Make sure the string is always null terminated if it fills up // DYNAMIC_MAX_STRING-2 tagBuff[DYNAMIC_MAX_STRING-1] = '\0'; - if (readAheadPos != mWritePos && mEntries[readAheadPos].mTagName == 'd') { + if (readAheadPos != mWritePos && mEntries[readAheadPos].isEmbeddedString()) { tagStringData = processDynamicTag(framePos, &incBy, tagBuff.get()); } // Write one frame. It can have either - // 1. only location - 'l' containing a memory address - // 2. location and line number - 'c' followed by 'd's, - // an optional 'n' and an optional 'y' - // 3. a JIT return address - 'j' containing native code address - if (frame.mTagName == 'l') { + // 1. only location - a NativeLeafAddr containing a memory address + // 2. location and line number - a CodeLocation followed by + // EmbeddedStrings, an optional LineNumber and an + // optional Category + // 3. a JitReturnAddress containing a native code address + if (frame.isNativeLeafAddr()) { // Bug 753041 // We need a double cast here to tell GCC that we don't want to sign // extend 32-bit addresses starting with 0xFXXXXXX. unsigned long long pc = (unsigned long long)(uintptr_t)frame.mTagPtr; snprintf(tagBuff.get(), DYNAMIC_MAX_STRING, "%#llx", pc); stack.AppendFrame(UniqueStacks::OnStackFrameKey(tagBuff.get())); - } else if (frame.mTagName == 'c') { + } else if (frame.isCodeLocation()) { UniqueStacks::OnStackFrameKey frameKey(tagStringData); readAheadPos = (framePos + incBy) % mEntrySize; if (readAheadPos != mWritePos && - mEntries[readAheadPos].mTagName == 'n') { + mEntries[readAheadPos].isLineNumber()) { frameKey.mLine = Some((unsigned) mEntries[readAheadPos].mTagInt); incBy++; } readAheadPos = (framePos + incBy) % mEntrySize; if (readAheadPos != mWritePos && - mEntries[readAheadPos].mTagName == 'y') { + mEntries[readAheadPos].isCategory()) { frameKey.mCategory = Some((unsigned) mEntries[readAheadPos].mTagInt); incBy++; } stack.AppendFrame(frameKey); - } else if (frame.mTagName == 'J') { + } else if (frame.isJitReturnAddr()) { // A JIT frame may expand to multiple frames due to inlining. void* pc = frame.mTagPtr; unsigned depth = aUniqueStacks.LookupJITFrameDepth(pc); @@ -723,7 +708,9 @@ void ProfileBuffer::StreamSamplesToJSON(SpliceableJSONWriter& aWriter, int aThre sample->mStack = stack.GetOrAddIndex(); break; } - } + default: + break; + } /* switch (entry.kind()) */ } readPos = (readPos + 1) % mEntrySize; } @@ -739,9 +726,9 @@ void ProfileBuffer::StreamMarkersToJSON(SpliceableJSONWriter& aWriter, int aThre int currentThreadID = -1; while (readPos != mWritePos) { ProfileEntry entry = mEntries[readPos]; - if (entry.mTagName == 'T') { + if (entry.isThreadId()) { currentThreadID = entry.mTagInt; - } else if (currentThreadID == aThreadId && entry.mTagName == 'm') { + } else if (currentThreadID == aThreadId && entry.isMarker()) { const ProfilerMarker* marker = entry.getMarker(); if (marker->GetTime() >= aSinceTime) { entry.getMarker()->StreamJSON(aWriter, aUniqueStacks); @@ -759,7 +746,7 @@ int ProfileBuffer::FindLastSampleOfThread(int aThreadId) readPos != (mReadPos + mEntrySize - 1) % mEntrySize; readPos = (readPos + mEntrySize - 1) % mEntrySize) { ProfileEntry entry = mEntries[readPos]; - if (entry.mTagName == 'T' && entry.mTagInt == aThreadId) { + if (entry.isThreadId() && entry.mTagInt == aThreadId) { return readPos; } } @@ -774,7 +761,7 @@ void ProfileBuffer::DuplicateLastSample(int aThreadId) return; } - MOZ_ASSERT(mEntries[lastSampleStartPos].mTagName == 'T'); + MOZ_ASSERT(mEntries[lastSampleStartPos].isThreadId()); addTag(mEntries[lastSampleStartPos]); @@ -782,20 +769,19 @@ void ProfileBuffer::DuplicateLastSample(int aThreadId) for (int readPos = (lastSampleStartPos + 1) % mEntrySize; readPos != mWritePos; readPos = (readPos + 1) % mEntrySize) { - switch (mEntries[readPos].mTagName) { - case 'T': + switch (mEntries[readPos].kind()) { + case ProfileEntry::Kind::ThreadId: // We're done. return; - case 't': + case ProfileEntry::Kind::Time: // Copy with new time - addTag(ProfileEntry('t', (mozilla::TimeStamp::Now() - sStartTime).ToMilliseconds())); + addTag(ProfileEntry::Time((mozilla::TimeStamp::Now() - sStartTime).ToMilliseconds())); break; - case 'm': + case ProfileEntry::Kind::Marker: // Don't copy markers break; - // Copy anything else we don't know about - // L, B, S, c, s, d, l, f, h, r, t, p default: + // Copy anything else we don't know about addTag(mEntries[readPos]); break; } diff --git a/tools/profiler/core/ProfileEntry.h b/tools/profiler/core/ProfileEntry.h index 66a643373fc2..84364d35df6b 100644 --- a/tools/profiler/core/ProfileEntry.h +++ b/tools/profiler/core/ProfileEntry.h @@ -25,6 +25,22 @@ #include "mozilla/HashFunctions.h" #include "mozilla/UniquePtr.h" +#define PROFILE_ENTRY_KIND_LIST(_) \ + _(Category, int) \ + _(CodeLocation, const char *) \ + _(EmbeddedString, void *) \ + _(FrameNumber, int) \ + _(JitReturnAddr, void *) \ + _(LineNumber, int) \ + _(NativeLeafAddr, void *) \ + _(Marker, ProfilerMarker *) \ + _(ResidentMemory, double) \ + _(Responsiveness, double) \ + _(Sample, const char *) \ + _(ThreadId, int) \ + _(Time, double) \ + _(UnsharedMemory, double) + // NB: Packing this structure has been shown to cause SIGBUS issues on ARM. #ifndef __arm__ #pragma pack(push, 1) @@ -33,28 +49,46 @@ class ProfileEntry { public: + enum class Kind : uint8_t { + INVALID = 0, +# define DEF_ENUM_(k, t) k, + PROFILE_ENTRY_KIND_LIST(DEF_ENUM_) +# undef DEF_ENUM_ + LIMIT + }; + ProfileEntry(); +private: // aTagData must not need release (i.e. be a string from the text segment) - ProfileEntry(char aTagName, const char *aTagData); - ProfileEntry(char aTagName, void *aTagPtr); - ProfileEntry(char aTagName, ProfilerMarker *aTagMarker); - ProfileEntry(char aTagName, double aTagDouble); - ProfileEntry(char aTagName, uintptr_t aTagOffset); - ProfileEntry(char aTagName, Address aTagAddress); - ProfileEntry(char aTagName, int aTagLine); - ProfileEntry(char aTagName, char aTagChar); - bool is_ent_hint(char hintChar); - bool is_ent_hint(); - bool is_ent(char tagName); - void* get_tagPtr(); + ProfileEntry(Kind aKind, const char *aTagData); + ProfileEntry(Kind aKind, void *aTagPtr); + ProfileEntry(Kind aKind, ProfilerMarker *aTagMarker); + ProfileEntry(Kind aKind, double aTagDouble); + ProfileEntry(Kind aKind, uintptr_t aTagOffset); + ProfileEntry(Kind aKind, Address aTagAddress); + ProfileEntry(Kind aKind, int aTagLine); + ProfileEntry(Kind aKind, char aTagChar); + +public: +# define DEF_MAKE_(k, t) \ + static ProfileEntry k(t val) { return ProfileEntry(Kind::k, val); } + PROFILE_ENTRY_KIND_LIST(DEF_MAKE_) +# undef DEF_MAKE_ + + Kind kind() const { return mKind; } + bool hasKind(Kind k) const { return kind() == k; } + +# define DEF_METHODS_(k, t) \ + bool is##k() const { return hasKind(Kind::k); } + PROFILE_ENTRY_KIND_LIST(DEF_METHODS_) +# undef DEF_METHODS_ + const ProfilerMarker* getMarker() { - MOZ_ASSERT(mTagName == 'm'); + MOZ_ASSERT(isMarker()); return mTagMarker; } - char getTagName() const { return mTagName; } - private: FRIEND_TEST(ThreadProfile, InsertOneTag); FRIEND_TEST(ThreadProfile, InsertOneTagWithTinyBuffer); @@ -73,7 +107,7 @@ private: int mTagInt; char mTagChar; }; - char mTagName; + Kind mKind; }; #ifndef __arm__ diff --git a/tools/profiler/core/Sampler.cpp b/tools/profiler/core/Sampler.cpp index 12ec6de50879..8b48287d9111 100644 --- a/tools/profiler/core/Sampler.cpp +++ b/tools/profiler/core/Sampler.cpp @@ -767,9 +767,9 @@ void PseudoStack::flushSamplerOnJSShutdown() //////////////////////////////////////////////////////////////////////// static -void addDynamicTag(ThreadInfo& aInfo, char aTagName, const char* aStr) +void addDynamicCodeLocationTag(ThreadInfo& aInfo, const char* aStr) { - aInfo.addTag(ProfileEntry(aTagName, "")); + aInfo.addTag(ProfileEntry::CodeLocation("")); // Add one to store the null termination size_t strLen = strlen(aStr) + 1; for (size_t j = 0; j < strLen;) { @@ -782,7 +782,7 @@ void addDynamicTag(ThreadInfo& aInfo, char aTagName, const char* aStr) memcpy(text, &aStr[j], len); j += sizeof(void*)/sizeof(char); // Cast to *((void**) to pass the text data to a void* - aInfo.addTag(ProfileEntry('d', *((void**)(&text[0])))); + aInfo.addTag(ProfileEntry::EmbeddedString(*((void**)(&text[0])))); } } @@ -797,14 +797,14 @@ void addPseudoEntry(volatile StackEntry& entry, ThreadInfo& aInfo, int lineno = -1; - // First entry has tagName 's' (start) + // First entry has kind CodeLocation // Check for magic pointer bit 1 to indicate copy const char* sampleLabel = entry.label(); if (entry.isCopyLabel()) { - // Store the string using 1 or more 'd' (dynamic) tags + // Store the string using 1 or more EmbeddedString tags // that will happen to the preceding tag - addDynamicTag(aInfo, 'c', sampleLabel); + addDynamicCodeLocationTag(aInfo, sampleLabel); if (entry.isJs()) { JSScript* script = entry.script(); if (script) { @@ -827,7 +827,7 @@ void addPseudoEntry(volatile StackEntry& entry, ThreadInfo& aInfo, lineno = entry.line(); } } else { - aInfo.addTag(ProfileEntry('c', sampleLabel)); + aInfo.addTag(ProfileEntry::CodeLocation(sampleLabel)); // XXX: Bug 1010578. Don't assume a CPP entry and try to get the // line for js entries as well. @@ -837,7 +837,7 @@ void addPseudoEntry(volatile StackEntry& entry, ThreadInfo& aInfo, } if (lineno != -1) { - aInfo.addTag(ProfileEntry('n', lineno)); + aInfo.addTag(ProfileEntry::LineNumber(lineno)); } uint32_t category = entry.category(); @@ -845,7 +845,7 @@ void addPseudoEntry(volatile StackEntry& entry, ThreadInfo& aInfo, MOZ_ASSERT(!(category & StackEntry::FRAME_LABEL_COPY)); if (category) { - aInfo.addTag(ProfileEntry('y', (int)category)); + aInfo.addTag(ProfileEntry::Category((int)category)); } } @@ -928,7 +928,7 @@ mergeStacksIntoProfile(ThreadInfo& aInfo, TickSample* aSample, } // Start the sample with a root entry. - aInfo.addTag(ProfileEntry('s', "(root)")); + aInfo.addTag(ProfileEntry::Sample("(root)")); // While the pseudo-stack array is ordered oldest-to-youngest, the JS and // native arrays are ordered youngest-to-oldest. We must add frames to @@ -1012,7 +1012,7 @@ mergeStacksIntoProfile(ThreadInfo& aInfo, TickSample* aSample, // Stringifying non-wasm JIT frames is delayed until streaming // time. To re-lookup the entry in the JitcodeGlobalTable, we need to - // store the JIT code address ('J') in the circular buffer. + // store the JIT code address (OptInfoAddr) in the circular buffer. // // Note that we cannot do this when we are sychronously sampling the // current thread; that is, when called from profiler_get_backtrace. The @@ -1020,16 +1020,16 @@ mergeStacksIntoProfile(ThreadInfo& aInfo, TickSample* aSample, // amount of time, such as in nsRefreshDriver. Problematically, the // stored backtrace may be alive across a GC during which the profiler // itself is disabled. In that case, the JS engine is free to discard - // its JIT code. This means that if we inserted such 'J' entries into - // the buffer, nsRefreshDriver would now be holding on to a backtrace - // with stale JIT code return addresses. + // its JIT code. This means that if we inserted such OptInfoAddr entries + // into the buffer, nsRefreshDriver would now be holding on to a + // backtrace with stale JIT code return addresses. if (aSample->isSamplingCurrentThread || jsFrame.kind == JS::ProfilingFrameIterator::Frame_Wasm) { - addDynamicTag(aInfo, 'c', jsFrame.label); + addDynamicCodeLocationTag(aInfo, jsFrame.label); } else { MOZ_ASSERT(jsFrame.kind == JS::ProfilingFrameIterator::Frame_Ion || jsFrame.kind == JS::ProfilingFrameIterator::Frame_Baseline); - aInfo.addTag(ProfileEntry('J', jsFrames[jsIndex].returnAddress)); + aInfo.addTag(ProfileEntry::JitReturnAddr(jsFrames[jsIndex].returnAddress)); } jsIndex--; @@ -1041,7 +1041,7 @@ mergeStacksIntoProfile(ThreadInfo& aInfo, TickSample* aSample, if (nativeStackAddr) { MOZ_ASSERT(nativeIndex >= 0); aInfo - .addTag(ProfileEntry('l', (void*)aNativeStack.pc_array[nativeIndex])); + .addTag(ProfileEntry::NativeLeafAddr((void*)aNativeStack.pc_array[nativeIndex])); } if (nativeIndex >= 0) { nativeIndex--; @@ -1299,7 +1299,7 @@ doSampleStackTrace(ThreadInfo& aInfo, TickSample* aSample, #ifdef ENABLE_LEAF_DATA if (aSample && aAddLeafAddresses) { - aInfo.addTag(ProfileEntry('l', (void*)aSample->pc)); + aInfo.addTag(ProfileEntry::NativeLeafAddr((void*)aSample->pc)); } #endif } @@ -1316,10 +1316,10 @@ Sampler::InplaceTick(TickSample* sample) { ThreadInfo& currThreadInfo = *sample->threadInfo; - currThreadInfo.addTag(ProfileEntry('T', currThreadInfo.ThreadId())); + currThreadInfo.addTag(ProfileEntry::ThreadId(currThreadInfo.ThreadId())); mozilla::TimeDuration delta = sample->timestamp - sStartTime; - currThreadInfo.addTag(ProfileEntry('t', delta.ToMilliseconds())); + currThreadInfo.addTag(ProfileEntry::Time(delta.ToMilliseconds())); PseudoStack* stack = currThreadInfo.Stack(); @@ -1341,27 +1341,27 @@ Sampler::InplaceTick(TickSample* sample) while (pendingMarkersList && pendingMarkersList->peek()) { ProfilerMarker* marker = pendingMarkersList->popHead(); currThreadInfo.addStoredMarker(marker); - currThreadInfo.addTag(ProfileEntry('m', marker)); + currThreadInfo.addTag(ProfileEntry::Marker(marker)); } } if (currThreadInfo.GetThreadResponsiveness()->HasData()) { mozilla::TimeDuration delta = currThreadInfo.GetThreadResponsiveness()->GetUnresponsiveDuration(sample->timestamp); - currThreadInfo.addTag(ProfileEntry('r', delta.ToMilliseconds())); + currThreadInfo.addTag(ProfileEntry::Responsiveness(delta.ToMilliseconds())); } // rssMemory is equal to 0 when we are not recording. if (sample->rssMemory != 0) { - currThreadInfo.addTag(ProfileEntry('R', static_cast(sample->rssMemory))); + currThreadInfo.addTag(ProfileEntry::ResidentMemory(static_cast(sample->rssMemory))); } // ussMemory is equal to 0 when we are not recording. if (sample->ussMemory != 0) { - currThreadInfo.addTag(ProfileEntry('U', static_cast(sample->ussMemory))); + currThreadInfo.addTag(ProfileEntry::UnsharedMemory(static_cast(sample->ussMemory))); } if (sLastFrameNumber != sFrameNumber) { - currThreadInfo.addTag(ProfileEntry('f', sFrameNumber)); + currThreadInfo.addTag(ProfileEntry::FrameNumber(sFrameNumber)); sLastFrameNumber = sFrameNumber; } } diff --git a/tools/profiler/tests/gtest/ThreadProfileTest.cpp b/tools/profiler/tests/gtest/ThreadProfileTest.cpp index 4e306283f668..e9e27eaf0bb6 100644 --- a/tools/profiler/tests/gtest/ThreadProfileTest.cpp +++ b/tools/profiler/tests/gtest/ThreadProfileTest.cpp @@ -23,9 +23,9 @@ TEST(ThreadProfile, InsertOneTag) { Thread::tid_t tid = 1000; ThreadInfo info("testThread", tid, true, stack, nullptr); RefPtr pb = new ProfileBuffer(10); - pb->addTag(ProfileEntry('t', 123.1)); + pb->addTag(ProfileEntry::Time(123.1)); ASSERT_TRUE(pb->mEntries != nullptr); - ASSERT_TRUE(pb->mEntries[pb->mReadPos].mTagName == 't'); + ASSERT_TRUE(pb->mEntries[pb->mReadPos].kind() == ProfileEntry::Kind::Time); ASSERT_TRUE(pb->mEntries[pb->mReadPos].mTagDouble == 123.1); } @@ -37,13 +37,13 @@ TEST(ThreadProfile, InsertTagsNoWrap) { RefPtr pb = new ProfileBuffer(100); int test_size = 50; for (int i = 0; i < test_size; i++) { - pb->addTag(ProfileEntry('t', i)); + pb->addTag(ProfileEntry::Time(i)); } ASSERT_TRUE(pb->mEntries != nullptr); int readPos = pb->mReadPos; while (readPos != pb->mWritePos) { - ASSERT_TRUE(pb->mEntries[readPos].mTagName == 't'); - ASSERT_TRUE(pb->mEntries[readPos].mTagInt == readPos); + ASSERT_TRUE(pb->mEntries[readPos].kind() == ProfileEntry::Kind::Time); + ASSERT_TRUE(pb->mEntries[readPos].mTagDouble == readPos); readPos = (readPos + 1) % pb->mEntrySize; } } @@ -59,15 +59,15 @@ TEST(ThreadProfile, InsertTagsWrap) { RefPtr pb = new ProfileBuffer(buffer_size); int test_size = 43; for (int i = 0; i < test_size; i++) { - pb->addTag(ProfileEntry('t', i)); + pb->addTag(ProfileEntry::Time(i)); } ASSERT_TRUE(pb->mEntries != nullptr); int readPos = pb->mReadPos; int ctr = 0; while (readPos != pb->mWritePos) { - ASSERT_TRUE(pb->mEntries[readPos].mTagName == 't'); + ASSERT_TRUE(pb->mEntries[readPos].kind() == ProfileEntry::Kind::Time); // the first few tags were discarded when we wrapped - ASSERT_TRUE(pb->mEntries[readPos].mTagInt == ctr + (test_size - tags)); + ASSERT_TRUE(pb->mEntries[readPos].mTagDouble == ctr + (test_size - tags)); ctr++; readPos = (readPos + 1) % pb->mEntrySize; }