Skip to content

Commit

Permalink
OS#9726517 : Give NewScFunc the correct nested function index when it…
Browse files Browse the repository at this point in the history
… we transfrom GetCachedFunc to NewScFunc in the backend
  • Loading branch information
rajatd committed Jul 24, 2017
1 parent 72a2b06 commit db2510c
Show file tree
Hide file tree
Showing 12 changed files with 10,312 additions and 10,189 deletions.
5 changes: 4 additions & 1 deletion lib/Backend/BackwardPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3062,8 +3062,11 @@ BackwardPass::DeadStoreOrChangeInstrForScopeObjRemoval(IR::Instr ** pInstrPrev)
{
instr->m_opcode = Js::OpCode::NewScFunc;
IR::Opnd * intConstOpnd = instr->UnlinkSrc2();
Assert(intConstOpnd->IsIntConstOpnd());

instr->ReplaceSrc1(intConstOpnd);
uint nestedFuncIndex = instr->m_func->GetJITFunctionBody()->GetNestedFuncIndexForSlotIdInCachedScope(intConstOpnd->AsIntConstOpnd()->AsUint32());

instr->ReplaceSrc1(IR::IntConstOpnd::New(nestedFuncIndex, TyUint32, instr->m_func));
instr->SetSrc2(IR::RegOpnd::New(currFunc->GetLocalFrameDisplaySym(), IRType::TyVar, currFunc));
}
break;
Expand Down
14 changes: 14 additions & 0 deletions lib/Backend/JITTimeFunctionBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ JITTimeFunctionBody::InitializeJITFunctionData(
jitBody->literalRegexCount = functionBody->GetLiteralRegexCount();
jitBody->literalRegexes = (intptr_t*)functionBody->GetLiteralRegexesWithLock();

Js::AuxArray<uint32> * slotIdInCachedScopeToNestedIndexArray = functionBody->GetSlotIdInCachedScopeToNestedIndexArrayWithLock();
if (slotIdInCachedScopeToNestedIndexArray)
{
jitBody->functionSlotsInCachedScopeCount = slotIdInCachedScopeToNestedIndexArray->count;
jitBody->slotIdInCachedScopeToNestedIndexArray = slotIdInCachedScopeToNestedIndexArray->elements;
}
#ifdef ASMJS_PLAT
if (functionBody->GetIsAsmJsFunction())
{
Expand Down Expand Up @@ -924,6 +930,14 @@ JITTimeFunctionBody::GetLiteralRegexAddr(uint index) const
return m_bodyData.literalRegexes[index];
}

uint
JITTimeFunctionBody::GetNestedFuncIndexForSlotIdInCachedScope(uint index) const
{
AssertOrFailFast(m_bodyData.slotIdInCachedScopeToNestedIndexArray != nullptr);
AssertOrFailFast(index < m_bodyData.functionSlotsInCachedScopeCount);
return m_bodyData.slotIdInCachedScopeToNestedIndexArray[index];
}

void *
JITTimeFunctionBody::GetConstTable() const
{
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/JITTimeFunctionBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class JITTimeFunctionBody
intptr_t GetFormalsPropIdArrayAddr() const;
intptr_t GetObjectLiteralTypeRef(uint index) const;
intptr_t GetLiteralRegexAddr(uint index) const;
uint GetNestedFuncIndexForSlotIdInCachedScope(uint index) const;
const AsmJsJITInfo * GetAsmJsInfo() const;
const JITTimeProfileInfo * GetReadOnlyProfileInfo() const;
JITTimeProfileInfo * GetProfileInfo() const;
Expand Down
3 changes: 3 additions & 0 deletions lib/JITIDL/JITTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ typedef struct FunctionBodyDataIDL
unsigned int literalRegexCount;
unsigned int auxDataCount;
unsigned int auxContextDataCount;
unsigned int functionSlotsInCachedScopeCount;

unsigned int fullStatementMapCount;
unsigned int propertyIdsForRegSlotsCount;
Expand Down Expand Up @@ -576,6 +577,8 @@ typedef struct FunctionBodyDataIDL

IDL_DEF([size_is(auxContextDataCount)]) byte * auxContextData;

IDL_DEF([size_is(functionSlotsInCachedScopeCount)]) unsigned int * slotIdInCachedScopeToNestedIndexArray;

ProfileDataIDL * profileData;

AsmJsDataIDL * asmJsData;
Expand Down
9 changes: 9 additions & 0 deletions lib/Runtime/Base/FunctionBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4916,6 +4916,7 @@ namespace Js
this->SetFormalsPropIdArray(nullptr);
this->SetReferencedPropertyIdMap(nullptr);
this->SetLiteralRegexs(nullptr);
this->SetSlotIdInCachedScopeToNestedIndexArray(nullptr);
this->SetStatementMaps(nullptr);
this->SetCodeGenGetSetRuntimeData(nullptr);
this->SetPropertyIdOnRegSlotsContainer(nullptr);
Expand Down Expand Up @@ -6303,6 +6304,13 @@ namespace Js
this->SetLiteralRegexs(nullptr);
}

Js::AuxArray<uint32> * FunctionBody::AllocateSlotIdInCachedScopeToNestedIndexArray(uint32 slotCount)
{
Js::AuxArray<uint32> * slotIdToNestedIndexArray = RecyclerNewPlusLeaf(GetScriptContext()->GetRecycler(), slotCount * sizeof(uint32), Js::AuxArray<uint32>, slotCount);
SetSlotIdInCachedScopeToNestedIndexArray(slotIdToNestedIndexArray);
return slotIdToNestedIndexArray;
}

void FunctionBody::ResetProfileIds()
{
#if ENABLE_PROFILE_INFO
Expand Down Expand Up @@ -6330,6 +6338,7 @@ namespace Js
ResetLiteralRegexes();
ResetLoops();
ResetProfileIds();
ResetSlotIdInCachedScopeToNestedIndexArray();

SetFirstTmpRegister(Constants::NoRegister);
SetLocalClosureRegister(Constants::NoRegister);
Expand Down
8 changes: 8 additions & 0 deletions lib/Runtime/Base/FunctionBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,7 @@ namespace Js
ScopeInfo = 20,
FormalsPropIdArray = 21,
ForInCacheArray = 22,
SlotIdInCachedScopeToNestedIndexArray = 23,

Max,
Invalid = 0xff
Expand Down Expand Up @@ -3463,10 +3464,17 @@ namespace Js
void SetLiteralRegex(const uint index, UnifiedRegex::RegexPattern *const pattern);
Field(DynamicType*)* GetObjectLiteralTypes() const { return static_cast<Field(DynamicType*)*>(this->GetAuxPtr(AuxPointerType::ObjLiteralTypes)); }
Field(DynamicType*)* GetObjectLiteralTypesWithLock() const { return static_cast<Field(DynamicType*)*>(this->GetAuxPtrWithLock(AuxPointerType::ObjLiteralTypes)); }

Js::AuxArray<uint32> * GetSlotIdInCachedScopeToNestedIndexArray() const { return static_cast<Js::AuxArray<uint32> *>(this->GetAuxPtr(AuxPointerType::SlotIdInCachedScopeToNestedIndexArray)); }
Js::AuxArray<uint32> * GetSlotIdInCachedScopeToNestedIndexArrayWithLock() const { return static_cast<Js::AuxArray<uint32> *>(this->GetAuxPtrWithLock(AuxPointerType::SlotIdInCachedScopeToNestedIndexArray)); }
Js::AuxArray<uint32> * AllocateSlotIdInCachedScopeToNestedIndexArray(uint32 slotCount);

private:
void ResetLiteralRegexes();
void ResetObjectLiteralTypes();
void SetObjectLiteralTypes(DynamicType** objLiteralTypes) { this->SetAuxPtr(AuxPointerType::ObjLiteralTypes, objLiteralTypes); };
void SetSlotIdInCachedScopeToNestedIndexArray(Js::AuxArray<uint32> * slotIdInCachedScopeToNestedIndexArray) { this->SetAuxPtr(AuxPointerType::SlotIdInCachedScopeToNestedIndexArray, slotIdInCachedScopeToNestedIndexArray); }
void ResetSlotIdInCachedScopeToNestedIndexArray() { SetSlotIdInCachedScopeToNestedIndexArray(nullptr); }
public:

void ResetByteCodeGenState();
Expand Down
5 changes: 5 additions & 0 deletions lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,9 @@ void ByteCodeGenerator::DefineCachedFunctions(FuncInfo *funcInfoParent)

Js::FuncInfoArray *info = AnewPlus(alloc, extraBytes, Js::FuncInfoArray, slotCount);

// slotCount is guaranteed to be non-zero here.
Js::AuxArray<uint32> * slotIdInCachedScopeToNestedIndexArray = funcInfoParent->GetParsedFunctionBody()->AllocateSlotIdInCachedScopeToNestedIndexArray(slotCount);

slotCount = 0;

auto fillEntries = [&](ParseNode *pnodeFnc)
Expand All @@ -1069,6 +1072,8 @@ void ByteCodeGenerator::DefineCachedFunctions(FuncInfo *funcInfoParent)
Js::FuncInfoEntry *entry = &info->elements[slotCount];
entry->nestedIndex = pnodeFnc->sxFnc.nestedIndex;
entry->scopeSlot = sym->GetScopeSlot();

slotIdInCachedScopeToNestedIndexArray->elements[slotCount] = pnodeFnc->sxFnc.nestedIndex;
slotCount++;
}
};
Expand Down
62 changes: 62 additions & 0 deletions lib/Runtime/ByteCode/ByteCodeSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ namespace Js
const int magicEndOfAsmJsModuleInfo = *(int*)"]asmmodinfo";
const int magicStartOfPropIdsOfFormals = *(int*)"propIdOfFormals[";
const int magicEndOfPropIdsOfFormals = *(int*)"]propIdOfFormals";
const int magicStartOfSlotIdToNestedIndexArray = *(int*)"slotIdToNestedIndexArray[";
const int magicEndOfSlotIdToNestedIndexArray = *(int*)"]slotIdToNestedIndexArray"
#endif

