Commit afba831b authored by Stefan Behnel's avatar Stefan Behnel

speed up access to module globals

parent 34ded093
...@@ -1615,7 +1615,6 @@ class NameNode(AtomicExprNode): ...@@ -1615,7 +1615,6 @@ class NameNode(AtomicExprNode):
self.is_temp = 0 self.is_temp = 0
else: else:
self.is_temp = 1 self.is_temp = 1
env.use_utility_code(get_name_interned_utility_code)
self.is_used_as_rvalue = 1 self.is_used_as_rvalue = 1
elif entry.type.is_memoryviewslice: elif entry.type.is_memoryviewslice:
...@@ -1754,28 +1753,37 @@ class NameNode(AtomicExprNode): ...@@ -1754,28 +1753,37 @@ class NameNode(AtomicExprNode):
interned_cname)) interned_cname))
code.putln('if (unlikely(!%s)) {' % self.result()) code.putln('if (unlikely(!%s)) {' % self.result())
code.putln('PyErr_Clear();') code.putln('PyErr_Clear();')
code.globalstate.use_utility_code(
UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
code.putln( code.putln(
'%s = __Pyx_GetName(%s, %s);' % ( '%s = __Pyx_GetModuleGlobalName(%s);' % (
self.result(), self.result(),
Naming.module_cname,
interned_cname)) interned_cname))
if not self.cf_is_null: if not self.cf_is_null:
code.putln("}") code.putln("}")
code.putln(code.error_goto_if_null(self.result(), self.pos)) code.putln(code.error_goto_if_null(self.result(), self.pos))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
elif entry.is_pyglobal or entry.is_builtin: elif entry.is_builtin:
assert entry.type.is_pyobject, "Python global or builtin not a Python object" assert entry.type.is_pyobject, "Python global or builtin not a Python object"
interned_cname = code.intern_identifier(self.entry.name) interned_cname = code.intern_identifier(self.entry.name)
if entry.is_builtin:
namespace = Naming.builtins_cname
else: # entry.is_pyglobal
namespace = entry.scope.namespace_cname
code.globalstate.use_utility_code(get_name_interned_utility_code) code.globalstate.use_utility_code(get_name_interned_utility_code)
code.putln( code.putln(
'%s = __Pyx_GetName(%s, %s); %s' % ( '%s = __Pyx_GetName(%s, %s); %s' % (
self.result(), self.result(),
namespace, Naming.builtins_cname,
interned_cname,
code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result())
elif entry.is_pyglobal:
assert entry.type.is_pyobject, "Python global or builtin not a Python object"
interned_cname = code.intern_identifier(self.entry.name)
code.globalstate.use_utility_code(
UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
code.putln(
'%s = __Pyx_GetModuleGlobalName(%s); %s' % (
self.result(),
interned_cname, interned_cname,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
......
...@@ -571,6 +571,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -571,6 +571,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put(Nodes.branch_prediction_macros) code.put(Nodes.branch_prediction_macros)
code.putln('') code.putln('')
code.putln('static PyObject *%s;' % env.module_cname) code.putln('static PyObject *%s;' % env.module_cname)
code.putln('static PyObject *%s;' % env.module_dict_cname)
code.putln('static PyObject *%s;' % Naming.builtins_cname) code.putln('static PyObject *%s;' % Naming.builtins_cname)
code.putln('static PyObject *%s;' % Naming.empty_tuple) code.putln('static PyObject *%s;' % Naming.empty_tuple)
code.putln('static PyObject *%s;' % Naming.empty_bytes) code.putln('static PyObject *%s;' % Naming.empty_bytes)
...@@ -2182,6 +2183,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2182,6 +2183,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
Naming.pymoduledef_cname)) Naming.pymoduledef_cname))
code.putln("#endif") code.putln("#endif")
code.putln(code.error_goto_if_null(env.module_cname, self.pos)) code.putln(code.error_goto_if_null(env.module_cname, self.pos))
code.putln(
"%s = PyModule_GetDict(%s); %s" % (
env.module_dict_cname, env.module_cname,
code.error_goto_if_null(env.module_dict_cname, self.pos)))
code.put_incref(env.module_dict_cname, py_object_type, nanny=False)
# CPython may not have put us into sys.modules yet, but relative imports and reimports require it # CPython may not have put us into sys.modules yet, but relative imports and reimports require it
fq_module_name = env.qualified_name fq_module_name = env.qualified_name
......
...@@ -5734,10 +5734,10 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -5734,10 +5734,10 @@ class ForFromStatNode(LoopNode, StatNode):
target_node = ExprNodes.PyTempNode(self.target.pos, None) target_node = ExprNodes.PyTempNode(self.target.pos, None)
target_node.allocate(code) target_node.allocate(code)
interned_cname = code.intern_identifier(self.target.entry.name) interned_cname = code.intern_identifier(self.target.entry.name)
code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code) code.globalstate.use_utility_code(
code.putln("%s = __Pyx_GetName(%s, %s); %s" % ( UtilityCode.load_cached("GetModuleGlobalName", "ObjectHandling.c"))
code.putln("%s = __Pyx_GetModuleGlobalName(%s); %s" % (
target_node.result(), target_node.result(),
Naming.module_cname,
interned_cname, interned_cname,
code.error_goto_if_null(target_node.result(), self.target.pos))) code.error_goto_if_null(target_node.result(), self.target.pos)))
code.put_gotref(target_node.result()) code.put_gotref(target_node.result())
......
...@@ -606,6 +606,39 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { ...@@ -606,6 +606,39 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
return result; return result;
} }
/////////////// GetModuleGlobalName.proto ///////////////
static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name); /*proto*/
/////////////// GetModuleGlobalName ///////////////
//@requires: PyObjectGetAttrStr
//@substitute: naming
static CYTHON_INLINE PyObject *__Pyx_GetModuleGlobalName(PyObject *name) {
PyObject *result;
#if CYTHON_COMPILING_IN_CPYTHON
result = PyDict_GetItem($moddict_cname, name);
if (result) {
Py_INCREF(result);
} else {
#else
result = PyObject_GetItem($moddict_cname, name);
if (!result) {
PyErr_Clear();
#endif
result = __Pyx_PyObject_GetAttrStr($builtins_cname, name);
if (unlikely(!result)) {
PyErr_Format(PyExc_NameError,
#if PY_MAJOR_VERSION >= 3
"name '%U' is not defined", name);
#else
"name '%s' is not defined", PyString_AS_STRING(name));
#endif
}
}
return result;
}
/////////////// PyObjectGetAttrStr.proto /////////////// /////////////// PyObjectGetAttrStr.proto ///////////////
#if CYTHON_COMPILING_IN_CPYTHON #if CYTHON_COMPILING_IN_CPYTHON
......
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