def allocate(cls, context, builder, list_type, nitems): intp_t = context.get_value_type(types.intp) if isinstance(nitems, int): nitems = ir.Constant(intp_t, nitems) payload_type = context.get_data_type(types.ListPayload(list_type)) payload_size = context.get_abi_sizeof(payload_type) itemsize = get_itemsize(context, list_type) # Total allocation size = <payload header size> + nitems * itemsize allocsize, ovf = cgutils.muladd_with_overflow(builder, nitems, ir.Constant(intp_t, itemsize), ir.Constant(intp_t, payload_size)) with builder.if_then(ovf, likely=False): context.call_conv.return_user_exc(builder, MemoryError, ("cannot allocate list",)) meminfo = context.nrt_meminfo_varsize_alloc(builder, size=allocsize) cgutils.guard_memory_error(context, builder, meminfo, "cannot allocate list") self = cls(context, builder, list_type, None) self._list.meminfo = meminfo self._payload.allocated = nitems self._payload.size = ir.Constant(intp_t, 0) # for safety return self
def _payload_realloc(new_allocated): payload_type = context.get_data_type(types.ListPayload(self._ty)) payload_size = context.get_abi_sizeof(payload_type) allocsize, ovf = cgutils.muladd_with_overflow( builder, new_allocated, ir.Constant(intp_t, itemsize), ir.Constant(intp_t, payload_size) ) with builder.if_then(ovf, likely=False): context.call_conv.return_user_exc(builder, MemoryError, ("cannot resize list",)) ptr = context.nrt_meminfo_varsize_realloc(builder, self._list.meminfo, size=allocsize) cgutils.guard_memory_error(context, builder, ptr, "cannot resize list") self._payload.allocated = new_allocated
def allocate_ex(cls, context, builder, list_type, nitems): """ Allocate a ListInstance with its storage. Return a (ok, instance) tuple where *ok* is a LLVM boolean and *instance* is a ListInstance object (the object's contents are only valid when *ok* is true). """ intp_t = context.get_value_type(types.intp) if isinstance(nitems, int): nitems = ir.Constant(intp_t, nitems) payload_type = context.get_data_type(types.ListPayload(list_type)) payload_size = context.get_abi_sizeof(payload_type) itemsize = get_itemsize(context, list_type) # Account for the fact that the payload struct contains one entry payload_size -= itemsize ok = cgutils.alloca_once_value(builder, cgutils.true_bit) self = cls(context, builder, list_type, None) # Total allocation size = <payload header size> + nitems * itemsize allocsize, ovf = cgutils.muladd_with_overflow( builder, nitems, ir.Constant(intp_t, itemsize), ir.Constant(intp_t, payload_size)) with builder.if_then(ovf, likely=False): builder.store(cgutils.false_bit, ok) with builder.if_then(builder.load(ok), likely=True): meminfo = context.nrt.meminfo_new_varsize_dtor( builder, size=allocsize, dtor=self.get_dtor()) with builder.if_else(cgutils.is_null(builder, meminfo), likely=False) as (if_error, if_ok): with if_error: builder.store(cgutils.false_bit, ok) with if_ok: self._list.meminfo = meminfo self._list.parent = context.get_constant_null( types.pyobject) self._payload.allocated = nitems self._payload.size = ir.Constant(intp_t, 0) # for safety self._payload.dirty = cgutils.false_bit # Zero the allocated region self.zfill(self.size.type(0), nitems) return builder.load(ok), self
def _payload_realloc(new_allocated): payload_type = context.get_data_type(types.ListPayload(self._ty)) payload_size = context.get_abi_sizeof(payload_type) allocsize, ovf = cgutils.muladd_with_overflow( builder, new_allocated, ir.Constant(intp_t, itemsize), ir.Constant(intp_t, payload_size)) with builder.if_then(ovf, likely=False): context.call_conv.return_user_exc(builder, MemoryError, ("cannot resize list",)) ptr = context.nrt_meminfo_varsize_realloc(builder, self._list.meminfo, size=allocsize) cgutils.guard_memory_error(context, builder, ptr, "cannot resize list") self._payload.allocated = new_allocated
def allocate_ex(cls, context, builder, list_type, nitems): """ Allocate a ListInstance with its storage. Return a (ok, instance) tuple where *ok* is a LLVM boolean and *instance* is a ListInstance object (the object's contents are only valid when *ok* is true). """ intp_t = context.get_value_type(types.intp) if isinstance(nitems, int): nitems = ir.Constant(intp_t, nitems) payload_type = context.get_data_type(types.ListPayload(list_type)) payload_size = context.get_abi_sizeof(payload_type) itemsize = get_itemsize(context, list_type) # Account for the fact that the payload struct contains one entry payload_size -= itemsize ok = cgutils.alloca_once_value(builder, cgutils.true_bit) self = cls(context, builder, list_type, None) # Total allocation size = <payload header size> + nitems * itemsize allocsize, ovf = cgutils.muladd_with_overflow(builder, nitems, ir.Constant(intp_t, itemsize), ir.Constant(intp_t, payload_size)) with builder.if_then(ovf, likely=False): builder.store(cgutils.false_bit, ok) with builder.if_then(builder.load(ok), likely=True): meminfo = context.nrt.meminfo_new_varsize_dtor( builder, size=allocsize, dtor=self.get_dtor()) with builder.if_else(cgutils.is_null(builder, meminfo), likely=False) as (if_error, if_ok): with if_error: builder.store(cgutils.false_bit, ok) with if_ok: self._list.meminfo = meminfo self._list.parent = context.get_constant_null(types.pyobject) self._payload.allocated = nitems self._payload.size = ir.Constant(intp_t, 0) # for safety self._payload.dirty = cgutils.false_bit # Zero the allocated region self.zfill(self.size.type(0), nitems) return builder.load(ok), self
def _allocate_payload(self, nentries, realloc=False): """ Allocate and initialize payload for the given number of entries. If *realloc* is True, the existing meminfo is reused. CAUTION: *nentries* must be a power of 2! """ context = self._context builder = self._builder ok = cgutils.alloca_once_value(builder, cgutils.true_bit) intp_t = context.get_value_type(types.intp) zero = ir.Constant(intp_t, 0) one = ir.Constant(intp_t, 1) payload_type = context.get_data_type(types.SetPayload(self._ty)) payload_size = context.get_abi_sizeof(payload_type) entry_size = self._entrysize # Account for the fact that the payload struct already contains an entry payload_size -= entry_size # Total allocation size = <payload header size> + nentries * entry_size allocsize, ovf = cgutils.muladd_with_overflow(builder, nentries, ir.Constant(intp_t, entry_size), ir.Constant(intp_t, payload_size)) with builder.if_then(ovf, likely=False): builder.store(cgutils.false_bit, ok) with builder.if_then(builder.load(ok), likely=True): if realloc: meminfo = self._set.meminfo ptr = context.nrt.meminfo_varsize_alloc(builder, meminfo, size=allocsize) alloc_ok = cgutils.is_null(builder, ptr) else: meminfo = context.nrt.meminfo_new_varsize(builder, size=allocsize) alloc_ok = cgutils.is_null(builder, meminfo) with builder.if_else(cgutils.is_null(builder, meminfo), likely=False) as (if_error, if_ok): with if_error: builder.store(cgutils.false_bit, ok) with if_ok: if not realloc: self._set.meminfo = meminfo self._set.parent = context.get_constant_null(types.pyobject) payload = self.payload # Initialize entries to 0xff (EMPTY) cgutils.memset(builder, payload.ptr, allocsize, 0xFF) payload.used = zero payload.fill = zero payload.finger = zero new_mask = builder.sub(nentries, one) payload.mask = new_mask if DEBUG_ALLOCS: context.printf(builder, "allocated %zd bytes for set at %p: mask = %zd\n", allocsize, payload.ptr, new_mask) return builder.load(ok)
def _allocate_payload(self, nentries, realloc=False): """ Allocate and initialize payload for the given number of entries. If *realloc* is True, the existing meminfo is reused. CAUTION: *nentries* must be a power of 2! """ context = self._context builder = self._builder ok = cgutils.alloca_once_value(builder, cgutils.true_bit) intp_t = context.get_value_type(types.intp) zero = ir.Constant(intp_t, 0) one = ir.Constant(intp_t, 1) payload_type = context.get_data_type(types.SetPayload(self._ty)) payload_size = context.get_abi_sizeof(payload_type) entry_size = self._entrysize # Account for the fact that the payload struct already contains an entry payload_size -= entry_size # Total allocation size = <payload header size> + nentries * entry_size allocsize, ovf = cgutils.muladd_with_overflow( builder, nentries, ir.Constant(intp_t, entry_size), ir.Constant(intp_t, payload_size)) with builder.if_then(ovf, likely=False): builder.store(cgutils.false_bit, ok) with builder.if_then(builder.load(ok), likely=True): if realloc: meminfo = self._set.meminfo ptr = context.nrt.meminfo_varsize_alloc(builder, meminfo, size=allocsize) alloc_ok = cgutils.is_null(builder, ptr) else: meminfo = context.nrt.meminfo_new_varsize(builder, size=allocsize) alloc_ok = cgutils.is_null(builder, meminfo) with builder.if_else(cgutils.is_null(builder, meminfo), likely=False) as (if_error, if_ok): with if_error: builder.store(cgutils.false_bit, ok) with if_ok: if not realloc: self._set.meminfo = meminfo self._set.parent = context.get_constant_null( types.pyobject) payload = self.payload # Initialize entries to 0xff (EMPTY) cgutils.memset(builder, payload.ptr, allocsize, 0xFF) payload.used = zero payload.fill = zero payload.finger = zero new_mask = builder.sub(nentries, one) payload.mask = new_mask if DEBUG_ALLOCS: context.printf( builder, "allocated %zd bytes for set at %p: mask = %zd\n", allocsize, payload.ptr, new_mask) return builder.load(ok)