def free_mem(self, addr, size): # first check if its a right alloc if not self.addrs.has_key(addr): raise VamosInternalError("Invalid Free'd Memory at %06x" % addr) # align size to 4 bytes size = (size + 3) & ~3 real_size = self.addrs[addr] assert size == real_size # remove from valid allocs del self.addrs[addr] # create a new free chunk chunk = MemoryChunk(addr, real_size) self._insert_chunk(chunk) # try to merge with prev/next prev = chunk.prev if prev != None: new_chunk = self._merge_chunk(prev, chunk) if new_chunk != None: log_mem_alloc.debug("merged: %s + this=%s -> %s", prev, chunk, new_chunk) chunk = new_chunk next = chunk.next if next != None: new_chunk = self._merge_chunk(chunk, next) if new_chunk != None: log_mem_alloc.debug("merged: this=%s + %s -> %s", chunk, next, new_chunk) # correct free bytes self.free_bytes += size num_allocs = len(self.addrs) log_mem_alloc.info("[free @%06x-%06x: %06x bytes] %s", addr, addr+size, size, self._stat_info())
def alloc_mem(self, size, except_on_fail=True): """allocate memory and return addr or 0 if no more memory""" # align size to 4 bytes size = (size + 3) & ~3 # find best free chunk chunk, left = self._find_best_chunk(size) # out of memory? if chunk == None: if except_on_fail: self.dump_orphans() log_mem_alloc.error("[alloc: NO MEMORY for %06x bytes]" % size) raise VamosInternalError("[alloc: NO MEMORY for %06x bytes]" % size) return 0 # remove chunk from free list # is something left? addr = chunk.addr if left == 0: self._remove_chunk(chunk) else: left_chunk = MemoryChunk(addr + size, left) self._replace_chunk(chunk, left_chunk) # add to valid allocs map self.addrs[addr] = size self.free_bytes -= size # erase memory self.mem.clear_block(addr, size, 0) log_mem_alloc.info("[alloc @%06x-%06x: %06x bytes] %s", addr, addr+size, size, self._stat_info()) if addr % 4: raise VamosInternalError( "Memory pool is invalid, return address not aligned by a long word") return addr
def map_struct(self, name, addr, struct): size = struct.get_size() access = AccessStruct(self.mem, struct, addr) if self.label_mgr is not None: label = self.label_mgr.get_label(addr) else: label = None mem = Memory(addr, size, label, access) log_mem_alloc.info("map struct: %s", mem) return mem
def alloc_bstr(self, name, bstr): size = len(bstr) + 2 # front: count, end: extra zero for safety addr = self.alloc_mem(size) if self.label_mgr is not None: label = LabelRange(name, addr, size) self.label_mgr.add_label(label) else: label = None self.mem.w_bstr(addr, bstr) mem = Memory(addr, size, label, self.mem) log_mem_alloc.info("alloc b_str: %s", mem) self.mem_objs[addr] = mem return mem
def alloc_cstr(self, name, cstr): size = len(cstr) + 1 addr = self.alloc_mem(size) if self.label_mgr is not None: label = LabelRange(name, addr, size) self.label_mgr.add_label(label) else: label = None self.mem.w_cstr(addr, cstr) mem = Memory(addr, size, label, self.mem) log_mem_alloc.info("alloc c_str: %s", mem) self.mem_objs[addr] = mem return mem
def alloc_memory(self, name, size, add_label=True, except_on_failure=True): addr = self.alloc_mem(size, except_on_failure) if addr == 0: return None if add_label and self.label_mgr is not None: label = LabelRange(name, addr, size) self.label_mgr.add_label(label) else: label = None mem = Memory(addr, size, label, self.mem) log_mem_alloc.info("alloc memory: %s", mem) self.mem_objs[addr] = mem return mem
def alloc_struct(self, name, struct, size=None, add_label=True): if size is None: size = struct.get_size() addr = self.alloc_mem(size) if self.label_mgr is not None and add_label: label = LabelStruct(name, addr, struct) self.label_mgr.add_label(label) else: label = None access = AccessStruct(self.mem, struct, addr) mem = Memory(addr, size, label, access) log_mem_alloc.info("alloc struct: %s", mem) self.mem_objs[addr] = mem return mem
def free_bstr(self, mem): log_mem_alloc.info("free b_str: %s", mem) if self.label_mgr is not None: self.label_mgr.remove_label(mem.label) self.free_mem(mem.addr, mem.size) del self.mem_objs[mem.addr]
def free_memory(self, mem): log_mem_alloc.info("free memory: %s", mem) if mem.label != None: self.label_mgr.remove_label(mem.label) self.free_mem(mem.addr, mem.size) del self.mem_objs[mem.addr]