1/*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *     http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20/*
21    auto_weak.h
22    Weak reference accounting
23    Copyright (c) 2004-2011 Apple Inc. All rights reserved.
24 */
25
26#ifndef __AUTO_WEAK__
27#define __AUTO_WEAK__
28
29#define AUTO_USE_NEW_WEAK_CALLBACK
30#include "auto_impl_utilities.h"
31
32__BEGIN_DECLS
33
34namespace Auto {
35    class Zone;
36}
37
38/*
39The weak table is a hash table governed by a single spin lock.
40An allocated blob of memory, most often an object, but under GC any such allocation,
41may have its address stored in a __weak marked storage location through use of
42compiler generated write-barriers or hand coded uses of the register weak primitive.
43Associated with the registration can be a callback block for the case when one of
44 the allocated chunks of memory is reclaimed.
45The table is hashed on the address of the allocated memory.  When __weak marked memory
46 changes its reference, we count on the fact that we can still see its previous reference.
47
48So, in the hash table, indexed by the weakly referenced item, is a list of all locations
49 where this address is currently being stored.
50
51*/
52
53struct weak_referrer_t {
54    void **referrer;    // clear this address
55    auto_weak_callback_block_t *block;
56};
57typedef struct weak_referrer_t weak_referrer_t;
58
59// clear references to garbage
60extern auto_weak_callback_block_t *weak_clear_references(Auto::Zone *azone, size_t garbage_count, vm_address_t *garbage, uintptr_t *weak_referents_count, uintptr_t *weak_refs_count);
61
62// register a new weak reference
63extern void weak_register(Auto::Zone *azone, const void *referent, void **referrer, auto_weak_callback_block_t *block);
64
65// unregister an existing weak reference
66extern void weak_unregister(Auto::Zone *azone, const void *referent, void **referrer);
67
68// unregister all weak references from a block.
69extern void weak_unregister_with_layout(Auto::Zone *azone, void *block[], const unsigned char *map);
70
71// unregister weak references in a block range.
72extern void weak_unregister_range(Auto::Zone *azone, void **referrers, size_t count);
73
74// call all registered weak reference callbacks.
75extern void weak_call_callbacks(auto_weak_callback_block_t *block);
76
77// unregister all weak references within a known address range.
78extern void weak_unregister_data_segment(Auto::Zone *azone, void *base, size_t size);
79
80// NOTE:  the remaining routines all assume the weak lock is held by the caller.
81
82// forwards weak references from oldReferent to newReferent.
83extern void weak_transfer_weak_referents(Auto::Zone *azone, const void *oldReferent, const void *newReferent);
84extern void weak_transfer_weak_contents(Auto::Zone *azone, void *oldBlock[], void *newBlock[], const uint8_t *map);
85extern void weak_transfer_weak_contents_unscanned(Auto::Zone *azone, void *oldBlock[], void *newBlock[], size_t size, bool forwarding);
86
87// unregister weak references in a block range.
88extern void weak_unregister_range_no_lock(Auto::Zone *azone, void **referrers, size_t count);
89
90#ifdef __BLOCKS__
91
92typedef void (^weak_ref_visitor_t) (const weak_referrer_t &ref);
93
94// dump just the weak references to this block.
95extern void weak_enumerate_weak_references(Auto::Zone *azone, const void *referent, weak_ref_visitor_t visitor);
96
97// dump all weak registrations
98extern void weak_enumerate_table(Auto::Zone *azone, weak_ref_visitor_t visitor);
99
100// fixup all weak registrations (compaction)
101typedef void (^weak_ref_fixer_t) (weak_referrer_t &ref);
102extern void weak_enumerate_table_fixup(Auto::Zone *azone, weak_ref_fixer_t fixer);
103
104#endif
105
106__END_DECLS
107
108#endif /* __AUTO_WEAK__ */
109