xref: /php-src/Zend/zend_weakrefs.h (revision cbf67e4f)
1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 2.00 of the Zend license,     |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | http://www.zend.com/license/2_00.txt.                                |
9    | If you did not receive a copy of the Zend license and are unable to  |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@zend.com so we can mail you a copy immediately.              |
12    +----------------------------------------------------------------------+
13    | Authors: krakjoe@php.net                                             |
14    +----------------------------------------------------------------------+
15 */
16 
17 #ifndef ZEND_WEAKREFS_H
18 #define ZEND_WEAKREFS_H
19 
20 #include "zend_alloc.h"
21 
22 BEGIN_EXTERN_C()
23 
24 extern ZEND_API zend_class_entry *zend_ce_weakref;
25 
26 void zend_register_weakref_ce(void);
27 
28 void zend_weakrefs_init(void);
29 void zend_weakrefs_shutdown(void);
30 
31 ZEND_API void zend_weakrefs_notify(zend_object *object);
32 
33 ZEND_API zval *zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pData);
34 ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key);
zend_weakrefs_hash_add_ptr(HashTable * ht,zend_object * key,void * ptr)35 static zend_always_inline void *zend_weakrefs_hash_add_ptr(HashTable *ht, zend_object *key, void *ptr) {
36 	zval tmp, *zv;
37 	ZVAL_PTR(&tmp, ptr);
38 	if ((zv = zend_weakrefs_hash_add(ht, key, &tmp))) {
39 		return Z_PTR_P(zv);
40 	} else {
41 		return NULL;
42 	}
43 }
44 
45 /* Because php uses the raw numbers as a hash function, raw pointers will lead to hash collisions.
46  * We have a guarantee that the lowest ZEND_MM_ALIGNED_OFFSET_LOG2 bits of a pointer are zero.
47  *
48  * E.g. On most 64-bit platforms, pointers are aligned to 8 bytes, so the least significant 3 bits are always 0 and can be discarded.
49  *
50  * NOTE: This function is only used for EG(weakrefs) and zend_weakmap->ht.
51  * It is not used for the HashTable instances associated with ZEND_WEAKREF_TAG_HT tags (created in zend_weakref_register, which uses ZEND_WEAKREF_ENCODE instead).
52  * The ZEND_WEAKREF_TAG_HT instances are used to disambiguate between multiple weak references to the same zend_object.
53  */
zend_object_to_weakref_key(const zend_object * object)54 static zend_always_inline zend_ulong zend_object_to_weakref_key(const zend_object *object)
55 {
56 	ZEND_ASSERT(((uintptr_t)object) % ZEND_MM_ALIGNMENT == 0);
57 	return ((uintptr_t) object) >> ZEND_MM_ALIGNMENT_LOG2;
58 }
59 
zend_weakref_key_to_object(zend_ulong key)60 static zend_always_inline zend_object *zend_weakref_key_to_object(zend_ulong key)
61 {
62 	return (zend_object *) (((uintptr_t) key) << ZEND_MM_ALIGNMENT_LOG2);
63 }
64 
65 HashTable *zend_weakmap_get_gc(zend_object *object, zval **table, int *n);
66 HashTable *zend_weakmap_get_key_entry_gc(zend_object *object, zval **table, int *n);
67 HashTable *zend_weakmap_get_entry_gc(zend_object *object, zval **table, int *n);
68 HashTable *zend_weakmap_get_object_key_entry_gc(zend_object *object, zval **table, int *n);
69 HashTable *zend_weakmap_get_object_entry_gc(zend_object *object, zval **table, int *n);
70 
71 END_EXTERN_C()
72 
73 #endif
74 
75