Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: optinfo-into-bridges
Changeset: r87804:55bfa972b650
Date: 2016-10-14 15:46 +0200
http://bitbucket.org/pypy/pypy/changeset/55bfa972b650/

Log:    factor out resumecode decoding into a Reader class instead of
        passing indexes everywhere

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
@@ -141,14 +141,13 @@
     def get_register_index_f(self, index):
         return ord(self.live_f[index])
 
-    def enumerate_vars(self, callback_i, callback_r, callback_f, spec, index):
+    def enumerate_vars(self, callback_i, callback_r, callback_f, spec):
         for i in range(self.get_register_count_i()):
-            index = callback_i(index, self.get_register_index_i(i))
+            callback_i(self.get_register_index_i(i))
         for i in range(self.get_register_count_r()):
-            index = callback_r(index, self.get_register_index_r(i))
+            callback_r(self.get_register_index_r(i))
         for i in range(self.get_register_count_f()):
-            index = callback_f(index, self.get_register_index_f(i))
-        return index
+            callback_f(self.get_register_index_f(i))
     enumerate_vars._annspecialcase_ = 'specialize:arg(4)'
 
 _liveness_cache = {}
diff --git a/rpython/jit/metainterp/optimizeopt/bridgeopt.py 
b/rpython/jit/metainterp/optimizeopt/bridgeopt.py
--- a/rpython/jit/metainterp/optimizeopt/bridgeopt.py
+++ b/rpython/jit/metainterp/optimizeopt/bridgeopt.py
@@ -1,7 +1,7 @@
 """ Code to feed information from the optimizer via the resume code into the
 optimizer of the bridge attached to a guard. """
 
-from rpython.jit.metainterp.resumecode import numb_next_item, 
numb_next_n_items, unpack_numbering
+from rpython.jit.metainterp import resumecode
 
 # XXX at the moment this is all quite ad-hoc. Could be delegated to the
 # different optimization passes
@@ -81,6 +81,7 @@
         for box1, descr, box2 in triples:
             index = metainterp_sd.descrs_dct.get(descr, -1)
             if index == -1:
+                # XXX XXX XXX fix length!
                 continue # just skip it, if the descr is not encodable
             numb_state.append_short(tag_box(box1, liveboxes_from_env, memo))
             numb_state.append_int(index)
@@ -90,12 +91,13 @@
         numb_state.append_int(0)
 
 def deserialize_optimizer_knowledge(optimizer, resumestorage, frontend_boxes, 
liveboxes):
+    reader = resumecode.Reader(resumestorage.rd_numb)
     assert len(frontend_boxes) == len(liveboxes)
-    numb = resumestorage.rd_numb
     metainterp_sd = optimizer.metainterp_sd
 
     # skip resume section
-    index = skip_resume_section(numb, optimizer)
+    startcount = reader.next_item()
+    reader.jump(startcount - 1)
 
     # class knowledge
     bitfield = 0
@@ -104,7 +106,7 @@
         if box.type != "r":
             continue
         if not mask:
-            bitfield, index = numb_next_item(numb, index)
+            bitfield = reader.next_item()
             mask = 0b100000
         class_known = bitfield & mask
         mask >>= 1
@@ -113,19 +115,15 @@
             optimizer.make_constant_class(box, cls)
 
     # heap knowledge
-    length, index = numb_next_item(numb, index)
+    length = reader.next_item()
     result = []
     for i in range(length):
-        tagged, index = numb_next_item(numb, index)
+        tagged = reader.next_item()
         box1 = decode_box(resumestorage, tagged, liveboxes, metainterp_sd.cpu)
-        tagged, index = numb_next_item(numb, index)
+        tagged = reader.next_item()
         descr = metainterp_sd.opcode_descrs[tagged]
-        tagged, index = numb_next_item(numb, index)
+        tagged = reader.next_item()
         box2 = decode_box(resumestorage, tagged, liveboxes, metainterp_sd.cpu)
         result.append((box1, descr, box2))
     if optimizer.optheap:
         optimizer.optheap.deserialize_optheap(result)
-
-def skip_resume_section(numb, optimizer):
-    startcount, index = numb_next_item(numb, 0)
-    return numb_next_n_items(numb, startcount, 0)
diff --git a/rpython/jit/metainterp/resume.py b/rpython/jit/metainterp/resume.py
--- a/rpython/jit/metainterp/resume.py
+++ b/rpython/jit/metainterp/resume.py
@@ -950,12 +950,9 @@
 
     def _init(self, cpu, storage):
         self.cpu = cpu
