[pypy-svn] pypy numpy-exp: Refactor virtualizable.py to actually allow multiple jits with virtualizables
fijal
commits-noreply at bitbucket.org
Sun Feb 13 16:16:01 CET 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-exp
Changeset: r41877:e211d75bf89f
Date: 2011-02-11 22:02 +0200
http://bitbucket.org/pypy/pypy/changeset/e211d75bf89f/
Log: Refactor virtualizable.py to actually allow multiple jits with
virtualizables in one compiled executable
diff --git a/pypy/jit/metainterp/resume.py b/pypy/jit/metainterp/resume.py
--- a/pypy/jit/metainterp/resume.py
+++ b/pypy/jit/metainterp/resume.py
@@ -1007,17 +1007,16 @@
return len(numb.nums)
index = len(numb.nums) - 1
virtualizable = self.decode_ref(numb.nums[index])
- virtualizable = vinfo.cast_gcref_to_vtype(virtualizable)
if self.resume_after_guard_not_forced == 1:
# in the middle of handle_async_forcing()
- assert virtualizable.vable_token
- virtualizable.vable_token = vinfo.TOKEN_NONE
+ assert vinfo.gettoken(virtualizable)
+ vinfo.settoken(virtualizable, vinfo.TOKEN_NONE)
else:
# just jumped away from assembler (case 4 in the comment in
# virtualizable.py) into tracing (case 2); check that vable_token
# is and stays 0. Note the call to reset_vable_token() in
# warmstate.py.
- assert not virtualizable.vable_token
+ assert not vinfo.gettoken(virtualizable)
return vinfo.write_from_resume_data_partial(virtualizable, self, numb)
def load_value_of_type(self, TYPE, tagged):
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
@@ -2151,7 +2151,7 @@
# warmstate.py.
virtualizable_box = self.virtualizable_boxes[-1]
virtualizable = vinfo.unwrap_virtualizable_box(virtualizable_box)
- assert not virtualizable.vable_token
+ assert not vinfo.gettoken(virtualizable)
# fill the virtualizable with the local boxes
self.synchronize_virtualizable()
#
diff --git a/pypy/jit/metainterp/test/test_ztranslation.py b/pypy/jit/metainterp/test/test_ztranslation.py
--- a/pypy/jit/metainterp/test/test_ztranslation.py
+++ b/pypy/jit/metainterp/test/test_ztranslation.py
@@ -29,6 +29,12 @@
def __init__(self, i):
self.i = i
+ class OtherFrame(object):
+ _virtualizable2_ = ['i']
+
+ def __init__(self, i):
+ self.i = i
+
class JitCellCache:
entry = None
jitcellcache = JitCellCache()
@@ -61,18 +67,20 @@
frame.i -= 1
return total * 10
#
- myjitdriver2 = JitDriver(greens = ['g'], reds = ['m', 'x', 's'])
+ myjitdriver2 = JitDriver(greens = ['g'], reds = ['m', 's', 'f'],
+ virtualizables = ['f'])
def f2(g, m, x):
s = ""
+ f = OtherFrame(x)
while m > 0:
- myjitdriver2.can_enter_jit(g=g, m=m, x=x, s=s)
- myjitdriver2.jit_merge_point(g=g, m=m, x=x, s=s)
+ myjitdriver2.can_enter_jit(g=g, m=m, f=f, s=s)
+ myjitdriver2.jit_merge_point(g=g, m=m, f=f, s=s)
s += 'xy'
if s[:2] == 'yz':
return -666
m -= 1
- x += 3
- return x
+ f.i += 3
+ return f.i
#
def main(i, j):
return f(i) - f2(i+j, i, j)
@@ -124,9 +132,7 @@
type_system=self.type_system,
optimizer=OPTIMIZER_FULL,
ProfilerClass=Profiler)
- assert res == main(40)
-
-
+ assert res == main(40)
class TestTranslationLLtype(TranslationTest):
diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py
--- a/pypy/jit/metainterp/virtualizable.py
+++ b/pypy/jit/metainterp/virtualizable.py
@@ -1,4 +1,4 @@
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
from pypy.rpython import rvirtualizable2
@@ -8,7 +8,7 @@
from pypy.jit.metainterp.typesystem import deref, fieldType, arrayItem
from pypy.jit.metainterp import history
from pypy.jit.metainterp.warmstate import wrap, unwrap
-
+from pypy.rlib.objectmodel import specialize
class VirtualizableInfo:
TOKEN_NONE = 0 # must be 0 -- see also x86.call_assembler
@@ -76,6 +76,8 @@
setarrayitem = cpu.ts.setarrayitem
#
def read_boxes(cpu, virtualizable):
+ assert lltype.typeOf(virtualizable) == llmemory.GCREF
+ virtualizable = cast_gcref_to_vtype(virtualizable)
boxes = []
for _, fieldname in unroll_static_fields:
x = getattr(virtualizable, fieldname)
@@ -87,6 +89,7 @@
return boxes
#
def write_boxes(virtualizable, boxes):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
i = 0
for FIELDTYPE, fieldname in unroll_static_fields:
x = unwrap(FIELDTYPE, boxes[i])
@@ -101,6 +104,7 @@
assert len(boxes) == i + 1
#
def write_from_resume_data_partial(virtualizable, reader, numb):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
# Load values from the reader (see resume.py) described by
# the list of numbers 'nums', and write them in their proper
# place in the 'virtualizable'. This works from the end of
@@ -124,6 +128,7 @@
return i
#
def load_list_of_boxes(virtualizable, reader, numb):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
# Uses 'virtualizable' only to know the length of the arrays;
# does not write anything into it. The returned list is in
# the format expected of virtualizable_boxes, so it ends in
@@ -147,6 +152,7 @@
return boxes
#
def check_boxes(virtualizable, boxes):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
# for debugging
i = 0
for FIELDTYPE, fieldname in unroll_static_fields:
@@ -162,6 +168,7 @@
assert len(boxes) == i + 1
#
def get_index_in_array(virtualizable, arrayindex, index):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
index += self.num_static_extra_boxes
j = 0
for _, fieldname in unroll_array_fields:
@@ -173,6 +180,7 @@
assert False, "invalid arrayindex"
#
def get_array_length(virtualizable, arrayindex):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
j = 0
for _, fieldname in unroll_array_fields:
if arrayindex == j:
@@ -197,6 +205,70 @@
self.get_index_in_array = get_index_in_array
self.get_array_length = get_array_length
+ def cast_to_vtype(virtualizable):
+ return self.cpu.ts.cast_to_instance_maybe(VTYPEPTR, virtualizable)
+ self.cast_to_vtype = cast_to_vtype
+
+ def cast_gcref_to_vtype(virtualizable):
+ assert lltype.typeOf(virtualizable) == llmemory.GCREF
+ return lltype.cast_opaque_ptr(VTYPEPTR, virtualizable)
+ self.cast_gcref_to_vtype = cast_gcref_to_vtype
+
+ def reset_vable_token(virtualizable):
+ virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
+ self.reset_vable_token = reset_vable_token
+
+ def clear_vable_token(virtualizable):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
+ if virtualizable.vable_token:
+ force_now(virtualizable)
+ assert not virtualizable.vable_token
+ self.clear_vable_token = clear_vable_token
+
+ def tracing_before_residual_call(virtualizable):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
+ assert not virtualizable.vable_token
+ virtualizable.vable_token = VirtualizableInfo.TOKEN_TRACING_RESCALL
+ self.tracing_before_residual_call = tracing_before_residual_call
+
+ def tracing_after_residual_call(virtualizable):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
+ if virtualizable.vable_token:
+ # not modified by the residual call; assert that it is still
+ # set to TOKEN_TRACING_RESCALL and clear it.
+ assert virtualizable.vable_token == VirtualizableInfo.TOKEN_TRACING_RESCALL
+ virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
+ return False
+ else:
+ # marker "modified during residual call" set.
+ return True
+ self.tracing_after_residual_call = tracing_after_residual_call
+
+ def force_now(virtualizable):
+ token = virtualizable.vable_token
+ if token == VirtualizableInfo.TOKEN_TRACING_RESCALL:
+ # The values in the virtualizable are always correct during
+ # tracing. We only need to reset vable_token to TOKEN_NONE
+ # as a marker for the tracing, to tell it that this
+ # virtualizable escapes.
+ virtualizable.vable_token = VirtualizableInfo.TOKEN_NONE
+ else:
+ from pypy.jit.metainterp.compile import ResumeGuardForcedDescr
+ ResumeGuardForcedDescr.force_now(cpu, token)
+ assert virtualizable.vable_token == VirtualizableInfo.TOKEN_NONE
+ force_now._dont_inline_ = True
+ self.force_now = force_now
+
+ def gettoken(virtualizable):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
+ return virtualizable.vable_token
+ self.gettoken = gettoken
+
+ def settoken(virtualizable, token):
+ virtualizable = cast_gcref_to_vtype(virtualizable)
+ virtualizable.vable_token = token
+ self.settoken = settoken
+
def _freeze_(self):
return True
@@ -216,55 +288,11 @@
all_graphs, self.VTYPEPTR, funcptr)
def unwrap_virtualizable_box(self, virtualizable_box):
- return virtualizable_box.getref(self.VTYPEPTR)
-
- def cast_to_vtype(self, virtualizable):
- return self.cpu.ts.cast_to_instance_maybe(self.VTYPEPTR, virtualizable)
- cast_to_vtype._annspecialcase_ = 'specialize:ll'
-
- def cast_gcref_to_vtype(self, virtualizable):
- return lltype.cast_opaque_ptr(self.VTYPEPTR, virtualizable)
-
+ return virtualizable_box.getref(llmemory.GCREF)
+
def is_vtypeptr(self, TYPE):
return rvirtualizable2.match_virtualizable_type(TYPE, self.VTYPEPTR)
- def reset_vable_token(self, virtualizable):
- virtualizable.vable_token = self.TOKEN_NONE
-
- def clear_vable_token(self, virtualizable):
- if virtualizable.vable_token:
- self.force_now(virtualizable)
- assert not virtualizable.vable_token
-
- def tracing_before_residual_call(self, virtualizable):
- assert not virtualizable.vable_token
- virtualizable.vable_token = self.TOKEN_TRACING_RESCALL
-
- def tracing_after_residual_call(self, virtualizable):
- if virtualizable.vable_token:
- # not modified by the residual call; assert that it is still
- # set to TOKEN_TRACING_RESCALL and clear it.
- assert virtualizable.vable_token == self.TOKEN_TRACING_RESCALL
- virtualizable.vable_token = self.TOKEN_NONE
- return False
- else:
- # marker "modified during residual call" set.
- return True
-
- def force_now(self, virtualizable):
- token = virtualizable.vable_token
- if token == self.TOKEN_TRACING_RESCALL:
- # The values in the virtualizable are always correct during
- # tracing. We only need to reset vable_token to TOKEN_NONE
- # as a marker for the tracing, to tell it that this
- # virtualizable escapes.
- virtualizable.vable_token = self.TOKEN_NONE
- else:
- from pypy.jit.metainterp.compile import ResumeGuardForcedDescr
- ResumeGuardForcedDescr.force_now(self.cpu, token)
- assert virtualizable.vable_token == self.TOKEN_NONE
- force_now._dont_inline_ = True
-
# ____________________________________________________________
#
# The 'vable_token' field of a virtualizable is either 0, -1, or points
More information about the Pypy-commit
mailing list