* Imports.
**********************************************************************/
+#include <os/feature_private.h> // os_feature_enabled_simple()
#include "objc-private.h"
#include "objc-loadmethod.h"
#include "objc-file.h"
#undef OPTION
};
+namespace objc {
+ int PageCountWarning = 50; // Default value if the environment variable is not set
+}
// objc's key for pthread_getspecific
#if SUPPORT_DIRECT_THREAD_KEYS
#endif
}
+/***********************************************************************
+* SetPageCountWarning
+* Convert environment variable value to integer value.
+* If the value is valid, set the global PageCountWarning value.
+**********************************************************************/
+void SetPageCountWarning(const char* envvar) {
+ if (envvar) {
+ long result = strtol(envvar, NULL, 10);
+ if (result <= INT_MAX && result >= -1) {
+ int32_t var = (int32_t)result;
+ if (var != 0) { // 0 is not a valid value for the env var
+ objc::PageCountWarning = var;
+ }
+ }
+ }
+}
/***********************************************************************
* environ_init
return;
}
+ // Turn off autorelease LRU coalescing by default for apps linked against
+ // older SDKs. LRU coalescing can reorder releases and certain older apps
+ // are accidentally relying on the ordering.
+ // rdar://problem/63886091
+ if (!dyld_program_sdk_at_least(dyld_fall_2020_os_versions))
+ DisableAutoreleaseCoalescingLRU = true;
+
bool PrintHelp = false;
bool PrintOptions = false;
bool maybeMallocDebugging = false;
continue;
}
+ if (0 == strncmp(*p, "OBJC_DEBUG_POOL_DEPTH=", 22)) {
+ SetPageCountWarning(*p + 22);
+ continue;
+ }
+
const char *value = strchr(*p, '=');
if (!*value) continue;
value++;
*opt->var = (0 == strcmp(value, "YES"));
break;
}
- }
+ }
}
- // Special case: enable some autorelease pool debugging
+ // Special case: enable some autorelease pool debugging
// when some malloc debugging is enabled
// and OBJC_DEBUG_POOL_ALLOCATION is not set to something other than NO.
if (maybeMallocDebugging) {
}
}
+ if (!os_feature_enabled_simple(objc4, preoptimizedCaches, true)) {
+ DisablePreoptCaches = true;
+ }
+
// Print OBJC_HELP and OBJC_PRINT_OPTIONS output.
if (PrintHelp || PrintOptions) {
if (PrintHelp) {
return _object_get_associative_reference(object, key);
}
-static void
-_base_objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
-{
- _object_set_associative_reference(object, key, value, policy);
-}
-
-static ChainedHookFunction<objc_hook_setAssociatedObject> SetAssocHook{_base_objc_setAssociatedObject};
+typedef void (*objc_hook_setAssociatedObject)(id _Nonnull object, const void * _Nonnull key,
+ id _Nullable value, objc_AssociationPolicy policy);
void
objc_setHook_setAssociatedObject(objc_hook_setAssociatedObject _Nonnull newValue,
objc_hook_setAssociatedObject _Nullable * _Nonnull outOldValue) {
- SetAssocHook.set(newValue, outOldValue);
+ // See objc_object::setHasAssociatedObjects() for a replacement
}
void
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
{
- SetAssocHook.get()(object, key, value, policy);
+ _object_set_associative_reference(object, key, value, policy);
}
-
void objc_removeAssociatedObjects(id object)
{
if (object && object->hasAssociatedObjects()) {
- _object_remove_assocations(object);
+ _object_remove_assocations(object, /*deallocating*/false);
}
}