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 make_function_returning_stack_pointer(self): rmmap.enter_assembler_writing() try: mc = InstrBuilder() mc.MOV_rr(r.x0.value, r.sp.value) mc.RET_r(r.lr.value) return mc.materialize(self.cpu, []) finally: rmmap.leave_assembler_writing()
def gcrefs_trace(gc, obj_addr, callback, arg1, arg2): rmmap.enter_assembler_writing() obj = llmemory.cast_adr_to_ptr(obj_addr, lltype.Ptr(GCREFTRACER)) i = 0 length = obj.array_length addr = obj.array_base_addr while i < length: p = rffi.cast(llmemory.Address, addr + i * WORD) gc._trace_callback(callback, arg1, arg2, p) i += 1 rmmap.leave_assembler_writing()
def invalidate_loop(self, looptoken): """Activate all GUARD_NOT_INVALIDATED in the loop and its attached bridges. Before this call, all GUARD_NOT_INVALIDATED do nothing; after this call, they all fail. Note that afterwards, if one such guard fails often enough, it has a bridge attached to it; it is possible then to re-call invalidate_loop() on the same looptoken, which must invalidate all newer GUARD_NOT_INVALIDATED, but not the old one that already has a bridge attached to it.""" rmmap.enter_assembler_writing() try: for jmp, tgt in looptoken.compiled_loop_token.invalidate_positions: mc = InstrBuilder() mc.B_ofs(tgt) mc.copy_to_raw_memory(jmp) finally: rmmap.leave_assembler_writing() # positions invalidated looptoken.compiled_loop_token.invalidate_positions = []
def setup_once(self): # the address of the function called by 'new' rmmap.enter_assembler_writing() gc_ll_descr = self.cpu.gc_ll_descr gc_ll_descr.initialize() if hasattr(gc_ll_descr, 'minimal_size_in_nursery'): self.gc_minimal_size_in_nursery = gc_ll_descr.minimal_size_in_nursery else: self.gc_minimal_size_in_nursery = 0 if hasattr(gc_ll_descr, 'gcheaderbuilder'): self.gc_size_of_header = gc_ll_descr.gcheaderbuilder.size_gc_header else: self.gc_size_of_header = WORD # for tests self.memcpy_addr = rffi.cast(lltype.Signed, memcpy_fn) self.memset_addr = rffi.cast(lltype.Signed, memset_fn) self._build_failure_recovery(False, withfloats=False) self._build_failure_recovery(True, withfloats=False) self._build_wb_slowpath(False) self._build_wb_slowpath(True) self._build_wb_slowpath(False, for_frame=True) # only one of those self.build_frame_realloc_slowpath() if self.cpu.supports_floats: self._build_failure_recovery(False, withfloats=True) self._build_failure_recovery(True, withfloats=True) self._build_wb_slowpath(False, withfloats=True) self._build_wb_slowpath(True, withfloats=True) self._build_propagate_exception_path() if gc_ll_descr.get_malloc_slowpath_addr is not None: # generate few slowpaths for various cases self.malloc_slowpath = self._build_malloc_slowpath(kind='fixed') self.malloc_slowpath_varsize = self._build_malloc_slowpath( kind='var') if hasattr(gc_ll_descr, 'malloc_str'): self.malloc_slowpath_str = self._build_malloc_slowpath(kind='str') else: self.malloc_slowpath_str = None if hasattr(gc_ll_descr, 'malloc_unicode'): self.malloc_slowpath_unicode = self._build_malloc_slowpath( kind='unicode') else: self.malloc_slowpath_unicode = None lst = [0, 0, 0, 0] lst[0] = self._build_cond_call_slowpath(False, False) lst[1] = self._build_cond_call_slowpath(False, True) if self.cpu.supports_floats: lst[2] = self._build_cond_call_slowpath(True, False) lst[3] = self._build_cond_call_slowpath(True, True) self.cond_call_slowpath = lst self._build_stack_check_slowpath() self._build_release_gil(gc_ll_descr.gcrootmap) # do not rely on the attribute _debug for jitlog if not self._debug: # if self._debug is already set it means that someone called # set_debug by hand before initializing the assembler. Leave it # as it is should_debug = have_debug_prints_for('jit-backend-counts') self.set_debug(should_debug) # when finishing, we only have one value at [0], the rest dies self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, flavor='raw', track_allocation=False) self.gcmap_for_finish[0] = r_uint(1) rmmap.leave_assembler_writing()