1 /* 2 * Copyright (c) 2024 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_SERIALIZER_SERIALIZATION_CHUNK_H 17 #define ECMASCRIPT_SERIALIZER_SERIALIZATION_CHUNK_H 18 19 #include "ecmascript/js_tagged_value-inl.h" 20 #include "ecmascript/mem/mem.h" 21 22 namespace panda::ecmascript { 23 24 class SerializationChunk { 25 public: SerializationChunk()26 explicit SerializationChunk() {} ~SerializationChunk()27 ~SerializationChunk() 28 { 29 if (begin_ != 0U) { 30 free(ToVoidPtr(begin_)); 31 } 32 } 33 NO_COPY_SEMANTIC(SerializationChunk); 34 NO_MOVE_SEMANTIC(SerializationChunk); 35 Emplace(JSTaggedType value)36 void Emplace(JSTaggedType value) 37 { 38 if (top_ == end_) { 39 Expand(); 40 } 41 ASSERT(top_ < end_); 42 *reinterpret_cast<JSTaggedType *>(top_) = value; 43 top_ += JSTaggedValue::TaggedTypeSize(); 44 } 45 Get(size_t index)46 JSTaggedType Get(size_t index) const 47 { 48 ASSERT(begin_ + index * JSTaggedValue::TaggedTypeSize() < top_); 49 return *reinterpret_cast<JSTaggedType *>(begin_ + index * JSTaggedValue::TaggedTypeSize()); 50 } 51 Expand()52 void Expand() 53 { 54 ASSERT(top_ == end_); 55 size_t oldCapacity = end_ - begin_; 56 size_t newCapacity = 0; 57 if (oldCapacity == 0U) { 58 newCapacity = INITIAL_CHUNK_CAPACITY; 59 } else { 60 newCapacity = (end_ - begin_) * CHUNK_CAPACITY_INCREASE_RATE; 61 } 62 void *newChunk = malloc(newCapacity); 63 if (newChunk == nullptr) { 64 LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << newCapacity; 65 UNREACHABLE(); 66 } 67 68 if (begin_ != 0U) { 69 if (memcpy_s(newChunk, newCapacity, ToVoidPtr(begin_), end_ - begin_) != EOK) { 70 LOG_FULL(FATAL) << "memcpy_s fail"; 71 } 72 free(ToVoidPtr(begin_)); 73 } 74 begin_ = ToUintPtr(newChunk); 75 top_ = begin_ + oldCapacity; 76 end_ = begin_ + newCapacity; 77 } 78 Empty()79 bool Empty() const 80 { 81 return top_ == begin_; 82 } 83 Size()84 size_t Size() const 85 { 86 return (top_ - begin_) / JSTaggedValue::TaggedTypeSize(); 87 } 88 Iterate(const RootVisitor & v)89 void Iterate(const RootVisitor &v) 90 { 91 for (uintptr_t slot = begin_; slot < top_; slot += JSTaggedValue::TaggedTypeSize()) { 92 v(Root::ROOT_VM, ObjectSlot(slot)); 93 } 94 } 95 96 private: 97 static constexpr size_t INITIAL_CHUNK_CAPACITY = 1_KB; 98 static constexpr int CHUNK_CAPACITY_INCREASE_RATE = 2; 99 uintptr_t begin_ {0U}; 100 uintptr_t end_ {0U}; 101 uintptr_t top_ {0U}; 102 }; 103 } 104 105 #endif // ECMASCRIPT_SERIALIZER_SERIALIZE_DATA_H 106