-        self.numb = storage.rd_numb
-        count, self.cur_index = resumecode.numb_next_item(
-            self.numb, 0)
-        # XXX inefficient
-        self.size_resume_section = resumecode.numb_next_n_items(
-            self.numb, count, 0)
+        self.resumecodereader = resumecode.Reader(storage.rd_numb)
+        count = self.resumecodereader.next_item()
+        self.items_resume_section = count
         self.count = storage.rd_count
         self.consts = storage.rd_consts
 
@@ -964,14 +961,12 @@
         self._prepare_pendingfields(storage.rd_pendingfields)
 
     def read_jitcode_pos_pc(self):
-        jitcode_pos, self.cur_index = resumecode.numb_next_item(self.numb,
-            self.cur_index)
-        pc, self.cur_index = resumecode.numb_next_item(self.numb,
-            self.cur_index)
+        jitcode_pos = self.resumecodereader.next_item()
+        pc = self.resumecodereader.next_item()
         return jitcode_pos, pc
 
     def done_reading(self):
-        return self.cur_index >= self.size_resume_section
+        return self.resumecodereader.items_read >= self.items_resume_section
 
     def getvirtual_ptr(self, index):
         # Returns the index'th virtual, building it lazily if needed.
@@ -1048,29 +1043,25 @@
     def _prepare_next_section(self, info):
         # Use info.enumerate_vars(), normally dispatching to
         # rpython.jit.codewriter.jitcode.  Some tests give a different 'info'.
-        self.cur_index = info.enumerate_vars(self._callback_i,
-                                        self._callback_r,
-                                        self._callback_f,
-                                        self.unique_id,  # <-- annotation hack
-                                        self.cur_index)
+        info.enumerate_vars(self._callback_i,
+                            self._callback_r,
+                            self._callback_f,
+                            self.unique_id)  # <-- annotation hack
 
-    def _callback_i(self, index, register_index):
-        item, index = resumecode.numb_next_item(self.numb, index)
+    def _callback_i(self, register_index):
+        item = self.resumecodereader.next_item()
         value = self.decode_int(item)
         self.write_an_int(register_index, value)
-        return index
 
-    def _callback_r(self, index, register_index):
-        item, index = resumecode.numb_next_item(self.numb, index)
+    def _callback_r(self, register_index):
+        item = self.resumecodereader.next_item()
         value = self.decode_ref(item)
         self.write_a_ref(register_index, value)
-        return index
 
-    def _callback_f(self, index, register_index):
-        item, index = resumecode.numb_next_item(self.numb, index)
+    def _callback_f(self, register_index):
+        item = self.resumecodereader.next_item()
         value = self.decode_float(item)
         self.write_a_float(register_index, value)
-        return index
 
 # ---------- when resuming for pyjitpl.py, make boxes ----------
 
@@ -1109,42 +1100,33 @@
         self.boxes_f = boxes_f
         self._prepare_next_section(info)
 
-    def consume_virtualizable_boxes(self, vinfo, index):
+    def consume_virtualizable_boxes(self, vinfo):
         # we have to ignore the initial part of 'nums' (containing vrefs),
         # find the virtualizable from nums[-1], and use it to know how many
         # boxes of which type we have to return.  This does not write
         # anything into the virtualizable.
-        numb = self.numb
-        item, index = resumecode.numb_next_item(numb, index)
+        item = self.resumecodereader.next_item()
         virtualizablebox = self.decode_ref(item)
         virtualizable = vinfo.unwrap_virtualizable_box(virtualizablebox)
-        return vinfo.load_list_of_boxes(virtualizable, self, virtualizablebox,
-            numb, index)
+        return vinfo.load_list_of_boxes(virtualizable, self, virtualizablebox)
 
-    def consume_virtualref_boxes(self, index):
+    def consume_virtualref_boxes(self):
         # Returns a list of boxes, assumed to be all BoxPtrs.
         # We leave up to the caller to call vrefinfo.continue_tracing().
-        size, index = resumecode.numb_next_item(self.numb, index)
-        if size == 0:
-            return [], index
-        lst = []
-        for i in range(size * 2):
-            item, index = resumecode.numb_next_item(self.numb, index)
-            lst.append(self.decode_ref(item))
-        return lst, index
+        size = self.resumecodereader.next_item()
+        return [self.decode_ref(self.resumecodereader.next_item())
+                    for i in range(size * 2)]
 
     def consume_vref_and_vable_boxes(self, vinfo, ginfo):
-        vable_size, index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+        vable_size = self.resumecodereader.next_item()
         if vinfo is not None:
-            virtualizable_boxes, index = 
self.consume_virtualizable_boxes(vinfo,
-                                                                          
index)
+            virtualizable_boxes = self.consume_virtualizable_boxes(vinfo)
         elif ginfo is not None:
