1 /** 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef PANDA_RUNTIME_MEM_GC_G1_REF_UPDATER_H 16 #define PANDA_RUNTIME_MEM_GC_G1_REF_UPDATER_H 17 18 #include "runtime/include/object_header.h" 19 #include "runtime/mem/gc/gc_barrier_set.h" 20 #include "runtime/mem/region_allocator.h" 21 22 namespace panda::mem { 23 24 template <class LanguageConfig> 25 class BaseRefUpdater { 26 public: operator()27 bool operator()(ObjectHeader *object, ObjectHeader *ref, uint32_t offset, 28 [[maybe_unused]] bool isVolatile = false) const 29 { 30 auto *forwarded = UpdateRefToMovedObject(object, ref, offset); 31 Process(object, offset, forwarded); 32 return true; 33 } 34 35 DEFAULT_COPY_SEMANTIC(BaseRefUpdater); 36 DEFAULT_MOVE_SEMANTIC(BaseRefUpdater); 37 virtual ~BaseRefUpdater() = default; 38 39 protected: BaseRefUpdater(uint32_t regionSizeBits)40 explicit BaseRefUpdater(uint32_t regionSizeBits) : regionSizeBits_(regionSizeBits) {} 41 42 virtual void Process(ObjectHeader *object, size_t offset, ObjectHeader *ref) const = 0; 43 IsSameRegion(ObjectHeader * o1,ObjectHeader * o2)44 bool IsSameRegion(ObjectHeader *o1, ObjectHeader *o2) const 45 { 46 return panda::mem::IsSameRegion(o1, o2, regionSizeBits_); 47 } 48 49 private: 50 ObjectHeader *UpdateRefToMovedObject(ObjectHeader *object, ObjectHeader *ref, uint32_t offset) const; 51 52 uint32_t regionSizeBits_; 53 }; 54 55 template <class LanguageConfig, bool NEED_LOCK = false> 56 class UpdateRemsetRefUpdater : public BaseRefUpdater<LanguageConfig> { 57 public: UpdateRemsetRefUpdater(uint32_t regionSizeBits)58 explicit UpdateRemsetRefUpdater(uint32_t regionSizeBits) : BaseRefUpdater<LanguageConfig>(regionSizeBits) {} 59 60 protected: 61 void Process(ObjectHeader *object, size_t offset, ObjectHeader *ref) const override; 62 }; 63 64 template <class LanguageConfig> 65 class EnqueueRemsetRefUpdater : public BaseRefUpdater<LanguageConfig> { 66 public: EnqueueRemsetRefUpdater(CardTable * cardTable,GCG1BarrierSet::ThreadLocalCardQueues * updatedRefsQueue,uint32_t regionSizeBits)67 EnqueueRemsetRefUpdater(CardTable *cardTable, GCG1BarrierSet::ThreadLocalCardQueues *updatedRefsQueue, 68 uint32_t regionSizeBits) 69 : BaseRefUpdater<LanguageConfig>(regionSizeBits), cardTable_(cardTable), updatedRefsQueue_(updatedRefsQueue) 70 { 71 } 72 73 protected: Process(ObjectHeader * object,size_t offset,ObjectHeader * ref)74 void Process(ObjectHeader *object, size_t offset, ObjectHeader *ref) const override 75 { 76 if (!this->IsSameRegion(object, ref)) { 77 auto *card = cardTable_->GetCardPtr(ToUintPtr(object) + offset); 78 if (card->IsClear()) { 79 card->Mark(); 80 updatedRefsQueue_->push_back(card); 81 } 82 } 83 } 84 85 private: 86 CardTable *cardTable_; 87 GCG1BarrierSet::ThreadLocalCardQueues *updatedRefsQueue_; 88 }; 89 } // namespace panda::mem 90 91 #endif 92