44.intel_syntax noprefix
55#include "AsmMacros_Shared.h"
66
7- // Allocate non - array , non - finalizable object. If the allocation doesn 't fit into the current thread' s
8- // allocation context then automatically fallback to the slow allocation path.
7+ // Shared code for RhpNewFast , RhpNewFastAlign8 and RhpNewFastMisalign
98// ECX == MethodTable
10- LEAF_ENTRY RhpNewFast , _TEXT
9+ .macro NEW_FAST Variation
1110
1211 // edx = ee_alloc_context pointer , TRASHES eax
1312 INLINE_GET_ALLOC_CONTEXT
1413
15- //
16- // ecx contains MethodTable pointer
17- //
14+ // When doing aligned or misaligned allocation we first check
15+ // the alignment and skip to the regular path if it's already
16+ // matching the expectation.
17+ // Otherwise , we try to allocate size + ASM_MIN_OBJECT_SIZE and
18+ // then prepend a dummy free object at the beginning of the
19+ // allocation.
20+ .ifnc \Variation ,
21+ mov eax , [ edx + OFFSETOF__ee_alloc_context__alloc_ptr ]
22+ test eax , 7
23+ .ifc \Variation , Align8
24+ jz 1f // AlreadyAligned
25+ .else // Variation == "Misalign"
26+ jnz 1f // AlreadyAligned
27+ .endif
28+
1829 mov eax , [ ecx + OFFSETOF__MethodTable__m_uBaseSize ]
30+ add eax , ASM_MIN_OBJECT_SIZE
31+ add eax , [ edx + OFFSETOF__ee_alloc_context__alloc_ptr ]
32+ cmp eax , [ edx + OFFSETOF__ee_alloc_context__combined_limit ]
33+ ja 2f // AllocFailed
34+ mov [ edx + OFFSETOF__ee_alloc_context__alloc_ptr ], eax
1935
20- //
21- // eax : base size
22- // ecx : MethodTable pointer
23- // edx : ee_alloc_context pointer
24- //
36+ // calc the new object pointer and initialize it
37+ sub eax , [ ecx + OFFSETOF__MethodTable__m_uBaseSize ]
38+ mov [ eax + OFFSETOF__Object__m_pEEType ], ecx
39+
40+ // initialize the padding object preceeding the new object
41+ PREPARE_EXTERNAL_VAR G_FREE_OBJECT_METHOD_TABLE , edx
42+ mov [ eax + OFFSETOF__Object__m_pEEType - ASM_MIN_OBJECT_SIZE ], edx
43+ mov dword ptr [ eax + OFFSETOF__Array__m_Length - ASM_MIN_OBJECT_SIZE ], 0
44+
45+ ret
46+ .endif // Variation != ""
2547
48+ 1 : // AlreadyAligned
49+ mov eax , [ ecx + OFFSETOF__MethodTable__m_uBaseSize ]
2650 add eax , [ edx + OFFSETOF__ee_alloc_context__alloc_ptr ]
2751 cmp eax , [ edx + OFFSETOF__ee_alloc_context__combined_limit ]
28- ja AllocFailed
29-
30- // set the new alloc pointer
52+ ja 2f // AllocFailed
3153 mov [ edx + OFFSETOF__ee_alloc_context__alloc_ptr ], eax
3254
33- // calc the new object pointer
55+ // calc the new object pointer and initialize it
3456 sub eax , [ ecx + OFFSETOF__MethodTable__m_uBaseSize ]
35-
36- // set the new object's MethodTable pointer
3757 mov [ eax + OFFSETOF__Object__m_pEEType ], ecx
38- ret
3958
40- AllocFailed:
59+ ret
4160
42- xor edx , edx // Flags
61+ 2 : // AllocFailed
62+ .ifc \Variation ,
63+ xor edx , edx
64+ .else
65+ .ifc \Variation , Align8
66+ mov edx , GC_ALLOC_ALIGN8
67+ .else
68+ mov edx , GC_ALLOC_ALIGN8 + GC_ALLOC_ALIGN8_BIAS
69+ .endif
70+ .endif
4371 jmp RhpNewObject
4472
73+ .endm
74+
75+ // Allocate non - array , non - finalizable object. If the allocation doesn 't fit into the current thread' s
76+ // allocation context then automatically fallback to the slow allocation path.
77+ // ECX == MethodTable
78+ LEAF_ENTRY RhpNewFast , _TEXT
79+ NEW_FAST
4580LEAF_END RhpNewFast , _TEXT
4681
82+ // Allocate simple object ( not finalizable , array or value type) on an 8 byte boundary.
83+ // ECX == MethodTable
84+ LEAF_ENTRY RhpNewFastAlign8 , _TEXT
85+ NEW_FAST Align8
86+ LEAF_END RhpNewFastAlign8 , _TEXT
87+
88+ // Allocate a value type object (i.e. box it) on an 8 byte boundary + 4 (so th at the value type payload
89+ // itself is 8 byte aligned).
90+ // ECX == MethodTable
91+ LEAF_ENTRY RhpNewFastMisalign , _TEXT
92+ NEW_FAST Misalign
93+ LEAF_END RhpNewFastMisalign , _TEXT
94+
4795// Allocate non - array object with finalizer.
4896// ECX == MethodTable
4997LEAF_ENTRY RhpNewFinalizable , _TEXT
50-
5198 mov edx , GC_ALLOC_FINALIZE // Flags
5299 jmp RhpNewObject
53-
54100LEAF_END RhpNewFinalizable , _TEXT
55101
102+ // Allocate non - array object with finalizer on an 8 byte boundary.
103+ // ECX == MethodTable
104+ LEAF_ENTRY RhpNewFinalizableAlign8 , _TEXT
105+ mov edx , GC_ALLOC_FINALIZE + GC_ALLOC_ALIGN8 // Flags
106+ jmp RhpNewObject
107+ LEAF_END RhpNewFinalizableAlign8 , _TEXT
108+
56109// Allocate non - array object
57110// ECX == MethodTable
58111// EDX == alloc flags
@@ -253,21 +306,14 @@ LEAF_ENTRY RhpNewObjectArrayFast, _TEXT
253306LEAF_END RhpNewObjectArrayFast , _TEXT
254307#endif
255308
256-
257- //
258- // Object * RhpNewArray(MethodTable * pMT , INT_PTR size)
259- //
260- // ecx == MethodTable
261- // edx == element count
262- //
263- LEAF_ENTRY RhpNewArray , _TEXT
264-
309+ // Shared code for RhpNewArray and RhpNewArrayFastAlign8
310+ .macro NEW_ARRAY Flags
265311 PUSH_COOP_PINVOKE_FRAME eax
266312
267313 // Push alloc helper arguments (transition frame , size , flags , MethodTable).
268314 push eax // transition frame
269315 push edx // numElements
270- push 0 // Flags
316+ push \ Flags // Flags
271317 push ecx // MethodTable
272318
273319 // void * RhpGcAlloc(MethodTable * pEEType , uint32_t uFlags , uintptr_t numElements , void * pTransitionFrame)
@@ -278,15 +324,37 @@ LEAF_ENTRY RhpNewArray, _TEXT
278324 POP_COOP_PINVOKE_FRAME
279325
280326 test eax , eax
281- jz ArrayOutOfMemory
327+ jz 1f
282328
283329 ret
284330
285- ArrayOutOfMemory :
331+ 1 :
286332 // This is the OOM failure path. We're going to tail - call to a managed helper th at will throw
287333 // an out of memory exception th at the caller of this allocator understands.
288334
289335 xor edx , edx // Indicate th at we should throw OOM.
290336 jmp RhExceptionHandling_FailedAllocation
337+ .endm
291338
339+ //
340+ // Object * RhpNewArray(MethodTable * pMT , INT_PTR size)
341+ //
342+ // ecx == MethodTable
343+ // edx == element count
344+ //
345+ LEAF_ENTRY RhpNewArray , _TEXT
346+ NEW_ARRAY 0
292347LEAF_END RhpNewArray , _TEXT
348+
349+ //
350+ // Object * RhpNewArrayFastAlign8(MethodTable * pMT , INT_PTR size)
351+ //
352+ // ecx == MethodTable
353+ // edx == element count
354+ //
355+ LEAF_ENTRY RhpNewArrayFastAlign8 , _TEXT
356+ // We don't really provide a fast path here. CoreCLR has a configurable threshold
357+ // for array size to go to large object heap and it's not worth the extra effort
358+ // to check for it.
359+ NEW_ARRAY GC_ALLOC_ALIGN8
360+ LEAF_END RhpNewArrayFastAlign8 , _TEXT
0 commit comments