Skip to content

Commit c427ca9

Browse files
committed
Implement fixup table for most of the NativeCodeData allocated structures
1 parent 429de60 commit c427ca9

11 files changed

+376
-19
lines changed

lib/Backend/BailOut.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@ class BailOutRecord
167167
static uint32 GetArgumentsObjectOffset();
168168
static const uint BailOutRegisterSaveSlotCount = LinearScanMD::RegisterSaveSlotCount;
169169

170+
void Fixup(NativeCodeData::DataChunk* chunkList)
171+
{
172+
FixupNativeDataPointer(globalBailOutRecordTable, chunkList);
173+
FixupNativeDataPointer(argOutOffsetInfo, chunkList);
174+
FixupNativeDataPointer(parent, chunkList);
175+
FixupNativeDataPointer(constants, chunkList);
176+
FixupNativeDataPointer(ehBailoutData, chunkList);
177+
FixupNativeDataPointer(stackLiteralBailOutRecord, chunkList);
178+
}
179+
170180
public:
171181
template <size_t N>
172182
void FillNativeRegToByteCodeRegMap(uint (&nativeRegToByteCodeRegMap)[N]);
@@ -248,6 +258,15 @@ class BailOutRecord
248258
int * outParamOffsets;
249259
uint startCallCount;
250260
uint argOutSymStart;
261+
void Fixup(NativeCodeData::DataChunk* chunkList)
262+
{
263+
FixupNativeDataPointer(argOutFloat64Syms, chunkList);
264+
FixupNativeDataPointer(argOutLosslessInt32Syms, chunkList);
265+
FixupNativeDataPointer(argOutSimd128F4Syms, chunkList);
266+
FixupNativeDataPointer(argOutSimd128I4Syms, chunkList);
267+
FixupNativeDataPointer(startCallOutParamCounts, chunkList);
268+
FixupNativeDataPointer(outParamOffsets, chunkList);
269+
}
251270
};
252271

253272
// The offset to 'globalBailOutRecordTable' is hard-coded in LinearScanMD::SaveAllRegisters, so let this be the first member variable
@@ -427,4 +446,59 @@ struct GlobalBailOutRecordDataTable
427446
}
428447
}
429448
}
449+
450+
void Fixup(NativeCodeData::DataChunk* chunkList)
451+
{
452+
FixupNativeDataPointer(globalBailOutRecordDataRows, chunkList);
453+
}
430454
};
455+
#if DBG
456+
template<> void NativeCodeData::AllocatorT<BailOutRecord::StackLiteralBailOutRecord>::Fixup(void* pThis, NativeCodeData::DataChunk* chunkList) {}
457+
template<> void NativeCodeData::AllocatorT<Js::EquivalentPropertyEntry>::Fixup(void* pThis, NativeCodeData::DataChunk* chunkList) {}
458+
template<> void NativeCodeData::AllocatorT<GlobalBailOutRecordDataRow>::Fixup(void* pThis, NativeCodeData::DataChunk* chunkList) {}
459+
#else
460+
template<>
461+
char*
462+
NativeCodeData::AllocatorT<BailOutRecord::StackLiteralBailOutRecord>::Alloc(size_t requestedBytes)
463+
{
464+
return __super::Alloc(requestedBytes);
465+
}
466+
template<>
467+
char*
468+
NativeCodeData::AllocatorT<BailOutRecord::StackLiteralBailOutRecord>::AllocZero(size_t requestedBytes)
469+
{
470+
return __super::AllocZero(requestedBytes);
471+
}
472+
473+
template<>
474+
char*
475+
NativeCodeData::AllocatorT<Js::EquivalentPropertyEntry>::Alloc(size_t requestedBytes)
476+
{
477+
return __super::Alloc(requestedBytes);
478+
}
479+
template<>
480+
char*
481+
NativeCodeData::AllocatorT<Js::EquivalentPropertyEntry>::AllocZero(size_t requestedBytes)
482+
{
483+
return __super::AllocZero(requestedBytes);
484+
}
485+
486+
template<>
487+
char*
488+
NativeCodeData::AllocatorT<GlobalBailOutRecordDataRow>::Alloc(size_t requestedBytes)
489+
{
490+
return __super::Alloc(requestedBytes);
491+
}
492+
template<>
493+
char*
494+
NativeCodeData::AllocatorT<GlobalBailOutRecordDataRow>::AllocZero(size_t requestedBytes)
495+
{
496+
return __super::AllocZero(requestedBytes);
497+
}
498+
#endif
499+
500+
template<> void NativeCodeData::AllocatorT<GlobalBailOutRecordDataTable*>::Fixup(void* pThis, NativeCodeData::DataChunk* chunkList)
501+
{
502+
// for every pointer needs to update the table
503+
NativeCodeData::AddFixupEntryForPointerArray(pThis, chunkList);
504+
}

