RecordedStatuses.cpp
1 /* 2 * Copyright (C) 2018-2020 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 deletes = WTFMove(other.deletes); 38 shrinkToFit(); 39 return *this; 40 } 41 42 RecordedStatuses::RecordedStatuses(RecordedStatuses&& other) 43 { 44 *this = WTFMove(other); 45 } 46 47 CallLinkStatus* RecordedStatuses::addCallLinkStatus(const CodeOrigin& codeOrigin, const CallLinkStatus& status) 48 { 49 auto statusPtr = makeUnique<CallLinkStatus>(status); 50 CallLinkStatus* result = statusPtr.get(); 51 calls.append(std::make_pair(codeOrigin, WTFMove(statusPtr))); 52 return result; 53 } 54 55 GetByStatus* RecordedStatuses::addGetByStatus(const CodeOrigin& codeOrigin, const GetByStatus& status) 56 { 57 auto statusPtr = makeUnique<GetByStatus>(status); 58 GetByStatus* result = statusPtr.get(); 59 gets.append(std::make_pair(codeOrigin, WTFMove(statusPtr))); 60 return result; 61 } 62 63 PutByIdStatus* RecordedStatuses::addPutByIdStatus(const CodeOrigin& codeOrigin, const PutByIdStatus& status) 64 { 65 auto statusPtr = makeUnique<PutByIdStatus>(status); 66 PutByIdStatus* result = statusPtr.get(); 67 puts.append(std::make_pair(codeOrigin, WTFMove(statusPtr))); 68 return result; 69 } 70 71 InByIdStatus* RecordedStatuses::addInByIdStatus(const CodeOrigin& codeOrigin, const InByIdStatus& status) 72 { 73 auto statusPtr = makeUnique<InByIdStatus>(status); 74 InByIdStatus* result = statusPtr.get(); 75 ins.append(std::make_pair(codeOrigin, WTFMove(statusPtr))); 76 return result; 77 } 78 79 DeleteByStatus* RecordedStatuses::addDeleteByStatus(const CodeOrigin& codeOrigin, const DeleteByStatus& status) 80 { 81 auto statusPtr = makeUnique<DeleteByStatus>(status); 82 DeleteByStatus* result = statusPtr.get(); 83 deletes.append(std::make_pair(codeOrigin, WTFMove(statusPtr))); 84 return result; 85 } 86 87 void RecordedStatuses::visitAggregate(SlotVisitor& slotVisitor) 88 { 89 for (auto& pair : gets) 90 pair.second->visitAggregate(slotVisitor); 91 for (auto& pair : deletes) 92 pair.second->visitAggregate(slotVisitor); 93 } 94 95 void RecordedStatuses::markIfCheap(SlotVisitor& slotVisitor) 96 { 97 for (auto& pair : gets) 98 pair.second->markIfCheap(slotVisitor); 99 for (auto& pair : puts) 100 pair.second->markIfCheap(slotVisitor); 101 for (auto& pair : ins) 102 pair.second->markIfCheap(slotVisitor); 103 for (auto& pair : deletes) 104 pair.second->markIfCheap(slotVisitor); 105 } 106 107 void RecordedStatuses::finalizeWithoutDeleting(VM& vm) 108 { 109 // This variant of finalize gets called from within graph safepoints -- so there may be DFG IR in 110 // some compiler thread that points to the statuses. That thread is stopped at a safepoint so 111 // it's OK to edit its data structure, but it's not OK to delete them. Hence we don't remove 112 // anything from the vector or delete the unique_ptrs. 113 114 auto finalize = [&] (auto& vector) { 115 for (auto& pair : vector) { 116 if (!pair.second->finalize(vm)) 117 *pair.second = { }; 118 } 119 }; 120 forEachVector(finalize); 121 } 122 123 void RecordedStatuses::finalize(VM& vm) 124 { 125 auto finalize = [&] (auto& vector) { 126 vector.removeAllMatching( 127 [&] (auto& pair) -> bool { 128 return !*pair.second || !pair.second->finalize(vm); 129 }); 130 vector.shrinkToFit(); 131 }; 132 forEachVector(finalize); 133 } 134 135 void RecordedStatuses::shrinkToFit() 136 { 137 forEachVector([] (auto& vector) { vector.shrinkToFit(); }); 138 } 139 140 } // namespace JSC 141