[pypy-commit] pypy resume-refactor: revive clone if mutable, unfortunately needed

fijal noreply at buildbot.pypy.org
Wed Jan 29 10:25:10 CET 2014


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: resume-refactor
Changeset: r68987:3190114e9b0a
Date: 2014-01-29 10:24 +0100
http://bitbucket.org/pypy/pypy/changeset/3190114e9b0a/

Log:	revive clone if mutable, unfortunately needed

diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -347,8 +347,6 @@
         assert isinstance(frame, LLFrame)
         assert frame.forced_deadframe is None
         values = {}
-        import pdb
-        pdb.set_trace()
         for k, v in frame.lltrace.numbering.iteritems():
             try:
                 values[v] = frame.env[k]
diff --git a/rpython/jit/codewriter/jitcode.py b/rpython/jit/codewriter/jitcode.py
--- a/rpython/jit/codewriter/jitcode.py
+++ b/rpython/jit/codewriter/jitcode.py
@@ -102,8 +102,6 @@
     def __repr__(self):
         return '<JitCode %r>' % self.name
 
-    def _clone_if_mutable(self):
-        raise NotImplementedError
 
 class MissingLiveness(Exception):
     pass
diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py
--- a/rpython/jit/metainterp/compile.py
+++ b/rpython/jit/metainterp/compile.py
@@ -483,8 +483,8 @@
     _counters = None    # they get stored in _counters then.
 
     # the following attributes are used by the resume
-    rd_loop = None # keeping the loop alive
     rd_bytecode_position = -1 # position in the generated bytecode
+    rd_resume_bytecode = None
 
     CNT_BASE_MASK  =  0x0FFFFFFF     # the base counter value
     CNT_BUSY_FLAG  =  0x10000000     # if set, busy tracing from the guard
@@ -494,7 +494,7 @@
     CNT_REF        =  0x40000000
     CNT_FLOAT      =  0x60000000
 
-    def store_final_boxes(self, guard_op, boxes):
+    def set_opnum(self, guard_op):
         self.guard_opnum = guard_op.getopnum()
 
     def make_a_counter_per_value(self, guard_value_op):
@@ -618,11 +618,27 @@
                                new_loop.operations,
                                new_loop.original_jitcell_token)
 
+    def copy_all_attributes_into(self, res):
+        # XXX a bit ugly to have to list them all here
+        res.rd_resume_bytecode = self.rd_resume_bytecode
+        res.rd_bytecode_position = self.rd_bytecode_position
+
+    def _clone_if_mutable(self):
+        res = ResumeGuardDescr()
+        self.copy_all_attributes_into(res)
+        return res
+
 class ResumeGuardNotInvalidated(ResumeGuardDescr):
-    pass
+    def _clone_if_mutable(self):
+        res = ResumeGuardNotInvalidated()
+        self.copy_all_attributes_into(res)
+        return res
 
 class ResumeAtPositionDescr(ResumeGuardDescr):
-    pass
+    def _clone_if_mutable(self):
+        res = ResumeAtPositionDescr()
+        self.copy_all_attributes_into(res)
+        return res
 
 class AllVirtuals:
     llopaque = True
@@ -705,6 +721,12 @@
         hidden_all_virtuals = obj.hide(metainterp_sd.cpu)
         metainterp_sd.cpu.set_savedata_ref(deadframe, hidden_all_virtuals)
 
+    def _clone_if_mutable(self):
+        res = ResumeGuardForcedDescr(self.metainterp_sd,
+                                     self.jitdriver_sd)
+        self.copy_all_attributes_into(res)
+        return res
+
 
 class AbstractResumeGuardCounters(object):
     # Completely custom algorithm for now: keep 5 pairs (value, counter),
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
@@ -133,6 +133,14 @@
     def repr_of_descr(self):
         return '%r' % (self,)
 
+    def _clone_if_mutable(self):
+        return self
+    def clone_if_mutable(self):
+        clone = self._clone_if_mutable()
+        if not we_are_translated():
+            assert clone.__class__ is self.__class__
+        return clone
+
     def hide(self, cpu):
         descr_ptr = cpu.ts.cast_instance_to_base_ref(self)
         return cpu.ts.cast_to_ref(descr_ptr)
diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py
--- a/rpython/jit/metainterp/optimizeopt/optimizer.py
+++ b/rpython/jit/metainterp/optimizeopt/optimizer.py
@@ -557,6 +557,8 @@
                 self.replace_op(self.replaces_guard[op], op)
                 del self.replaces_guard[op]
                 return
+            else:
+                op = self.fixup_guard(op, pendingfields)
             self.resumebuilder.guard_seen(op, pendingfields)
         elif op.can_raise():
             self.exception_might_have_happened = True
@@ -577,19 +579,11 @@
         else:
             assert False
 
-    def store_final_boxes_in_guard(self, op, pendingfields):
-        xxx
+    def fixup_guard(self, op, pendingfields):
         assert pendingfields is not None
         descr = op.getdescr()
         assert isinstance(descr, compile.ResumeGuardDescr)
-        modifier = resume.ResumeDataVirtualAdder(descr, self.resumedata_memo)
-        try:
-            newboxes = modifier.finish(self, pendingfields)
-            if len(newboxes) > self.metainterp_sd.options.failargs_limit:
-                raise resume.TagOverflow
-        except resume.TagOverflow:
-            raise compile.giveup()
-        descr.store_final_boxes(op, newboxes)
+        descr.set_opnum(op)
         #
         if op.getopnum() == rop.GUARD_VALUE:
             if self.getvalue(op.getarg(0)) in self.bool_boxes:
