def realloc_frame(frame, size): try: if not we_are_translated(): assert not self._exception_emulator[0] frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date # frame info lives on assembler stack, so we need to enable # writing enter_assembler_writing() frame.jf_frame_info.update_frame_depth(base_ofs, size) leave_assembler_writing() new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc # all other fields are empty llop.gc_writebarrier(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) except Exception as e: print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO)
def f(): s = lltype.malloc(S) s.x = 42 llop.bare_setfield(lltype.Void, s0, void('next'), s) llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(s0)) rgc.collect(0) return s0.next.x
def attach_handle_on_suspstack(self, handle): s = self.suspstack self.suspstack = NULL_SUSPSTACK ll_assert(bool(s.anchor), "s.anchor should not be null") s.handle = handle llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(s)) return s
def ll_writebarrier(gc_obj): """Use together with custom tracers. When you update some object pointer stored in raw memory, you must call this function on 'gc_obj', which must be the object of type TP with the custom tracer (*not* the value stored!). This makes sure that the custom hook will be called again.""" from rpython.rtyper.lltypesystem.lloperation import llop llop.gc_writebarrier(lltype.Void, gc_obj)
def attach_handle_on_suspstack(self, handle): s = self.suspstack self.suspstack = NULL_SUSPSTACK ll_assert(bool(s.anchor), "s.anchor should not be null") s.handle = handle llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(s)) return s
def f(): s = lltype.malloc(S) s.x = 42 llop.bare_setfield(lltype.Void, s0, void('next'), s) llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(s0)) rgc.collect(0) return s0.next.x
def ll_writebarrier(gc_obj): """Use together with custom tracers. When you update some object pointer stored in raw memory, you must call this function on 'gc_obj', which must be the object of type TP with the custom tracer (*not* the value stored!). This makes sure that the custom hook will be called again.""" from rpython.rtyper.lltypesystem.lloperation import llop llop.gc_writebarrier(lltype.Void, gc_obj)
def attach_handle_on_stacklet(stacklet, h): if not h: raise MemoryError elif _c.is_empty_handle(h): ll_assert(gcrootfinder.sscopy == llmemory.NULL, "empty_handle but sscopy != NULL") return NULL_STACKLET else: # This is a return that gave us a real handle. Store it. stacklet.s_handle = h stacklet.s_sscopy = gcrootfinder.sscopy ll_assert(gcrootfinder.sscopy != llmemory.NULL, "!empty_handle but sscopy == NULL") gcrootfinder.sscopy = llmemory.NULL llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(stacklet)) return stacklet
def ll_dict_remove_deleted_items(d): if d.num_live_items < len(d.entries) // 4: # At least 75% of the allocated entries are dead, so shrink the memory # allocated as well as doing a compaction. new_allocated = _overallocate_entries_len(d.num_live_items) newitems = lltype.malloc(lltype.typeOf(d).TO.entries.TO, new_allocated) else: newitems = d.entries # The loop below does a lot of writes into 'newitems'. It's a better # idea to do a single gc_writebarrier rather than activating the # card-by-card logic (worth 11% in microbenchmarks). from rpython.rtyper.lltypesystem.lloperation import llop llop.gc_writebarrier(lltype.Void, newitems) # ENTRIES = lltype.typeOf(d).TO.entries.TO ENTRY = ENTRIES.OF isrc = 0 idst = 0 isrclimit = d.num_ever_used_items while isrc < isrclimit: if d.entries.valid(isrc): src = d.entries[isrc] dst = newitems[idst] dst.key = src.key dst.value = src.value if hasattr(ENTRY, "f_hash"): dst.f_hash = src.f_hash if hasattr(ENTRY, "f_valid"): assert src.f_valid dst.f_valid = True idst += 1 isrc += 1 assert d.num_live_items == idst d.num_ever_used_items = idst if (ENTRIES.must_clear_key or ENTRIES.must_clear_value) and d.entries == newitems: # must clear the extra entries: they may contain valid pointers # which would create a temporary memory leak while idst < isrclimit: entry = newitems[idst] if ENTRIES.must_clear_key: entry.key = lltype.nullptr(ENTRY.key.TO) if ENTRIES.must_clear_value: entry.value = lltype.nullptr(ENTRY.value.TO) idst += 1 else: d.entries = newitems ll_dict_reindex(d, _ll_len_of_d_indexes(d))
def ll_dict_remove_deleted_items(d): if d.num_live_items < len(d.entries) // 4: # At least 75% of the allocated entries are dead, so shrink the memory # allocated as well as doing a compaction. new_allocated = _overallocate_entries_len(d.num_live_items) newitems = lltype.malloc(lltype.typeOf(d).TO.entries.TO, new_allocated) else: newitems = d.entries # The loop below does a lot of writes into 'newitems'. It's a better # idea to do a single gc_writebarrier rather than activating the # card-by-card logic (worth 11% in microbenchmarks). from rpython.rtyper.lltypesystem.lloperation import llop llop.gc_writebarrier(lltype.Void, newitems) # ENTRIES = lltype.typeOf(d).TO.entries.TO ENTRY = ENTRIES.OF isrc = 0 idst = 0 isrclimit = d.num_ever_used_items while isrc < isrclimit: if d.entries.valid(isrc): src = d.entries[isrc] dst = newitems[idst] dst.key = src.key dst.value = src.value if hasattr(ENTRY, 'f_hash'): dst.f_hash = src.f_hash if hasattr(ENTRY, 'f_valid'): assert src.f_valid dst.f_valid = True idst += 1 isrc += 1 assert d.num_live_items == idst d.num_ever_used_items = idst if ((ENTRIES.must_clear_key or ENTRIES.must_clear_value) and d.entries == newitems): # must clear the extra entries: they may contain valid pointers # which would create a temporary memory leak while idst < isrclimit: entry = newitems[idst] if ENTRIES.must_clear_key: entry.key = lltype.nullptr(ENTRY.key.TO) if ENTRIES.must_clear_value: entry.value = lltype.nullptr(ENTRY.value.TO) idst += 1 else: d.entries = newitems ll_dict_reindex(d, _ll_len_of_d_indexes(d))
def make_framework_tracer(array_base_addr, gcrefs): # careful about the order here: the allocation of the GCREFTRACER # can trigger a GC. So we must write the gcrefs into the raw # array only afterwards... rgc.register_custom_trace_hook(GCREFTRACER, lambda_gcrefs_trace) length = len(gcrefs) tr = lltype.malloc(GCREFTRACER) # --no GC from here-- tr.array_base_addr = array_base_addr tr.array_length = length i = 0 while i < length: p = rffi.cast(rffi.SIGNEDP, array_base_addr + i * WORD) p[0] = rffi.cast(lltype.Signed, gcrefs[i]) i += 1 llop.gc_writebarrier(lltype.Void, tr) # --no GC until here-- return tr
def make_framework_tracer(array_base_addr, gcrefs): # careful about the order here: the allocation of the GCREFTRACER # can trigger a GC. So we must write the gcrefs into the raw # array only afterwards... rgc.register_custom_trace_hook(GCREFTRACER, lambda_gcrefs_trace) length = len(gcrefs) tr = lltype.malloc(GCREFTRACER) # --no GC from here-- tr.array_base_addr = array_base_addr tr.array_length = length i = 0 while i < length: p = rffi.cast(rffi.SIGNEDP, array_base_addr + i * WORD) p[0] = rffi.cast(lltype.Signed, gcrefs[i]) i += 1 llop.gc_writebarrier(lltype.Void, tr) # --no GC until here-- return tr
def attach_handle_on_stacklet(stacklet, h): ll_assert(stacklet.s_handle == _c.null_handle, "attach stacklet 1: garbage") ll_assert(stacklet.s_sscopy == llmemory.NULL, "attach stacklet 2: garbage") if not h: raise MemoryError elif _c.is_empty_handle(h): ll_assert(gcrootfinder.sscopy == llmemory.NULL, "empty_handle but sscopy != NULL") return NULL_STACKLET else: # This is a return that gave us a real handle. Store it. stacklet.s_handle = h stacklet.s_sscopy = gcrootfinder.sscopy ll_assert(gcrootfinder.sscopy != llmemory.NULL, "!empty_handle but sscopy == NULL") gcrootfinder.sscopy = llmemory.NULL llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(stacklet)) return stacklet
def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert isinstance(clt, CompiledLoopTokenASMJS) funcid = clt.func.compiled_funcid loopid = clt.compiled_loopid frame_info = clt.func.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = clt._ll_initial_locs if SANITYCHECK: assert len(locs) == len(args) if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: # Store each argument into the frame. for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) llop.gc_writebarrier(lltype.Void, ll_frame) # Send the threadlocaladdr. if self.translate_support_code: ll_tlref = llop.threadlocalref_addr(llmemory.Address) else: ll_tlref = rffi.cast(llmemory.Address, self._debug_errno_container) # Invoke it via the helper. ll_frameadr = self.cast_ptr_to_int(ll_frame) ll_tladdr = self.cast_adr_to_int(ll_tlref) ll_frameadr = support.jitInvoke(funcid, ll_frameadr, ll_tladdr, loopid) ll_frame = self.cast_int_to_ptr(ll_frameadr, llmemory.GCREF) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter return ll_frame
def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert isinstance(clt, CompiledLoopTokenASMJS) funcid = clt.func.compiled_funcid loopid = clt.compiled_loopid frame_info = clt.func.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = clt._ll_initial_locs if SANITYCHECK: assert len(locs) == len(args) if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: # Store each argument into the frame. for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) llop.gc_writebarrier(lltype.Void, ll_frame) # Send the threadlocaladdr. if self.translate_support_code: ll_tlref = llop.threadlocalref_addr( llmemory.Address) else: ll_tlref = rffi.cast(llmemory.Address, self._debug_errno_container) # Invoke it via the helper. ll_frameadr = self.cast_ptr_to_int(ll_frame) ll_tladdr = self.cast_adr_to_int(ll_tlref) ll_frameadr = support.jitInvoke(funcid, ll_frameadr, ll_tladdr, loopid) ll_frame = self.cast_int_to_ptr(ll_frameadr, llmemory.GCREF) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter return ll_frame
def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert len(args) == clt._debug_nbargs # addr = executable_token._ll_function_addr func = rffi.cast(FUNCPTR, addr) #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = executable_token.compiled_loop_token._ll_initial_locs prev_interpreter = None # help flow space if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) if self.translate_support_code: ll_threadlocal_addr = llop.threadlocalref_addr( llmemory.Address) else: ll_threadlocal_addr = rffi.cast(llmemory.Address, self._debug_tls_errno_container) llop.gc_writebarrier(lltype.Void, ll_frame) ll_frame = func(ll_frame, ll_threadlocal_addr) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter #llop.debug_print(lltype.Void, "<<<< Back") return ll_frame
def execute_token(executable_token, *args): clt = executable_token.compiled_loop_token assert len(args) == clt._debug_nbargs # addr = executable_token._ll_function_addr func = rffi.cast(FUNCPTR, addr) #llop.debug_print(lltype.Void, ">>>> Entering", addr) frame_info = clt.frame_info frame = self.gc_ll_descr.malloc_jitframe(frame_info) ll_frame = lltype.cast_opaque_ptr(llmemory.GCREF, frame) locs = executable_token.compiled_loop_token._ll_initial_locs prev_interpreter = None # help flow space if not self.translate_support_code: prev_interpreter = LLInterpreter.current_interpreter LLInterpreter.current_interpreter = self.debug_ll_interpreter try: for i, kind in kinds: arg = args[i] num = locs[i] if kind == history.INT: self.set_int_value(ll_frame, num, arg) elif kind == history.FLOAT: self.set_float_value(ll_frame, num, arg) else: assert kind == history.REF self.set_ref_value(ll_frame, num, arg) if self.translate_support_code: ll_threadlocal_addr = llop.threadlocalref_addr( llmemory.Address) else: ll_threadlocal_addr = rffi.cast(llmemory.Address, self._debug_errno_container) llop.gc_writebarrier(lltype.Void, ll_frame) ll_frame = func(ll_frame, ll_threadlocal_addr) finally: if not self.translate_support_code: LLInterpreter.current_interpreter = prev_interpreter #llop.debug_print(lltype.Void, "<<<< Back") return ll_frame
def realloc_frame(frame, size): try: if not we_are_translated(): assert not self._exception_emulator[0] frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, frame) if size > frame.jf_frame_info.jfi_frame_depth: # update the frame_info size, which is for whatever reason # not up to date frame.jf_frame_info.update_frame_depth(base_ofs, size) new_frame = jitframe.JITFRAME.allocate(frame.jf_frame_info) frame.jf_forward = new_frame i = 0 while i < len(frame.jf_frame): new_frame.jf_frame[i] = frame.jf_frame[i] frame.jf_frame[i] = 0 i += 1 new_frame.jf_savedata = frame.jf_savedata new_frame.jf_guard_exc = frame.jf_guard_exc # all other fields are empty llop.gc_writebarrier(lltype.Void, new_frame) return lltype.cast_opaque_ptr(llmemory.GCREF, new_frame) except Exception as e: print "Unhandled exception", e, "in realloc_frame" return lltype.nullptr(llmemory.GCREF.TO)
def f(): llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(s)) return True
def f(): llop.gc_writebarrier(lltype.Void, llmemory.cast_ptr_to_adr(s)) return True