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