Commits

Maciej Fijalkowski committed 3297b30

progress

  • Participants
  • Parent commits 2f37843
  • Branches continulet-jit-3

Comments (0)

Files changed (4)

File pypy/jit/backend/llgraph/runner.py

         class MiniStats:
             pass
         self.stats = stats or MiniStats()
+        self.TOKEN_TRACING_RESCALL = NotAFrame()
 
     def compile_loop(self, inputargs, operations, looptoken, log=True, name=''):
         clt = model.CompiledLoopToken(self, looptoken.number)
     def bh_getfield_gc(self, p, descr):
         if isinstance(descr, JFDescrDescr):
             result = p.latest_descr
+            if result is None:
+                return lltype.nullptr(llmemory.GCREF.TO)
             # <XXX> HACK
             result._TYPE = llmemory.GCREF
             result._identityhash = lambda: hash(result)   # for rd_hash()
             # <XXX/>
-            return p.latest_descr
+            return result
         p = support.cast_arg(lltype.Ptr(descr.S), p)
         return support.cast_result(descr.FIELD, getattr(p, descr.fieldname))
 
     def bh_read_timestamp(self):
         return read_timestamp()
 
+class NotAFrame(object):
+    _TYPE = llmemory.GCREF
+
+    class latest_descr:
+        pass
+
+    def __eq__(self, other):
+        return isinstance(other, NotAFrame)
+    def __ne__(self, other):
+        return not (self == other)
+
 class LLFrame(object):
     _TYPE = llmemory.GCREF
+    latest_descr = None
 
     # some obscure hacks to support comparison with llmemory.GCREF
     def __ne__(self, other):

File pypy/jit/metainterp/pyjitpl.py

         if not self._establish_nullity(jfbox, orgpc):
             return      # jfbox is NULL
         cpu = self.metainterp.cpu
+        if jfbox.getref_base() == cpu.TOKEN_TRACING_RESCALL:
+            # we're trying to force a virtualizable that is being traced,
+            # abort as bad loop
+            raise SwitchToBlackhole(Counters.ABORT_BAD_LOOP)
         descr = cpu.jitframe_get_jfdescr_descr()
         jfdescrbox = self._opimpl_getfield_gc_any(jfbox, descr)
         jfdescrbox = self.implement_guard_value(orgpc, jfdescrbox)

File pypy/jit/metainterp/virtualizable.py

     def __init__(self, warmrunnerdesc, VTYPEPTR):
         self.warmrunnerdesc = warmrunnerdesc
         cpu = warmrunnerdesc.cpu
+        self.TOKEN_TRACING_RESCALL = cpu.TOKEN_TRACING_RESCALL
         if cpu.ts.name == 'ootype':
             import py
             py.test.skip("ootype: fix virtualizables")
         def tracing_before_residual_call(virtualizable):
             virtualizable = cast_gcref_to_vtype(virtualizable)
             assert virtualizable.jit_frame == jitframe.TOKEN_NONE
-            virtualizable.jit_frame = jitframe.TOKEN_TRACING_RESCALL
+            virtualizable.jit_frame = self.TOKEN_TRACING_RESCALL
         self.tracing_before_residual_call = tracing_before_residual_call
 
         def tracing_after_residual_call(virtualizable):
             if virtualizable.jit_frame != jitframe.TOKEN_NONE:
                 # not modified by the residual call; assert that it is still
                 # set to TOKEN_TRACING_RESCALL and clear it.
-                assert virtualizable.jit_frame == jitframe.TOKEN_TRACING_RESCALL
+                assert virtualizable.jit_frame == self.TOKEN_TRACING_RESCALL
                 virtualizable.jit_frame = jitframe.TOKEN_NONE
                 return False
             else:
 
         def force_now(virtualizable):
             token = virtualizable.jit_frame
-            if token == jitframe.TOKEN_TRACING_RESCALL:
+            if token == self.TOKEN_TRACING_RESCALL:
                 # The values in the virtualizable are always correct during
                 # tracing.  We only need to reset jit_frame to TOKEN_NONE
                 # as a marker for the tracing, to tell it that this

File pypy/jit/metainterp/virtualref.py

     def __init__(self, warmrunnerdesc):
         self.warmrunnerdesc = warmrunnerdesc
         self.cpu = warmrunnerdesc.cpu
+        self.TOKEN_TRACING_RESCALL = self.cpu.TOKEN_TRACING_RESCALL
         # we make the low-level type of an RPython class directly
         self.JIT_VIRTUAL_REF = lltype.GcStruct('JitVirtualRef',
             ('super', rclass.OBJECT),
             return
         vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref)
         assert vref.jit_frame == jitframe.TOKEN_NONE
-        vref.jit_frame = jitframe.TOKEN_TRACING_RESCALL
+        vref.jit_frame = self.TOKEN_TRACING_RESCALL
 
     def tracing_after_residual_call(self, gcref):
         if not self.is_virtual_ref(gcref):
         if vref.jit_frame != jitframe.TOKEN_NONE:
             # not modified by the residual call; assert that it is still
             # set to TOKEN_TRACING_RESCALL and clear it.
-            assert vref.jit_frame == jitframe.TOKEN_TRACING_RESCALL
+            assert vref.jit_frame == self.TOKEN_TRACING_RESCALL
             vref.jit_frame = jitframe.TOKEN_NONE
             return False
         else:
             return
         assert real_object
         vref = lltype.cast_opaque_ptr(lltype.Ptr(self.JIT_VIRTUAL_REF), gcref)
-        assert vref.jit_frame != jitframe.TOKEN_TRACING_RESCALL
+        assert vref.jit_frame != self.TOKEN_TRACING_RESCALL
         vref.jit_frame = jitframe.TOKEN_NONE
         vref.forced = lltype.cast_opaque_ptr(rclass.OBJECTPTR, real_object)
 
         vref = lltype.cast_pointer(lltype.Ptr(self.JIT_VIRTUAL_REF), inst)
         token = vref.jit_frame
         if token != jitframe.TOKEN_NONE:
-            if token == jitframe.TOKEN_TRACING_RESCALL:
+            if token == self.TOKEN_TRACING_RESCALL:
                 # The "virtual" is not a virtual at all during tracing.
                 # We only need to reset jit_frame to TOKEN_NONE
                 # as a marker for the tracing, to tell it that this