• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)23 void 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()32 void 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)41 FreeObject *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)60 FreeObject *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)87 FreeObject *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)100 FreeObject *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