src/hbtools/hbbincssmaker/hbcssconverterutils.cpp
changeset 21 4633027730f5
parent 7 923ff622b8b9
equal deleted inserted replaced
7:923ff622b8b9 21:4633027730f5
    35 // Global list that stores pointers to the member variables where shared container instances
    35 // Global list that stores pointers to the member variables where shared container instances
    36 // store offsets returned my memory allocator.
    36 // store offsets returned my memory allocator.
    37 // CSS converter utilizes it to automatically adjust the offsets if allocated cells are moved.
    37 // CSS converter utilizes it to automatically adjust the offsets if allocated cells are moved.
    38 
    38 
    39 // Map is used only to get faster lookups, item's value is obsolete
    39 // Map is used only to get faster lookups, item's value is obsolete
    40 static QMap<int *, int> registered;
    40 static QMap<qptrdiff *, int> registered;
    41 
    41 
    42 
    42 
    43 // Shared chunk allocation information for css data
    43 // Shared chunk allocation information for css data
    44 static int totalAllocated = 0;
    44 static int totalAllocated = 0;
    45 // Using map instead of hash to guarantee that the items are in order
    45 // Using map instead of hash to guarantee that the items are in order
    46 // so the cell with offset 0 which is the HbCss::StyleSheet structure
    46 // so the cell with offset 0 which is the HbCss::StyleSheet structure
    47 // is always first in the cell list, so its offset does not get changed
    47 // is always first in the cell list, so its offset does not get changed
    48 // when the chunk is defragmented.
    48 // when the chunk is defragmented.
    49 static QMap<int, int> cells;
    49 static QMap<qptrdiff, int> cells;
    50 
    50 
    51 
    51 
    52 void HbCssConverterUtils::registerOffsetHolder(int *offset)
    52 void HbCssConverterUtils::registerOffsetHolder(qptrdiff *offset)
    53 {
    53 {
    54     registered.insert(offset, 1);
    54     registered.insert(offset, 1);
    55 }
    55 }
    56 
    56 
    57 void HbCssConverterUtils::unregisterOffsetHolder(int *offset)
    57 void HbCssConverterUtils::unregisterOffsetHolder(qptrdiff *offset)
    58 {
    58 {
    59     registered.remove(offset);
    59     registered.remove(offset);
    60 }
    60 }
    61 
    61 
    62 QMultiHash<int, int *> HbCssConverterUtils::registeredOffsetHolders()
    62 QMultiHash<int, qptrdiff *> HbCssConverterUtils::registeredOffsetHolders()
    63 {
    63 {
    64     QMultiHash<int, int *> holders;
    64     QMultiHash<int, qptrdiff *> holders;
    65     holders.reserve(registered.size());
    65     holders.reserve(registered.size());
    66     QMap<int *, int>::const_iterator end = registered.constEnd();
    66     QMap<qptrdiff *, int>::const_iterator end = registered.constEnd();
    67     for (QMap<int *, int>::const_iterator i = registered.constBegin(); i != end; ++i) {
    67     for (QMap<qptrdiff *, int>::const_iterator i = registered.constBegin(); i != end; ++i) {
    68         int *holder = i.key();
    68         qptrdiff *holder = i.key();
    69         holders.insertMulti(*holder, holder);
    69         holders.insertMulti(*holder, holder);
    70     }
    70     }
    71     return holders;
    71     return holders;
    72 }
    72 }
    73 
    73 
    75 {
    75 {
    76     registered.clear();
    76     registered.clear();
    77 }
    77 }
    78 
    78 
    79 
    79 
    80 void HbCssConverterUtils::cellAllocated(int offset, int size)
    80 void HbCssConverterUtils::cellAllocated(qptrdiff offset, int size)
    81 {
    81 {
    82     cells.insert(offset, ALIGN(size));
    82     cells.insert(offset, ALIGN(size));
    83     totalAllocated += ALIGN(size);
    83     totalAllocated += ALIGN(size);
    84 }
    84 }
    85 
    85 
    86 void HbCssConverterUtils::cellFreed(int offset)
    86 void HbCssConverterUtils::cellFreed(qptrdiff offset)
    87 {
    87 {
    88     int size = cells.value(offset, 0);
    88     int size = cells.value(offset, 0);
    89     totalAllocated -= size;
    89     totalAllocated -= size;
    90     cells.remove(offset);
    90     cells.remove(offset);
    91 
    91 
    93         // Make sure there are no registered offset holders in the freed cell any more
    93         // Make sure there are no registered offset holders in the freed cell any more
    94         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
    94         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
    95         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
    95         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
    96         const char *chunkBase = static_cast<const char *>(shared->base());
    96         const char *chunkBase = static_cast<const char *>(shared->base());
    97         const char *freedEnd = chunkBase + offset + size;
    97         const char *freedEnd = chunkBase + offset + size;
    98         const int *freedStart = reinterpret_cast<const int *>(chunkBase + offset);
    98         const qptrdiff *freedStart = reinterpret_cast<const qptrdiff *>(chunkBase + offset);
    99 
    99 
   100         QMap<int *, int>::iterator freedHolders =
   100         QMap<qptrdiff *, int>::iterator freedHolders =
   101                 registered.lowerBound(const_cast<int *>(freedStart));
   101                 registered.lowerBound(const_cast<qptrdiff *>(freedStart));
   102         while(freedHolders != registered.end()
   102         while(freedHolders != registered.end()
   103               && reinterpret_cast<char*>(freedHolders.key()) <  freedEnd) {
   103               && reinterpret_cast<char*>(freedHolders.key()) <  freedEnd) {
   104             freedHolders = registered.erase(freedHolders);
   104             freedHolders = registered.erase(freedHolders);
   105         }
   105         }
   106     }
   106     }
   107 }
   107 }
   108 
   108 
   109 void HbCssConverterUtils::cellMoved(int offset, int newOffset)
   109 void HbCssConverterUtils::cellMoved(qptrdiff offset, qptrdiff newOffset)
   110 {
   110 {
   111     int size = cells.value(offset, 0);
   111     int size = cells.value(offset, 0);
   112 
   112 
   113     if (size > 0) {
   113     if (size > 0) {
   114         // Check if there were registered offset holders in the old cell
   114         // Check if there were registered offset holders in the old cell
   115         // and register corresponding ones in the reallocated cell.
   115         // and register corresponding ones in the reallocated cell.
   116         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
   116         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
   117         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
   117         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
   118         const char *chunkBase = static_cast<const char *>(shared->base());
   118         const char *chunkBase = static_cast<const char *>(shared->base());
   119         const char *freedEnd = chunkBase + offset + size;
   119         const char *freedEnd = chunkBase + offset + size;
   120         const int *freedStart = reinterpret_cast<const int *>(chunkBase + offset);
   120         const qptrdiff *freedStart = reinterpret_cast<const qptrdiff *>(chunkBase + offset);
   121 
   121 
   122         QMap<int *, int>::iterator freedHolders =
   122         QMap<qptrdiff *, int>::iterator freedHolders =
   123                 registered.lowerBound(const_cast<int *>(freedStart));
   123                 registered.lowerBound(const_cast<qptrdiff *>(freedStart));
   124         QList<int *> newHolders;
   124         QList<qptrdiff *> newHolders;
   125         while(freedHolders != registered.end()
   125         while(freedHolders != registered.end()
   126               && reinterpret_cast<char*>(freedHolders.key()) <  freedEnd) {
   126               && reinterpret_cast<char*>(freedHolders.key()) <  freedEnd) {
   127             char *holderC = reinterpret_cast<char*>(freedHolders.key());
   127             char *holderC = reinterpret_cast<char*>(freedHolders.key());
   128             newHolders.append(reinterpret_cast<int*>(holderC + newOffset - offset));
   128             newHolders.append(reinterpret_cast<qptrdiff*>(holderC + newOffset - offset));
   129             freedHolders = registered.erase(freedHolders);
   129             freedHolders = registered.erase(freedHolders);
   130         }
   130         }
   131         for (int i = 0; i < newHolders.size(); ++i) {
   131         for (int i = 0; i < newHolders.size(); ++i) {
   132             registerOffsetHolder(newHolders.at(i));
   132             registerOffsetHolder(newHolders.at(i));
   133         }
   133         }
   146     strMap.clear();
   146     strMap.clear();
   147 
   147 
   148     // Register shared cache pointer in chunk header
   148     // Register shared cache pointer in chunk header
   149     //as shared cache may also be moved in defragmentation
   149     //as shared cache may also be moved in defragmentation
   150     HbSharedChunkHeader *chunkHeader = static_cast<HbSharedChunkHeader*>(shared->base());
   150     HbSharedChunkHeader *chunkHeader = static_cast<HbSharedChunkHeader*>(shared->base());
   151     registerOffsetHolder(reinterpret_cast<int *>(&chunkHeader->sharedCacheOffset));
   151     registerOffsetHolder(reinterpret_cast<qptrdiff *>(&chunkHeader->sharedCacheOffset));
   152 
   152 
   153     QMultiHash<int, int *> offsetHolders = registeredOffsetHolders();
   153     QMultiHash<int, qptrdiff *> offsetHolders = registeredOffsetHolders();
   154 
   154 
   155     // Create new buffer where the current chunk contents are defragmented
   155     // Create new buffer where the current chunk contents are defragmented
   156     char *buffer = static_cast<char*>(::malloc(shared->size()));
   156     char *buffer = static_cast<char*>(::malloc(shared->size()));
   157     int newCurrentOffset = 0;
   157     qptrdiff newCurrentOffset = 0;
   158 
   158 
   159     // Create new cell order and update offset holders
   159     // Create new cell order and update offset holders
   160     QMap<int,int>::const_iterator end = cells.constEnd();
   160     QMap<qptrdiff,int>::const_iterator end = cells.constEnd();
   161 
   161 
   162     for (QMap<int,int>::const_iterator i = cells.constBegin(); i != end; ++i) {
   162     for (QMap<qptrdiff,int>::const_iterator i = cells.constBegin(); i != end; ++i) {
   163         // Get the old cell
   163         // Get the old cell
   164         int offset = i.key();
   164         qptrdiff offset = i.key();
   165         int size = i.value();
   165         int size = i.value();
   166         
   166         
   167         // Update registered offset holders
   167         // Update registered offset holders
   168         QList<int *> values = offsetHolders.values(offset);
   168         QList<qptrdiff *> values = offsetHolders.values(offset);
   169         offsetHolders.remove(offset);
   169         offsetHolders.remove(offset);
   170         int newOffset = newCurrentOffset + sizeof(HbSharedChunkHeader);
   170         qptrdiff newOffset = newCurrentOffset + sizeof(HbSharedChunkHeader);
   171         for (int j = 0; j < values.size(); ++j) {
   171         for (int j = 0; j < values.size(); ++j) {
   172             int *holder = values[j];
   172             qptrdiff *holder = values[j];
   173             *holder = newOffset;
   173             *holder = newOffset;
   174             offsetHolders.insertMulti(*holder, holder);
   174             offsetHolders.insertMulti(*holder, holder);
   175         }
   175         }
   176         newCurrentOffset += size;
   176         newCurrentOffset += size;
   177     }
   177     }
   178 
   178 
   179     newCurrentOffset = 0;
   179     newCurrentOffset = 0;
   180     // Move allocated cells to a linear buffer
   180     // Move allocated cells to a linear buffer
   181     for (QMap<int, int>::const_iterator i = cells.constBegin(); i != end; ++i) {
   181     for (QMap<qptrdiff, int>::const_iterator i = cells.constBegin(); i != end; ++i) {
   182         // Get the old cell
   182         // Get the old cell
   183         int offset = i.key();
   183         qptrdiff offset = i.key();
   184         int size = i.value();
   184         int size = i.value();
   185         // Copy to new chunk
   185         // Copy to new chunk
   186         memcpy(buffer + newCurrentOffset, static_cast<char*>(shared->base()) + offset, size);
   186         memcpy(buffer + newCurrentOffset, static_cast<char*>(shared->base()) + offset, size);
   187         newCurrentOffset += size;
   187         newCurrentOffset += size;
   188     }
   188     }
   190     // Free all cells from the shared chunk and move the defragmented buffer in the beginning of the chunk.
   190     // Free all cells from the shared chunk and move the defragmented buffer in the beginning of the chunk.
   191     // Note that chunk memory management is screwed up after this point, so no more allocations should be
   191     // Note that chunk memory management is screwed up after this point, so no more allocations should be
   192     // done in it after this.
   192     // done in it after this.
   193 
   193 
   194     unregisterAll();
   194     unregisterAll();
   195     QList<int> keys = cells.keys();
   195     QList<qptrdiff> keys = cells.keys();
   196 
   196 
   197     for (int j = 0; j < keys.count(); ++j) {
   197     for (int j = 0; j < keys.count(); ++j) {
   198         shared->free(keys.at(j));
   198         shared->free(keys.at(j));
   199     }
   199     }
   200 
   200 
   201     // CSS binary data is placed after the chunk header.
   201     // CSS binary data is placed after the chunk header.
   202     int cssBinaryOffset = sizeof(HbSharedChunkHeader);
   202     qptrdiff cssBinaryOffset = sizeof(HbSharedChunkHeader);
   203     char *address = HbMemoryUtils::getAddress<char>(HbMemoryManager::SharedMemory, cssBinaryOffset);
   203     char *address = HbMemoryUtils::getAddress<char>(HbMemoryManager::SharedMemory, cssBinaryOffset);
   204     memcpy(address, buffer, newCurrentOffset);
   204     memcpy(address, buffer, newCurrentOffset);
   205 
   205 
   206     cells.clear();
   206     cells.clear();
   207     totalAllocated = 0;
   207     totalAllocated = 0;