//------------------------------------------------------------------------------------------------------- // Copyright (C) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. //------------------------------------------------------------------------------------------------------- #include "Backend.h" CompileAssert(sizeof(JITTimeConstructorCache) == sizeof(JITTimeConstructorCacheIDL)); JITTimeConstructorCache::JITTimeConstructorCache(const Js::JavascriptFunction* constructor, Js::ConstructorCache* runtimeCache) { Assert(constructor != nullptr); Assert(runtimeCache != nullptr); m_data.runtimeCacheAddr = runtimeCache; m_data.runtimeCacheGuardAddr = const_cast(runtimeCache->GetAddressOfGuardValue()); m_data.slotCount = runtimeCache->content.slotCount; m_data.inlineSlotCount = runtimeCache->content.inlineSlotCount; m_data.skipNewScObject = runtimeCache->content.skipDefaultNewObject; m_data.ctorHasNoExplicitReturnValue = runtimeCache->content.ctorHasNoExplicitReturnValue; m_data.typeIsFinal = runtimeCache->content.typeIsFinal; m_data.isUsed = false; m_data.guardedPropOps = 0; if (runtimeCache->IsNormal()) { JITType::BuildFromJsType(runtimeCache->content.type, (JITType*)&m_data.type); } } JITTimeConstructorCache::JITTimeConstructorCache(const JITTimeConstructorCache* other) { Assert(other != nullptr); Assert(other->GetRuntimeCacheAddr() != 0); m_data.runtimeCacheAddr = reinterpret_cast(other->GetRuntimeCacheAddr()); m_data.runtimeCacheGuardAddr = reinterpret_cast(other->GetRuntimeCacheGuardAddr()); m_data.type = *(TypeIDL*)PointerValue(other->GetType().t); m_data.slotCount = other->GetSlotCount(); m_data.inlineSlotCount = other->GetInlineSlotCount(); m_data.skipNewScObject = other->SkipNewScObject(); m_data.ctorHasNoExplicitReturnValue = other->CtorHasNoExplicitReturnValue(); m_data.typeIsFinal = other->IsTypeFinal(); m_data.isUsed = false; m_data.guardedPropOps = 0; // REVIEW: OOP JIT should we copy these when cloning? } JITTimeConstructorCache* JITTimeConstructorCache::Clone(JitArenaAllocator* allocator) const { JITTimeConstructorCache* clone = Anew(allocator, JITTimeConstructorCache, this); return clone; } BVSparse* JITTimeConstructorCache::GetGuardedPropOps() const { return (BVSparse*)(m_data.guardedPropOps & ~(intptr_t)1); } void JITTimeConstructorCache::EnsureGuardedPropOps(JitArenaAllocator* allocator) { if (GetGuardedPropOps() == nullptr) { m_data.guardedPropOps = (intptr_t)Anew(allocator, BVSparse, allocator); m_data.guardedPropOps |= 1; // tag it to prevent false positive after the arena address reuse in recycler } } void JITTimeConstructorCache::SetGuardedPropOp(uint propOpId) { Assert(GetGuardedPropOps() != nullptr); GetGuardedPropOps()->Set(propOpId); } void JITTimeConstructorCache::AddGuardedPropOps(const BVSparse* propOps) { Assert(GetGuardedPropOps() != nullptr); GetGuardedPropOps()->Or(propOps); } intptr_t JITTimeConstructorCache::GetRuntimeCacheAddr() const { return reinterpret_cast(PointerValue(m_data.runtimeCacheAddr)); } intptr_t JITTimeConstructorCache::GetRuntimeCacheGuardAddr() const { return reinterpret_cast(PointerValue(m_data.runtimeCacheGuardAddr)); } JITTypeHolder JITTimeConstructorCache::GetType() const { return JITTypeHolder((JITType*)&m_data.type); } int JITTimeConstructorCache::GetSlotCount() const { return m_data.slotCount; } int16 JITTimeConstructorCache::GetInlineSlotCount() const { return m_data.inlineSlotCount; } bool JITTimeConstructorCache::SkipNewScObject() const { return m_data.skipNewScObject != FALSE; } bool JITTimeConstructorCache::CtorHasNoExplicitReturnValue() const { return m_data.ctorHasNoExplicitReturnValue != FALSE; } bool JITTimeConstructorCache::IsTypeFinal() const { return m_data.typeIsFinal != FALSE; } bool JITTimeConstructorCache::IsUsed() const { return m_data.isUsed != FALSE; } // TODO: OOP JIT, does this need to flow back? void JITTimeConstructorCache::SetUsed(bool val) { m_data.isUsed = val; } JITTimeConstructorCacheIDL * JITTimeConstructorCache::GetData() { return &m_data; }