primitive_scope part2

Signed-off-by: huangzhenghua <huangzhenghua3@huawei.com>
Change-Id: Ifb7358f808fecca12f4bc7fc7815211806fa287a
This commit is contained in:
huangzhenghua 2024-04-30 01:02:42 +08:00
parent c01419af99
commit 91e54b81b6
6 changed files with 138 additions and 16 deletions

View File

@ -1041,7 +1041,7 @@ void EcmaContext::ShrinkPrimitiveStorage(int prevIndex)
#if ECMASCRIPT_ENABLE_ZAP_MEM
uintptr_t size = ToUintPtr(primitiveScopeStorageEnd_) - ToUintPtr(primitiveScopeStorageNext_);
if (currentPrimitiveStorageIndex_ != -1) {
if (memset_s(PrimitiveScopeStorageNext_, size, 0, size) != EOK) {
if (memset_s(primitiveScopeStorageNext_, size, 0, size) != EOK) {
LOG_FULL(FATAL) << "memset_s failed";
UNREACHABLE();
}

View File

@ -45,7 +45,7 @@ void EcmaHandleScope::OpenPrimitiveScope(EcmaContext *context)
prevPrimitiveStorageIndex_ = context->currentPrimitiveStorageIndex_;
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
context->PrimitiveScopeCountAdd();
prevHandleScope_ = context->GetLastPrimitiveScope();
prevPrimitiveScope_ = context->GetLastPrimitiveScope();
context->SetLastPrimitiveScope(this);
#endif
}

View File

@ -58,6 +58,7 @@ private:
#ifdef ECMASCRIPT_ENABLE_HANDLE_LEAK_CHECK
ClockScope scope_;
EcmaHandleScope *prevHandleScope_ {nullptr};
EcmaHandleScope *prevPrimitiveScope_ {nullptr};
#endif
NO_COPY_SEMANTIC(EcmaHandleScope);

View File

@ -81,21 +81,13 @@ public:
DEFAULT_NOEXCEPT_MOVE_SEMANTIC(JSHandle);
DEFAULT_COPY_SEMANTIC(JSHandle);
JSHandle(const JSThread *thread, JSTaggedValue value, bool isPrimitive = false)
JSHandle(const JSThread *thread, JSTaggedValue value)
{
if (isPrimitive) {
address_ = EcmaHandleScope::NewPrimitiveHandle(
const_cast<JSThread *>(thread), value.GetRawData());
}
address_ = EcmaHandleScope::NewHandle(const_cast<JSThread *>(thread), value.GetRawData());
}
JSHandle(const JSThread *thread, const TaggedObject *value, bool isPrimitive = false)
JSHandle(const JSThread *thread, const TaggedObject *value)
{
if (isPrimitive) {
address_ = EcmaHandleScope::NewPrimitiveHandle(
const_cast<JSThread *>(thread), JSTaggedValue(value).GetRawData());
}
address_ = EcmaHandleScope::NewHandle(const_cast<JSThread *>(thread), JSTaggedValue(value).GetRawData());
}
@ -242,6 +234,127 @@ public:
*addr = handle.GetTaggedValue();
}
};
template <typename T>
class JSPrimitiveHandle {
public:
inline JSPrimitiveHandle() : address_(reinterpret_cast<uintptr_t>(nullptr)) {}
~JSPrimitiveHandle() = default;
DEFAULT_NOEXCEPT_MOVE_SEMANTIC(JSPrimitiveHandle);
DEFAULT_COPY_SEMANTIC(JSPrimitiveHandle);
JSPrimitiveHandle(const JSThread *thread, JSTaggedValue value)
{
address_ = EcmaHandleScope::NewPrimitiveHandle(
const_cast<JSThread *>(thread), value.GetRawData());
}
JSPrimitiveHandle(const JSThread *thread, const TaggedObject *value)
{
address_ = EcmaHandleScope::NewPrimitiveHandle(
const_cast<JSThread *>(thread), JSTaggedValue(value).GetRawData());
}
inline uintptr_t GetAddress() const
{
return address_;
}
template <typename S>
explicit JSPrimitiveHandle(const JSPrimitiveHandle<S> &handle) : address_(handle.GetAddress()) {}
template <typename S>
inline static JSPrimitiveHandle<T> Cast(const JSPrimitiveHandle<S> &handle)
{
T::Cast(handle.GetTaggedValue().GetTaggedObject());
return JSPrimitiveHandle<T>(handle.GetAddress());
}
inline JSTaggedValue GetTaggedValue() const
{
CHECK_NO_DEREF_HANDLE;
if (GetAddress() == 0U) {
return JSTaggedValue::Undefined();
}
return *(reinterpret_cast<JSTaggedValue *>(GetAddress())); // NOLINT(clang-analyzer-core.NullDereference)
}
inline JSTaggedType GetTaggedType() const
{
CHECK_NO_DEREF_HANDLE;
if (GetAddress() == 0U) {
return JSTaggedValue::Undefined().GetRawData();
}
return *reinterpret_cast<JSTaggedType *>(GetAddress()); // NOLINT(clang-analyzer-core.NullDereference)
}
inline T *operator*() const
{
return T::Cast(GetTaggedValue().GetTaggedObject());
}
inline T *operator->() const
{
return T::Cast(GetTaggedValue().GetTaggedObject());
}
inline bool operator==(const JSPrimitiveHandle<T> &other) const
{
return GetTaggedType() == other.GetTaggedType();
}
inline bool operator!=(const JSPrimitiveHandle<T> &other) const
{
return GetTaggedType() != other.GetTaggedType();
}
inline bool IsEmpty() const
{
return GetAddress() == 0U;
}
template <typename R>
R *GetObject() const
{
return reinterpret_cast<R *>(GetTaggedValue().GetTaggedObject());
}
inline explicit JSPrimitiveHandle(uintptr_t slot) : address_(slot)
{
if (!std::is_convertible<T *, JSTaggedValue *>::value) {
ASSERT(slot != 0);
if ((*reinterpret_cast<JSTaggedValue *>(slot)).IsHeapObject()) {
T::Cast((*reinterpret_cast<JSTaggedValue *>(slot)).GetTaggedObject());
}
}
}
void Dump() const DUMP_API_ATTR
{
GetTaggedValue().D();
}
private:
inline explicit JSPrimitiveHandle(const JSTaggedType *slot) : address_(reinterpret_cast<uintptr_t>(slot)) {}
inline explicit JSPrimitiveHandle(const T *const *slot) : address_(reinterpret_cast<uintptr_t>(slot)) {}
uintptr_t address_; // NOLINT(misc-non-private-member-variables-in-classes)
friend class EcmaVM;
friend class GlobalEnv;
friend class GlobalHandleCollection;
friend class RuntimeStubs;
};
template <>
inline JSTaggedValue *JSPrimitiveHandle<JSTaggedValue>::operator->() const
{
return reinterpret_cast<JSTaggedValue *>(GetAddress());
}
template <>
inline JSTaggedValue *JSPrimitiveHandle<JSTaggedValue>::operator*() const
{
return reinterpret_cast<JSTaggedValue *>(GetAddress());
}
} // namespace panda::ecmascript
#endif // ECMASCRIPT_JSHANDLE_H

