• 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 
Set(size_t index,JSTaggedType value)46     void Set(size_t index, JSTaggedType value)
47     {
48         ASSERT(begin_ + index * JSTaggedValue::TaggedTypeSize() < top_);
49         *reinterpret_cast<JSTaggedType *>(begin_ + index * JSTaggedValue::TaggedTypeSize()) = value;
50     }
51 
Get(size_t index)52     JSTaggedType Get(size_t index) const
53     {
54         ASSERT(begin_ + index * JSTaggedValue::TaggedTypeSize() < top_);
55         return *reinterpret_cast<JSTaggedType *>(begin_ + index * JSTaggedValue::TaggedTypeSize());
56     }
57 
Expand()58     void Expand()
59     {
60         ASSERT(top_ == end_);
61         size_t oldCapacity = end_ - begin_;
62         size_t newCapacity = 0;
63         if (oldCapacity == 0U) {
64             newCapacity = INITIAL_CHUNK_CAPACITY;
65         } else {
66             newCapacity = (end_ - begin_) * CHUNK_CAPACITY_INCREASE_RATE;
67         }
68         void *newChunk = malloc(newCapacity);
69         if (newChunk == nullptr) {
70             LOG_ECMA_MEM(FATAL) << "malloc failed, current alloc size = " << newCapacity;
71             UNREACHABLE();
72         }
73 
74         if (begin_ != 0U) {
75             if (memcpy_s(newChunk, newCapacity, ToVoidPtr(begin_), end_ - begin_) != EOK) {
76                 LOG_FULL(FATAL) << "memcpy_s fail";
77             }
78             free(ToVoidPtr(begin_));
79         }
80         begin_ = ToUintPtr(newChunk);
81         top_ = begin_ + oldCapacity;
82         end_ = begin_ + newCapacity;
83     }
84 
Empty()85     bool Empty() const
86     {
87         return top_ == begin_;
88     }
89 
Size()90     size_t Size() const
91     {
92         return (top_ - begin_) / JSTaggedValue::TaggedTypeSize();
93     }
94 
Iterate(RootVisitor & v)95     void Iterate(RootVisitor &v)
96     {
97         for (uintptr_t slot = begin_; slot < top_; slot += JSTaggedValue::TaggedTypeSize()) {
98             v.VisitRoot(Root::ROOT_VM, ObjectSlot(slot));
99         }
100     }
101 
102 private:
103     static constexpr size_t INITIAL_CHUNK_CAPACITY = 1_KB;
104     static constexpr int CHUNK_CAPACITY_INCREASE_RATE = 2;
105     uintptr_t begin_ {0U};
106     uintptr_t end_ {0U};
107     uintptr_t top_ {0U};
108 };
109 }
110 
111 #endif  // ECMASCRIPT_SERIALIZER_SERIALIZE_DATA_H
112