Skip to content

Commit 4c410fd

Browse files
committed
osx: JIT support
This PR; - Enables JIT on macOS - Fixes / improvements to xplat exception handling
1 parent 9e59b6c commit 4c410fd

30 files changed

+1184
-1525
lines changed

CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,7 @@ if(CLR_CMAKE_PLATFORM_XPLAT)
294294
add_definitions(-DFEATURE_PAL)
295295
endif(CLR_CMAKE_PLATFORM_XPLAT)
296296

297-
if(NO_JIT_SH
298-
OR CLR_CMAKE_PLATFORM_DARWIN) # TODO: JIT for OSX
297+
if(NO_JIT_SH)
299298
unset(NO_JIT_SH CACHE) # don't cache
300299
unset(BuildJIT CACHE) # also clear it just in case
301300
add_definitions(-DDISABLE_JIT=1)

lib/Backend/EhFrame.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ ubyte GetDwarfRegNum(ubyte regNum)
5151
return DWARF_RegNum[regNum];
5252
}
5353

54-
// Enocde into ULEB128 (Unsigned Little Endian Base 128)
54+
// Encode into ULEB128 (Unsigned Little Endian Base 128)
5555
BYTE* EmitLEB128(BYTE* pc, unsigned value)
5656
{
5757
do

lib/Backend/Encoder.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ void Encoder::ValidateCRCOnFinalBuffer(_In_reads_bytes_(finalCodeSize) BYTE * fi
868868

869869
currentEndAddress = finalBufferRelocTuplePtr;
870870
crcSizeToCompute = currentEndAddress - currentStartAddress;
871-
871+
872872
Assert(currentEndAddress >= currentStartAddress);
873873

874874
finalBufferCRC = CalculateCRC(finalBufferCRC, crcSizeToCompute, currentStartAddress);
@@ -910,7 +910,7 @@ void Encoder::EnsureRelocEntryIntegrity(size_t newBufferStartAddress, size_t cod
910910
{
911911
size_t targetBrAddress = 0;
912912
size_t newBufferEndAddress = newBufferStartAddress + codeSize;
913-
913+
914914
//Handle Dictionary addresses here - The target address will be in the dictionary.
915915
if (relocAddress < oldBufferAddress || relocAddress >= (oldBufferAddress + codeSize))
916916
{
@@ -939,6 +939,7 @@ void Encoder::EnsureRelocEntryIntegrity(size_t newBufferStartAddress, size_t cod
939939

940940
uint Encoder::CalculateCRC(uint bufferCRC, size_t data)
941941
{
942+
#if defined(_WIN32) || defined(__SSE4_2__)
942943
#if defined(_M_IX86)
943944
if (AutoSystemInfo::Data.SSE4_2Available())
944945
{
@@ -950,6 +951,7 @@ uint Encoder::CalculateCRC(uint bufferCRC, size_t data)
950951
//CRC32 always returns a 32-bit result
951952
return (uint)_mm_crc32_u64(bufferCRC, data);
952953
}
954+
#endif
953955
#endif
954956

955957
return CalculateCRC32(bufferCRC, data);
@@ -1153,7 +1155,7 @@ Encoder::ShortenBranchesAndLabelAlign(BYTE **codeStart, ptrdiff_t *codeSize, uin
11531155
// Next, we re-write the code to shorten the BRs and adjust relocList offsets to point to new buffer.
11541156
// We also write NOPs for aligned loops.
11551157
BYTE* tmpBuffer = AnewArray(m_tempAlloc, BYTE, newCodeSize);
1156-
1158+
11571159
uint srcBufferCrc = *pShortenedBufferCRC; //This has the intial Random CRC seed to start with.
11581160

11591161
// start copying to new buffer
@@ -1257,7 +1259,7 @@ Encoder::ShortenBranchesAndLabelAlign(BYTE **codeStart, ptrdiff_t *codeSize, uin
12571259
AssertMsg((((uint32)(label->GetPC() - buffStart)) & 0xf) == 0, "Misaligned Label");
12581260

12591261
to = reloc.getLabelOrigPC() - 1;
1260-
1262+
12611263
CopyPartialBufferAndCalculateCRC(&dst_p, dst_size, from, to, pShortenedBufferCRC);
12621264
srcBufferCrc = CalculateCRC(srcBufferCrc, to - from + 1, from);
12631265

@@ -1280,7 +1282,7 @@ Encoder::ShortenBranchesAndLabelAlign(BYTE **codeStart, ptrdiff_t *codeSize, uin
12801282
}
12811283
}
12821284
// copy last chunk
1283-
//Exclude jumpTable content from CRC calculation.
1285+
//Exclude jumpTable content from CRC calculation.
12841286
//Though jumpTable is not part of the encoded bytes, codeSize has jumpTableSize included in it.
12851287
CopyPartialBufferAndCalculateCRC(&dst_p, dst_size, from, buffStart + *codeSize - 1, pShortenedBufferCRC, jumpTableSize);
12861288
srcBufferCrc = CalculateCRC(srcBufferCrc, buffStart + *codeSize - from - jumpTableSize, from);

lib/Backend/PDataManager.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,22 @@ void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
5555
}
5656

5757
#else // !_WIN32
58+
5859
// ----------------------------------------------------------------------------
5960
// !_WIN32 x64 unwind uses .eh_frame
6061
// ----------------------------------------------------------------------------
6162

62-
void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart, _In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd, _Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
63+
void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart,
64+
_In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd,
65+
_Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
6366
{
64-
__register_frame(pdataStart);
67+
__REGISTER_FRAME(pdataStart);
6568
*pdataTable = pdataStart;
6669
}
6770

6871
void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
6972
{
70-
__deregister_frame(pdata);
73+
__DEREGISTER_FRAME(pdata);
7174
}
7275

7376
#endif // !_WIN32

lib/Backend/amd64/LinearScanMdA.S

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@
77
#include "unixasmmacros.inc"
88

99

10-
// BailOutRecord::BailOut(BailOutRecord const * bailOutRecord)
11-
// .extern _ZN13BailOutRecord7BailOutEPKS_
12-
13-
// BranchBailOutRecord::BailOut(BranchBailOutRecord const * bailOutRecord, BOOL cond)
14-
// .extern _ZN19BranchBailOutRecord7BailOutEPKS_i
15-
16-
1710
//------------------------------------------------------------------------------
1811
// LinearScanMD::SaveAllRegisters(BailOutRecord *const bailOutRecord)
1912

@@ -106,7 +99,7 @@ NESTED_ENTRY _ZN12LinearScanMD26SaveAllRegistersAndBailOutEP13BailOutRecord, _TE
10699
add rsp, 28h // deallocate stack space
107100
.cfi_adjust_cfa_offset -0x28
108101

109-
jmp _ZN13BailOutRecord7BailOutEPKS_
102+
jmp C_FUNC(_ZN13BailOutRecord7BailOutEPKS_)
110103

111104
NESTED_END _ZN12LinearScanMD26SaveAllRegistersAndBailOutEP13BailOutRecord, _TEXT
112105

@@ -132,6 +125,6 @@ NESTED_ENTRY _ZN12LinearScanMD32SaveAllRegistersAndBranchBailOutEP19BranchBailOu
132125
add rsp, 28h // deallocate stack space
133126
.cfi_adjust_cfa_offset -0x28
134127

135-
jmp _ZN19BranchBailOutRecord7BailOutEPKS_i
128+
jmp C_FUNC(_ZN19BranchBailOutRecord7BailOutEPKS_i)
136129

137130
NESTED_END _ZN12LinearScanMD32SaveAllRegistersAndBranchBailOutEP19BranchBailOutRecordi, _TEXT

lib/Backend/amd64/Thunks.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ NESTED_ENTRY _ZN19NativeCodeGenerator22CheckAsmJsCodeGenThunkEPN2Js16RecyclableO
7272
movaps xmmword ptr [rsp + 20h], xmm2
7373
movaps xmmword ptr [rsp + 30h], xmm3
7474

75-
call _ZN19NativeCodeGenerator17CheckAsmJsCodeGenEPN2Js14ScriptFunctionE
75+
call C_FUNC(_ZN19NativeCodeGenerator17CheckAsmJsCodeGenEPN2Js14ScriptFunctionE)
7676

7777
// restore potential floating point arguments from stack
7878
movaps xmm0, xmmword ptr [rsp + 00h]

lib/Common/Memory/amd64/XDataAllocator.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ CompileAssert(false)
1212
#include "XDataAllocator.h"
1313
#include "Core/DelayLoadLibrary.h"
1414

15+
#ifndef _WIN32
16+
#include "PlatformAgnostic/AssemblyCommon.h" // __REGISTER_FRAME / __DEREGISTER_FRAME
17+
#endif
18+
1519
XDataAllocator::XDataAllocator(BYTE* address, uint size, HANDLE processHandle) :
1620
freeList(nullptr),
1721
start(address),
@@ -155,7 +159,7 @@ void XDataAllocator::Register(XDataAllocation * xdataInfo, ULONG_PTR functionSta
155159

156160
#else // !_WIN32
157161
Assert(ReadHead(xdataInfo->address)); // should be non-empty .eh_frame
158-
__register_frame(xdataInfo->address);
162+
__REGISTER_FRAME(xdataInfo->address);
159163
#endif
160164
}
161165

@@ -176,6 +180,6 @@ void XDataAllocator::Unregister(XDataAllocation * xdataInfo)
176180

177181
#else // !_WIN32
178182
Assert(ReadHead(xdataInfo->address)); // should be non-empty .eh_frame
179-
__deregister_frame(xdataInfo->address);
183+
__DEREGISTER_FRAME(xdataInfo->address);
180184
#endif
181185
}

lib/Common/Memory/amd64/XDataAllocator.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ CompileAssert(false)
77
#endif
88
#pragma once
99

10-
#ifndef _WIN32
11-
extern "C" void __register_frame(const void* ehframe);
12-
extern "C" void __deregister_frame(const void* ehframe);
13-
#endif
14-
1510
namespace Memory
1611
{
1712
#ifdef _WIN32
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
#pragma once
6+
7+
#ifndef _WIN32
8+
9+
extern "C" void __register_frame(const void* ehframe);
10+
extern "C" void __deregister_frame(const void* ehframe);
11+
12+
#if defined(_AMD64_) && !defined(DISABLE_JIT)
13+
#if defined(__APPLE__) // no multi fde support
14+
#ifndef __IOS__
15+
typedef void(*mac_fde_reg_op)(const void*addr);
16+
void mac_fde_wrapper(const char *dataStart, mac_fde_reg_op reg_op);
17+
#define __REGISTER_FRAME(addr) mac_fde_wrapper((const char*)addr, __register_frame)
18+
#define __DEREGISTER_FRAME(addr) mac_fde_wrapper((const char*)addr, __deregister_frame)
19+
#else // __IOS__ // no JIT
20+
#define __REGISTER_FRAME(addr)
21+
#define __DEREGISTER_FRAME(addr)
22+
#endif // !__IOS__
23+
#else // multi FDE support
24+
#define __REGISTER_FRAME(addr) __register_frame(addr)
25+
#define __DEREGISTER_FRAME(addr) __deregister_frame(addr)
26+
#endif // __APPLE__
27+
#endif // _AMD64_ && !DISABLE_JIT
28+
29+
#endif // !_WIN32

lib/Runtime/ByteCode/AsmJsByteCodeWriter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ namespace Js
436436
{
437437
MULTISIZE_LAYOUT_WRITE(AsmReg7, op, R0, R1, R2, R3, R4, R5, R6);
438438
}
439-
439+
440440
void AsmJsByteCodeWriter::AsmReg9(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8)
441441
{
442442
MULTISIZE_LAYOUT_WRITE(AsmReg9, op, R0, R1, R2, R3, R4, R5, R6, R7, R8);
@@ -445,7 +445,7 @@ namespace Js
445445
{
446446
MULTISIZE_LAYOUT_WRITE(AsmReg10, op, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9);
447447
}
448-
448+
449449
void AsmJsByteCodeWriter::AsmReg11(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8, RegSlot R9, RegSlot R10)
450450
{
451451
MULTISIZE_LAYOUT_WRITE(AsmReg11, op, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10);
@@ -456,7 +456,7 @@ namespace Js
456456
{
457457
MULTISIZE_LAYOUT_WRITE(AsmReg17, op, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16);
458458
}
459-
459+
460460
void AsmJsByteCodeWriter::AsmReg18(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8,
461461
RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16, RegSlot R17)
462462
{

lib/Runtime/ByteCode/ByteCodeWriter.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ namespace Js
216216
AllocateLoopHeaders();
217217
}
218218

219-
219+
220220

221221
m_functionWrite->MarkScript(finalByteCodeBlock, finalAuxiliaryBlock, finalAuxiliaryContextBlock,
222222
m_byteCodeCount, m_byteCodeInLoopCount, m_byteCodeWithoutLDACount);
@@ -2397,7 +2397,7 @@ namespace Js
23972397
//
23982398
// Write the buffer's contents
23992399
//
2400-
2400+
24012401
Assert(byteOffset < m_auxiliaryData.GetCurrentOffset());
24022402

24032403
OpLayoutAuxNoReg data;
@@ -3242,7 +3242,9 @@ namespace Js
32423242
}
32433243

32443244
template <>
3245-
inline void ByteCodeWriter::Data::EncodeOpCode<SmallLayout>(uint16 op, ByteCodeWriter* writer)
3245+
void ByteCodeWriter::Data::EncodeOpCode<SmallLayout>(
3246+
uint16 op,
3247+
ByteCodeWriter* writer)
32463248
{
32473249
DebugOnly(const uint offset = currentOffset);
32483250
if (op <= (uint16)Js::OpCode::MaxByteSizedOpcodes)
@@ -3256,7 +3258,8 @@ namespace Js
32563258
Write(&byteop, sizeof(byte));
32573259
Write(&op, sizeof(uint16));
32583260
}
3259-
Assert(OpCodeUtil::EncodedSize((Js::OpCode)op, SmallLayout) == (currentOffset - offset));
3261+
Assert(OpCodeUtil::EncodedSize((Js::OpCode)op, SmallLayout)
3262+
== (currentOffset - offset));
32603263
}
32613264

32623265
template <LayoutSize layoutSize>

lib/Runtime/ByteCode/ByteCodeWriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ namespace Js
9696

9797
template <LayoutSize layoutSize> void EncodeOpCode(uint16 op, ByteCodeWriter* writer);
9898
template <> void EncodeOpCode<SmallLayout>(uint16 op, ByteCodeWriter* writer);
99+
99100
// EncodeT functions return the global offset where the opcode has been encoded
100101
template <LayoutSize layoutSize> uint EncodeT(OpCode op, ByteCodeWriter* writer);
101102
template <LayoutSize layoutSize> uint EncodeT(OpCode op, const void * rawData, int byteSize, ByteCodeWriter* writer);

lib/Runtime/Language/DynamicProfileInfo.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -889,10 +889,11 @@ namespace Js
889889

890890
// We are overloading the value types to store whether it is a mod by power of 2.
891891
// TaggedInt:
892-
inline void DynamicProfileInfo::RecordModulusOpType(FunctionBody* body, ProfileId profileId, bool isModByPowerOf2)
892+
void DynamicProfileInfo::RecordModulusOpType(FunctionBody* body,
893+
ProfileId profileId, bool isModByPowerOf2)
893894
{
894895
Assert(profileId < body->GetProfiledDivOrRemCount());
895-
// allow one op of the modulus to be optimized - anyway
896+
/* allow one op of the modulus to be optimized - anyway */
896897
if (divideTypeInfo[profileId].IsUninitialized())
897898
{
898899
divideTypeInfo[profileId] = ValueType::GetInt(true);
@@ -901,11 +902,13 @@ namespace Js
901902
{
902903
if (isModByPowerOf2)
903904
{
904-
divideTypeInfo[profileId] = divideTypeInfo[profileId].Merge(ValueType::GetInt(true));
905+
divideTypeInfo[profileId] = divideTypeInfo[profileId]
906+
.Merge(ValueType::GetInt(true));
905907
}
906908
else
907909
{
908-
divideTypeInfo[profileId] = divideTypeInfo[profileId].Merge(ValueType::Float);
910+
divideTypeInfo[profileId] = divideTypeInfo[profileId]
911+
.Merge(ValueType::Float);
909912
}
910913
}
911914
}

lib/Runtime/Language/DynamicProfileInfo.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#pragma once
66

77
// DisableJit-TODO
8-
#if ENABLE_PROFILE_INFO
8+
#if ENABLE_PROFILE_INFO
99

1010
#ifdef DYNAMIC_PROFILE_MUTATOR
1111
class DynamicProfileMutatorImpl;
@@ -375,6 +375,7 @@ namespace Js
375375
ValueType * GetDivideTypeInfo() const { return divideTypeInfo; }
376376

377377
void RecordModulusOpType(FunctionBody* body, ProfileId profileId, bool isModByPowerOf2);
378+
378379
bool IsModulusOpByPowerOf2(FunctionBody* body, ProfileId profileId) const;
379380

380381
void RecordSwitchType(FunctionBody* body, ProfileId switchId, Var object);

lib/Runtime/Language/InterpreterStackFrame.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1696,7 +1696,6 @@ namespace Js
16961696
{
16971697
#if DYNAMIC_INTERPRETER_THUNK
16981698
Assert(function);
1699-
17001699
Js::FunctionBody *functionBody = function->GetFunctionBody();
17011700
JavascriptMethod entrypoint = functionBody->EnsureDynamicInterpreterThunk(function->GetFunctionEntryPointInfo());
17021701
Assert(!IsDelayDynamicInterpreterThunk(functionBody->GetDirectEntryPoint(function->GetEntryPointInfo())));

0 commit comments

Comments
 (0)