Commit e159ce51 authored by Robert Bradshaw's avatar Robert Bradshaw

Further optimizations on tp_clear/traverse

parent 6d16147e
...@@ -712,21 +712,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -712,21 +712,29 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"}") "}")
def generate_traverse_function(self, scope, code): def generate_traverse_function(self, scope, code):
tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
slot_func = scope.mangle_internal("tp_traverse")
base_type = scope.parent_type.base_type base_type = scope.parent_type.base_type
if tp_slot.slot_code(scope) != slot_func:
return # never used
code.putln("") code.putln("")
code.putln( code.putln(
"static int %s(PyObject *o, visitproc v, void *a) {" "static int %s(PyObject *o, visitproc v, void *a) {"
% scope.mangle_internal("tp_traverse")) % slot_func)
py_attrs = [] py_attrs = []
for entry in scope.var_entries: for entry in scope.var_entries:
if entry.type.is_pyobject and entry.name != "__weakref__": if entry.type.is_pyobject and entry.name != "__weakref__":
py_attrs.append(entry) py_attrs.append(entry)
if base_type or py_attrs: if base_type or py_attrs:
code.putln( code.putln("int e;")
"int e;")
if py_attrs: if py_attrs:
self.generate_self_cast(scope, code) self.generate_self_cast(scope, code)
if base_type: if base_type:
# want to call it explicitly if possible so inlining can be performed
parent_slot = tp_slot.slot_code(base_type.scope)
if scope.parent_scope is base_type.scope.parent_scope and parent_slot != '0':
code.putln("e = %s(o, v, a); if (e) return e;" % parent_slot)
else:
code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname) code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
code.putln( code.putln(
"e = %s->tp_traverse(o, v, a); if (e) return e;" % "e = %s->tp_traverse(o, v, a); if (e) return e;" %
...@@ -750,11 +758,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -750,11 +758,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
"}") "}")
def generate_clear_function(self, scope, code): def generate_clear_function(self, scope, code):
tp_slot = TypeSlots.GCDependentSlot("tp_clear")
slot_func = scope.mangle_internal("tp_clear")
base_type = scope.parent_type.base_type base_type = scope.parent_type.base_type
if tp_slot.slot_code(scope) != slot_func:
return # never used
code.putln("") code.putln("")
code.putln( code.putln("static int %s(PyObject *o) {" % slot_func)
"static int %s(PyObject *o) {"
% scope.mangle_internal("tp_clear"))
py_attrs = [] py_attrs = []
for entry in scope.var_entries: for entry in scope.var_entries:
if entry.type.is_pyobject and entry.name != "__weakref__": if entry.type.is_pyobject and entry.name != "__weakref__":
...@@ -763,10 +773,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -763,10 +773,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_self_cast(scope, code) self.generate_self_cast(scope, code)
code.putln("PyObject* tmp;") code.putln("PyObject* tmp;")
if base_type: if base_type:
# want to call it explicitly if possible so inlining can be performed
parent_slot = tp_slot.slot_code(base_type.scope)
if scope.parent_scope is base_type.scope.parent_scope and parent_slot != '0':
code.putln("%s(o);" % parent_slot)
else:
code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname) code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
code.putln( code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
"%s->tp_clear(o);" %
base_type.typeptr_cname)
code.putln("}") code.putln("}")
for entry in py_attrs: for entry in py_attrs:
name = "p->%s" % entry.cname name = "p->%s" % entry.cname
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment