Skip to content

Commit 1c88c65

Browse files
committed
Hello world works
1 parent cfb1cd3 commit 1c88c65

38 files changed

+459
-232
lines changed

lib/Backend/Backend.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,14 @@ enum IRDumpFlags
114114
#include "ChakraJIT.h"
115115
#include "JITTimeProfileInfo.h"
116116
#include "CodeGenWorkItemType.h"
117+
#include "CodeGenAllocators.h"
117118
#include "ThreadContextInfo.h"
118119
#include "ScriptContextInfo.h"
119120
#include "JITOutput.h"
120121
#include "JITTimeScriptContext.h"
121122
#include "JITTimeFunctionBody.h"
122123
#include "JITTimeWorkItem.h"
123124
#include "NativeCodeData.h"
124-
#include "CodeGenAllocators.h"
125125
#include "IRType.h"
126126
#include "md.h"
127127
#include "..\Runtime\ByteCode\BackEndOpcodeAttr.h"

lib/Backend/CodeGenAllocators.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
//-------------------------------------------------------------------------------------------------------
55
#include "BackEnd.h"
66

7-
CodeGenAllocators::CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext)
7+
CodeGenAllocators::CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext, HANDLE processHandle)
88
: pageAllocator(policyManager, Js::Configuration::Global.flags, PageAllocatorType_BGJIT,
99
(AutoSystemInfo::Data.IsLowMemoryProcess() ?
1010
PageAllocator::DefaultLowMaxFreePageCount :
1111
PageAllocator::DefaultMaxFreePageCount))
1212
, allocator(L"NativeCode", &pageAllocator, Js::Throw::OutOfMemory)
13-
, emitBufferManager(policyManager, &allocator, scriptContext, L"JIT code buffer", ALLOC_XDATA)
13+
, emitBufferManager(policyManager, &allocator, scriptContext, L"JIT code buffer", ALLOC_XDATA, processHandle)
1414
#if !_M_X64_OR_ARM64 && _CONTROL_FLOW_GUARD
1515
, canCreatePreReservedSegment(false)
1616
#endif

lib/Backend/CodeGenAllocators.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct CodeGenAllocators
2424
size_t staticNativeCodeData;
2525
#endif
2626

27-
CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext);
27+
CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext, HANDLE processHandle);
2828
PageAllocator *GetPageAllocator() { return &pageAllocator; };
2929
~CodeGenAllocators();
3030
};

lib/Backend/CodeGenWorkItem.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -311,50 +311,6 @@ void CodeGenWorkItem::OnRemoveFromJitQueue(NativeCodeGenerator* generator)
311311
}
312312
}
313313

314-
void CodeGenWorkItem::RecordNativeCodeSize(Func *func, size_t bytes, ushort pdataCount, ushort xdataSize)
315-
{
316-
BYTE *buffer;
317-
#if defined(_M_ARM32_OR_ARM64)
318-
bool canAllocInPreReservedHeapPageSegment = false;
319-
#else
320-
bool canAllocInPreReservedHeapPageSegment = func->CanAllocInPreReservedHeapPageSegment();
321-
#endif
322-
EmitBufferAllocation *allocation = func->GetEmitBufferManager()->AllocateBuffer(bytes, &buffer, pdataCount, xdataSize, canAllocInPreReservedHeapPageSegment, true);
323-
324-
#if DBG
325-
MEMORY_BASIC_INFORMATION memBasicInfo;
326-
size_t resultBytes = VirtualQuery(allocation->allocation->address, &memBasicInfo, sizeof(memBasicInfo));
327-
Assert(resultBytes != 0 && memBasicInfo.Protect == PAGE_EXECUTE);
328-
#endif
329-
330-
Assert(allocation != nullptr);
331-
if (buffer == nullptr)
332-
Js::Throw::OutOfMemory();
333-
334-
SetCodeAddress((size_t)buffer);
335-
SetCodeSize(bytes);
336-
SetPdataCount(pdataCount);
337-
SetXdataSize(xdataSize);
338-
SetAllocation(allocation);
339-
}
340-
341-
void CodeGenWorkItem::RecordNativeCode(Func *func, const BYTE* sourceBuffer)
342-
{
343-
if (!func->GetEmitBufferManager()->CommitBuffer(this->GetAllocation(), (BYTE *)GetCodeAddress(), GetCodeSize(), sourceBuffer))
344-
{
345-
Js::Throw::OutOfMemory();
346-
}
347-
348-
this->isAllocationCommitted = true;
349-
350-
#if DBG_DUMP
351-
if (Type() == JsLoopBodyWorkItemType)
352-
{
353-
func->GetEmitBufferManager()->totalBytesLoopBody += GetCodeSize();
354-
}
355-
#endif
356-
}
357-
358314
void CodeGenWorkItem::OnWorkItemProcessFail(NativeCodeGenerator* codeGen)
359315
{
360316
if (!isAllocationCommitted && this->allocation != nullptr && this->allocation->allocation != nullptr)

lib/Backend/CodeGenWorkItem.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,6 @@ struct CodeGenWorkItem : public JsUtil::Job
134134
return this->entryPointInfo;
135135
}
136136

