Skip to content

Commit 015b05d

Browse files
committed
Update Memory handling to support Apple Silicon
- Memory page size on apple arm64 is 16kb - This change caused ushort overflows - minor edits to orders of operations to fix - New assembler file for arm64_SAVE_REGISTERS
1 parent 3fb33a8 commit 015b05d

9 files changed

+86
-9
lines changed

lib/Common/Core/SysInfo.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
//----------------------------------------------------------------------------
@@ -62,7 +63,11 @@ class AutoSystemInfo : public SYSTEM_INFO
6263
#ifdef _WIN32
6364
static HMODULE GetCRTHandle();
6465
#endif
66+
#if defined(__APPLE__) && defined(_M_ARM64)
67+
static DWORD const PageSize = 16384;
68+
#else
6569
static DWORD const PageSize = 4096;
70+
#endif
6671

6772
static size_t const MaxPageCount = SIZE_MAX / PageSize;
6873

@@ -136,7 +141,12 @@ class AutoSystemInfo : public SYSTEM_INFO
136141

137142

138143
// For Prefast where it doesn't like symbolic constants
144+
#if defined(__APPLE__) && defined(_M_ARM64)
145+
CompileAssert(AutoSystemInfo::PageSize == 16384);
146+
#define __in_ecount_pagesize __in_ecount(16384)
147+
#define __in_ecount_twopagesize __in_ecount(32768)
148+
#else
139149
CompileAssert(AutoSystemInfo::PageSize == 4096);
140150
#define __in_ecount_pagesize __in_ecount(4096)
141151
#define __in_ecount_twopagesize __in_ecount(8192)
142-
152+
#endif

lib/Common/Memory/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ if(CC_TARGETS_AMD64)
4545
amd64/XDataAllocator.cpp
4646
amd64/amd64_SAVE_REGISTERS.S
4747
)
48+
elseif(CC_TARGETS_ARM64)
49+
set (CCM_SOURCE_FILES ${CCM_SOURCE_FILES}
50+
arm64/XDataAllocator.cpp
51+
arm64/arm64_SAVE_REGISTERS.S
52+
)
4853
elseif(CC_TARGETS_ARM)
4954
set (CCM_SOURCE_FILES ${CCM_SOURCE_FILES}
5055
arm/XDataAllocator.cpp

lib/Common/Memory/CustomHeap.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#include "CommonMemoryPch.h"
@@ -294,7 +295,11 @@ BOOL Heap<TAlloc, TPreReservedAlloc>::ProtectAllocationWithExecuteReadWrite(Allo
294295
}
295296
else
296297
{
298+
#if defined(__APPLE__) && defined(_M_ARM64)
299+
protectFlags = PAGE_READWRITE; // PAGE_EXECUTE_READWRITE banned on Apple Silicon
300+
#else
297301
protectFlags = PAGE_EXECUTE_READWRITE;
302+
#endif
298303
}
299304
return this->ProtectAllocation(allocation, protectFlags, PAGE_EXECUTE_READ, addressInPage);
300305
}
@@ -311,7 +316,11 @@ BOOL Heap<TAlloc, TPreReservedAlloc>::ProtectAllocationWithExecuteReadOnly(__in
311316
{
312317
protectFlags = PAGE_EXECUTE_READ;
313318
}
319+
#if defined(__APPLE__) && defined(_M_ARM64)
320+
return this->ProtectAllocation(allocation, protectFlags, PAGE_READWRITE, addressInPage); // PAGE_EXECUTE_READWRITE banned on Apple Silicon
321+
#else
314322
return this->ProtectAllocation(allocation, protectFlags, PAGE_EXECUTE_READWRITE, addressInPage);
323+
#endif
315324
}
316325

317326
template<typename TAlloc, typename TPreReservedAlloc>

