Changeset 15334


Ignore:
Timestamp:
Jun 11, 2014, 9:50:38 PM (9 years ago)
Author:
philip
Message:

Fix TestHeaderless failure on GCC 4.9.

Once 'delete' is called on an object, that object no longer exists, and accessing its member variables is undefined behaviour. GCC 4.9's optimiser recognises this, and eliminates any writes to member variables inside the destructor, since it knows they cannot legally be read later.

BoundaryTagManager relied on ~FreedBlock resetting its memory to 0, so this optimisation broke it. Replace the placement new/delete with plain non-magic Setup/Reset functions, to avoid the optimisation.

Fixes #2481.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • ps/trunk/source/lib/allocators/headerless.cpp

    r10799 r15334  
    5555    }
    5656
    57     FreedBlock(uintptr_t id, size_t size)
    58         :  m_magic(s_magic), m_size(size), m_id(id)
    59     {
    60     }
    61 
    62     ~FreedBlock()
     57    void Setup(uintptr_t id, size_t size)
     58    {
     59        m_magic = s_magic;
     60        m_size = size;
     61        m_id = id;
     62    }
     63
     64    void Reset()
    6365    {
    6466        // clear all fields to prevent accidental reuse
     
    411413    FreedBlock* WriteTags(u8* p, size_t size)
    412414    {
    413         FreedBlock* freedBlock = new(p) FreedBlock(s_headerId, size);
    414         (void)new(Footer(freedBlock)) FreedBlock(s_footerId, size);
     415        FreedBlock* freedBlock = (FreedBlock*)p;
     416        freedBlock->Setup(s_headerId, size);
     417        Footer(freedBlock)->Setup(s_footerId, size);
    415418
    416419        m_freeBlocks++;
     
    431434
    432435        FreedBlock* footer = Footer(freedBlock);
    433         freedBlock->~FreedBlock();
    434         footer->~FreedBlock();
     436        freedBlock->Reset();
     437        footer->Reset();
    435438    }
    436439
Note: See TracChangeset for help on using the changeset viewer.