[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