|
10 | 10 | // r0 == MethodTable
|
11 | 11 | .macro NEW_FAST Variation
|
12 | 12 | PROLOG_PUSH "{r4,lr}"
|
13 |
| - mov r4, r0 // save MethodTable |
| 13 | + mov r4, r0 // save MethodTable |
14 | 14 |
|
15 | 15 | // r0 = ee_alloc_context pointer; trashes volatile registers, expects saved lr
|
16 | 16 | INLINE_GET_ALLOC_CONTEXT_BASE
|
17 | 17 |
|
| 18 | + ldr r2, [r4, #OFFSETOF__MethodTable__m_uBaseSize] |
| 19 | + |
| 20 | + // Load potential new object address into r3. |
| 21 | + ldr r3, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
| 22 | + |
| 23 | + // Load and calculate the maximum size of object we can fit. |
| 24 | + ldr r1, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit)] |
| 25 | + sub r1, r3 |
| 26 | + |
18 | 27 | // When doing aligned or misaligned allocation we first check
|
19 | 28 | // the alignment and skip to the regular path if it's already
|
20 | 29 | // matching the expectation.
|
21 | 30 | // Otherwise, we try to allocate size + ASM_MIN_OBJECT_SIZE and
|
22 | 31 | // then prepend a dummy free object at the beginning of the
|
23 | 32 | // allocation.
|
24 | 33 | .ifnc \Variation,
|
25 |
| - ldr r3, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
26 | 34 | tst r3, #0x7
|
27 | 35 | .ifc \Variation,Align8
|
28 | 36 | beq 1f // AlreadyAligned
|
29 | 37 | .else // Variation == "Misalign"
|
30 | 38 | bne 1f // AlreadyAligned
|
31 | 39 | .endif
|
32 | 40 |
|
33 |
| - ldr r2, [r4, #OFFSETOF__MethodTable__m_uBaseSize] |
34 | 41 | add r2, ASM_MIN_OBJECT_SIZE
|
35 |
| - ldr r3, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
36 |
| - add r2, r3 |
37 |
| - bcs 2f // AllocFailed |
38 |
| - ldr r1, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit)] |
| 42 | + |
| 43 | + // Determine whether the end of the object is too big for the current allocation context. If so, |
| 44 | + // we abandon the attempt to allocate the object directly and fall back to the slow helper. |
39 | 45 | cmp r2, r1
|
40 | 46 | bhi 2f // AllocFailed
|
41 | 47 |
|
42 |
| - // set the new alloc pointer |
| 48 | + // Update the alloc pointer to account for the allocation. |
| 49 | + add r2, r3 |
43 | 50 | str r2, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)]
|
44 | 51 |
|
45 |
| - // initialize the padding object preceeding the new object |
| 52 | + // Initialize the padding object preceeding the new object. |
46 | 53 | PREPARE_EXTERNAL_VAR_INDIRECT G_FREE_OBJECT_METHOD_TABLE, r2
|
47 | 54 | str r2, [r3, #OFFSETOF__Object__m_pEEType]
|
48 | 55 | mov r2, #0
|
49 | 56 | str r2, [r3, #OFFSETOF__Array__m_Length]
|
50 | 57 |
|
51 |
| - // calc the new object pointer and initialize it |
| 58 | + // Calculate the new object pointer and initialize it. |
52 | 59 | add r3, ASM_MIN_OBJECT_SIZE
|
53 | 60 | str r4, [r3, #OFFSETOF__Object__m_pEEType]
|
54 | 61 |
|
| 62 | + // Return the object allocated in r0. |
55 | 63 | mov r0, r3
|
56 | 64 |
|
57 | 65 | EPILOG_POP "{r4,pc}"
|
58 | 66 | .endif // Variation != ""
|
59 | 67 |
|
60 | 68 | 1: // AlreadyAligned
|
61 | 69 |
|
62 |
| - // r4 contains MethodTable pointer |
63 |
| - ldr r2, [r4, #OFFSETOF__MethodTable__m_uBaseSize] |
64 |
| - |
65 | 70 | // r0: ee_alloc_context pointer
|
66 |
| - // r4: MethodTable pointer |
| 71 | + // r1: ee_alloc_context.combined_limit |
67 | 72 | // r2: base size
|
| 73 | + // r3: ee_alloc_context.alloc_ptr |
| 74 | + // r4: MethodTable pointer |
68 | 75 |
|
69 |
| - ldr r3, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
70 |
| - add r2, r3 |
71 |
| - bcs 2f // AllocFailed |
72 |
| - ldr r1, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit)] |
| 76 | + // Determine whether the end of the object is too big for the current allocation context. If so, |
| 77 | + // we abandon the attempt to allocate the object directly and fall back to the slow helper. |
73 | 78 | cmp r2, r1
|
74 | 79 | bhi 2f // AllocFailed
|
75 | 80 |
|
76 |
| - // set the new alloc pointer |
77 |
| - str r2, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
| 81 | + // Calculate the new alloc pointer to account for the allocation. |
| 82 | + add r2, r3 |
78 | 83 |
|
79 |
| - // Set the new object's MethodTable pointer |
| 84 | + // Set the new object's MethodTable pointer. |
80 | 85 | str r4, [r3, #OFFSETOF__Object__m_pEEType]
|
81 | 86 |
|
| 87 | + // Update the alloc pointer to the newly calculated one. |
| 88 | + str r2, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
| 89 | + |
| 90 | + // Return the object allocated in r0. |
82 | 91 | mov r0, r3
|
83 | 92 |
|
84 | 93 | EPILOG_POP "{r4,pc}"
|
@@ -198,27 +207,27 @@ NESTED_END RhpNewObject, _TEXT
|
198 | 207 | // r6 == string/array size
|
199 | 208 | // r0 == ee_alloc_context*
|
200 | 209 |
|
201 |
| - // Load potential new object address into r12. |
202 |
| - ldr r12, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
| 210 | + // Load potential new object address into r3. |
| 211 | + ldr r3, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
203 | 212 |
|
204 |
| - // Determine whether the end of the object would lie outside of the current allocation context. If so, |
205 |
| - // we abandon the attempt to allocate the object directly and fall back to the slow helper. |
206 |
| - adds r6, r12 |
207 |
| - bcs 1f // if we get a carry here, the string/array is too large to fit below 4 GB |
| 213 | + // Load and calculate the maximum size of object we can fit |
| 214 | + ldr r1, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit)] |
| 215 | + sub r1, r3 |
208 | 216 |
|
209 |
| - ldr r12, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__combined_limit)] |
210 |
| - cmp r6, r12 |
| 217 | + // Determine whether the end of the object is too big for the current allocation context. If so, |
| 218 | + // we abandon the attempt to allocate the object directly and fall back to the slow helper. |
| 219 | + cmp r6, r1 |
211 | 220 | bhi 1f
|
212 | 221 |
|
213 |
| - // Reload new object address into r12. |
214 |
| - ldr r12, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
215 |
| - |
216 |
| - // Update the alloc pointer to account for the allocation. |
217 |
| - str r6, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
| 222 | + // Calculate the alloc pointer to account for the allocation. |
| 223 | + add r6, r3 |
218 | 224 |
|
219 | 225 | // Set the new object's MethodTable pointer and element count.
|
220 |
| - str r4, [r12, #OFFSETOF__Object__m_pEEType] |
221 |
| - str r5, [r12, #OFFSETOF__Array__m_Length] |
| 226 | + str r4, [r3, #OFFSETOF__Object__m_pEEType] |
| 227 | + str r5, [r3, #OFFSETOF__Array__m_Length] |
| 228 | + |
| 229 | + // Update the alloc pointer to the newly calculated one. |
| 230 | + str r6, [r0, #(OFFSETOF__ee_alloc_context + OFFSETOF__ee_alloc_context__alloc_ptr)] |
222 | 231 |
|
223 | 232 | // Return the object allocated in r0.
|
224 | 233 | mov r0, r12
|
|
0 commit comments