• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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