View File

@ -192,6 +192,8 @@ using ecmascript::base::NumberHelper;
template <typename T>
using JSHandle = ecmascript::JSHandle<T>;
template <typename T>
using JSPrimitiveHandle = ecmascript::JSPrimitiveHandle<T>;
template <typename T>
using JSMutableHandle = ecmascript::JSMutableHandle<T>;
using PathHelper = ecmascript::base::PathHelper;
@ -898,7 +900,7 @@ Local<NumberRef> NumberRef::New(const EcmaVM *vm, double input)
if (std::isnan(input)) {
input = ecmascript::base::NAN_VALUE;
}
JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
JSPrimitiveHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
return JSNApiHelper::ToLocal<NumberRef>(number);
}
@ -907,7 +909,7 @@ Local<NumberRef> NumberRef::New(const EcmaVM *vm, int32_t input)
// Omit exception check because ark calls here may not
// cause side effect even pending exception exists.
CROSS_THREAD_CHECK(vm);
JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
JSPrimitiveHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
return JSNApiHelper::ToLocal<NumberRef>(number);
}
@ -916,7 +918,7 @@ Local<NumberRef> NumberRef::New(const EcmaVM *vm, uint32_t input)
// Omit exception check because ark calls here may not
// cause side effect even pending exception exists.
CROSS_THREAD_CHECK(vm);
JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
JSPrimitiveHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
return JSNApiHelper::ToLocal<NumberRef>(number);
}
@ -925,7 +927,7 @@ Local<NumberRef> NumberRef::New(const EcmaVM *vm, int64_t input)
// Omit exception check because ark calls here may not
// cause side effect even pending exception exists.
CROSS_THREAD_CHECK(vm);
JSHandle<JSTaggedValue> number(thread, JSTaggedValue(input), true);
JSPrimitiveHandle<JSTaggedValue> number(thread, JSTaggedValue(input));
return JSNApiHelper::ToLocal<NumberRef>(number);
}

View File

@ -121,6 +121,12 @@ public:
return Local<T>(from.GetAddress());
}
template<typename T>
static inline Local<T> ToLocal(ecmascript::JSPrimitiveHandle<ecmascript::JSTaggedValue> from)
{
return Local<T>(from.GetAddress());
}
static inline ecmascript::JSTaggedValue ToJSTaggedValue(JSValueRef *from)
{
ASSERT(from != nullptr);