Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60051:279c4bd34be3
Date: 2013-01-14 18:33 +0200
http://bitbucket.org/pypy/pypy/changeset/279c4bd34be3/
Log: kill the descr indexes
diff --git a/pypy/jit/backend/llgraph/runner.py
b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -862,23 +862,22 @@
fielddescr = jd.vable_token_descr
self.cpu.bh_setfield_gc(vable, 0, fielddescr)
faildescr = self.cpu.get_latest_descr(pframe)
- failindex = self.cpu.get_fail_descr_number(faildescr)
- if failindex == self.cpu.done_with_this_frame_int_v:
+ if faildescr == self.cpu.done_with_this_frame_descr_int:
reset_vable(jd, vable)
return self.cpu.get_int_value(pframe, 0)
- if failindex == self.cpu.done_with_this_frame_ref_v:
+ if faildescr == self.cpu.done_with_this_frame_descr_ref:
reset_vable(jd, vable)
return self.cpu.get_ref_value(pframe, 0)
- if failindex == self.cpu.done_with_this_frame_float_v:
+ if faildescr == self.cpu.done_with_this_frame_descr_float:
reset_vable(jd, vable)
return self.cpu.get_float_value(pframe, 0)
- if failindex == self.cpu.done_with_this_frame_void_v:
+ if faildescr == self.cpu.done_with_this_frame_descr_void:
reset_vable(jd, vable)
return None
#
assembler_helper_ptr = jd.assembler_helper_adr.ptr # fish
try:
- result = assembler_helper_ptr(failindex, pframe, vable)
+ result = assembler_helper_ptr(pframe, vable)
except LLException, lle:
assert self.last_exception is None, "exception left behind"
self.last_exception = lle
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -102,6 +102,7 @@
gcrefs_output_list.append(p)
if op.is_guard() or op.getopnum() == rop.FINISH:
rgc._make_sure_does_not_move(op.getdescr())
+ gcrefs_output_list.append(op.getdescr())
def rewrite_assembler(self, cpu, operations, gcrefs_output_list):
rewriter = GcRewriterAssembler(self, cpu)
@@ -119,8 +120,8 @@
descrs.jf_descr = cpu.fielddescrof(jitframe.JITFRAME, 'jf_descr')
descrs.jf_guard_exc = cpu.fielddescrof(jitframe.JITFRAME,
'jf_guard_exc')
- descrs.jf_force_index = cpu.fielddescrof(jitframe.JITFRAME,
- 'jf_force_index')
+ descrs.jf_force_descr = cpu.fielddescrof(jitframe.JITFRAME,
+ 'jf_force_descr')
descrs.jf_frame_info = cpu.fielddescrof(jitframe.JITFRAME,
'jf_frame_info')
descrs.jfi_frame_depth = cpu.fielddescrof(jitframe.JITFRAMEINFO,
diff --git a/pypy/jit/backend/llsupport/jitframe.py
b/pypy/jit/backend/llsupport/jitframe.py
--- a/pypy/jit/backend/llsupport/jitframe.py
+++ b/pypy/jit/backend/llsupport/jitframe.py
@@ -24,8 +24,8 @@
# This field is also set immediately before doing CALL_MAY_FORCE
# or CALL_ASSEMBLER.
('jf_descr', llmemory.GCREF),
- # index of guard_not_force
- ('jf_force_index', lltype.Signed),
+ # guard_not_forced descr
+ ('jf_force_descr', llmemory.GCREF),
# For the front-end: a GCREF for the savedata
('jf_savedata', llmemory.GCREF),
# For GUARD_(NO)_EXCEPTION and GUARD_NOT_FORCED: the exception we
diff --git a/pypy/jit/backend/llsupport/llmodel.py
b/pypy/jit/backend/llsupport/llmodel.py
--- a/pypy/jit/backend/llsupport/llmodel.py
+++ b/pypy/jit/backend/llsupport/llmodel.py
@@ -205,11 +205,6 @@
descr = deadframe.jf_descr
return history.AbstractDescr.show(self, descr)
- def store_fail_descr(self, deadframe, failindex):
- faildescr = self.get_fail_descr_from_number(failindex)
- frame = lltype.cast_opaque_ptr(jitframe.JITFRAMEPTR, deadframe)
- frame.jf_descr = cast_instance_to_gcref(faildescr)
-
def _decode_pos(self, deadframe, index):
descr = self.get_latest_descr(deadframe)
if descr.final_descr:
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -1,6 +1,5 @@
from pypy.rlib.debug import debug_start, debug_print, debug_stop
-from pypy.rlib.objectmodel import we_are_translated
-from pypy.jit.metainterp import history
+from pypy.jit.metainterp import compile
from pypy.rpython.lltypesystem import lltype
@@ -12,52 +11,20 @@
# Boxes and Consts are BoxFloats and ConstFloats.
supports_singlefloats = False
- done_with_this_frame_void_v = -1
- done_with_this_frame_int_v = -1
- done_with_this_frame_ref_v = -1
- done_with_this_frame_float_v = -1
- propagate_exception_v = -1
total_compiled_loops = 0
total_compiled_bridges = 0
total_freed_loops = 0
total_freed_bridges = 0
+ propagate_exception_descr = None
+
# for heaptracker
# _all_size_descrs_with_vtable = None
_vtable_to_descr_dict = None
def __init__(self):
- self.fail_descr_list = []
- self.fail_descr_free_list = []
-
- def reserve_some_free_fail_descr_number(self):
- lst = self.fail_descr_list
- if len(self.fail_descr_free_list) > 0:
- n = self.fail_descr_free_list.pop()
- assert lst[n] is None
- else:
- n = len(lst)
- lst.append(None)
- return n
-
- def get_fail_descr_number(self, descr):
- assert isinstance(descr, history.AbstractFailDescr)
- if not we_are_translated():
- if not hasattr(descr, '_cpu'):
- assert descr.index == -1, "descr.index is already >= 0??"
- descr._cpu = self
- assert descr._cpu is self,"another CPU has already seen the descr!"
- #
- n = descr.index
- if n < 0:
- n = self.reserve_some_free_fail_descr_number()
- self.fail_descr_list[n] = descr
- descr.index = n
- return n
-
- def get_fail_descr_from_number(self, n):
- return self.fail_descr_list[n]
+ self.__dict__.update(compile.make_done_loop_tokens())
def setup_once(self):
"""Called once by the front-end when the program starts."""
@@ -196,19 +163,7 @@
guarantees that at the point of the call to free_code_group(),
none of the corresponding assembler is currently running.
"""
- # The base class provides a limited implementation: freeing the
- # resume descrs. This is already quite helpful, because the
- # resume descrs are the largest consumers of memory (about 3x
- # more than the assembler, in the case of the x86 backend).
- lst = self.fail_descr_list
- # We expect 'compiled_loop_token' to be itself garbage-collected soon,
- # but better safe than sorry: be ready to handle several calls to
- # free_loop_and_bridges() for the same compiled_loop_token.
- faildescr_indices = compiled_loop_token.faildescr_indices
- compiled_loop_token.faildescr_indices = []
- for n in faildescr_indices:
- lst[n] = None
- self.fail_descr_free_list.extend(faildescr_indices)
+ pass
def sizeof(self, S):
raise NotImplementedError
diff --git a/pypy/jit/backend/test/runner_test.py
b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -2758,13 +2758,12 @@
def test_assembler_call(self):
called = []
- def assembler_helper(failindex, deadframe, virtualizable):
- self.cpu.store_fail_descr(deadframe, failindex)
+ def assembler_helper(deadframe, virtualizable):
assert self.cpu.get_int_value(deadframe, 0) == 97
called.append(self.cpu.get_latest_descr(deadframe))
return 4 + 9
- FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF,
+ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF,
llmemory.GCREF],
lltype.Signed))
class FakeJitDriverSD:
@@ -2773,9 +2772,6 @@
assembler_helper_adr = llmemory.cast_ptr_to_adr(
_assembler_helper_ptr)
- # ensure the fail_descr_number is not zero
- for _ in range(10):
- self.cpu.reserve_some_free_fail_descr_number()
ops = '''
[i0, i1, i2, i3, i4, i5, i6, i7, i8, i9]
i10 = int_add(i0, i1)
@@ -2818,8 +2814,8 @@
# test the fast path, which should not call assembler_helper()
del called[:]
- self.cpu.done_with_this_frame_int_v = self.cpu.get_fail_descr_number(
- finish_descr)
+ prev_descr = self.cpu.done_with_this_frame_descr_int
+ self.cpu.done_with_this_frame_descr_int = finish_descr
try:
othertoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
@@ -2828,21 +2824,20 @@
assert self.cpu.get_int_value(deadframe, 0) == 97
assert not called
finally:
- del self.cpu.done_with_this_frame_int_v
+ self.cpu.done_with_this_frame_int_v = prev_descr
def test_assembler_call_float(self):
if not self.cpu.supports_floats:
py.test.skip("requires floats")
called = []
- def assembler_helper(failindex, deadframe, virtualizable):
- self.cpu.store_fail_descr(deadframe, failindex)
+ def assembler_helper(deadframe, virtualizable):
x = self.cpu.get_float_value(deadframe, 0)
assert longlong.getrealfloat(x) == 1.2 + 3.2
called.append(self.cpu.get_latest_descr(deadframe))
print '!' * 30 + 'assembler_helper'
return 13.5
- FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF,
+ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF,
llmemory.GCREF],
lltype.Float))
class FakeJitDriverSD:
@@ -2856,8 +2851,6 @@
FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
EffectInfo.MOST_GENERAL)
- for _ in range(10):
- self.cpu.reserve_some_free_fail_descr_number()
ops = '''
[f0, f1]
f2 = float_add(f0, f1)
@@ -2890,8 +2883,8 @@
# test the fast path, which should not call assembler_helper()
del called[:]
- self.cpu.done_with_this_frame_float_v = self.cpu.get_fail_descr_number(
- finish_descr)
+ prev_descr = self.cpu.done_with_this_frame_descr_float
+ self.cpu.done_with_this_frame_descr_float = finish_descr
try:
othertoken = JitCellToken()
self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
@@ -2902,7 +2895,7 @@
assert longlong.getrealfloat(x) == 1.2 + 4.2
assert not called
finally:
- del self.cpu.done_with_this_frame_float_v
+ self.cpu.done_with_this_frame_descr_float = prev_descr
def test_raw_malloced_getarrayitem(self):
ARRAY = rffi.CArray(lltype.Signed)
@@ -2932,15 +2925,13 @@
if not self.cpu.supports_floats:
py.test.skip("requires floats")
called = []
- def assembler_helper(failindex, deadframe, virtualizable):
- self.cpu.store_fail_descr(deadframe, failindex)
+ def assembler_helper(deadframe, virtualizable):
x = self.cpu.get_float_value(deadframe, 0)
assert longlong.getrealfloat(x) == 1.25 + 3.25
called.append(self.cpu.get_latest_descr(deadframe))
return 13.5
- FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed,
- llmemory.GCREF, llmemory.GCREF],
+ FUNCPTR = lltype.Ptr(lltype.FuncType([llmemory.GCREF, llmemory.GCREF],
lltype.Float))
class FakeJitDriverSD:
index_of_virtualizable = -1
@@ -2953,8 +2944,6 @@
FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES,
EffectInfo.MOST_GENERAL)
- for _ in range(10):
- self.cpu.reserve_some_free_fail_descr_number()
ops = '''
[f0, f1]
f2 = float_add(f0, f1)
@@ -3347,8 +3336,7 @@
def test_memoryerror(self):
excdescr = BasicFailDescr(666)
- self.cpu.propagate_exception_v = self.cpu.get_fail_descr_number(
- excdescr)
+ self.cpu.propagate_exception_descr = excdescr
self.cpu.setup_once() # xxx redo it, because we added
# propagate_exception_v
i0 = BoxInt()
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
@@ -249,7 +249,7 @@
self.malloc_slowpath2 = rawstart
def _build_propagate_exception_path(self):
- if self.cpu.propagate_exception_v < 0:
+ if not self.cpu.propagate_exception_descr:
return # not supported (for tests, or non-translated)
#
self.mc = codebuf.MachineCodeBlockWrapper()
@@ -259,7 +259,12 @@
self._store_and_reset_exception(eax)
ofs = self.cpu.get_ofs_of_frame_field('jf_guard_exc')
self.mc.MOV_br(ofs, eax.value)
- self.mc.MOV_ri(eax.value, self.cpu.propagate_exception_v)
+ propagate_exception_descr = rffi.cast(lltype.Signed,
+ cast_instance_to_gcref(self.cpu.propagate_exception_descr))
+ ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
+ base_ofs = self.cpu.get_baseofs_of_frame_field()
+ self.mc.MOV_bi(ofs, propagate_exception_descr)
+ self.mc.LEA_rb(eax.value, -base_ofs)
#
self._call_footer()
rawstart = self.mc.materialize(self.cpu.asmmemmgr, [])
@@ -268,7 +273,7 @@
def _build_stack_check_slowpath(self):
_, _, slowpathaddr = self.cpu.insert_stack_check()
- if slowpathaddr == 0 or self.cpu.propagate_exception_v < 0:
+ if slowpathaddr == 0 or not self.cpu.propagate_exception_descr:
return # no stack check (for tests, or non-translated)
xxx
#
@@ -554,15 +559,13 @@
# Arguments should be unique
assert len(set(inputargs)) == len(inputargs)
- descr_number = self.cpu.get_fail_descr_number(faildescr)
-
self.setup(original_loop_token)
+ descr_number = compute_unique_id(faildescr)
if log:
operations = self._inject_debugging_code(faildescr, operations,
'b', descr_number)
- descr = self.cpu.get_fail_descr_from_number(descr_number)
- arglocs = self.rebuild_faillocs_from_descr(descr, inputargs)
+ arglocs = self.rebuild_faillocs_from_descr(faildescr, inputargs)
regalloc = RegAlloc(self, self.cpu.translate_support_code)
startpos = self.mc.get_relative_pos()
operations = regalloc.prepare_bridge(inputargs, arglocs,
@@ -575,7 +578,7 @@
#
rawstart = self.materialize_loop(original_loop_token)
debug_start("jit-backend-addr")
- debug_print("bridge out of Guard %d has address %x to %x" %
+ debug_print("bridge out of Guard %x has address %x to %x" %
(descr_number, rawstart, rawstart + codeendpos))
debug_stop("jit-backend-addr")
self.patch_pending_failure_recoveries(rawstart)
@@ -1980,10 +1983,9 @@
def _store_force_index(self, guard_op):
faildescr = guard_op.getdescr()
- fail_index = self.cpu.get_fail_descr_number(faildescr)
- ofs = self.cpu.get_ofs_of_frame_field('jf_force_index')
- self.mc.MOV_bi(ofs, fail_index)
- return fail_index
+ ofs = self.cpu.get_ofs_of_frame_field('jf_force_descr')
+ self.mc.MOV_bi(ofs, rffi.cast(lltype.Signed,
+ cast_instance_to_gcref(faildescr)))
def _emit_guard_not_forced(self, guard_token):
ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
@@ -1992,8 +1994,8 @@
def genop_guard_call_may_force(self, op, guard_op, guard_token,
arglocs, result_loc):
- fail_index = self._store_force_index(guard_op)
- self._genop_call(op, arglocs, result_loc, fail_index)
+ self._store_force_index(guard_op)
+ self._genop_call(op, arglocs, result_loc, -1)
self._emit_guard_not_forced(guard_token)
def genop_guard_call_release_gil(self, op, guard_op, guard_token,
@@ -2126,21 +2128,24 @@
[argloc], 0, tmp=eax)
if op.result is None:
assert result_loc is None
- value = self.cpu.done_with_this_frame_void_v
+ value = self.cpu.done_with_this_frame_descr_void
else:
kind = op.result.type
if kind == INT:
assert result_loc is eax
- value = self.cpu.done_with_this_frame_int_v
+ value = self.cpu.done_with_this_frame_descr_int
elif kind == REF:
assert result_loc is eax
- value = self.cpu.done_with_this_frame_ref_v
+ value = self.cpu.done_with_this_frame_descr_ref
elif kind == FLOAT:
- value = self.cpu.done_with_this_frame_float_v
+ value = self.cpu.done_with_this_frame_descr_float
else:
raise AssertionError(kind)
- self.mc.CMP_ri(eax.value, value)
+ value = rffi.cast(lltype.Signed, cast_instance_to_gcref(value))
+ base_ofs = self.cpu.get_baseofs_of_frame_field()
+ ofs = self.cpu.get_ofs_of_frame_field('jf_descr')
+ self.mc.CMP_mi((eax.value, base_ofs + ofs), value)
# patched later
self.mc.J_il8(rx86.Conditions['E'], 0) # goto B if we get
'done_with_this_frame'
je_location = self.mc.get_relative_pos()
@@ -2150,7 +2155,7 @@
assert jd is not None
asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
self._emit_call(fail_index, imm(asm_helper_adr),
- [eax, frame_loc, imm0], 0, tmp=ecx)
+ [eax, imm0], 0, tmp=ecx)
if IS_X86_32 and isinstance(result_loc, StackLoc) and result_loc.type
== FLOAT:
self.mc.FSTPL_b(result_loc.value)
#else: result_loc is already either eax or None, checked below
@@ -2175,8 +2180,6 @@
#
if op.result is not None:
# load the return value from the dead frame's value index 0
- assert isinstance(frame_loc, StackLoc)
- self.mc.MOV_rb(eax.value, frame_loc.value)
kind = op.result.type
if kind == FLOAT:
_, descr = self.cpu.getarraydescr_for_frame(kind, 0)
diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -160,9 +160,7 @@
descr = self.gc_ll_descr.getframedescrs(self).arraydescr
ofs = self.unpack_arraydescr(descr)
frame = rffi.cast(jitframe.JITFRAMEPTR, addr_of_force_token - ofs)
- fail_index = frame.jf_force_index
- faildescr = self.get_fail_descr_from_number(fail_index)
- frame.jf_descr = cast_instance_to_gcref(faildescr)
+ frame.jf_descr = frame.jf_force_descr
return frame
def redirect_call_assembler(self, oldlooptoken, newlooptoken):
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -459,7 +459,7 @@
exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef()
# pseudo loop tokens to make the life of optimize.py easier
- return {'loop_tokens_done_with_this_frame_int': [
+ d = {'loop_tokens_done_with_this_frame_int': [
TerminatingLoopToken(1, done_with_this_frame_descr_int)
],
'loop_tokens_done_with_this_frame_ref': [
@@ -474,7 +474,9 @@
'loop_tokens_exit_frame_with_exception_ref': [
TerminatingLoopToken(1, exit_frame_with_exception_descr_ref)
],
- }
+ }
+ d.update(locals())
+ return d
class ResumeDescr(AbstractFailDescr):
pass
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1475,7 +1475,7 @@
jd.propagate_exc_descr = exc_descr
#
num = self.cpu.get_fail_descr_number(exc_descr)
- self.cpu.propagate_exception_v = num
+ self.cpu.propagate_exc_descr = exc_descr
#
self.globaldata = MetaInterpGlobalData(self)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit