Author: Hakan Ardo <ha...@debian.org> Branch: jit-short_from_state Changeset: r46493:3d47ca2e7086 Date: 2011-08-14 09:38 +0200 http://bitbucket.org/pypy/pypy/changeset/3d47ca2e7086/
Log: hg merge default diff --git a/ctypes_configure/stdoutcapture.py b/ctypes_configure/stdoutcapture.py --- a/ctypes_configure/stdoutcapture.py +++ b/ctypes_configure/stdoutcapture.py @@ -15,6 +15,15 @@ not hasattr(os, 'fdopen')): self.dummy = 1 else: + try: + self.tmpout = os.tmpfile() + if mixed_out_err: + self.tmperr = self.tmpout + else: + self.tmperr = os.tmpfile() + except OSError: # bah? on at least one Windows box + self.dummy = 1 + return self.dummy = 0 # make new stdout/stderr files if needed self.localoutfd = os.dup(1) @@ -29,11 +38,6 @@ sys.stderr = os.fdopen(self.localerrfd, 'w', 0) else: self.saved_stderr = None - self.tmpout = os.tmpfile() - if mixed_out_err: - self.tmperr = self.tmpout - else: - self.tmperr = os.tmpfile() os.dup2(self.tmpout.fileno(), 1) os.dup2(self.tmperr.fileno(), 2) diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -891,7 +891,8 @@ self.statement = c_void_p() next_char = c_char_p() - ret = sqlite.sqlite3_prepare_v2(self.con.db, sql, -1, byref(self.statement), byref(next_char)) + sql_char = c_char_p(sql) + ret = sqlite.sqlite3_prepare_v2(self.con.db, sql_char, -1, byref(self.statement), byref(next_char)) if ret == SQLITE_OK and self.statement.value is None: # an empty statement, we work around that, as it's the least trouble ret = sqlite.sqlite3_prepare_v2(self.con.db, "select 42", -1, byref(self.statement), byref(next_char)) @@ -901,7 +902,9 @@ raise self.con._get_exception(ret) self.con._remember_statement(self) if _check_remaining_sql(next_char.value): - raise Warning, "One and only one statement required" + raise Warning, "One and only one statement required: %r" % ( + next_char.value,) + # sql_char should remain alive until here self._build_row_cast_map() diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py --- a/pypy/jit/backend/x86/assembler.py +++ b/pypy/jit/backend/x86/assembler.py @@ -92,6 +92,7 @@ self.datablockwrapper = None self.stack_check_slowpath = 0 self.propagate_exception_path = 0 + self.gcrootmap_retaddr_forced = 0 self.teardown() def leave_jitted_hook(self): @@ -357,6 +358,7 @@ self.stack_check_slowpath = rawstart @staticmethod + @rgc.no_collect def _release_gil_asmgcc(css): # similar to trackgcroot.py:pypy_asm_stackwalk, first part from pypy.rpython.memory.gctransform import asmgcroot @@ -372,6 +374,7 @@ before() @staticmethod + @rgc.no_collect def _reacquire_gil_asmgcc(css): # first reacquire the GIL after = rffi.aroundstate.after @@ -386,12 +389,14 @@ next.prev = prev @staticmethod + @rgc.no_collect def _release_gil_shadowstack(): before = rffi.aroundstate.before if before: before() @staticmethod + @rgc.no_collect def _reacquire_gil_shadowstack(): after = rffi.aroundstate.after if after: @@ -2218,13 +2223,27 @@ css = get_ebp_ofs(pos + use_words - 1) self._regalloc.close_stack_struct = css # The location where the future CALL will put its return address - # will be [ESP-WORD], so save that as the next frame's top address - self.mc.LEA_rs(eax.value, -WORD) # LEA EAX, [ESP-4] + # will be [ESP-WORD]. But we can't use that as the next frame's + # top address! As the code after releasegil() runs without the + # GIL, it might not be set yet by the time we need it (very + # unlikely), or it might be overwritten by the following call + # to reaquiregil() (much more likely). So we hack even more + # and use a dummy location containing a dummy value (a pointer + # to itself) which we pretend is the return address :-/ :-/ :-/ + # It prevents us to store any %esp-based stack locations but we + # don't so far. + adr = self.datablockwrapper.malloc_aligned(WORD, WORD) + rffi.cast(rffi.CArrayPtr(lltype.Signed), adr)[0] = adr + self.gcrootmap_retaddr_forced = adr frame_ptr = css + WORD * (2+asmgcroot.FRAME_PTR) - self.mc.MOV_br(frame_ptr, eax.value) # MOV [css.frame], EAX + if rx86.fits_in_32bits(adr): + self.mc.MOV_bi(frame_ptr, adr) # MOV [css.frame], adr + else: + self.mc.MOV_ri(eax.value, adr) # MOV EAX, adr + self.mc.MOV_br(frame_ptr, eax.value) # MOV [css.frame], EAX # Save ebp index_of_ebp = css + WORD * (2+asmgcroot.INDEX_OF_EBP) - self.mc.MOV_br(index_of_ebp, ebp.value) # MOV [css.ebp], EBP + self.mc.MOV_br(index_of_ebp, ebp.value) # MOV [css.ebp], EBP # Call the closestack() function (also releasing the GIL) if IS_X86_32: reg = eax @@ -2252,6 +2271,9 @@ if gcrootmap.is_shadow_stack: args = [] else: + assert self.gcrootmap_retaddr_forced == -1, ( + "missing mark_gc_roots() in CALL_RELEASE_GIL") + self.gcrootmap_retaddr_forced = 0 css = self._regalloc.close_stack_struct assert css != 0 if IS_X86_32: @@ -2502,7 +2524,13 @@ if gcrootmap.is_shadow_stack: gcrootmap.write_callshape(mark, force_index) else: - self.mc.insert_gcroot_marker(mark) + if self.gcrootmap_retaddr_forced == 0: + self.mc.insert_gcroot_marker(mark) # common case + else: + assert self.gcrootmap_retaddr_forced != -1, ( + "two mark_gc_roots() in a CALL_RELEASE_GIL") + gcrootmap.put(self.gcrootmap_retaddr_forced, mark) + self.gcrootmap_retaddr_forced = -1 def target_arglocs(self, loop_token): return loop_token._x86_arglocs diff --git a/pypy/module/posix/interp_posix.py b/pypy/module/posix/interp_posix.py --- a/pypy/module/posix/interp_posix.py +++ b/pypy/module/posix/interp_posix.py @@ -473,7 +473,7 @@ FIELDS = PORTABLE_STAT_FIELDS else: FIELDS = STAT_FIELDS # also when not translating at all - return space.newlist([space.wrap(name) for name, _ in FIELDS]) + return space.newlist([space.wrap(name) for _, (name, _) in FIELDS]) class State: diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py --- a/pypy/rpython/lltypesystem/rffi.py +++ b/pypy/rpython/lltypesystem/rffi.py @@ -749,21 +749,18 @@ return hlstrtype(gc_buf) new_buf = lltype.malloc(STRTYPE, needed_size) - try: - str_chars_offset = (offsetof(STRTYPE, 'chars') + \ - itemoffsetof(STRTYPE.chars, 0)) - if gc_buf: - src = cast_ptr_to_adr(gc_buf) + str_chars_offset - else: - src = cast_ptr_to_adr(raw_buf) + itemoffsetof(TYPEP.TO, 0) - dest = cast_ptr_to_adr(new_buf) + str_chars_offset - ## FIXME: This is bad, because dest could potentially move - ## if there are threads involved. - raw_memcopy(src, dest, - llmemory.sizeof(ll_char_type) * needed_size) - return hlstrtype(new_buf) - finally: - keepalive_until_here(new_buf) + str_chars_offset = (offsetof(STRTYPE, 'chars') + \ + itemoffsetof(STRTYPE.chars, 0)) + if gc_buf: + src = cast_ptr_to_adr(gc_buf) + str_chars_offset + else: + src = cast_ptr_to_adr(raw_buf) + itemoffsetof(TYPEP.TO, 0) + dest = cast_ptr_to_adr(new_buf) + str_chars_offset + raw_memcopy(src, dest, + llmemory.sizeof(ll_char_type) * needed_size) + keepalive_until_here(gc_buf) + keepalive_until_here(new_buf) + return hlstrtype(new_buf) # (char*, str) -> None def keep_buffer_alive_until_here(raw_buf, gc_buf): @@ -1068,4 +1065,4 @@ [VOIDP, VOIDP, SIZE_T], lltype.Void, threadsafe=False -) \ No newline at end of file +) diff --git a/pypy/rpython/lltypesystem/rstr.py b/pypy/rpython/lltypesystem/rstr.py --- a/pypy/rpython/lltypesystem/rstr.py +++ b/pypy/rpython/lltypesystem/rstr.py @@ -3,6 +3,7 @@ from pypy.rpython.error import TyperError from pypy.rlib.objectmodel import malloc_zero_filled, we_are_translated from pypy.rlib.objectmodel import _hash_string, enforceargs +from pypy.rlib.objectmodel import keepalive_until_here from pypy.rlib.debug import ll_assert from pypy.rlib.jit import elidable, we_are_jitted, dont_look_inside from pypy.rlib.rarithmetic import ovfcheck @@ -67,6 +68,8 @@ src = llmemory.cast_ptr_to_adr(src) + _str_ofs(srcstart) dst = llmemory.cast_ptr_to_adr(dst) + _str_ofs(dststart) llmemory.raw_memcopy(src, dst, llmemory.sizeof(CHAR_TP) * length) + keepalive_until_here(src) + keepalive_until_here(dst) copy_string_contents._always_inline_ = True #copy_string_contents.oopspec = ( # '%s.copy_contents(src, dst, srcstart, dststart, length)' % name) diff --git a/pypy/translator/c/gcc/test/elf64/track_zero_4.s b/pypy/translator/c/gcc/test/elf64/track_zero_4.s new file mode 100644 --- /dev/null +++ b/pypy/translator/c/gcc/test/elf64/track_zero_4.s @@ -0,0 +1,18 @@ + .type pypy_g_do_call_1, @function +pypy_g_do_call_1: + pushq %rbx + pushq %r12 + movq %rdi, %rbx + movq %rsi, %r12 + call number1 + ;; expected {16(%rsp) | 8(%rsp), (%rsp), %r13, %r14, %r15, %rbp | %r12} + testq %rbx, %rbx + movq %r12, %rbx + je .L1 + movq (%rax), %rbx +.L1: + /* GCROOT %rbx */ + popq %r12 + popq %rbx + ret + .size pypy_g_do_call_1, .-pypy_g_do_call_1 diff --git a/pypy/translator/c/gcc/trackgcroot.py b/pypy/translator/c/gcc/trackgcroot.py --- a/pypy/translator/c/gcc/trackgcroot.py +++ b/pypy/translator/c/gcc/trackgcroot.py @@ -163,6 +163,9 @@ # Add the instruction to the list, and link it to the previous one. previnsn = self.insns[-1] self.insns.append(insn) + if (isinstance(insn, (InsnSetLocal, InsnCopyLocal)) and + insn.target == self.tested_for_zero): + self.tested_for_zero = None try: lst = insn.previous_insns _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit