]> git.saurik.com Git - apple/objc4.git/blobdiff - runtime/objc-externalref.mm
objc4-706.tar.gz
[apple/objc4.git] / runtime / objc-externalref.mm
diff --git a/runtime/objc-externalref.mm b/runtime/objc-externalref.mm
deleted file mode 100644 (file)
index 8511fe9..0000000
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Copyright (c) 2010 Apple Inc.  All Rights Reserved.
- * 
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "objc-private.h"
-
-#include <malloc/malloc.h>
-#include <assert.h>
-#include "runtime.h"
-#include "objc-os.h"
-#include "message.h"
-#if SUPPORT_GC
-#include "auto_zone.h"
-#endif
-
-enum {
-    // external references to data segment objects all use this type
-    OBJC_XREF_TYPE_STATIC = 3,
-    
-    OBJC_XREF_TYPE_MASK = 3
-};
-
-// Macros to encode/decode reference values and types.
-#define encode_pointer_and_type(pointer, type) (~((uintptr_t)(pointer) | type))
-#define decode_pointer(encoded) ((id)((~(encoded)) & (~OBJC_XREF_TYPE_MASK)))
-#define decode_type(encoded) ((~(encoded)) & OBJC_XREF_TYPE_MASK)
-#define encode_index_and_type(index, type) (~((index<<3) | type))
-#define decode_index(encoded) ((~encoded)>>3)
-
-#if SUPPORT_GC
-
-typedef struct {
-    objc_xref_type_t    _type;         // type of list.
-    dispatch_queue_t    _synchronizer; // a reader/write lock
-    __strong void       **_buffer;     // a retained all pointers block
-    size_t              _size;         // number of pointers that fit in _list (buffer size)
-    size_t              _count;        // count of pointers in _list (in use count)
-    size_t              _search;       // lowest index in list which *might* be unused
-} external_ref_list;
-
-static external_ref_list _xref_lists[2];
-
-#define is_strong(list) (list->_type == OBJC_XREF_STRONG)
-#define is_weak(list) (list->_type == OBJC_XREF_WEAK)
-
-inline static size_t _index_for_type(objc_xref_type_t ref_type) {
-    assert(ref_type == OBJC_XREF_STRONG || ref_type == OBJC_XREF_WEAK);
-    return (ref_type - 1);
-}
-
-static void _initialize_gc() {
-    static dispatch_once_t init_guard;
-    dispatch_once(&init_guard, ^{
-        external_ref_list *_strong_list = &_xref_lists[_index_for_type(OBJC_XREF_STRONG)];
-        _strong_list->_type = OBJC_XREF_STRONG;
-        _strong_list->_synchronizer = dispatch_queue_create("OBJC_XREF_STRONG synchronizer", DISPATCH_QUEUE_CONCURRENT);
-        
-        external_ref_list *_weak_list = &_xref_lists[_index_for_type(OBJC_XREF_WEAK)];
-        _weak_list->_type = OBJC_XREF_WEAK;
-        _weak_list->_synchronizer = dispatch_queue_create("OBJC_XREF_WEAK synchronizer", DISPATCH_QUEUE_CONCURRENT);
-    });
-}
-
-#define EMPTY_SLOT ((void*)0x1)
-
-// grow the buffer by one page
-static bool _grow_list(external_ref_list *list) {
-    auto_memory_type_t memory_type = (is_strong(list) ? AUTO_MEMORY_ALL_POINTERS : AUTO_MEMORY_ALL_WEAK_POINTERS);
-    size_t new_size = list->_size + PAGE_MAX_SIZE / sizeof(void *);
-    // auto_realloc() has been enhanced to handle strong and weak memory.
-    void **new_list = (void **)(list->_buffer ? malloc_zone_realloc(gc_zone, list->_buffer, new_size * sizeof(void *)) : auto_zone_allocate_object(gc_zone, new_size * sizeof(void *), memory_type, false, false));
-    if (!new_list) _objc_fatal("unable to allocate, size = %ld\n", new_size);
-    
-    list->_search = list->_size;
-    // Fill the newly allocated space with empty slot tokens.
-    for (size_t index = list->_size; index < new_size; ++index)
-        new_list[index] = EMPTY_SLOT;
-    list->_size = new_size;
-    auto_zone_root_write_barrier(gc_zone, &list->_buffer, new_list);
-    return true;
-}
-
-
-// find an unused slot in the list, growing the list if necessary
-static size_t _find_unused_index(external_ref_list *list) {
-    size_t index;
-    if (list->_size == list->_count) {
-        _grow_list(list);
-    }
-    // find the lowest unused index in _list
-    index = list->_search;
-    while (list->_buffer[index] != EMPTY_SLOT)
-        index++;
-    // mark the slot as no longer empty, good form for weak slots.
-    list->_buffer[index] = NULL;
-    return index;
-}
-
-
-// return the strong or weak list
-inline static external_ref_list *_list_for_type(objc_xref_type_t ref_type) {
-    return &_xref_lists[_index_for_type(ref_type)];
-}
-
-
-// create a GC external reference
-objc_xref_t _object_addExternalReference_gc(id obj, objc_xref_type_t ref_type) {
-    _initialize_gc();
-    __block size_t index;
-    objc_xref_t xref;
-    
-    if (auto_zone_is_valid_pointer(gc_zone, obj)) {
-        external_ref_list *list = _list_for_type(ref_type);
-        
-        // writer lock
-        dispatch_barrier_sync(list->_synchronizer, (dispatch_block_t)^{
-            index = _find_unused_index(list);
-            if (ref_type == OBJC_XREF_STRONG) {
-                auto_zone_set_write_barrier(gc_zone, &list->_buffer[index], obj);
-            } else {
-                auto_assign_weak_reference(gc_zone, obj, (const void **)&list->_buffer[index], NULL);
-            }
-            list->_count++;
-        });
-        xref = encode_index_and_type(index, ref_type);
-    } else {
-        // data segment object
-        xref = encode_pointer_and_type(obj, OBJC_XREF_TYPE_STATIC);
-    }
-    return xref;
-}
-
-
-id _object_readExternalReference_gc(objc_xref_t ref) {
-    _initialize_gc();
-    __block id result;
-    objc_xref_type_t ref_type = decode_type(ref);
-    if (ref_type != OBJC_XREF_TYPE_STATIC) {
-        size_t index = decode_index(ref);
-        external_ref_list *list = _list_for_type(ref_type);
-        
-        dispatch_sync(list->_synchronizer, ^{
-            if (index >= list->_size) {
-                _objc_fatal("attempted to resolve invalid external reference\n");
-            }
-            if (ref_type == OBJC_XREF_STRONG)
-                result = (id)list->_buffer[index];
-            else
-                result = (id)auto_read_weak_reference(gc_zone, &list->_buffer[index]);
-            if (result == (id)EMPTY_SLOT)
-                _objc_fatal("attempted to resolve unallocated external reference\n");
-        });
-    } else {
-        // data segment object
-        result = decode_pointer(ref);
-    }
-    return result;
-}
-
-
-void _object_removeExternalReference_gc(objc_xref_t ref) {
-    _initialize_gc();
-    objc_xref_type_t ref_type = decode_type(ref);
-    if (ref_type != OBJC_XREF_TYPE_STATIC) {
-        size_t index = decode_index(ref);
-        external_ref_list *list = _list_for_type(ref_type);
-        
-        dispatch_barrier_sync(list->_synchronizer, ^{
-            if (index >= list->_size) {
-                _objc_fatal("attempted to destroy invalid external reference\n");
-            }
-            id old_value;
-            if (ref_type == OBJC_XREF_STRONG) {
-                old_value = (id)list->_buffer[index];
-            } else {
-                old_value = (id)auto_read_weak_reference(gc_zone, &list->_buffer[index]);
-                auto_assign_weak_reference(gc_zone, NULL, (const void **)&list->_buffer[index], NULL);
-            }
-            list->_buffer[index] = EMPTY_SLOT;
-            if (old_value == (id)EMPTY_SLOT)
-                _objc_fatal("attempted to destroy unallocated external reference\n");
-            list->_count--;
-            if (list->_search > index)
-                list->_search = index;
-        });
-    } else {
-        // nothing for data segment object
-    }
-}
-
-
-// SUPPORT_GC
-#endif
-
-
-objc_xref_t _object_addExternalReference_non_gc(id obj, objc_xref_type_t ref_type) {
-    switch (ref_type) {
-        case OBJC_XREF_STRONG:
-            ((id(*)(id, SEL))objc_msgSend)(obj, SEL_retain);
-            break;
-        case OBJC_XREF_WEAK:
-            break;
-        default:
-            _objc_fatal("invalid external reference type: %d", (int)ref_type);
-            break;
-    }
-    return encode_pointer_and_type(obj, ref_type);
-}
-
-
-id _object_readExternalReference_non_gc(objc_xref_t ref) {
-    id obj = decode_pointer(ref);
-    return obj;
-}
-
-
-void _object_removeExternalReference_non_gc(objc_xref_t ref) {
-    id obj = decode_pointer(ref);
-    objc_xref_type_t ref_type = decode_type(ref);
-    switch (ref_type) {
-        case OBJC_XREF_STRONG:
-            ((void(*)(id, SEL))objc_msgSend)(obj, SEL_release);
-            break;
-        case OBJC_XREF_WEAK:
-            break;
-        default:
-            _objc_fatal("invalid external reference type: %d", (int)ref_type);
-            break;
-    }
-}
-
-
-uintptr_t _object_getExternalHash(id object) {
-    return (uintptr_t)object;
-}
-
-
-#if SUPPORT_GC
-
-// These functions are resolver functions in objc-auto.mm.
-
-#else
-
-objc_xref_t 
-_object_addExternalReference(id obj, objc_xref_t type) 
-{
-    return _object_addExternalReference_non_gc(obj, type);
-}
-
-
-id 
-_object_readExternalReference(objc_xref_t ref) 
-{
-    return _object_readExternalReference_non_gc(ref);
-}
-
-
-void 
-_object_removeExternalReference(objc_xref_t ref) 
-{
-    _object_removeExternalReference_non_gc(ref);
-}
-
-#endif