/ bytecode / RecordedStatuses.cpp
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