def __init__(self, dmm, fe_type): payload_type = types.SetPayload(fe_type) members = [ # The meminfo data points to a SetPayload ('meminfo', types.MemInfoPointer(payload_type)), # This member is only used only for reflected sets ('parent', types.pyobject), ] super(SetModel, self).__init__(dmm, fe_type, members)
def get_payload_struct(context, builder, set_type, ptr): """ Given a set value and type, get its payload structure (as a reference, so that mutations are seen by all). """ payload_type = types.SetPayload(set_type) ptrty = context.get_data_type(payload_type).as_pointer() payload = builder.bitcast(ptr, ptrty) return context.make_data_helper(builder, payload_type, ref=payload)
def __init__(self, dmm, fe_type): payload_type = types.SetPayload(fe_type.container) members = [ # The meminfo data points to a SetPayload (shared with the # original set object) ('meminfo', types.MemInfoPointer(payload_type)), # The index into the entries table ('index', types.EphemeralPointer(types.intp)), ] super(SetIterModel, self).__init__(dmm, fe_type, members)
def _copy_payload(self, src_payload): """ Raw-copy the given payload into self. """ 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 mask = src_payload.mask nentries = builder.add(one, mask) # Total allocation size = <payload header size> + nentries * entry_size # (note there can't be any overflow since we're reusing an existing # payload's parameters) allocsize = builder.add( ir.Constant(intp_t, payload_size), builder.mul(ir.Constant(intp_t, entry_size), nentries)) with builder.if_then(builder.load(ok), likely=True): 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: self._set.meminfo = meminfo payload = self.payload payload.used = src_payload.used payload.fill = src_payload.fill payload.finger = zero payload.mask = mask cgutils.raw_memcpy(builder, payload.entries, src_payload.entries, nentries, entry_size) if DEBUG_ALLOCS: context.printf( builder, "allocated %zd bytes for set at %p: mask = %zd\n", allocsize, payload.ptr, 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)