465bbf129b700c0f5200900ecb35c0de58d32b24
[WebKit-https.git] / Source / WebCore / replay / SegmentedInputStorage.cpp
1 /*
2  * Copyright (C) 2013 University of Washington. All rights reserved.
3  * Copyright (C) 2014 Apple Inc. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
16  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "SegmentedInputStorage.h"
30
31 #if ENABLE(WEB_REPLAY)
32
33 #if !LOG_DISABLED
34 #include "Logging.h"
35 #include "SerializationMethods.h"
36 #include <replay/EncodedValue.h>
37 #include <wtf/text/CString.h>
38 #include <wtf/text/WTFString.h>
39 #endif
40
41 namespace WebCore {
42
43 #if !LOG_DISABLED
44 // These are used to make the log spew from LOG(WebReplay, ...) more readable.
45 static const char* queueTypeToLogPrefix(InputQueue inputQueue, bool isLoad)
46 {
47     if (isLoad) {
48         switch (inputQueue) {
49         case InputQueue::EventLoopInput: return "(DSPTCH-LOAD)";
50         case InputQueue::LoaderMemoizedData: return "<LDMEMO-LOAD";
51         case InputQueue::ScriptMemoizedData: return "<---<---<---JSMEMO-LOAD";
52         case InputQueue::Count: return "ERROR!";
53         }
54     } else {
55         switch (inputQueue) {
56         case InputQueue::EventLoopInput: return ">DSPTCH-STORE";
57         case InputQueue::LoaderMemoizedData: return "<LDMEMO-STORE";
58         case InputQueue::ScriptMemoizedData: return "<---<---<---JSMEMO-STORE";
59         case InputQueue::Count: return "ERROR!";
60         }
61     }
62 }
63
64 static String jsonStringForInput(const NondeterministicInputBase& input)
65 {
66     EncodedValue encodedValue = EncodingTraits<NondeterministicInputBase>::encodeValue(input);
67     return encodedValue.asObject()->toJSONString();
68 }
69 #endif // !LOG_DISABLED
70
71 static size_t offsetForInputQueue(InputQueue inputQueue)
72 {
73     return static_cast<size_t>(inputQueue);
74 }
75
76 SegmentedInputStorage::SegmentedInputStorage()
77     : m_inputCount(0)
78 {
79     for (size_t i = 0; i < offsetForInputQueue(InputQueue::Count); i++)
80         m_queues.append(new QueuedInputs);
81 }
82
83 SegmentedInputStorage::~SegmentedInputStorage()
84 {
85     for (size_t i = 0; i < offsetForInputQueue(InputQueue::Count); i++)
86         delete m_queues.at(i);
87 }
88
89 NondeterministicInputBase* SegmentedInputStorage::load(InputQueue inputQueue, size_t offset)
90 {
91     ASSERT(offset < queueSize(inputQueue));
92
93     NondeterministicInputBase* input = queue(inputQueue).at(offset).get();
94     ASSERT(input);
95
96     LOG(WebReplay, "%-20s %s: %s %s\n", "ReplayEvents", queueTypeToLogPrefix(inputQueue, true), input->type().string().utf8().data(), jsonStringForInput(*input).utf8().data());
97
98     return input;
99 }
100
101 void SegmentedInputStorage::store(std::unique_ptr<NondeterministicInputBase> input)
102 {
103     ASSERT(input);
104     ASSERT(input->queue() < InputQueue::Count);
105
106     LOG(WebReplay, "%-14s#%-5u %s: %s %s\n", "ReplayEvents", m_inputCount++, queueTypeToLogPrefix(input->queue(), false), input->type().string().utf8().data(), jsonStringForInput(*input).utf8().data());
107
108     m_queues.at(offsetForInputQueue(input->queue()))->append(WTF::move(input));
109 }
110
111 size_t SegmentedInputStorage::queueSize(InputQueue inputQueue) const
112 {
113     return queue(inputQueue).size();
114 }
115
116 const SegmentedInputStorage::QueuedInputs& SegmentedInputStorage::queue(InputQueue queue) const
117 {
118     ASSERT(queue < InputQueue::Count);
119     return *m_queues.at(offsetForInputQueue(queue));
120 }
121
122 } // namespace WebCore
123
124 #endif // ENABLE(WEB_REPLAY)