Explorar o código

ChakraCore fix for servicing release 18-02B: CVE-2018-0836

Michael Holman %!s(int64=8) %!d(string=hai) anos
pai
achega
b99d0dcbf5

+ 3 - 0
lib/Backend/FlowGraph.cpp

@@ -293,6 +293,7 @@ FlowGraph::Build(void)
         case Js::OpCode::TryCatch:
             if (this->catchLabelStack)
             {
+                AssertOrFailFast(!this->catchLabelStack->Empty());
                 this->catchLabelStack->Pop();
             }
             break;
@@ -300,6 +301,7 @@ FlowGraph::Build(void)
         case Js::OpCode::TryFinally:
             if (this->finallyLabelStack)
             {
+                AssertOrFailFast(!this->finallyLabelStack->Empty());
                 this->finallyLabelStack->Pop();
             }
             break;
@@ -497,6 +499,7 @@ FlowGraph::Build(void)
             }
             else if (instr->m_opcode == Js::OpCode::Finally)
             {
+                AssertOrFailFast(!this->finallyLabelStack->Empty());
                 this->finallyLabelStack->Pop();
             }
         }

+ 4 - 5
lib/Backend/FunctionJITTimeInfo.cpp

@@ -259,7 +259,7 @@ FunctionJITTimeInfo::GetRuntimeInfo() const
 ObjTypeSpecFldInfo *
 FunctionJITTimeInfo::GetObjTypeSpecFldInfo(uint index) const
 {
-    Assert(index < GetBody()->GetInlineCacheCount());
+    AssertOrFailFast(index < GetBody()->GetInlineCacheCount());
     if (m_data.objTypeSpecFldInfoArray == nullptr)
     {
         return nullptr;
@@ -271,7 +271,7 @@ FunctionJITTimeInfo::GetObjTypeSpecFldInfo(uint index) const
 ObjTypeSpecFldInfo *
 FunctionJITTimeInfo::GetGlobalObjTypeSpecFldInfo(uint index) const
 {
-    Assert(index < m_data.globalObjTypeSpecFldInfoCount);
+    AssertOrFailFast(index < m_data.globalObjTypeSpecFldInfoCount);
 
     return reinterpret_cast<ObjTypeSpecFldInfo *>(m_data.globalObjTypeSpecFldInfoArray[index]);
 }
@@ -298,8 +298,7 @@ FunctionJITTimeInfo::GetLdFldInlinee(Js::InlineCacheIndex inlineCacheIndex) cons
     {
         return nullptr;
     }
-    Assert(inlineCacheIndex < m_data.ldFldInlineeCount);
-
+    AssertOrFailFast(inlineCacheIndex < m_data.ldFldInlineeCount);
 
     return reinterpret_cast<const FunctionJITTimeInfo*>(m_data.ldFldInlinees[inlineCacheIndex]);
 }
@@ -312,7 +311,7 @@ FunctionJITTimeInfo::GetInlinee(Js::ProfileId profileId) const
     {
         return nullptr;
     }
-    Assert(profileId < m_data.inlineeCount);
+    AssertOrFailFast(profileId < m_data.inlineeCount);
 
     auto inlinee = reinterpret_cast<const FunctionJITTimeInfo *>(m_data.inlinees[profileId]);
     if (inlinee == nullptr && m_data.inlineesRecursionFlags[profileId])

+ 32 - 24
lib/Backend/IRBuilder.cpp

@@ -460,9 +460,7 @@ IRBuilder::Build()
         this->m_loopBodyLocalsStartSlot = (Js::PropertyId)(localsOffset / sizeof(Js::Var));
     }
 
-#if DBG
     m_offsetToInstructionCount = offsetToInstructionCount;
-#endif
     m_offsetToInstruction = JitAnewArrayZ(m_tempAlloc, IR::Instr *, offsetToInstructionCount);
 
 #ifdef BYTECODE_BRANCH_ISLAND
