src/hbtools/hbbincssmaker/hbcssconverterutils.cpp
changeset 5 627c4a0fd0e7
parent 2 06ff229162e9
child 7 923ff622b8b9
equal deleted inserted replaced
3:11d3954df52a 5:627c4a0fd0e7
    53 void HbCssConverterUtils::unregisterOffsetHolder(int *offset)
    53 void HbCssConverterUtils::unregisterOffsetHolder(int *offset)
    54 {
    54 {
    55     registered.remove(offset);
    55     registered.remove(offset);
    56 }
    56 }
    57 
    57 
    58 
    58 QMultiHash<int, int *> HbCssConverterUtils::registeredOffsetHolders()
    59 QList<int *> HbCssConverterUtils::registeredOffsetHolders()
    59 {
    60 {
    60     QMultiHash<int, int *> holders;
    61     return registered.keys();
    61     holders.reserve(registered.size());
       
    62     QMap<int *, int>::const_iterator end = registered.constEnd();
       
    63     for (QMap<int *, int>::const_iterator i = registered.constBegin(); i != end; ++i) {
       
    64         int *holder = i.key();
       
    65         holders.insertMulti(*holder, holder);
       
    66     }
       
    67     return holders;
    62 }
    68 }
    63 
    69 
    64 void HbCssConverterUtils::unregisterAll()
    70 void HbCssConverterUtils::unregisterAll()
    65 {
    71 {
    66     registered.clear();
    72     registered.clear();
    82     if (size > 0) {
    88     if (size > 0) {
    83         // Make sure there are no registered offset holders in the freed cell any more
    89         // Make sure there are no registered offset holders in the freed cell any more
    84         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
    90         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
    85         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
    91         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
    86         const char *chunkBase = static_cast<const char *>(shared->base());
    92         const char *chunkBase = static_cast<const char *>(shared->base());
    87 
    93         const char *freedEnd = chunkBase + offset + size;
    88         QList<int *> offsetHolders = HbCssConverterUtils::registeredOffsetHolders();
    94         const int *freedStart = reinterpret_cast<const int *>(chunkBase + offset);
    89         for (int i = 0; i<offsetHolders.count(); ++i) {
    95 
    90             int *holder = offsetHolders.at(i);
    96         QMap<int *, int>::iterator freedHolders =
    91             if ((char*)holder >= chunkBase + offset && (char*)holder < chunkBase + offset + size) {
    97                 registered.lowerBound(const_cast<int *>(freedStart));
    92                 HbCssConverterUtils::unregisterOffsetHolder(holder);
    98         while(freedHolders != registered.end()
    93             }
    99               && reinterpret_cast<char*>(freedHolders.key()) <  freedEnd) {
       
   100             freedHolders = registered.erase(freedHolders);
    94         }
   101         }
    95     }
   102     }
    96 }
   103 }
    97 
   104 
    98 void HbCssConverterUtils::cellMoved(int offset, int newOffset)
   105 void HbCssConverterUtils::cellMoved(int offset, int newOffset)
   100     int size = cells.value(offset, 0);
   107     int size = cells.value(offset, 0);
   101 
   108 
   102     if (size > 0) {
   109     if (size > 0) {
   103         // Check if there were registered offset holders in the old cell
   110         // Check if there were registered offset holders in the old cell
   104         // and register corresponding ones in the reallocated cell.
   111         // and register corresponding ones in the reallocated cell.
   105         QList<int *> holders = HbCssConverterUtils::registeredOffsetHolders();
       
   106 
       
   107         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
   112         GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
   108         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
   113         HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
   109         const char *chunkBase = static_cast<const char *>(shared->base());    
   114         const char *chunkBase = static_cast<const char *>(shared->base());
   110         
   115         const char *freedEnd = chunkBase + offset + size;
   111         for (int i=0; i<holders.count(); i++) {
   116         const int *freedStart = reinterpret_cast<const int *>(chunkBase + offset);
   112             int *holder = holders.at(i);
   117 
   113             char *holderC = (char*)holder;
   118         QMap<int *, int>::iterator freedHolders =
   114             if (holderC >= chunkBase + offset && holderC < chunkBase + offset + size) {
   119                 registered.lowerBound(const_cast<int *>(freedStart));
   115                 HbCssConverterUtils::unregisterOffsetHolder(holder);
   120         QList<int *> newHolders;
   116                 HbCssConverterUtils::registerOffsetHolder((int*)(holderC + newOffset - offset));
   121         while(freedHolders != registered.end()
   117             }
   122               && reinterpret_cast<char*>(freedHolders.key()) <  freedEnd) {
       
   123             char *holderC = reinterpret_cast<char*>(freedHolders.key());
       
   124             newHolders.append(reinterpret_cast<int*>(holderC + newOffset - offset));
       
   125             freedHolders = registered.erase(freedHolders);
       
   126         }
       
   127         for (int i = 0; i < newHolders.size(); ++i) {
       
   128             registerOffsetHolder(newHolders.at(i));
   118         }
   129         }
   119     }
   130     }
   120 }
   131 }
   121 
   132 
   122 /**
   133 /**
   127 int HbCssConverterUtils::defragmentChunk()
   138 int HbCssConverterUtils::defragmentChunk()
   128 {
   139 {
   129     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
   140     GET_MEMORY_MANAGER(HbMemoryManager::SharedMemory);
   130     HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
   141     HbSharedMemoryManager *shared = static_cast<HbSharedMemoryManager*>(manager);
   131 
   142 
   132     // Register shared cache pointer in chunk header as shared cache may also be moved in defragmentation
   143     // Register shared cache pointer in chunk header
   133     HbSharedChunkHeader *chunkHeader = static_cast<HbSharedChunkHeader*>(shared->base());    
   144     //as shared cache may also be moved in defragmentation
   134     HbCssConverterUtils::registerOffsetHolder(reinterpret_cast<int *>(&chunkHeader->sharedCacheOffset));
   145     HbSharedChunkHeader *chunkHeader = static_cast<HbSharedChunkHeader*>(shared->base());
   135 
   146     registerOffsetHolder(reinterpret_cast<int *>(&chunkHeader->sharedCacheOffset));
   136     QList<int *> offsetHolders = HbCssConverterUtils::registeredOffsetHolders();
   147 
       
   148     QMultiHash<int, int *> offsetHolders = registeredOffsetHolders();
   137 
   149 
   138     // Create new buffer where the current chunk contents are defragmented
   150     // Create new buffer where the current chunk contents are defragmented
   139     void *buffer = ::malloc(shared->size());
   151     char *buffer = static_cast<char*>(::malloc(shared->size()));
   140     int newCurrentOffset = 0;
   152     int newCurrentOffset = 0;
   141 
   153 
   142     // Create new cell order and update offset holders
   154     // Create new cell order and update offset holders
   143     QMap<int,int>::const_iterator i = cells.constBegin();
   155     QMap<int,int>::const_iterator end = cells.constEnd();
   144 
   156 
   145     while (i != cells.constEnd()) {
   157     for (QMap<int,int>::const_iterator i = cells.constBegin(); i != end; ++i) {
   146         // Get the old cell
   158         // Get the old cell
   147         int offset = i.key();
   159         int offset = i.key();
   148         int size = i.value();
   160         int size = i.value();
   149         
   161         
   150         // Update registered offset holders
   162         // Update registered offset holders
   151 
   163         QList<int *> values = offsetHolders.values(offset);
   152         // TODO: optimize this, now there's linear search for each cell!
   164         offsetHolders.remove(offset);
   153 		for (int j=0; j<offsetHolders.count(); ++j) {
   165         int newOffset = newCurrentOffset + sizeof(HbSharedChunkHeader);
   154 			int *holder = offsetHolders.at(j);
   166         for (int j = 0; j < values.size(); ++j) {
   155 			if (*holder == offset) {
   167             int *holder = values[j];
   156 				// Change stored offset value
   168             *holder = newOffset;
   157 				*holder = newCurrentOffset + sizeof(HbSharedChunkHeader);
   169             offsetHolders.insertMulti(*holder, holder);
   158 			}
   170         }
   159 		}
       
   160 
       
   161         newCurrentOffset += size;
   171         newCurrentOffset += size;
   162         i++;
   172     }
   163     }
   173 
   164 
       
   165     i = cells.constBegin();
       
   166     newCurrentOffset = 0;
   174     newCurrentOffset = 0;
   167 
       
   168     // Move allocated cells to a linear buffer
   175     // Move allocated cells to a linear buffer
   169     while (i != cells.constEnd()) {
   176     for (QMap<int, int>::const_iterator i = cells.constBegin(); i != end; ++i) {
   170         // Get the old cell
   177         // Get the old cell
   171         int offset = i.key();
   178         int offset = i.key();
   172         int size = i.value();
   179         int size = i.value();
   173         // Copy to new chunk
   180         // Copy to new chunk
   174         memcpy((char*)buffer + newCurrentOffset, (char*)shared->base() + offset, size);
   181         memcpy(buffer + newCurrentOffset, static_cast<char*>(shared->base()) + offset, size);
   175 
       
   176         newCurrentOffset += size;
   182         newCurrentOffset += size;
   177         i++;
       
   178     }
   183     }
   179 
   184 
   180     // Free all cells from the shared chunk and move the defragmented buffer in the beginning of the chunk.
   185     // Free all cells from the shared chunk and move the defragmented buffer in the beginning of the chunk.
   181     // Note that chunk memory management is screwed up after this point, so no more allocations should be
   186     // Note that chunk memory management is screwed up after this point, so no more allocations should be
   182     // done in it after this.
   187     // done in it after this.
   183 
   188 
   184     HbCssConverterUtils::unregisterAll();
   189     unregisterAll();
   185     QList<int> keys = cells.keys();
   190     QList<int> keys = cells.keys();
   186 
   191 
   187     for (int j=0; j<keys.count(); ++j) {
   192     for (int j = 0; j < keys.count(); ++j) {
   188         shared->free(keys.at(j));
   193         shared->free(keys.at(j));
   189     }
   194     }
   190 
   195 
   191     // CSS binary data is placed after the chunk header.
   196     // CSS binary data is placed after the chunk header.
   192     int cssBinaryOffset = sizeof(HbSharedChunkHeader);
   197     int cssBinaryOffset = sizeof(HbSharedChunkHeader);