[llvm] r341029 - [XRay] FDRTraceWriter and FDR Trace Loading
Dean Michael Berris via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 31 09:19:14 PDT 2018
Yeah, I think there’s still the difference in packing/layout for some fields in a struct that I’m running into.
I’ve just pushed another change which changes the way we’re serialising the data to not rely on structs being packed a specific way. That’s r341223, which is waiting for a run on the bots.
Fingers crossed that change does it!
Cheers
> On 1 Sep 2018, at 02:02, <douglas.yung at sony.com> <douglas.yung at sony.com> wrote:
>
> Hi Dean,
>
> Unfortunately it looks like the tests are still failing after your change. Can you take a look?
>
> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/19534/steps/test/logs/stdio
>
> FAIL: LLVM-Unit :: XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion1 (3122 of 43583)
> ******************** TEST 'LLVM-Unit :: XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion1' FAILED ********************
> Note: Google Test filter = FDRTraceWriterTest.WriteToStringBufferVersion1
>
> [==========] Running 1 test from 1 test case.
>
> [----------] Global test environment set-up.
>
> [----------] 1 test from FDRTraceWriterTest
>
> [ RUN ] FDRTraceWriterTest.WriteToStringBufferVersion1
>
> C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.src\unittests\XRay\FDRTraceWriterTest.cpp(160): error: Value of: Data.size()
>
> Expected: is equal to 4128
>
> Actual: 4136
>
> [ FAILED ] FDRTraceWriterTest.WriteToStringBufferVersion1 (0 ms)
>
> [----------] 1 test from FDRTraceWriterTest (0 ms total)
>
>
>
> [----------] Global test environment tear-down
>
> [==========] 1 test from 1 test case ran. (0 ms total)
>
> [ PASSED ] 0 tests.
>
> [ FAILED ] 1 test, listed below:
>
> [ FAILED ] FDRTraceWriterTest.WriteToStringBufferVersion1
>
>
>
> 1 FAILED TEST
>
>
> ********************
>
> FAIL: LLVM-Unit :: XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion2 (3246 of 43583)
> ******************** TEST 'LLVM-Unit :: XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion2' FAILED ********************
> Note: Google Test filter = FDRTraceWriterTest.WriteToStringBufferVersion2
>
> [==========] Running 1 test from 1 test case.
>
> [----------] Global test environment set-up.
>
> [----------] 1 test from FDRTraceWriterTest
>
> [ RUN ] FDRTraceWriterTest.WriteToStringBufferVersion2
>
> C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.src\unittests\XRay\FDRTraceWriterTest.cpp(106): error: Failed
>
> Malformed log: Read New Buffer record kind out of sequence; expected: FUNCTION_SEQUENCE at offset 105.
>
> Program aborted due to an unhandled Error:
>
> Malformed log: Read New Buffer record kind out of sequence; expected: FUNCTION_SEQUENCE at offset 105.LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB. Make sure the file exists and is readable. Calling loadDataForExe
>
>
>
> LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB. Make sure the file exists and is readable. Calling loadDataForExe
>
>
>
> #0 0x0115f237 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x3f237)
>
> #1 0x759e2722 (C:\WINDOWS\System32\ucrtbase.dll+0xa2722)
>
> #2 0x0114ff98 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x2ff98)
>
> #3 0x0117dee0 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x5dee0)
>
> #4 0x01190a94 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x70a94)
>
> #5 0x00dc48d0
>
> #6 0x65636172
>
> #7 0x74697257 (C:\WINDOWS\System32\msvcp_win.dll+0x37257)
>
> #8 0x65547265
>
>
> ********************
> FAIL: LLVM-Unit :: XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion3 (3247 of 43583)
> ******************** TEST 'LLVM-Unit :: XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion3' FAILED ********************
> Note: Google Test filter = FDRTraceWriterTest.WriteToStringBufferVersion3
>
> [==========] Running 1 test from 1 test case.
>
> [----------] Global test environment set-up.
>
> [----------] 1 test from FDRTraceWriterTest
>
> [ RUN ] FDRTraceWriterTest.WriteToStringBufferVersion3
>
> C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.src\unittests\XRay\FDRTraceWriterTest.cpp(62): error: Failed
>
> Malformed log: Read New Buffer record kind out of sequence; expected: FUNCTION_SEQUENCE at offset 121.
>
> Program aborted due to an unhandled Error:
>
> Malformed log: Read New Buffer record kind out of sequence; expected: FUNCTION_SEQUENCE at offset 121.LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB. Make sure the file exists and is readable. Calling loadDataForExe
>
>
>
> LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB. Make sure the file exists and is readable. Calling loadDataForExe
>
>
>
> #0 0x0115f237 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x3f237)
>
> #1 0x759e2722 (C:\WINDOWS\System32\ucrtbase.dll+0xa2722)
>
> #2 0x0114ff98 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x2ff98)
>
> #3 0x0117dee0 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x5dee0)
>
> #4 0x01190a94 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x70a94)
>
> #5 0x0127c970
>
> #6 0x65636172
>
> #7 0x74697257 (C:\WINDOWS\System32\msvcp_win.dll+0x37257)
>
> #8 0x65547265
>
> #9 0x73007473
>
> #10 0x00392f74
>
>
> ********************
>
> Douglas Yung
>
>> -----Original Message-----
>> From: Dean Michael Berris [mailto:dean.berris at gmail.com]
>> Sent: Friday, August 31, 2018 3:42
>> To: Yung, Douglas
>> Cc: Dean Michael Berris; Vedant Kumar via llvm-commits
>> Subject: Re: [llvm] r341029 - [XRay] FDRTraceWriter and FDR Trace
>> Loading
>>
>> This should now be fixed in r341194.
>>
>> Thanks Doug!
>>
>>> On 31 Aug 2018, at 20:01, Dean Michael Berris <dean.berris at gmail.com>
>> wrote:
>>>
>>> Actually, I think I found it — it seems that I’m relying on bitfield
>> order being portable, but it isn’t. I’m working on a fix now.
>>>
>>>> On 31 Aug 2018, at 19:37, Dean Michael Berris
>> <dean.berris at gmail.com> wrote:
>>>>
>>>> Oops, thanks for pointing it out.
>>>>
>>>> Is there a way to make this XFAIL on Windows?
>>>>
>>>> This is really bizarre, since I don’t have a way of reproducing
>> this.
>>>>
>>>>> On 31 Aug 2018, at 18:37, via llvm-commits <llvm-
>> commits at lists.llvm.org> wrote:
>>>>>
>>>>> Hi Dean,
>>>>>
>>>>> The unit test you added in this commit, FDRTraceWriterTest is
>> causing 3 failures on the PS4 Windows bot, can you take a look?
>>>>>
>>>>> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-
>> windows10pro-fast/builds/19491/steps/test/logs/stdio
>>>>>
>>>>> Failing Tests (3):
>>>>> LLVM-Unit ::
>> XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion1
>>>>> LLVM-Unit ::
>> XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion2
>>>>> LLVM-Unit ::
>> XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion3
>>>>>
>>>>> Sample failure output:
>>>>>
>>>>> FAIL: LLVM-Unit ::
>> XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion1
>> (3227 of 43541)
>>>>> ******************** TEST 'LLVM-Unit ::
>> XRay/./XRayTests.exe/FDRTraceWriterTest.WriteToStringBufferVersion1'
>> FAILED ********************
>>>>> Note: Google Test filter =
>> FDRTraceWriterTest.WriteToStringBufferVersion1
>>>>>
>>>>> [==========] Running 1 test from 1 test case.
>>>>>
>>>>> [----------] Global test environment set-up.
>>>>>
>>>>> [----------] 1 test from FDRTraceWriterTest
>>>>>
>>>>> [ RUN ] FDRTraceWriterTest.WriteToStringBufferVersion1
>>>>>
>>>>> C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-windows10pro-
>> fast\llvm.src\unittests\XRay\FDRTraceWriterTest.cpp(157): error: Failed
>>>>>
>>>>> Malformed log: Read New Buffer record kind out of sequence;
>> expected: FUNCTION_SEQUENCE at offset 89.
>>>>>
>>>>> Program aborted due to an unhandled Error:
>>>>>
>>>>> Malformed log: Read New Buffer record kind out of sequence;
>> expected: FUNCTION_SEQUENCE at offset 89.LLVMSymbolizer: error reading
>> file: PDB Error: Unable to load PDB. Make sure the file exists and is
>> readable. Calling loadDataForExe
>>>>>
>>>>>
>>>>>
>>>>> LLVMSymbolizer: error reading file: PDB Error: Unable to load PDB.
>> Make sure the file exists and is readable. Calling loadDataForExe
>>>>>
>>>>>
>>>>>
>>>>> #0 0x0003e887 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-
>> windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x2e887)
>>>>>
>>>>> #1 0x759e2722 (C:\WINDOWS\System32\ucrtbase.dll+0xa2722)
>>>>>
>>>>> #2 0x0003b918 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-
>> windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x2b918)
>>>>>
>>>>> #3 0x00064880 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-
>> windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x54880)
>>>>>
>>>>> #4 0x00076b54 (C:\ps4-buildslave2\llvm-clang-lld-x86_64-scei-ps4-
>> windows10pro-fast\llvm.obj\unittests\XRay\XRayTests.exe+0x66b54)
>>>>>
>>>>> #5 0x01b10518
>>>>>
>>>>> #6 0x65636172
>>>>>
>>>>> #7 0x74697257 (C:\WINDOWS\System32\msvcp_win.dll+0x37257)
>>>>>
>>>>> #8 0x65547265
>>>>>
>>>>>
>>>>> ********************
>>>>>
>>>>> Douglas Yung
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: llvm-commits [mailto:llvm-commits-bounces at lists.llvm.org] On
>>>>>> Behalf Of Dean Michael Berris via llvm-commits
>>>>>> Sent: Thursday, August 30, 2018 0:22
>>>>>> To: llvm-commits at lists.llvm.org
>>>>>> Subject: [llvm] r341029 - [XRay] FDRTraceWriter and FDR Trace
>> Loading
>>>>>>
>>>>>> Author: dberris
>>>>>> Date: Thu Aug 30 00:22:21 2018
>>>>>> New Revision: 341029
>>>>>>
>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=341029&view=rev
>>>>>> Log:
>>>>>> [XRay] FDRTraceWriter and FDR Trace Loading
>>>>>>
>>>>>> Summary:
>>>>>> This is the first step in the larger refactoring and reduction of
>>>>>> D50441.
>>>>>>
>>>>>> This step in the process does the following:
>>>>>>
>>>>>> - Introduces more granular types of `Record`s representing the
>> many
>>>>>> kinds of records written/read by the Flight Data Recorder (FDR)
>> mode
>>>>>> `Trace` loading function(s).
>>>>>>
>>>>>> - Introduces an abstract `RecordVisitor` type meant to handle the
>>>>>> processing of the various `Record` derived types. This
>>>>>> `RecordVisitor`
>>>>>> has two implementations in this patch: `RecordInitializer` and
>>>>>> `FDRTraceWriter`.
>>>>>>
>>>>>> - We also introduce a convenience interface for building a
>> collection
>>>>>> of
>>>>>> `Record` instances called a `LogBuilder`. This allows us to
>> generate
>>>>>> sequences of `Record` instances manually (used in unit tests but
>>>>>> useful otherwise).
>>>>>>
>>>>>> - The`FDRTraceWriter` class implements the `RecordVisitor`
>> interface
>>>>>> and
>>>>>> handles the writing of metadata records to a `raw_ostream`. We
>>>>>> demonstrate that in the unit test, we can generate in-memory FDR
>> mode
>>>>>> traces using the specific `Record` derived types, which we load
>>>>>> through the `loadTrace(...)` function yielding valid `Trace`
>> objects.
>>>>>>
>>>>>> This patch introduces the required types and concepts for us to
>> start
>>>>>> replacing the logic implemented in the `loadFDRLog` function to
>> use the
>>>>>> more granular types. In subsequent patches, we will introduce more
>>>>>> visitor implementations which isolate the verification, printing,
>>>>>> indexing, production/consumption, and finally the conversion of
>> the FDR
>>>>>> mode logs.
>>>>>>
>>>>>> The overarching goal of these changes is to make handling FDR mode
>> logs
>>>>>> better tested, more understandable, more extensible, and more
>>>>>> systematic. This will also allow us to better represent the
>> execution
>>>>>> trace, as we improve the fidelity of the events we represent in an
>> XRay
>>>>>> `Trace` object, which we intend to do after FDR mode log
>> processing is
>>>>>> in better shape.
>>>>>>
>>>>>> Reviewers: eizan
>>>>>>
>>>>>> Reviewed By: eizan
>>>>>>
>>>>>> Subscribers: mgorny, hiraditya, llvm-commits
>>>>>>
>>>>>> Differential Revision: https://reviews.llvm.org/D51210
>>>>>>
>>>>>> Added:
>>>>>> llvm/trunk/include/llvm/XRay/FDRLogBuilder.h
>>>>>> llvm/trunk/include/llvm/XRay/FDRRecords.h
>>>>>> llvm/trunk/include/llvm/XRay/FDRTraceWriter.h
>>>>>> llvm/trunk/lib/XRay/FDRRecords.cpp
>>>>>> llvm/trunk/lib/XRay/FDRTraceWriter.cpp
>>>>>> llvm/trunk/lib/XRay/RecordInitializer.cpp
>>>>>> llvm/trunk/unittests/XRay/FDRTraceWriterTest.cpp
>>>>>> Modified:
>>>>>> llvm/trunk/lib/XRay/CMakeLists.txt
>>>>>> llvm/trunk/unittests/XRay/CMakeLists.txt
>>>>>>
>>>>>> Added: llvm/trunk/include/llvm/XRay/FDRLogBuilder.h
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/include/llvm/XRay/FDRLogBuilder.h?rev=341029&view=au
>>>>>> to
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/include/llvm/XRay/FDRLogBuilder.h (added)
>>>>>> +++ llvm/trunk/include/llvm/XRay/FDRLogBuilder.h Thu Aug 30
>> 00:22:21
>>>>>> 2018
>>>>>> @@ -0,0 +1,41 @@
>>>>>> +//===- FDRLogBuilder.h - XRay FDR Log Building Utility ----------
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// The LLVM Compiler Infrastructure
>>>>>> +//
>>>>>> +// This file is distributed under the University of Illinois Open
>>>>>> Source
>>>>>> +// License. See LICENSE.TXT for details.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
>>>>>> +#define LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
>>>>>> +
>>>>>> +#include "llvm/XRay/FDRRecords.h"
>>>>>> +
>>>>>> +namespace llvm {
>>>>>> +namespace xray {
>>>>>> +
>>>>>> +/// The LogBuilder class allows for creating ad-hoc collections
>> of
>>>>>> records
>>>>>> +/// through the `add<...>(...)` function. An example use of this
>> API
>>>>>> is in
>>>>>> +/// crafting arbitrary sequences of records:
>>>>>> +///
>>>>>> +/// auto Records = LogBuilder()
>>>>>> +/// .add<BufferExtents>(256)
>>>>>> +/// .add<NewBufferRecord>(1)
>>>>>> +/// .consume();
>>>>>> +///
>>>>>> +class LogBuilder {
>>>>>> + std::vector<std::unique_ptr<Record>> Records;
>>>>>> +
>>>>>> +public:
>>>>>> + template <class R, class... T> LogBuilder &add(T &&... A) {
>>>>>> + Records.emplace_back(new R(std::forward<T>(A)...));
>>>>>> + return *this;
>>>>>> + }
>>>>>> +
>>>>>> + std::vector<std::unique_ptr<Record>> consume() { return
>>>>>> std::move(Records); }
>>>>>> +};
>>>>>> +
>>>>>> +} // namespace xray
>>>>>> +} // namespace llvm
>>>>>> +
>>>>>> +#endif // LLVM_INCLUDE_LLVM_XRAY_FDRLOGBUILDER_H_
>>>>>>
>>>>>> Added: llvm/trunk/include/llvm/XRay/FDRRecords.h
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/include/llvm/XRay/FDRRecords.h?rev=341029&view=auto
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/include/llvm/XRay/FDRRecords.h (added)
>>>>>> +++ llvm/trunk/include/llvm/XRay/FDRRecords.h Thu Aug 30 00:22:21
>> 2018
>>>>>> @@ -0,0 +1,292 @@
>>>>>> +//===- FDRRecords.h - XRay Flight Data Recorder Mode Records ----
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// The LLVM Compiler Infrastructure
>>>>>> +//
>>>>>> +// This file is distributed under the University of Illinois Open
>>>>>> Source
>>>>>> +// License. See LICENSE.TXT for details.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// Define types and operations on these types that represent the
>>>>>> different kinds
>>>>>> +// of records we encounter in XRay flight data recorder mode
>> traces.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +#ifndef LLVM_LIB_XRAY_FDRRECORDS_H_
>>>>>> +#define LLVM_LIB_XRAY_FDRRECORDS_H_
>>>>>> +
>>>>>> +#include "llvm/Support/DataExtractor.h"
>>>>>> +#include "llvm/Support/Error.h"
>>>>>> +#include "llvm/XRay/XRayRecord.h"
>>>>>> +#include <cstdint>
>>>>>> +
>>>>>> +namespace llvm {
>>>>>> +namespace xray {
>>>>>> +
>>>>>> +class RecordVisitor;
>>>>>> +class RecordInitializer;
>>>>>> +
>>>>>> +class Record {
>>>>>> +protected:
>>>>>> + enum class Type {
>>>>>> + Unknown,
>>>>>> + Function,
>>>>>> + Metadata,
>>>>>> + };
>>>>>> +
>>>>>> +public:
>>>>>> + Record(const Record &) = delete;
>>>>>> + Record(Record &&) = delete;
>>>>>> + Record &operator=(const Record &) = delete;
>>>>>> + Record &operator=(Record &&) = delete;
>>>>>> + Record() = default;
>>>>>> +
>>>>>> + virtual Type type() const = 0;
>>>>>> +
>>>>>> + // Each Record should be able to apply an abstract visitor, and
>>>>>> choose the
>>>>>> + // appropriate function in the visitor to invoke, given its own
>>>>>> type.
>>>>>> + virtual Error apply(RecordVisitor &V) = 0;
>>>>>> +
>>>>>> + virtual ~Record() = default;
>>>>>> +};
>>>>>> +
>>>>>> +class MetadataRecord : public Record {
>>>>>> +protected:
>>>>>> + static constexpr int kMetadataBodySize = 15;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + enum class MetadataType : unsigned {
>>>>>> + Unknown,
>>>>>> + BufferExtents,
>>>>>> + WallClockTime,
>>>>>> + NewCPUId,
>>>>>> + TSCWrap,
>>>>>> + CustomEvent,
>>>>>> + CallArg,
>>>>>> + PIDEntry,
>>>>>> + NewBuffer,
>>>>>> + EndOfBuffer,
>>>>>> + };
>>>>>> +
>>>>>> + Type type() const override { return Type::Metadata; }
>>>>>> +
>>>>>> + // All metadata records must know to provide the type of their
>> open
>>>>>> + // metadata record.
>>>>>> + virtual MetadataType metadataType() const = 0;
>>>>>> +
>>>>>> + virtual ~MetadataRecord() = default;
>>>>>> +};
>>>>>> +
>>>>>> +// What follows are specific Metadata record types which
>> encapsulate
>>>>>> the
>>>>>> +// information associated with specific metadata record types in
>> an
>>>>>> FDR mode
>>>>>> +// log.
>>>>>> +class BufferExtents : public MetadataRecord {
>>>>>> + uint64_t Size = 0;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + BufferExtents() = default;
>>>>>> + explicit BufferExtents(uint64_t S) : MetadataRecord(), Size(S)
>> {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override {
>>>>>> + return MetadataType::BufferExtents;
>>>>>> + }
>>>>>> +
>>>>>> + uint64_t size() const { return Size; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class WallclockRecord : public MetadataRecord {
>>>>>> + uint64_t Seconds = 0;
>>>>>> + uint32_t Nanos = 0;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + WallclockRecord() = default;
>>>>>> + explicit WallclockRecord(uint64_t S, uint32_t N)
>>>>>> + : MetadataRecord(), Seconds(S), Nanos(N) {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override {
>>>>>> + return MetadataType::WallClockTime;
>>>>>> + }
>>>>>> +
>>>>>> + uint64_t seconds() const { return Seconds; }
>>>>>> + uint32_t nanos() const { return Nanos; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class NewCPUIDRecord : public MetadataRecord {
>>>>>> + uint16_t CPUId = 0;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + NewCPUIDRecord() = default;
>>>>>> + explicit NewCPUIDRecord(uint16_t C) : MetadataRecord(),
>> CPUId(C) {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override { return
>>>>>> MetadataType::NewCPUId; }
>>>>>> +
>>>>>> + uint16_t cpuid() const { return CPUId; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class TSCWrapRecord : public MetadataRecord {
>>>>>> + uint64_t BaseTSC = 0;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + TSCWrapRecord() = default;
>>>>>> + explicit TSCWrapRecord(uint64_t B) : MetadataRecord(),
>> BaseTSC(B) {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override { return
>>>>>> MetadataType::TSCWrap; }
>>>>>> +
>>>>>> + uint64_t tsc() const { return BaseTSC; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class CustomEventRecord : public MetadataRecord {
>>>>>> + int32_t Size = 0;
>>>>>> + uint64_t TSC = 0;
>>>>>> + std::string Data{};
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + CustomEventRecord() = default;
>>>>>> + explicit CustomEventRecord(uint64_t S, uint64_t T, std::string
>> D)
>>>>>> + : MetadataRecord(), Size(S), TSC(T), Data(std::move(D)) {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override {
>>>>>> + return MetadataType::CustomEvent;
>>>>>> + }
>>>>>> +
>>>>>> + int32_t size() const { return Size; }
>>>>>> + uint64_t tsc() const { return TSC; }
>>>>>> + StringRef data() const { return Data; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class CallArgRecord : public MetadataRecord {
>>>>>> + uint64_t Arg;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + CallArgRecord() = default;
>>>>>> + explicit CallArgRecord(uint64_t A) : MetadataRecord(), Arg(A)
>> {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override { return
>>>>>> MetadataType::CallArg; }
>>>>>> +
>>>>>> + uint64_t arg() const { return Arg; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class PIDRecord : public MetadataRecord {
>>>>>> + uint64_t PID = 0;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + PIDRecord() = default;
>>>>>> + explicit PIDRecord(uint64_t P) : MetadataRecord(), PID(P) {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override { return
>>>>>> MetadataType::PIDEntry; }
>>>>>> +
>>>>>> + uint64_t pid() const { return PID; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class NewBufferRecord : public MetadataRecord {
>>>>>> + int32_t TID = 0;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> +public:
>>>>>> + NewBufferRecord() = default;
>>>>>> + explicit NewBufferRecord(int32_t T) : MetadataRecord(), TID(T)
>> {}
>>>>>> +
>>>>>> + MetadataType metadataType() const override { return
>>>>>> MetadataType::NewBuffer; }
>>>>>> +
>>>>>> + int32_t tid() const { return TID; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class EndBufferRecord : public MetadataRecord {
>>>>>> +public:
>>>>>> + EndBufferRecord() = default;
>>>>>> +
>>>>>> + MetadataType metadataType() const override {
>>>>>> + return MetadataType::EndOfBuffer;
>>>>>> + }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class FunctionRecord : public Record {
>>>>>> + RecordTypes Kind;
>>>>>> + int32_t FuncId;
>>>>>> + uint32_t Delta;
>>>>>> + friend class RecordInitializer;
>>>>>> +
>>>>>> + static constexpr unsigned kFunctionRecordSize = 8;
>>>>>> +
>>>>>> +public:
>>>>>> + FunctionRecord() = default;
>>>>>> + explicit FunctionRecord(RecordTypes K, int32_t F, uint32_t D)
>>>>>> + : Record(), Kind(K), FuncId(F), Delta(D) {}
>>>>>> +
>>>>>> + Type type() const override { return Type::Function; }
>>>>>> +
>>>>>> + // A function record is a concrete record type which has a
>> number of
>>>>>> common
>>>>>> + // properties.
>>>>>> + RecordTypes recordType() const { return Kind; }
>>>>>> + int32_t functionId() const { return FuncId; }
>>>>>> + uint64_t delta() const { return Delta; }
>>>>>> +
>>>>>> + Error apply(RecordVisitor &V) override;
>>>>>> +};
>>>>>> +
>>>>>> +class RecordVisitor {
>>>>>> +public:
>>>>>> + virtual ~RecordVisitor() = default;
>>>>>> +
>>>>>> + // Support all specific kinds of records:
>>>>>> + virtual Error visit(BufferExtents &) = 0;
>>>>>> + virtual Error visit(WallclockRecord &) = 0;
>>>>>> + virtual Error visit(NewCPUIDRecord &) = 0;
>>>>>> + virtual Error visit(TSCWrapRecord &) = 0;
>>>>>> + virtual Error visit(CustomEventRecord &) = 0;
>>>>>> + virtual Error visit(CallArgRecord &) = 0;
>>>>>> + virtual Error visit(PIDRecord &) = 0;
>>>>>> + virtual Error visit(NewBufferRecord &) = 0;
>>>>>> + virtual Error visit(EndBufferRecord &) = 0;
>>>>>> + virtual Error visit(FunctionRecord &) = 0;
>>>>>> +};
>>>>>> +
>>>>>> +class RecordInitializer : public RecordVisitor {
>>>>>> + DataExtractor &E;
>>>>>> + uint32_t &OffsetPtr;
>>>>>> +
>>>>>> +public:
>>>>>> + explicit RecordInitializer(DataExtractor &DE, uint32_t &OP)
>>>>>> + : RecordVisitor(), E(DE), OffsetPtr(OP) {}
>>>>>> +
>>>>>> + Error visit(BufferExtents &) override;
>>>>>> + Error visit(WallclockRecord &) override;
>>>>>> + Error visit(NewCPUIDRecord &) override;
>>>>>> + Error visit(TSCWrapRecord &) override;
>>>>>> + Error visit(CustomEventRecord &) override;
>>>>>> + Error visit(CallArgRecord &) override;
>>>>>> + Error visit(PIDRecord &) override;
>>>>>> + Error visit(NewBufferRecord &) override;
>>>>>> + Error visit(EndBufferRecord &) override;
>>>>>> + Error visit(FunctionRecord &) override;
>>>>>> +};
>>>>>> +
>>>>>> +} // namespace xray
>>>>>> +} // namespace llvm
>>>>>> +
>>>>>> +#endif // LLVM_LIB_XRAY_FDRRECORDS_H_
>>>>>>
>>>>>> Added: llvm/trunk/include/llvm/XRay/FDRTraceWriter.h
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/include/llvm/XRay/FDRTraceWriter.h?rev=341029&view=a
>>>>>> uto
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/include/llvm/XRay/FDRTraceWriter.h (added)
>>>>>> +++ llvm/trunk/include/llvm/XRay/FDRTraceWriter.h Thu Aug 30
>> 00:22:21
>>>>>> 2018
>>>>>> @@ -0,0 +1,53 @@
>>>>>> +//===- FDRTraceWriter.h - XRay FDR Trace Writer -----------------
>> *-
>>>>>> C++ -*-===//
>>>>>> +//
>>>>>> +// The LLVM Compiler Infrastructure
>>>>>> +//
>>>>>> +// This file is distributed under the University of Illinois Open
>>>>>> Source
>>>>>> +// License. See LICENSE.TXT for details.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// Test a utility that can write out XRay FDR Mode formatted
>> trace
>>>>>> files.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +#ifndef LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
>>>>>> +#define LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
>>>>>> +
>>>>>> +#include "llvm/Support/raw_ostream.h"
>>>>>> +#include "llvm/XRay/FDRRecords.h"
>>>>>> +#include "llvm/XRay/XRayRecord.h"
>>>>>> +
>>>>>> +namespace llvm {
>>>>>> +namespace xray {
>>>>>> +
>>>>>> +/// The FDRTraceWriter allows us to hand-craft an XRay Flight
>> Data
>>>>>> Recorder
>>>>>> +/// (FDR) mode log file. This is used primarily for testing,
>>>>>> generating
>>>>>> +/// sequences of FDR records that can be read/processed. It can
>> also
>>>>>> be used to
>>>>>> +/// generate various kinds of execution traces without using the
>> XRay
>>>>>> runtime.
>>>>>> +/// Note that this writer does not do any validation, but uses
>> the
>>>>>> types of
>>>>>> +/// records defined in the FDRRecords.h file.
>>>>>> +class FDRTraceWriter : public RecordVisitor {
>>>>>> +public:
>>>>>> + // Construct an FDRTraceWriter associated with an output
>> stream.
>>>>>> + explicit FDRTraceWriter(raw_ostream &O, const XRayFileHeader
>> &H);
>>>>>> + ~FDRTraceWriter();
>>>>>> +
>>>>>> + Error visit(BufferExtents &) override;
>>>>>> + Error visit(WallclockRecord &) override;
>>>>>> + Error visit(NewCPUIDRecord &) override;
>>>>>> + Error visit(TSCWrapRecord &) override;
>>>>>> + Error visit(CustomEventRecord &) override;
>>>>>> + Error visit(CallArgRecord &) override;
>>>>>> + Error visit(PIDRecord &) override;
>>>>>> + Error visit(NewBufferRecord &) override;
>>>>>> + Error visit(EndBufferRecord &) override;
>>>>>> + Error visit(FunctionRecord &) override;
>>>>>> +
>>>>>> +private:
>>>>>> + raw_ostream &OS;
>>>>>> +};
>>>>>> +
>>>>>> +} // namespace xray
>>>>>> +} // namespace llvm
>>>>>> +
>>>>>> +#endif // LLVM_INCLUDE_LLVM_XRAY_FDRTRACEWRITER_H_
>>>>>>
>>>>>> Modified: llvm/trunk/lib/XRay/CMakeLists.txt
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/lib/XRay/CMakeLists.txt?rev=341029&r1=341028&r2=3410
>>>>>> 29&view=diff
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/lib/XRay/CMakeLists.txt (original)
>>>>>> +++ llvm/trunk/lib/XRay/CMakeLists.txt Thu Aug 30 00:22:21 2018
>>>>>> @@ -1,7 +1,10 @@
>>>>>> add_llvm_library(LLVMXRay
>>>>>> + FDRRecords.cpp
>>>>>> + FDRTraceWriter.cpp
>>>>>> FileHeaderReader.cpp
>>>>>> InstrumentationMap.cpp
>>>>>> - Profile.cpp
>>>>>> + Profile.cpp
>>>>>> + RecordInitializer.cpp
>>>>>> Trace.cpp
>>>>>>
>>>>>> ADDITIONAL_HEADER_DIRS
>>>>>>
>>>>>> Added: llvm/trunk/lib/XRay/FDRRecords.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>> project/llvm/trunk/lib/XRay/FDRRecords.cpp?rev=341029&view=auto
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/lib/XRay/FDRRecords.cpp (added)
>>>>>> +++ llvm/trunk/lib/XRay/FDRRecords.cpp Thu Aug 30 00:22:21 2018
>>>>>> @@ -0,0 +1,31 @@
>>>>>> +//===- FDRRecords.cpp - XRay Flight Data Recorder Mode Records -
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// The LLVM Compiler Infrastructure
>>>>>> +//
>>>>>> +// This file is distributed under the University of Illinois Open
>>>>>> Source
>>>>>> +// License. See LICENSE.TXT for details.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// Define types and operations on these types that represent the
>>>>>> different kinds
>>>>>> +// of records we encounter in XRay flight data recorder mode
>> traces.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +#include "llvm/XRay/FDRRecords.h"
>>>>>> +
>>>>>> +namespace llvm {
>>>>>> +namespace xray {
>>>>>> +
>>>>>> +Error BufferExtents::apply(RecordVisitor &V) { return
>> V.visit(*this);
>>>>>> }
>>>>>> +Error WallclockRecord::apply(RecordVisitor &V) { return
>>>>>> V.visit(*this); }
>>>>>> +Error NewCPUIDRecord::apply(RecordVisitor &V) { return
>> V.visit(*this);
>>>>>> }
>>>>>> +Error TSCWrapRecord::apply(RecordVisitor &V) { return
>> V.visit(*this);
>>>>>> }
>>>>>> +Error CustomEventRecord::apply(RecordVisitor &V) { return
>>>>>> V.visit(*this); }
>>>>>> +Error CallArgRecord::apply(RecordVisitor &V) { return
>> V.visit(*this);
>>>>>> }
>>>>>> +Error PIDRecord::apply(RecordVisitor &V) { return V.visit(*this);
>> }
>>>>>> +Error NewBufferRecord::apply(RecordVisitor &V) { return
>>>>>> V.visit(*this); }
>>>>>> +Error EndBufferRecord::apply(RecordVisitor &V) { return
>>>>>> V.visit(*this); }
>>>>>> +Error FunctionRecord::apply(RecordVisitor &V) { return
>> V.visit(*this);
>>>>>> }
>>>>>> +
>>>>>> +} // namespace xray
>>>>>> +} // namespace llvm
>>>>>>
>>>>>> Added: llvm/trunk/lib/XRay/FDRTraceWriter.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/lib/XRay/FDRTraceWriter.cpp?rev=341029&view=auto
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/lib/XRay/FDRTraceWriter.cpp (added)
>>>>>> +++ llvm/trunk/lib/XRay/FDRTraceWriter.cpp Thu Aug 30 00:22:21
>> 2018
>>>>>> @@ -0,0 +1,145 @@
>>>>>> +//===- FDRTraceWriter.cpp - XRay FDR Trace Writer ---------------
>> *-
>>>>>> C++ -*-===//
>>>>>> +//
>>>>>> +// The LLVM Compiler Infrastructure
>>>>>> +//
>>>>>> +// This file is distributed under the University of Illinois Open
>>>>>> Source
>>>>>> +// License. See LICENSE.TXT for details.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// Test a utility that can write out XRay FDR Mode formatted
>> trace
>>>>>> files.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +#include "llvm/XRay/FDRTraceWriter.h"
>>>>>> +#include <tuple>
>>>>>> +
>>>>>> +namespace llvm {
>>>>>> +namespace xray {
>>>>>> +
>>>>>> +namespace {
>>>>>> +
>>>>>> +struct alignas(32) FileHeader {
>>>>>> + uint16_t Version;
>>>>>> + uint16_t Type;
>>>>>> + bool ConstantTSC : 1;
>>>>>> + bool NonstopTSC : 1;
>>>>>> + alignas(8) uint64_t CycleFrequency;
>>>>>> + char FreeForm[16];
>>>>>> +};
>>>>>> +
>>>>>> +struct MetadataBlob {
>>>>>> + uint8_t Type : 1;
>>>>>> + uint8_t RecordKind : 7;
>>>>>> + char Data[15];
>>>>>> +} __attribute__((packed));
>>>>>> +
>>>>>> +struct FunctionDeltaBlob {
>>>>>> + uint8_t Type : 1;
>>>>>> + uint8_t RecordKind : 3;
>>>>>> + int FuncId : 28;
>>>>>> + uint32_t TSCDelta;
>>>>>> +} __attribute__((packed));
>>>>>> +
>>>>>> +template <size_t Index> struct IndexedMemcpy {
>>>>>> + template <
>>>>>> + class Tuple,
>>>>>> + typename std::enable_if<
>>>>>> + (Index <
>>>>>> + std::tuple_size<typename
>>>>>> std::remove_reference<Tuple>::type>::value),
>>>>>> + int>::type = 0>
>>>>>> + static void Copy(char *Dest, Tuple &&T) {
>>>>>> + auto Next = static_cast<char *>(std::memcpy(
>>>>>> + Dest, reinterpret_cast<const char
>>>>>> *>(&std::get<Index>(T)),
>>>>>> + sizeof(std::get<Index>(T)))) +
>>>>>> + sizeof(std::get<Index>(T));
>>>>>> + IndexedMemcpy<Index + 1>::Copy(Next, T);
>>>>>> + }
>>>>>> +
>>>>>> + template <
>>>>>> + class Tuple,
>>>>>> + typename std::enable_if<
>>>>>> + (Index >=
>>>>>> + std::tuple_size<typename
>>>>>> std::remove_reference<Tuple>::type>::value),
>>>>>> + int>::type = 0>
>>>>>> + static void Copy(char *, Tuple &&) {}
>>>>>> +};
>>>>>> +
>>>>>> +template <uint8_t Kind, class... Data>
>>>>>> +Error writeMetadata(raw_ostream &OS, Data... Ds) {
>>>>>> + MetadataBlob B;
>>>>>> + B.Type = 1;
>>>>>> + B.RecordKind = Kind;
>>>>>> + IndexedMemcpy<0>::Copy(B.Data, std::make_tuple(Ds...));
>>>>>> + OS.write(reinterpret_cast<const char *>(&B),
>> sizeof(MetadataBlob));
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +} // namespace
>>>>>> +
>>>>>> +FDRTraceWriter::FDRTraceWriter(raw_ostream &O, const
>> XRayFileHeader
>>>>>> &H)
>>>>>> + : OS(O) {
>>>>>> + // We need to re-construct a header, by writing the fields we
>> care
>>>>>> about for
>>>>>> + // traces, in the format that the runtime would have written.
>>>>>> + FileHeader Raw;
>>>>>> + Raw.Version = H.Version;
>>>>>> + Raw.Type = H.Type;
>>>>>> + Raw.ConstantTSC = H.ConstantTSC;
>>>>>> + Raw.NonstopTSC = H.NonstopTSC;
>>>>>> + Raw.CycleFrequency = H.CycleFrequency;
>>>>>> + memcpy(&Raw.FreeForm, H.FreeFormData, 16);
>>>>>> + OS.write(reinterpret_cast<const char *>(&Raw),
>>>>>> sizeof(XRayFileHeader));
>>>>>> +}
>>>>>> +
>>>>>> +FDRTraceWriter::~FDRTraceWriter() {}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(BufferExtents &R) {
>>>>>> + return writeMetadata<7u>(OS, R.size());
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(WallclockRecord &R) {
>>>>>> + return writeMetadata<4u>(OS, R.seconds(), R.nanos());
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(NewCPUIDRecord &R) {
>>>>>> + return writeMetadata<2u>(OS, R.cpuid());
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(TSCWrapRecord &R) {
>>>>>> + return writeMetadata<3u>(OS, R.tsc());
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(CustomEventRecord &R) {
>>>>>> + if (auto E = writeMetadata<5u>(OS, R.size(), R.tsc()))
>>>>>> + return E;
>>>>>> + OS.write(R.data().data(), R.data().size());
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(CallArgRecord &R) {
>>>>>> + return writeMetadata<6u>(OS, R.arg());
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(PIDRecord &R) {
>>>>>> + return writeMetadata<9u>(OS, R.pid());
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(NewBufferRecord &R) {
>>>>>> + return writeMetadata<0u>(OS, R.tid());
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(EndBufferRecord &R) {
>>>>>> + return writeMetadata<1u>(OS, 0);
>>>>>> +}
>>>>>> +
>>>>>> +Error FDRTraceWriter::visit(FunctionRecord &R) {
>>>>>> + FunctionDeltaBlob B;
>>>>>> + B.Type = 0;
>>>>>> + B.RecordKind = static_cast<uint8_t>(R.recordType());
>>>>>> + B.FuncId = R.functionId();
>>>>>> + B.TSCDelta = R.delta();
>>>>>> + OS.write(reinterpret_cast<const char *>(&B),
>>>>>> sizeof(FunctionDeltaBlob));
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +} // namespace xray
>>>>>> +} // namespace llvm
>>>>>>
>>>>>> Added: llvm/trunk/lib/XRay/RecordInitializer.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/lib/XRay/RecordInitializer.cpp?rev=341029&view=auto
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/lib/XRay/RecordInitializer.cpp (added)
>>>>>> +++ llvm/trunk/lib/XRay/RecordInitializer.cpp Thu Aug 30 00:22:21
>> 2018
>>>>>> @@ -0,0 +1,247 @@
>>>>>> +//===- FDRRecordProducer.cpp - XRay FDR Mode Record Producer ----
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// The LLVM Compiler Infrastructure
>>>>>> +//
>>>>>> +// This file is distributed under the University of Illinois Open
>>>>>> Source
>>>>>> +// License. See LICENSE.TXT for details.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +#include "llvm/XRay/FDRRecords.h"
>>>>>> +
>>>>>> +namespace llvm {
>>>>>> +namespace xray {
>>>>>> +
>>>>>> +Error RecordInitializer::visit(BufferExtents &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr, sizeof(uint64_t)))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a buffer extent
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.Size = E.getU64(&OffsetPtr);
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read buffer extent at offset
>>>>>> %d.",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> PreReadOffset);
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(WallclockRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a wallclock
>> record
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> + auto BeginOffset = OffsetPtr;
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.Seconds = E.getU64(&OffsetPtr);
>>>>>> + if (OffsetPtr == PreReadOffset)
>>>>>> + return createStringError(
>>>>>> + std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read wall clock 'seconds' field at offset %d.",
>>>>>> OffsetPtr);
>>>>>> +
>>>>>> + PreReadOffset = OffsetPtr;
>>>>>> + R.Nanos = E.getU32(&OffsetPtr);
>>>>>> + if (OffsetPtr == PreReadOffset)
>>>>>> + return createStringError(
>>>>>> + std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read wall clock 'nanos' field at offset %d.",
>>>>>> OffsetPtr);
>>>>>> +
>>>>>> + // Align to metadata record size boundary.
>>>>>> + assert(OffsetPtr - BeginOffset <=
>>>>>> MetadataRecord::kMetadataBodySize);
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> BeginOffset);
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(NewCPUIDRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a new cpu id
>> record
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.CPUId = E.getU16(&OffsetPtr);
>>>>>> + if (OffsetPtr == PreReadOffset)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read CPU id at offset %d.",
>>>>>> OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> PreReadOffset);
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(TSCWrapRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a new TSC wrap
>> record
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.BaseTSC = E.getU64(&OffsetPtr);
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read TSC wrap record at
>> offset
>>>>>> %d.",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> PreReadOffset);
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(CustomEventRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a custom event
>> record
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + auto BeginOffset = OffsetPtr;
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.Size = E.getSigned(&OffsetPtr, sizeof(int32_t));
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return createStringError(
>>>>>> + std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read a custom event record size field offset
>> %d.",
>>>>>> OffsetPtr);
>>>>>> +
>>>>>> + PreReadOffset = OffsetPtr;
>>>>>> + R.TSC = E.getU64(&OffsetPtr);
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return createStringError(
>>>>>> + std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read a custom event TSC field at offset %d.",
>>>>>> OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> BeginOffset);
>>>>>> +
>>>>>> + // Next we read in a fixed chunk of data from the given offset.
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr, R.Size))
>>>>>> + return createStringError(
>>>>>> + std::make_error_code(std::errc::bad_address),
>>>>>> + "Cannot read %d bytes of custom event data from offset
>> %d.",
>>>>>> R.Size,
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + std::vector<uint8_t> Buffer;
>>>>>> + Buffer.resize(R.Size);
>>>>>> + if (E.getU8(&OffsetPtr, Buffer.data(), R.Size) !=
>> Buffer.data())
>>>>>> + return createStringError(
>>>>>> + std::make_error_code(std::errc::bad_message),
>>>>>> + "Failed reading data into buffer of size %d at offset
>> %d.",
>>>>>> R.Size,
>>>>>> + OffsetPtr);
>>>>>> + R.Data.assign(Buffer.begin(), Buffer.end());
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(CallArgRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a call argument
>>>>>> record (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.Arg = E.getU64(&OffsetPtr);
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read a call arg record at
>> offset
>>>>>> %d.",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> PreReadOffset);
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(PIDRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a process ID
>> record
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.PID = E.getU64(&OffsetPtr);
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read a process ID record at
>>>>>> offset %d.",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> PreReadOffset);
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(NewBufferRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a new buffer
>> record
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + auto PreReadOffset = OffsetPtr;
>>>>>> + R.TID = E.getSigned(&OffsetPtr, sizeof(int32_t));
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Cannot read a new buffer record at
>>>>>> offset %d.",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize - (OffsetPtr -
>>>>>> PreReadOffset);
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(EndBufferRecord &R) {
>>>>>> + if (!E.isValidOffsetForDataOfSize(OffsetPtr,
>>>>>> +
>>>>>> MetadataRecord::kMetadataBodySize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for an end-of-buffer
>>>>>> record (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + OffsetPtr += MetadataRecord::kMetadataBodySize;
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +Error RecordInitializer::visit(FunctionRecord &R) {
>>>>>> + // For function records, we need to retreat one byte back to
>> read a
>>>>>> full
>>>>>> + // unsigned 32-bit value. The first four bytes will have the
>>>>>> following
>>>>>> + // layout:
>>>>>> + //
>>>>>> + // bit 0 : function record indicator (must be 0)
>>>>>> + // bits 1..3 : function record type
>>>>>> + // bits 4..32 : function id
>>>>>> + //
>>>>>> + if (OffsetPtr == 0 || !E.isValidOffsetForDataOfSize(
>>>>>> + --OffsetPtr,
>>>>>> FunctionRecord::kFunctionRecordSize))
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Invalid offset for a function
>> record
>>>>>> (%d).",
>>>>>> + OffsetPtr);
>>>>>> +
>>>>>> + auto BeginOffset = OffsetPtr;
>>>>>> + auto PreReadOffset = BeginOffset;
>>>>>> + uint32_t Buffer = E.getU32(&OffsetPtr);
>>>>>> + if (PreReadOffset == OffsetPtr)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_address),
>>>>>> + "Cannot read function id field from
>>>>>> offset %d.",
>>>>>> + OffsetPtr);
>>>>>> + unsigned FunctionType = (Buffer >> 1) & 0x07;
>>>>>> + switch (FunctionType) {
>>>>>> + case static_cast<unsigned>(RecordTypes::ENTER):
>>>>>> + case static_cast<unsigned>(RecordTypes::ENTER_ARG):
>>>>>> + case static_cast<unsigned>(RecordTypes::EXIT):
>>>>>> + case static_cast<unsigned>(RecordTypes::TAIL_EXIT):
>>>>>> + R.Kind = static_cast<RecordTypes>(FunctionType);
>>>>>> + break;
>>>>>> + default:
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Unknown function record type '%d'
>> at
>>>>>> offset %d.",
>>>>>> + FunctionType, BeginOffset);
>>>>>> + }
>>>>>> +
>>>>>> + R.FuncId = Buffer >> 4;
>>>>>> + PreReadOffset = OffsetPtr;
>>>>>> + R.Delta = E.getU32(&OffsetPtr);
>>>>>> + if (OffsetPtr == PreReadOffset)
>>>>>> + return
>>>>>> createStringError(std::make_error_code(std::errc::bad_message),
>>>>>> + "Failed reading TSC delta from
>> offset
>>>>>> %d.",
>>>>>> + OffsetPtr);
>>>>>> + assert(FunctionRecord::kFunctionRecordSize == (OffsetPtr -
>>>>>> BeginOffset));
>>>>>> + return Error::success();
>>>>>> +}
>>>>>> +
>>>>>> +} // namespace xray
>>>>>> +} // namespace llvm
>>>>>>
>>>>>> Modified: llvm/trunk/unittests/XRay/CMakeLists.txt
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/unittests/XRay/CMakeLists.txt?rev=341029&r1=341028&r
>>>>>> 2=341029&view=diff
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/unittests/XRay/CMakeLists.txt (original)
>>>>>> +++ llvm/trunk/unittests/XRay/CMakeLists.txt Thu Aug 30 00:22:21
>> 2018
>>>>>> @@ -1,9 +1,10 @@
>>>>>> set(LLVM_LINK_COMPONENTS
>>>>>> Support
>>>>>> - XRay
>>>>>> + XRay
>>>>>> )
>>>>>>
>>>>>> add_llvm_unittest(XRayTests
>>>>>> + FDRTraceWriterTest.cpp
>>>>>> GraphTest.cpp
>>>>>> ProfileTest.cpp
>>>>>> )
>>>>>>
>>>>>> Added: llvm/trunk/unittests/XRay/FDRTraceWriterTest.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-
>>>>>>
>> project/llvm/trunk/unittests/XRay/FDRTraceWriterTest.cpp?rev=341029&vie
>>>>>> w=auto
>>>>>>
>> =======================================================================
>>>>>> =======
>>>>>> --- llvm/trunk/unittests/XRay/FDRTraceWriterTest.cpp (added)
>>>>>> +++ llvm/trunk/unittests/XRay/FDRTraceWriterTest.cpp Thu Aug 30
>>>>>> 00:22:21 2018
>>>>>> @@ -0,0 +1,175 @@
>>>>>> +//===- llvm/unittest/XRay/FDRTraceWriterTest.cpp ----------------
>> *-
>>>>>> C++ -*-===//
>>>>>> +//
>>>>>> +// The LLVM Compiler Infrastructure
>>>>>> +//
>>>>>> +// This file is distributed under the University of Illinois Open
>>>>>> Source
>>>>>> +// License. See LICENSE.TXT for details.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +//
>>>>>> +// Test a utility that can write out XRay FDR Mode formatted
>> trace
>>>>>> files.
>>>>>> +//
>>>>>> +//===------------------------------------------------------------
>> -----
>>>>>> -----===//
>>>>>> +#include "llvm/XRay/FDRTraceWriter.h"
>>>>>> +#include "llvm/Support/raw_ostream.h"
>>>>>> +#include "llvm/XRay/FDRLogBuilder.h"
>>>>>> +#include "llvm/XRay/FDRRecords.h"
>>>>>> +#include "llvm/XRay/Trace.h"
>>>>>> +#include "gmock/gmock.h"
>>>>>> +#include "gtest/gtest.h"
>>>>>> +#include <string>
>>>>>> +
>>>>>> +namespace llvm {
>>>>>> +namespace xray {
>>>>>> +namespace {
>>>>>> +
>>>>>> +using testing::ElementsAre;
>>>>>> +using testing::Eq;
>>>>>> +using testing::Field;
>>>>>> +using testing::IsEmpty;
>>>>>> +using testing::Not;
>>>>>> +
>>>>>> +// We want to be able to create an instance of an FDRTraceWriter
>> and
>>>>>> associate
>>>>>> +// it with a stream, which could be loaded and turned into a
>> Trace
>>>>>> instance.
>>>>>> +// This test writes out version 3 trace logs.
>>>>>> +TEST(FDRTraceWriterTest, WriteToStringBufferVersion3) {
>>>>>> + std::string Data;
>>>>>> + raw_string_ostream OS(Data);
>>>>>> + XRayFileHeader H;
>>>>>> + H.Version = 3;
>>>>>> + H.Type = 1;
>>>>>> + H.ConstantTSC = true;
>>>>>> + H.NonstopTSC = true;
>>>>>> + H.CycleFrequency = 3e9;
>>>>>> + FDRTraceWriter Writer(OS, H);
>>>>>> + auto L = LogBuilder()
>>>>>> + .add<BufferExtents>(80)
>>>>>> + .add<NewBufferRecord>(1)
>>>>>> + .add<WallclockRecord>(1, 1)
>>>>>> + .add<PIDRecord>(1)
>>>>>> + .add<NewCPUIDRecord>(1)
>>>>>> + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
>>>>>> + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
>>>>>> + .consume();
>>>>>> + for (auto &P : L)
>>>>>> + ASSERT_FALSE(errorToBool(P->apply(Writer)));
>>>>>> + OS.flush();
>>>>>> +
>>>>>> + // Then from here we load the Trace file.
>>>>>> + DataExtractor DE(Data, true, 8);
>>>>>> + auto TraceOrErr = loadTrace(DE, true);
>>>>>> + if (!TraceOrErr)
>>>>>> + FAIL() << TraceOrErr.takeError();
>>>>>> + auto &Trace = TraceOrErr.get();
>>>>>> +
>>>>>> + ASSERT_THAT(Trace, Not(IsEmpty()));
>>>>>> + ASSERT_THAT(
>>>>>> + Trace,
>>>>>> + ElementsAre(AllOf(Field(&XRayRecord::FuncId, Eq(1)),
>>>>>> + Field(&XRayRecord::TId, Eq(1u)),
>>>>>> + Field(&XRayRecord::CPU, Eq(1u)),
>>>>>> + Field(&XRayRecord::Type,
>>>>>> Eq(RecordTypes::ENTER))),
>>>>>> + AllOf(Field(&XRayRecord::FuncId, Eq(1)),
>>>>>> + Field(&XRayRecord::TId, Eq(1u)),
>>>>>> + Field(&XRayRecord::CPU, Eq(1u)),
>>>>>> + Field(&XRayRecord::Type,
>>>>>> Eq(RecordTypes::EXIT)))));
>>>>>> +}
>>>>>> +
>>>>>> +// This version is almost exactly the same as above, except
>> writing
>>>>>> version 2
>>>>>> +// logs, without the PID records.
>>>>>> +TEST(FDRTraceWriterTest, WriteToStringBufferVersion2) {
>>>>>> + std::string Data;
>>>>>> + raw_string_ostream OS(Data);
>>>>>> + XRayFileHeader H;
>>>>>> + H.Version = 2;
>>>>>> + H.Type = 1;
>>>>>> + H.ConstantTSC = true;
>>>>>> + H.NonstopTSC = true;
>>>>>> + H.CycleFrequency = 3e9;
>>>>>> + FDRTraceWriter Writer(OS, H);
>>>>>> + auto L = LogBuilder()
>>>>>> + .add<BufferExtents>(64)
>>>>>> + .add<NewBufferRecord>(1)
>>>>>> + .add<WallclockRecord>(1, 1)
>>>>>> + .add<NewCPUIDRecord>(1)
>>>>>> + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
>>>>>> + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
>>>>>> + .consume();
>>>>>> + for (auto &P : L)
>>>>>> + ASSERT_FALSE(errorToBool(P->apply(Writer)));
>>>>>> + OS.flush();
>>>>>> +
>>>>>> + // Then from here we load the Trace file.
>>>>>> + DataExtractor DE(Data, true, 8);
>>>>>> + auto TraceOrErr = loadTrace(DE, true);
>>>>>> + if (!TraceOrErr)
>>>>>> + FAIL() << TraceOrErr.takeError();
>>>>>> + auto &Trace = TraceOrErr.get();
>>>>>> +
>>>>>> + ASSERT_THAT(Trace, Not(IsEmpty()));
>>>>>> + ASSERT_THAT(
>>>>>> + Trace,
>>>>>> + ElementsAre(AllOf(Field(&XRayRecord::FuncId, Eq(1)),
>>>>>> + Field(&XRayRecord::TId, Eq(1u)),
>>>>>> + Field(&XRayRecord::CPU, Eq(1u)),
>>>>>> + Field(&XRayRecord::Type,
>>>>>> Eq(RecordTypes::ENTER))),
>>>>>> + AllOf(Field(&XRayRecord::FuncId, Eq(1)),
>>>>>> + Field(&XRayRecord::TId, Eq(1u)),
>>>>>> + Field(&XRayRecord::CPU, Eq(1u)),
>>>>>> + Field(&XRayRecord::Type,
>>>>>> Eq(RecordTypes::EXIT)))));
>>>>>> +}
>>>>>> +
>>>>>> +// This covers version 1 of the log, without a BufferExtents
>> record
>>>>>> but has an
>>>>>> +// explicit EndOfBuffer record.
>>>>>> +TEST(FDRTraceWriterTest, WriteToStringBufferVersion1) {
>>>>>> + std::string Data;
>>>>>> + raw_string_ostream OS(Data);
>>>>>> + XRayFileHeader H;
>>>>>> + H.Version = 1;
>>>>>> + H.Type = 1;
>>>>>> + H.ConstantTSC = true;
>>>>>> + H.NonstopTSC = true;
>>>>>> + H.CycleFrequency = 3e9;
>>>>>> + // Write the size of buffers out, arbitrarily it's 4k.
>>>>>> + constexpr uint64_t BufferSize = 4096;
>>>>>> + std::memcpy(H.FreeFormData, reinterpret_cast<const char
>>>>>> *>(&BufferSize),
>>>>>> + sizeof(BufferSize));
>>>>>> + FDRTraceWriter Writer(OS, H);
>>>>>> + auto L = LogBuilder()
>>>>>> + .add<NewBufferRecord>(1)
>>>>>> + .add<WallclockRecord>(1, 1)
>>>>>> + .add<NewCPUIDRecord>(1)
>>>>>> + .add<FunctionRecord>(RecordTypes::ENTER, 1, 1)
>>>>>> + .add<FunctionRecord>(RecordTypes::EXIT, 1, 100)
>>>>>> + .add<EndBufferRecord>()
>>>>>> + .consume();
>>>>>> + for (auto &P : L)
>>>>>> + ASSERT_FALSE(errorToBool(P->apply(Writer)));
>>>>>> +
>>>>>> + // We need to pad the buffer with 4016 (4096 - 80) bytes of
>> zeros.
>>>>>> + OS.write_zeros(4016);
>>>>>> + OS.flush();
>>>>>> +
>>>>>> + // Then from here we load the Trace file.
>>>>>> + DataExtractor DE(Data, true, 8);
>>>>>> + auto TraceOrErr = loadTrace(DE, true);
>>>>>> + if (!TraceOrErr)
>>>>>> + FAIL() << TraceOrErr.takeError();
>>>>>> + auto &Trace = TraceOrErr.get();
>>>>>> +
>>>>>> + ASSERT_THAT(Trace, Not(IsEmpty()));
>>>>>> + ASSERT_THAT(
>>>>>> + Trace,
>>>>>> + ElementsAre(AllOf(Field(&XRayRecord::FuncId, Eq(1)),
>>>>>> + Field(&XRayRecord::TId, Eq(1u)),
>>>>>> + Field(&XRayRecord::CPU, Eq(1u)),
>>>>>> + Field(&XRayRecord::Type,
>>>>>> Eq(RecordTypes::ENTER))),
>>>>>> + AllOf(Field(&XRayRecord::FuncId, Eq(1)),
>>>>>> + Field(&XRayRecord::TId, Eq(1u)),
>>>>>> + Field(&XRayRecord::CPU, Eq(1u)),
>>>>>> + Field(&XRayRecord::Type,
>>>>>> Eq(RecordTypes::EXIT)))));
>>>>>> +}
>>>>>> +
>>>>>> +} // namespace
>>>>>> +} // namespace xray
>>>>>> +} // namespace llvm
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> llvm-commits mailing list
>>>>>> llvm-commits at lists.llvm.org
>>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>> _______________________________________________
>>>>> llvm-commits mailing list
>>>>> llvm-commits at lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>
>>>> -- Dean
>>>>
>>>
>>> -- Dean
>>>
>>
>> -- Dean
>
-- Dean
More information about the llvm-commits
mailing list