60
60
61
61
// we can't do the FCS code here, because its just super slow if
62
62
// the constant isn't known.
63
- // This is like call2 , except that we need do check the first
64
- // cache entry.
63
+ // This is like call_cache_collision , except that we still need do check the
64
+ // first cache entry.
65
65
MULLE_C_NEVER_INLINE
66
66
void * mulle_objc_object_call ( void * obj ,
67
67
mulle_objc_methodid_t methodid ,
@@ -169,29 +169,6 @@ void mulle_objc_implementation_trace( mulle_objc_implementation_t imp,
169
169
170
170
171
171
172
- static void mulle_objc_object_fail_thread_affinity ( struct _mulle_objc_object * obj ,
173
- mulle_thread_t affinity_thread ,
174
- char * name )
175
- {
176
- struct _mulle_objc_universe * universe ;
177
- struct _mulle_objc_class * cls ;
178
- int ismeta ;
179
-
180
- cls = _mulle_objc_object_get_isa ( obj );
181
- ismeta = _mulle_objc_class_is_metaclass ( cls );
182
- universe = _mulle_objc_class_get_universe ( cls );
183
-
184
- mulle_objc_universe_fail_generic ( universe ,
185
- "%s <%s %p> with affinity to thread %p gets a -%s call from thread %p" ,
186
- ismeta ? "Class" : "Object" ,
187
- _mulle_objc_class_get_name ( cls ),
188
- obj ,
189
- affinity_thread ,
190
- name ,
191
- mulle_thread_self ());
192
- }
193
-
194
-
195
172
// MEMO: TAO and the Cache
196
173
//
197
174
// When we do TAO, we need to call this often. The idea is that all methods
@@ -278,9 +255,11 @@ void mulle_objc_object_taocheck_call( void *obj,
278
255
case _mulle_objc_methodfamily_init :
279
256
case _mulle_objc_methodfamily_dealloc :
280
257
return ;
258
+ default :
259
+ break ;
281
260
}
282
261
283
- // forward: is not "methodid", that's what we foward to
262
+ // forward: is not "methodid", that's what we forward to
284
263
if ( method -> descriptor .methodid == MULLE_OBJC_FORWARD_METHODID )
285
264
return ;
286
265
@@ -291,7 +270,7 @@ void mulle_objc_object_taocheck_call( void *obj,
291
270
if ( _mulle_objc_universe_is_deinitializing ( universe ))
292
271
return ;
293
272
294
- mulle_objc_object_fail_thread_affinity ( obj , object_thread , _mulle_objc_descriptor_get_name ( desc ) );
273
+ mulle_objc_universe_fail_wrongthread ( universe , obj , object_thread , desc );
295
274
}
296
275
297
276
@@ -310,6 +289,7 @@ static void *_mulle_objc_object_callback_class( void *obj,
310
289
mulle_objc_implementation_t imp ;
311
290
mulle_functionpointer_t p ;
312
291
struct _mulle_objc_cache * cache ;
292
+ struct _mulle_objc_impcache * icache ;
313
293
struct _mulle_objc_cacheentry * entries ;
314
294
struct _mulle_objc_cacheentry * entry ;
315
295
struct _mulle_objc_method * method ;
@@ -339,7 +319,8 @@ static void *_mulle_objc_object_callback_class( void *obj,
339
319
340
320
if ( ! entry -> key .uniqueid )
341
321
{
342
- method = _mulle_objc_class_refresh_method_nofail ( cls , methodid );
322
+ icache = _mulle_objc_cache_get_impcache_from_cache ( cache );
323
+ method = (* icache -> callback .refresh_method_nofail )( cls , methodid );
343
324
imp = _mulle_objc_method_get_implementation ( method );
344
325
imp = _mulle_objc_implementation_debug ( imp , obj , methodid , parameter , cls );
345
326
break ;
@@ -358,13 +339,14 @@ static void *_mulle_objc_object_callback_class( void *obj,
358
339
// collision, it skips the first found entry. This method is put into
359
340
// the method cache, you don't call it directly.
360
341
//
361
- static void * _mulle_objc_object_callback2 ( void * obj ,
362
- mulle_objc_methodid_t methodid ,
363
- void * parameter )
342
+ static void * _mulle_objc_object_callback_cache_collision ( void * obj ,
343
+ mulle_objc_methodid_t methodid ,
344
+ void * parameter )
364
345
{
365
346
mulle_objc_implementation_t imp ;
366
347
mulle_functionpointer_t p ;
367
348
struct _mulle_objc_cache * cache ;
349
+ struct _mulle_objc_impcache * icache ;
368
350
struct _mulle_objc_cacheentry * entries ;
369
351
struct _mulle_objc_cacheentry * entry ;
370
352
struct _mulle_objc_method * method ;
@@ -395,7 +377,8 @@ static void *_mulle_objc_object_callback2( void *obj,
395
377
396
378
if ( ! entry -> key .uniqueid )
397
379
{
398
- method = _mulle_objc_class_refresh_method_nofail ( cls , methodid );
380
+ icache = _mulle_objc_cache_get_impcache_from_cache ( cache );
381
+ method = (* icache -> callback .refresh_method_nofail )( cls , methodid );
399
382
imp = _mulle_objc_method_get_implementation ( method );
400
383
imp = _mulle_objc_implementation_debug ( imp , obj , methodid , parameter , cls );
401
384
break ;
@@ -407,20 +390,48 @@ static void *_mulle_objc_object_callback2( void *obj,
407
390
}
408
391
409
392
393
+ //
394
+ // this function is called, when there is no entry in the cache
395
+ //
396
+ static void * _mulle_objc_object_callback_cache_miss ( void * obj ,
397
+ mulle_objc_methodid_t methodid ,
398
+ void * parameter )
399
+ {
400
+ mulle_objc_implementation_t imp ;
401
+ struct _mulle_objc_method * method ;
402
+ struct _mulle_objc_class * cls ;
403
+ struct _mulle_objc_impcache * icache ;
404
+ struct _mulle_objc_cache * cache ;
405
+ struct _mulle_objc_cacheentry * entries ;
406
+
407
+ assert ( mulle_objc_uniqueid_is_sane ( methodid ));
408
+
409
+ cls = _mulle_objc_object_get_isa ( obj );
410
+ entries = _mulle_objc_cachepivot_get_entries_atomic ( & cls -> cachepivot .pivot );
411
+ cache = _mulle_objc_cacheentry_get_cache_from_entries ( entries );
412
+ icache = _mulle_objc_cache_get_impcache_from_cache ( cache );
413
+ method = (* icache -> callback .refresh_method_nofail )( cls , methodid );
414
+ imp = _mulle_objc_method_get_implementation ( method );
415
+ imp = _mulle_objc_implementation_debug ( imp , obj , methodid , parameter , cls );
416
+ return ( (* imp )( obj , methodid , parameter ));
417
+ }
418
+
419
+
410
420
//
411
421
// This function is called, when the first inline cache check gave a
412
422
// collision, it skips the first found entry. This is not called directly
413
423
// but placed into the method cache.
414
424
//
415
425
static void *
416
- _mulle_objc_object_call_superback ( void * obj ,
426
+ _mulle_objc_object_callback_super ( void * obj ,
417
427
mulle_objc_methodid_t methodid ,
418
428
void * parameter ,
419
429
mulle_objc_superid_t superid ,
420
430
struct _mulle_objc_class * cls )
421
431
{
422
432
mulle_objc_implementation_t imp ;
423
433
struct _mulle_objc_cache * cache ;
434
+ struct _mulle_objc_impcache * icache ;
424
435
struct _mulle_objc_cacheentry * entries ;
425
436
struct _mulle_objc_cacheentry * entry ;
426
437
struct _mulle_objc_method * method ;
@@ -445,7 +456,8 @@ static void *
445
456
}
446
457
if ( ! entry -> key .uniqueid )
447
458
{
448
- method = _mulle_objc_class_refresh_supermethod_nofail ( cls , superid );
459
+ icache = _mulle_objc_cache_get_impcache_from_cache ( cache );
460
+ method = (* icache -> callback .refresh_supermethod_nofail )( cls , superid );
449
461
imp = _mulle_objc_method_get_implementation ( method );
450
462
imp = _mulle_objc_implementation_debug ( imp , obj , methodid , parameter , cls );
451
463
break ;
@@ -458,14 +470,15 @@ static void *
458
470
459
471
460
472
static void *
461
- _mulle_objc_object_call_superback2 ( void * obj ,
462
- mulle_objc_methodid_t methodid ,
463
- void * parameter ,
464
- mulle_objc_superid_t superid ,
465
- struct _mulle_objc_class * cls )
473
+ _mulle_objc_object_callback_super_cache_collision ( void * obj ,
474
+ mulle_objc_methodid_t methodid ,
475
+ void * parameter ,
476
+ mulle_objc_superid_t superid ,
477
+ struct _mulle_objc_class * cls )
466
478
{
467
479
mulle_objc_implementation_t imp ;
468
480
struct _mulle_objc_cache * cache ;
481
+ struct _mulle_objc_impcache * icache ;
469
482
struct _mulle_objc_cacheentry * entries ;
470
483
struct _mulle_objc_cacheentry * entry ;
471
484
struct _mulle_objc_method * method ;
@@ -492,7 +505,8 @@ static void *
492
505
493
506
if ( ! entry -> key .uniqueid )
494
507
{
495
- method = _mulle_objc_class_refresh_supermethod_nofail ( cls , superid );
508
+ icache = _mulle_objc_cache_get_impcache_from_cache ( cache );
509
+ method = (* icache -> callback .refresh_supermethod_nofail )( cls , superid );
496
510
imp = _mulle_objc_method_get_implementation ( method );
497
511
imp = _mulle_objc_implementation_debug ( imp , obj , methodid , parameter , cls );
498
512
break ;
@@ -502,15 +516,43 @@ static void *
502
516
}
503
517
504
518
505
- void _mulle_objc_impcache_init_normal_callbacks ( struct _mulle_objc_impcache * p )
519
+ static void *
520
+ _mulle_objc_object_callback_super_cache_miss ( void * obj ,
521
+ mulle_objc_methodid_t methodid ,
522
+ void * parameter ,
523
+ mulle_objc_superid_t superid ,
524
+ struct _mulle_objc_class * cls )
506
525
{
507
- p -> call = _mulle_objc_object_callback_class ;
508
- p -> call2 = _mulle_objc_object_callback2 ;
509
- p -> supercall = _mulle_objc_object_call_superback ; // public actually
510
- p -> supercall2 = _mulle_objc_object_call_superback2 ;
526
+ mulle_objc_implementation_t imp ;
527
+ struct _mulle_objc_method * method ;
528
+ struct _mulle_objc_impcache * icache ;
529
+ struct _mulle_objc_cache * cache ;
530
+ struct _mulle_objc_cacheentry * entries ;
531
+
532
+ entries = _mulle_objc_cachepivot_get_entries_atomic ( & cls -> cachepivot .pivot );
533
+ cache = _mulle_objc_cacheentry_get_cache_from_entries ( entries );
534
+ icache = _mulle_objc_cache_get_impcache_from_cache ( cache );
535
+ method = (* icache -> callback .refresh_supermethod_nofail )( cls , superid );
536
+ imp = _mulle_objc_method_get_implementation ( method );
537
+ imp = _mulle_objc_implementation_debug ( imp , obj , methodid , parameter , cls );
538
+ return ( (* imp )( obj , methodid , parameter ));
511
539
}
512
540
513
541
542
+ struct _mulle_objc_impcache_callback _mulle_objc_impcache_callback_normal =
543
+ {
544
+ .call = _mulle_objc_object_callback_class ,
545
+ .call_cache_collision = _mulle_objc_object_callback_cache_collision ,
546
+ .call_cache_miss = _mulle_objc_object_callback_cache_miss ,
547
+ .supercall = _mulle_objc_object_callback_super , // public actually
548
+ .supercall_cache_collision = _mulle_objc_object_callback_super_cache_collision ,
549
+ .supercall_cache_miss = _mulle_objc_object_callback_super_cache_miss ,
550
+
551
+ .refresh_method_nofail = _mulle_objc_class_refresh_method_nofail ,
552
+ .refresh_supermethod_nofail = _mulle_objc_class_refresh_supermethod_nofail
553
+ };
554
+
555
+
514
556
// need to call cls->call to prepare caches
515
557
516
558
#pragma mark - multiple objects call
@@ -557,7 +599,6 @@ void mulle_objc_objects_call( void **objects,
557
599
assert ( imp );
558
600
}
559
601
560
- // this should use mulle_objc_implementation_invoke
561
602
mulle_objc_implementation_invoke ( lastSelIMP [ i ], p , methodid , params );
562
603
}
563
604
}
0 commit comments