ObjFW  Check-in [5fd6d0a46d]

Overview
Comment:Properly align objects on MS-DOS

When running an MS-DOS application on Windows 98 SE, it is possible to
use SSE in an MS-DOS application, so it is important that objects are
aligned properly.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5fd6d0a46d6a0196a0dabde342ceeb6e0af62ca89fb3f1d1fdcad76445229fdc
User & Date: js on 2024-03-28 18:29:13
Other Links: manifest | tags
Context
2024-03-28
21:01
Set version to 1.2dev check-in: cb375e3914 user: js tags: trunk
21:00
Branch for 1.1 check-in: 27115cc8f6 user: js tags: 1.1
18:29
Properly align objects on MS-DOS check-in: 5fd6d0a46d user: js tags: trunk
15:58
OFMatrix4x4: Move values to ivars check-in: 71237f1a49 user: js tags: trunk
Changes

Modified src/OFObject.m from [69eb852a00] to [3ec904d9fc].

77
78
79
80
81
82
83



84
85
86
87
88
89
90
extern struct Stret OFForward_stret(id, SEL, ...);
#else
# define OFForward OFMethodNotFound
# define OFForward_stret OFMethodNotFound_stret
#endif

struct PreIvars {



	int retainCount;
#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	OFSpinlock retainCountSpinlock;
#endif
};

#define PRE_IVARS_ALIGN \







>
>
>







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
extern struct Stret OFForward_stret(id, SEL, ...);
#else
# define OFForward OFMethodNotFound
# define OFForward_stret OFMethodNotFound_stret
#endif

struct PreIvars {
#ifdef OF_MSDOS
	ptrdiff_t offset;
#endif
	int retainCount;
#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	OFSpinlock retainCountSpinlock;
#endif
};

#define PRE_IVARS_ALIGN \
153
154
155
156
157
158
159



























160
161
162
163
164
165
166
}

void
OFFreeMemory(void *pointer)
{
	free(pointer);
}




























#if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM)
static void
initRandom(void)
{
	struct timeval tv;








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
}

void
OFFreeMemory(void *pointer)
{
	free(pointer);
}

#ifdef OF_MSDOS
/* Unfortunately, DJGPP's memalign() is broken. */

static void *
alignedAlloc(size_t size, size_t alignment, ptrdiff_t *offset)
{
	char *ptr, *aligned;

	if ((ptr = malloc(size + alignment)) == NULL)
		return NULL;

	aligned = (char *)OFRoundUpToPowerOf2(alignment, (uintptr_t)ptr);
	*offset = aligned - ptr;

	return aligned;
}

static void
alignedFree(void *ptr, ptrdiff_t offset)
{
	if (ptr == NULL)
		return;

	free((void *)((uintptr_t)ptr - offset));
}
#endif

#if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM)
static void
initRandom(void)
{
	struct timeval tv;

328
329
330
331
332
333
334



335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350








351
352
353
354
355
356
357
358



359
360
361
362
363
364
365


366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382


383
384
385
386
387
388
389
390
391

id
OFAllocObject(Class class, size_t extraSize, size_t extraAlignment,
    void **extra)
{
	OFObject *instance;
	size_t instanceSize;




	instanceSize = class_getInstanceSize(class);

	if OF_UNLIKELY (extraAlignment > 1)
		extraAlignment = OFRoundUpToPowerOf2(extraAlignment,
		    PRE_IVARS_ALIGN + instanceSize) -
		    PRE_IVARS_ALIGN - instanceSize;

#ifndef OF_WINDOWS
	instance = calloc(1, PRE_IVARS_ALIGN + instanceSize +
	    extraAlignment + extraSize);
#else
	instance = __mingw_aligned_malloc(PRE_IVARS_ALIGN + instanceSize +
	    extraAlignment + extraSize, OF_BIGGEST_ALIGNMENT);
	memset(instance, 0, PRE_IVARS_ALIGN + instanceSize + extraAlignment +
	    extraSize);








#endif

	if OF_UNLIKELY (instance == nil) {
		object_setClass((id)&allocFailedException,
		    [OFAllocFailedException class]);
		@throw (id)&allocFailedException;
	}




	((struct PreIvars *)instance)->retainCount = 1;

#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	if OF_UNLIKELY (OFSpinlockNew(
	    &((struct PreIvars *)instance)->retainCountSpinlock) != 0) {
# ifndef OF_WINDOWS
		free(instance);


# else
		__mingw_aligned_free(instance);
# endif
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}
#endif

	instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN);

	if (!objc_constructInstance(class, instance)) {
#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
		OFSpinlockFree(&((struct PreIvars *)(void *)
		    ((char *)instance - PRE_IVARS_ALIGN))->retainCountSpinlock);
#endif
#ifndef OF_WINDOWS
		free((char *)instance - PRE_IVARS_ALIGN);


#else
		__mingw_aligned_free((char *)instance - PRE_IVARS_ALIGN);
#endif
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}

	if OF_UNLIKELY (extra != NULL)
		*extra = (char *)instance + instanceSize + extraAlignment;







