Forcibly realign instance variables to take into account the padding

from the reference count.
main
David Chisnall 9 years ago
parent 9a2f43ca7d
commit 6df23377a0

@ -5,7 +5,7 @@
# List of single-file tests. # List of single-file tests.
set(TESTS set(TESTS
#alignTest.m alignTest.m
AllocatePair.m AllocatePair.m
AssociatedObject.m AssociatedObject.m
AssociatedObject2.m AssociatedObject2.m

@ -36,7 +36,24 @@ typedef double __attribute__((vector_size(32))) v4d;
} }
@end @end
typedef int v4si __attribute__ ((vector_size (16)));
@interface Foo : Test
{
v4si var;
}
- (void)check;
@end
@implementation Foo
- (void)check
{
size_t addr = (size_t)&var;
fprintf(stderr, "self: %p Addr: %p\n", self, &var);
assert(addr % 16 == 0);
}
@end
int main(void) int main(void)
{ {
[[Vector alloc] permute]; [[Vector alloc] permute];
[[Foo new] check];
} }

@ -1,3 +1,4 @@
#include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -56,30 +57,24 @@ PRIVATE void objc_compute_ivar_offsets(Class class)
long ivar_size = (i+1 == class->ivars->count) long ivar_size = (i+1 == class->ivars->count)
? (class_size - ivar->offset) ? (class_size - ivar->offset)
: ivar->offset - class->ivars->ivar_list[i+1].offset; : ivar->offset - class->ivars->ivar_list[i+1].offset;
#if 0
// We only need to do the realignment for things that are // We only need to do the realignment for things that are
// bigger than a pointer, and we don't need to do it in GC mode // bigger than a pointer, and we don't need to do it in GC mode
// where we don't add any extra padding. // where we don't add any extra padding.
if (!isGCEnabled && (ivar_size > sizeof(void*))) if (!isGCEnabled && (ivar_size > sizeof(void*)))
{ {
long fudge = (ivar_start +ivar->offset + sizeof(void*)) % 16; long offset = ivar_start + ivar->offset + sizeof(intptr_t);
// For now, assume that nothing needs to be more than 16-byte aligned.
// This is not correct for AVX vectors, but we probably
// can't do anything about that for now (as malloc is only
// giving us 16-byte aligned memory)
long fudge = 16 - (offset % 16);
if (fudge != 0) if (fudge != 0)
{ {
// If this is the first ivar in the class, then ivar->offset += fudge;
// we can eat some of the padding that the compiler class->instance_size += fudge;
// added... assert((ivar_start + ivar->offset + sizeof(intptr_t)) % 16 == 0);
if ((i == 0) && (ivar->offset > 0) && ((ivar_start + sizeof(void*) %16) == 0))
{
ivar->offset = 0;
}
else
{
ivar_start += fudge;
class->instance_size += fudge;
}
} }
} }
#endif
ivar->offset += ivar_start; ivar->offset += ivar_start;
/* If we're using the new ABI then we also set up the faster ivar /* If we're using the new ABI then we also set up the faster ivar
* offset variables. * offset variables.

Loading…
Cancel
Save