We should support CreateThis in the FTL
[WebKit-https.git] / Source / JavaScriptCore / bytecode / RecordedStatuses.cpp
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "RecordedStatuses.h"
28
29 namespace JSC {
30
31 RecordedStatuses& RecordedStatuses::operator=(RecordedStatuses&& other)
32 {
33     calls = WTFMove(other.calls);
34     gets = WTFMove(other.gets);
35     puts = WTFMove(other.puts);
36     ins = WTFMove(other.ins);
37     shrinkToFit();
38     return *this;
39 }
40
41 RecordedStatuses::RecordedStatuses(RecordedStatuses&& other)
42 {
43     *this = WTFMove(other);
44 }
45
46 CallLinkStatus* RecordedStatuses::addCallLinkStatus(const CodeOrigin& codeOrigin, const CallLinkStatus& status)
47 {
48     auto statusPtr = std::make_unique<CallLinkStatus>(status);
49     CallLinkStatus* result = statusPtr.get();
50     calls.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
51     return result;
52 }
53
54 GetByIdStatus* RecordedStatuses::addGetByIdStatus(const CodeOrigin& codeOrigin, const GetByIdStatus& status)
55 {
56     auto statusPtr = std::make_unique<GetByIdStatus>(status);
57     GetByIdStatus* result = statusPtr.get();
58     gets.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
59     return result;
60 }
61     
62 PutByIdStatus* RecordedStatuses::addPutByIdStatus(const CodeOrigin& codeOrigin, const PutByIdStatus& status)
63 {
64     auto statusPtr = std::make_unique<PutByIdStatus>(status);
65     PutByIdStatus* result = statusPtr.get();
66     puts.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
67     return result;
68 }
69
70 InByIdStatus* RecordedStatuses::addInByIdStatus(const CodeOrigin& codeOrigin, const InByIdStatus& status)
71 {
72     auto statusPtr = std::make_unique<InByIdStatus>(status);
73     InByIdStatus* result = statusPtr.get();
74     ins.append(std::make_pair(codeOrigin, WTFMove(statusPtr)));
75     return result;
76 }
77
78 void RecordedStatuses::markIfCheap(SlotVisitor& slotVisitor)
79 {
80     for (auto& pair : gets)
81         pair.second->markIfCheap(slotVisitor);
82     for (auto& pair : puts)
83         pair.second->markIfCheap(slotVisitor);
84     for (auto& pair : ins)
85         pair.second->markIfCheap(slotVisitor);
86 }
87
88 void RecordedStatuses::finalizeWithoutDeleting()
89 {
90     // This variant of finalize gets called from within graph safepoints -- so there may be DFG IR in
91     // some compiler thread that points to the statuses. That thread is stopped at a safepoint so
92     // it's OK to edit its data structure, but it's not OK to delete them. Hence we don't remove
93     // anything from the vector or delete the unique_ptrs.
94     
95     auto finalize = [] (auto& vector) {
96         for (auto& pair : vector) {
97             if (!pair.second->finalize())
98                 *pair.second = { };
99         }
100     };
101     forEachVector(finalize);
102 }
103
104 void RecordedStatuses::finalize()
105 {
106     auto finalize = [] (auto& vector) {
107         vector.removeAllMatching(
108             [&] (auto& pair) -> bool {
109                 return !*pair.second || !pair.second->finalize();
110             });
111         vector.shrinkToFit();
112     };
113     forEachVector(finalize);
114 }
115
116 void RecordedStatuses::shrinkToFit()
117 {
118     forEachVector([] (auto& vector) { vector.shrinkToFit(); });
119 }
120
121 } // namespace JSC
122