Commit 34e0614c by Stefan Marr

Added add bytecode to improve interpreter performance

Signed-off-by: Stefan Marr <git@stefan-marr.de>
1 parent 598cef90
......@@ -44,6 +44,12 @@ class BytecodeGenerator(object):
def emitSEND(self, mgenc, msg):
self._emit2(mgenc, BC.send, mgenc.find_literal_index(msg))
def emitQUICKSEND(self, mgenc, msg):
if msg.get_string() == "+":
self._emit1(mgenc, BC.add)
else:
raise RuntimeError("Unsupported msg: " + msg)
def emitPUSHCONSTANT(self, mgenc, lit):
self._emit2(mgenc, BC.push_constant, mgenc.find_literal_index(lit))
......
......@@ -446,14 +446,20 @@ class Parser(object):
else:
self._bc_gen.emitSEND(mgenc, msg)
@staticmethod
def _is_quick_send(msg):
return msg.get_string() == "+"
def _binary_message(self, mgenc, is_super_send):
msg = self._binary_selector()
mgenc.add_literal_if_absent(msg)
self._binary_operand(mgenc, [False])
if is_super_send[0]:
self._bc_gen.emitSUPERSEND(mgenc, msg)
elif self._is_quick_send(msg):
self._bc_gen.emitQUICKSEND(mgenc, msg)
else:
self._bc_gen.emitSEND(mgenc, msg)
......
from rpython.rlib.unroll import unrolling_iterable
from rpython.rlib import jit
class Bytecodes(object):
# Bytecodes used by the Simple Object Machine (SOM)
......@@ -20,8 +21,11 @@ class Bytecodes(object):
super_send = 13
return_local = 14
return_non_local = 15
# quick sends, short cutting well known operations
add = 16
_num_bytecodes = 16
_num_bytecodes = 17
_bytecode_length = [ 1, # halt
1, # dup
......@@ -38,7 +42,10 @@ class Bytecodes(object):
2, # send
2, # super_send
1, # return_local
1 ] # return_non_local
1, # return_non_local
1, # add
]
_stack_effect_depends_on_message = -1000 # chose a unresonable number to be recognizable
......@@ -56,8 +63,9 @@ class Bytecodes(object):
-1, # pop_field
_stack_effect_depends_on_message, # send
_stack_effect_depends_on_message, # super_send
0, # return_local
0 ] # return_non_local
0, # return_local
0,
-1] # return_non_local
@jit.elidable
def bytecode_length(bytecode):
......
......@@ -2,13 +2,19 @@ from som.interpreter.bytecodes import bytecode_length, Bytecodes
from som.interpreter.control_flow import ReturnException
from rpython.rlib import jit
from som.vmobjects.integer import Integer, integer_value_fits
class Interpreter(object):
_immutable_fields_ = ["_universe"]
_immutable_fields_ = ["_universe", "_add_symbol"]
def __init__(self, universe):
self._universe = universe
self._universe = universe
self._add_symbol = None
def initialize_known_quick_sends(self):
self._add_symbol = self._universe.symbol_for("+")
def get_universe(self):
return self._universe
......@@ -131,6 +137,27 @@ class Interpreter(object):
raise ReturnException(result, context)
# TODO: this should be done like in the RTruffleSOM variant
def _push_long_result(self, frame, result):
# Check with integer bounds and push:
if integer_value_fits(result):
frame.push(self._universe.new_integer(int(result)))
else:
frame.push(self._universe.new_biginteger(result))
def _do_add(self, bytecode_index, frame, method):
rcvr = frame.get_stack_element(1)
right = frame.get_stack_element(0)
if isinstance(rcvr, Integer) and isinstance(right, Integer):
frame.pop()
frame.pop()
result = rcvr.get_embedded_integer() + right.get_embedded_integer()
self._push_long_result(frame, result)
else:
self._send(method, frame, self._add_symbol,
rcvr.get_class(self._universe), bytecode_index)
def _do_send(self, bytecode_index, frame, method):
# Handle the send bytecode
signature = method.get_constant(bytecode_index)
......@@ -142,7 +169,8 @@ class Interpreter(object):
receiver = frame.get_stack_element(num_args - 1)
# Send the message
self._send(method, frame, signature, receiver.get_class(self._universe), bytecode_index)
self._send(method, frame, signature, receiver.get_class(self._universe),
bytecode_index)
@jit.unroll_safe
......@@ -200,6 +228,8 @@ class Interpreter(object):
return self._do_return_local(frame)
elif bytecode == Bytecodes.return_non_local: # BC:15
return self._do_return_non_local(frame)
elif bytecode == Bytecodes.add:
self._do_add(current_bc_idx, frame, method)
current_bc_idx = next_bc_idx
......
......@@ -320,6 +320,8 @@ class Universe(object):
self.blockClasses = [self.blockClass] + \
[self._make_block_class(i) for i in [1, 2, 3]]
self._interpreter.initialize_known_quick_sends()
return system_object
@jit.elidable
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!