diff options
author | Armin Rigo <arigo@tunes.org> | 2011-08-02 18:09:11 +0200 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2011-08-02 18:09:11 +0200 |
commit | 153e17116b82491a75bbd8d8facbaad167dfe23c (patch) | |
tree | 23c60f5c63b238b8e7a75153dda1658e38a82c4b | |
parent | Add an assert. (diff) | |
download | pypy-153e17116b82491a75bbd8d8facbaad167dfe23c.tar.gz pypy-153e17116b82491a75bbd8d8facbaad167dfe23c.tar.bz2 pypy-153e17116b82491a75bbd8d8facbaad167dfe23c.zip |
Finish to fix the remaining cases. A bit hard to test for all cases...
-rw-r--r-- | pypy/jit/backend/llsupport/gc.py | 69 | ||||
-rw-r--r-- | pypy/jit/backend/test/runner_test.py | 12 | ||||
-rw-r--r-- | pypy/jit/backend/x86/assembler.py | 31 |
3 files changed, 56 insertions, 56 deletions
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py index b410bb2c28..e73b2ef1e7 100644 --- a/pypy/jit/backend/llsupport/gc.py +++ b/pypy/jit/backend/llsupport/gc.py @@ -544,18 +544,19 @@ class GcLLDescr_framework(GcLLDescription): assert self.GCClass.inline_simple_malloc assert self.GCClass.inline_simple_malloc_varsize - # make a malloc function, with three arguments + # make a malloc function, with two arguments def malloc_basic(size, tid): type_id = llop.extract_ushort(llgroup.HALFWORD, tid) has_finalizer = bool(tid & (1<<llgroup.HALFSHIFT)) check_typeid(type_id) - try: - res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, - type_id, size, True, - has_finalizer, False) - except MemoryError: - fatalerror("out of memory (from JITted code)") - res = lltype.nullptr(llmemory.GCREF.TO) + res = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, + type_id, size, True, + has_finalizer, False) + # In case the operation above failed, we are returning NULL + # from this function to assembler. There is also an RPython + # exception set, typically MemoryError; but it's easier and + # faster to check for the NULL return value, as done by + # translator/exceptiontransform.py. #llop.debug_print(lltype.Void, "\tmalloc_basic", size, type_id, # "-->", res) return res @@ -571,14 +572,10 @@ class GcLLDescr_framework(GcLLDescription): def malloc_array(itemsize, tid, num_elem): type_id = llop.extract_ushort(llgroup.HALFWORD, tid) check_typeid(type_id) - try: - return llop1.do_malloc_varsize_clear( - llmemory.GCREF, - type_id, num_elem, self.array_basesize, itemsize, - self.array_length_ofs, True) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return lltype.nullptr(llmemory.GCREF.TO) + return llop1.do_malloc_varsize_clear( + llmemory.GCREF, + type_id, num_elem, self.array_basesize, itemsize, + self.array_length_ofs, True) self.malloc_array = malloc_array self.GC_MALLOC_ARRAY = lltype.Ptr(lltype.FuncType( [lltype.Signed] * 3, llmemory.GCREF)) @@ -591,23 +588,15 @@ class GcLLDescr_framework(GcLLDescription): unicode_type_id = self.layoutbuilder.get_type_id(rstr.UNICODE) # def malloc_str(length): - try: - return llop1.do_malloc_varsize_clear( - llmemory.GCREF, - str_type_id, length, str_basesize, str_itemsize, - str_ofs_length, True) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return lltype.nullptr(llmemory.GCREF.TO) + return llop1.do_malloc_varsize_clear( + llmemory.GCREF, + str_type_id, length, str_basesize, str_itemsize, + str_ofs_length, True) def malloc_unicode(length): - try: - return llop1.do_malloc_varsize_clear( - llmemory.GCREF, - unicode_type_id, length, unicode_basesize,unicode_itemsize, - unicode_ofs_length, True) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return lltype.nullptr(llmemory.GCREF.TO) + return llop1.do_malloc_varsize_clear( + llmemory.GCREF, + unicode_type_id, length, unicode_basesize,unicode_itemsize, + unicode_ofs_length, True) self.malloc_str = malloc_str self.malloc_unicode = malloc_unicode self.GC_MALLOC_STR_UNICODE = lltype.Ptr(lltype.FuncType( @@ -628,16 +617,12 @@ class GcLLDescr_framework(GcLLDescription): if self.DEBUG: random_usage_of_xmm_registers() assert size >= self.minimal_size_in_nursery - try: - # NB. although we call do_malloc_fixedsize_clear() here, - # it's a bit of a hack because we set tid to 0 and may - # also use it to allocate varsized objects. The tid - # and possibly the length are both set afterward. - gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, - 0, size, True, False, False) - except MemoryError: - fatalerror("out of memory (from JITted code)") - return 0 + # NB. although we call do_malloc_fixedsize_clear() here, + # it's a bit of a hack because we set tid to 0 and may + # also use it to allocate varsized objects. The tid + # and possibly the length are both set afterward. + gcref = llop1.do_malloc_fixedsize_clear(llmemory.GCREF, + 0, size, True, False, False) return rffi.cast(lltype.Signed, gcref) self.malloc_slowpath = malloc_slowpath self.MALLOC_SLOWPATH = lltype.FuncType([lltype.Signed], lltype.Signed) diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py index 9b23d51fcf..aeed99b95d 100644 --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -2822,14 +2822,10 @@ class LLtypeBackendTest(BaseBackendTest): inputargs = [i0] looptoken = LoopToken() self.cpu.compile_loop(inputargs, operations, looptoken) - # overflowing values: - for big in [ - sys.maxint // 4 + 1, # just too large - int(2*(sys.maxint+1) // 4) + 3, # intmask(this * 4) == 3 - ]: - self.cpu.set_future_value_int(0, big) - fail = self.cpu.execute_token(looptoken) - assert fail.identifier == excdescr.identifier + # overflowing value: + self.cpu.set_future_value_int(0, sys.maxint // 4 + 1) + fail = self.cpu.execute_token(looptoken) + assert fail.identifier == excdescr.identifier class OOtypeBackendTest(BaseBackendTest): diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py index f651207060..88354f8073 100644 --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -128,9 +128,9 @@ class Assembler386(object): self._build_failure_recovery(True, withfloats=True) support.ensure_sse2_floats() self._build_float_constants() + self._build_propagate_exception_path() if gc_ll_descr.get_malloc_slowpath_addr is not None: self._build_malloc_slowpath() - self._build_propagate_exception_path() self._build_stack_check_slowpath() if gc_ll_descr.gcrootmap: self._build_release_gil(gc_ll_descr.gcrootmap) @@ -244,9 +244,27 @@ class Assembler386(object): if self.cpu.supports_floats: # restore the XMM registers for i in range(self.cpu.NUM_REGS):# from where they were saved mc.MOVSD_xs(i, (WORD*2)+8*i) + # + # Note: we check this after the code above, just because the code + # above is more than 127 bytes on 64-bits... + mc.TEST_rr(eax.value, eax.value) + mc.J_il8(rx86.Conditions['Z'], 0) # patched later + jz_location = mc.get_relative_pos() + # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() mc.MOV(edx, heap(nursery_free_adr)) # load this in EDX mc.RET() + # + # If the slowpath malloc failed, we raise a MemoryError that + # always interrupts the current loop, as a "good enough" + # approximation. Also note that we didn't RET from this helper; + # but the code we jump to will actually restore the stack + # position based on EBP, which will get us out of here for free. + offset = mc.get_relative_pos() - jz_location + assert 0 < offset <= 127 + mc.overwrite(jz_location-1, chr(offset)) + mc.JMP(imm(self.propagate_exception_path)) + # rawstart = mc.materialize(self.cpu.asmmemmgr, []) self.malloc_slowpath2 = rawstart @@ -1443,7 +1461,7 @@ class Assembler386(object): assert isinstance(loc_vtable, ImmedLoc) arglocs = arglocs[:-1] self.call(self.malloc_func_addr, arglocs, eax) - # xxx ignore NULL returns for now + self.propagate_memoryerror_if_eax_is_null() self.set_vtable(eax, loc_vtable) def set_vtable(self, loc, loc_vtable): @@ -1467,14 +1485,17 @@ class Assembler386(object): def genop_new_array(self, op, arglocs, result_loc): assert result_loc is eax self.call(self.malloc_array_func_addr, arglocs, eax) + self.propagate_memoryerror_if_eax_is_null() def genop_newstr(self, op, arglocs, result_loc): assert result_loc is eax self.call(self.malloc_str_func_addr, arglocs, eax) + self.propagate_memoryerror_if_eax_is_null() def genop_newunicode(self, op, arglocs, result_loc): assert result_loc is eax self.call(self.malloc_unicode_func_addr, arglocs, eax) + self.propagate_memoryerror_if_eax_is_null() def propagate_memoryerror_if_eax_is_null(self): # if self.propagate_exception_path == 0 (tests), this may jump to 0 @@ -1761,10 +1782,8 @@ class Assembler386(object): def generate_propagate_error_64(self): assert WORD == 8 - mc = self.mc - startpos = mc.get_relative_pos() - mc.MOV_ri(X86_64_SCRATCH_REG.value, self.propagate_exception_path) - mc.JMP_r(X86_64_SCRATCH_REG.value) + startpos = self.mc.get_relative_pos() + self.mc.JMP(imm(self.propagate_exception_path)) return startpos def generate_quick_failure(self, guardtok): |