@@ -820,7 +818,8 @@ IRBuilder::Build()
                     m_lastInstr->m_opcode == Js::OpCode::RuntimeTypeError)
                 {
                     uint32 lastInstrOffset = m_lastInstr->GetByteCodeOffset();
-                    Assert(lastInstrOffset < m_offsetToInstructionCount);
+
+                    AssertOrFailFast(lastInstrOffset < m_offsetToInstructionCount);
 #if DBG
                     __analysis_assume(lastInstrOffset < this->m_offsetToInstructionCount);
 #endif
@@ -1069,7 +1068,7 @@ IRBuilder::CreateLabel(IR::BranchInstr * branchInstr, uint& offset)
 
     for (;;)
     {
-        Assert(offset < m_offsetToInstructionCount);
+        AssertOrFailFast(offset < m_offsetToInstructionCount);
         targetInstr = this->m_offsetToInstruction[offset];
         if (targetInstr != nullptr)
         {
@@ -1118,7 +1117,7 @@ IRBuilder::CreateLabel(IR::BranchInstr * branchInstr, uint& offset)
 
 void IRBuilder::InsertInstr(IR::Instr *instr, IR::Instr* insertBeforeInstr)
 {
-    Assert(insertBeforeInstr->GetByteCodeOffset() < m_offsetToInstructionCount);
+    AssertOrFailFast(insertBeforeInstr->GetByteCodeOffset() < m_offsetToInstructionCount);
     instr->SetByteCodeOffset(insertBeforeInstr);
     uint32 offset = insertBeforeInstr->GetByteCodeOffset();
     if (m_offsetToInstruction[offset] == insertBeforeInstr)
@@ -1150,7 +1149,7 @@ IRBuilder::AddInstr(IR::Instr *instr, uint32 offset)
     m_lastInstr->InsertAfter(instr);
     if (offset != Js::Constants::NoByteCodeOffset)
     {
-        Assert(offset < m_offsetToInstructionCount);
+        AssertOrFailFast(offset < m_offsetToInstructionCount);
         if (m_offsetToInstruction[offset] == nullptr)
         {
             m_offsetToInstruction[offset] = instr;
@@ -1213,6 +1212,7 @@ IRBuilder::BuildIndirOpnd(IR::RegOpnd *baseReg, uint32 offset, const char16 *des
 IR::SymOpnd *
 IRBuilder::BuildFieldOpnd(Js::OpCode newOpcode, Js::RegSlot reg, Js::PropertyId propertyId, Js::PropertyIdIndexType propertyIdIndex, PropertyKind propertyKind, uint inlineCacheIndex)
 {
+    AssertOrFailFast(inlineCacheIndex < m_func->GetJITFunctionBody()->GetInlineCacheCount() || inlineCacheIndex == Js::Constants::NoInlineCacheIndex);
     PropertySym * propertySym = BuildFieldSym(reg, propertyId, propertyIdIndex, inlineCacheIndex, propertyKind);
     IR::SymOpnd * symOpnd;
 
@@ -1798,7 +1798,8 @@ IRBuilder::BuildReg1(Js::OpCode newOpcode, uint32 offset, Js::RegSlot R0)
     case Js::OpCode::Catch:
         if (this->handlerOffsetStack)
         {
-            Assert(this->handlerOffsetStack->Top().Second() == true);
+            AssertOrFailFast(!this->handlerOffsetStack->Empty());
+            AssertOrFailFast(this->handlerOffsetStack->Top().Second() == true);
             this->handlerOffsetStack->Pop();
         }
         dstIsCatchObject = true;
@@ -6125,19 +6126,24 @@ IRBuilder::BuildProfiledCallI(Js::OpCode opcode, uint32 offset, Js::RegSlot retu
                 if(this->m_func->GetWorkItem()->GetJITTimeInfo())
                 {
                     const FunctionJITTimeInfo *inlinerData = this->m_func->GetWorkItem()->GetJITTimeInfo();
-                    if(!(this->IsLoopBody() && PHASE_OFF(Js::InlineInJitLoopBodyPhase, this->m_func)) && 
-                        inlinerData && inlinerData->GetInlineesBV() && (!inlinerData->GetInlineesBV()->Test(profileId)
+                    if (!(this->IsLoopBody() && PHASE_OFF(Js::InlineInJitLoopBodyPhase, this->m_func))
+                        && inlinerData && inlinerData->GetInlineesBV())
+                    {
+                        AssertOrFailFast(profileId < inlinerData->GetInlineesBV()->Length());
+                        if (!inlinerData->GetInlineesBV()->Test(profileId)
 #if DBG
-                        || (PHASE_STRESS(Js::BailOnNoProfilePhase, this->m_func->GetTopFunc()) &&
-                            (CONFIG_FLAG(SkipFuncCountForBailOnNoProfile) < 0 ||
-                            this->m_func->m_callSiteCount >= (uint)CONFIG_FLAG(SkipFuncCountForBailOnNoProfile)))
+                            || (PHASE_STRESS(Js::BailOnNoProfilePhase, this->m_func->GetTopFunc())
+                                && (CONFIG_FLAG(SkipFuncCountForBailOnNoProfile) < 0
+                                    || this->m_func->m_callSiteCount >= (uint)CONFIG_FLAG(SkipFuncCountForBailOnNoProfile)))
 #endif
-                        ))
-                    {
-                        this->InsertBailOnNoProfile(offset);
-                        isProtectedByNoProfileBailout = true;
+                            )
+                        {
+                            this->InsertBailOnNoProfile(offset);
+                            isProtectedByNoProfileBailout = true;
+                        }
                     }
-                    else
+
+                    if (!isProtectedByNoProfileBailout)
                     {
                         this->callTreeHasSomeProfileInfo = true;
                     }
@@ -6398,10 +6404,10 @@ IRBuilder::BuildCallCommon(IR::Instr * instr, StackSym * symDst, Js::ArgSlot arg
 #endif
 
     // Link all the args of this call by creating a def/use chain through the src2.
-
-    for (argInstr = this->m_argStack->Pop();
-        argInstr && argInstr->m_opcode != Js::OpCode::StartCall;
-        argInstr = this->m_argStack->Pop())
+    AssertOrFailFast(!m_argStack->Empty());
+    for (argInstr = m_argStack->Pop();
+        argInstr && !m_argStack->Empty() && argInstr->m_opcode != Js::OpCode::StartCall;
+        argInstr = m_argStack->Pop())
     {
         prevInstr->SetSrc2(argInstr->GetDst());
         prevInstr = argInstr;
@@ -6409,8 +6415,9 @@ IRBuilder::BuildCallCommon(IR::Instr * instr, StackSym * symDst, Js::ArgSlot arg
         count++;
 #endif
     }
+    AssertOrFailFast(argInstr->m_opcode == Js::OpCode::StartCall);
 
-    if (this->m_argStack->Empty())
+    if (m_argStack->Empty())
     {
         this->callTreeHasSomeProfileInfo = false;
     }
@@ -6736,7 +6743,8 @@ IRBuilder::BuildEmpty(Js::OpCode newOpcode, uint32 offset)
     case Js::OpCode::Finally:
         if (this->handlerOffsetStack)
         {
-            Assert(this->handlerOffsetStack->Top().Second() == false);
+            AssertOrFailFast(!this->handlerOffsetStack->Empty());
+            AssertOrFailFast(this->handlerOffsetStack->Top().Second() == false);
             this->handlerOffsetStack->Pop();
         }
         finallyBlockLevel++;
@@ -6971,7 +6979,6 @@ IRBuilder::BuildBr(Js::OpCode newOpcode, uint32 offset)
     IR::BranchInstr * branchInstr;
     const unaligned   Js::OpLayoutBr *branchInsn = m_jnReader.Br();
     unsigned int      targetOffset = m_jnReader.GetCurrentOffset() + branchInsn->RelativeJumpOffset;
-
 #ifdef BYTECODE_BRANCH_ISLAND
     bool isLongBranchIsland = (m_jnReader.PeekOp() == Js::OpCode::BrLong);
     if (isLongBranchIsland)
@@ -7154,6 +7161,7 @@ IRBuilder::BuildBrEnvProperty(Js::OpCode newOpcode, uint32 offset)
 BranchReloc *
 IRBuilder::AddBranchInstr(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset)
 {
+    AssertOrFailFast(targetOffset <= m_func->GetJITFunctionBody()->GetByteCodeLength());
     //
     // Loop jitting would be done only till the LoopEnd
     // Any branches beyond that offset are for the return stmt

+ 1 - 1
lib/Backend/IRBuilder.h

@@ -333,6 +333,7 @@ private:
     Func *              m_func;
     IR::Instr *         m_lastInstr;
     IR::Instr **        m_offsetToInstruction;
+    uint32              m_offsetToInstructionCount;
     uint32              m_functionStartOffset;
     Js::ByteCodeReader  m_jnReader;
     Js::StatementReader<Js::FunctionBody::ArenaStatementMapList> m_statementReader;
@@ -363,7 +364,6 @@ private:
     // used to estimate how much stack we should probe for at the
     // beginning of a JITted function.
 #if DBG
-    uint32              m_offsetToInstructionCount;
     uint32              m_callsOnStack;
 #endif
     uint32              m_argsOnStack;

+ 8 - 8
lib/Backend/IRBuilderAsmJs.cpp

@@ -111,9 +111,7 @@ IRBuilderAsmJs::Build()
         offsetToInstructionCount = lastOffset + 2;
     }
 
-#if DBG
     m_offsetToInstructionCount = offsetToInstructionCount;
-#endif
     m_offsetToInstruction = JitAnewArrayZ(m_tempAlloc, IR::Instr *, offsetToInstructionCount);
 
     LoadNativeCodeData();
@@ -219,7 +217,7 @@ IRBuilderAsmJs::AddInstr(IR::Instr * instr, uint32 offset)
     m_lastInstr->InsertAfter(instr);
     if (offset != Js::Constants::NoByteCodeOffset)
     {
-        Assert(offset < m_offsetToInstructionCount);
+        AssertOrFailFast(offset < m_offsetToInstructionCount);
         if (m_offsetToInstruction[offset] == nullptr)
         {
             m_offsetToInstruction[offset] = instr;
@@ -669,6 +667,7 @@ IRBuilderAsmJs::RegIsConstant(Js::RegSlot reg)
 BranchReloc *
 IRBuilderAsmJs::AddBranchInstr(IR::BranchInstr * branchInstr, uint32 offset, uint32 targetOffset)
 {
+    AssertOrFailFast(targetOffset <= m_func->GetJITFunctionBody()->GetByteCodeLength());
     //
     // Loop jitting would be done only till the LoopEnd
     // Any branches beyond that offset are for the return statement
@@ -1041,8 +1040,8 @@ IRBuilderAsmJs::CreateLabel(IR::BranchInstr * branchInstr, uint & offset)
     IR::Instr * targetInstr = nullptr;
     while (targetInstr == nullptr)
     {
+        AssertOrFailFast(offset < m_offsetToInstructionCount);
         targetInstr = m_offsetToInstruction[offset];
-        Assert(offset < m_offsetToInstructionCount);
         ++offset;
     }
 
@@ -1788,7 +1787,7 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl
                 instr->AsProfiledInstr()->u.profileId = profileId;
             }
         }
-
+        AssertOrFailFast(!this->m_argOffsetStack->Empty());
         argOffset = m_argOffsetStack->Pop();
         argOffset -= MachPtr;
         break;
@@ -1810,7 +1809,8 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl
     IR::Instr * argInstr = nullptr;
     IR::Instr * prevInstr = instr;
 
-    for (argInstr = m_argStack->Pop(); argInstr->m_opcode != Js::OpCode::StartCall; argInstr = m_argStack->Pop())
+    AssertOrFailFast(!this->m_argStack->Empty());
+    for (argInstr = m_argStack->Pop(); !m_argStack->Empty() && argInstr->m_opcode != Js::OpCode::StartCall; argInstr = m_argStack->Pop())
     {
         if (newOpcode == Js::OpCodeAsmJs::I_Call || newOpcode == Js::OpCodeAsmJs::ProfiledI_Call)
         {
@@ -1840,10 +1840,10 @@ IRBuilderAsmJs::BuildAsmCall(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::ArgSl
         count++;
     }
 
-    Assert(argInstr->m_opcode == Js::OpCode::StartCall);
+    AssertOrFailFast(argInstr->m_opcode == Js::OpCode::StartCall);
     argInstr->SetSrc1(IR::IntConstOpnd::New(count, TyUint16, m_func));
 
-    Assert(argOffset == 0);
+    AssertOrFailFast(argOffset == 0);
     prevInstr->SetSrc2(argInstr->GetDst());
 
 #ifdef ENABLE_SIMDJS

+ 0 - 2
lib/Backend/IRBuilderAsmJs.h

@@ -252,9 +252,7 @@ private:
     JitLoopBodyData*        m_jitLoopBodyData = nullptr;
     IRBuilderAsmJsSwitchAdapter m_switchAdapter;
     SwitchIRBuilder         m_switchBuilder;
-#if DBG
     uint32                  m_offsetToInstructionCount;
-#endif
 
 #define BUILD_LAYOUT_DEF(layout, ...) void Build##layout (Js::OpCodeAsmJs, uint32, __VA_ARGS__);
 #define Reg_Type Js::RegSlot

+ 12 - 12
lib/Backend/JITTimeFunctionBody.cpp

@@ -490,7 +490,7 @@ Js::PropertyId
 JITTimeFunctionBody::GetPropertyIdFromCacheId(uint cacheId) const
 {
     Assert(m_bodyData.cacheIdToPropertyIdMap);
-    Assert(cacheId < GetInlineCacheCount());
+    AssertOrFailFast(cacheId < GetInlineCacheCount());
     return static_cast<Js::PropertyId>(m_bodyData.cacheIdToPropertyIdMap[cacheId]);
 }
 
@@ -504,7 +504,7 @@ JITTimeFunctionBody::GetReferencedPropertyId(uint index) const
     uint mapIndex = index - TotalNumberOfBuiltInProperties;
 
     Assert(m_bodyData.referencedPropertyIdMap != nullptr);
-    Assert(mapIndex < m_bodyData.referencedPropertyIdCount);
+    AssertOrFailFast(mapIndex < m_bodyData.referencedPropertyIdCount);
 
     return m_bodyData.referencedPropertyIdMap[mapIndex];
 }
@@ -852,7 +852,7 @@ intptr_t
 JITTimeFunctionBody::GetConstantVar(Js::RegSlot location) const
 {
     Assert(m_bodyData.constTable != nullptr);
-    Assert(location < GetConstCount());
+    AssertOrFailFast(location < GetConstCount());
     Assert(location != 0);
 
     return static_cast<intptr_t>(m_bodyData.constTable[location - Js::FunctionBody::FirstRegSlot]);
@@ -863,7 +863,7 @@ JITTimeFunctionBody::GetConstantContent(Js::RegSlot location) const
 {
     Assert(m_bodyData.constTableContent != nullptr);
     Assert(m_bodyData.constTableContent->content != nullptr);
-    Assert(location < GetConstCount());
+    AssertOrFailFast(location < GetConstCount());
     Assert(location != 0);
 
     JITRecyclableObject * obj = (JITRecyclableObject *)m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
@@ -888,7 +888,7 @@ intptr_t
 JITTimeFunctionBody::GetInlineCache(uint index) const
 {
     Assert(m_bodyData.inlineCaches != nullptr);
-    Assert(index < GetInlineCacheCount());
+    AssertOrFailFast(index < GetInlineCacheCount());
 #if 0 // TODO: michhol OOP JIT, add these asserts
     Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone ||
         this->m_inlineCacheTypes[index] == InlineCacheTypeInlineCache);
@@ -901,7 +901,7 @@ intptr_t
 JITTimeFunctionBody::GetIsInstInlineCache(uint index) const
 {
     Assert(m_bodyData.inlineCaches != nullptr);
-    Assert(index < m_bodyData.isInstInlineCacheCount);
+    AssertOrFailFast(index < m_bodyData.isInstInlineCacheCount);
     index += GetInlineCacheCount();
 #if 0 // TODO: michhol OOP JIT, add these asserts
     Assert(this->m_inlineCacheTypes[index] == InlineCacheTypeNone ||
@@ -916,7 +916,7 @@ JITTimeFunctionBody::GetConstantType(Js::RegSlot location) const
 {
     Assert(m_bodyData.constTable != nullptr);
     Assert(m_bodyData.constTableContent != nullptr);
-    Assert(location < GetConstCount());
+    AssertOrFailFast(location < GetConstCount());
     Assert(location != 0);
     auto obj = m_bodyData.constTableContent->content[location - Js::FunctionBody::FirstRegSlot];
 
@@ -939,7 +939,7 @@ JITTimeFunctionBody::GetConstantType(Js::RegSlot location) const
 intptr_t
 JITTimeFunctionBody::GetLiteralRegexAddr(uint index) const
 {
-    Assert(index < m_bodyData.literalRegexCount);
+    AssertOrFailFast(index < m_bodyData.literalRegexCount);
 
     return m_bodyData.literalRegexes[index];
 }
@@ -968,7 +968,7 @@ JITTimeFunctionBody::GetRootObject() const
 Js::FunctionInfoPtrPtr
 JITTimeFunctionBody::GetNestedFuncRef(uint index) const
 {
-    Assert(index < GetNestedCount());
+    AssertOrFailFast(index < GetNestedCount());
     Js::FunctionInfoPtrPtr baseAddr = (Js::FunctionInfoPtrPtr)m_bodyData.nestedFuncArrayAddr;
     return baseAddr + index;
 }
@@ -976,7 +976,7 @@ JITTimeFunctionBody::GetNestedFuncRef(uint index) const
 intptr_t
 JITTimeFunctionBody::GetLoopHeaderAddr(uint loopNum) const
 {
-    Assert(loopNum < GetLoopCount());
+    AssertOrFailFast(loopNum < GetLoopCount());
     intptr_t baseAddr = m_bodyData.loopHeaderArrayAddr;
     return baseAddr + (loopNum * sizeof(Js::LoopHeader));
 }
@@ -984,7 +984,7 @@ JITTimeFunctionBody::GetLoopHeaderAddr(uint loopNum) const
 const JITLoopHeaderIDL *
 JITTimeFunctionBody::GetLoopHeaderData(uint loopNum) const
 {
-    Assert(loopNum < GetLoopCount());
+    AssertOrFailFast(loopNum < GetLoopCount());
     return &m_bodyData.loopHeaders[loopNum];
 }
 
@@ -1021,7 +1021,7 @@ JITTimeFunctionBody::HasPropIdToFormalsMap() const
 bool
 JITTimeFunctionBody::IsRegSlotFormal(Js::RegSlot reg) const
 {
-    Assert(reg < m_bodyData.propertyIdsForRegSlotsCount);
+    AssertOrFailFast(reg < m_bodyData.propertyIdsForRegSlotsCount);
     Js::PropertyId propId = (Js::PropertyId)m_bodyData.propertyIdsForRegSlots[reg];
     Js::PropertyIdArray * formalProps = GetFormalsPropIdArray();
     for (uint32 i = 0; i < formalProps->count; i++)

+ 12 - 10
lib/Backend/JITTimeProfileInfo.cpp

@@ -141,33 +141,35 @@ JITTimeProfileInfo::InitializeJITProfileData(
 const Js::LdElemInfo *
 JITTimeProfileInfo::GetLdElemInfo(Js::ProfileId ldElemId) const
 {
+    AssertOrFailFast(ldElemId < m_profileData.profiledLdElemCount);
     return &(reinterpret_cast<Js::LdElemInfo*>(m_profileData.ldElemData)[ldElemId]);
 }
 
 const Js::StElemInfo *
 JITTimeProfileInfo::GetStElemInfo(Js::ProfileId stElemId) const
 {
+    AssertOrFailFast(stElemId < m_profileData.profiledStElemCount);
     return &(reinterpret_cast<Js::StElemInfo*>(m_profileData.stElemData)[stElemId]);
 }
 
 Js::ArrayCallSiteInfo *
 JITTimeProfileInfo::GetArrayCallSiteInfo(Js::ProfileId index) const
 {
-    Assert(index < GetProfiledArrayCallSiteCount());
+    AssertOrFailFast(index < GetProfiledArrayCallSiteCount());
     return &(reinterpret_cast<Js::ArrayCallSiteInfo*>(m_profileData.arrayCallSiteData)[index]);
 }
 
 intptr_t
 JITTimeProfileInfo::GetArrayCallSiteInfoAddr(Js::ProfileId index) const
 {
-    Assert(index < GetProfiledArrayCallSiteCount());
+    AssertOrFailFast(index < GetProfiledArrayCallSiteCount());
     return m_profileData.arrayCallSiteDataAddr + index * sizeof(ArrayCallSiteIDL);
 }
 
 Js::FldInfo *
 JITTimeProfileInfo::GetFldInfo(uint fieldAccessId) const
 {
-    Assert(fieldAccessId < GetProfiledFldCount());
+    AssertOrFailFast(fieldAccessId < GetProfiledFldCount());
     return &(reinterpret_cast<Js::FldInfo*>(m_profileData.fldData)[fieldAccessId]);
 }
 
@@ -181,7 +183,7 @@ JITTimeProfileInfo::GetFldInfoAddr(uint fieldAccessId) const
 ValueType
 JITTimeProfileInfo::GetSlotLoad(Js::ProfileId slotLoadId) const
 {
-    Assert(slotLoadId < GetProfiledSlotCount());
+    AssertOrFailFast(slotLoadId < GetProfiledSlotCount());
     return reinterpret_cast<ValueType*>(m_profileData.slotData)[slotLoadId];
 }
 
@@ -197,32 +199,32 @@ JITTimeProfileInfo::GetReturnType(Js::OpCode opcode, Js::ProfileId callSiteId) c
     if (opcode < Js::OpCode::ProfiledReturnTypeCallI || (opcode > Js::OpCode::ProfiledReturnTypeCallIFlags && opcode < Js::OpCode::ProfiledReturnTypeCallIExtended) || opcode > Js::OpCode::ProfiledReturnTypeCallIExtendedFlags)
     {
         Assert(Js::DynamicProfileInfo::IsProfiledCallOp(opcode));
-        Assert(callSiteId < GetProfiledCallSiteCount());
+        AssertOrFailFast(callSiteId < GetProfiledCallSiteCount());
         return GetCallSiteInfo()[callSiteId].returnType;
     }
     Assert(Js::DynamicProfileInfo::IsProfiledReturnTypeOp(opcode));
-    Assert(callSiteId < GetProfiledReturnTypeCount());
+    AssertOrFailFast(callSiteId < GetProfiledReturnTypeCount());
     return reinterpret_cast<ValueType*>(m_profileData.returnTypeData)[callSiteId];
 }
 
 ValueType
 JITTimeProfileInfo::GetDivProfileInfo(Js::ProfileId divideId) const
 {
-    Assert(divideId < GetProfiledDivOrRemCount());
+    AssertOrFailFast(divideId < GetProfiledDivOrRemCount());
     return reinterpret_cast<ValueType*>(m_profileData.divideTypeInfo)[divideId];
 }
 
 ValueType
 JITTimeProfileInfo::GetSwitchProfileInfo(Js::ProfileId switchId) const
 {
-    Assert(switchId < GetProfiledSwitchCount());
+    AssertOrFailFast(switchId < GetProfiledSwitchCount());
     return reinterpret_cast<ValueType*>(m_profileData.switchTypeInfo)[switchId];
 }
 
 ValueType
 JITTimeProfileInfo::GetParameterInfo(Js::ArgSlot index) const
 {
-    Assert(index < GetProfiledInParamsCount());
+    AssertOrFailFast(index < GetProfiledInParamsCount());
     return reinterpret_cast<ValueType*>(m_profileData.parameterInfo)[index];
 }
 
@@ -231,7 +233,7 @@ JITTimeProfileInfo::GetLoopImplicitCallFlags(uint loopNum) const
 {
     // TODO: michhol OOP JIT, investigate vaibility of reenabling this assert
     // Assert(Js::DynamicProfileInfo::EnableImplicitCallFlags(functionBody));
-    Assert(loopNum < GetLoopCount());
+    AssertOrFailFast(loopNum < GetLoopCount());
 
     // Mask out the dispose implicit call. We would bailout on reentrant dispose,
     // but it shouldn't affect optimization.

+ 1 - 1
lib/Backend/ServerScriptContext.cpp

@@ -384,7 +384,7 @@ ServerScriptContext::Release()
 Field(Js::Var)*
 ServerScriptContext::GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex)
 {
-    Assert(m_moduleRecords.ContainsKey(moduleIndex));
+    AssertOrFailFast(m_moduleRecords.ContainsKey(moduleIndex));
     auto record = m_moduleRecords.Item(moduleIndex);
     return record->localExportSlotsAddr;
 }