1/* 2 * Copyright (c) 2010-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#ifndef _OBJC_WEAK_H_ 25#define _OBJC_WEAK_H_ 26 27#include <objc/objc.h> 28#include "objc-config.h" 29 30__BEGIN_DECLS 31 32/* 33The weak table is a hash table governed by a single spin lock. 34An allocated blob of memory, most often an object, but under GC any such 35allocation, may have its address stored in a __weak marked storage location 36through use of compiler generated write-barriers or hand coded uses of the 37register weak primitive. Associated with the registration can be a callback 38block for the case when one of the allocated chunks of memory is reclaimed. 39The table is hashed on the address of the allocated memory. When __weak 40marked memory changes its reference, we count on the fact that we can still 41see its previous reference. 42 43So, in the hash table, indexed by the weakly referenced item, is a list of 44all locations where this address is currently being stored. 45 46For ARR, we also keep track of whether an arbitrary object is being 47deallocated by briefly placing it in the table just prior to invoking 48dealloc, and removing it via objc_clear_deallocating just prior to memory 49reclamation. 50 51*/ 52 53/// The address of a __weak object reference 54typedef objc_object ** weak_referrer_t; 55 56#if __LP64__ 57#define PTR_MINUS_1 63 58#else 59#define PTR_MINUS_1 31 60#endif 61 62/** 63 * The internal structure stored in the weak references table. 64 * It maintains and stores 65 * a hash set of weak references pointing to an object. 66 * If out_of_line==0, the set is instead a small inline array. 67 */ 68#define WEAK_INLINE_COUNT 4 69struct weak_entry_t { 70 DisguisedPtr<objc_object> referent; 71 union { 72 struct { 73 weak_referrer_t *referrers; 74 uintptr_t out_of_line : 1; 75 uintptr_t num_refs : PTR_MINUS_1; 76 uintptr_t mask; 77 uintptr_t max_hash_displacement; 78 }; 79 struct { 80 // out_of_line=0 is LSB of one of these (don't care which) 81 weak_referrer_t inline_referrers[WEAK_INLINE_COUNT]; 82 }; 83 }; 84}; 85 86/** 87 * The global weak references table. Stores object ids as keys, 88 * and weak_entry_t structs as their values. 89 */ 90struct weak_table_t { 91 weak_entry_t *weak_entries; 92 size_t num_entries; 93 uintptr_t mask; 94 uintptr_t max_hash_displacement; 95}; 96 97/// Adds an (object, weak pointer) pair to the weak table. 98id weak_register_no_lock(weak_table_t *weak_table, id referent, id *referrer); 99 100/// Removes an (object, weak pointer) pair from the weak table. 101void weak_unregister_no_lock(weak_table_t *weak_table, id referent, id *referrer); 102 103#if !NDEBUG 104/// Returns true if an object is weakly referenced somewhere. 105bool weak_is_registered_no_lock(weak_table_t *weak_table, id referent); 106#endif 107 108/// Assert a weak pointer is valid and retain the object during its use. 109id weak_read_no_lock(weak_table_t *weak_table, id *referrer); 110 111/// Called on object destruction. Sets all remaining weak pointers to nil. 112void weak_clear_no_lock(weak_table_t *weak_table, id referent); 113 114__END_DECLS 115 116#endif /* _OBJC_WEAK_H_ */ 117