Fix ivar offset calculation with alignment.

When upgrading legacy ivars, pick a sensible guess.
When calculating ivar offsets, use the supplied alignment.
main
David Chisnall 8 years ago
parent f91fb2e745
commit 5b0f05e6e0

@ -5,9 +5,9 @@
#include "objc/runtime.h"
#include "objc/objc-arc.h"
#include "class.h"
#include "ivar.h"
#include "visibility.h"
#include "gc_ops.h"
#include "legacy.h"
ptrdiff_t objc_alignof_type(const char *);
ptrdiff_t objc_sizeof_type(const char *);
@ -78,18 +78,14 @@ PRIVATE void objc_compute_ivar_offsets(Class class)
// 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
// where we don't add any extra padding.
if (!isGCEnabled && (ivar_size > sizeof(void*)))
if (!isGCEnabled && (ivar->align > __alignof__(void*)))
{
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);
long fudge = ivar->align - (offset % ivar->align);
*ivar->offset += fudge;
class->instance_size += fudge;
cumulative_fudge += fudge;
assert((ivar_start + *ivar->offset + sizeof(intptr_t)) % 16 == 0);
assert((ivar_start + *ivar->offset + sizeof(intptr_t)) % ivar->align == 0);
}
*ivar->offset += ivar_start;
}

@ -38,8 +38,15 @@ static struct objc_ivar_list *upgradeIvarList(struct legacy_gnustep_objc_class *
n->count = l->count;
for (int i=0 ; i<l->count ; i++)
{
int nextOffset = (i+1 < l->count) ? l->ivar_list[i+1].offset : cls->instance_size;
if (nextOffset < 0)
{
nextOffset = -nextOffset;
}
const char *type = l->ivar_list[i].type;
int size = nextOffset - l->ivar_list[i].offset;
n->ivar_list[i].name = l->ivar_list[i].name;
n->ivar_list[i].type = l->ivar_list[i].type;
n->ivar_list[i].type = type;
if (objc_test_class_flag_legacy(cls, objc_class_flag_new_abi))
{
n->ivar_list[i].offset = cls->ivar_offsets[i];
@ -48,8 +55,11 @@ static struct objc_ivar_list *upgradeIvarList(struct legacy_gnustep_objc_class *
{
n->ivar_list[i].offset = &l->ivar_list[i].offset;
}
const char *type = l->ivar_list[i].type;
n->ivar_list[i].align = ((type == NULL) || type[0] == 0) ? __alignof__(void*) : objc_alignof_type(type);
if (type[0] == '\0')
{
n->ivar_list[i].align = size;
}
ivarSetOwnership(&n->ivar_list[i], ownershipForIvar(cls, i));
}
return n;

Loading…
Cancel
Save