lib/Backend/Encoder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ Encoder::Encode()
402402

403403
// The extra room for sizeof(Js::TypePropertyGuardEntry) allocated by HeapNewPlus will be used for the terminating invalid propertyId.
404404
// Review (jedmiad): Skip zeroing? This is heap allocated so there shouldn't be any false recycler references.
405-
Js::TypeGuardTransferEntry* typeGuardTransferRecord = HeapNewPlusZ(typeGuardTransferSize, Js::TypeGuardTransferEntry);
405+
Js::TypeGuardTransferEntry* typeGuardTransferRecord = NativeCodeDataNewPlusZ(typeGuardTransferSize, m_func->GetNativeCodeDataAllocator(), Js::TypeGuardTransferEntry);
406406

407407
Func* func = this->m_func;
408408

@@ -426,6 +426,8 @@ Encoder::Encode()
426426

427427
Assert(reinterpret_cast<char*>(dstEntry) <= reinterpret_cast<char*>(typeGuardTransferRecord) + typeGuardTransferSize + sizeof(Js::TypeGuardTransferEntry));
428428

429+
//TODO: OOP JIT need a way to pass back the jitTransferData and in main process it need to amend the reference to typeGuardTransferRecord
430+
// or just have a allocation offset to locate the typeGuardTransferRecord
429431
entryPointInfo->RecordTypeGuards(this->m_func->indexedPropertyGuardCount, typeGuardTransferRecord, typeGuardTransferSize);
430432
}
431433

