fff4f2324d
This class is structurally equivalent to _HashVMBase and the only reason for it to exist for inability of normal Dart classes to extend _HashVMBase - but this can worked around by properly configuring _HashVMBase class in bootstrapping. TEST=ci Change-Id: I5ca401e274920d2b4739424c6b6595306a6a6964 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494140 Commit-Queue: Slava Egorov <vegorov@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
662 lines
35 KiB
C++
662 lines
35 KiB
C++
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
#ifndef RUNTIME_VM_CLASS_ID_H_
|
|
#define RUNTIME_VM_CLASS_ID_H_
|
|
|
|
// This header defines the list of VM implementation classes and their ids.
|
|
//
|
|
// Note: we assume that all builds of Dart VM use exactly the same class ids
|
|
// for these classes.
|
|
|
|
#include "platform/assert.h"
|
|
#include "vm/globals.h"
|
|
|
|
namespace dart {
|
|
|
|
// Large enough to contain the class-id part of the object header. See
|
|
// UntaggedObject. Signed to be comparable to intptr_t.
|
|
typedef int32_t ClassIdTagType;
|
|
|
|
static constexpr intptr_t kClassIdTagMax = (1 << 20) - 1;
|
|
|
|
// Classes that are not subclasses of Instance and only handled by the VM,
|
|
// but do not require any special handling other than being a predefined class.
|
|
#define CLASS_LIST_INTERNAL_ONLY(V) \
|
|
V(Class) \
|
|
V(PatchClass) \
|
|
V(Function) \
|
|
V(TypeParameters) \
|
|
V(ClosureData) \
|
|
V(FfiTrampolineData) \
|
|
V(Field) \
|
|
V(Script) \
|
|
V(Library) \
|
|
V(Namespace) \
|
|
V(KernelProgramInfo) \
|
|
V(WeakSerializationReference) \
|
|
V(WeakArray) \
|
|
V(Code) \
|
|
V(Bytecode) \
|
|
V(Instructions) \
|
|
V(InstructionsSection) \
|
|
V(InstructionsTable) \
|
|
V(ObjectPool) \
|
|
V(PcDescriptors) \
|
|
V(CodeSourceMap) \
|
|
V(CompressedStackMaps) \
|
|
V(LocalVarDescriptors) \
|
|
V(ExceptionHandlers) \
|
|
V(Context) \
|
|
V(ContextScope) \
|
|
V(Sentinel) \
|
|
V(SingleTargetCache) \
|
|
V(MonomorphicSmiableCall) \
|
|
V(CallSiteData) \
|
|
V(UnlinkedCall) \
|
|
V(ICData) \
|
|
V(MegamorphicCache) \
|
|
V(SubtypeTestCache) \
|
|
V(LoadingUnit) \
|
|
V(Error) \
|
|
V(ApiError) \
|
|
V(LanguageError) \
|
|
V(UnhandledException) \
|
|
V(UnwindError)
|
|
|
|
// Classes that are subclasses of Instance and neither part of a specific cid
|
|
// grouping like strings, arrays, etc. nor require special handling outside of
|
|
// being a predefined class.
|
|
#define CLASS_LIST_INSTANCE_SINGLETONS(V) \
|
|
V(Instance) \
|
|
V(LibraryPrefix) \
|
|
V(TypeArguments) \
|
|
V(AbstractType) \
|
|
V(Type) \
|
|
V(FunctionType) \
|
|
V(RecordType) \
|
|
V(TypeParameter) \
|
|
V(FinalizerBase) \
|
|
V(Finalizer) \
|
|
V(NativeFinalizer) \
|
|
V(FinalizerEntry) \
|
|
V(Closure) \
|
|
V(Number) \
|
|
V(Integer) \
|
|
V(Smi) \
|
|
V(Mint) \
|
|
V(Double) \
|
|
V(Bool) \
|
|
V(Float32x4) \
|
|
V(Int32x4) \
|
|
V(Float64x2) \
|
|
V(Record) \
|
|
V(TypedDataBase) \
|
|
V(TypedData) \
|
|
V(ExternalTypedData) \
|
|
V(TypedDataView) \
|
|
V(Pointer) \
|
|
V(DynamicLibrary) \
|
|
V(Capability) \
|
|
V(ReceivePort) \
|
|
V(SendPort) \
|
|
V(StackTrace) \
|
|
V(SuspendState) \
|
|
V(RegExp) \
|
|
V(WeakProperty) \
|
|
V(WeakReference) \
|
|
V(MirrorReference) \
|
|
V(FutureOr) \
|
|
V(UserTag) \
|
|
V(TransferableTypedData)
|
|
|
|
#define CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY_NOR_MAP(V) \
|
|
CLASS_LIST_INTERNAL_ONLY(V) CLASS_LIST_INSTANCE_SINGLETONS(V)
|
|
|
|
#define CLASS_LIST_MAPS(V) \
|
|
V(Map) \
|
|
V(ConstMap)
|
|
|
|
#define CLASS_LIST_SETS(V) \
|
|
V(Set) \
|
|
V(ConstSet)
|
|
|
|
#define CLASS_LIST_FIXED_LENGTH_ARRAYS(V) \
|
|
V(Array) \
|
|
V(ImmutableArray)
|
|
|
|
#define CLASS_LIST_ARRAYS(V) \
|
|
CLASS_LIST_FIXED_LENGTH_ARRAYS(V) \
|
|
V(GrowableObjectArray)
|
|
|
|
#define CLASS_LIST_STRINGS(V) \
|
|
V(String) \
|
|
V(OneByteString) \
|
|
V(TwoByteString)
|
|
|
|
#define CLASS_LIST_TYPED_DATA(V) \
|
|
V(Int8Array) \
|
|
V(Uint8Array) \
|
|
V(Uint8ClampedArray) \
|
|
V(Int16Array) \
|
|
V(Uint16Array) \
|
|
V(Int32Array) \
|
|
V(Uint32Array) \
|
|
V(Int64Array) \
|
|
V(Uint64Array) \
|
|
V(Float32Array) \
|
|
V(Float64Array) \
|
|
V(Float32x4Array) \
|
|
V(Int32x4Array) \
|
|
V(Float64x2Array)
|
|
|
|
#define CLASS_LIST_FFI_NUMERIC_FIXED_SIZE(V) \
|
|
V(Int8) \
|
|
V(Int16) \
|
|
V(Int32) \
|
|
V(Int64) \
|
|
V(Uint8) \
|
|
V(Uint16) \
|
|
V(Uint32) \
|
|
V(Uint64) \
|
|
V(Float) \
|
|
V(Double)
|
|
|
|
#define CLASS_LIST_FFI_TYPE_MARKER(V) \
|
|
CLASS_LIST_FFI_NUMERIC_FIXED_SIZE(V) \
|
|
V(Void) \
|
|
V(Handle) \
|
|
V(Bool)
|
|
|
|
#define CLASS_LIST_FFI(V) \
|
|
V(NativeFunction) \
|
|
CLASS_LIST_FFI_TYPE_MARKER(V) \
|
|
V(NativeType) \
|
|
V(Struct)
|
|
|
|
#define DART_CLASS_LIST_TYPED_DATA(V) \
|
|
V(Int8) \
|
|
V(Uint8) \
|
|
V(Uint8Clamped) \
|
|
V(Int16) \
|
|
V(Uint16) \
|
|
V(Int32) \
|
|
V(Uint32) \
|
|
V(Int64) \
|
|
V(Uint64) \
|
|
V(Float32) \
|
|
V(Float64) \
|
|
V(Float32x4) \
|
|
V(Int32x4) \
|
|
V(Float64x2)
|
|
|
|
#define CLASS_LIST_FOR_HANDLES(V) \
|
|
CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY_NOR_MAP(V) \
|
|
V(Map) \
|
|
V(Set) \
|
|
V(Array) \
|
|
V(GrowableObjectArray) \
|
|
V(String)
|
|
|
|
#define CLASS_LIST_NO_OBJECT(V) \
|
|
CLASS_LIST_NO_OBJECT_NOR_STRING_NOR_ARRAY_NOR_MAP(V) \
|
|
CLASS_LIST_MAPS(V) \
|
|
CLASS_LIST_SETS(V) \
|
|
CLASS_LIST_ARRAYS(V) \
|
|
CLASS_LIST_STRINGS(V)
|
|
|
|
#define CLASS_LIST(V) \
|
|
V(Object) \
|
|
CLASS_LIST_NO_OBJECT(V)
|
|
|
|
#define LEAF_HANDLE_LIST(V) \
|
|
V(Class) \
|
|
V(PatchClass) \
|
|
V(Function) \
|
|
V(TypeParameters) \
|
|
V(ClosureData) \
|
|
V(FfiTrampolineData) \
|
|
V(Field) \
|
|
V(Script) \
|
|
V(Library) \
|
|
V(Namespace) \
|
|
V(KernelProgramInfo) \
|
|
V(WeakSerializationReference) \
|
|
V(WeakArray) \
|
|
V(Code) \
|
|
V(Bytecode) \
|
|
V(Instructions) \
|
|
V(InstructionsSection) \
|
|
V(InstructionsTable) \
|
|
V(ObjectPool) \
|
|
V(PcDescriptors) \
|
|
V(CodeSourceMap) \
|
|
V(CompressedStackMaps) \
|
|
V(LocalVarDescriptors) \
|
|
V(ExceptionHandlers) \
|
|
V(Context) \
|
|
V(ContextScope) \
|
|
V(Sentinel) \
|
|
V(SingleTargetCache) \
|
|
V(UnlinkedCall) \
|
|
V(MonomorphicSmiableCall) \
|
|
V(ICData) \
|
|
V(MegamorphicCache) \
|
|
V(SubtypeTestCache) \
|
|
V(LoadingUnit) \
|
|
V(ApiError) \
|
|
V(LanguageError) \
|
|
V(UnhandledException) \
|
|
V(UnwindError) \
|
|
V(LibraryPrefix) \
|
|
V(TypeArguments) \
|
|
V(Type) \
|
|
V(FunctionType) \
|
|
V(RecordType) \
|
|
V(TypeParameter) \
|
|
V(Finalizer) \
|
|
V(NativeFinalizer) \
|
|
V(FinalizerEntry) \
|
|
V(Closure) \
|
|
V(Smi) \
|
|
V(Mint) \
|
|
V(Double) \
|
|
V(Bool) \
|
|
V(Float32x4) \
|
|
V(Int32x4) \
|
|
V(Float64x2) \
|
|
V(Record) \
|
|
V(TypedData) \
|
|
V(ExternalTypedData) \
|
|
V(TypedDataView) \
|
|
V(Pointer) \
|
|
V(DynamicLibrary) \
|
|
V(Capability) \
|
|
V(ReceivePort) \
|
|
V(SendPort) \
|
|
V(StackTrace) \
|
|
V(SuspendState) \
|
|
V(RegExp) \
|
|
V(WeakProperty) \
|
|
V(WeakReference) \
|
|
V(MirrorReference) \
|
|
V(FutureOr) \
|
|
V(UserTag) \
|
|
V(TransferableTypedData) \
|
|
V(Map) \
|
|
V(Set) \
|
|
V(Array) \
|
|
V(GrowableObjectArray) \
|
|
V(String)
|
|
|
|
#undef CID
|
|
#define DEFINE_CLASS_ID(clazz) CID(clazz##Cid)
|
|
#define DEFINE_FFI_CLASS_ID(clazz) CID(Ffi##clazz##Cid)
|
|
#define DEFINE_TYPED_DATA_CLASS_ID(clazz) \
|
|
CID(TypedData##clazz##Cid) \
|
|
CID(TypedData##clazz##ViewCid) \
|
|
CID(ExternalTypedData##clazz##Cid) \
|
|
CID(UnmodifiableTypedData##clazz##ViewCid)
|
|
|
|
#define CLASS_ID_LIST \
|
|
/* Illegal class id. */ \
|
|
CID(IllegalCid) \
|
|
/* Pseudo class id for native pointers, the heap should never see an */ \
|
|
/* object with this class id. */ \
|
|
CID(NativePointer) \
|
|
/* The following entries describes classes for pseudo-objects in the heap */ \
|
|
/* that should never be reachable from live objects. Free list elements */ \
|
|
/* maintain the free list for old space, and forwarding corpses are used */ \
|
|
/* to implement one-way become. */ \
|
|
CID(FreeListElement) \
|
|
CID(ForwardingCorpse) \
|
|
CLASS_LIST(DEFINE_CLASS_ID) \
|
|
CID(LinkedHashBaseCid) \
|
|
CLASS_LIST_FFI(DEFINE_FFI_CLASS_ID) \
|
|
CLASS_LIST_TYPED_DATA(DEFINE_TYPED_DATA_CLASS_ID) \
|
|
CID(ByteDataViewCid) \
|
|
CID(UnmodifiableByteDataViewCid) \
|
|
CID(ByteBufferCid) \
|
|
/* The following entries do not describe a predefined class, but instead */ \
|
|
/* are class indexes for pre-allocated instances */ \
|
|
/* (Null, dynamic, void, Never). */ \
|
|
CID(NullCid) \
|
|
CID(DynamicCid) \
|
|
CID(VoidCid) \
|
|
CID(NeverCid)
|
|
|
|
enum ClassId : intptr_t {
|
|
#define CID(cid) k##cid,
|
|
CLASS_ID_LIST
|
|
#undef CID
|
|
kNumPredefinedCids,
|
|
};
|
|
|
|
static constexpr const char* kClassIdNames[] = {
|
|
#define CID(cid) #cid,
|
|
CLASS_ID_LIST
|
|
#undef CID
|
|
};
|
|
|
|
#undef DEFINE_CLASS_ID
|
|
#undef DEFINE_FFI_CLASS_ID
|
|
#undef DEFINE_TYPED_DATA_CLASS_ID
|
|
#undef CLASS_ID_LIST
|
|
|
|
// Keep these in sync with the cid numbering above.
|
|
const int kTypedDataCidRemainderInternal = 0;
|
|
const int kTypedDataCidRemainderView = 1;
|
|
const int kTypedDataCidRemainderExternal = 2;
|
|
const int kTypedDataCidRemainderUnmodifiable = 3;
|
|
const int kNumTypedDataCidRemainders = kTypedDataCidRemainderUnmodifiable + 1;
|
|
|
|
// Class Id predicates.
|
|
|
|
bool IsInternalOnlyClassId(intptr_t index);
|
|
bool IsErrorClassId(intptr_t index);
|
|
bool IsNumberClassId(intptr_t index);
|
|
bool IsIntegerClassId(intptr_t index);
|
|
bool IsStringClassId(intptr_t index);
|
|
bool IsOneByteStringClassId(intptr_t index);
|
|
bool IsBuiltinListClassId(intptr_t index);
|
|
bool IsTypeClassId(intptr_t index);
|
|
bool IsTypedDataBaseClassId(intptr_t index);
|
|
bool IsTypedDataClassId(intptr_t index);
|
|
bool IsTypedDataViewClassId(intptr_t index);
|
|
bool IsExternalTypedDataClassId(intptr_t index);
|
|
bool IsFfiPointerClassId(intptr_t index);
|
|
bool IsFfiTypeClassId(intptr_t index);
|
|
bool IsFfiDynamicLibraryClassId(intptr_t index);
|
|
bool IsInternalVMdefinedClassId(intptr_t index);
|
|
bool IsImplicitFieldClassId(intptr_t index);
|
|
|
|
// Should be used for looping over non-Object internal-only cids.
|
|
constexpr intptr_t kFirstInternalOnlyCid = kClassCid;
|
|
constexpr intptr_t kLastInternalOnlyCid = kUnwindErrorCid;
|
|
// Use the currently surrounding cids to check that no new classes have been
|
|
// added to the beginning or end of CLASS_LIST_INTERNAL_ONLY without adjusting
|
|
// the above definitions.
|
|
COMPILE_ASSERT(kFirstInternalOnlyCid == kObjectCid + 1);
|
|
COMPILE_ASSERT(kInstanceCid == kLastInternalOnlyCid + 1);
|
|
|
|
// Returns true for any class id that either does not correspond to a real
|
|
// class, like kIllegalCid or kForwardingCorpse, or that is internal to the VM
|
|
// and should not be exposed directly to user code.
|
|
inline bool IsInternalOnlyClassId(intptr_t index) {
|
|
// Fix the condition below if these become non-contiguous.
|
|
COMPILE_ASSERT(kIllegalCid + 1 == kNativePointer &&
|
|
kIllegalCid + 2 == kFreeListElement &&
|
|
kIllegalCid + 3 == kForwardingCorpse &&
|
|
kIllegalCid + 4 == kObjectCid &&
|
|
kIllegalCid + 5 == kFirstInternalOnlyCid);
|
|
return index <= kLastInternalOnlyCid;
|
|
}
|
|
|
|
inline bool IsCallSiteDataClassId(intptr_t index) {
|
|
COMPILE_ASSERT(kCallSiteDataCid + 1 == kUnlinkedCallCid &&
|
|
kCallSiteDataCid + 2 == kICDataCid &&
|
|
kCallSiteDataCid + 3 == kMegamorphicCacheCid);
|
|
return (index >= kCallSiteDataCid && index <= kMegamorphicCacheCid);
|
|
}
|
|
|
|
// Make sure this function is updated when new Error types are added.
|
|
static const ClassId kFirstErrorCid = kErrorCid;
|
|
static const ClassId kLastErrorCid = kUnwindErrorCid;
|
|
COMPILE_ASSERT(kFirstErrorCid == kErrorCid &&
|
|
kApiErrorCid == kFirstErrorCid + 1 &&
|
|
kLanguageErrorCid == kFirstErrorCid + 2 &&
|
|
kUnhandledExceptionCid == kFirstErrorCid + 3 &&
|
|
kUnwindErrorCid == kFirstErrorCid + 4 &&
|
|
kLastErrorCid == kUnwindErrorCid &&
|
|
// Change if needed for detecting a new error added at the end.
|
|
kLastInternalOnlyCid == kLastErrorCid);
|
|
|
|
inline bool IsErrorClassId(intptr_t index) {
|
|
return (index >= kFirstErrorCid && index <= kLastErrorCid);
|
|
}
|
|
|
|
inline bool IsAbstractTypeClassId(intptr_t index) {
|
|
COMPILE_ASSERT(kAbstractTypeCid + 1 == kTypeCid &&
|
|
kAbstractTypeCid + 2 == kFunctionTypeCid &&
|
|
kAbstractTypeCid + 3 == kRecordTypeCid &&
|
|
kAbstractTypeCid + 4 == kTypeParameterCid);
|
|
return (index >= kAbstractTypeCid && index <= kTypeParameterCid);
|
|
}
|
|
|
|
inline bool IsConcreteTypeClassId(intptr_t index) {
|
|
// Make sure to update when new AbstractType subclasses are added.
|
|
COMPILE_ASSERT(kFunctionTypeCid == kTypeCid + 1 &&
|
|
kRecordTypeCid == kTypeCid + 2 &&
|
|
kTypeParameterCid == kTypeCid + 3);
|
|
return (index >= kTypeCid && index <= kTypeParameterCid);
|
|
}
|
|
|
|
inline bool IsNumberClassId(intptr_t index) {
|
|
// Make sure this function is updated when new Number types are added.
|
|
COMPILE_ASSERT(kIntegerCid == kNumberCid + 1 && kSmiCid == kNumberCid + 2 &&
|
|
kMintCid == kNumberCid + 3 && kDoubleCid == kNumberCid + 4);
|
|
return (index >= kNumberCid && index <= kDoubleCid);
|
|
}
|
|
|
|
inline bool IsIntegerClassId(intptr_t index) {
|
|
// Make sure this function is updated when new Integer types are added.
|
|
COMPILE_ASSERT(kSmiCid == kIntegerCid + 1 && kMintCid == kIntegerCid + 2);
|
|
return (index >= kIntegerCid && index <= kMintCid);
|
|
}
|
|
|
|
// Make sure this check is updated when new StringCid types are added.
|
|
COMPILE_ASSERT(kOneByteStringCid == kStringCid + 1 &&
|
|
kTwoByteStringCid == kStringCid + 2);
|
|
|
|
inline bool IsStringClassId(intptr_t index) {
|
|
return (index >= kStringCid && index <= kTwoByteStringCid);
|
|
}
|
|
|
|
inline bool IsOneByteStringClassId(intptr_t index) {
|
|
return (index == kOneByteStringCid);
|
|
}
|
|
|
|
inline bool IsArrayClassId(intptr_t index) {
|
|
COMPILE_ASSERT(kImmutableArrayCid == kArrayCid + 1);
|
|
COMPILE_ASSERT(kGrowableObjectArrayCid == kArrayCid + 2);
|
|
return (index >= kArrayCid && index <= kGrowableObjectArrayCid);
|
|
}
|
|
|
|
inline bool IsBuiltinListClassId(intptr_t index) {
|
|
// Make sure this function is updated when new builtin List types are added.
|
|
return (IsArrayClassId(index) || IsTypedDataBaseClassId(index) ||
|
|
(index == kByteBufferCid));
|
|
}
|
|
|
|
inline bool IsTypeClassId(intptr_t index) {
|
|
// Only Type, FunctionType and RecordType can be encountered as instance
|
|
// types at runtime.
|
|
return index == kTypeCid || index == kFunctionTypeCid ||
|
|
index == kRecordTypeCid;
|
|
}
|
|
|
|
static const ClassId kFirstTypedDataCid = kTypedDataInt8ArrayCid;
|
|
static const ClassId kLastTypedDataCid =
|
|
kUnmodifiableTypedDataFloat64x2ArrayViewCid;
|
|
|
|
// Make sure the following checks are updated when adding new TypedData types.
|
|
|
|
// The following asserts assume this.
|
|
COMPILE_ASSERT(kTypedDataCidRemainderInternal == 0);
|
|
// Ensure that each typed data type comes in internal/view/external variants
|
|
// next to each other.
|
|
COMPILE_ASSERT(kTypedDataInt8ArrayCid + kTypedDataCidRemainderView ==
|
|
kTypedDataInt8ArrayViewCid);
|
|
COMPILE_ASSERT(kTypedDataInt8ArrayCid + kTypedDataCidRemainderExternal ==
|
|
kExternalTypedDataInt8ArrayCid);
|
|
COMPILE_ASSERT(kTypedDataInt8ArrayCid + kTypedDataCidRemainderUnmodifiable ==
|
|
kUnmodifiableTypedDataInt8ArrayViewCid);
|
|
// Ensure the order of the typed data members in 3-step.
|
|
COMPILE_ASSERT(kFirstTypedDataCid == kTypedDataInt8ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 1 * kNumTypedDataCidRemainders ==
|
|
kTypedDataUint8ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 2 * kNumTypedDataCidRemainders ==
|
|
kTypedDataUint8ClampedArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 3 * kNumTypedDataCidRemainders ==
|
|
kTypedDataInt16ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 4 * kNumTypedDataCidRemainders ==
|
|
kTypedDataUint16ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 5 * kNumTypedDataCidRemainders ==
|
|
kTypedDataInt32ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 6 * kNumTypedDataCidRemainders ==
|
|
kTypedDataUint32ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 7 * kNumTypedDataCidRemainders ==
|
|
kTypedDataInt64ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 8 * kNumTypedDataCidRemainders ==
|
|
kTypedDataUint64ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 9 * kNumTypedDataCidRemainders ==
|
|
kTypedDataFloat32ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 10 * kNumTypedDataCidRemainders ==
|
|
kTypedDataFloat64ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 11 * kNumTypedDataCidRemainders ==
|
|
kTypedDataFloat32x4ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 12 * kNumTypedDataCidRemainders ==
|
|
kTypedDataInt32x4ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 13 * kNumTypedDataCidRemainders ==
|
|
kTypedDataFloat64x2ArrayCid);
|
|
COMPILE_ASSERT(kFirstTypedDataCid + 13 * kNumTypedDataCidRemainders +
|
|
kTypedDataCidRemainderUnmodifiable ==
|
|
kLastTypedDataCid);
|
|
// Checks for possible new typed data entries added before or after the current
|
|
// entries.
|
|
COMPILE_ASSERT(kFfiStructCid + 1 == kFirstTypedDataCid);
|
|
COMPILE_ASSERT(kLastTypedDataCid + 1 == kByteDataViewCid);
|
|
|
|
inline bool IsTypedDataBaseClassId(intptr_t index) {
|
|
return index >= kFirstTypedDataCid && index <= kLastTypedDataCid;
|
|
}
|
|
|
|
inline bool IsTypedDataClassId(intptr_t index) {
|
|
return IsTypedDataBaseClassId(index) &&
|
|
((index - kFirstTypedDataCid) % kNumTypedDataCidRemainders) ==
|
|
kTypedDataCidRemainderInternal;
|
|
}
|
|
|
|
inline bool IsTypedDataViewClassId(intptr_t index) {
|
|
const bool is_byte_data_view = index == kByteDataViewCid;
|
|
return is_byte_data_view ||
|
|
(IsTypedDataBaseClassId(index) &&
|
|
((index - kFirstTypedDataCid) % kNumTypedDataCidRemainders) ==
|
|
kTypedDataCidRemainderView);
|
|
}
|
|
|
|
inline bool IsExternalTypedDataClassId(intptr_t index) {
|
|
return IsTypedDataBaseClassId(index) &&
|
|
((index - kFirstTypedDataCid) % kNumTypedDataCidRemainders) ==
|
|
kTypedDataCidRemainderExternal;
|
|
}
|
|
|
|
inline bool IsUnmodifiableTypedDataViewClassId(intptr_t index) {
|
|
const bool is_byte_data_view = index == kUnmodifiableByteDataViewCid;
|
|
return is_byte_data_view ||
|
|
(IsTypedDataBaseClassId(index) &&
|
|
((index - kFirstTypedDataCid) % kNumTypedDataCidRemainders) ==
|
|
kTypedDataCidRemainderUnmodifiable);
|
|
}
|
|
|
|
inline bool IsClampedTypedDataBaseClassId(intptr_t index) {
|
|
if (!IsTypedDataBaseClassId(index)) return false;
|
|
const intptr_t internal_cid =
|
|
index - ((index - kFirstTypedDataCid) % kNumTypedDataCidRemainders) +
|
|
kTypedDataCidRemainderInternal;
|
|
// Currently, the only clamped typed data arrays are Uint8.
|
|
return internal_cid == kTypedDataUint8ClampedArrayCid;
|
|
}
|
|
|
|
// Whether the given cid is an external array cid, that is, an array where
|
|
// the payload is not in GC-managed memory.
|
|
inline bool IsExternalPayloadClassId(classid_t cid) {
|
|
return cid == kPointerCid || IsExternalTypedDataClassId(cid);
|
|
}
|
|
|
|
// For predefined cids only. Refer to Class::is_deeply_immutable for
|
|
// instances of non-predefined classes.
|
|
//
|
|
// Having the `@pragma('vm:deeply-immutable')`, which means statically proven
|
|
// deeply immutable, implies true for this function. The other way around is not
|
|
// guaranteed, predefined classes can be marked deeply immutable in the VM while
|
|
// not having their subtypes or super type being deeply immutable.
|
|
//
|
|
// Keep consistent with runtime/docs/deeply_immutable.md.
|
|
inline bool IsDeeplyImmutableCid(intptr_t predefined_cid) {
|
|
ASSERT(predefined_cid < kNumPredefinedCids);
|
|
return IsStringClassId(predefined_cid) || predefined_cid == kNumberCid ||
|
|
predefined_cid == kIntegerCid || predefined_cid == kSmiCid ||
|
|
predefined_cid == kMintCid || predefined_cid == kNeverCid ||
|
|
predefined_cid == kSentinelCid || predefined_cid == kStackTraceCid ||
|
|
predefined_cid == kDoubleCid || predefined_cid == kFloat32x4Cid ||
|
|
predefined_cid == kFloat64x2Cid || predefined_cid == kInt32x4Cid ||
|
|
predefined_cid == kSendPortCid || predefined_cid == kCapabilityCid ||
|
|
predefined_cid == kRegExpCid || predefined_cid == kBoolCid ||
|
|
predefined_cid == kNullCid || predefined_cid == kPointerCid ||
|
|
predefined_cid == kTypeCid || predefined_cid == kTypeArgumentsCid ||
|
|
predefined_cid == kTypeParameterCid ||
|
|
predefined_cid == kRecordTypeCid ||
|
|
predefined_cid == kFunctionTypeCid || predefined_cid == kConstMapCid;
|
|
}
|
|
|
|
inline bool IsShallowlyImmutableCid(intptr_t predefined_cid) {
|
|
ASSERT(predefined_cid < kNumPredefinedCids);
|
|
return predefined_cid == kClosureCid ||
|
|
IsUnmodifiableTypedDataViewClassId(predefined_cid);
|
|
}
|
|
|
|
inline bool IsFfiTypeClassId(intptr_t index) {
|
|
switch (index) {
|
|
case kPointerCid:
|
|
case kFfiNativeFunctionCid:
|
|
#define CASE_FFI_CID(name) case kFfi##name##Cid:
|
|
CLASS_LIST_FFI_TYPE_MARKER(CASE_FFI_CID)
|
|
#undef CASE_FFI_CID
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
UNREACHABLE();
|
|
}
|
|
|
|
inline bool IsFfiPredefinedClassId(classid_t class_id) {
|
|
switch (class_id) {
|
|
case kPointerCid:
|
|
case kDynamicLibraryCid:
|
|
#define CASE_FFI_CID(name) case kFfi##name##Cid:
|
|
CLASS_LIST_FFI(CASE_FFI_CID)
|
|
#undef CASE_FFI_CID
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
UNREACHABLE();
|
|
}
|
|
|
|
inline bool IsFfiPointerClassId(intptr_t index) {
|
|
return index == kPointerCid;
|
|
}
|
|
|
|
inline bool IsFfiDynamicLibraryClassId(intptr_t index) {
|
|
return index == kDynamicLibraryCid;
|
|
}
|
|
|
|
inline bool IsInternalVMdefinedClassId(intptr_t index) {
|
|
return ((index < kNumPredefinedCids) && !IsImplicitFieldClassId(index));
|
|
}
|
|
|
|
// This is a set of classes that are not Dart classes whose representation
|
|
// is defined by the VM but are used in the VM code by computing the
|
|
// implicit field offsets of the various fields in the dart object.
|
|
inline bool IsImplicitFieldClassId(intptr_t index) {
|
|
return index == kByteBufferCid;
|
|
}
|
|
|
|
COMPILE_ASSERT(kByteBufferCid + 1 == kNullCid);
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_CLASS_ID_H_
|