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 "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 explicit 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 UNUSED_BIT_NUMBER = 9; // unused bit number 52 static constexpr int IS_REFERENCE_BIT_NUMBER = 16; // [0x0000] is reference 53 54 using RegionIndexBits = BitField<size_t, 0, REGION_INDEX_BIT_NUMBER>; 55 using ObjectOffsetInRegionBits = RegionIndexBits::NextField<size_t, OBJECT_OFFSET_IN_REGION_NUMBER>; 56 using ObjectToStringBits = ObjectOffsetInRegionBits::NextField<bool, OBJECT_TO_STRING_FLAG_NUMBER>; 57 using ObjectTypeBits = ObjectToStringBits::NextField<size_t, OBJECT_TYPE_BIT_NUMBER>; 58 using ObjectSpecialBits = ObjectTypeBits::NextField<bool, OBJECT_SPECIAL>; 59 using GlobalConstOrBuiltinsBits = ObjectSpecialBits::NextField<bool, GLOBAL_CONST_OR_BUILTINS>; 60 using UnusedBits = GlobalConstOrBuiltinsBits::NextField<size_t, UNUSED_BIT_NUMBER>; 61 using IsReferenceBits = UnusedBits::NextField<size_t, IS_REFERENCE_BIT_NUMBER>; 62 SetRegionIndex(size_t region_index)63 void SetRegionIndex(size_t region_index) 64 { 65 RegionIndexBits::Set<uint64_t>(region_index, &value_); 66 } 67 SetObjectOffsetInRegion(size_t object_offset)68 void SetObjectOffsetInRegion(size_t object_offset) 69 { 70 ObjectOffsetInRegionBits::Set<uint64_t>(object_offset, &value_); 71 } 72 SetReferenceToString(bool flag)73 void SetReferenceToString(bool flag) 74 { 75 ObjectToStringBits::Set<uint64_t>(flag, &value_); 76 } 77 IsReferenceToString()78 bool IsReferenceToString() const 79 { 80 return ObjectToStringBits::Decode(value_); 81 } 82 SetObjectType(size_t object_type)83 void SetObjectType(size_t object_type) 84 { 85 ObjectTypeBits::Set<uint64_t>(object_type, &value_); 86 } 87 GetValue()88 uint64_t GetValue() const 89 { 90 return value_; 91 } 92 GetRegionIndex()93 size_t GetRegionIndex() const 94 { 95 return RegionIndexBits::Decode(value_); 96 } 97 GetObjectOffsetInRegion()98 size_t GetObjectOffsetInRegion() const 99 { 100 return ObjectOffsetInRegionBits::Decode(value_); 101 } 102 GetNativePointerOrObjectIndex()103 size_t GetNativePointerOrObjectIndex() const 104 { 105 return (ObjectOffsetInRegionBits::Decode(value_) << REGION_INDEX_BIT_NUMBER) + RegionIndexBits::Decode(value_); 106 } 107 GetObjectType()108 size_t GetObjectType() const 109 { 110 return ObjectTypeBits::Decode(value_); 111 } 112 IsReference()113 bool IsReference() const 114 { 115 return IsReferenceBits::Decode(value_) == 0; 116 } 117 IsSpecial()118 bool IsSpecial() const 119 { 120 return ObjectSpecialBits::Decode(value_); 121 } 122 SetObjectSpecial()123 void SetObjectSpecial() 124 { 125 ObjectSpecialBits::Set<uint64_t>(true, &value_); 126 } 127 IsGlobalConstOrBuiltins()128 bool IsGlobalConstOrBuiltins() const 129 { 130 return GlobalConstOrBuiltinsBits::Decode(value_); 131 } 132 SetGlobalConstOrBuiltins()133 void SetGlobalConstOrBuiltins() 134 { 135 GlobalConstOrBuiltinsBits::Set<uint64_t>(true, &value_); 136 } 137 138 // low 28 bits are used to record object location(region index and object offset), besides, it's 139 // used to record string index, global const and builtins object index, native pointer index SetNativePointerOrObjectIndex(size_t index)140 void SetNativePointerOrObjectIndex(size_t index) 141 { 142 ASSERT(index < Constants::MAX_OBJECT_INDEX); 143 ObjectOffsetInRegionBits::Set<uint64_t>(index >> REGION_INDEX_BIT_NUMBER, &value_); 144 RegionIndexBits::Set<uint64_t>(index & Constants::REGION_INDEX_MASK, &value_); 145 } 146 ClearObjectSpecialFlag()147 void ClearObjectSpecialFlag() 148 { 149 ObjectSpecialBits::Set<uint64_t>(false, &value_); 150 } 151 152 private: 153 uint64_t value_; 154 }; 155 static_assert(EncodeBit::REGION_INDEX_BIT_NUMBER + EncodeBit::OBJECT_OFFSET_IN_REGION_NUMBER + 156 EncodeBit::OBJECT_TO_STRING_FLAG_NUMBER + EncodeBit::OBJECT_TYPE_BIT_NUMBER + EncodeBit::OBJECT_SPECIAL + 157 EncodeBit::GLOBAL_CONST_OR_BUILTINS + EncodeBit::UNUSED_BIT_NUMBER + 158 EncodeBit::IS_REFERENCE_BIT_NUMBER == Constants::UINT_64_BITS_COUNT); 159 } // namespace panda::ecmascript 160 161 #endif // ECMASCRIPT_SNAPSHOT_MEM_ENCODE_BIT_H 162