lib/Common/Memory/Recycler.inl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#pragma once
@@ -587,8 +588,10 @@ SmallHeapBlockT<TBlockAttributes>::GetAddressBitIndex(void * objectAddress)
587588
{
588589
Assert(HeapInfo::IsAlignedAddress(objectAddress));
589590

590-
ushort offset = (ushort)(::Math::PointerCastToIntegralTruncate<uint>(objectAddress) % (TBlockAttributes::PageCount * AutoSystemInfo::PageSize));
591-
offset = offset >> HeapConstants::ObjectAllocationShift;
591+
ushort offset = (ushort)(
592+
(::Math::PointerCastToIntegralTruncate<uint>(objectAddress)
593+
% (TBlockAttributes::PageCount * AutoSystemInfo::PageSize))
594+
>> HeapConstants::ObjectAllocationShift);
592595

593596
Assert(offset <= USHRT_MAX);
594597
Assert(offset <= TBlockAttributes::MaxAddressBit);

lib/Common/Memory/RecyclerWriteBarrierManager.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#pragma once
@@ -211,10 +212,17 @@ class RecyclerWriteBarrierManager
211212
static DWORD GetWriteBarrier(void * address);
212213
#endif
213214

215+
#if defined(__APPLE__) && defined(_M_ARM64)
216+
static size_t const s_WriteBarrierPageSize = 16384;
217+
static uint const s_BitArrayCardTableShift = 9;
218+
static uint const s_BytesPerCardBit = 1 << s_BitArrayCardTableShift; // 512 = 1 << 9
219+
static uint const s_BytesPerCard = s_BytesPerCardBit * 32; // 16k
220+
#else
214221
static size_t const s_WriteBarrierPageSize = 4096;
215222
static uint const s_BitArrayCardTableShift = 7;
216223
static uint const s_BytesPerCardBit = 1 << s_BitArrayCardTableShift; // 128 = 1 << 7
217224
static uint const s_BytesPerCard = s_BytesPerCardBit * 32; // 4K = 1 << 12 = 128 << 5
225+
#endif
218226

219227
private:
220228

lib/Common/Memory/SmallFinalizableHeapBlock.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#include "CommonMemoryPch.h"
@@ -14,7 +15,7 @@ SmallFinalizableWithBarrierHeapBlockT<TBlockAttributes>::New(HeapBucketT<SmallFi
1415
Assert((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / bucket->sizeCat <= USHRT_MAX);
1516

1617
ushort objectSize = (ushort)bucket->sizeCat;
17-
ushort objectCount = (ushort)(TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize;
18+
ushort objectCount = (ushort)((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize);
1819
return NoMemProtectHeapNewNoThrowPlusPrefixZ(Base::GetAllocPlusSize(objectCount), SmallFinalizableWithBarrierHeapBlockT<TBlockAttributes>, bucket, objectSize, objectCount);
1920
}
2021

@@ -39,7 +40,7 @@ SmallRecyclerVisitedHostHeapBlockT<TBlockAttributes>::New(HeapBucketT<SmallRecyc
3940
Assert((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / bucket->sizeCat <= USHRT_MAX);
4041

4142
ushort objectSize = (ushort)bucket->sizeCat;
42-
ushort objectCount = (ushort)(TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize;
43+
ushort objectCount = (ushort)((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize);
4344
return NoMemProtectHeapNewNoThrowPlusPrefixZ(Base::GetAllocPlusSize(objectCount), SmallRecyclerVisitedHostHeapBlockT<TBlockAttributes>, bucket, objectSize, objectCount);
4445
}
4546

@@ -62,7 +63,7 @@ SmallFinalizableHeapBlockT<TBlockAttributes>::New(HeapBucketT<SmallFinalizableHe
6263
Assert((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / bucket->sizeCat <= USHRT_MAX);
6364

6465
ushort objectSize = (ushort)bucket->sizeCat;
65-
ushort objectCount = (ushort)(TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize;
66+
ushort objectCount = (ushort)((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize);
6667
return NoMemProtectHeapNewNoThrowPlusPrefixZ(Base::GetAllocPlusSize(objectCount), SmallFinalizableHeapBlockT<TBlockAttributes>, bucket, objectSize, objectCount);
6768
}
6869

lib/Common/Memory/SmallLeafHeapBlock.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#include "CommonMemoryPch.h"
@@ -13,7 +14,7 @@ SmallLeafHeapBlockT<TBlockAttributes>::New(HeapBucketT<SmallLeafHeapBlockT<TBloc
1314
Assert((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / bucket->sizeCat <= USHRT_MAX);
1415

1516
ushort objectSize = (ushort)bucket->sizeCat;
16-
ushort objectCount = (ushort)(TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize;
17+
ushort objectCount = (ushort)((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize);
1718
return NoMemProtectHeapNewNoThrowPlusPrefixZ(Base::GetAllocPlusSize(objectCount), SmallLeafHeapBlockT<TBlockAttributes>, bucket, objectSize, objectCount);
1819
}
1920

lib/Common/Memory/SmallNormalHeapBlock.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//-------------------------------------------------------------------------------------------------------
22
// Copyright (C) Microsoft. All rights reserved.
3+
// Copyright (c) ChakraCore Project Contributors. All rights reserved.
34
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
45
//-------------------------------------------------------------------------------------------------------
56
#include "CommonMemoryPch.h"
@@ -13,7 +14,7 @@ SmallNormalHeapBlockT<TBlockAttributes>::New(HeapBucketT<SmallNormalHeapBlockT<T
1314
Assert((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / bucket->sizeCat <= USHRT_MAX);
1415

1516
ushort objectSize = (ushort)bucket->sizeCat;
16-
ushort objectCount = (ushort)(TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize;
17+
ushort objectCount = (ushort)((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize);
1718

1819
HeapBlockType blockType = (TBlockAttributes::IsSmallBlock ? HeapBlock::SmallNormalBlockType : HeapBlock::MediumNormalBlockType);
1920
return NoMemProtectHeapNewNoThrowPlusPrefixZ(Base::GetAllocPlusSize(objectCount), SmallNormalHeapBlockT<TBlockAttributes>, bucket, objectSize, objectCount, blockType);
@@ -29,7 +30,7 @@ SmallNormalWithBarrierHeapBlockT<TBlockAttributes>::New(HeapBucketT<SmallNormalW
2930
Assert((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / bucket->sizeCat <= USHRT_MAX);
3031

3132
ushort objectSize = (ushort)bucket->sizeCat;
32-
ushort objectCount = (ushort)(TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize;
33+
ushort objectCount = (ushort)((TBlockAttributes::PageCount * AutoSystemInfo::PageSize) / objectSize);
3334

3435
HeapBlockType blockType = (TBlockAttributes::IsSmallBlock ? HeapBlock::SmallNormalBlockWithBarrierType : HeapBlock::MediumNormalBlockWithBarrierType);
3536
return NoMemProtectHeapNewNoThrowPlusPrefixZ(Base::GetAllocPlusSize(objectCount), SmallNormalWithBarrierHeapBlockT<TBlockAttributes>, bucket, objectSize, objectCount, blockType);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
;-------------------------------------------------------------------------------------------------------
2+
; Copyright (C) Microsoft. All rights reserved.
3+
; Copyright (c) ChakraCore Project Contributors. All rights reserved.
4+
; Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
5+
;-------------------------------------------------------------------------------------------------------
6+
7+
#include "unixasmmacros.inc"
8+
9+
//void arm64_SAVE_REGISTERS(registers)
10+
//
11+
// This method pushes the 16 general purpose registers into the passed in array.
12+
// By convention, the stack pointer will always be stored at registers[0]
13+
//
14+
// void* registers[16];
15+
// arm64_SAVE_REGISTERS(registers);
16+
//
17+
.p2align 2
18+
.globl C_FUNC(arm64_SAVE_REGISTERS)
19+
C_FUNC(arm64_SAVE_REGISTERS):
20+
; Can't use sp with stp so mov to a volatile register
21+
; and then store onto passed in array
22+
mov x17, sp
23+
str x17, [x0, #0x00]
24+
str x1, [x0, #0x08]
25+
stp x2, x3, [x0, #0x10]
26+
stp x4, x5, [x0, #0x20]
27+
stp x6, x7, [x0, #0x30]
28+
stp x8, x9, [x0, #0x40]
29+
stp x10, x11, [x0, #0x50]
30+
stp x12, x13, [x0, #0x60]
31+
stp x14, x15, [x0, #0x70]
32+
stp x16, x19, [x0, #0x80]
33+
stp x20, x21, [x0, #0x90]
34+
stp x22, x23, [x0, #0xA0]
35+
stp x24, x25, [x0, #0xB0]
36+
stp x26, x27, [x0, #0xC0]
37+
str x28, [x0, #0xD0]
38+
39+
br lr

0 commit comments

Comments
 (0)