// Serialized files are architecture specific
Expand Down Expand Up @@ -1566,6 +1568,33 @@ class ByteCodeBufferBuilder
return size;
}

uint32 AddSlotIdInCachedScopeToNestedIndexArray(BufferBuilderList& builder, FunctionBody * functionBody)
{
if (functionBody->GetSlotIdInCachedScopeToNestedIndexArray() == nullptr)
{
return PrependByte(builder, _u("SlotIdInCachedScopeToNestedIndexArray exists"), 0);
}

uint32 size = 0;

#ifdef BYTE_CODE_MAGIC_CONSTANTS
size += PrependInt32(builder, _u("Start SlotIdInCachedScopeToNestedIndexArray"), magicStartOfSlotIdToNestedIndexArray);
#endif

size += PrependByte(builder, _u("SlotIdInCachedScopeToNestedIndexArray exists"), 1);
Js::AuxArray<uint32> * slotIdToNestedIndexArray = functionBody->GetSlotIdInCachedScopeToNestedIndexArray();
size += PrependInt32(builder, _u("SlotIdInCachedScopeToNestedIndexArray count"), slotIdToNestedIndexArray->count);
for (uint i = 0; i < slotIdToNestedIndexArray->count; i++)
{
size += PrependInt32(builder, _u("Nested function index for slot id in cached scope"), slotIdToNestedIndexArray->elements[i]);
}

#ifdef BYTE_CODE_MAGIC_CONSTANTS
size += PrependInt32(builder, _u("End magicStartOfSlotIdToNestedIndexArray"), magicEndOfSlotIdToNestedIndexArray);
#endif
return size;
}

