blob: 53ef9745d3cff82d7510b60f0f89e21abe4e310b [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// 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"
void
SymTable::Init(Func* func)
{
m_func = func;
m_propertyMap = JitAnew(func->m_alloc, PropertyMap, func->m_alloc);
m_propertyEquivBvMap = JitAnew(func->m_alloc, PropertyEquivBvMap, func->m_alloc);
}
///----------------------------------------------------------------------------
///
/// SymTable::Add
///
/// Add newSym to this symbol table.
///
///----------------------------------------------------------------------------
void
SymTable::Add(Sym * newSym)
{
int hash;
newSym->m_id += this->m_IDAdjustment;
hash = this->Hash(newSym->m_id);
AssertMsg(newSym->m_next == NULL, "Error inserting a symbol in the SymTable with a non-NULL next ptr.");
newSym->m_next = m_table[hash];
m_table[hash] = newSym;
if (newSym->IsPropertySym())
{
PropertySym * propertySym = newSym->AsPropertySym();
if (propertySym->m_fieldKind != PropertyKindWriteGuard)
{
SymIdPropIdPair pair(propertySym->m_stackSym->m_id, propertySym->m_propertyId);
#if DBG
PropertySym * foundPropertySym;
Assert(!this->m_propertyMap->TryGetValue(pair, &foundPropertySym));
#endif
this->m_propertyMap->Add(pair, propertySym);
}
if (propertySym->m_fieldKind == PropertyKindSlots ||
propertySym->m_fieldKind == PropertyKindData ||
propertySym->m_fieldKind == PropertyKindWriteGuard)
{
BVSparse<JitArenaAllocator> *bvEquivSet;
if (!this->m_propertyEquivBvMap->TryGetValue(propertySym->m_propertyId, &bvEquivSet))
{
bvEquivSet = JitAnew(this->m_func->m_alloc, BVSparse<JitArenaAllocator>, this->m_func->m_alloc);
this->m_propertyEquivBvMap->Add(propertySym->m_propertyId, bvEquivSet);
}
bvEquivSet->Set(propertySym->m_id);
propertySym->m_propertyEquivSet = bvEquivSet;
}
}
m_func->OnAddSym(newSym);
}
///----------------------------------------------------------------------------
///
/// SymTable::Find
///
/// Find the symbol with the given SymID in this table.
/// Returns NULL if it can't find one.
///
///----------------------------------------------------------------------------
Sym *
SymTable::Find(SymID id) const
{
int hash;
id += this->m_IDAdjustment;
hash = this->Hash(id);
for (Sym *sym = m_table[hash]; sym != NULL; sym = sym->m_next)
{
if (sym->m_id == id)
{
return sym;
}
}
return NULL;
}
///----------------------------------------------------------------------------
///
/// SymTable::FindStackSym
///
/// Find the stack symbol with the given SymID in this table. If the
/// symbol exists, it needs to be a StackSym.
/// Returns NULL if it can't find one.
///
///----------------------------------------------------------------------------
StackSym *
SymTable::FindStackSym(SymID id) const
{
Sym * sym;
sym = this->Find(id);
if (sym)
{
AssertMsg(sym->IsStackSym(), "Looking for StackSym, found something else");
return sym->AsStackSym();
}
return NULL;
}
///----------------------------------------------------------------------------
///
/// SymTable::FindPropertySym
///
/// Find the field symbol with the given SymID in this table. If the
/// symbol exists, it needs to be a PropertySym.
/// Returns NULL if it can't find one.
///
///----------------------------------------------------------------------------
PropertySym *
SymTable::FindPropertySym(SymID id) const
{
Sym * sym;
sym = this->Find(id);
if (sym)
{
AssertMsg(sym->IsPropertySym(), "Looking for PropertySym, found something else");
return sym->AsPropertySym();
}
return NULL;
}
///----------------------------------------------------------------------------
///
/// SymTable::FindPropertySym
///
/// Find the stack symbol with the corresponding to given StackSym and
/// propertyId.
/// Returns NULL if it can't find one.
///
///----------------------------------------------------------------------------
PropertySym *
SymTable::FindPropertySym(SymID stackSymID, int32 propertyId) const
{
PropertySym * propertySym = nullptr;
stackSymID += this->m_IDAdjustment;
SymIdPropIdPair pair(stackSymID, propertyId);
if (this->m_propertyMap->TryGetValue(pair, &propertySym))
{
Assert(propertySym->m_propertyId == propertyId);
Assert(propertySym->m_stackSym->m_id == stackSymID);
return propertySym;
}
return NULL;
}
///----------------------------------------------------------------------------
///
/// SymTable::Hash
///
///----------------------------------------------------------------------------
int
SymTable::Hash(SymID id) const
{
return (id % k_symTableSize);
}
///----------------------------------------------------------------------------
///
/// SymTable::SetStartingID
///
///----------------------------------------------------------------------------
void
SymTable::SetStartingID(SymID startingID)
{
AssertMsg(m_currentID == 0, "SymTable::SetStarting() can only be called before any symbols are allocated");
m_currentID = startingID;
}
void
SymTable::IncreaseStartingID(SymID IDIncrease)
{
m_currentID += IDIncrease;
}
///----------------------------------------------------------------------------
///
/// SymTable::NewID
///
///----------------------------------------------------------------------------
SymID
SymTable::NewID()
{
SymID newId = m_currentID++;
AssertMsg(m_currentID > newId, "Too many symbols: m_currentID overflow!");
return newId - m_IDAdjustment;
}
///----------------------------------------------------------------------------
///
/// SymTable::GetArgSlotSym
///
/// Get a StackSym to represent this argument slot.
///
///----------------------------------------------------------------------------
StackSym *
SymTable::GetArgSlotSym(Js::ArgSlot argSlotNum)
{
StackSym * argSym;
argSym = StackSym::NewArgSlotSym(argSlotNum, m_func);
argSym->m_offset = (argSlotNum - 1) * MachPtr;
argSym->m_allocated = true;
return argSym;
}
StackSym *
SymTable::GetImplicitParam(Js::ArgSlot paramSlotNum)
{
Assert(paramSlotNum - 1 < this->k_maxImplicitParamSlot);
if (this->m_implicitParams[paramSlotNum - 1])
{
return this->m_implicitParams[paramSlotNum - 1];
}
StackSym *implicitParamSym = StackSym::NewParamSlotSym(paramSlotNum, this->m_func, TyVar);
implicitParamSym->m_isImplicitParamSym = true;
this->m_implicitParams[paramSlotNum - 1] = implicitParamSym;
return implicitParamSym;
}
///----------------------------------------------------------------------------
///
/// SymTable::GetMaxSymID
///
/// Returns the largest SymID in the table at this point.
///
///----------------------------------------------------------------------------
SymID
SymTable::GetMaxSymID() const
{
return m_currentID - 1;
}
///----------------------------------------------------------------------------
///
/// SymTable::ClearStackSymScratch
///
///----------------------------------------------------------------------------
void
SymTable::ClearStackSymScratch()
{
FOREACH_SYM_IN_TABLE(sym, this)
{
if (sym->IsStackSym())
{
memset(&(sym->AsStackSym()->scratch), 0, sizeof(sym->AsStackSym()->scratch));
}
} NEXT_SYM_IN_TABLE;
}