* 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_BARRIERS_H
#define ECMASCRIPT_MEM_BARRIERS_H
#include "ecmascript/common.h"
#include "ecmascript/js_tagged_value.h"
#include "ecmascript/mem/mark_word.h"
#include "ecmascript/mem/mem_common.h"
#include "base_runtime.h"
#include "thread/mutator_base.h"
namespace panda::ecmascript {
class Region;
enum class WriteBarrierType : size_t { NORMAL, DESERIALIZE, AOT_DESERIALIZE };
class Barriers {
public:
template<class T>
static inline void SetPrimitive(void *obj, size_t offset, T value)
{
auto *addr = reinterpret_cast<T *>(ToUintPtr(obj) + offset);
*addr = value;
}
#ifdef ARK_USE_SATB_BARRIER
template<>
inline void SetPrimitive(void *obj, size_t offset, JSTaggedType value)
{
CMCWriteBarrier(nullptr, obj, offset, JSTaggedValue::Hole().GetRawData());
auto *addr = reinterpret_cast<JSTaggedType *>(ToUintPtr(obj) + offset);
*addr = value;
}
#endif
template<class T>
static inline T AtomicSetPrimitive(volatile void *obj, size_t offset, T oldValue, T value)
{
volatile auto atomicField = reinterpret_cast<volatile std::atomic<T> *>(ToUintPtr(obj) + offset);
std::atomic_compare_exchange_strong_explicit(atomicField, &oldValue, value, std::memory_order_release,
std::memory_order_relaxed);
return oldValue;
}
template<bool needWriteBarrier = true>
static void SetObject(const JSThread *thread, void *obj, size_t offset, JSTaggedType value);
static void PUBLIC_API CheckObjectForCMS(const JSThread *thread, void *obj, size_t offset, JSTaggedValue value,
bool writeBarrierCheck = false);
static void PUBLIC_API CheckValueForCMS(const JSThread *thread, JSTaggedValue value);
template <bool needWriteBarrier, bool maybeOverlap>
static void CopyObject(const JSThread *thread, const TaggedObject *dstObj, JSTaggedValue *dstAddr,
const JSTaggedValue *srcAddr, size_t count);
template<bool needReadBarrier, bool maybeOverlap>
static void CopyObjectPrimitive(const JSThread *thread, JSTaggedValue* dst, const JSTaggedValue* src,
size_t count);
static void SynchronizedSetObject(const JSThread *thread, void *obj, size_t offset, JSTaggedType value,
bool isPrimitive = false);
template<class T>
static inline T GetPrimitive(const void *obj, size_t offset)
{
auto *addr = reinterpret_cast<T *>(ToUintPtr(obj) + offset);
return *addr;
}
static JSTaggedType ReadBarrierForObject(const JSThread *thread, uintptr_t slotAddress);
static JSTaggedType ReadBarrierForStringTableSlot(JSTaggedType value);
static TaggedObject* GetTaggedObject(const JSThread *thread, const void* obj, size_t offset);
static JSTaggedType GetTaggedValue(const JSThread *thread, const void *obj, size_t offset);
static JSTaggedType GetTaggedValue(const JSThread *thread, uintptr_t slotAddress);
static JSTaggedType GetTaggedValueAtomic(const JSThread *thread, const void *obj, size_t offset);
static JSTaggedType UpdateSlot(const JSThread *thread, void *obj, size_t offset);
static JSTaggedType UpdateSlot(const JSThread *thread, uintptr_t slotAddress);
template <RBMode mode = RBMode::DEFAULT_RB>
static TaggedObject *GetTaggedObject(const JSThread *thread, const void *obj, size_t offset);
template <RBMode mode>
static JSTaggedType GetTaggedValue(const JSThread *thread, const void *obj, size_t offset);
template <RBMode mode>
static JSTaggedType GetTaggedValue(const JSThread *thread, uintptr_t slotAddress);
template <RBMode mode>
static JSTaggedType GetTaggedValueAtomic(const JSThread *thread, const void *obj, size_t offset);
static void PUBLIC_API Update(const JSThread *thread, uintptr_t slotAddr, Region *objectRegion,
TaggedObject *value, Region *valueRegion,
WriteBarrierType writeType = WriteBarrierType::NORMAL);
static void PUBLIC_API UpdateShared(const JSThread *thread, uintptr_t slotAddr, Region *objectRegion,
TaggedObject *value, Region *valueRegion);
static void PUBLIC_API CMCWriteBarrier(const JSThread *thread, void *obj, size_t offset, JSTaggedType value);
static void PUBLIC_API CMCArrayCopyWriteBarrier(const JSThread *thread, const TaggedObject *dstObj,
void* src, void* dst, size_t count);
static bool ShouldProcessSATB(common::GCPhase gcPhase);
static bool ShouldGetGCReason(common::GCPhase gcPhase);
static bool ShouldUpdateRememberSet(common::GCPhase gcPhase);
static void CMCArrayCopyReadBarrierForward(const JSThread *thread, JSTaggedValue* dst, const JSTaggedValue* src,
size_t count);
static void CMCArrayCopyReadBarrierBackward(const JSThread *thread, JSTaggedValue* dst, const JSTaggedValue* src,
size_t count);
};
}
#endif