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_SNAPSHOT_MEM_ENCODE_BIT_H
17 #define ECMASCRIPT_SNAPSHOT_MEM_ENCODE_BIT_H
18 
19 #include "ecmascript/mem/c_containers.h"
20 #include "ecmascript/mem/slots.h"
21 #include "ecmascript/snapshot/mem/constants.h"
22 
23 #include "libpandabase/utils/bit_field.h"
24 
25 /*
26  *                        EncodeBit: use uint64_t value to encode TaggedObject when serialize
27  *
28  *  |0000...000|  |0000...00| |0|    |0|       |0|    |00000000|  |0|     |0000...000|   |00...0|
29  *     16bit         8bit    1bit   1bit      1bit      8bit     1bit         18bit       10bit
30  *  is reference    unused   weak  builtins  special  obj type   string   obj offset    region index
31  */
32 
33 namespace panda::ecmascript {
34 class EncodeBit final {
35 public:
36     ~EncodeBit() = default;
37     EncodeBit() = delete;
38 
39     DEFAULT_COPY_SEMANTIC(EncodeBit);
40     DEFAULT_MOVE_SEMANTIC(EncodeBit);
41 
EncodeBit(uint64_t value)42     explicit EncodeBit(uint64_t value) : value_(value) {}
43 
44     // encode bit
45     static constexpr int REGION_INDEX_BIT_NUMBER = 10;         // region index
46     static constexpr int OBJECT_OFFSET_IN_REGION_NUMBER = 18;  // object offset in current region
47     static constexpr int OBJECT_TO_STRING_FLAG_NUMBER = 1;     // 1 : reference to string
48     static constexpr int OBJECT_TYPE_BIT_NUMBER = 8;           // js_type
49     static constexpr int OBJECT_SPECIAL = 1;                   // special
50     static constexpr int GLOBAL_CONST_OR_BUILTINS = 1;         // is global const or builtins object
51     static constexpr int TS_WEAK_OBJECT = 1;                   // weak objects generated by AOT, e.g. TSHClass
52     static constexpr int UNUSED_BIT_NUMBER = 8;                // unused bit number
53     static constexpr int IS_REFERENCE_BIT_NUMBER = 16;         // [0x0000] is reference
54 
55     using RegionIndexBits = BitField<size_t, 0, REGION_INDEX_BIT_NUMBER>;
56     using ObjectOffsetInRegionBits = RegionIndexBits::NextField<size_t, OBJECT_OFFSET_IN_REGION_NUMBER>;
57     using ObjectToStringBits = ObjectOffsetInRegionBits::NextField<bool, OBJECT_TO_STRING_FLAG_NUMBER>;
58     using ObjectTypeBits = ObjectToStringBits::NextField<size_t, OBJECT_TYPE_BIT_NUMBER>;
59     using ObjectSpecialBits = ObjectTypeBits::NextField<bool, OBJECT_SPECIAL>;
60     using GlobalConstOrBuiltinsBits = ObjectSpecialBits::NextField<bool, GLOBAL_CONST_OR_BUILTINS>;
61     using TSWeakObjectBits = GlobalConstOrBuiltinsBits::NextField<bool, TS_WEAK_OBJECT>;
62     using UnusedBits = TSWeakObjectBits::NextField<size_t, UNUSED_BIT_NUMBER>;
63     using IsReferenceBits = UnusedBits::NextField<size_t, IS_REFERENCE_BIT_NUMBER>;
64 
SetRegionIndex(size_t region_index)65     void SetRegionIndex(size_t region_index)
66     {
67         RegionIndexBits::Set<uint64_t>(region_index, &value_);
68     }
69 
SetObjectOffsetInRegion(size_t object_offset)70     void SetObjectOffsetInRegion(size_t object_offset)
71     {
72         ObjectOffsetInRegionBits::Set<uint64_t>(object_offset, &value_);
73     }
74 
SetReferenceToString(bool flag)75     void SetReferenceToString(bool flag)
76     {
77         ObjectToStringBits::Set<uint64_t>(flag, &value_);
78     }
79 
IsReferenceToString() const80     bool IsReferenceToString() const
81     {
82         return ObjectToStringBits::Decode(value_);
83     }
84 
SetObjectType(size_t object_type)85     void SetObjectType(size_t object_type)
86     {
87         ObjectTypeBits::Set<uint64_t>(object_type, &value_);
88     }
89 
GetValue() const90     uint64_t GetValue() const
91     {
92         return value_;
93     }
94 
GetRegionIndex() const95     size_t GetRegionIndex() const
96     {
97         return RegionIndexBits::Decode(value_);
98     }
99 
GetObjectOffsetInRegion() const100     size_t GetObjectOffsetInRegion() const
101     {
102         return ObjectOffsetInRegionBits::Decode(value_);
103     }
104 
GetNativePointerOrObjectIndex() const105     size_t GetNativePointerOrObjectIndex() const
106     {
107         return (ObjectOffsetInRegionBits::Decode(value_) << REGION_INDEX_BIT_NUMBER) + RegionIndexBits::Decode(value_);
108     }
109 
GetObjectType() const110     size_t GetObjectType() const
111     {
112         return ObjectTypeBits::Decode(value_);
113     }
114 
IsReference() const115     bool IsReference() const
116     {
117         return IsReferenceBits::Decode(value_) == 0;
118     }
119 
IsSpecial() const120     bool IsSpecial() const
121     {
122         return ObjectSpecialBits::Decode(value_);
123     }
124 
SetObjectSpecial()125     void SetObjectSpecial()
126     {
127         ObjectSpecialBits::Set<uint64_t>(true, &value_);
128     }
129 
IsGlobalConstOrBuiltins() const130     bool IsGlobalConstOrBuiltins() const
131     {
132         return GlobalConstOrBuiltinsBits::Decode(value_);
133     }
134 
SetGlobalConstOrBuiltins()135     void SetGlobalConstOrBuiltins()
136     {
137         GlobalConstOrBuiltinsBits::Set<uint64_t>(true, &value_);
138     }
139 
IsTSWeakObject() const140     bool IsTSWeakObject() const
141     {
142         return TSWeakObjectBits::Decode(value_);
143     }
144 
SetTSWeakObject()145     void SetTSWeakObject()
146     {
147         TSWeakObjectBits::Set<uint64_t>(true, &value_);
148     }
149 
150     // low 28 bits are used to record object location(region index and object offset), besides, it's
151     // used to record string index, global const and builtins object index, native pointer index
SetNativePointerOrObjectIndex(size_t index)152     void SetNativePointerOrObjectIndex(size_t index)
153     {
154         ASSERT(index < Constants::MAX_OBJECT_INDEX);
155         ObjectOffsetInRegionBits::Set<uint64_t>(index >> REGION_INDEX_BIT_NUMBER, &value_);
156         RegionIndexBits::Set<uint64_t>(index & Constants::REGION_INDEX_MASK, &value_);
157     }
158 
ClearObjectSpecialFlag()159     void ClearObjectSpecialFlag()
160     {
161         ObjectSpecialBits::Set<uint64_t>(false, &value_);
162     }
163 
164 private:
165     uint64_t value_;
166 };
167 static_assert(EncodeBit::REGION_INDEX_BIT_NUMBER + EncodeBit::OBJECT_OFFSET_IN_REGION_NUMBER +
168               EncodeBit::OBJECT_TO_STRING_FLAG_NUMBER + EncodeBit::OBJECT_TYPE_BIT_NUMBER + EncodeBit::OBJECT_SPECIAL +
169               EncodeBit::GLOBAL_CONST_OR_BUILTINS + EncodeBit::TS_WEAK_OBJECT + EncodeBit::UNUSED_BIT_NUMBER +
170               EncodeBit::IS_REFERENCE_BIT_NUMBER == Constants::UINT_64_BITS_COUNT);
171 }  // namespace panda::ecmascript
172 
173 #endif  // ECMASCRIPT_SNAPSHOT_MEM_ENCODE_BIT_H
174