File: rvirtualizable.py

package info (click to toggle)
pypy 7.0.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 107,216 kB
  • sloc: python: 1,201,787; ansic: 62,419; asm: 5,169; cpp: 3,017; sh: 2,534; makefile: 545; xml: 243; lisp: 45; awk: 4
file content (75 lines) | stat: -rw-r--r-- 3,227 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from rpython.rtyper.rmodel import inputconst, log
from rpython.rtyper.lltypesystem import lltype, llmemory
from rpython.rtyper.rclass import (FieldListAccessor, InstanceRepr)


class VirtualizableInstanceRepr(InstanceRepr):

    def _super(self):
        return super(VirtualizableInstanceRepr, self)

    def __init__(self, rtyper, classdef):
        self._super().__init__(rtyper, classdef)
        classdesc = classdef.classdesc
        if classdesc.get_param('_virtualizable2_'):
            raise Exception("_virtualizable2_ is now called _virtualizable_, "
                            "please rename")
        if classdesc.get_param('_virtualizable_', inherit=False):
            basedesc = classdesc.basedesc
            assert (basedesc is None or
                    basedesc.get_param('_virtualizable_') is None)
            self.top_of_virtualizable_hierarchy = True
            self.accessor = FieldListAccessor()
        else:
            self.top_of_virtualizable_hierarchy = False

    def _setup_repr_llfields(self):
        llfields = []
        if self.top_of_virtualizable_hierarchy:
            llfields.append(('vable_token', llmemory.GCREF))
        return llfields

    def _setup_repr(self):
        if self.top_of_virtualizable_hierarchy:
            hints = {'virtualizable_accessor': self.accessor}
            llfields = self._setup_repr_llfields()
            if llfields:
                self._super()._setup_repr(llfields, hints=hints)
            else:
                self._super()._setup_repr(hints = hints)
            vfields = self.classdef.classdesc.get_param('_virtualizable_')
            self.my_redirected_fields = self._parse_field_list(
                vfields, self.accessor, hints)
        else:
            self._super()._setup_repr()
            # ootype needs my_redirected_fields even for subclass. lltype does
            # not need it, but it doesn't hurt to have it anyway
            self.my_redirected_fields = self.rbase.my_redirected_fields

    def hook_access_field(self, vinst, cname, llops, flags):
        # if not flags.get('access_directly'):
        if self.my_redirected_fields.get(cname.value):
            cflags = inputconst(lltype.Void, flags)
            llops.genop('jit_force_virtualizable', [vinst, cname, cflags])


def replace_force_virtualizable_with_call(graphs, VTYPEPTR, funcptr):
    # funcptr should be a function pointer with a VTYPEPTR argument
    c_funcptr = inputconst(lltype.typeOf(funcptr), funcptr)
    count = 0
    for graph in graphs:
        for block in graph.iterblocks():
            if not block.operations:
                continue
            newoplist = []
            for i, op in enumerate(block.operations):
                if (op.opname == 'jit_force_virtualizable' and
                        op.args[0].concretetype == VTYPEPTR):
                    if op.args[-1].value.get('access_directly', False):
                        continue
                    op.opname = 'direct_call'
                    op.args = [c_funcptr, op.args[0]]
                    count += 1
                newoplist.append(op)
            block.operations = newoplist
    log("replaced %d 'jit_force_virtualizable' with %r" % (count, funcptr))