# HG changeset patch # User Paul Boddie # Date 1267572360 -3600 # Node ID 12bf807e1e08357150b4e59bae3f446ffdee5485 # Parent fbb411daecea835a23a44f1546dbd6266f8110d3 Added an elementary mechanism for estimating the cost of executed instructions, eliminating any cost from the inputs in combined instructions. diff -r fbb411daecea -r 12bf807e1e08 micropython/rsvp.py --- a/micropython/rsvp.py Fri Feb 26 01:56:26 2010 +0100 +++ b/micropython/rsvp.py Wed Mar 03 00:26:00 2010 +0100 @@ -382,99 +382,256 @@ # Access to stored constant data. -class LoadConst(Address): "Load the constant or module from the specified location." -class LoadClass(Address): "Load the class from the specified location." -class LoadFunction(Address): "Load the function from the specified location." +class LoadConst(Address): + "Load the constant or module from the specified location." + cost = 1 + +class LoadClass(Address): + "Load the class from the specified location." + cost = 1 + +class LoadFunction(Address): + "Load the function from the specified location." + cost = 1 # Access within an invocation frame. -class LoadName(FR): "Load the current value from the given local attribute/variable." -class StoreName(FR): "Store the source value into the given local attribute/variable." -class LoadTemp(Immediate): "Load the current value from the given temporary location." -class StoreTemp(Immediate): "Store the current value into the given temporary location." +class LoadName(FR): + "Load the current value from the given local attribute/variable." + cost = 2 + +class StoreName(FR): + "Store the source value into the given local attribute/variable." + cost = 2 + +class LoadTemp(Immediate): + "Load the current value from the given temporary location." + cost = 2 + +class StoreTemp(Immediate): + "Store the current value into the given temporary location." + cost = 2 # Access to static data. -class LoadAddress(Address): "Load the current value from the given fixed attribute address." -class StoreAddress(Address): "Store the source value into the given fixed attribute address." -class LoadAddressContext(Address): "Load the current value from the given fixed attribute address, using the current value as context." -class StoreAddressContext(Address): "Store the current value into the given fixed attribute address, using the current value as context." +class LoadAddress(Address): + "Load the current value from the given fixed attribute address." + cost = 1 + +class StoreAddress(Address): + "Store the source value into the given fixed attribute address." + cost = 1 + +class LoadAddressContext(Address): + "Load the current value from the given fixed attribute address, using the current value as context." + cost = 2 + +class StoreAddressContext(Address): + "Store the current value into the given fixed attribute address, using the current value as context." + cost = 2 + class LoadAddressContextCond(Address): - """Load the current value from the given fixed attribute address, only using the current value as - context if the attribute is compatible.""" -class MakeInstance(Immediate): "Make a new instance using the current value as a reference to a template." -class MakeFragment(Immediate): "Make a new list fragment." + """ + Load the current value from the given fixed attribute address, only using the current value as + context if the attribute is compatible. + """ + cost = 4 + +class MakeInstance(Immediate): + "Make a new instance using the current value as a reference to a template." + cost = 5 + +class MakeFragment(Immediate): + "Make a new list fragment." + cost = 5 # Access to address-relative data. (LoadAttrIndexContext not defined.) -class LoadAttr(AR): "Load into the current value the given attribute of the object referenced by the current value." -class StoreAttr(AR): "Store the source value into the given attribute of the object referenced by the current value." -class LoadAttrIndex(Immediate): "Load into the current value the attribute of the current value with the given index." -class StoreAttrIndex(Immediate): "Store the source value into the attribute of the current value with the given index." +class LoadAttr(AR): + "Load into the current value the given attribute of the object referenced by the current value." + cost = 2 + +class StoreAttr(AR): + "Store the source value into the given attribute of the object referenced by the current value." + cost = 2 + +class LoadAttrIndex(Immediate): + "Load into the current value the attribute of the current value with the given index." + cost = 6 + +class StoreAttrIndex(Immediate): + "Store the source value into the attribute of the current value with the given index." + cost = 6 + class LoadAttrIndexContextCond(Immediate): - """Load into the current value the attribute of the current value with the given index, only making the - current value the context if the attribute is compatible.""" + """ + Load into the current value the attribute of the current value with the given index, only making the + current value the context if the attribute is compatible. + """ + cost = 8 # Access to object details. -class LoadCallable(Instruction): "Load the target of an invocation." -class StoreCallable(Instruction): "Store the source value into the object referenced by the current value." +class LoadCallable(Instruction): + "Load the target of an invocation." + cost = 2 + +class StoreCallable(Instruction): + "Store the source value into the object referenced by the current value." + cost = 3 # Access to invocation frames in preparation. -class MakeFrame(Immediate): "Make a new invocation frame." -class AdjustFrame(Immediate): "Adjust the current invocation frame for corrected invocations." -class DropFrame(Instruction): "Drop an invocation frame." -class StoreFrame(Immediate): "Store the current value as an argument for the parameter with the given position." -class StoreFrameIndex(Immediate): "Store the source value as an argument of the current value for the parameter with the given index." -class LoadContext(Instruction): "Load the context of an invocation." +class MakeFrame(Immediate): + "Make a new invocation frame." + cost = 2 + +class AdjustFrame(Immediate): + "Adjust the current invocation frame for corrected invocations." + cost = 2 + +class DropFrame(Instruction): + "Drop an invocation frame." + cost = 2 + +class StoreFrame(Immediate): + "Store the current value as an argument for the parameter with the given position." + cost = 2 + +class StoreFrameIndex(Immediate): + "Store the source value as an argument of the current value for the parameter with the given index." + cost = 6 + +class LoadContext(Instruction): + "Load the context of an invocation." + cost = 2 # Context-related tests. -class CheckContext(Instruction): "Check to see if the context is valid." -class CheckClass(Instruction): "Check the current value to determine whether it is a class." -class CheckInstance(Instruction): """Check the current value as an instance of a class or its subclasses (used with 'self' in an - invocation).""" -class CheckType(Instruction): "Check the current value as an instance of a specific class only." +class CheckContext(Instruction): + "Check to see if the context is valid." + cost = 2 + +class CheckClass(Instruction): + "Check the current value to determine whether it is a class." + cost = 2 + +class CheckInstance(Instruction): + """ + Check the current value as an instance of a class or its subclasses (used with 'self' in an + invocation). + """ + cost = 6 + +class CheckType(Instruction): + "Check the current value as an instance of a specific class only." + cost = 5 # Access to frames upon invocation. -class CheckFrame(Immediate): "Check the frame for the correct number of arguments." -class CheckExtra(Immediate): "Ensure that the frame can provide extra arguments." -class FillDefaults(Immediate): "Fill frame positions with defaults, if appropriate." -class ExtendFrame(Immediate): "Extend the current frame for temporary storage use." -class CopyExtra(Immediate): "Copy extra arguments into a separate sequence, starting from the given position." +class CheckFrame(Immediate): + "Check the frame for the correct number of arguments." + cost = 3 + +class CheckExtra(Immediate): + "Ensure that the frame can provide extra arguments." + cost = 3 + +class FillDefaults(Immediate): + "Fill frame positions with defaults, if appropriate." + cost = 8 # variable + +class ExtendFrame(Immediate): + "Extend the current frame for temporary storage use." + cost = 1 + +class CopyExtra(Immediate): + "Copy extra arguments into a separate sequence, starting from the given position." + cost = 10 # Invocation-related instructions, using a special result "register". -class JumpInFrame(Instruction): "Jump, using the current locals, to the current callable." -class JumpWithFrame(Instruction): "Jump, adopting the invocation frame, to the current callable." -class JumpWithFrameDirect(Target): "Jump to the specified address, adopting the invocation frame." -class Return(Instruction): "Return from a subprogram." -class LoadResult(Instruction): "Load into the current value a returned value." -class StoreResult(Instruction): "Store the current value as a value to be returned." +class JumpInFrame(Instruction): + "Jump, using the current locals, to the current callable." + cost = 2 + +class JumpWithFrame(Instruction): + "Jump, adopting the invocation frame, to the current callable." + cost = 3 + +class JumpWithFrameDirect(Target): + "Jump to the specified address, adopting the invocation frame." + cost = 3 + +class Return(Instruction): + "Return from a subprogram." + cost = 2 + +class LoadResult(Instruction): + "Load into the current value a returned value." + cost = 1 + +class StoreResult(Instruction): + "Store the current value as a value to be returned." + cost = 1 # Branch-related instructions. -class Jump(Address): "Jump unconditionally." -class JumpIfFalse(Address): "Jump if the last evaluation gave a false result." -class JumpIfTrue(Address): "Jump if the last evaluation gave a true result." +class Jump(Address): + "Jump unconditionally." + cost = 1 + +class JumpIfFalse(Address): + "Jump if the last evaluation gave a false result." + cost = 2 + +class JumpIfTrue(Address): + "Jump if the last evaluation gave a true result." + cost = 2 # Exception-related instructions, using a special exception "register". -class LoadException(Instruction): "Load the raised exception." -class StoreException(Instruction): "Store the current object in the exception register." -class ClearException(Instruction): "Reset the exception register." -class RaiseException(Instruction): "Raise an exception, jumping to the active handler." -class PushHandler(Address): "Push an exception handler onto the handler stack." -class PopHandler(Instruction): "Pop an exception handler from the handler stack." -class CheckException(Instruction): "Check the raised exception against another." +class LoadException(Instruction): + "Load the raised exception." + cost = 1 + +class StoreException(Instruction): + "Store the current object in the exception register." + cost = 1 + +class ClearException(Instruction): + "Reset the exception register." + cost = 1 + +class RaiseException(Instruction): + "Raise an exception, jumping to the active handler." + cost = 2 + +class PushHandler(Address): + "Push an exception handler onto the handler stack." + cost = 3 + +class PopHandler(Instruction): + "Pop an exception handler from the handler stack." + cost = 3 + +class CheckException(Instruction): + "Check the raised exception against another." + cost = 6 # Test instructions, operating on the boolean status register. -class TestIdentity(Instruction): "Test whether the current value is identical to the source value, setting the boolean status." -class TestIdentityAddress(Address): "Test whether the current value is identical to the given address, setting the boolean status." -class InvertBoolean(Instruction): "Invert the boolean status." +class TestIdentity(Instruction): + "Test whether the current value is identical to the source value, setting the boolean status." + cost = 2 + +class TestIdentityAddress(Address): + "Test whether the current value is identical to the given address, setting the boolean status." + cost = 2 + +class InvertBoolean(Instruction): + "Invert the boolean status." + cost = 1 # Instructions which affect the current value. (LoadAttrIndexContext not defined.) @@ -487,13 +644,12 @@ CopyExtra ) -# Instructions which use the current value. +# Instructions which use the current value. (LoadAttrIndexContext not defined.) simple_input_user_instructions = ( StoreTemp, StoreFrame, StoreResult, StoreException, # as the value being stored LoadAddressContext, LoadAddressContextCond, # as the object being referenced - LoadAttr, LoadAttrIndex, # LoadAttrIndexContext, # as the object being referenced - LoadAttrIndexContextCond, # as the object being referenced + LoadAttr, LoadAttrIndex, LoadAttrIndexContextCond, # as the object being referenced StoreAttr, StoreAttrIndex, StoreCallable, # as the object being referenced StoreFrameIndex, # as the object being referenced StoreAddressContext, # as the context diff -r fbb411daecea -r 12bf807e1e08 rsvp.py --- a/rsvp.py Fri Feb 26 01:56:26 2010 +0100 +++ b/rsvp.py Wed Mar 03 00:26:00 2010 +0100 @@ -97,7 +97,11 @@ self.pc = pc or 0 self.debug = debug self.abort_upon_exception = abort_upon_exception + + # Profiling. + self.counter = 0 + self.cost = 0 # Stacks. @@ -262,6 +266,7 @@ print "At address", self.pc else: print "successfully." + print "After", self.counter, "instructions at cost", self.cost, "units." def test(self, module): @@ -333,11 +338,13 @@ raise IllegalInstruction, (self.pc, instruction_name) return method - def perform(self, instruction): + def perform(self, instruction, is_input=0): "Perform the 'instruction', returning the next PC value or None." - self.counter += 1 + if not is_input: + self.counter += 1 + self.cost += instruction.cost self.operand = instruction.get_operand() method = self.get_method(instruction) return method() @@ -352,11 +359,11 @@ value = self.value if self.instruction.source is not None: - self.perform(self.instruction.source) + self.perform(self.instruction.source, 1) self.source = self.value self.value = value if self.instruction.input is not None: - self.perform(self.instruction.input) + self.perform(self.instruction.input, 1) def jump(self, addr, next):