lib/Backend/Func.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -433,41 +433,47 @@ Func::Codegen()
433433
{
434434
// fill in the fixup list by scanning the memory
435435
// todo: this should be done while generating code
436-
unsigned int count = 0;
436+
437437
NativeCodeData::DataChunk *chunk = (NativeCodeData::DataChunk*)dataAllocator->chunkList;
438438
NativeCodeData::DataChunk *next1 = chunk;
439439
while (next1)
440440
{
441-
count++;
441+
if (next1->fixupFunc)
442+
{
443+
next1->fixupFunc(next1->data, chunk);
444+
}
445+
446+
#if DBG
442447
NativeCodeData::DataChunk *next2 = chunk;
443448
while (next2)
444449
{
445450
for (int i = 0; i < next1->len / sizeof(void*); i++)
446451
{
447452
if (((void**)next1->data)[i] == (void*)next2->data)
448453
{
449-
NativeCodeData::AddFixupEntry((void*)next2->data, &((void**)next1->data)[i], next1->data);
454+
NativeCodeData::VerifyExistFixupEntry((void*)next2->data, &((void**)next1->data)[i], next1->data);
455+
//NativeCodeData::AddFixupEntry((void*)next2->data, &((void**)next1->data)[i], next1->data, chunk);
450456
}
451457
}
452458
next2 = next2->next;
453459
}
460+
#endif
454461
next1 = next1->next;
455462
}
456463
////
457-
464+
458465

459466
JITOutputData* jitOutputData = m_output.GetOutputData();
460467

461-
462-
jitOutputData->nativeDataFixupTable = (NativeDataFixupTable*)midl_user_allocate(sizeof(NativeDataFixupTable) + sizeof(NativeDataFixupRecord)* (dataAllocator->allocCount - 1));
468+
jitOutputData->nativeDataFixupTable = (NativeDataFixupTable*)midl_user_allocate(offsetof(NativeDataFixupTable, fixupRecords) + sizeof(NativeDataFixupRecord)* (dataAllocator->allocCount));
463469
jitOutputData->nativeDataFixupTable->count = dataAllocator->allocCount;
464470

465471
jitOutputData->buffer = (NativeDataBuffer*)midl_user_allocate(offsetof(NativeDataBuffer, data) + dataAllocator->totalSize);
466472
jitOutputData->buffer->len = dataAllocator->totalSize;
467473

468474

469475
unsigned int len = 0;
470-
count = 0;
476+
unsigned int count = 0;
471477
next1 = chunk;
472478
while (next1)
473479
{

lib/Backend/InlineeFrameInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ struct InlineeFrameRecord
113113
void DumpOffset(int offset) const;
114114
#endif
115115

116+
void Fixup(NativeCodeData::DataChunk* chunkList)
117+
{
118+
FixupNativeDataPointer(argOffsets, chunkList);
119+
FixupNativeDataPointer(constants, chunkList);
120+
FixupNativeDataPointer(parent, chunkList);
121+
}
122+
116123
private:
117124
void Restore(Js::FunctionBody* functionBody, InlinedFrameLayout *outerMostFrame, Js::JavascriptCallStackLayout * layout) const;
118125
Js::Var Restore(int offset, bool isFloat64, bool isInt32, Js::JavascriptCallStackLayout * layout, Js::FunctionBody* functionBody) const;

lib/Backend/LinearScan.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1903,7 +1903,7 @@ LinearScan::FillBailOutRecord(IR::Instr * instr)
19031903
linearScanMD.GenerateBailOut(instr, state.registerSaveSyms, _countof(state.registerSaveSyms));
19041904

19051905
// generate the constant table
1906-
Js::Var * constants = NativeCodeDataNewArray(allocator, Js::Var, state.constantList.Count());
1906+
Js::Var * constants = NativeCodeDataNewArrayNoFixup(allocator, Js::Var, state.constantList.Count());
19071907
uint constantCount = state.constantList.Count();
19081908
while (!state.constantList.Empty())
19091909
{

lib/Backend/NativeCodeData.cpp

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,101 @@ NativeCodeData::~NativeCodeData()
1818
PERF_COUNTER_SUB(Code, TotalNativeCodeDataSize, this->size);
1919
}
2020

21-
// dataAddr: target address
21+
// targetAddr: target address
2222
// startAddress: current data start address
2323
// addrToFixup: address that currently pointing to dataAddr, which need to be updated
2424
void
25-
NativeCodeData::AddFixupEntry(void* dataAddr, void* addrToFixup, void* startAddress)
25+
NativeCodeData::AddFixupEntry(void* targetAddr, void* addrToFixup, void* startAddress, DataChunk * chunkList)
2626
{
27+
Assert(addrToFixup >= startAddress);
28+
Assert(((__int64)addrToFixup) % sizeof(void*) == 0);
29+
30+
if (targetAddr == nullptr)
31+
{
32+
return;
33+
}
34+
35+
DataChunk* targetChunk = ((DataChunk*)((char*)targetAddr - offsetof(DataChunk, data)));
36+
37+
#if DBG
38+
bool foundTargetChunk = false;
39+
while (chunkList)
40+
{
41+
foundTargetChunk |= (chunkList == targetChunk);
42+
chunkList = chunkList->next;
43+
}
44+
AssertMsg(foundTargetChunk, "current pointer is not allocated with NativeCodeData allocator?"); // change to valid check instead of assertion?
45+
#endif
46+
2747
DataChunk* chunk = (DataChunk*)((char*)startAddress - offsetof(DataChunk, data));
2848

2949
NativeDataFixupEntry* entry = (NativeDataFixupEntry*)midl_user_allocate(sizeof(NativeDataFixupEntry));
3050
entry->addrOffset = (unsigned int)((__int64)addrToFixup - (__int64)startAddress);
31-
entry->targetTotalOffset = ((DataChunk*)((char*)dataAddr - offsetof(DataChunk, data)))->offset;
51+
Assert(entry->addrOffset <= chunk->len - sizeof(void*));
52+
53+
entry->targetTotalOffset = targetChunk->offset;
3254
entry->next = chunk->fixupList;
3355
chunk->fixupList = entry;
56+
}
57+
58+
void
59+
NativeCodeData::AddFixupEntryForPointerArray(void* startAddress, DataChunk * chunkList)
60+
{
61+
DataChunk* chunk = (DataChunk*)((char*)startAddress - offsetof(DataChunk, data));
62+
Assert(chunk->len % sizeof(void*) == 0);
63+
for (int i = 0; i < chunk->len / sizeof(void*); i++)
64+
{
65+
void* targetAddr = *(void**)startAddress;
66+
67+
if (targetAddr == nullptr)
68+
{
69+
continue;
70+
}
3471

72+
DataChunk* targetChunk = ((DataChunk*)((char*)targetAddr - offsetof(DataChunk, data)));
73+
74+
#if DBG
75+
bool foundTargetChunk = false;
76+
DataChunk* chunk1 = chunkList;
77+
while (chunk1 && !foundTargetChunk)
78+
{
79+
foundTargetChunk = (chunk1 == targetChunk);
80+
chunk1 = chunk1->next;
81+
}
82+
AssertMsg(foundTargetChunk, "current pointer is not allocated with NativeCodeData allocator?"); // change to valid check instead of assertion?
83+
#endif
84+
85+
NativeDataFixupEntry* entry = (NativeDataFixupEntry*)midl_user_allocate(sizeof(NativeDataFixupEntry));
86+
entry->addrOffset = i*sizeof(void*);
87+
entry->targetTotalOffset = targetChunk->offset;
88+
entry->next = chunk->fixupList;
89+
chunk->fixupList = entry;
90+
}
91+
}
92+
93+
void
94+
NativeCodeData::VerifyExistFixupEntry(void* targetAddr, void* addrToFixup, void* startAddress)
95+
{
96+
DataChunk* chunk = (DataChunk*)((char*)startAddress - offsetof(DataChunk, data));
97+
if (chunk->len == 0)
98+
{
99+
return;
100+
}
101+
unsigned int offset = (unsigned int)((char*)addrToFixup - (char*)startAddress);
102+
Assert(offset <= chunk->len);
103+
104+
NativeDataFixupEntry* entry = chunk->fixupList;
105+
while (entry)
106+
{
107+
if (entry->addrOffset == offset)
108+
{
109+
DataChunk* targetChunk = ((DataChunk*)((char*)targetAddr - offsetof(DataChunk, data)));
110+
Assert(entry->targetTotalOffset == targetChunk->offset);
111+
return;
112+
}
113+
entry = entry->next;
114+
}
115+
AssertMsg(false, "Data chunk not found");
35116
}
36117

37118
void
@@ -74,11 +155,15 @@ NativeCodeData::Allocator::Alloc(size_t requestSize)
74155
requestSize = Math::Align(requestSize, sizeof(void*));
75156
DataChunk * newChunk = HeapNewStructPlus(requestSize, DataChunk);
76157

158+
#if DBG
159+
newChunk->dataType = nullptr;
160+
#endif
77161

78162
newChunk->next = nullptr;
79163
newChunk->allocIndex = this->allocCount++;
80164
newChunk->len = (unsigned int)requestSize;
81165
newChunk->fixupList = nullptr;
166+
newChunk->fixupFunc = nullptr;
82167
newChunk->offset = this->totalSize;
83168
if (this->chunkList == nullptr)
84169
{

0 commit comments

Comments
 (0)