1 /* 2 * Copyright (c) 2021-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_TAGGED_OBJECT_STATE_WORD_H 17 #define ECMASCRIPT_TAGGED_OBJECT_STATE_WORD_H 18 19 #include "common_interfaces/base/common.h" 20 #include "common_interfaces/objects/base_state_word.h" 21 #include <atomic> 22 23 using ClassWordType = uint64_t; 24 25 namespace panda::ecmascript { 26 class TaggedObject; 27 28 class TaggedStateWord { 29 public: 30 static constexpr size_t ADDRESS_WIDTH = 48; 31 static constexpr uint64_t ADDRESS_MASK = (0x1ULL << ADDRESS_WIDTH) - 1; 32 33 // Little endian 34 struct GCStateWord { 35 common::StateWordType address_ : ADDRESS_WIDTH; 36 common::StateWordType padding_ : 12; 37 common::StateWordType remainded_ : 4; 38 }; 39 40 struct ClassStateWord { 41 ClassWordType class_ : ADDRESS_WIDTH; 42 ClassWordType padding_ : 12; 43 ClassWordType remainded_ : 4; 44 }; 45 46 inline void SynchronizedSetGCStateWord(common::StateWordType address, common::StateWordType padding = 0, 47 common::StateWordType remainded = 0) 48 { 49 GCStateWord newState; 50 newState.address_ = address; 51 newState.padding_ = padding; 52 newState.remainded_ = remainded; 53 SynchronizedSetGCStateWord(newState); 54 } SetClass(ClassWordType cls)55 inline void SetClass(ClassWordType cls) 56 { 57 class_.class_ = cls; 58 } 59 SynchronizedSetClass(ClassWordType cls)60 inline void SynchronizedSetClass(ClassWordType cls) 61 { 62 reinterpret_cast<volatile std::atomic<uint32_t> *>(&class_)->store( 63 static_cast<uint32_t>(cls), std::memory_order_release); 64 } 65 GetClass()66 inline uintptr_t GetClass() const 67 { 68 return static_cast<uintptr_t>(class_.class_); 69 } 70 SynchronizedGetClass()71 inline uintptr_t SynchronizedGetClass() const 72 { 73 return static_cast<uintptr_t>( 74 reinterpret_cast<volatile std::atomic<uint32_t> *>(reinterpret_cast<uintptr_t>(&class_)) 75 ->load(std::memory_order_acquire)) + 76 BASE_ADDRESS; 77 } 78 SetForwardingAddress(uintptr_t fwdPtr)79 inline void SetForwardingAddress(uintptr_t fwdPtr) 80 { 81 state_.address_ = fwdPtr; 82 } 83 GetForwardingAddress()84 inline uintptr_t GetForwardingAddress() const 85 { 86 return state_.address_; 87 } 88 89 static constexpr int STATE_WORD_OFFSET = sizeof(ClassWordType); 90 static PUBLIC_API uintptr_t BASE_ADDRESS; 91 92 private: SynchronizedSetGCStateWord(GCStateWord state)93 inline void SynchronizedSetGCStateWord(GCStateWord state) 94 { 95 reinterpret_cast<volatile std::atomic<GCStateWord> *>(&state_)->store(state, std::memory_order_release); 96 } 97 98 union { 99 GCStateWord state_; 100 ClassStateWord class_; 101 }; 102 103 friend class TaggedObject; 104 }; 105 static_assert(sizeof(TaggedStateWord) == sizeof(uint64_t), "Excepts 8 bytes"); 106 static_assert(common::BaseStateWord::PADDING_WIDTH == 60, "Excepts 60 bits"); 107 static_assert(common::BaseStateWord::FORWARD_WIDTH == 2, "Excepts 2 bits"); 108 static_assert(common::BaseStateWord::LANGUAGE_WIDTH == 2, "Excepts 2 bits"); 109 } // namespace panda::ecmascript 110 #endif // ECMASCRIPT_TAGGED_OBJECT_STATE_WORD_H 111