@@ -605,7 +599,6 @@
                 else:
                     raise AssertionError("uh?")
                 newop = ResOperation(opnum, [op.getarg(0)], op.result, descr)
-                newop.setfailargs(op.getfailargs())
                 return newop
             else:
                 # a real GUARD_VALUE.  Make it use one counter per value.
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -167,7 +167,7 @@
         jump_args = [self.getvalue(a).get_key_box() for a in original_jump_args]
 
         assert self.optimizer.loop.resume_at_jump_descr
-        resume_at_jump_descr = self.optimizer.loop.resume_at_jump_descr
+        resume_at_jump_descr = self.optimizer.loop.resume_at_jump_descr.clone_if_mutable()
         assert isinstance(resume_at_jump_descr, ResumeGuardDescr)
 
         modifier = VirtualStateAdder(self.optimizer)
@@ -416,7 +416,7 @@
             if op.is_guard():
                 op = op.clone()
                 op.setfailargs(None)
-                descr = target_token.resume_at_jump_descr
+                descr = target_token.resume_at_jump_descr.clone_if_mutable()
                 op.setdescr(descr)
                 short[i] = op
 
@@ -439,7 +439,7 @@
             if op.result and op.result in self.short_boxes.assumed_classes:
                 target_token.assumed_classes[newop.result] = self.short_boxes.assumed_classes[op.result]
             short[i] = newop
-        target_token.resume_at_jump_descr = target_token.resume_at_jump_descr
+        target_token.resume_at_jump_descr = target_token.resume_at_jump_descr.clone_if_mutable()
 
         # Forget the values to allow them to be freed
         for box in short[0].getarglist():
@@ -483,7 +483,7 @@
             if not isinstance(a, Const) and a not in self.short_seen:
                 self.add_op_to_short(self.short_boxes.producer(a), emit, guards_needed)
         if op.is_guard():
-            descr = self.short_resume_at_jump_descr
+            descr = self.short_resume_at_jump_descr.clone_if_mutable()
             op.setdescr(descr)
 
         if guards_needed and self.short_boxes.has_producer(op.result):
@@ -582,7 +582,7 @@
 
                 for guard in extra_guards:
                     if guard.is_guard():
-                        descr = target.resume_at_jump_descr
+                        descr = target.resume_at_jump_descr.clone_if_mutable()
                         inliner.inline_descr_inplace(descr)
                         guard.setdescr(descr)
                     self.optimizer.send_extra_operation(guard)
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -80,6 +80,8 @@
     def clone(self):
         args = self.getarglist()
         descr = self.getdescr()
+        if descr is not None:
+            descr = descr.clone_if_mutable()
         op = ResOperation(self.getopnum(), args[:], self.result, descr)
         if not we_are_translated():
             op.name = self.name
diff --git a/rpython/jit/metainterp/test/test_loop.py b/rpython/jit/metainterp/test/test_loop.py
--- a/rpython/jit/metainterp/test/test_loop.py
+++ b/rpython/jit/metainterp/test/test_loop.py
@@ -189,10 +189,6 @@
             found = 0
             for op in get_stats().loops[0]._all_operations():
                 if op.getopname() == 'guard_true':
-                    liveboxes = op.getfailargs()
-                    assert len(liveboxes) == 2     # x, y (in some order)
-                    assert isinstance(liveboxes[0], history.BoxInt)
-                    assert isinstance(liveboxes[1], history.BoxInt)
                     found += 1
             if 'unroll' in self.enable_opts:
                 assert found == 2
diff --git a/rpython/jit/resume/frontend.py b/rpython/jit/resume/frontend.py
--- a/rpython/jit/resume/frontend.py
+++ b/rpython/jit/resume/frontend.py
@@ -154,9 +154,18 @@
                                                 None, None)
             return virtual_box
 
+    def getkind(self, fielddescr):
+        if fielddescr.is_pointer_field():
+            return REF
+        elif fielddescr.is_float_field():
+            return FLOAT
+        else:
+            assert fielddescr.is_field_signed()
+            return INT
+        
     def setfield_gc(self, box, encoded_field_pos, fielddescr):
         field_box = self.get_box_value(-1, -1, encoded_field_pos,
-                                       fielddescr.kind)
+                                       self.getkind(fielddescr))
         self.metainterp.execute_and_record(rop.SETFIELD_GC, fielddescr,
                                            box, field_box)
 
@@ -173,6 +182,7 @@
         miframe.registers_r[i] = box
 
     def store_float_box(self, frame_pos, pos, miframe, i, jitframe_pos):
+        xxx
         box = self.get_box_value(jitframe_pos)
         if box is None:
             return
diff --git a/rpython/jit/resume/reader.py b/rpython/jit/resume/reader.py
--- a/rpython/jit/resume/reader.py
+++ b/rpython/jit/resume/reader.py
@@ -32,7 +32,7 @@
         self.fields = {}
 
     def allocate_box(self, metainterp):
-        return metainterp.execute_and_record(rop.NEW_WITH_VTABLE,
+        return metainterp.execute_and_record(rop.NEW_WITH_VTABLE, None,
                                              ConstInt(self.const_class))
 
     def allocate_direct(self, cpu):
@@ -176,6 +176,9 @@
     def resume_new(self, v_pos, descr):
         self.l.append("%d = resume_new %d" % (v_pos, descr.global_descr_index))
 
+    def resume_clear(self, frame_pos, pos_in_frame):
+        self.l.append("resume_clear %d %d" % (frame_pos, pos_in_frame))
+
     def resume_new_with_vtable(self, v_pos, c_const_class):
         self.l.append("%d = resume_new_with_vtable %d" % (v_pos,
                                                 c_const_class.getint()))


More information about the pypy-commit mailing list