137-
void RecordNativeCodeSize(Func *func, size_t bytes, ushort pdataCount, ushort xdataSize);
138-
void RecordNativeCode(Func *func, const BYTE* sourceBuffer);
139-
140137
Js::CodeGenRecyclableData *RecyclableData() const
141138
{
142139
return recyclableData;
@@ -193,25 +190,6 @@ struct CodeGenWorkItem : public JsUtil::Job
193190
return jitData.isJitInDebugMode != 0;
194191
}
195192

196-
#if _M_X64 || _M_ARM
197-
size_t RecordUnwindInfo(size_t offset, BYTE *unwindInfo, size_t size)
198-
{
199-
#if _M_X64
200-
Assert(offset == 0);
201-
Assert(XDATA_SIZE >= size);
202-
js_memcpy_s(GetAllocation()->allocation->xdata.address, XDATA_SIZE, unwindInfo, size);
203-
return 0;
204-
#else
205-
BYTE *xdataFinal = GetAllocation()->allocation->xdata.address + offset;
206-
207-
Assert(xdataFinal);
208-
Assert(((DWORD)xdataFinal & 0x3) == 0); // 4 byte aligned
209-
js_memcpy_s(xdataFinal, size, unwindInfo, size);
210-
return (size_t)xdataFinal;
211-
#endif
212-
}
213-
#endif
214-
215193
#if _M_ARM
216194
void RecordPdataEntry(int index, DWORD beginAddress, DWORD unwindData)
217195
{
@@ -251,9 +229,6 @@ struct JsFunctionCodeGen sealed : public CodeGenWorkItem
251229
bool isJitInDebugMode)
252230
: CodeGenWorkItem(manager, functionBody, entryPointInfo, isJitInDebugMode, JsFunctionType)
253231
{
254-
auto funcEPInfo = (Js::FunctionEntryPointInfo*)entryPointInfo;
255-
this->jitData.readOnlyEPData.callsCountAddress = (uintptr_t)&funcEPInfo->callsCount;
256-
257232
size_t sizeInChars = this->GetDisplayName(nullptr, 256);
258233

259234
WCHAR * displayName = HeapNewArray(WCHAR, sizeInChars);

lib/Backend/EmitBuffer.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ template class EmitBufferManager<CriticalSection>;
1313
//----------------------------------------------------------------------------
1414
template <typename SyncObject>
1515
EmitBufferManager<SyncObject>::EmitBufferManager(AllocationPolicyManager * policyManager, ArenaAllocator * allocator,
16-
Js::ScriptContext * scriptContext, LPCWSTR name, bool allocXdata) :
17-
allocationHeap(policyManager, allocator, allocXdata),
16+
Js::ScriptContext * scriptContext, LPCWSTR name, bool allocXdata, HANDLE processHandle) :
17+
allocationHeap(policyManager, allocator, allocXdata, processHandle),
1818
allocator(allocator),
1919
allocations(nullptr),
20-
scriptContext(scriptContext)
20+
scriptContext(scriptContext),
21+
processHandle(processHandle)
2122
{
2223
#if DBG_DUMP
2324
this->totalBytesCode = 0;
@@ -154,11 +155,6 @@ EmitBufferManager<SyncObject>::NewAllocation(size_t bytes, ushort pdataCount, us
154155
bool isAllJITCodeInPreReservedRegion = true;
155156
CustomHeap::Allocation* heapAllocation = this->allocationHeap.Alloc(bytes, pdataCount, xdataSize, canAllocInPreReservedHeapPageSegment, isAnyJittedCode, &isAllJITCodeInPreReservedRegion);
156157

157-
if (!isAllJITCodeInPreReservedRegion)
158-
{
159-
this->scriptContext->GetThreadContext()->ResetIsAllJITCodeInPreReservedRegion();
160-
}
161-
162158
if (heapAllocation == nullptr)
163159
{
164160
// This is used in interpreter scenario, thus we need to try to recover memory, if possible.
@@ -181,6 +177,7 @@ EmitBufferManager<SyncObject>::NewAllocation(size_t bytes, ushort pdataCount, us
181177
allocation->bytesUsed = 0;
182178
allocation->nextAllocation = this->allocations;
183179
allocation->recorded = false;
180+
allocation->inPrereservedRegion = isAllJITCodeInPreReservedRegion;
184181

185182
this->allocations = allocation;
186183

@@ -300,7 +297,7 @@ EmitBufferAllocation* EmitBufferManager<SyncObject>::AllocateBuffer(__in size_t
300297

301298
#if DBG
302299
MEMORY_BASIC_INFORMATION memBasicInfo;
303-
size_t resultBytes = VirtualQuery(allocation->allocation->address, &memBasicInfo, sizeof(memBasicInfo));
300+
size_t resultBytes = VirtualQueryEx(this->processHandle, allocation->allocation->address, &memBasicInfo, sizeof(memBasicInfo));
304301
Assert(resultBytes != 0 && memBasicInfo.Protect == PAGE_EXECUTE);
305302
#endif
306303

@@ -421,7 +418,7 @@ EmitBufferManager<SyncObject>::CommitBuffer(EmitBufferAllocation* allocation, __
421418
if (alignPad != 0)
422419
{
423420
DWORD alignBytes = alignPad < spaceInCurrentPage ? alignPad : spaceInCurrentPage;
424-
CustomHeap::FillDebugBreak(currentDestBuffer, alignBytes);
421+
CustomHeap::FillDebugBreak(currentDestBuffer, alignBytes, this->processHandle);
425422

426423
alignPad -= alignBytes;
427424
currentDestBuffer += alignBytes;
@@ -439,7 +436,7 @@ EmitBufferManager<SyncObject>::CommitBuffer(EmitBufferAllocation* allocation, __
439436
{
440437
AssertMsg(alignPad == 0, "If we are copying right now - we should be done with setting alignment.");
441438

442-
memcpy_s(currentDestBuffer, allocation->BytesFree(), sourceBuffer, bytesToChange);
439+
ChakraMemCopy(currentDestBuffer, allocation->BytesFree(), sourceBuffer, bytesToChange, this->processHandle);
443440

444441
currentDestBuffer += bytesToChange;
445442
sourceBuffer += bytesToChange;

lib/Backend/EmitBuffer.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ struct EmitBufferAllocation
1212
CustomHeap::Allocation* allocation;
1313
size_t bytesUsed;
1414
size_t bytesCommitted;
15+
bool inPrereservedRegion;
1516
bool recorded;
1617
EmitBufferAllocation * nextAllocation;
1718

@@ -30,7 +31,7 @@ template <class SyncObject = FakeCriticalSection>
3031
class EmitBufferManager
3132
{
3233
public:
33-
EmitBufferManager(AllocationPolicyManager * policyManager, ArenaAllocator * allocator, Js::ScriptContext * scriptContext, LPCWSTR name, bool allocXdata);
34+
EmitBufferManager(AllocationPolicyManager * policyManager, ArenaAllocator * allocator, Js::ScriptContext * scriptContext, LPCWSTR name, bool allocXdata, HANDLE processHandle);
3435
~EmitBufferManager();
3536

3637
// All the following methods are guarded with the SyncObject
@@ -126,6 +127,7 @@ class EmitBufferManager
126127
CustomHeap::Heap allocationHeap;
127128

128129
SyncObject criticalSection;
130+
HANDLE processHandle;
129131
#if DBG_DUMP
130132

131133
public:

lib/Backend/Encoder.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -239,11 +239,13 @@ Encoder::Encode()
239239
}
240240
}
241241
#endif
242+
#if 0 // TODO: michhol OOP JIT, understand this code
242243
for (int32 i = 0; i < m_pragmaInstrToRecordMap->Count(); i ++)
243244
{
244245
IR::PragmaInstr *inst = m_pragmaInstrToRecordMap->Item(i);
245246
inst->RecordThrowMap(iter, inst->m_offsetInBuffer);
246247
}
248+
#endif
247249

248250
JITTimeWorkItem * workItem = m_func->GetWorkItem();
249251

@@ -271,33 +273,38 @@ Encoder::Encode()
271273

272274
TryCopyAndAddRelocRecordsForSwitchJumpTableEntries(m_encodeBuffer, codeSize, jumpTableListForSwitchStatement, totalJmpTableSizeInBytes);
273275

274-
workItem->RecordNativeCodeSize(m_func, (DWORD)codeSize, pdataCount, xdataSize);
276+
EmitBufferAllocation * alloc = m_func->GetJITOutput()->RecordNativeCodeSize(m_func, (DWORD)codeSize, pdataCount, xdataSize);
277+
278+
if (!alloc->inPrereservedRegion)
279+
{
280+
m_func->GetThreadContextInfo()->ResetIsAllJITCodeInPreReservedRegion();
281+
}
275282

276283
this->m_bailoutRecordMap->MapAddress([=](int index, LazyBailOutRecord* record)
277284
{
278285
this->m_encoderMD.AddLabelReloc((BYTE*)&record->instructionPointer);
279286
});
280287

281288
// Relocs
282-
m_encoderMD.ApplyRelocs((size_t) workItem->GetCodeAddress());
283-
284-
workItem->RecordNativeCode(m_func, m_encodeBuffer);
289+
m_encoderMD.ApplyRelocs((size_t)alloc->allocation->address);
285290

286-
m_func->GetScriptContext()->GetThreadContext()->SetValidCallTargetForCFG((PVOID) workItem->GetCodeAddress());
291+
m_func->GetJITOutput()->RecordNativeCode(m_func, m_encodeBuffer, alloc);
287292

288293
#ifdef _M_X64
289294
m_func->m_prologEncoder.FinalizeUnwindInfo();
290-
workItem->RecordUnwindInfo(0, m_func->m_prologEncoder.GetUnwindInfo(), m_func->m_prologEncoder.SizeOfUnwindInfo());
295+
m_func->GetJITOutput()->RecordUnwindInfo(
296+
0,
297+
m_func->m_prologEncoder.GetUnwindInfo(),
298+
m_func->m_prologEncoder.SizeOfUnwindInfo(),
299+
alloc->allocation->xdata.address,
300+
m_func->GetThreadContextInfo()->GetProcessHandle());
291301
#elif _M_ARM
292302
m_func->m_unwindInfo.EmitUnwindInfo(workItem);
293303
workItem->SetCodeAddress(workItem->GetCodeAddress() | 0x1); // Set thumb mode
294304
#endif
295305

296-
Js::EntryPointInfo* entryPointInfo = this->m_func->m_workItem->GetEntryPoint();
306+
Js::EntryPointInfo* entryPointInfo = nullptr;
297307
const bool isSimpleJit = m_func->IsSimpleJit();
298-
Assert(
299-
isSimpleJit ||
300-
entryPointInfo->GetJitTransferData() != nullptr && !entryPointInfo->GetJitTransferData()->GetIsReady());
301308

302309
if (this->m_inlineeFrameMap->Count() > 0 &&
303310
!(this->m_inlineeFrameMap->Count() == 1 && this->m_inlineeFrameMap->Item(0).record == nullptr))
@@ -477,13 +484,7 @@ Encoder::Encode()
477484

478485
entryPointInfo->RecordCtorCacheGuards(ctorCachesTransferRecord, ctorCachesTransferSize);
479486
}
480-
481-
if(!isSimpleJit)
482-
{
483-
entryPointInfo->GetJitTransferData()->SetIsReady();
484-
}
485-
486-
workItem->FinalizeNativeCode(m_func);
487+
m_func->GetJITOutput()->FinalizeNativeCode(m_func, alloc);
487488

488489
END_CODEGEN_PHASE(m_func, Js::EmitterPhase);
489490

@@ -503,9 +504,9 @@ Encoder::Encode()
503504
__analysis_assume(m_instrNumber < instrCount);
504505
instr->DumpGlobOptInstrString();
505506
#ifdef _WIN64
506-
Output::Print(L"%12IX ", m_offsetBuffer[m_instrNumber++] + (BYTE *)workItem->GetCodeAddress());
507+
Output::Print(L"%12IX ", m_offsetBuffer[m_instrNumber++] + (BYTE *)m_func->GetJITOutput()->GetCodeAddress());
507508
#else
508-
Output::Print(L"%8IX ", m_offsetBuffer[m_instrNumber++] + (BYTE *)workItem->GetCodeAddress());
509+
Output::Print(L"%8IX ", m_offsetBuffer[m_instrNumber++] + (BYTE *)m_func->GetJITOutput()->GetCodeAddress());
509510
#endif
510511
instr->Dump();
511512
} NEXT_INSTR_IN_FUNC;
@@ -518,7 +519,7 @@ Encoder::Encode()
518519
{
519520
workItem->DumpNativeOffsetMaps();
520521
workItem->DumpNativeThrowSpanSequence();
521-
this->DumpInlineeFrameMap(workItem->GetCodeAddress());
522+
this->DumpInlineeFrameMap(m_func->GetJITOutput()->GetCodeAddress());
522523
Output::Flush();
523524
}
524525
#endif

lib/Backend/Func.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
1010
ThreadContextInfo * threadContextInfo,
1111
ScriptContextInfo * scriptContextInfo,
12+
JITOutputData * outputData,
1213
const Js::FunctionCodeGenJitTimeData *const jitTimeData,
1314
const Js::FunctionCodeGenRuntimeData *const runtimeData,
1415
Js::PolymorphicInlineCacheInfo * const polymorphicInlineCacheInfo, CodeGenAllocators *const codeGenAllocators,
@@ -19,6 +20,7 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
1920
m_alloc(alloc),
2021
m_workItem(workItem),
2122
m_jitTimeData(jitTimeData),
23+
m_output(outputData),
2224
m_threadContextInfo(threadContextInfo),
2325
m_scriptContextInfo(scriptContextInfo),
2426
m_runtimeData(runtimeData),
@@ -299,6 +301,7 @@ Func::Codegen()
299301
this->m_fg = nullptr;
300302
}
301303

304+
Dump();
302305
#ifdef IR_VIEWER
303306
IRtoJSObjectBuilder::DumpIRtoGlobalObject(this, Js::GlobOptPhase);
304307
#endif /* IR_VIEWER */
@@ -309,6 +312,7 @@ Func::Codegen()
309312
lowerer.Lower();
310313
END_CODEGEN_PHASE(this, Js::LowererPhase);
311314

315+
Dump();
312316
#ifdef IR_VIEWER
313317
IRtoJSObjectBuilder::DumpIRtoGlobalObject(this, Js::LowererPhase);
314318
#endif /* IR_VIEWER */

lib/Backend/Func.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class Func
7070
Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
7171
ThreadContextInfo * threadContextInfo,
7272
ScriptContextInfo * scriptContextInfo,
73+
JITOutputData * outputData,
7374
const Js::FunctionCodeGenJitTimeData *const jitTimeData, const Js::FunctionCodeGenRuntimeData *const runtimeData,
7475
Js::PolymorphicInlineCacheInfo * const polymorphicInlineCacheInfo, CodeGenAllocators *const codeGenAllocators,
7576
CodeGenNumberAllocator * numberAllocator, JITTimeProfileInfo *const profileInfo,
@@ -175,6 +176,11 @@ class Func
175176
return m_scriptContextInfo;
176177
}
177178

179+
JITOutput* GetJITOutput()
180+
{
181+
return &m_output;
182+
}
183+
178184
const JITTimeFunctionBody * const GetJITFunctionBody() const
179185
{
180186
return m_workItem->GetJITFunctionBody();

0 commit comments

Comments
 (0)