def ll_arraycopy(source, dest, source_start, dest_start, length): from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.objectmodel import keepalive_until_here # XXX: Hack to ensure that we get a proper effectinfo.write_descrs_arrays # and also, maybe, speed up very small cases if length <= 1: if length == 1: copy_item(source, dest, source_start, dest_start) return # supports non-overlapping copies only if not we_are_translated(): if source == dest: assert (source_start + length <= dest_start or dest_start + length <= source_start) TP = lltype.typeOf(source).TO assert TP == lltype.typeOf(dest).TO slowpath = False if must_split_gc_address_space(): slowpath = True elif _contains_gcptr(TP.OF): # perform a write barrier that copies necessary flags from # source to dest if not llop.gc_writebarrier_before_copy(lltype.Bool, source, dest, source_start, dest_start, length): slowpath = True if slowpath: # if the write barrier is not supported, or if we translate with # the option 'split_gc_address_space', then copy by hand i = 0 while i < length: copy_item(source, dest, i + source_start, i + dest_start) i += 1 return source_addr = llmemory.cast_ptr_to_adr(source) dest_addr = llmemory.cast_ptr_to_adr(dest) cp_source_addr = (source_addr + llmemory.itemoffsetof(TP, 0) + llmemory.sizeof(TP.OF) * source_start) cp_dest_addr = (dest_addr + llmemory.itemoffsetof(TP, 0) + llmemory.sizeof(TP.OF) * dest_start) llmemory.raw_memcopy(cp_source_addr, cp_dest_addr, llmemory.sizeof(TP.OF) * length) keepalive_until_here(source) keepalive_until_here(dest)
def ll_arraycopy(source, dest, source_start, dest_start, length): from rpython.rtyper.lltypesystem.lloperation import llop from rpython.rlib.objectmodel import keepalive_until_here # XXX: Hack to ensure that we get a proper effectinfo.write_descrs_arrays # and also, maybe, speed up very small cases if length <= 1: if length == 1: copy_item(source, dest, source_start, dest_start) return # supports non-overlapping copies only if not we_are_translated(): if source == dest: assert (source_start + length <= dest_start or dest_start + length <= source_start) TP = lltype.typeOf(source).TO assert TP == lltype.typeOf(dest).TO if _contains_gcptr(TP.OF): # perform a write barrier that copies necessary flags from # source to dest if not llop.gc_writebarrier_before_copy(lltype.Bool, source, dest, source_start, dest_start, length): # if the write barrier is not supported, copy by hand i = 0 while i < length: copy_item(source, dest, i + source_start, i + dest_start) i += 1 return source_addr = llmemory.cast_ptr_to_adr(source) dest_addr = llmemory.cast_ptr_to_adr(dest) cp_source_addr = (source_addr + llmemory.itemoffsetof(TP, 0) + llmemory.sizeof(TP.OF) * source_start) cp_dest_addr = (dest_addr + llmemory.itemoffsetof(TP, 0) + llmemory.sizeof(TP.OF) * dest_start) llmemory.raw_memcopy(cp_source_addr, cp_dest_addr, llmemory.sizeof(TP.OF) * length) keepalive_until_here(source) keepalive_until_here(dest)