1 /** 2 * Copyright (c) 2024-2025 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 PLUGINS_ETS_RUNTIME_ETS_MARK_WORD_H 17 #define PLUGINS_ETS_RUNTIME_ETS_MARK_WORD_H 18 19 #include <cstdint> 20 21 #include "libpandabase/macros.h" 22 #include "runtime/mark_word.h" 23 #include "plugins/ets/runtime/ets_object_state_info.h" 24 25 namespace ark::ets { 26 27 class EtsObject; 28 29 // 64 bits ets object header for high-end devices: (32 bits pointer) 30 // |--------------------------------------------------------------------------------------|--------------------| 31 // | Object Header (64 bits) | State | 32 // |--------------------------------------------------------------------------------------|--------------------| 33 // | Mark Word (32 bits) | Class Word (32 bits) | | 34 // |--------------------------------------------------------------------------------------|--------------------| 35 // | state:00 | RB:1 | GC:1 | nothing:28 | OOP to metadata object | Unlock | 36 // |----------|---------------------------------------------------------------------------|--------------------| 37 // | state:01 | RB:1 | GC:1 | Info:28 | OOP to metadata object | Use Info | 38 // |----------|---------------------------------------------------------------------------|--------------------| 39 // | state:10 | RB:1 | GC:1 | I:1 | Hash:27 | OOP to metadata object | EtsHashed | 40 // |----------|---------------------------------------------------------------------------|--------------------| 41 // | state:10 | RB:1 | GC:1 | I:1 | InteropIndex:27 | OOP to metadata object | HasInteropIndex | 42 // |--------------------------------------------------------------------------------------|--------------------| 43 // | state:11 | Forwarding address:30 | OOP to metadata object | GC | 44 // |--------------------------------------------------------------------------------------|--------------------| 45 // 46 // It is similar to mark word object header except Hash and InteropIndex states. 47 // `I` - bit that indicate usage of InteropIndex, 1 - HashInteropIndex, 0 - EtsHashed 48 // 49 class EtsMarkWord : private MarkWord { 50 public: 51 // EtsMarkWord implement specific logic of HASH usage 52 // Big enum 53 enum EtsMarkWordRepresentation : MarkWordSize { 54 INTEROP_INDEX_FLAG_SIZE = 1UL, 55 INTEROP_INDEX_SIZE = HASH_SIZE - INTEROP_INDEX_FLAG_SIZE, 56 HASH_SIZE = HASH_SIZE - INTEROP_INDEX_FLAG_SIZE, 57 58 HASH_STATE_ETS_HASH = 0, 59 HASH_STATE_INTEROP_INDEX = 1, 60 61 HASH_STATE_SHIFT = HASH_SIZE, 62 63 INTEROP_INDEX_FLAG_SHIFT = HASH_SIZE, 64 INTEROP_INDEX_FLAG_MASK = (1UL << INTEROP_INDEX_FLAG_SIZE) - 1UL, 65 66 // Interop index state masks and shifts 67 INTEROP_INDEX_SHIFT = 0U, 68 INTEROP_INDEX_MASK = (1UL << INTEROP_INDEX_SIZE) - 1UL, 69 INTEROP_INDEX_MASK_IN_PLACE = INTEROP_INDEX_MASK << INTEROP_INDEX_SHIFT, 70 71 // Ets Hash state 72 HASH_SHIFT = 0U, 73 HASH_MASK = (1UL << HASH_SIZE) - 1UL, 74 HASH_MASK_IN_PLACE = HASH_MASK << HASH_SHIFT, 75 76 INFO_TABLE_POINTER_SHIFT = MONITOR_POINTER_SHIFT, 77 INFO_TABLE_POINTER_MASK = MONITOR_POINTER_MASK, 78 INFO_TABLE_POINTER_MASK_IN_PLACE = MONITOR_POINTER_MASK_IN_PLACE, 79 INFO_TABLE_POINTER_MAX_COUNT = MONITOR_POINTER_MAX_COUNT, 80 }; 81 82 enum EtsObjectState { 83 STATE_UNLOCKED = MarkWord::STATE_UNLOCKED, 84 UNUSED_STATE_STATE_LIGHT_LOCKED = MarkWord::STATE_LIGHT_LOCKED, 85 STATE_USE_INFO = MarkWord::STATE_HEAVY_LOCKED, 86 STATE_HASHED = MarkWord::STATE_HASHED, 87 STATE_GC = MarkWord::STATE_GC, 88 STATE_HAS_INTEROP_INDEX = STATE_GC + 1, 89 }; 90 91 // MarkWord specific methods 92 // Value of Mark Word GetValue()93 MarkWordSize GetValue() const 94 { 95 return MarkWord::GetValue(); 96 } 97 98 // For GC bit IsMarkedForGC()99 bool IsMarkedForGC() const 100 { 101 return MarkWord::IsMarkedForGC(); 102 }; 103 SetMarkedForGC()104 EtsMarkWord SetMarkedForGC() 105 { 106 return EtsMarkWord(MarkWord::SetMarkedForGC()); 107 }; 108 SetUnMarkedForGC()109 EtsMarkWord SetUnMarkedForGC() 110 { 111 return EtsMarkWord(MarkWord::SetUnMarkedForGC()); 112 } 113 114 // For read barrier bit IsReadBarrierSet()115 bool IsReadBarrierSet() const 116 { 117 return MarkWord::IsReadBarrierSet(); 118 } 119 SetReadBarrier()120 EtsMarkWord SetReadBarrier() 121 { 122 return EtsMarkWord(MarkWord::SetReadBarrier()); 123 } 124 ClearReadBarrier()125 EtsMarkWord ClearReadBarrier() 126 { 127 return EtsMarkWord(MarkWord::ClearReadBarrier()); 128 } 129 130 // For Info state state GetInfoId()131 EtsObjectStateInfo::Id GetInfoId() const 132 { 133 return static_cast<EtsObjectStateInfo::Id>(MarkWord::GetMonitorId()); 134 } 135 GetState()136 EtsObjectState GetState() const 137 { 138 auto state = MarkWord::GetState(); 139 if (state == MarkWord::STATE_HASHED) { 140 return GetStateBasedOnMarkHash(); 141 } 142 return static_cast<EtsObjectState>(state); 143 } 144 DecodeFromHash(uint32_t hash)145 EtsMarkWord DecodeFromHash(uint32_t hash) 146 { 147 return EtsMarkWord::FromMarkWord(MarkWord::DecodeFromHashWide(((hash & HASH_MASK) << HASH_SHIFT) | 148 (HASH_STATE_ETS_HASH << HASH_STATE_SHIFT))); 149 } 150 DecodeFromInteropIndex(uint32_t index)151 EtsMarkWord DecodeFromInteropIndex(uint32_t index) 152 { 153 return EtsMarkWord::FromMarkWord(MarkWord::DecodeFromHashWide( 154 ((index & INTEROP_INDEX_MASK) << INTEROP_INDEX_SHIFT) | (HASH_STATE_INTEROP_INDEX << HASH_STATE_SHIFT))); 155 } 156 DecodeFromInfo(EtsObjectStateInfo::Id id)157 EtsMarkWord DecodeFromInfo(EtsObjectStateInfo::Id id) 158 { 159 return EtsMarkWord(MarkWord::DecodeFromMonitor(static_cast<Monitor::MonitorId>(id))); 160 } 161 DecodeFromUnlocked()162 EtsMarkWord DecodeFromUnlocked() 163 { 164 return EtsMarkWord(MarkWord::DecodeFromUnlocked()); 165 } 166 GetHash()167 uint32_t GetHash() const 168 { 169 return (GetValue() >> HASH_SHIFT) & HASH_MASK; 170 } 171 GetInteropIndex()172 uint32_t GetInteropIndex() const 173 { 174 return (GetValue() >> INTEROP_INDEX_SHIFT) & INTEROP_INDEX_MASK; 175 } 176 177 private: GetStateBasedOnMarkHash()178 EtsObjectState GetStateBasedOnMarkHash() const 179 { 180 auto flag = (GetValue() >> INTEROP_INDEX_FLAG_SHIFT) & INTEROP_INDEX_FLAG_MASK; 181 return (flag != 0) ? STATE_HAS_INTEROP_INDEX : STATE_HASHED; 182 } 183 184 // Methods for MarkWord usage FromMarkWord(MarkWord word)185 static EtsMarkWord FromMarkWord(MarkWord word) 186 { 187 return *(const_cast<EtsMarkWord *>(reinterpret_cast<const EtsMarkWord *>(&word))); 188 } 189 ToMark()190 MarkWord ToMark() const 191 { 192 return *(const_cast<MarkWord *>(reinterpret_cast<const MarkWord *>(this))); 193 } 194 EtsMarkWord(const MarkWord & value)195 explicit EtsMarkWord(const MarkWord &value) : MarkWord(value) {} 196 197 friend EtsObject; 198 }; 199 200 static_assert(sizeof(EtsMarkWord) == sizeof(MarkWord)); 201 202 } // namespace ark::ets 203 204 #endif // PLUGINS_ETS_RUNTIME_ETS_MARK_WORD_H 205