mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-04-09 03:11:07 +00:00

Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IBOJPH?from=project-issue Signed-off-by: ywx <yinwuxiao@huawei.com> Change-Id: I61fc22946332cfde815cf9433d7ac98a46ea6231
112 lines
5.3 KiB
C++
112 lines
5.3 KiB
C++
/*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef ECMASCRIPT_ENUM_CACHE_H
|
|
#define ECMASCRIPT_ENUM_CACHE_H
|
|
|
|
#include "ecmascript/ecma_macros.h"
|
|
#include "ecmascript/mem/barriers.h"
|
|
|
|
// EnumCacheKind is only used in for-in.
|
|
enum class EnumCacheKind : uint8_t {
|
|
NONE, // No Cache, go slow path
|
|
SIMPLE, // Simple enum cache
|
|
PROTOCHAIN, // Prototype chain info enum cache
|
|
};
|
|
|
|
// +---------------+-------------------------------------------+-------------------------------------------------+
|
|
// | EnumCacheKind | Status Description | Valid Conditions |
|
|
// +---------------+-------------------------------------------+-------------------------------------------------+
|
|
// | None | - Uninitialized or in SlowPath mode. | - None (No additional conditions required) |
|
|
// | | No active cache optimization. | |
|
|
// +---------------+-------------------------------------------+-------------------------------------------------+
|
|
// | SIMPLE | - Fast path for simple enum cache check. | - Receiver's proto is NOT a HeapObject, |
|
|
// | | Indicates: | OR |
|
|
// | | • Properties exist ONLY on the object | - Receiver.proto.ProtoChainInfoEnumCache == |
|
|
// | | itself (no prototype chain properties) | Undefined. (Ensure no keys on prototype chain)|
|
|
// | | • NO elements (indexed properties) on | |
|
|
// | | self/proto | |
|
|
// +---------------+-------------------------------------------+-------------------------------------------------+
|
|
// | PROTOCHAIN | - Fast path for protochain enum cache. | - Receiver's proto is a HeapObject, AND |
|
|
// | | Indicates: | - Receiver.ProtoChainInfoEnumCache == |
|
|
// | | • Properties exist on the object itself | receiver.proto.EnumCacheAll (Cache matches |
|
|
// | | or prototype chain | prototype's full enum cache), AND |
|
|
// | | • NO elements (indexed properties) on | - Receiver.ProtoChainInfoEnumCache != Null |
|
|
// | | self/proto | (Valid cache exists). |
|
|
// +---------------+-------------------------------------------+-------------------------------------------------+
|
|
|
|
namespace panda {
|
|
namespace ecmascript {
|
|
class EnumCache : public TaggedObject {
|
|
public:
|
|
CAST_CHECK(EnumCache, IsEnumCache);
|
|
|
|
static constexpr size_t ENUM_CACHE_OWN_OFFSET = TaggedObjectSize();
|
|
|
|
static bool CheckSelfAndProtoEnumCache(JSTaggedValue enumCacheOwn, JSTaggedValue enumCacheProto)
|
|
{
|
|
if (!enumCacheOwn.IsEnumCache() || !enumCacheProto.IsEnumCache()) {
|
|
return false;
|
|
}
|
|
auto keyOwn = EnumCache::Cast(enumCacheOwn.GetTaggedObject())->GetProtoChainInfoEnumCache();
|
|
auto keyProto = EnumCache::Cast(enumCacheProto.GetTaggedObject())->GetEnumCacheAll();
|
|
if (keyOwn != keyProto || keyOwn == JSTaggedValue::Null()) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
inline bool IsEnumCacheAllValid() const
|
|
{
|
|
return GetEnumCacheAll() != JSTaggedValue::Null();
|
|
}
|
|
|
|
inline bool IsEnumCacheOwnValid() const
|
|
{
|
|
return GetEnumCacheOwn() != JSTaggedValue::Null();
|
|
}
|
|
|
|
inline bool IsEnumCacheProtoInfoUndefined() const
|
|
{
|
|
return GetProtoChainInfoEnumCache() == JSTaggedValue::Undefined();
|
|
}
|
|
|
|
inline void SetInvalidState(const JSThread *thread)
|
|
{
|
|
SetEnumCacheAll(thread, JSTaggedValue::Null());
|
|
SetProtoChainInfoEnumCache(thread, JSTaggedValue::Null());
|
|
}
|
|
|
|
// EnumCacheOwn holds enum keys on itself.
|
|
ACCESSORS(EnumCacheOwn, ENUM_CACHE_OWN_OFFSET, ENUM_CACHE_ALL_OFFSET);
|
|
|
|
// EnumCacheAll holds all enum keys on the prototype chain, including its own keys.
|
|
ACCESSORS(EnumCacheAll, ENUM_CACHE_ALL_OFFSET, PROTO_CHAIN_INFO_ENUM_CACHE_OFFSET);
|
|
|
|
// ProtoChainInfoEnumCache holds all enum keys on the prototype chain, excluding its own keys.
|
|
ACCESSORS(ProtoChainInfoEnumCache, PROTO_CHAIN_INFO_ENUM_CACHE_OFFSET, ENUM_CACHE_KIND_OFFSET);
|
|
ACCESSORS_PRIMITIVE_FIELD(EnumCacheKind, uint32_t, ENUM_CACHE_KIND_OFFSET, LAST_OFFSET);
|
|
|
|
DEFINE_ALIGN_SIZE(LAST_OFFSET);
|
|
|
|
DECL_VISIT_OBJECT(ENUM_CACHE_OWN_OFFSET, ENUM_CACHE_KIND_OFFSET)
|
|
|
|
DECL_DUMP()
|
|
};
|
|
} // namespace ecmascript
|
|
} // namespace panda
|
|
|
|
#endif // ECMASCRIPT_IC_ENUM_CACHE_H
|
|
|