* Copyright (c) 2025 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.
*/
#include "ecmascript/cross_vm/js_tagged_value_hybrid-inl.h"
#include "ecmascript/mem/dynamic_object_operator.h"
#include "ecmascript/mem/object_xray.h"
#include "ecmascript/runtime.h"
namespace panda::ecmascript {
DynamicObjectOperator DynamicObjectOperator::dynOperator_;
void DynamicObjectOperator::Initialize()
{
if (g_isEnableCMCGC) {
BaseObject::RegisterDynamic(&dynOperator_);
}
}
void DynamicObjectOperator::IterateXRef([[maybe_unused]] const BaseObject *object,
[[maybe_unused]] const common::RefFieldVisitor &visitor) const
{
#if defined(PANDA_JS_ETS_HYBRID_MODE) && defined(USE_CMC_GC)
if (g_isEnableCMCGC) {
JSTaggedValue value(reinterpret_cast<TaggedObject *>(const_cast<BaseObject *>(object)));
if (value.IsJSXRefObject()) {
Runtime::GetInstance()->GetSTSVMInterface()->MarkFromObject(
JSObject::Cast(TaggedObject::Cast(object))
->GetNativePointerField(Runtime::GetInstance()->GetMainThread(), 0), visitor);
}
} else {
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
}
#else
LOG_ECMA(FATAL) << "this branch is unreachable";
UNREACHABLE();
#endif
}
void RefFieldObjectVisitor::VisitObjectRangeImpl(BaseObject *root, uintptr_t startAddr,
uintptr_t endAddr, VisitObjectArea area)
{
ObjectSlot start(startAddr);
ObjectSlot end(endAddr);
if (UNLIKELY(area == VisitObjectArea::IN_OBJECT)) {
VisitBodyInObj(TaggedObject::Cast(root), start, end, [this](ObjectSlot slot) {
visit(slot);
});
return;
}
for (ObjectSlot slot = start; slot < end; slot++) {
visit(slot);
}
}
void RefFieldObjectVisitor::VisitObjectHClassImpl(BaseObject *hclass)
{
JSTaggedValue clz(reinterpret_cast<TaggedObject *>(hclass));
visitor_(reinterpret_cast<common::RefField<>&>(clz));
}
void RefFieldObjectVisitor::VisitAllRefFields(TaggedObject *obj)
{
VisitObjectHClassImpl(obj->GetClass());
ObjectXRay::VisitObjectBodyFast<VisitType::OLD_GC_VISIT>(obj, obj->GetClass(), *this);
}
void RefFieldObjectVisitor::visit(ObjectSlot slot)
{
if (!slot.GetTaggedValue().IsHeapObject()) {
return;
}
visitor_(reinterpret_cast<common::RefField<>&>(*(slot.GetRefFieldAddr())));
}
}