-            item, index = resumecode.numb_next_item(self.numb, index)
+            item = self.resumecodereader.next_item()
             virtualizable_boxes = [self.decode_ref(item)]
         else:
             virtualizable_boxes = None
-        virtualref_boxes, index = self.consume_virtualref_boxes(index)
-        self.cur_index = index
+        virtualref_boxes = self.consume_virtualref_boxes()
         return virtualizable_boxes, virtualref_boxes
 
     def allocate_with_vtable(self, descr=None):
@@ -1421,30 +1403,26 @@
         info = blackholeinterp.get_current_position_info()
         self._prepare_next_section(info)
 
-    def consume_virtualref_info(self, vrefinfo, index):
+    def consume_virtualref_info(self, vrefinfo):
         # we have to decode a list of references containing pairs
         # [..., virtual, vref, ...] and returns the index at the end
-        size, index = resumecode.numb_next_item(self.numb, index)
+        size = self.resumecodereader.next_item()
         if vrefinfo is None or size == 0:
             assert size == 0
-            return index
+            return
         for i in range(size):
-            virtual_item, index = resumecode.numb_next_item(
-                self.numb, index)
-            vref_item, index = resumecode.numb_next_item(
-                self.numb, index)
+            virtual_item = self.resumecodereader.next_item()
+            vref_item = self.resumecodereader.next_item()
             virtual = self.decode_ref(virtual_item)
             vref = self.decode_ref(vref_item)
             # For each pair, we store the virtual inside the vref.
             vrefinfo.continue_tracing(vref, virtual)
-        return index
 
-    def consume_vable_info(self, vinfo, index):
+    def consume_vable_info(self, vinfo):
         # we have to ignore the initial part of 'nums' (containing vrefs),
         # find the virtualizable from nums[-1], load all other values
         # from the CPU stack, and copy them into the virtualizable
-        numb = self.numb
-        item, index = resumecode.numb_next_item(self.numb, index)
+        item = self.resumecodereader.next_item()
         virtualizable = self.decode_ref(item)
         # just reset the token, we'll force it later
         vinfo.reset_token_gcref(virtualizable)
@@ -1467,18 +1445,17 @@
     load_value_of_type._annspecialcase_ = 'specialize:arg(1)'
 
     def consume_vref_and_vable(self, vrefinfo, vinfo, ginfo):
-        vable_size, index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+        vable_size = self.resumecodereader.next_item()
         if self.resume_after_guard_not_forced != 2:
             if vinfo is not None:
-                index = self.consume_vable_info(vinfo, index)
+                self.consume_vable_info(vinfo)
             if ginfo is not None:
-                _, index = resumecode.numb_next_item(self.numb, index)
-            index = self.consume_virtualref_info(vrefinfo, index)
+                _ = self.resumecodereader.next_item()
+            self.consume_virtualref_info(vrefinfo)
         else:
-            index = resumecode.numb_next_n_items(self.numb, vable_size, index)
-            vref_size, index = resumecode.numb_next_item(self.numb, index)
-            index = resumecode.numb_next_n_items(self.numb, vref_size * 2, 
index)
-        self.cur_index = index 
+            self.resumecodereader.jump(vable_size)
+            vref_size = self.resumecodereader.next_item()
+            self.resumecodereader.jump(vref_size * 2)
 
     def allocate_with_vtable(self, descr=None):
         from rpython.jit.metainterp.executor import exec_new_with_vtable
diff --git a/rpython/jit/metainterp/resumecode.py 
b/rpython/jit/metainterp/resumecode.py
--- a/rpython/jit/metainterp/resumecode.py
+++ b/rpython/jit/metainterp/resumecode.py
@@ -86,3 +86,30 @@
         next, i = numb_next_item(numb, i)
         l.append(next)
     return l
+
+class Reader(object):
+    def __init__(self, code):
+        self.code = code
+        self.cur_pos = 0 # index into the code
+        self.items_read = 0 # number of items read
+
+    def next_item(self):
+        result, self.cur_pos =  numb_next_item(self.code, self.cur_pos)
+        self.items_read += 1
+        return result
+
+    def peek(self):
+        result, _ =  numb_next_item(self.code, self.cur_pos)
+        return result
+
+    def jump(self, size):
+        """ jump n items forward without returning anything """
+        index = self.cur_pos
+        for i in range(size):
+            _, index = numb_next_item(self.code, index)
+        self.items_read += size
+        self.cur_pos = index
+
+    def unpack(self):
+        # mainly for debugging
+        return unpack_numbering(self.code)
diff --git a/rpython/jit/metainterp/test/test_resume.py 
b/rpython/jit/metainterp/test/test_resume.py
--- a/rpython/jit/metainterp/test/test_resume.py
+++ b/rpython/jit/metainterp/test/test_resume.py
@@ -254,18 +254,17 @@
     def get_current_position_info(self):
         class MyInfo:
             @staticmethod
