Beispiel #1
0
// CObject local new operator to mark allocation in heap
void* CObject::operator new(size_t size)
{
    _ASSERT(size >= sizeof(CObject));
    size = max(size, sizeof(CObject) + sizeof(TCounter));

#ifdef USE_SINGLE_ALLOC
    void* ptr = single_alloc(size);
    sx_FillNewMemory(ptr, size);
    //static_cast<CObject*>(ptr)->m_Counter.Set(0);
    return ptr;
#else
    void* ptr = ::operator new(size);

#if USE_TLS_PTR
    // just remember pointer in TLS
    sx_PushLastNewPtr(ptr, eMagicCounterNew);
#else// !USE_TLS_PTR
#if USE_HEAPOBJ_LIST
    {{
        CFastMutexGuard LOCK(sm_ObjectMutex);
        s_heap_obj->push_front(ptr);
    }}
#else// !USE_HEAPOBJ_LIST
    sx_FillNewMemory(ptr, size);
#  if USE_COMPLEX_MASK
    GetSecondCounter(static_cast<CObject*>(ptr))->Set(eMagicCounterNew);
#  endif// USE_COMPLEX_MASK
#endif// USE_HEAPOBJ_LIST
    static_cast<CObject*>(ptr)->m_Counter.Set(eMagicCounterNew);
#endif// USE_TLS_PTR
    return ptr;
#endif
}
Beispiel #2
0
// CObject new operator from memory pool
void* CObject::operator new(size_t size, CObjectMemoryPool* memory_pool)
{
    _ASSERT(size >= sizeof(CObject));
    if ( !memory_pool ) {
        return operator new(size);
    }
    void* ptr = memory_pool->Allocate(size);
    if ( !ptr ) {
        return operator new(size);
    }
#if USE_TLS_PTR
    // just remember pointer in TLS
    sx_PushLastNewPtr(ptr, eMagicCounterPoolNew);
#else// !USE_TLS_PTR
#  if USE_COMPLEX_MASK
    GetSecondCounter(static_cast<CObject*>(ptr))->Set(eMagicCounterPoolNew);
#  endif// USE_COMPLEX_MASK
    static_cast<CObject*>(ptr)->m_Counter.Set(eMagicCounterPoolNew);
#endif// USE_TLS_PTR
    return ptr;
}
Beispiel #3
0
void CTestTlsObjectApp::RunTest(void)
{
    const size_t OBJECT_SIZE = sizeof(CObjectWithNew);
    for ( int t = 0; t < 1; ++t ) {
        // prealloc
        {
            size_t size = (OBJECT_SIZE+16)*COUNT;
            void* p = ::operator new(size);
            memset(p, 1, size);
            ::operator delete(p);
        }
        {
            const size_t COUNT2 = COUNT*2;
            void** p = new void*[COUNT2];
            for ( size_t i = 0; i < COUNT2; ++i ) {
                add_alloc(1);
                add_step();
                p[i] = ::operator new(OBJECT_SIZE);
            }
            for ( size_t i = 0; i < COUNT2; ++i ) {
                add_alloc(-1);
                add_step();
                ::operator delete(p[i]);
            }
            delete[] p;
        }
        {
            const size_t COUNT2 = COUNT*2;
            int** p = new int*[COUNT2];
            for ( size_t i = 0; i < COUNT2; ++i ) {
                add_alloc(1);
                add_step();
                p[i] = new int(int(i));
            }
            for ( size_t i = 0; i < COUNT2; ++i ) {
                add_alloc(-1);
                add_step();
                delete p[i];
            }
            delete[] p;
        }
    }
    //return;
    CStopWatch sw;
    check_cnts();
    for ( int t = 0; t < 1; ++t ) {
        void** ptr = new void*[COUNT];
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_alloc(1);
            add_step();
            ptr[i] = ::operator new(OBJECT_SIZE);
        }
        double t1 = sw.Elapsed();
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_alloc(-1);
            add_step();
            ::operator delete(ptr[i]);
        }
        double t2 = sw.Elapsed();
        message("plain malloc", "create", t1, "delete", t2, COUNT);
        delete[] ptr;
    }
    check_cnts();
    {
        sw.Start();
        int* ptr = new int;
        sx_PushLastNewPtr(ptr, 2);
        double t1 = sw.Elapsed();
        sw.Start();
        _VERIFY(sx_PopLastNewPtr(ptr));
        delete ptr;
        double t2 = sw.Elapsed();
        message("tls", "set", t1, "get", t2, COUNT);
    }
    check_cnts();
    {
        CObjectWithNew** ptr = new CObjectWithNew*[COUNT];
        for ( size_t i = 0; i < COUNT; ++i ) {
            ptr[i] = 0;
        }
        sw.Start();
        s_CurrentStep = "new CObjectWithNew";
        s_CurrentInHeap = true;
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            ptr[i] = new CObjectWithNew;
        }
        s_CurrentInHeap = false;
        double t1 = sw.Elapsed();
        check_cnts(COUNT);
        for ( size_t i = 0; i < COUNT; ++i ) {
            _ASSERT(ptr[i]->IsInHeap());
        }
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            CObjectWithNew::Delete(ptr[i]);
        }
        double t2 = sw.Elapsed();
        message("new CObjectWithNew", "create", t1, "delete", t2, COUNT);
        delete[] ptr;
    }
    check_cnts();
    {
        CObjectWithTLS** ptr = new CObjectWithTLS*[COUNT];
        sw.Start();
        s_CurrentStep = "new CObjectWithTLS";
        s_CurrentInHeap = true;
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            try {
                switch ( rand()%3 ) {
                case 0: ptr[i] = new CObjectWithTLS; break;
                case 1: ptr[i] = new CObjectWithTLS2; break;
                case 2: ptr[i] = new CObjectWithTLS3; break;
                }
            }
            catch ( exception& ) {
                ptr[i] = 0;
            }
            _ASSERT(!sx_HaveLastNewPtr());
            _ASSERT(!ptr[i] || ptr[i]->IsInHeap());
        }
        s_CurrentInHeap = false;
        double t1 = sw.Elapsed();
        check_cnts(COUNT);
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            CObjectWithTLS::Delete(ptr[i]);
        }
        double t2 = sw.Elapsed();
        message("new CObjectWithTLS", "create", t1, "delete", t2, COUNT);
        delete[] ptr;
    }
    check_cnts();
    {
        CRef<CObjectWithRef>* ptr = new CRef<CObjectWithRef>[COUNT];
        sw.Start();
        s_CurrentStep = "new CObjectWithRef";
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            try {
                switch ( rand()%2 ) {
                case 0: ptr[i] = new CObjectWithRef; break;
                case 1: ptr[i] = new CObjectWithRef2; break;
                }
            }
            catch ( exception& ) {
                ptr[i] = 0;
            }
            _ASSERT(!sx_HaveLastNewPtr());
            _ASSERT(!ptr[i] || ptr[i]->CanBeDeleted());
        }
        double t1 = sw.Elapsed();
        check_cnts(COUNT);
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            ptr[i].Reset();
        }
        double t2 = sw.Elapsed();
        message("new CObjectWithRef", "create", t1, "delete", t2, COUNT);
        delete[] ptr;
    }
    check_cnts();
    {
        CObjectWithNew** ptr = new CObjectWithNew*[COUNT];
        for ( size_t i = 0; i < COUNT; ++i ) {
            ptr[i] = 0;
        }
        sw.Start();
        s_CurrentStep = "new CObjectWithNew()";
        s_CurrentInHeap = true;
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            ptr[i] = new CObjectWithNew();
        }
        s_CurrentInHeap = false;
        double t1 = sw.Elapsed();
        check_cnts(COUNT);
        for ( size_t i = 0; i < COUNT; ++i ) {
            _ASSERT(ptr[i]->IsInHeap());
        }
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            CObjectWithNew::Delete(ptr[i]);
        }
        double t2 = sw.Elapsed();
        message("new CObjectWithNew()", "create", t1, "delete", t2, COUNT);
        delete[] ptr;
    }
    check_cnts();
    {
        CObjectWithTLS** ptr = new CObjectWithTLS*[COUNT];
        sw.Start();
        s_CurrentStep = "new CObjectWithTLS()";
        s_CurrentInHeap = true;
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            try {
                switch ( rand()%4 ) {
                case 0: ptr[i] = new CObjectWithTLS(); break;
                case 1: ptr[i] = new CObjectWithTLS2(); break;
                case 2: ptr[i] = new CObjectWithTLS3(); break;
                case 3: ptr[i] = new CObjectWithTLS3(RecursiveNewTLS(rand()%4)); break;
                }
            }
            catch ( exception& ) {
                ptr[i] = 0;
            }
            _ASSERT(!sx_HaveLastNewPtr());
            _ASSERT(!ptr[i] || ptr[i]->IsInHeap());
        }
        s_CurrentInHeap = false;
        double t1 = sw.Elapsed();
        check_cnts(COUNT);
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            CObjectWithTLS::Delete(ptr[i]);
        }
        double t2 = sw.Elapsed();
        message("new CObjectWithTLS()", "create", t1, "delete", t2, COUNT);
        delete[] ptr;
    }
    check_cnts();
    {
        CRef<CObjectWithRef>* ptr = new CRef<CObjectWithRef>[COUNT];
        sw.Start();
        s_CurrentStep = "new CObjectWithRef()";
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            try {
                size_t j = rand()%COUNT;
                switch ( rand()%4 ) {
                case 0: ptr[j] = new CObjectWithRef(); break;
                case 1: ptr[j] = new CObjectWithRef(RecursiveNewRef(rand()%4)); break;
                case 2: ptr[j] = new CObjectWithRef2(); break;
                case 3: ptr[j] = new CObjectWithRef2(RecursiveNewRef(rand()%4)); break;
                }
            }
            catch ( exception& ) {
                ptr[i] = 0;
            }
            _ASSERT(!sx_HaveLastNewPtr());
            _ASSERT(!ptr[i] || ptr[i]->CanBeDeleted());
        }
        double t1 = sw.Elapsed();
        check_cnts(COUNT);
        sw.Start();
        for ( size_t i = 0; i < COUNT; ++i ) {
            add_step();
            ptr[i] = 0;
        }
        double t2 = sw.Elapsed();
        message("new CObjectWithRef()", "create", t1, "delete", t2, COUNT);
        delete[] ptr;
    }
    check_cnts();
    {
        sw.Start();
        s_CurrentStep = "CObjectWithNew[]";
        CArray<CObjectWithNew, COUNT>* arr =
            new CArray<CObjectWithNew, COUNT>;
        double t1 = sw.Elapsed();
        check_cnts(COUNT, COUNT);
        for ( size_t i = 0; i < COUNT; ++i ) {
            _ASSERT(!arr->m_Array[i].IsInHeap());
        }
        sw.Start();
        delete arr;
        double t2 = sw.Elapsed();
        message("static CObjectWithNew", "create", t1, "delete", t2, COUNT);
    }
    check_cnts();
    {
        sw.Start();
        s_CurrentStep = "CObjectWithTLS[]";
        CArray<CObjectWithTLS, COUNT, false>* arr =
            new CArray<CObjectWithTLS, COUNT, false>;
        double t1 = sw.Elapsed();
        check_cnts(COUNT, COUNT);
        for ( size_t i = 0; i < COUNT; ++i ) {
            _ASSERT(!arr->m_Array[i].IsInHeap());
        }
        sw.Start();
        delete arr;
        double t2 = sw.Elapsed();
        message("static CObjectWithTLS", "create", t1, "delete", t2, COUNT);
    }
    check_cnts();
    {
        sw.Start();
        s_CurrentStep = "CObjectWithRef[]";
        CArray<CObjectWithRef, COUNT, false>* arr =
            new CArray<CObjectWithRef, COUNT, false>;
        double t1 = sw.Elapsed();
        check_cnts(COUNT, COUNT);
        for ( size_t i = 0; i < COUNT; ++i ) {
            _ASSERT(!arr->m_Array[i].CanBeDeleted());
        }
        sw.Start();
        delete arr;
        double t2 = sw.Elapsed();
        message("static CObjectWithRef", "create", t1, "delete", t2, COUNT);
    }
    check_cnts();
}
Beispiel #4
0
 static void RegisterNew(CObjectWithTLS* ptr) {
     sx_PushLastNewPtr(ptr, 2);
 }