Пример #1
0
void uReleaseStruct(uType* type, void* address)
{
#if DEBUG_ARC >= 4
    Xli::Error->WriteFormat("release %s [struct] (%d bytes)%s\n", type->FullName, type->ValueSize, uGetCaller().Ptr());
#endif
    for (size_t i = 0; i < type->Refs.StrongCount; i++)
    {
        uObject*& ptr = *(uObject**)((uint8_t*)address + type->Refs.Strong[i].Value);
        uRelease(ptr);
        ptr = NULL;
    }

    for (size_t i = 0; i < type->Refs.WeakCount; i++)
        uStoreWeak((uWeakObject**)((uint8_t*)address + type->Refs.Weak[i].Value), NULL);
}
Пример #2
0
uAutoReleasePool::~uAutoReleasePool()
{
    uThreadData* thread = uGetThreadData();
    uAutoReleaseFrame* frame = thread->AutoReleasePtr;
    U_ASSERT(thread->AutoReleasePtr >= thread->AutoReleaseStack);

    for (size_t i = frame->StartIndex; i < thread->AutoReleaseList.Length(); i++)
    {
        uObject* object = thread->AutoReleaseList[i];
#ifdef DEBUG_ARC
        frame->AllocCount++;
        frame->AllocSize += object->__size;
#endif
        uRelease(object);
    }

#if DEBUG_ARC >= 1
    Xli::Error->WriteFormat("--- Alloc'd %d objects (%d bytes), Free'd %d objects (%d bytes) ---\n", frame->AllocCount, frame->AllocSize, frame->FreeCount, frame->FreeSize);
#endif
    thread->AutoReleaseList.Resize(frame->StartIndex);
    thread->AutoReleasePtr--;
}
Пример #3
0
void uRelease(uObject* object)
{
    if (object)
    {
        if (Xli::AtomicDecrement(&object->__retains) == 0)
        {
            if (!uTryClearWeak(object))
                return;
#ifdef DEBUG_ARC
            uThreadData* thread = uGetThreadData();

            if (thread->AutoReleasePtr >= thread->AutoReleaseStack)
            {
                uAutoReleaseFrame* frame = thread->AutoReleasePtr;
                if (frame->AllocCount > 0)
                {
                    frame->FreeCount++;
                    frame->FreeSize += object->__size;
                }
            }
#endif
            uType* type = object->__type;

            switch (type->Type)
            {
            case uTypeTypeClass:
            {
                uType* baseType = type;
                do
                {
                    if (baseType->fp_Finalize)
                    {
                        try { (*baseType->fp_Finalize)(object); }
                        catch (...) { Xli::Error->WriteFormat("Runtime Error: Unhandled exception in finalizer for %s\n", baseType->FullName); }
                    }
                } while ((baseType = baseType->Base));
                uReleaseStruct(type, object);
                break;
            }

            case uTypeTypeStruct:
                // This must be a boxed value, so append size of object header
                uReleaseStruct(type, (uint8_t*)object + sizeof(uObject));
                break;

            case uTypeTypeDelegate:
                uRelease(((uDelegate*)object)->_object);
                uRelease(((uDelegate*)object)->_prev);
                break;

            case uTypeTypeArray:
            {
                uArray* array = (uArray*)object;
                uArrayType* arrayType = (uArrayType*)type;
                uType* elmType = arrayType->ElementType;

                switch (elmType->Type)
                {
                case uTypeTypeClass:
                case uTypeTypeInterface:
                case uTypeTypeDelegate:
                case uTypeTypeArray:
                    for (uObject** objAddr = (uObject**)array->_ptr;
                         array->_length--;
                         objAddr++)
                        uRelease(*objAddr);
                    break;

                case uTypeTypeStruct:
                    for (uint8_t* address = (uint8_t*)array->_ptr;
                         array->_length--;
                         address += elmType->ValueSize)
                        uReleaseStruct(elmType, address);
                    break;

                default:
                    break;
                }
                break;
            }
            default:
                break;
            }
#if DEBUG_ARC >= 2
            Xli::Error->WriteFormat("free %s #%d (%d bytes)%s\n", object->__type->FullName, object->__id, object->__size, uGetCaller().Ptr());
#endif
#ifdef DEBUG_DUMPS
            uEnterCritical();
            _HeapObjects->Remove(object);
            uExitCritical();
#endif
            U_ASSERT(object->__type != ::g::Uno::Type_typeof());
            U_FREE_OBJECT(object);
            return;
        }

        if (object->__retains < 0)
        {
#if DEBUG_ARC >= 4
            Xli::Error->WriteFormat("*** BAD OBJECT: %s #%d (%d retains) ***%s\n", object->__type->FullName, object->__id, object->__retains, uGetCaller().Ptr());
#else
            Xli::Error->WriteFormat("*** BAD OBJECT: 0x%llx ***\n", (uintptr_t)object);
#endif
            U_FATAL();
        }
        else
        {
#if DEBUG_ARC >= 3
            Xli::Error->WriteFormat("release %s #%d (%d bytes, %d retains)%s\n", object->__type->FullName, object->__id, object->__size, object->__retains, uGetCaller().Ptr());
#endif
        }
    }
}
//~
void __JavaUnoObject_Finalizer(JNIEnv *env , jclass clazz, jlong ptr)
{
    uAutoReleasePool pool;
    uRelease((::g::Uno::Compiler::ExportTargetInterop::Foreign::Android::JavaUnoObject*)ptr);
}