Commit 54182a5d authored by Stefan Marr's avatar Stefan Marr

Merge pull request #1 from cfbolz/master

Optimize low-hanging fruit in the jitted RPython version
parents 3558b9f8 18ad30f8
This diff is collapsed.
from rpython.rlib.rrandom import Random
from rpython.rlib import jit
from som.interpreter.interpreter import Interpreter
from som.interpreter.bytecodes import Bytecodes
......@@ -26,14 +27,29 @@ import time
from rlib.exit import Exit
from rlib.osext import path_split
class GlobalVersion(object):
pass
class Universe(object):
_immutable_fields_ = [
"nilObject",
"trueObject",
"falseObject",
"objectClass",
"integerClass",
"doubleClass",
"primitiveClass",
"_global_version?",
]
def __init__(self, avoid_exit = False):
self._interpreter = Interpreter(self)
self._symbol_table = SymbolTable()
self._globals = {}
self._global_version = GlobalVersion()
self.nilObject = None
self.trueObject = None
self.falseObject = None
......@@ -51,6 +67,7 @@ class Universe(object):
self.primitiveClass = None
self.systemClass = None
self.blockClass = None
self.blockClasses = None
self.stringClass = None
self.doubleClass = None
......@@ -279,7 +296,10 @@ class Universe(object):
self.set_global( trueClassName, trueClass)
self.set_global(falseClassName, falseClass)
self.blockClasses = [self.blockClass] + \
[self._make_block_class(i) for i in [1, 2, 3]]
return system_object
def symbol_for(self, string):
......@@ -474,35 +494,31 @@ class Universe(object):
def get_global(self, name):
# Return the global with the given name if it's in the dictionary of globals
if self.has_global(name):
return self._globals[name]
# if not, return None
jit.promote(self)
return self._get_global(name, self._global_version)
# Global not found
return None
@jit.elidable
def _get_global(self, name, version):
return self._globals.get(name, None)
def set_global(self, name, value):
# Insert the given value into the dictionary of globals
self._globals[name] = value
self._global_version = GlobalVersion()
def has_global(self, name):
# Returns if the universe has a value for the global of the given name
return name in self._globals
def _get_block_class(self, number_of_arguments = None):
if not number_of_arguments:
# Get the generic block class
return self.blockClass
def _get_block_class(self, number_of_arguments):
return self.blockClasses[number_of_arguments]
def _make_block_class(self, number_of_arguments):
# Compute the name of the block class with the given number of
# arguments
name = self.symbol_for("Block" + str(number_of_arguments))
# Lookup the specific block class in the dictionary of globals and
# return it
if self.has_global(name):
return self.get_global(name)
# Get the block class for blocks with the given number of arguments
result = self._load_class(name, None)
......@@ -517,8 +533,9 @@ class Universe(object):
def load_class(self, name):
# Check if the requested class is already in the dictionary of globals
if self.has_global(name):
return self.get_global(name)
result = self.get_global(name)
if result is not None:
return result
# Load the class
result = self._load_class(name, None)
......
from rpython.rlib import jit
from som.vmobjects.object import Object
from som.vmobjects.primitive import Primitive
......@@ -15,7 +17,7 @@ class Block(Object):
def get_method(self):
# Get the method of this block by reading the field with method index
return self._method
return jit.promote(self._method)
def get_context(self):
# Get the context of this block by reading the field with context index
......@@ -26,6 +28,7 @@ class Block(Object):
return self.NUMBER_OF_BLOCK_FIELDS
class Evaluation(Primitive):
_immutable_fields_ = ['_number_of_arguments']
def __init__(self, num_args, universe, invoke):
Primitive.__init__(self, self._compute_signature_string(num_args),
universe, invoke)
......
......@@ -17,13 +17,12 @@ class Frame(Array):
# Static field indices and number of frame fields
NUMBER_OF_FRAME_FIELDS = Array.NUMBER_OF_OBJECT_FIELDS
_immutable_fields_ = ["_method", "_context", "_previous_frame"]
_immutable_fields_ = ["_method", "_context"]
def __init__(self, nilObject, num_elements, method, context, previous_frame):
Array.__init__(self, nilObject, num_elements)
self._stack_pointer = 0
self._bytecode_index = 0
self._local_offset = 0
self._method = method
self._context = context
self._previous_frame = previous_frame if previous_frame else nilObject
......@@ -62,6 +61,7 @@ class Frame(Array):
# Return the found context
return frame
@jit.unroll_safe
def get_outer_context(self, nilObject):
# Compute the outer context of this frame
frame = self
......@@ -77,6 +77,9 @@ class Frame(Array):
# Get the method by reading the field with method index
return self._method
def get_number_of_arguments(self):
return self.get_method().get_number_of_arguments()
def _get_default_number_of_fields(self):
# Return the default number of fields in a frame
return self.NUMBER_OF_FRAME_FIELDS
......@@ -95,7 +98,7 @@ class Frame(Array):
def get_stack_pointer(self):
# Get the current stack pointer for this frame
return self._stack_pointer
return jit.promote(self._stack_pointer)
def set_stack_pointer(self, value):
# Set the current stack pointer for this frame
......@@ -103,10 +106,9 @@ class Frame(Array):
def reset_stack_pointer(self):
# arguments are stored in front of local variables
self._local_offset = self.get_method().get_number_of_arguments()
# Set the stack pointer to its initial value thereby clearing the stack
self.set_stack_pointer(self._local_offset +
self.set_stack_pointer(self.get_number_of_arguments() +
self.get_method().get_number_of_locals().get_embedded_integer() - 1)
def get_bytecode_index(self):
......@@ -128,10 +130,10 @@ class Frame(Array):
self.set_indexable_field(self.get_stack_pointer() - index, value)
def _get_local(self, index):
return self.get_indexable_field(self._local_offset + index)
return self.get_indexable_field(self.get_number_of_arguments() + index)
def _set_local(self, index, value):
self.set_indexable_field(self._local_offset + index, value)
self.set_indexable_field(self.get_number_of_arguments() + index, value)
def get_local(self, index, context_level):
# Get the local with the given index in the given context
......
......@@ -49,6 +49,8 @@ class Method(Array):
# Get the maximum number of stack elements
return self._maximum_number_of_stack_elements
# XXX this means that the JIT doesn't see changes to the method object
@jit.elidable_promote('all')
def get_signature(self):
# Get the signature of this method by reading the field with signature
# index
......@@ -72,6 +74,8 @@ class Method(Array):
if self.get_indexable_field(i).is_invokable():
self.get_indexable_field(i).set_holder(value)
# XXX this means that the JIT doesn't see changes to the constants
@jit.elidable_promote('all')
def get_constant(self, bytecode_index):
# Get the constant associated to a given bytecode index
return self.get_indexable_field(self.get_bytecode(bytecode_index + 1))
......@@ -88,7 +92,7 @@ class Method(Array):
# Get the number of bytecodes in this method
return len(self._bytecodes)
@jit.elidable
@jit.elidable_promote('all')
def get_bytecode(self, index):
# Get the bytecode at the given index
assert 0 <= index and index < len(self._bytecodes)
......
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