1 /* 2 * Copyright (c) 2021 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 16 #include "ecmascript/mem/free_object_set.h" 17 18 #include "ecmascript/base/asan_interface.h" 19 #include "ecmascript/free_object.h" 20 #include "ecmascript/mem/free_object_list.h" 21 22 namespace panda::ecmascript { Free(uintptr_t begin,size_t size)23void FreeObjectSet::Free(uintptr_t begin, size_t size) 24 { 25 auto freeObject = FreeObject::Cast(begin); 26 ASSERT(freeObject->IsFreeObject()); 27 freeObject->SetNext(freeObject_); 28 freeObject_ = freeObject; 29 available_ += size; 30 } 31 Rebuild()32void FreeObjectSet::Rebuild() 33 { 34 freeObject_ = INVALID_OBJECT; 35 available_ = 0; 36 isAdded_ = false; 37 next_ = nullptr; 38 prev_ = nullptr; 39 } 40 ObtainSmallFreeObject(size_t size)41FreeObject *FreeObjectSet::ObtainSmallFreeObject(size_t size) 42 { 43 FreeObject *curFreeObject = INVALID_OBJECT; 44 if (freeObject_ != INVALID_OBJECT) { 45 freeObject_->AsanUnPoisonFreeObject(); 46 if (freeObject_->Available() >= size) { 47 curFreeObject = freeObject_; 48 freeObject_ = freeObject_->GetNext(); 49 curFreeObject->SetNext(INVALID_OBJECT); 50 available_ -= curFreeObject->Available(); 51 // It need to mark unpoison when object being allocated in freelist. 52 ASAN_UNPOISON_MEMORY_REGION(curFreeObject, curFreeObject->Available()); 53 } else { 54 freeObject_->AsanPoisonFreeObject(); 55 } 56 } 57 return curFreeObject; 58 } 59 ObtainLargeFreeObject(size_t size)60FreeObject *FreeObjectSet::ObtainLargeFreeObject(size_t size) 61 { 62 FreeObject *prevFreeObject = freeObject_; 63 FreeObject *curFreeObject = freeObject_; 64 while (curFreeObject != INVALID_OBJECT) { 65 curFreeObject->AsanUnPoisonFreeObject(); 66 if (curFreeObject->Available() >= size) { 67 if (curFreeObject == freeObject_) { 68 freeObject_ = curFreeObject->GetNext(); 69 } else { 70 prevFreeObject->SetNext(curFreeObject->GetNext()); 71 prevFreeObject->AsanPoisonFreeObject(); 72 } 73 curFreeObject->SetNext(INVALID_OBJECT); 74 available_ -= curFreeObject->Available(); 75 ASAN_UNPOISON_MEMORY_REGION(curFreeObject, curFreeObject->Available()); 76 return curFreeObject; 77 } 78 if (prevFreeObject != curFreeObject) { 79 prevFreeObject->AsanPoisonFreeObject(); 80 } 81 prevFreeObject = curFreeObject; 82 curFreeObject = curFreeObject->GetNext(); 83 } 84 return INVALID_OBJECT; 85 } 86 LookupSmallFreeObject(size_t size)87FreeObject *FreeObjectSet::LookupSmallFreeObject(size_t size) 88 { 89 if (freeObject_ != INVALID_OBJECT) { 90 freeObject_->AsanUnPoisonFreeObject(); 91 if (freeObject_->Available() >= size) { 92 freeObject_->AsanPoisonFreeObject(); 93 return freeObject_; 94 } 95 freeObject_->AsanPoisonFreeObject(); 96 } 97 return INVALID_OBJECT; 98 } 99 LookupLargeFreeObject(size_t size)100FreeObject *FreeObjectSet::LookupLargeFreeObject(size_t size) 101 { 102 if (available_ < size) { 103 return INVALID_OBJECT; 104 } 105 FreeObject *curFreeObject = freeObject_; 106 while (curFreeObject != INVALID_OBJECT) { 107 curFreeObject->AsanUnPoisonFreeObject(); 108 if (curFreeObject->Available() >= size) { 109 curFreeObject->AsanPoisonFreeObject(); 110 return curFreeObject; 111 } 112 FreeObject *preFreeObject = curFreeObject; 113 curFreeObject = curFreeObject->GetNext(); 114 preFreeObject->AsanPoisonFreeObject(); 115 } 116 return INVALID_OBJECT; 117 } 118 } // namespace panda::ecmascript 119