diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-02-18 15:01:55 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-02-24 13:33:59 +0000 |
commit | c3737fb3824b8bc4e1dfd84573d413bce0a68bdd (patch) | |
tree | f8672e0aa2a4497bafb0fe7161e24144bec41101 | |
parent | caa20eed16deeb5ded3c74ba00653345a1ead782 (diff) | |
download | qtwebengine-chromium-c3737fb3824b8bc4e1dfd84573d413bce0a68bdd.tar.gz |
[Backport] metatrace: remove memset and trivial-ctor assumption
Turns out that on MSVC std::atomic<int> is not trivially constructible
(although I think is still a plain old int, it just fails the check).
Fall back on resetting each element individually.
Thankfully the compiler can see through and eventually figures out
it can do a memset: https://godbolt.org/z/wMre8O
Bug: chromium:1010616
Fixes: QTBUG-82272
Change-Id: I971ff888306d6bdbaf6e6b886f9ca506ddc1b30a
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r-- | chromium/third_party/perfetto/include/perfetto/ext/base/metatrace.h | 21 | ||||
-rw-r--r-- | chromium/third_party/perfetto/src/base/metatrace.cc | 8 |
2 files changed, 19 insertions, 10 deletions
diff --git a/chromium/third_party/perfetto/include/perfetto/ext/base/metatrace.h b/chromium/third_party/perfetto/include/perfetto/ext/base/metatrace.h index d560c3e5a24..9e9c95f6584 100644 --- a/chromium/third_party/perfetto/include/perfetto/ext/base/metatrace.h +++ b/chromium/third_party/perfetto/include/perfetto/ext/base/metatrace.h @@ -106,22 +106,33 @@ struct Record { timestamp_ns_high = static_cast<uint16_t>(diff >> 32); } + // We can't just memset() this class because on MSVC std::atomic<> is not + // trivially constructible anymore. Also std::atomic<> has a deleted copy + // constructor so we cant just do "*this = Record()" either. + // See http://bit.ly/339Jlzd . + void clear() { + this->~Record(); + new (this) Record(); + } + // This field holds the type (counter vs event) in the MSB and event ID (as // defined in metatrace_events.h) in the lowest 15 bits. It is also used also // as a linearization point: this is always written after all the other // fields with a release-store. This is so the reader can determine whether it // can safely process the other event fields after a load-acquire. - std::atomic<uint16_t> type_and_id; + std::atomic<uint16_t> type_and_id{}; // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp. // This gives us 78 hours from Enabled(). - uint16_t timestamp_ns_high; - uint32_t timestamp_ns_low; + uint16_t timestamp_ns_high = 0; + uint32_t timestamp_ns_low = 0; - uint32_t thread_id; + uint32_t thread_id = 0; union { - uint32_t duration_ns; // If type == event. + // Only one of the two elements can be zero initialized, clang complains + // about "initializing multiple members of union" otherwise. + uint32_t duration_ns = 0; // If type == event. int32_t counter_value; // If type == counter. }; }; diff --git a/chromium/third_party/perfetto/src/base/metatrace.cc b/chromium/third_party/perfetto/src/base/metatrace.cc index ca59b125c25..8c62c0017f1 100644 --- a/chromium/third_party/perfetto/src/base/metatrace.cc +++ b/chromium/third_party/perfetto/src/base/metatrace.cc @@ -84,11 +84,9 @@ void Disable() { // static void RingBuffer::Reset() { - static_assert(PERFETTO_IS_TRIVIALLY_CONSTRUCTIBLE(Record) && - std::is_trivially_destructible<Record>::value, - "Record must be trivial"); - memset(&records_[0], 0, sizeof(records_)); - memset(&bankruptcy_record_, 0, sizeof(bankruptcy_record_)); + bankruptcy_record_.clear(); + for (Record& record : records_) + record.clear(); wr_index_ = 0; rd_index_ = 0; has_overruns_ = false; |