Skip to content

Commit

Permalink
osx: JIT support
Browse files Browse the repository at this point in the history
This PR;
- Enables JIT on macOS
- Fixes / improvements to xplat exception handling
  • Loading branch information
obastemur committed Oct 27, 2016
1 parent 2b0bbf5 commit d13c2a2
Show file tree
Hide file tree
Showing 30 changed files with 1,179 additions and 1,520 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,7 @@ if(CLR_CMAKE_PLATFORM_XPLAT)
add_definitions(-DFEATURE_PAL)
endif(CLR_CMAKE_PLATFORM_XPLAT)

if(NO_JIT_SH
OR CLR_CMAKE_PLATFORM_DARWIN) # TODO: JIT for OSX
if(NO_JIT_SH)
unset(NO_JIT_SH CACHE) # don't cache
unset(BuildJIT CACHE) # also clear it just in case
add_definitions(-DDISABLE_JIT=1)
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/EhFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ ubyte GetDwarfRegNum(ubyte regNum)
return DWARF_RegNum[regNum];
}

// Enocde into ULEB128 (Unsigned Little Endian Base 128)
// Encode into ULEB128 (Unsigned Little Endian Base 128)
BYTE* EmitLEB128(BYTE* pc, unsigned value)
{
do
Expand Down
12 changes: 7 additions & 5 deletions lib/Backend/Encoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ void Encoder::ValidateCRCOnFinalBuffer(_In_reads_bytes_(finalCodeSize) BYTE * fi

currentEndAddress = finalBufferRelocTuplePtr;
crcSizeToCompute = currentEndAddress - currentStartAddress;

Assert(currentEndAddress >= currentStartAddress);

finalBufferCRC = CalculateCRC(finalBufferCRC, crcSizeToCompute, currentStartAddress);
Expand Down Expand Up @@ -910,7 +910,7 @@ void Encoder::EnsureRelocEntryIntegrity(size_t newBufferStartAddress, size_t cod
{
size_t targetBrAddress = 0;
size_t newBufferEndAddress = newBufferStartAddress + codeSize;

//Handle Dictionary addresses here - The target address will be in the dictionary.
if (relocAddress < oldBufferAddress || relocAddress >= (oldBufferAddress + codeSize))
{
Expand Down Expand Up @@ -939,6 +939,7 @@ void Encoder::EnsureRelocEntryIntegrity(size_t newBufferStartAddress, size_t cod

uint Encoder::CalculateCRC(uint bufferCRC, size_t data)
{
#if defined(_WIN32) || defined(__SSE4_2__)
#if defined(_M_IX86)
if (AutoSystemInfo::Data.SSE4_2Available())
{
Expand All @@ -950,6 +951,7 @@ uint Encoder::CalculateCRC(uint bufferCRC, size_t data)
//CRC32 always returns a 32-bit result
return (uint)_mm_crc32_u64(bufferCRC, data);
}
#endif
#endif

return CalculateCRC32(bufferCRC, data);
Expand Down Expand Up @@ -1153,7 +1155,7 @@ Encoder::ShortenBranchesAndLabelAlign(BYTE **codeStart, ptrdiff_t *codeSize, uin
// Next, we re-write the code to shorten the BRs and adjust relocList offsets to point to new buffer.
// We also write NOPs for aligned loops.
BYTE* tmpBuffer = AnewArray(m_tempAlloc, BYTE, newCodeSize);

uint srcBufferCrc = *pShortenedBufferCRC; //This has the intial Random CRC seed to start with.

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

to = reloc.getLabelOrigPC() - 1;

CopyPartialBufferAndCalculateCRC(&dst_p, dst_size, from, to, pShortenedBufferCRC);
srcBufferCrc = CalculateCRC(srcBufferCrc, to - from + 1, from);

Expand All @@ -1280,7 +1282,7 @@ Encoder::ShortenBranchesAndLabelAlign(BYTE **codeStart, ptrdiff_t *codeSize, uin
}
}
// copy last chunk
//Exclude jumpTable content from CRC calculation.
//Exclude jumpTable content from CRC calculation.
//Though jumpTable is not part of the encoded bytes, codeSize has jumpTableSize included in it.
CopyPartialBufferAndCalculateCRC(&dst_p, dst_size, from, buffStart + *codeSize - 1, pShortenedBufferCRC, jumpTableSize);
srcBufferCrc = CalculateCRC(srcBufferCrc, buffStart + *codeSize - from - jumpTableSize, from);
Expand Down
9 changes: 6 additions & 3 deletions lib/Backend/PDataManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,22 @@ void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
}

#else // !_WIN32

// ----------------------------------------------------------------------------
// !_WIN32 x64 unwind uses .eh_frame
// ----------------------------------------------------------------------------

void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart, _In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd, _Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
void PDataManager::RegisterPdata(RUNTIME_FUNCTION* pdataStart,
_In_ const ULONG_PTR functionStart, _In_ const ULONG_PTR functionEnd,
_Out_ PVOID* pdataTable, ULONG entryCount, ULONG maxEntryCount)
{
__register_frame(pdataStart);
__REGISTER_FRAME(pdataStart);
*pdataTable = pdataStart;
}

void PDataManager::UnregisterPdata(RUNTIME_FUNCTION* pdata)
{
__deregister_frame(pdata);
__DEREGISTER_FRAME(pdata);
}

#endif // !_WIN32
Expand Down
11 changes: 2 additions & 9 deletions lib/Backend/amd64/LinearScanMdA.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@
#include "unixasmmacros.inc"


// BailOutRecord::BailOut(BailOutRecord const * bailOutRecord)
// .extern _ZN13BailOutRecord7BailOutEPKS_

// BranchBailOutRecord::BailOut(BranchBailOutRecord const * bailOutRecord, BOOL cond)
// .extern _ZN19BranchBailOutRecord7BailOutEPKS_i


//------------------------------------------------------------------------------
// LinearScanMD::SaveAllRegisters(BailOutRecord *const bailOutRecord)

Expand Down Expand Up @@ -106,7 +99,7 @@ NESTED_ENTRY _ZN12LinearScanMD26SaveAllRegistersAndBailOutEP13BailOutRecord, _TE
add rsp, 28h // deallocate stack space
.cfi_adjust_cfa_offset -0x28

jmp _ZN13BailOutRecord7BailOutEPKS_
jmp C_FUNC(_ZN13BailOutRecord7BailOutEPKS_)

NESTED_END _ZN12LinearScanMD26SaveAllRegistersAndBailOutEP13BailOutRecord, _TEXT

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

jmp _ZN19BranchBailOutRecord7BailOutEPKS_i
jmp C_FUNC(_ZN19BranchBailOutRecord7BailOutEPKS_i)

NESTED_END _ZN12LinearScanMD32SaveAllRegistersAndBranchBailOutEP19BranchBailOutRecordi, _TEXT
2 changes: 1 addition & 1 deletion lib/Backend/amd64/Thunks.S
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ NESTED_ENTRY _ZN19NativeCodeGenerator22CheckAsmJsCodeGenThunkEPN2Js16RecyclableO
movaps xmmword ptr [rsp + 20h], xmm2
movaps xmmword ptr [rsp + 30h], xmm3

call _ZN19NativeCodeGenerator17CheckAsmJsCodeGenEPN2Js14ScriptFunctionE
call C_FUNC(_ZN19NativeCodeGenerator17CheckAsmJsCodeGenEPN2Js14ScriptFunctionE)

// restore potential floating point arguments from stack
movaps xmm0, xmmword ptr [rsp + 00h]
Expand Down
8 changes: 6 additions & 2 deletions lib/Common/Memory/amd64/XDataAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ CompileAssert(false)
#include "XDataAllocator.h"
#include "Core/DelayLoadLibrary.h"

#ifndef _WIN32
#include "PlatformAgnostic/AssemblyCommon.h" // __REGISTER_FRAME / __DEREGISTER_FRAME
#endif

XDataAllocator::XDataAllocator(BYTE* address, uint size, HANDLE processHandle) :
freeList(nullptr),
start(address),
Expand Down Expand Up @@ -155,7 +159,7 @@ void XDataAllocator::Register(XDataAllocation * xdataInfo, ULONG_PTR functionSta

#else // !_WIN32
Assert(ReadHead(xdataInfo->address)); // should be non-empty .eh_frame
__register_frame(xdataInfo->address);
__REGISTER_FRAME(xdataInfo->address);
#endif
}

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

#else // !_WIN32
Assert(ReadHead(xdataInfo->address)); // should be non-empty .eh_frame
__deregister_frame(xdataInfo->address);
__DEREGISTER_FRAME(xdataInfo->address);
#endif
}
5 changes: 0 additions & 5 deletions lib/Common/Memory/amd64/XDataAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ CompileAssert(false)
#endif
#pragma once

#ifndef _WIN32
extern "C" void __register_frame(const void* ehframe);
extern "C" void __deregister_frame(const void* ehframe);
#endif

namespace Memory
{
#ifdef _WIN32
Expand Down
29 changes: 29 additions & 0 deletions lib/Common/PlatformAgnostic/AssemblyCommon.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#pragma once

#ifndef _WIN32

extern "C" void __register_frame(const void* ehframe);
extern "C" void __deregister_frame(const void* ehframe);

#if defined(_AMD64_) && !defined(DISABLE_JIT)
#if defined(__APPLE__) // no multi fde support
#ifndef __IOS__
typedef void(*mac_fde_reg_op)(const void*addr);
void mac_fde_wrapper(const char *dataStart, mac_fde_reg_op reg_op);
#define __REGISTER_FRAME(addr) mac_fde_wrapper((const char*)addr, __register_frame)
#define __DEREGISTER_FRAME(addr) mac_fde_wrapper((const char*)addr, __deregister_frame)
#else // __IOS__ // no JIT
#define __REGISTER_FRAME(addr)
#define __DEREGISTER_FRAME(addr)
#endif // !__IOS__
#else // multi FDE support
#define __REGISTER_FRAME(addr) __register_frame(addr)
#define __DEREGISTER_FRAME(addr) __deregister_frame(addr)
#endif // __APPLE__
#endif // _AMD64_ && !DISABLE_JIT

#endif // !_WIN32
6 changes: 3 additions & 3 deletions lib/Runtime/ByteCode/AsmJsByteCodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ namespace Js
{
MULTISIZE_LAYOUT_WRITE(AsmReg7, op, R0, R1, R2, R3, R4, R5, R6);
}

void AsmJsByteCodeWriter::AsmReg9(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8)
{
MULTISIZE_LAYOUT_WRITE(AsmReg9, op, R0, R1, R2, R3, R4, R5, R6, R7, R8);
Expand All @@ -428,7 +428,7 @@ namespace Js
{
MULTISIZE_LAYOUT_WRITE(AsmReg10, op, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9);
}

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)
{
MULTISIZE_LAYOUT_WRITE(AsmReg11, op, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10);
Expand All @@ -439,7 +439,7 @@ namespace Js
{
MULTISIZE_LAYOUT_WRITE(AsmReg17, op, R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16);
}

void AsmJsByteCodeWriter::AsmReg18(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, RegSlot R3, RegSlot R4, RegSlot R5, RegSlot R6, RegSlot R7, RegSlot R8,
RegSlot R9, RegSlot R10, RegSlot R11, RegSlot R12, RegSlot R13, RegSlot R14, RegSlot R15, RegSlot R16, RegSlot R17)
{
Expand Down
11 changes: 7 additions & 4 deletions lib/Runtime/ByteCode/ByteCodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ namespace Js
AllocateLoopHeaders();
}



m_functionWrite->MarkScript(finalByteCodeBlock, finalAuxiliaryBlock, finalAuxiliaryContextBlock,
m_byteCodeCount, m_byteCodeInLoopCount, m_byteCodeWithoutLDACount);
Expand Down Expand Up @@ -2397,7 +2397,7 @@ namespace Js
//
// Write the buffer's contents
//

Assert(byteOffset < m_auxiliaryData.GetCurrentOffset());

OpLayoutAuxNoReg data;
Expand Down Expand Up @@ -3242,7 +3242,9 @@ namespace Js
}

template <>
inline void ByteCodeWriter::Data::EncodeOpCode<SmallLayout>(uint16 op, ByteCodeWriter* writer)
void ByteCodeWriter::Data::EncodeOpCode<SmallLayout>(
uint16 op,
ByteCodeWriter* writer)
{
DebugOnly(const uint offset = currentOffset);
if (op <= (uint16)Js::OpCode::MaxByteSizedOpcodes)
Expand All @@ -3256,7 +3258,8 @@ namespace Js
Write(&byteop, sizeof(byte));
Write(&op, sizeof(uint16));
}
Assert(OpCodeUtil::EncodedSize((Js::OpCode)op, SmallLayout) == (currentOffset - offset));
Assert(OpCodeUtil::EncodedSize((Js::OpCode)op, SmallLayout)
== (currentOffset - offset));
}

template <LayoutSize layoutSize>
Expand Down
1 change: 1 addition & 0 deletions lib/Runtime/ByteCode/ByteCodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ namespace Js

template <LayoutSize layoutSize> void EncodeOpCode(uint16 op, ByteCodeWriter* writer);
template <> void EncodeOpCode<SmallLayout>(uint16 op, ByteCodeWriter* writer);

// EncodeT functions return the global offset where the opcode has been encoded
template <LayoutSize layoutSize> uint EncodeT(OpCode op, ByteCodeWriter* writer);
template <LayoutSize layoutSize> uint EncodeT(OpCode op, const void * rawData, int byteSize, ByteCodeWriter* writer);
Expand Down
11 changes: 7 additions & 4 deletions lib/Runtime/Language/DynamicProfileInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -889,10 +889,11 @@ namespace Js

// We are overloading the value types to store whether it is a mod by power of 2.
// TaggedInt:
inline void DynamicProfileInfo::RecordModulusOpType(FunctionBody* body, ProfileId profileId, bool isModByPowerOf2)
void DynamicProfileInfo::RecordModulusOpType(FunctionBody* body,
ProfileId profileId, bool isModByPowerOf2)
{
Assert(profileId < body->GetProfiledDivOrRemCount());
// allow one op of the modulus to be optimized - anyway
/* allow one op of the modulus to be optimized - anyway */
if (divideTypeInfo[profileId].IsUninitialized())
{
divideTypeInfo[profileId] = ValueType::GetInt(true);
Expand All @@ -901,11 +902,13 @@ namespace Js
{
if (isModByPowerOf2)
{
divideTypeInfo[profileId] = divideTypeInfo[profileId].Merge(ValueType::GetInt(true));
divideTypeInfo[profileId] = divideTypeInfo[profileId]
.Merge(ValueType::GetInt(true));
}
else
{
divideTypeInfo[profileId] = divideTypeInfo[profileId].Merge(ValueType::Float);
divideTypeInfo[profileId] = divideTypeInfo[profileId]
.Merge(ValueType::Float);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/Runtime/Language/DynamicProfileInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#pragma once

// DisableJit-TODO
#if ENABLE_PROFILE_INFO
#if ENABLE_PROFILE_INFO

#ifdef DYNAMIC_PROFILE_MUTATOR
class DynamicProfileMutatorImpl;
Expand Down Expand Up @@ -375,6 +375,7 @@ namespace Js
ValueType * GetDivideTypeInfo() const { return divideTypeInfo; }

void RecordModulusOpType(FunctionBody* body, ProfileId profileId, bool isModByPowerOf2);

bool IsModulusOpByPowerOf2(FunctionBody* body, ProfileId profileId) const;

void RecordSwitchType(FunctionBody* body, ProfileId switchId, Var object);
Expand Down
1 change: 0 additions & 1 deletion lib/Runtime/Language/InterpreterStackFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1670,7 +1670,6 @@ namespace Js
{
#if DYNAMIC_INTERPRETER_THUNK
Assert(function);

Js::FunctionBody *functionBody = function->GetFunctionBody();
JavascriptMethod entrypoint = functionBody->EnsureDynamicInterpreterThunk(function->GetFunctionEntryPointInfo());
Assert(!IsDelayDynamicInterpreterThunk(functionBody->GetDirectEntryPoint(function->GetEntryPointInfo())));
Expand Down
Loading

0 comments on commit d13c2a2

Please sign in to comment.