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); }
void SwitchIRBuilder::OnCase(IR::RegOpnd * src1Opnd, IR::RegOpnd * src2Opnd, uint32 offset, uint32 targetOffset) { IR::BranchInstr * branchInstr; if (GlobOpt::IsSwitchOptEnabled(m_func->GetTopFunc()) && src2Opnd->m_sym->m_isIntConst && m_intConstSwitchCases->TestAndSet(src2Opnd->m_sym->GetIntConstValue())) { // We've already seen a case statement with the same int const value. No need to emit anything for this. return; } if (GlobOpt::IsSwitchOptEnabled(m_func->GetTopFunc()) && src2Opnd->m_sym->m_isStrConst && TestAndAddStringCaseConst(Js::JavascriptString::FromVar(src2Opnd->GetStackSym()->GetConstAddress(true)))) { // We've already seen a case statement with the same string const value. No need to emit anything for this. return; } branchInstr = IR::BranchInstr::New(m_eqOp, nullptr, src1Opnd, src2Opnd, m_func); branchInstr->m_isSwitchBr = true; /* // Switch optimization // For Integers - Binary Search or jump table optimization technique is used // For Strings - Dictionary look up technique is used. // // For optimizing, the Load instruction corresponding to the switch instruction is profiled in the interpreter. // Based on the dynamic profile data, optimization technique is decided. */ bool deferred = false; if (GlobOpt::IsSwitchOptEnabled(m_func->GetTopFunc())) { if (m_switchIntDynProfile && src2Opnd->m_sym->IsIntConst()) { CaseNode* caseNode = JitAnew(m_tempAlloc, CaseNode, branchInstr, offset, targetOffset, src2Opnd); m_caseNodes->Add(caseNode); deferred = true; } else if (m_switchStrDynProfile && src2Opnd->m_sym->m_isStrConst) { CaseNode* caseNode = JitAnew(m_tempAlloc, CaseNode, branchInstr, offset, targetOffset, src2Opnd); m_caseNodes->Add(caseNode); m_seenOnlySingleCharStrCaseNodes = m_seenOnlySingleCharStrCaseNodes && caseNode->GetSrc2StringConstLocal()->GetLength() == 1; deferred = true; } } if (!deferred) { FlushCases(offset); m_adapter->AddBranchInstr(branchInstr, offset, targetOffset); } }
IntBounds *IntBounds::New( const IntConstantBounds &constantBounds, const bool wasConstantUpperBoundEstablishedExplicitly, JitArenaAllocator *const allocator) { Assert(allocator); return JitAnew(allocator, IntBounds, constantBounds, wasConstantUpperBoundEstablishedExplicitly, allocator); }
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); }
void SwitchIRBuilder::Init(Func * func, JitArenaAllocator * tempAlloc, bool isAsmJs) { m_func = func; m_tempAlloc = tempAlloc; m_isAsmJs = isAsmJs; // caseNodes is a list of Case instructions m_caseNodes = CaseNodeList::New(tempAlloc); m_seenOnlySingleCharStrCaseNodes = true; m_intConstSwitchCases = JitAnew(tempAlloc, BVSparse<JitArenaAllocator>, tempAlloc); m_strConstSwitchCases = StrSwitchCaseList::New(tempAlloc); m_eqOp = isAsmJs ? Js::OpCode::BrEq_I4 : Js::OpCode::BrSrEq_A; m_ltOp = isAsmJs ? Js::OpCode::BrLt_I4 : Js::OpCode::BrLt_A; m_leOp = isAsmJs ? Js::OpCode::BrLe_I4 : Js::OpCode::BrLe_A; m_gtOp = isAsmJs ? Js::OpCode::BrGt_I4 : Js::OpCode::BrGt_A; m_geOp = isAsmJs ? Js::OpCode::BrGe_I4 : Js::OpCode::BrGe_A; m_subOp = isAsmJs ? Js::OpCode::Sub_I4 : Js::OpCode::Sub_A; }
IntBounds *IntBounds::Clone() const { JitArenaAllocator *const allocator = relativeLowerBounds.GetAllocator(); return JitAnew(allocator, IntBounds, *this); }