-            def enumerate_vars(callback_i, callback_r, callback_f, _, index):
+            def enumerate_vars(callback_i, callback_r, callback_f, _):
                 count_i = count_r = count_f = 0
                 for ARG in self.ARGS:
                     if ARG == lltype.Signed:
-                        index = callback_i(index, count_i); count_i += 1
+                        callback_i(count_i); count_i += 1
                     elif ARG == llmemory.GCREF:
-                        index = callback_r(index, count_r); count_r += 1
+                        callback_r(count_r); count_r += 1
                     elif ARG == longlong.FLOATSTORAGE:
-                        index = callback_f(index, count_f); count_f += 1
+                        callback_f(count_f); count_f += 1
                     else:
                         assert 0
-                return index
         return MyInfo()
 
     def setarg_i(self, index, value):
@@ -1074,11 +1073,11 @@
     cpu = MyCPU([])
     reader = ResumeDataDirectReader(MyMetaInterp(cpu), storage, "deadframe")
     reader.consume_vref_and_vable(None, None, None)
-    reader.cur_index += 2 # framestack
+    reader.resumecodereader.jump(2) # framestack
     _next_section(reader, sys.maxint, 1, sys.maxint, 2**16)
-    reader.cur_index += 2 # framestack
+    reader.resumecodereader.jump(2) # framestack
     _next_section(reader, 2, 3)
-    reader.cur_index += 2 # framestack
+    reader.resumecodereader.jump(2) # framestack
     _next_section(reader, sys.maxint, 2**16, -65)
 
 def test_virtual_adder_memo_const_sharing():
@@ -1117,9 +1116,10 @@
                 return True
         class MyInfo:
             @staticmethod
-            def enumerate_vars(callback_i, callback_r, callback_f, _, index):
-                while index < max_index:
-                    tagged, _ = resumecode.numb_next_item(self.numb, index)
+            def enumerate_vars(callback_i, callback_r, callback_f, _):
+                index = 0
+                while not self.done_reading():
+                    tagged = self.resumecodereader.peek()
                     _, tag = untag(tagged)
                     if tag == TAGVIRTUAL:
                         kind = REF
@@ -1127,22 +1127,21 @@
                         kind = Whatever()
                     box = self.decode_box(tagged, kind)
                     if box.type == INT:
-                        index = callback_i(index, index)
+                        callback_i(index)
                     elif box.type == REF:
-                        index = callback_r(index, index)
+                        callback_r(index)
                     elif box.type == FLOAT:
-                        index = callback_f(index, index)
+                        callback_f(index)
                     else:
                         assert 0
+                    index += 1
 
-        size_section, self.cur_index = resumecode.numb_next_item(self.numb, 0)
-        max_index = resumecode.numb_next_n_items(self.numb, size_section, 0)
-        size, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+        size = self.resumecodereader.next_item()
         assert size == 0
-        size, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+        size = self.resumecodereader.next_item()
         assert size == 0
-        pc, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
-        jitcode_pos, self.cur_index = resumecode.numb_next_item(self.numb, 
self.cur_index)
+        pc = self.resumecodereader.next_item()
+        jitcode_pos = self.resumecodereader.next_item()
 
         self._prepare_next_section(MyInfo())
         return self.lst
diff --git a/rpython/jit/metainterp/virtualizable.py 
b/rpython/jit/metainterp/virtualizable.py
--- a/rpython/jit/metainterp/virtualizable.py
+++ b/rpython/jit/metainterp/virtualizable.py
@@ -144,7 +144,7 @@
                     setarrayitem(lst, j, x)
             return index
 
-        def load_list_of_boxes(virtualizable, reader, vable_box, numb, index):
+        def load_list_of_boxes(virtualizable, reader, vable_box):
             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
@@ -152,13 +152,13 @@
             # the virtualizable itself.
             boxes = []
             for FIELDTYPE, fieldname in unroll_static_fields:
-                item, index = numb_next_item(numb, index)
+                item = reader.resumecodereader.next_item()
                 box = reader.decode_box_of_type(FIELDTYPE, item)
                 boxes.append(box)
             for ARRAYITEMTYPE, fieldname in unroll_array_fields:
                 lst = getattr(virtualizable, fieldname)
                 for j in range(getlength(lst)):
-                    item, index = numb_next_item(numb, index)                  
  
+                    item = reader.resumecodereader.next_item()
                     box = reader.decode_box_of_type(ARRAYITEMTYPE, item)
                     boxes.append(box)
             boxes.append(vable_box)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to