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 #ifndef ECMASCRIPT_FREE_OBJECT_H 17 #define ECMASCRIPT_FREE_OBJECT_H 18 19 #include "ecmascript/js_hclass.h" 20 #include "ecmascript/mem/barriers.h" 21 #include "ecmascript/mem/tagged_object-inl.h" 22 23 #define INVALID_OBJECT ((FreeObject *) JSTaggedValue::NULL_POINTER) 24 25 namespace panda::ecmascript { 26 class FreeObject : public TaggedObject { 27 public: Cast(uintptr_t object)28 static FreeObject *Cast(uintptr_t object) 29 { 30 return reinterpret_cast<FreeObject *>(object); 31 } 32 static FreeObject *FillFreeObject(EcmaVM *vm, uintptr_t address, size_t size); 33 IsEmpty()34 inline bool IsEmpty() const 35 { 36 return Available() == 0; 37 } 38 GetBegin()39 inline uintptr_t GetBegin() const 40 { 41 return reinterpret_cast<uintptr_t>(this); 42 } 43 GetEnd()44 inline uintptr_t GetEnd() const 45 { 46 return reinterpret_cast<uintptr_t>(this) + Available(); 47 } 48 SetAvailable(uint32_t size)49 inline void SetAvailable(uint32_t size) 50 { 51 if (size >= SIZE) { 52 Barriers::SetPrimitive<JSTaggedType>(this, SIZE_OFFSET, JSTaggedValue(size).GetRawData()); 53 } 54 } 55 Available()56 inline uint32_t Available() const 57 { 58 auto hclass = GetClass(); 59 if (hclass->IsFreeObjectWithShortField()) { 60 return hclass->GetObjectSize(); 61 } 62 ASSERT(GetSize().IsInt()); 63 return GetSize().GetInt(); 64 } 65 IsFreeObject()66 inline bool IsFreeObject() const 67 { 68 return GetClass()->IsFreeObject(); 69 } 70 71 // Before operating any freeobject, need to mark unpoison when is_asan is true. AsanUnPoisonFreeObject()72 inline void AsanUnPoisonFreeObject() const 73 { 74 #ifdef ARK_ASAN_ON 75 ASAN_UNPOISON_MEMORY_REGION(this, NEXT_OFFSET); 76 if (GetClass()->IsFreeObjectWithOneField()) { 77 ASAN_UNPOISON_MEMORY_REGION(this, SIZE_OFFSET); 78 } else if (GetClass()->IsFreeObjectWithTwoField()) { 79 ASAN_UNPOISON_MEMORY_REGION(this, SIZE); 80 } 81 #endif 82 } 83 84 // After operating any freeobject, need to marked poison again when is_asan is true AsanPoisonFreeObject()85 inline void AsanPoisonFreeObject() const 86 { 87 #ifdef ARK_ASAN_ON 88 if (GetClass()->IsFreeObjectWithNoneField()) { 89 ASAN_POISON_MEMORY_REGION(this, NEXT_OFFSET); 90 } else if (GetClass()->IsFreeObjectWithOneField()) { 91 ASAN_POISON_MEMORY_REGION(this, SIZE_OFFSET); 92 } else if (GetClass()->IsFreeObjectWithTwoField()) { 93 ASAN_POISON_MEMORY_REGION(this, SIZE); 94 } 95 #endif 96 } 97 98 static constexpr size_t NEXT_OFFSET = TaggedObjectSize(); 99 ACCESSORS_FIXED_SIZE_FIELD(Next, FreeObject *, JSTaggedType, NEXT_OFFSET, SIZE_OFFSET) 100 // TaggedArray visitor may be error while concurrent marking 101 ACCESSORS(Size, SIZE_OFFSET, SIZE) 102 }; 103 104 static_assert((FreeObject::SIZE % static_cast<uint8_t>(MemAlignment::MEM_ALIGN_OBJECT)) == 0); 105 } // namespace panda::ecmascript 106 107 #endif // ECMASCRIPT_MEM_FREE_OBJECT_H 108