blob: 8bb91765d23d25658a58a629938ccd7b8a41314b [file]
//-------------------------------------------------------------------------------------------------------
// 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<void*>(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<void*>(other->GetRuntimeCacheAddr());
m_data.runtimeCacheGuardAddr = reinterpret_cast<void*>(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<JitArenaAllocator>*
JITTimeConstructorCache::GetGuardedPropOps() const
{
return (BVSparse<JitArenaAllocator>*)(m_data.guardedPropOps & ~(intptr_t)1);
}
void
JITTimeConstructorCache::EnsureGuardedPropOps(JitArenaAllocator* allocator)
{
if (GetGuardedPropOps() == nullptr)
{
m_data.guardedPropOps = (intptr_t)Anew(allocator, BVSparse<JitArenaAllocator>, 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<JitArenaAllocator>* propOps)
{
Assert(GetGuardedPropOps() != nullptr);
GetGuardedPropOps()->Or(propOps);
}
intptr_t
JITTimeConstructorCache::GetRuntimeCacheAddr() const
{
return reinterpret_cast<intptr_t>(PointerValue(m_data.runtimeCacheAddr));
}
intptr_t
JITTimeConstructorCache::GetRuntimeCacheGuardAddr() const
{
return reinterpret_cast<intptr_t>(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;
}