1.1 --- a/optimiser.py Thu Oct 13 23:27:17 2016 +0200
1.2 +++ b/optimiser.py Fri Oct 14 18:34:14 2016 +0200
1.3 @@ -82,7 +82,6 @@
1.4 self.position_parameters()
1.5 self.populate_tables()
1.6 self.populate_constants()
1.7 - self.refine_access_plans()
1.8 self.initialise_access_instructions()
1.9
1.10 def to_output(self):
1.11 @@ -113,6 +112,7 @@
1.12
1.13 location " " name " " test " " test type " " base
1.14 " " traversed attributes " " traversed attribute ambiguity
1.15 + " " traversal access modes
1.16 " " attributes to traverse " " attribute ambiguity
1.17 " " context " " access method " " static attribute
1.18
1.19 @@ -120,6 +120,9 @@
1.20
1.21 qualified name of scope "." local name ":" name version
1.22
1.23 + Traversal access modes are either "class" (obtain accessor class to
1.24 + access attribute) or "object" (obtain attribute directly from accessor).
1.25 +
1.26 ----
1.27
1.28 The structures are presented as a table in the following format:
1.29 @@ -195,28 +198,6 @@
1.30 finally:
1.31 f.close()
1.32
1.33 - f = open(join(self.output, "attribute_plans"), "w")
1.34 - try:
1.35 - access_plans = self.access_plans.items()
1.36 - access_plans.sort()
1.37 -
1.38 - for location, (name, test, test_type, base,
1.39 - traversed, traversed_ambiguity,
1.40 - attrnames, attrnames_ambiguity, context,
1.41 - first_method, final_method, attr) in access_plans:
1.42 -
1.43 - print >>f, encode_access_location(location), \
1.44 - name, test, test_type or "{}", \
1.45 - base or "{}", \
1.46 - ".".join(traversed) or "{}", \
1.47 - ".".join(map(str, traversed_ambiguity)) or "{}", \
1.48 - ".".join(map(str, attrnames_ambiguity)) or "{}", \
1.49 - ".".join(attrnames) or "{}", \
1.50 - context, first_method, final_method, attr or "{}"
1.51 -
1.52 - finally:
1.53 - f.close()
1.54 -
1.55 f = open(join(self.output, "instruction_plans"), "w")
1.56 try:
1.57 access_instructions = self.access_instructions.items()
1.58 @@ -355,25 +336,6 @@
1.59 l.extend([None] * (position - len(l) + 1))
1.60 l[position] = attrname
1.61
1.62 - def refine_access_plans(self):
1.63 -
1.64 - "Augment deduced access plans with attribute position information."
1.65 -
1.66 - for access_location, access_plan in self.deducer.access_plans.items():
1.67 -
1.68 - # Obtain the access details.
1.69 -
1.70 - name, test, test_type, base, traversed, attrnames, \
1.71 - context, first_method, final_method, origin = access_plan
1.72 -
1.73 - traversed_ambiguity = self.get_ambiguity_for_attributes(traversed)
1.74 - attrnames_ambiguity = self.get_ambiguity_for_attributes(attrnames)
1.75 -
1.76 - self.access_plans[access_location] = \
1.77 - name, test, test_type, base, traversed, traversed_ambiguity, \
1.78 - attrnames, attrnames_ambiguity, context, \
1.79 - first_method, final_method, origin
1.80 -
1.81 def initialise_access_instructions(self):
1.82
1.83 "Expand access plans into instruction sequences."
1.84 @@ -382,9 +344,8 @@
1.85
1.86 # Obtain the access details.
1.87
1.88 - name, test, test_type, base, traversed, traversed_ambiguity, \
1.89 - attrnames, attrnames_ambiguity, context, \
1.90 - first_method, final_method, origin = access_plan
1.91 + name, test, test_type, base, traversed, traversal_modes, \
1.92 + attrnames, context, first_method, final_method, origin = access_plan
1.93
1.94 instructions = []
1.95 emit = instructions.append
1.96 @@ -448,14 +409,14 @@
1.97 elif first_method == "check-object":
1.98 emit(("set_accessor", ("check_and_load_via_object", accessor, attrname)))
1.99 elif first_method == "check-object-class":
1.100 - emit(("set_accessor", ("get_class_check_and_load", accessor, attrname)))
1.101 + emit(("set_accessor", ("check_and_load_via_any", accessor, attrname)))
1.102
1.103 # Obtain an accessor.
1.104
1.105 remaining = len(traversed + attrnames)
1.106
1.107 if traversed:
1.108 - for attrname in traversed:
1.109 + for attrname, traversal_mode in zip(traversed, traversal_modes):
1.110
1.111 # Set the context, if appropriate.
1.112
1.113 @@ -465,12 +426,15 @@
1.114 # Perform the access only if not achieved directly.
1.115
1.116 if remaining > 1 or final_method == "access":
1.117 - emit(("set_accessor", ("load_unambiguous", "accessor", attrname)))
1.118 + if traversal_mode == "class":
1.119 + emit(("set_accessor", ("load_via_class", "accessor", attrname)))
1.120 + else:
1.121 + emit(("set_accessor", ("load_via_object", "accessor", attrname)))
1.122
1.123 remaining -= 1
1.124
1.125 if attrnames:
1.126 - for attrname, ambiguity in zip(attrnames, attrnames_ambiguity):
1.127 + for attrname in attrnames:
1.128
1.129 # Set the context, if appropriate.
1.130
1.131 @@ -480,10 +444,7 @@
1.132 # Perform the access only if not achieved directly.
1.133
1.134 if remaining > 1 or final_method == "access":
1.135 - if ambiguity == 1:
1.136 - emit(("set_accessor", ("load_unambiguous", "accessor", attrname)))
1.137 - else:
1.138 - emit(("set_accessor", ("load_ambiguous", "accessor", attrname)))
1.139 + emit(("set_accessor", ("check_and_load_via_any", "accessor", attrname)))
1.140
1.141 remaining -= 1
1.142