>
>
>








|
<
<
<




>
>
>
>
>
>
>
>








>
>
>





|
|
>
>

|













|
|
>
>

|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436

id
OFAllocObject(Class class, size_t extraSize, size_t extraAlignment,
    void **extra)
{
	OFObject *instance;
	size_t instanceSize;
#ifdef OF_MSDOS
	ptrdiff_t offset;
#endif

	instanceSize = class_getInstanceSize(class);

	if OF_UNLIKELY (extraAlignment > 1)
		extraAlignment = OFRoundUpToPowerOf2(extraAlignment,
		    PRE_IVARS_ALIGN + instanceSize) -
		    PRE_IVARS_ALIGN - instanceSize;

#if defined(OF_WINDOWS)



	instance = __mingw_aligned_malloc(PRE_IVARS_ALIGN + instanceSize +
	    extraAlignment + extraSize, OF_BIGGEST_ALIGNMENT);
	memset(instance, 0, PRE_IVARS_ALIGN + instanceSize + extraAlignment +
	    extraSize);
#elif defined(OF_MSDOS)
	instance = alignedAlloc(PRE_IVARS_ALIGN + instanceSize +
	    extraAlignment + extraSize, OF_BIGGEST_ALIGNMENT, &offset);
	memset(instance, 0, PRE_IVARS_ALIGN + instanceSize + extraAlignment +
	    extraSize);
#else
	instance = calloc(1, PRE_IVARS_ALIGN + instanceSize +
	    extraAlignment + extraSize);
#endif

	if OF_UNLIKELY (instance == nil) {
		object_setClass((id)&allocFailedException,
		    [OFAllocFailedException class]);
		@throw (id)&allocFailedException;
	}

#ifdef OF_MSDOS
	((struct PreIvars *)instance)->offset = offset;
#endif
	((struct PreIvars *)instance)->retainCount = 1;

#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	if OF_UNLIKELY (OFSpinlockNew(
	    &((struct PreIvars *)instance)->retainCountSpinlock) != 0) {
# if defined(OF_WINDOWS)
		__mingw_aligned_free(instance);
# elif defined(OF_MSDOS)
		alignedFree(instance, offset);
# else
		free(instance);
# endif
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}
#endif

	instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN);

	if (!objc_constructInstance(class, instance)) {
#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
		OFSpinlockFree(&((struct PreIvars *)(void *)
		    ((char *)instance - PRE_IVARS_ALIGN))->retainCountSpinlock);
#endif
#if defined(OF_WINDOWS)
		__mingw_aligned_free((char *)instance - PRE_IVARS_ALIGN);
#elif defined(OF_MSDOS)
		alignedFree((char *)instance - PRE_IVARS_ALIGN, offset);
#else
		free((char *)instance - PRE_IVARS_ALIGN);
#endif
		@throw [OFInitializationFailedException
		    exceptionWithClass: class];
	}

	if OF_UNLIKELY (extra != NULL)
		*extra = (char *)instance + instanceSize + extraAlignment;
1245
1246
1247
1248
1249
1250
1251
1252
1253


1254
1255
1256
1257
1258
1259
1260
1261
1262
{
	objc_destructInstance(self);

#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	OFSpinlockFree(&PRE_IVARS->retainCountSpinlock);
#endif

#ifndef OF_WINDOWS
	free((char *)self - PRE_IVARS_ALIGN);


#else
	__mingw_aligned_free((char *)self - PRE_IVARS_ALIGN);
#endif
}

/* Required to use properties with the Apple runtime */
- (id)copyWithZone: (void *)zone
{
	if OF_UNLIKELY (zone != NULL) {







|
|
>
>

|







1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
{
	objc_destructInstance(self);

#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	OFSpinlockFree(&PRE_IVARS->retainCountSpinlock);
#endif

#if defined(OF_WINDOWS)
	__mingw_aligned_free((char *)self - PRE_IVARS_ALIGN);
#elif defined(OF_MSDOS)
	alignedFree((char *)self - PRE_IVARS_ALIGN, PRE_IVARS->offset);
#else
	free((char *)self - PRE_IVARS_ALIGN);
#endif
}

/* Required to use properties with the Apple runtime */
- (id)copyWithZone: (void *)zone
{
	if OF_UNLIKELY (zone != NULL) {