[pypy-commit] pypy inline-virtualref-2: start implementing, mostly works, two remaining issues:
alex_gaynor
noreply at buildbot.pypy.org
Wed Jan 23 14:41:45 CET 2013
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: inline-virtualref-2
Changeset: r60372:b6915c54d1d2
Date: 2013-01-23 05:41 -0800
http://bitbucket.org/pypy/pypy/changeset/b6915c54d1d2/
Log: start implementing, mostly works, two remaining issues:
1) Tests fail because check_resops looks at entry + loop, want only
loop. 2) Trace still contains: force_token, guard_no_exception, and
guard_not_forced
diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -79,9 +79,11 @@
OS_RAW_MALLOC_VARSIZE = 110
OS_RAW_FREE = 111
+ OS_JIT_FORCE_VIRTUAL = 120
+
# for debugging:
_OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL,
- OS_RAW_MALLOC_VARSIZE])
+ OS_RAW_MALLOC_VARSIZE, OS_JIT_FORCE_VIRTUAL])
def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays,
write_descrs_fields, write_descrs_arrays,
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1393,6 +1393,8 @@
elif oopspec_name == 'jit.isvirtual':
kind = getkind(args[0].concretetype)
return SpaceOperation('%s_isvirtual' % kind, args, op.result)
+ elif oopspec_name == 'jit.force_virtual':
+ return self._handle_oopspec_call(op, args, EffectInfo.OS_JIT_FORCE_VIRTUAL, EffectInfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE)
else:
raise AssertionError("missing support for %r" % oopspec_name)
diff --git a/rpython/jit/codewriter/support.py b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -1,24 +1,24 @@
import sys
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory
-from rpython.rtyper.ootypesystem import ootype
-from rpython.rtyper import rlist
-from rpython.rtyper.lltypesystem import rstr as ll_rstr, rdict as ll_rdict
-from rpython.rtyper.lltypesystem.module import ll_math
-from rpython.rtyper.lltypesystem.lloperation import llop
-from rpython.rtyper.ootypesystem import rdict as oo_rdict
-from rpython.rtyper.llinterp import LLInterpreter
-from rpython.rtyper.extregistry import ExtRegistryEntry
-from rpython.translator.simplify import get_funcobj
-from rpython.translator.unsimplify import split_block
+
+from rpython.annotator import model as annmodel
+from rpython.annotator.policy import AnnotatorPolicy
from rpython.flowspace.model import Variable, Constant
-from rpython.translator.translator import TranslationContext
-from rpython.annotator.policy import AnnotatorPolicy
-from rpython.annotator import model as annmodel
-from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
from rpython.jit.metainterp.typesystem import deref
from rpython.rlib import rgc
-from rpython.rlib.jit import elidable
+from rpython.rlib.jit import elidable, oopspec
from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint, intmask
+from rpython.rtyper import rlist
+from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
+from rpython.rtyper.extregistry import ExtRegistryEntry
+from rpython.rtyper.llinterp import LLInterpreter
+from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory, rstr as ll_rstr, rdict as ll_rdict
+from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rtyper.lltypesystem.module import ll_math
+from rpython.rtyper.ootypesystem import ootype, rdict as oo_rdict
+from rpython.translator.simplify import get_funcobj
+from rpython.translator.translator import TranslationContext
+from rpython.translator.unsimplify import split_block
+
def getargtypes(annotator, values):
if values is None: # for backend tests producing stand-alone exe's
@@ -213,10 +213,12 @@
_ll_5_list_ll_arraycopy = rgc.ll_arraycopy
+
@elidable
def _ll_1_gc_identityhash(x):
return lltype.identityhash(x)
+
# the following function should not be "@elidable": I can think of
# a corner case in which id(const) is constant-folded, and then 'const'
# disappears and is collected too early (possibly causing another object
@@ -224,6 +226,8 @@
def _ll_1_gc_id(ptr):
return llop.gc_id(lltype.Signed, ptr)
+
+ at oopspec("jit.force_virtual(inst)")
def _ll_1_jit_force_virtual(inst):
return llop.jit_force_virtual(lltype.typeOf(inst), inst)
diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -978,11 +978,9 @@
def get_all_jitcell_tokens(self):
tokens = [t() for t in self.jitcell_token_wrefs]
if None in tokens:
- assert False, "get_all_jitcell_tokens will not work as "+\
- "loops have been freed"
+ assert False, ("get_all_jitcell_tokens will not work as "
+ "loops have been freed")
return tokens
-
-
def check_history(self, expected=None, **check):
insns = {}
diff --git a/rpython/jit/metainterp/optimizeopt/virtualize.py b/rpython/jit/metainterp/optimizeopt/virtualize.py
--- a/rpython/jit/metainterp/optimizeopt/virtualize.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualize.py
@@ -1,12 +1,13 @@
+from rpython.jit.codewriter.effectinfo import EffectInfo
+from rpython.jit.metainterp.executor import execute
from rpython.jit.codewriter.heaptracker import vtable2descr
-from rpython.jit.metainterp.executor import execute
from rpython.jit.metainterp.history import Const, ConstInt, BoxInt
from rpython.jit.metainterp.optimizeopt import optimizer
+from rpython.jit.metainterp.optimizeopt.optimizer import OptValue
from rpython.jit.metainterp.optimizeopt.util import (make_dispatcher_method,
descrlist_dict, sort_descrs)
from rpython.jit.metainterp.resoperation import rop, ResOperation
from rpython.rlib.objectmodel import we_are_translated
-from rpython.jit.metainterp.optimizeopt.optimizer import OptValue
class AbstractVirtualValue(optimizer.OptValue):
@@ -386,6 +387,14 @@
self.make_equal_to(box, vvalue)
return vvalue
+ def optimize_CALL_MAY_FORCE(self, op):
+ effectinfo = op.getdescr().get_extra_info()
+ oopspecindex = effectinfo.oopspecindex
+ if oopspecindex == EffectInfo.OS_JIT_FORCE_VIRTUAL:
+ if self._optimize_JIT_FORCE_VIRTUAL(op):
+ return
+ self.emit_operation(op)
+
def optimize_VIRTUAL_REF(self, op):
indexbox = op.getarg(1)
#
@@ -429,7 +438,7 @@
# - set 'virtual_token' to TOKEN_NONE
args = [op.getarg(0), ConstInt(vrefinfo.TOKEN_NONE)]
seo(ResOperation(rop.SETFIELD_GC, args, None,
- descr = vrefinfo.descr_virtual_token))
+ descr=vrefinfo.descr_virtual_token))
# Note that in some cases the virtual in op.getarg(1) has been forced
# already. This is fine. In that case, and *if* a residual
# CALL_MAY_FORCE suddenly turns out to access it, then it will
@@ -437,6 +446,19 @@
# will work too (but just be a little pointless, as the structure
# was already forced).
+ def _optimize_JIT_FORCE_VIRTUAL(self, op):
+ vref = self.getvalue(op.getarg(1))
+ vrefinfo = self.optimizer.metainterp_sd.virtualref_info
+ if vref.is_virtual():
+ tokenvalue = vref.getfield(vrefinfo.descr_virtual_token, None)
+ if (tokenvalue is not None and tokenvalue.is_constant() and
+ tokenvalue.box.getint() == vrefinfo.TOKEN_NONE):
+ forcedvalue = vref.getfield(vrefinfo.descr_forced, None)
+ if forcedvalue is not None:
+ self.make_equal_to(op.result, forcedvalue)
+ return True
+ return False
+
def optimize_GETFIELD_GC(self, op):
value = self.getvalue(op.getarg(0))
# If this is an immutable field (as indicated by op.is_always_pure())
diff --git a/rpython/jit/metainterp/test/support.py b/rpython/jit/metainterp/test/support.py
--- a/rpython/jit/metainterp/test/support.py
+++ b/rpython/jit/metainterp/test/support.py
@@ -160,16 +160,17 @@
class JitMixin:
basic = True
+
def check_resops(self, expected=None, **check):
get_stats().check_resops(expected=expected, **check)
+
def check_simple_loop(self, expected=None, **check):
get_stats().check_simple_loop(expected=expected, **check)
-
-
def check_trace_count(self, count): # was check_loop_count
# The number of traces compiled
assert get_stats().compiled_count == count
+
def check_trace_count_at_most(self, count):
assert get_stats().compiled_count <= count
@@ -178,11 +179,12 @@
def check_target_token_count(self, count):
tokens = get_stats().get_all_jitcell_tokens()
- n = sum ([len(t.target_tokens) for t in tokens])
+ n = sum([len(t.target_tokens) for t in tokens])
assert n == count
def check_enter_count(self, count):
assert get_stats().enter_count == count
+
def check_enter_count_at_most(self, count):
assert get_stats().enter_count <= count
@@ -192,6 +194,7 @@
def check_aborted_count(self, count):
assert get_stats().aborted_count == count
+
def check_aborted_count_at_least(self, count):
assert get_stats().aborted_count >= count
diff --git a/rpython/jit/metainterp/test/test_virtualref.py b/rpython/jit/metainterp/test/test_virtualref.py
--- a/rpython/jit/metainterp/test/test_virtualref.py
+++ b/rpython/jit/metainterp/test/test_virtualref.py
@@ -680,7 +680,7 @@
return n
res = self.meta_interp(f, [10])
assert res == 0
- self.check_resops({'int_sub': 1, 'int_gt': 1, 'jump': 1})
+ self.check_resops({'int_sub': 1, 'int_gt': 1, 'jump': 1, 'guard_true': 1})
class TestLLtype(VRefTests, LLJitMixin):
More information about the pypy-commit
mailing list