# HG changeset patch # User Paul Boddie # Date 1201564871 -3600 # Node ID 3f372b5e291a4d9e4ec6642995982dbc964a3925 # Parent 86d7a399f63968dfd1d43852e5634c717cd7a6a3 Tidied and clarified the "safe containers" and constant attributes text, adding notes about single assignment restrictions. Expanded the method optimisation section. diff -r 86d7a399f639 -r 3f372b5e291a README.txt --- a/README.txt Mon Jan 28 01:15:01 2008 +0100 +++ b/README.txt Tue Jan 29 01:01:11 2008 +0100 @@ -188,25 +188,28 @@ The discussion below presents certain rules which must be imposed to uphold the above requirements. -Constant Attributes -------------------- +Safe Containers +--------------- Where attributes of modules, classes and instances are only set once and are effectively constant, it should be possible to circumvent the attribute lookup mechanism and to directly reference the attribute value. This technique may -only be considered applicable in the following cases for "container" objects: +only be considered applicable for the following "container" objects, subject +to the noted constraints: - 1. For modules, provided that assignments to module attributes are only - permitted within the module itself either at the top-level or via names - declared as globals. Thus, the following would not be permitted: + 1. For modules, "safety" is enforced by ensuring that assignments to module + attributes are only permitted within the module itself either at the + top-level or via names declared as globals. Thus, the following would not + be permitted: another_module.this_module.attr = value In the above, this_module is a reference to the current module. - 2. For classes, provided that assignments to class attributes are only - permitted within the class definition, outside methods. This would mean - that classes would be "sealed" at definition time (like functions). + 2. For classes, "safety" is enforced by ensuring that assignments to class + attributes are only permitted within the class definition, outside + methods. This would mean that classes would be "sealed" at definition time + (like functions). Unlike the property of function locals that they may only sensibly be accessed within the function in which they reside, these cases demand additional @@ -214,12 +217,29 @@ would be difficult to detect eligible attributes on arbitrary instances due to the need for some kind of type inference or abstract execution. -Where (1) and (2) apply, any attribute with only one recorded assignment on it -can be considered a constant attribute and this eligible for this -optimisation, the consequence of which would be the replacement of a -LoadAttrIndex instruction (which needs to look up an attribute using the -run-time details of the "container" and the compile-time details of the -attribute) with a LoadAttr instruction. +Constant Attributes +------------------- + +When accessed via "safe containers", as described above, any attribute with +only one recorded assignment on it can be considered a constant attribute and +this eligible for optimisation, the consequence of which would be the +replacement of a LoadAttrIndex instruction (which needs to look up an +attribute using the run-time details of the "container" and the compile-time +details of the attribute) with a LoadAttr instruction. + +However, some restrictions exist on assignment operations which may be +regarded to cause only one assignment in the lifetime of a program: + + 1. For module attributes, only assignments at the top-level outside loop + statements can be reliably assumed to cause only a single assignment. + + 2. For class attributes, only assignments at the top-level within class + definitions and outside loop statements can be reliably assumed to cause + only a single assignment. + +All assignments satisfying the "safe container" requirements, but not the +requirements immediately above, should each be recorded as causing at least +one assignment. Additional Controls ------------------- @@ -327,6 +347,31 @@ d = D() # D is not related to C C.f(d) # calling f(self) in C +If blatant usage of incompatible instances were somehow disallowed, it would +still be necessary to investigate the properties of an instance's class and +its relationship with other classes. Consider the following example: + + class A: + def f(self): ... + + class B: + def f(self): ... + def g(self): + self.f() + + class C(A, B): + pass + +Here, instances of B passed into the method B.g could be assumed to provide +access to B.f when self.f is resolved at compile-time. However, instances of C +passed into B.g would instead provide access to A.f when self.f is resolved at +compile-time (since the method resolution order is C, A, B instead of just B). + +One solution might be to specialise methods for each instance type, but this +could be costly. Another less ambitious solution might only involve the +optimisation of such internal method calls if an unambiguous target can be +resolved. + Optimising Function Invocations -------------------------------