// Gets the number of debugger slot array scopes there are in the function body's scope chain list.
uint32 GetDebuggerScopeSlotArrayCount(FunctionBody * function)
{
Expand Down Expand Up @@ -2129,6 +2158,7 @@ class ByteCodeBufferBuilder
AddReferencedPropertyIdMap(builder, function);

AddPropertyIdsForScopeSlotArray(builder, function);
AddSlotIdInCachedScopeToNestedIndexArray(builder, function);

uint debuggerScopeSlotArraySize = GetDebuggerScopeSlotArrayCount(function);
PrependInt32(builder, _u("Debugger Scope Slot Array Size"), debuggerScopeSlotArraySize);
Expand Down Expand Up @@ -2985,6 +3015,37 @@ class ByteCodeBufferReader
return current;
}

const byte * ReadSlotIdInCachedScopeToNestedIndexArray(const byte * current, FunctionBody * functionBody)
{
byte slotIdInCachedScopeToNestedIndexArrayExists;
current = ReadByte(current, &slotIdInCachedScopeToNestedIndexArrayExists);
if (slotIdInCachedScopeToNestedIndexArrayExists)
{
#ifdef BYTE_CODE_MAGIC_CONSTANTS
int constant;
current = ReadInt32(current, &constant);
Assert(constant == magicStartOfSlotIdToNestedIndexArray);
#endif
uint32 count;
current = ReadUInt32(current, &count);

Js::AuxArray<uint32> * slotIdInCachedScopeToNestedIndexArray = functionBody->AllocateSlotIdInCachedScopeToNestedIndexArray(count);

uint32 value;
for (uint i = 0; i < count; i++)
{
current = ReadUInt32(current, &value);
slotIdInCachedScopeToNestedIndexArray->elements[i] = value;
}
#ifdef BYTE_CODE_MAGIC_CONSTANTS
current = ReadInt32(current, &constant);
Assert(constant == magicEndOfSlotIdToNestedIndexArray);
#endif
}
return current;
}


const byte * ReadSlotArrayDebuggerScopeProperties(const byte * current, FunctionBody* function, DebuggerScope* debuggerScope, uint propertyCount)
{
Assert(function);
Expand Down Expand Up @@ -3765,6 +3826,7 @@ class ByteCodeBufferReader
(*functionBody)->AllocateInlineCache();

current = ReadPropertyIdsForScopeSlotArray(current, *functionBody);
current = ReadSlotIdInCachedScopeToNestedIndexArray(current, *functionBody);

uint debuggerScopeCount = 0;
current = ReadUInt32(current, &debuggerScopeCount);
Expand Down
Loading

0 comments on commit db2510c

Please sign in to comment.