* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMASCRIPT_MEM_SLOTS_H
#define ECMASCRIPT_MEM_SLOTS_H
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/mem/mem.h"
namespace panda::ecmascript {
enum class SlotStatus : bool {
KEEP_SLOT,
CLEAR_SLOT,
};
class ObjectSlot {
public:
explicit ObjectSlot(uintptr_t slotAddr) : slotAddress_(slotAddr) {}
ObjectSlot() : ObjectSlot(0) {}
~ObjectSlot() = default;
DEFAULT_COPY_SEMANTIC(ObjectSlot);
DEFAULT_MOVE_SEMANTIC(ObjectSlot);
void Update(TaggedObject *header)
{
Update(static_cast<JSTaggedType>(ToUintPtr(header)));
}
uintptr_t* GetRefFieldAddr()
{
return reinterpret_cast<uintptr_t*>(slotAddress_);
}
void Update(JSTaggedType value)
{
*reinterpret_cast<JSTaggedType *>(slotAddress_) = value;
}
void UpdateWeak(uintptr_t value)
{
*reinterpret_cast<JSTaggedType *>(slotAddress_) = value | JSTaggedValue::TAG_WEAK;
}
void CASUpdate(TaggedObject *oldObject, TaggedObject *toRef)
{
std::atomic_compare_exchange_strong_explicit(
reinterpret_cast<volatile std::atomic<TaggedObject*> *>(slotAddress_),
&oldObject, toRef, std::memory_order_relaxed, std::memory_order_relaxed);
}
void Clear()
{
*reinterpret_cast<JSTaggedType *>(slotAddress_) = JSTaggedValue::VALUE_UNDEFINED;
}
TaggedObject *GetTaggedObject() const
{
return reinterpret_cast<TaggedObject *>(GetTaggedType());
}
JSTaggedType GetTaggedType() const
{
return *reinterpret_cast<JSTaggedType *>(slotAddress_);
}
JSTaggedValue GetTaggedValue() const
{
return *reinterpret_cast<JSTaggedValue *>(slotAddress_);
}
ObjectSlot &operator++()
{
slotAddress_ += sizeof(JSTaggedType);
return *this;
}
ObjectSlot operator++(int)
{
ObjectSlot ret = *this;
slotAddress_ += sizeof(JSTaggedType);
return ret;
}
ObjectSlot operator+=(size_t length)
{
ObjectSlot ret = *this;
slotAddress_ += sizeof(JSTaggedType) * length;
return ret;
}
uintptr_t SlotAddress() const
{
return slotAddress_;
}
bool operator<(const ObjectSlot &other) const
{
return slotAddress_ < other.slotAddress_;
}
bool operator<=(const ObjectSlot &other) const
{
return slotAddress_ <= other.slotAddress_;
}
bool operator>(const ObjectSlot &other) const
{
return slotAddress_ > other.slotAddress_;
}
bool operator>=(const ObjectSlot &other) const
{
return slotAddress_ >= other.slotAddress_;
}
bool operator==(const ObjectSlot &other) const
{
return slotAddress_ == other.slotAddress_;
}
bool operator!=(const ObjectSlot &other) const
{
return slotAddress_ != other.slotAddress_;
}
private:
uintptr_t slotAddress_;
};
}
#endif