" % (self.source, flags)
-
-class Specializer(object):
- loop = None
- nodes = None
-
- def getnode(self, box):
- try:
- return self.nodes[box]
- except KeyError:
- if isinstance(box, Const):
- node = InstanceNode(box, const=True)
- else:
- node = InstanceNode(box)
- self.nodes[box] = node
- return node
-
- def getsource(self, box):
- if isinstance(box, Const):
- return box
- return self.nodes[box].source
-
- def find_nodes(self):
- for op in self.loop.operations:
- if op.is_always_pure():
- is_pure = True
- for arg in op.args:
- if not self.getnode(arg).const:
- is_pure = False
- if is_pure:
- box = op.result
- assert box is not None
- self.nodes[box] = InstanceNode(box.constbox(), const=True)
- continue
- else:
- if op.is_guard():
- for arg in op.suboperations[0].args:
- self.getnode(arg)
- # default case
- for box in op.args:
- self.getnode(box)
- box = op.result
- if box is not None:
- self.nodes[box] = InstanceNode(box)
-
- def new_arguments(self, op):
- newboxes = []
- for box in op.args:
- if isinstance(box, Box):
- instnode = self.nodes[box]
- box = instnode.source
- newboxes.append(box)
- return newboxes
-
- def optimize_guard(self, op):
- assert len(op.suboperations) == 1
- op_fail = op.suboperations[0]
- op_fail.args = self.new_arguments(op_fail)
- # modification in place. Reason for this is explained in mirror
- # in optimize.py
- op.suboperations = [op_fail]
-
- def optimize_operations(self):
- newoperations = []
- for op in self.loop.operations:
- if op.is_guard():
- if op.opnum == rop.GUARD_NONVIRTUALIZED:
- continue
- elif op.opnum == rop.GUARD_CLASS:
- node = self.getnode(op.args[0])
- if node.cls is not None:
- # assert that they're equal maybe
- continue
- node.cls = InstanceNode(op.args[1], const=True)
- elif op.opnum == rop.GUARD_VALUE:
- instnode = self.nodes[op.args[0]]
- assert isinstance(op.args[1], Const)
- if instnode.const:
- continue
- self.optimize_guard(op)
- instnode.const = True
- instnode.source = op.args[0].constbox()
- newoperations.append(op)
- continue
- self.optimize_guard(op)
- newoperations.append(op)
- continue
- # default handler
- op = op.clone()
- op.args = self.new_arguments(op)
- if op.is_always_pure():
- for box in op.args:
- if isinstance(box, Box):
- break
- else:
- # all constant arguments: constant-fold away
- box = op.result
- assert box is not None
- instnode = InstanceNode(box.constbox(), const=True)
- self.nodes[box] = instnode
- continue
- newoperations.append(op)
- print "Length of the loop:", len(newoperations)
- self.loop.operations = newoperations
-
- def optimize_loop(self, loop):
- self.nodes = {}
- self.loop = loop
- self.find_nodes()
- self.optimize_operations()
-specializer = Specializer()
+from pypy.jit.metainterp.resoperation import rop
def optimize_loop(options, old_loops, loop, cpu=None):
if old_loops:
assert len(old_loops) == 1
return old_loops[0]
else:
- specializer.optimize_loop(loop)
+ newoperations = []
+ for op in loop.operations:
+ if op.opnum == rop.GUARD_NONVIRTUALIZED:
+ continue
+ newoperations.append(op)
+ loop.operations = newoperations
return None
def optimize_bridge(options, old_loops, loop, cpu=None):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop_dummy.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop_dummy.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop_dummy.py Tue May 19 08:15:59 2009
@@ -20,5 +20,5 @@
class TestLLtype(LoopDummyTest, LLJitMixin):
pass
-class XTestOOtype(LoopDummyTest, OOJitMixin):
+class TestOOtype(LoopDummyTest, OOJitMixin):
pass
Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop_optimize2.py (from r65302, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop_dummy.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop_dummy.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop_optimize2.py Tue May 19 08:15:59 2009
@@ -1,7 +1,7 @@
from pypy.jit.metainterp.test import test_loop, test_send
from pypy.jit.metainterp.warmspot import ll_meta_interp
-from pypy.jit.metainterp.simple_optimize import Optimizer
+from pypy.jit.metainterp.optimize2 import Optimizer
from pypy.jit.metainterp.test.test_basic import LLJitMixin, OOJitMixin
class LoopDummyTest(test_loop.LoopTest, test_send.SendTests):
@@ -20,5 +20,5 @@
class TestLLtype(LoopDummyTest, LLJitMixin):
pass
-class XTestOOtype(LoopDummyTest, OOJitMixin):
+class TestOOtype(LoopDummyTest, OOJitMixin):
pass
Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (from r65302, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_simple_optimize.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_simple_optimize.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Tue May 19 08:15:59 2009
@@ -1,4 +1,5 @@
+import py
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
@@ -7,7 +8,7 @@
ConstInt, BoxInt
from pypy.jit.backend.llgraph import runner
-from pypy.jit.metainterp.simple_optimize import optimize_loop
+from pypy.jit.metainterp.optimize2 import optimize_loop
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
@@ -19,6 +20,9 @@
NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT),
('value', lltype.Signed),
('next', lltype.Ptr(NODE))))
+node = lltype.malloc(NODE)
+nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
+nodedescr = cpu.fielddescrof(NODE, 'value')
def newloop(inputargs, operations):
loop = TreeLoop("test")
@@ -27,8 +31,6 @@
return loop
def test_remove_guard_class():
- node = lltype.malloc(NODE)
- nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
ops = [
ResOperation(rop.GUARD_CLASS, [nodebox, vtable_box], None),
ResOperation(rop.GUARD_CLASS, [nodebox, vtable_box], None),
@@ -56,3 +58,21 @@
equaloplists(loop.operations, [
ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
])
+
+def test_remove_consecutive_getfields():
+ py.test.skip("in progress")
+ n1 = BoxInt()
+ n2 = BoxInt()
+ n3 = BoxInt()
+ ops = [
+ ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
+ ResOperation(rop.GETFIELD_GC, [nodebox], n2, nodedescr),
+ ResOperation(rop.INT_ADD, [n1, n2], n3),
+ ]
+ loop = newloop([nodebox], ops)
+ optimize_loop(None, [], loop)
+ equaloplists(loop.operations, [
+ ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
+ ResOperation(rop.INT_ADD, [n1, n1], n3),
+ ])
+
From antocuni at codespeak.net Tue May 19 10:31:14 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 19 May 2009 10:31:14 +0200 (CEST)
Subject: [pypy-svn] r65304 - pypy/branch/pyjitpl5/pypy/jit/metainterp
Message-ID: <20090519083114.C125B169DF6@codespeak.net>
Author: antocuni
Date: Tue May 19 10:31:13 2009
New Revision: 65304
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py
Log:
don't print stuff on stdout, as it breaks the minimal and cli backends
(because the spawn an external process and read the result as printed on
stdout)
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/simple_optimize.py Tue May 19 10:31:13 2009
@@ -121,7 +121,7 @@
self.nodes[box] = instnode
continue
newoperations.append(op)
- print "Length of the loop:", len(newoperations)
+ #print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
def optimize_loop(self, loop):
From david at codespeak.net Tue May 19 12:15:46 2009
From: david at codespeak.net (david at codespeak.net)
Date: Tue, 19 May 2009 12:15:46 +0200 (CEST)
Subject: [pypy-svn] r65305 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090519101546.56E47169E7B@codespeak.net>
Author: david
Date: Tue May 19 12:15:43 2009
New Revision: 65305
Added:
pypy/branch/io-lang/pypy/lang/io/test/test_number.py
Modified:
pypy/branch/io-lang/pypy/lang/io/model.py
pypy/branch/io-lang/pypy/lang/io/test/test_method.py
Log:
fixed issued evaluating variables in methods in the context of other objects than the Lobby
Modified: pypy/branch/io-lang/pypy/lang/io/model.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/model.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/model.py Tue May 19 12:15:43 2009
@@ -110,7 +110,7 @@
w_result = w_method.apply(space, w_receiver, self, w_context)
if self.next:
#TODO: optimize
- return self.next.eval(space, w_result, w_context)
+ return self.next.eval(space, w_result, w_receiver)
else:
return w_result
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_method.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_method.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_method.py Tue May 19 12:15:43 2009
@@ -50,4 +50,25 @@
def test_call_on_method():
inp = 'a := method(x, x + 1); getSlot("a") call(3)'
res, space = interpret(inp)
- assert res.value == 4
\ No newline at end of file
+ assert res.value == 4
+
+def test_method_binding():
+ inp = 'c := Object clone; c setSlot("b", 123); c setSlot("a", method(b)); c a'
+ res, space = interpret(inp)
+ assert res.value == 123
+
+def test_method_modified_binding():
+ inp = 'c := Object clone; c setSlot("b",123); c setSlot("a", method(x, b)); c setSlot("b",1); c a(3)'
+ res, space = interpret(inp)
+ assert res.value == 1
+
+
+def test_block_binding():
+ inp = 'c := Object clone; b := 123; c setSlot("a", block(x, b)); c a call(3)'
+ res, space = interpret(inp)
+ assert res.value == 123
+
+def test_block_modified_binding():
+ inp = 'c := Object clone; b := 42; c setSlot("a", block(x, b)); b := 1; c a call(3)'
+ res, space = interpret(inp)
+ assert res.value == 1
\ No newline at end of file
Added: pypy/branch/io-lang/pypy/lang/io/test/test_number.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_number.py Tue May 19 12:15:43 2009
@@ -0,0 +1,31 @@
+from pypy.lang.io.parserhack import interpret
+from pypy.lang.io.model import W_Number
+import py
+def test_even_simpler():
+ x, _ = interpret("2")
+ assert x.value == 2
+
+def test_simple():
+ x, _ = interpret("2 + 2")
+ assert x.value == 4
+
+def test_simple_minus():
+ x, _ = interpret("2 - 2")
+ assert x.value == 0
+
+def test_plus_in_context():
+ x, _ = interpret("""x := 7
+ c := method(2 - x)
+ c()
+ """)
+ assert x.value == -5
+
+def test_plus_in_method():
+ inp = """c := Object clone
+ c f := 5
+ c g := method(3 + f)
+ c g(7)
+ """
+ res, space = interpret(inp)
+ assert res.value == 8
+
From david at codespeak.net Tue May 19 12:22:54 2009
From: david at codespeak.net (david at codespeak.net)
Date: Tue, 19 May 2009 12:22:54 +0200 (CEST)
Subject: [pypy-svn] r65306 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090519102254.C29A8169E9B@codespeak.net>
Author: david
Date: Tue May 19 12:22:54 2009
New Revision: 65306
Added:
pypy/branch/io-lang/pypy/lang/io/test/test_object.py
Modified:
pypy/branch/io-lang/pypy/lang/io/object.py
Log:
Add do slot to Object to evaluate a set of messages in the context of the reciever
Modified: pypy/branch/io-lang/pypy/lang/io/object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/object.py Tue May 19 12:22:54 2009
@@ -35,4 +35,8 @@
def w_object_list(space, w_target, w_message, w_context):
w_items = [x.eval(space, w_target, w_context) for x in w_message.arguments]
return space.w_list.clone_and_init(space, w_items)
-
\ No newline at end of file
+
+ at register_method('Object', 'do')
+def w_object_do(space, w_target, w_message, w_context):
+ w_message.arguments[0].eval(space, w_target, w_context)
+ return w_target
\ No newline at end of file
Added: pypy/branch/io-lang/pypy/lang/io/test/test_object.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_object.py Tue May 19 12:22:54 2009
@@ -0,0 +1,16 @@
+from pypy.lang.io.parserhack import parse, interpret
+from pypy.lang.io.model import W_Object
+import py.test
+
+
+def test_object_do():
+ inp = '4 do(a := 23)'
+ res, space = interpret(inp)
+ assert res.slots['a'].value == 23
+ assert res.value == 4
+
+def test_object_do_multiple_slots():
+ inp = 'Object do(a := 23; b := method(a + 5); a := 1); Object b'
+ res, space = interpret(inp)
+ assert res.value == 6
+ assert space.w_object.slots['a'].value == 1
\ No newline at end of file
From david at codespeak.net Tue May 19 12:40:02 2009
From: david at codespeak.net (david at codespeak.net)
Date: Tue, 19 May 2009 12:40:02 +0200 (CEST)
Subject: [pypy-svn] r65307 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090519104002.37794169EC8@codespeak.net>
Author: david
Date: Tue May 19 12:40:01 2009
New Revision: 65307
Modified:
pypy/branch/io-lang/pypy/lang/io/object.py
pypy/branch/io-lang/pypy/lang/io/test/test_object.py
Log:
add anonymous slot to object, which evaluates and returns given argument
Modified: pypy/branch/io-lang/pypy/lang/io/object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/object.py Tue May 19 12:40:01 2009
@@ -39,4 +39,8 @@
@register_method('Object', 'do')
def w_object_do(space, w_target, w_message, w_context):
w_message.arguments[0].eval(space, w_target, w_context)
- return w_target
\ No newline at end of file
+ return w_target
+
+ at register_method('Object', '', unwrap_spec=[object, object])
+def w_object_(space, w_target, w_arg):
+ return w_arg
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_object.py Tue May 19 12:40:01 2009
@@ -13,4 +13,9 @@
inp = 'Object do(a := 23; b := method(a + 5); a := 1); Object b'
res, space = interpret(inp)
assert res.value == 6
- assert space.w_object.slots['a'].value == 1
\ No newline at end of file
+ assert space.w_object.slots['a'].value == 1
+
+def test_object_anon_slot():
+ inp = 'Object getSlot("+")("foo")'
+ res, space = interpret(inp)
+ assert res.value == 'foo'
\ No newline at end of file
From david at codespeak.net Tue May 19 13:09:32 2009
From: david at codespeak.net (david at codespeak.net)
Date: Tue, 19 May 2009 13:09:32 +0200 (CEST)
Subject: [pypy-svn] r65308 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090519110932.38BA6169E06@codespeak.net>
Author: david
Date: Tue May 19 13:09:30 2009
New Revision: 65308
Modified:
pypy/branch/io-lang/pypy/lang/io/object.py
pypy/branch/io-lang/pypy/lang/io/test/test_object.py
Log:
add hasSlot and ? slots to Object
Modified: pypy/branch/io-lang/pypy/lang/io/object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/object.py Tue May 19 13:09:30 2009
@@ -13,6 +13,19 @@
except KeyError:
return space.w_nil
+ at register_method('Object', 'hasSlot', unwrap_spec=[object, str])
+def w_object_has_slot(space, w_target, name):
+ if w_target.lookup(name) is None:
+ return space.w_false
+ return space.w_true
+
+ at register_method('Object', '?')
+def w_object_question_mark(space, w_target, w_message, w_context):
+ name = w_message.arguments[0].name
+ if w_object_has_slot(space, w_target, name) is space.w_false:
+ return space.w_nil
+ return w_message.arguments[0].eval(space, w_target, w_context)
+
@register_method('Object', 'method')
def w_object_method(space, w_target, w_message, w_context):
w_body = w_message.arguments[-1]
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_object.py Tue May 19 13:09:30 2009
@@ -18,4 +18,23 @@
def test_object_anon_slot():
inp = 'Object getSlot("+")("foo")'
res, space = interpret(inp)
- assert res.value == 'foo'
\ No newline at end of file
+ assert res.value == 'foo'
+
+def test_object_has_slot():
+ inp = 'Object hasSlot("foo")'
+ res, space = interpret(inp)
+ assert res is space.w_false
+
+ inp2 = 'Object hasSlot("clone")'
+ res, space = interpret(inp2)
+ assert res is space.w_true
+
+def test_object_question_mark_simple():
+ inp = 'Object do(a := 1); Object ?a'
+ res, space = interpret(inp)
+ assert res is not space.w_nil
+ assert res.value == 1
+
+ inp2 = 'Object ?a'
+ res, space = interpret(inp2)
+ assert res is space.w_nil
From david at codespeak.net Tue May 19 14:21:44 2009
From: david at codespeak.net (david at codespeak.net)
Date: Tue, 19 May 2009 14:21:44 +0200 (CEST)
Subject: [pypy-svn] r65309 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090519122144.D6316169F10@codespeak.net>
Author: david
Date: Tue May 19 14:21:42 2009
New Revision: 65309
Added:
pypy/branch/io-lang/pypy/lang/io/call.py
pypy/branch/io-lang/pypy/lang/io/message.py
pypy/branch/io-lang/pypy/lang/io/test/test_call.py
pypy/branch/io-lang/pypy/lang/io/test/test_message.py
Modified:
pypy/branch/io-lang/pypy/lang/io/model.py
pypy/branch/io-lang/pypy/lang/io/object.py
pypy/branch/io-lang/pypy/lang/io/objspace.py
pypy/branch/io-lang/pypy/lang/io/register.py
pypy/branch/io-lang/pypy/lang/io/test/test_method.py
pypy/branch/io-lang/pypy/lang/io/test/test_object.py
Log:
methods for Call and Message objects, corrected evaluation of method args and create call object for when a method is called. Add message slot to Object
Added: pypy/branch/io-lang/pypy/lang/io/call.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/call.py Tue May 19 14:21:42 2009
@@ -0,0 +1,9 @@
+from pypy.lang.io.register import register_method
+from pypy.lang.io.model import W_Message
+
+ at register_method('Call', 'argAt')
+def call_arg_at(space, w_target, w_message, w_context):
+ return space.w_message.slots['argAt'].apply(
+ space,
+ w_target.slots['message'],
+ w_message, w_context)
\ No newline at end of file
Added: pypy/branch/io-lang/pypy/lang/io/message.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/message.py Tue May 19 14:21:42 2009
@@ -0,0 +1,13 @@
+from pypy.lang.io.register import register_method
+from pypy.lang.io.model import W_Message
+
+ at register_method('Message', 'argAt', unwrap_spec=[object, int])
+def message_arg_at(space, w_message, arg_num):
+ if arg_num < len(w_message.arguments):
+ return w_message.arguments[arg_num]
+ return space.w_nil
+
+# @register_method('Message', 'setIsActivatable', unwrap_spec=[object, bool])
+# def message_setIsActivatable(space, w_target, setting):
+# w_target.activateable = setting
+# return w_target
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/model.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/model.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/model.py Tue May 19 14:21:42 2009
@@ -92,7 +92,7 @@
self.literal_value = parse_literal(space, name)
self.arguments = arguments
self.next = next
- W_Object.__init__(self, space)
+ W_Object.__init__(self, space, [space.w_message])
def __repr__(self):
return "Message(%r, %r, %r)" % (self.name, self.arguments, self.next)
@@ -129,17 +129,17 @@
def call(self, space, w_receiver, w_message, w_context):
w_locals = self.space.w_locals.clone()
+ w_call = self.space.w_call.clone()
assert w_locals is not None
- args = list(self.arguments)
+ assert w_call is not None
- for arg in w_message.arguments:
- try:
- w_locals.slots[args.pop(0)] = arg.eval(space, w_receiver, w_context)
- except IndexError:
- break
-
- for arg_name in args:
- w_locals.slots[arg_name] = space.w_nil
+ args = list(self.arguments)
+ n_params = len(w_message.arguments)
+ for i in range(len(args)):
+ if i < n_params:
+ w_locals.slots[args[i]] = w_message.arguments[i].eval(space, w_receiver, w_context)
+ else:
+ w_locals.slots[args[i]] = space.w_nil
if self.activateable:
w_locals.protos = [w_receiver]
@@ -147,7 +147,9 @@
else:
w_locals.protos = [w_context]
w_locals.slots['self'] = w_context
-
+
+ w_locals.slots['call'] = w_call
+ w_call.slots['message'] = w_message
return self.body.eval(space, w_locals, w_context)
Modified: pypy/branch/io-lang/pypy/lang/io/object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/object.py Tue May 19 14:21:42 2009
@@ -57,3 +57,8 @@
@register_method('Object', '', unwrap_spec=[object, object])
def w_object_(space, w_target, w_arg):
return w_arg
+
+
+ at register_method('Object', 'message')
+def object_message(space, w_target, w_message, w_context):
+ return w_message.arguments[0]
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/objspace.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/objspace.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/objspace.py Tue May 19 14:21:42 2009
@@ -6,7 +6,8 @@
import pypy.lang.io.object
import pypy.lang.io.block
import pypy.lang.io.list
-
+import pypy.lang.io.call
+import pypy.lang.io.message
class ObjSpace(object):
"""docstring for ObjSpace"""
def __init__(self):
@@ -19,24 +20,34 @@
self.w_true = W_Object(self, [self.w_object])
self.w_false = W_Object(self, [self.w_object])
self.w_nil = W_Object(self, [self.w_object])
- self.w_block = W_Block(self, [], W_Message(self, 'nil', []), False, [self.w_object])
self.w_list = W_List(self, [self.w_object])
+ self.w_call = W_Object(self)
+
self.init_w_object()
self.init_w_protos()
self.init_w_list()
-
+
+ self.init_w_message()
+
+ self.w_block = W_Block(self, [], W_Message(self, 'nil', []), False, [self.w_object])
self.init_w_block()
self.init_w_lobby()
self.init_w_number()
+
self.init_w_core()
-
+ self.init_w_call()
+
+ def init_w_call(self):
+ for key, function in cfunction_definitions['Call'].items():
+ self.w_call.slots[key] = W_CFunction(self, function)
+
def init_w_protos(self):
self.w_protos.protos.append(self.w_core)
self.w_protos.slots['Core'] = self.w_core
@@ -58,6 +69,7 @@
self.w_core.slots['false'] = self.w_false
self.w_core.slots['nil'] = self.w_nil
self.w_core.slots['List'] = self.w_list
+ self.w_core.slots['Call'] = self.w_call
def init_w_number(self):
self.w_number = instantiate(W_Number)
@@ -67,6 +79,14 @@
for key, function in cfunction_definitions['Number'].items():
self.w_number.slots[key] = W_CFunction(self, function)
+ def init_w_message(self):
+ self.w_message = instantiate(W_Message)
+ W_Object.__init__(self.w_message, self)
+ self.w_message.protos = [self.w_object]
+ self.w_message.name = "Unnamed"
+ for key, function in cfunction_definitions['Message'].items():
+ self.w_message.slots[key] = W_CFunction(self, function)
+
def init_w_lobby(self):
self.w_lobby.protos.append(self.w_protos)
self.w_object.protos.append(self.w_lobby)
Modified: pypy/branch/io-lang/pypy/lang/io/register.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/register.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/register.py Tue May 19 14:21:42 2009
@@ -24,6 +24,11 @@
args += (x, )
elif typ is str:
args += (x.value, )
+ elif typ is bool:
+ if x is space.w_true:
+ args += (True, )
+ else:
+ args += (False, )
else:
raise ValueError, 'Unknown unwrap spec'
Added: pypy/branch/io-lang/pypy/lang/io/test/test_call.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_call.py Tue May 19 14:21:42 2009
@@ -0,0 +1,8 @@
+from pypy.lang.io.parserhack import interpret
+from pypy.lang.io.model import W_Message
+import py
+
+def test_message_arg_at():
+ inp = 'a := method(x, y, z, call); a(1,2,3) argAt(1)'
+ res, space = interpret(inp)
+ assert res.name == '2'
\ No newline at end of file
Added: pypy/branch/io-lang/pypy/lang/io/test/test_message.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_message.py Tue May 19 14:21:42 2009
@@ -0,0 +1,27 @@
+from pypy.lang.io.parserhack import interpret
+from pypy.lang.io.model import W_Message, W_Block
+import py
+
+
+def test_message_protos():
+ inp = "a := block(1)\na"
+ res,space = interpret(inp)
+
+ assert res.body.protos == [space.w_message]
+ assert space.w_message.protos == [space.w_object]
+
+def test_message_arg_at():
+ inp = 'a := message(foo(2,3,4)); a argAt(1)'
+ res, space = interpret(inp)
+ assert res.name == '3'
+
+# def test_setIsActivatable():
+# inp = "a := block(1);a setIsActivateable(true); a"
+# res,space = interpret(inp)
+#
+# assert res.value == 1
+#
+# inp = "a := method(1);a setIsActivateable(false); a"
+# res,space = interpret(inp)
+#
+# assert isinstance(res, W_Block)
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_method.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_method.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_method.py Tue May 19 14:21:42 2009
@@ -71,4 +71,36 @@
def test_block_modified_binding():
inp = 'c := Object clone; b := 42; c setSlot("a", block(x, b)); b := 1; c a call(3)'
res, space = interpret(inp)
- assert res.value == 1
\ No newline at end of file
+ assert res.value == 1
+
+def test_block_call_slot():
+ py.test.skip()
+ inp = """
+ Object do(
+ /*doc Object inlineMethod
+ Creates a method which is executed directly in a receiver (no Locals object is created).
+
+
+ Io> m := inlineMethod(x := x*2)
+ Io> x := 1
+ ==> 1
+ Io> m
+ ==> 2
+ Io> m
+ ==> 4
+ Io> m
+ ==> 8
+
+ */
+ inlineMethod := method(call message argAt(0) setIsActivatable(true))
+ )
+ m := inlineMethod(x := x*2)
+ x := 1
+ m
+ m
+ """
+ # from A0_List.io
+ res, space = interpret(inp)
+ assert space.w_object.slots['inlineMethod'] is not None
+ assert res.value == 4
+
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_object.py Tue May 19 14:21:42 2009
@@ -1,5 +1,5 @@
from pypy.lang.io.parserhack import parse, interpret
-from pypy.lang.io.model import W_Object
+from pypy.lang.io.model import W_Object, W_Message
import py.test
@@ -38,3 +38,9 @@
inp2 = 'Object ?a'
res, space = interpret(inp2)
assert res is space.w_nil
+
+def test_object_message():
+ inp = 'message(foo)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_Message)
+ assert res.name == 'foo'
\ No newline at end of file
From antocuni at codespeak.net Tue May 19 17:28:41 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 19 May 2009 17:28:41 +0200 (CEST)
Subject: [pypy-svn] r65314 - in pypy/branch/pyjitpl5/pypy: jit/backend/cli
jit/backend/cli/test translator/cli/src
Message-ID: <20090519152841.0C672169F6B@codespeak.net>
Author: antocuni
Date: Tue May 19 17:28:40 2009
New Revision: 65314
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py
pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs
Log:
implement bridges; so far the implementation is very simple, just a tailcall
to the method containing the next loop; hopefully, the speed penalty
associated to the tail call is not too heavy, because we don't expect bridges
to be so frequent (thanks cfbolz for the idea). In the future, we might think
of other techniques to avoid tail calls.
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Tue May 19 17:28:40 2009
@@ -14,6 +14,7 @@
System = CLR.System
OpCodes = System.Reflection.Emit.OpCodes
LoopDelegate = CLR.pypy.runtime.LoopDelegate
+DelegateHolder = CLR.pypy.runtime.DelegateHolder
InputArgs = CLR.pypy.runtime.InputArgs
cVoid = ootype.nullruntimeclass
@@ -51,12 +52,40 @@
def store(self, meth):
assert False, 'cannot store() to Constant'
+ def get_cliobj(self):
+ return dotnet.cast_to_native_object(self.getobj())
+
class __extend__(ConstInt):
__metaclass__ = extendabletype
def load(self, meth):
meth.il.Emit(OpCodes.Ldc_I4, self.value)
+
+class ConstFunction(Const):
+
+ def __init__(self, name):
+ self.name = name
+ self.holder = DelegateHolder()
+
+ def get_cliobj(self):
+ return dotnet.cliupcast(self.holder, System.Object)
+
+ def load(self, meth):
+ holdertype = self.holder.GetType()
+ funcfield = holdertype.GetField('func')
+ Const.load(self, meth)
+ meth.il.Emit(OpCodes.Castclass, holdertype)
+ meth.il.Emit(OpCodes.Ldfld, funcfield)
+ meth.il.Emit(OpCodes.Castclass, dotnet.typeof(LoopDelegate))
+
+ def _getrepr_(self):
+ return '' % self.name
+
+ def __hash__(self):
+ return hash(self.holder)
+
+
class MethodArgument(AbstractValue):
def __init__(self, index, cliType):
self.index = index
@@ -87,6 +116,7 @@
class Method(object):
operations = [] # overwritten at the end of the module
+ tailcall = True
debug = False
def __init__(self, cpu, name, loop):
@@ -124,10 +154,12 @@
# initialize the array of genconsts
consts = dotnet.new_array(System.Object, len(self.consts))
for av_const, i in self.consts.iteritems():
- consts[i] = dotnet.cast_to_native_object(av_const.getobj())
+ #consts[i] = dotnet.cast_to_native_object(av_const.getobj())
+ consts[i] = av_const.get_cliobj()
# build the delegate
func = self.meth_wrapper.create_delegate(delegatetype, consts)
- self.func = dotnet.clidowncast(func, LoopDelegate)
+ func = dotnet.clidowncast(func, LoopDelegate)
+ self.loop._cli_funcbox.holder.SetFunc(func)
def _get_meth_wrapper(self):
restype = dotnet.class2type(cVoid)
@@ -282,7 +314,10 @@
self.il.Emit(OpCodes.Ldc_I4, index_op)
field = dotnet.typeof(InputArgs).GetField('failed_op')
self.il.Emit(OpCodes.Stfld, field)
- # store the lates values
+ self.emit_store_opargs(op)
+
+ def emit_store_opargs(self, op):
+ # store the latest values
i = 0
for box in op.args:
self.store_inputarg(i, box.type, box.getCliType(), box)
@@ -344,13 +379,23 @@
def emit_op_jump(self, op):
target = op.jump_target
- assert target is self.loop, 'TODO'
assert len(op.args) == len(target.inputargs)
- i = 0
- for i in range(len(op.args)):
- op.args[i].load(self)
- target.inputargs[i].store(self)
- self.il.Emit(OpCodes.Br, self.il_loop_start)
+ if target is self.loop:
+ i = 0
+ for i in range(len(op.args)):
+ op.args[i].load(self)
+ target.inputargs[i].store(self)
+ self.il.Emit(OpCodes.Br, self.il_loop_start)
+ else:
+ # it's a real bridge
+ self.emit_store_opargs(op)
+ self.av_inputargs.load(self)
+ self.loop._cli_funcbox.load(self)
+ methinfo = dotnet.typeof(LoopDelegate).GetMethod('Invoke')
+ if self.tailcall:
+ self.il.Emit(OpCodes.Tailcall)
+ self.il.Emit(OpCodes.Callvirt, methinfo)
+ self.il.Emit(OpCodes.Ret)
def emit_op_new_with_vtable(self, op):
assert isinstance(op.args[0], ConstObj) # ignored, using the descr instead
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Tue May 19 17:28:40 2009
@@ -1,6 +1,9 @@
+from pypy.tool.pairtype import extendabletype
from pypy.rpython.ootypesystem import ootype
+from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp.history import AbstractDescr, AbstractMethDescr
-from pypy.jit.metainterp.history import Box, BoxInt, BoxObj
+from pypy.jit.metainterp.history import Box, BoxInt, BoxObj, ConstObj, Const
+from pypy.jit.metainterp.history import TreeLoop
from pypy.jit.metainterp import executor
from pypy.jit.metainterp.resoperation import rop, opname
from pypy.jit.backend import model
@@ -12,6 +15,12 @@
System = CLR.System
InputArgs = CLR.pypy.runtime.InputArgs
+class __extend__(TreeLoop):
+ __metaclass__ = extendabletype
+
+ _cli_funcbox = None
+ _cli_meth = None
+
class CliCPU(model.AbstractCPU):
@@ -67,13 +76,18 @@
# ----------------------
def compile_operations(self, loop):
- from pypy.jit.backend.cli.method import Method
- meth = Method(self, loop.name, loop)
- loop._cli_meth = meth
+ from pypy.jit.backend.cli.method import Method, ConstFunction
+ if loop._cli_funcbox is None:
+ loop._cli_funcbox = ConstFunction(loop.name)
+ else:
+ # discard previously compiled loop
+ loop._cli_funcbox.holder.SetFunc(None)
+ loop._cli_meth = Method(self, loop.name, loop)
def execute_operations(self, loop):
meth = loop._cli_meth
- meth.func(self.get_inputargs())
+ func = loop._cli_funcbox.holder.GetFunc()
+ func(self.get_inputargs())
return meth.failing_ops[self.inputargs.get_failed_op()]
def set_future_value_int(self, index, intvalue):
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py Tue May 19 17:28:40 2009
@@ -37,7 +37,7 @@
test_oostring_instance = skip
test_long_long = skip
test_free_object = skip
+ test_stopatxpolicy = skip
- test_stopatxpolicy = _skip
test_bridge_from_interpreter = _skip
- test_bridge_from_interpreter_4 = _skip
+
Modified: pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs (original)
+++ pypy/branch/pyjitpl5/pypy/translator/cli/src/pypylib.cs Tue May 19 17:28:40 2009
@@ -291,24 +291,25 @@
return default_blockid;
}
}
+ */
public class DelegateHolder
{
- public Delegate func;
+ public LoopDelegate func;
// we need getter and setter because we can't directly access fields from RPython
- public void SetFunc(Delegate func)
+ public void SetFunc(LoopDelegate func)
{
this.func = func;
}
- public Delegate GetFunc()
+ public LoopDelegate GetFunc()
{
return this.func;
}
}
- */
+
public class AutoSaveAssembly
{
From fijal at codespeak.net Tue May 19 18:11:48 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 19 May 2009 18:11:48 +0200 (CEST)
Subject: [pypy-svn] r65315 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090519161148.A3F8A169F16@codespeak.net>
Author: fijal
Date: Tue May 19 18:11:47 2009
New Revision: 65315
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
more of optimizations. It's wrong with regard to aliasing and other things,
but that's in-progress
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 19 18:11:47 2009
@@ -1,7 +1,7 @@
""" Simplified optimize.py
"""
-from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.history import Const, Box
class InstanceNode(object):
@@ -11,7 +11,8 @@
assert isinstance(source, Const)
self.const = const
self.cls = None
- self.field_cache = {}
+ self.cleanfields = {}
+ self.dirtyfields = {}
def __repr__(self):
flags = ''
@@ -107,6 +108,24 @@
self.optimize_guard(op)
newoperations.append(op)
continue
+ elif op.opnum == rop.GETFIELD_GC:
+ instnode = self.getnode(op.args[0])
+ descr = op.descr
+ node = instnode.cleanfields.get(descr, None)
+ if node is not None:
+ self.nodes[op.result] = node
+ continue
+ else:
+ instnode.cleanfields[descr] = self.getnode(op.result)
+ elif op.opnum == rop.SETFIELD_GC:
+ instnode = self.getnode(op.args[0])
+ descr = op.descr
+ node = self.getnode(op.args[1])
+ instnode.dirtyfields[descr] = node
+ instnode.cleanfields[descr] = node
+ l = self.field_caches.setdefault(descr, [])
+ l.append((instnode, node))
+ continue
# default handler
op = op.clone()
op.args = self.new_arguments(op)
@@ -121,12 +140,23 @@
instnode = InstanceNode(box.constbox(), const=True)
self.nodes[box] = instnode
continue
+ elif not op.has_no_side_effect():
+ self.clean_up_caches(newoperations)
newoperations.append(op)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
+
+ def clean_up_caches(self, newoperations):
+ for descr, v in self.field_caches.iteritems():
+ for instnode, fieldnode in v:
+ newoperations.append(ResOperation(rop.SETFIELD_GC,
+ [instnode.source, fieldnode.source], None, descr))
+ del instnode.cleanfields[descr]
+ del instnode.dirtyfields[descr]
def optimize_loop(self, loop):
self.nodes = {}
+ self.field_caches = {}
self.loop = loop
self.find_nodes()
self.optimize_operations()
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Tue May 19 18:11:47 2009
@@ -60,7 +60,6 @@
])
def test_remove_consecutive_getfields():
- py.test.skip("in progress")
n1 = BoxInt()
n2 = BoxInt()
n3 = BoxInt()
@@ -76,3 +75,21 @@
ResOperation(rop.INT_ADD, [n1, n1], n3),
])
+def test_setfield_getfield_clean_cache():
+ n1 = BoxInt()
+ n2 = BoxInt()
+ n3 = BoxInt()
+ ops = [
+ ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
+ ResOperation(rop.SETFIELD_GC, [nodebox, ConstInt(3)], None, nodedescr),
+ ResOperation(rop.GETFIELD_GC, [nodebox], n2, nodedescr),
+ ResOperation(rop.CALL, [n2], None),
+ ]
+ loop = newloop([nodebox], ops)
+ optimize_loop(None, [], loop)
+ equaloplists(loop.operations, [
+ ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
+ ResOperation(rop.SETFIELD_GC, [nodebox, ConstInt(3)], None, nodedescr),
+ ResOperation(rop.CALL, [ConstInt(3)], None),
+ ])
+
From antocuni at codespeak.net Wed May 20 16:21:29 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 20 May 2009 16:21:29 +0200 (CEST)
Subject: [pypy-svn] r65331 - in pypy/branch/pyjitpl5/pypy/jit/backend/cli: .
test
Message-ID: <20090520142129.875B1169F06@codespeak.net>
Author: antocuni
Date: Wed May 20 16:21:28 2009
New Revision: 65331
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/methodfactory.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py
Log:
the code to implement bridges was broken, fix it:
- don't put a 'ret' in emit_store_opargs, else the jump is never taken
- put the array of failing ops on the cpu, not on the method, else the
"failed_op" index stored in inputargs is meaningless
- add a bunch of debugging stuff
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Wed May 20 16:21:28 2009
@@ -124,7 +124,6 @@
self.name = name
self.loop = loop
self.boxes = {} # box --> local var
- self.failing_ops = [] # index --> op
self.branches = []
self.branchlabels = []
self.consts = {} # object --> index
@@ -183,10 +182,10 @@
def get_index_for_failing_op(self, op):
try:
- return self.failing_ops.index(op)
+ return self.cpu.failing_ops.index(op)
except ValueError:
- self.failing_ops.append(op)
- return len(self.failing_ops)-1
+ self.cpu.failing_ops.append(op)
+ return len(self.cpu.failing_ops)-1
def get_index_for_constant(self, obj):
try:
@@ -231,6 +230,7 @@
self.il.Emit(OpCodes.Stelem, clitype)
def emit_load_inputargs(self):
+ self.emit_debug("executing: " + self.name)
i = 0
for box in self.loop.inputargs:
self.load_inputarg(i, box.type, box.getCliType())
@@ -243,8 +243,7 @@
def emit_operations(self, operations):
for op in operations:
- if self.debug:
- self.il.EmitWriteLine(op.repr())
+ self.emit_debug(op.repr())
func = self.operations[op.opnum]
assert func is not None
func(self, op)
@@ -278,6 +277,10 @@
def store_result(self, op):
op.result.store(self)
+ def emit_debug(self, msg):
+ if self.debug:
+ self.il.EmitWriteLine(msg)
+
def emit_clear_exception(self):
self.av_inputargs.load(self)
self.il.Emit(OpCodes.Ldnull)
@@ -315,6 +318,7 @@
field = dotnet.typeof(InputArgs).GetField('failed_op')
self.il.Emit(OpCodes.Stfld, field)
self.emit_store_opargs(op)
+ self.il.Emit(OpCodes.Ret)
def emit_store_opargs(self, op):
# store the latest values
@@ -322,7 +326,6 @@
for box in op.args:
self.store_inputarg(i, box.type, box.getCliType(), box)
i+=1
- self.il.Emit(OpCodes.Ret)
def emit_guard_bool(self, op, opcode):
assert op.suboperations
@@ -388,9 +391,10 @@
self.il.Emit(OpCodes.Br, self.il_loop_start)
else:
# it's a real bridge
+ self.emit_debug('jumping to ' + target.name)
self.emit_store_opargs(op)
+ target._cli_funcbox.load(self)
self.av_inputargs.load(self)
- self.loop._cli_funcbox.load(self)
methinfo = dotnet.typeof(LoopDelegate).GetMethod('Invoke')
if self.tailcall:
self.il.Emit(OpCodes.Tailcall)
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/methodfactory.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/methodfactory.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/methodfactory.py Wed May 20 16:21:28 2009
@@ -71,7 +71,7 @@
def create_delegate(self, delegatetype, consts):
t = self.typeBuilder.CreateType()
methinfo = t.GetMethod("invoke")
-## if self.name == 'generated_case_1':
+## if self.name == 'Loop #0(r1)_2':
## assemblyData.auto_save_assembly.Save()
return System.Delegate.CreateDelegate(delegatetype,
consts,
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Wed May 20 16:21:28 2009
@@ -20,6 +20,10 @@
_cli_funcbox = None
_cli_meth = None
+ _cli_count = 0
+
+ def _get_cli_name(self):
+ return '%s(r%d)' % (self.name, self._cli_count)
class CliCPU(model.AbstractCPU):
@@ -34,6 +38,7 @@
self.stats = stats
self.translate_support_code = translate_support_code
self.inputargs = None
+ self.failing_ops = [] # index --> op
self.ll_ovf_exc = self._get_prebuilt_exc(OverflowError)
self.ll_zero_exc = self._get_prebuilt_exc(ZeroDivisionError)
@@ -82,13 +87,13 @@
else:
# discard previously compiled loop
loop._cli_funcbox.holder.SetFunc(None)
- loop._cli_meth = Method(self, loop.name, loop)
+ loop._cli_meth = Method(self, loop._get_cli_name(), loop)
+ loop._cli_count += 1
def execute_operations(self, loop):
- meth = loop._cli_meth
func = loop._cli_funcbox.holder.GetFunc()
func(self.get_inputargs())
- return meth.failing_ops[self.inputargs.get_failed_op()]
+ return self.failing_ops[self.inputargs.get_failed_op()]
def set_future_value_int(self, index, intvalue):
self.get_inputargs().set_int(index, intvalue)
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_basic.py Wed May 20 16:21:28 2009
@@ -38,6 +38,3 @@
test_long_long = skip
test_free_object = skip
test_stopatxpolicy = skip
-
- test_bridge_from_interpreter = _skip
-
From antocuni at codespeak.net Wed May 20 18:19:31 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 20 May 2009 18:19:31 +0200 (CEST)
Subject: [pypy-svn] r65335 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test
Message-ID: <20090520161931.50F9A169F1C@codespeak.net>
Author: antocuni
Date: Wed May 20 18:19:29 2009
New Revision: 65335
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_basic.py
Log:
update test status: two more tests pass, one fails only on mono but not on windows, another is not a translation test
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_basic.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_basic.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_basic.py Wed May 20 18:19:29 2009
@@ -16,17 +16,21 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_basic.py
+ def mono_bug(self):
+ py.test.skip('mono bug?')
+
def skip(self):
py.test.skip('in-progress')
- test_stopatxpolicy = skip
+ test_stopatxpolicy = mono_bug
+
test_print = skip
test_bridge_from_interpreter = skip
test_bridge_from_interpreter_2 = skip
- test_bridge_from_interpreter_3 = skip
- test_bridge_from_interpreter_4 = skip
- test_bridge_leaving_interpreter_5 = skip
test_free_object = skip
+ def test_bridge_from_interpreter_4(self):
+ pass # not a translation test
+
def test_we_are_jitted(self):
py.test.skip("it seems to fail even with the x86 backend, didn't investigate the problem")
From antocuni at codespeak.net Wed May 20 18:32:08 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 20 May 2009 18:32:08 +0200 (CEST)
Subject: [pypy-svn] r65336 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test
Message-ID: <20090520163208.5F353169F7A@codespeak.net>
Author: antocuni
Date: Wed May 20 18:32:07 2009
New Revision: 65336
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_send.py
Log:
good, all these tests pass now
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_send.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_send.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_send.py Wed May 20 18:32:07 2009
@@ -7,12 +7,6 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_send.py
- def skip_loop(self):
- py.test.skip('jump across loops not implemented yet')
-
- test_three_receivers = skip_loop
- test_three_classes = skip_loop
- test_recursive_call_to_portal_from_blackhole = skip_loop
- test_indirect_call_unknown_object_1 = skip_loop
- test_three_cases = skip_loop
+ def test_recursive_call_to_portal_from_blackhole(self):
+ py.test.skip('string return values are not supported')
From antocuni at codespeak.net Wed May 20 18:36:31 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 20 May 2009 18:36:31 +0200 (CEST)
Subject: [pypy-svn] r65337 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test
Message-ID: <20090520163631.99F0A169EF3@codespeak.net>
Author: antocuni
Date: Wed May 20 18:36:30 2009
New Revision: 65337
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py
Log:
more passing tests. test_int_lshift_ovf still fails because of a
NotImplementedError (will investigate later)
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py Wed May 20 18:36:30 2009
@@ -7,17 +7,10 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_exception.py
- def skip_loop(self):
- py.test.skip('jump across loops not implemented yet')
-
def skip(self):
py.test.skip('in-progress')
- test_bridge_from_guard_exception = skip_loop
- test_exception_four_cases = skip_loop
- test_bridge_from_interpreter_exc = skip_loop
- test_bridge_from_interpreter_exc_2 = skip_loop
- test_int_lshift_ovf = skip_loop
+ test_int_lshift_ovf = skip
From antocuni at codespeak.net Wed May 20 18:42:02 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 20 May 2009 18:42:02 +0200 (CEST)
Subject: [pypy-svn] r65338 - in pypy/branch/pyjitpl5/pypy/jit/backend/cli: .
test
Message-ID: <20090520164202.3A1E1169F54@codespeak.net>
Author: antocuni
Date: Wed May 20 18:42:01 2009
New Revision: 65338
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py
Log:
implement set_overflow_error to make test_int_lshift_ovf passing
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Wed May 20 18:42:01 2009
@@ -129,10 +129,14 @@
self.get_inputargs().set_exc_value(None)
def set_overflow_error(self):
- raise NotImplementedError
+ exc_obj = ootype.cast_to_object(self.ll_ovf_exc)
+ exc_value = dotnet.cast_to_native_object(exc_obj)
+ self.get_inputargs().set_exc_value(exc_value)
def set_zero_division_error(self):
- raise NotImplementedError
+ exc_obj = ootype.cast_to_object(self.ll_zero_exc)
+ exc_value = dotnet.cast_to_native_object(exc_obj)
+ self.get_inputargs().set_exc_value(exc_value)
# ----------------------
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_exception.py Wed May 20 18:42:01 2009
@@ -7,10 +7,5 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_exception.py
- def skip(self):
- py.test.skip('in-progress')
-
- test_int_lshift_ovf = skip
-
-
+ pass
From antocuni at codespeak.net Wed May 20 18:51:57 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 20 May 2009 18:51:57 +0200 (CEST)
Subject: [pypy-svn] r65339 - pypy/branch/pyjitpl5/pypy/jit/backend/cli
Message-ID: <20090520165157.9E5A7169F1C@codespeak.net>
Author: antocuni
Date: Wed May 20 18:51:57 2009
New Revision: 65339
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
Log:
be explicit on which operation we don't expect in the cli backend. Only few "real" operations are left now
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Wed May 20 18:51:57 2009
@@ -504,21 +504,26 @@
def not_implemented(self, op):
raise NotImplementedError
- emit_op_cast_int_to_ptr = not_implemented
emit_op_guard_nonvirtualized = not_implemented
emit_op_unicodelen = not_implemented
- emit_op_setfield_raw = not_implemented
- emit_op_cast_ptr_to_int = not_implemented
emit_op_newunicode = not_implemented
emit_op_new_array = not_implemented
emit_op_unicodegetitem = not_implemented
emit_op_strgetitem = not_implemented
- emit_op_getfield_raw = not_implemented
- emit_op_unicodesetitem = not_implemented
- emit_op_getfield_raw_pure = not_implemented
emit_op_strlen = not_implemented
emit_op_newstr = not_implemented
- emit_op_strsetitem = not_implemented
+
+ def lltype_only(self, op):
+ print 'Operation %s is lltype specific, should not get here!' % op.getopname()
+ raise NotImplementedError
+
+ emit_op_setfield_raw = lltype_only
+ emit_op_getfield_raw = lltype_only
+ emit_op_getfield_raw_pure = lltype_only
+ emit_op_strsetitem = lltype_only
+ emit_op_unicodesetitem = lltype_only
+ emit_op_cast_int_to_ptr = lltype_only
+ emit_op_cast_ptr_to_int = lltype_only
# --------------------------------------------------------------------
From antocuni at codespeak.net Thu May 21 10:06:40 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 10:06:40 +0200 (CEST)
Subject: [pypy-svn] r65341 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test
Message-ID: <20090521080640.05049169F9F@codespeak.net>
Author: antocuni
Date: Thu May 21 10:06:38 2009
New Revision: 65341
Added:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py (contents, props changed)
Log:
add new tests (to be run directly through Python for .NET); most of them pass, a bunch can be run only after translation, only one seems to be related to a real failure
Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py Thu May 21 10:06:38 2009
@@ -0,0 +1,25 @@
+import py
+from pypy.jit.metainterp.test import test_loop
+from pypy.jit.backend.cli.test.test_basic import CliJitMixin
+
+
+class TestLoop(CliJitMixin, test_loop.TestOOtype):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_loop.py
+
+ def skip(self):
+ py.test.skip("works only after translation")
+
+ def _skip(self):
+ py.test.skip("in-progress")
+
+ test_loop_with_two_paths = skip
+ test_interp_many_paths = skip
+ test_interp_many_paths_2 = skip
+ test_adapt_bridge_to_merge_point = skip
+ test_outer_and_inner_loop = skip
+ test_path_with_operations_not_from_start_2 = skip
+
+ test_loop_unicode = _skip
+
+
From antocuni at codespeak.net Thu May 21 10:09:52 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 10:09:52 +0200 (CEST)
Subject: [pypy-svn] r65342 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test
Message-ID: <20090521080952.2CA7B169F96@codespeak.net>
Author: antocuni
Date: Thu May 21 10:09:51 2009
New Revision: 65342
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py
Log:
I was wrong, this test also has no chances to pass without translation
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py Thu May 21 10:09:51 2009
@@ -10,16 +10,12 @@
def skip(self):
py.test.skip("works only after translation")
- def _skip(self):
- py.test.skip("in-progress")
-
test_loop_with_two_paths = skip
test_interp_many_paths = skip
test_interp_many_paths_2 = skip
test_adapt_bridge_to_merge_point = skip
test_outer_and_inner_loop = skip
test_path_with_operations_not_from_start_2 = skip
-
- test_loop_unicode = _skip
+ test_loop_unicode = skip
From antocuni at codespeak.net Thu May 21 10:20:00 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 10:20:00 +0200 (CEST)
Subject: [pypy-svn] r65343 - pypy/branch/pyjitpl5/pypy/jit/backend/cli/test
Message-ID: <20090521082000.4524D169F97@codespeak.net>
Author: antocuni
Date: Thu May 21 10:19:59 2009
New Revision: 65343
Added:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py (contents, props changed)
Log:
more tests, most of them pass :-)
Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py Thu May 21 10:19:59 2009
@@ -0,0 +1,15 @@
+import py
+from pypy.jit.backend.cli.test.test_zrpy_basic import CliTranslatedJitMixin
+from pypy.jit.metainterp.test import test_loop
+
+
+class TestLoop(CliTranslatedJitMixin, test_loop.TestOOtype):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_loop.py
+
+ def skip(self):
+ py.test.skip('in-progress')
+
+ test_interp_many_paths = skip
+ test_interp_many_paths_2 = skip
+ test_loop_unicode = skip
From antocuni at codespeak.net Thu May 21 11:46:25 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 11:46:25 +0200 (CEST)
Subject: [pypy-svn] r65344 - in pypy/branch/pyjitpl5/pypy/jit: backend/cli
backend/cli/test backend/test metainterp/test
Message-ID: <20090521094625.D8EAF169F5C@codespeak.net>
Author: antocuni
Date: Thu May 21 11:46:23 2009
New Revision: 65344
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py
pypy/branch/pyjitpl5/pypy/jit/backend/test/support.py
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py
Log:
- add a new test to test_loop to test string operations
- fix oosends to String and Unicode objects
- test_loop_{string,unicode} pass
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Thu May 21 11:46:23 2009
@@ -418,7 +418,8 @@
assert isinstance(descr, runner.StaticMethDescr)
delegate_type = descr.get_delegate_clitype()
meth_invoke = descr.get_meth_info()
- self._emit_call(op, delegate_type, meth_invoke, descr.has_result)
+ self._emit_call(op, OpCodes.Callvirt, delegate_type,
+ meth_invoke, descr.has_result)
def emit_op_call(self, op):
emit_op = Method.emit_op_call_impl.im_func
@@ -432,17 +433,18 @@
assert isinstance(descr, runner.MethDescr)
clitype = descr.get_self_clitype()
methinfo = descr.get_meth_info()
- self._emit_call(op, clitype, methinfo, descr.has_result)
+ opcode = descr.get_call_opcode()
+ self._emit_call(op, opcode, clitype, methinfo, descr.has_result)
emit_op_oosend_pure = emit_op_oosend
- def _emit_call(self, op, clitype, methinfo, has_result):
+ def _emit_call(self, op, opcode, clitype, methinfo, has_result):
av_sm, args_av = op.args[0], op.args[1:]
av_sm.load(self)
self.il.Emit(OpCodes.Castclass, clitype)
for av_arg in args_av:
av_arg.load(self)
- self.il.Emit(OpCodes.Callvirt, methinfo)
+ self.il.Emit(opcode, methinfo)
if has_result:
self.store_result(op)
@@ -505,13 +507,7 @@
raise NotImplementedError
emit_op_guard_nonvirtualized = not_implemented
- emit_op_unicodelen = not_implemented
- emit_op_newunicode = not_implemented
emit_op_new_array = not_implemented
- emit_op_unicodegetitem = not_implemented
- emit_op_strgetitem = not_implemented
- emit_op_strlen = not_implemented
- emit_op_newstr = not_implemented
def lltype_only(self, op):
print 'Operation %s is lltype specific, should not get here!' % op.getopname()
@@ -524,6 +520,12 @@
emit_op_unicodesetitem = lltype_only
emit_op_cast_int_to_ptr = lltype_only
emit_op_cast_ptr_to_int = lltype_only
+ emit_op_newstr = lltype_only
+ emit_op_strlen = lltype_only
+ emit_op_strgetitem = lltype_only
+ emit_op_newunicode = lltype_only
+ emit_op_unicodelen = lltype_only
+ emit_op_unicodegetitem = lltype_only
# --------------------------------------------------------------------
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Thu May 21 11:46:23 2009
@@ -13,7 +13,9 @@
from pypy.translator.cli.dotnet import CLR
System = CLR.System
+OpCodes = System.Reflection.Emit.OpCodes
InputArgs = CLR.pypy.runtime.InputArgs
+cpypyString = dotnet.classof(CLR.pypy.runtime.String)
class __extend__(TreeLoop):
__metaclass__ = extendabletype
@@ -62,6 +64,8 @@
@cached_method('_methcache')
def methdescrof(self, SELFTYPE, methname):
+ if SELFTYPE in (ootype.String, ootype.Unicode):
+ return StringMethDescr(SELFTYPE, methname)
return MethDescr(SELFTYPE, methname)
@cached_method('_typecache')
@@ -348,6 +352,19 @@
clitype = self.get_self_clitype()
return clitype.GetMethod(self.methname+'')
+ def get_call_opcode(self):
+ return OpCodes.Callvirt
+
+
+class StringMethDescr(MethDescr):
+
+ def get_meth_info(self):
+ clitype = dotnet.class2type(cpypyString)
+ return clitype.GetMethod(self.methname+'')
+
+ def get_call_opcode(self):
+ return OpCodes.Call
+
class FieldDescr(AbstractDescr):
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py Thu May 21 11:46:23 2009
@@ -17,5 +17,5 @@
test_outer_and_inner_loop = skip
test_path_with_operations_not_from_start_2 = skip
test_loop_unicode = skip
-
+ test_loop_string = skip
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py Thu May 21 11:46:23 2009
@@ -10,6 +10,10 @@
def skip(self):
py.test.skip('in-progress')
- test_interp_many_paths = skip
- test_interp_many_paths_2 = skip
- test_loop_unicode = skip
+ def test_interp_many_paths(self):
+ pass # no chance to pass it after translation, because it passes
+ # non-int arguments to the function
+
+ def test_interp_many_paths_2(self):
+ pass # see above
+
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/test/support.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/test/support.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/test/support.py Thu May 21 11:46:23 2009
@@ -104,3 +104,9 @@
from pypy.translator.cli.test.runtest import compile_graph
func = compile_graph(entry_point_graph, t, nowrap=True, standalone=True)
return func(*args)
+
+ def run_directly(self, fn, args):
+ from pypy.translator.cli.test.runtest import compile_function, get_annotation
+ ann = [get_annotation(x) for x in args]
+ clifunc = compile_function(fn, ann)
+ return clifunc(*args)
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_loop.py Thu May 21 11:46:23 2009
@@ -16,6 +16,9 @@
CPUClass=self.CPUClass,
type_system=self.type_system)
+ def run_directly(self, f, args):
+ return f(*args)
+
def test_simple_loop(self):
myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
def f(x, y):
@@ -348,7 +351,21 @@
x += unichr(n)
n -= 1
return hash(x)
- expected = f(100)
+ expected = self.run_directly(f, [100])
+ res = self.meta_interp(f, [100])
+ assert res == expected
+
+ def test_loop_string(self):
+ myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
+ def f(n):
+ x = ''
+ while n > 13:
+ myjitdriver.can_enter_jit(n=n, x=x)
+ myjitdriver.jit_merge_point(n=n, x=x)
+ x += chr(n)
+ n -= 1
+ return hash(x)
+ expected = self.run_directly(f, [100])
res = self.meta_interp(f, [100])
assert res == expected
From antocuni at codespeak.net Thu May 21 12:39:36 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 12:39:36 +0200 (CEST)
Subject: [pypy-svn] r65345 - in pypy/branch/pyjitpl5/pypy/jit/backend/cli: .
test
Message-ID: <20090521103936.96331169F06@codespeak.net>
Author: antocuni
Date: Thu May 21 12:39:34 2009
New Revision: 65345
Added:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py (contents, props changed)
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
Log:
port more tests, implement do_oonewarray; test_simple_array passes
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Thu May 21 12:39:34 2009
@@ -149,6 +149,11 @@
assert len(args) == 1 # but we don't need it, so ignore
return typedescr.create()
+ def do_new_array(self, args, typedescr):
+ assert isinstance(typedescr, TypeDescr)
+ assert len(args) == 1
+ return typedescr.create_array(args[0])
+
def do_runtimenew(self, args, descr):
classbox = args[0]
classobj = ootype.cast_from_object(ootype.Class, classbox.getobj())
Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py Thu May 21 12:39:34 2009
@@ -0,0 +1,18 @@
+import py
+from pypy.jit.metainterp.test import test_vlist
+from pypy.jit.backend.cli.test.test_basic import CliJitMixin
+
+
+class TestVlist(CliJitMixin, test_vlist.TestOOtype):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_vlist.py
+
+ def skip(self):
+ py.test.skip("works only after translation")
+
+ def _skip(self):
+ py.test.skip("in-progress")
+
+ test_list_pass_around = _skip
+ test_cannot_be_virtual = _skip
+ test_ll_fixed_setitem_fast = _skip
From antocuni at codespeak.net Thu May 21 13:55:09 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 13:55:09 +0200 (CEST)
Subject: [pypy-svn] r65346 - in pypy/branch/pyjitpl5/pypy/jit/backend/cli: .
test
Message-ID: <20090521115509.BB87D169E92@codespeak.net>
Author: antocuni
Date: Thu May 21 13:55:06 2009
New Revision: 65346
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py
Log:
implement emit_op_new_arry, but comment it out as it cannot be tested without translation.
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Thu May 21 13:55:06 2009
@@ -502,12 +502,18 @@
self.il.Emit(OpCodes.Castclass, clitype)
self.il.Emit(OpCodes.Ldlen)
self.store_result(op)
-
- def not_implemented(self, op):
+
+ def emit_op_new_array(self, op):
raise NotImplementedError
+## descr = op.descr
+## assert isinstance(descr, runner.TypeDescr)
+## item_clitype = descr.get_clitype()
+## op.args[0].load(self)
+## self.il.Emit(OpCodes.Newarr, item_clitype)
+## self.store_result(op)
- emit_op_guard_nonvirtualized = not_implemented
- emit_op_new_array = not_implemented
+ def emit_op_guard_nonvirtualized(self, op):
+ raise NotImplementedError
def lltype_only(self, op):
print 'Operation %s is lltype specific, should not get here!' % op.getopname()
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Thu May 21 13:55:06 2009
@@ -277,13 +277,12 @@
self.getarraylength = getarraylength
self.instanceof = instanceof
self.ooclass = get_class_for_type(TYPE)
- self.ooarrayclass = get_class_for_type(ARRAY)
def get_clitype(self):
return dotnet.class2type(self.ooclass)
def get_array_clitype(self):
- return dotnet.class2type(self.ooarrayclass)
+ return self.get_clitype().MakeArrayType()
def get_constructor_info(self):
clitype = self.get_clitype()
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py Thu May 21 13:55:06 2009
@@ -10,9 +10,6 @@
def skip(self):
py.test.skip("works only after translation")
- def _skip(self):
- py.test.skip("in-progress")
-
- test_list_pass_around = _skip
- test_cannot_be_virtual = _skip
- test_ll_fixed_setitem_fast = _skip
+ test_list_pass_around = skip
+ test_cannot_be_virtual = skip
+ test_ll_fixed_setitem_fast = skip
From antocuni at codespeak.net Thu May 21 14:05:48 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 14:05:48 +0200 (CEST)
Subject: [pypy-svn] r65347 - in pypy/branch/pyjitpl5/pypy/jit/backend/cli: .
test
Message-ID: <20090521120548.C613A169EAA@codespeak.net>
Author: antocuni
Date: Thu May 21 14:05:47 2009
New Revision: 65347
Added:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py (contents, props changed)
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
Log:
implement emit_op_new_arry to make almost all these tests passing
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Thu May 21 14:05:47 2009
@@ -504,13 +504,12 @@
self.store_result(op)
def emit_op_new_array(self, op):
- raise NotImplementedError
-## descr = op.descr
-## assert isinstance(descr, runner.TypeDescr)
-## item_clitype = descr.get_clitype()
-## op.args[0].load(self)
-## self.il.Emit(OpCodes.Newarr, item_clitype)
-## self.store_result(op)
+ descr = op.descr
+ assert isinstance(descr, runner.TypeDescr)
+ item_clitype = descr.get_clitype()
+ op.args[0].load(self)
+ self.il.Emit(OpCodes.Newarr, item_clitype)
+ self.store_result(op)
def emit_op_guard_nonvirtualized(self, op):
raise NotImplementedError
Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py Thu May 21 14:05:47 2009
@@ -0,0 +1,13 @@
+import py
+from pypy.jit.backend.cli.test.test_zrpy_basic import CliTranslatedJitMixin
+from pypy.jit.metainterp.test import test_vlist
+
+
+class TestVList(CliTranslatedJitMixin, test_vlist.TestOOtype):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_vlist.py
+
+ def skip(self):
+ py.test.skip('in-progress')
+
+ test_ll_fixed_setitem_fast = skip
From antocuni at codespeak.net Thu May 21 14:12:42 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 14:12:42 +0200 (CEST)
Subject: [pypy-svn] r65348 - in pypy/branch/pyjitpl5/pypy:
jit/backend/cli/test rpython/ootypesystem
Message-ID: <20090521121242.71B38169EC4@codespeak.net>
Author: antocuni
Date: Thu May 21 14:12:41 2009
New Revision: 65348
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py
pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rpbc.py
Log:
delay the call to get_concrete_calltable, so that the low level types of the
methods arguments have been fully computed, much like r65288. test_ll_fixed_setitem_fast passes
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py Thu May 21 14:12:41 2009
@@ -7,7 +7,4 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_vlist.py
- def skip(self):
- py.test.skip('in-progress')
-
- test_ll_fixed_setitem_fast = skip
+ pass
Modified: pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rpbc.py (original)
+++ pypy/branch/pyjitpl5/pypy/rpython/ootypesystem/rpbc.py Thu May 21 14:12:41 2009
@@ -116,10 +116,11 @@
class MethodsPBCRepr(AbstractMethodsPBCRepr):
- def __init__(self, rtyper, s_pbc):
- AbstractMethodsPBCRepr.__init__(self, rtyper, s_pbc)
- sampledesc = s_pbc.descriptions.iterkeys().next()
- self.concretetable, _ = get_concrete_calltable(rtyper,
+ concretetable = None # set by _setup_repr_final
+
+ def _setup_repr_final(self):
+ sampledesc = self.s_pbc.descriptions.iterkeys().next()
+ self.concretetable, _ = get_concrete_calltable(self.rtyper,
sampledesc.funcdesc.getcallfamily())
def rtype_simple_call(self, hop):
From antocuni at codespeak.net Thu May 21 14:31:04 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 14:31:04 +0200 (CEST)
Subject: [pypy-svn] r65349 - in pypy/branch/pyjitpl5/pypy:
jit/backend/cli/test translator/cli
Message-ID: <20090521123104.746E9169F07@codespeak.net>
Author: antocuni
Date: Thu May 21 14:31:03 2009
New Revision: 65349
Added:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py (contents, props changed)
Modified:
pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py
Log:
port more tests, ignore 'promote_virtualizable' in the normal cli backend.
Added: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py Thu May 21 14:31:03 2009
@@ -0,0 +1,20 @@
+import py
+from pypy.jit.backend.cli.test.test_zrpy_basic import CliTranslatedJitMixin
+from pypy.jit.metainterp.test import test_virtualizable
+
+
+class TestVirtualizable(CliTranslatedJitMixin, test_virtualizable.TestOOtype):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_virtualizable.py
+
+ def skip(self):
+ py.test.skip('in-progress')
+
+ test_virtual_on_virtualizable = skip
+ test_no_virtual_on_virtualizable = skip
+ test_unequal_list_lengths_cannot_be_virtual = skip
+ test_virtualizable_hierarchy = skip
+ test_non_virtual_on_always_virtual = skip
+ test_external_pass = skip
+ test_always_virtual_with_origfields = skip
+ test_pass_always_virtual_to_bridge = skip
Modified: pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py (original)
+++ pypy/branch/pyjitpl5/pypy/translator/cli/opcodes.py Thu May 21 14:31:03 2009
@@ -80,6 +80,7 @@
'keepalive': Ignore,
'is_early_constant': [PushPrimitive(ootype.Bool, False)],
'jit_marker': Ignore,
+ 'promote_virtualizable': Ignore,
}
# __________ numeric operations __________
From antocuni at codespeak.net Thu May 21 14:50:56 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 14:50:56 +0200 (CEST)
Subject: [pypy-svn] r65350 - in pypy/branch/pyjitpl5/pypy/jit/backend/cli: .
test
Message-ID: <20090521125056.64C7A168044@codespeak.net>
Author: antocuni
Date: Thu May 21 14:50:55 2009
New Revision: 65350
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py
Log:
implement emit_op_instanceof, and all the remaining virtualizable tests pass.
Moreover, add stubs for all the few still missing operations, so that we can
kill the warning and put an assert instead
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/method.py Thu May 21 14:50:55 2009
@@ -410,6 +410,19 @@
self.il.Emit(OpCodes.Newobj, ctor_info)
self.store_result(op)
+ def emit_op_runtimenew(self, op):
+ raise NotImplementedError
+
+ def emit_op_instanceof(self, op):
+ descr = op.descr
+ assert isinstance(descr, runner.TypeDescr)
+ clitype = descr.get_clitype()
+ op.args[0].load(self)
+ self.il.Emit(OpCodes.Isinst, clitype)
+ self.il.Emit(OpCodes.Ldnull)
+ self.il.Emit(OpCodes.Cgt_Un)
+ self.store_result(op)
+
def emit_op_ooidentityhash(self, op):
raise NotImplementedError
@@ -518,6 +531,7 @@
print 'Operation %s is lltype specific, should not get here!' % op.getopname()
raise NotImplementedError
+ emit_op_new = lltype_only
emit_op_setfield_raw = lltype_only
emit_op_getfield_raw = lltype_only
emit_op_getfield_raw_pure = lltype_only
@@ -568,10 +582,7 @@
elif isinstance(instr, opcodes.PushArg):
lines.append('self.push_arg(op, %d)' % instr.n)
else:
- if not isinstance(instr, str):
- print 'WARNING: unknown instruction %s' % instr
- return
-
+ assert isinstance(instr, str), 'unknown instruction %s' % instr
if instr.startswith('call '):
signature = instr[len('call '):]
renderCall(lines, signature)
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py Thu May 21 14:50:55 2009
@@ -7,14 +7,4 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_virtualizable.py
- def skip(self):
- py.test.skip('in-progress')
-
- test_virtual_on_virtualizable = skip
- test_no_virtual_on_virtualizable = skip
- test_unequal_list_lengths_cannot_be_virtual = skip
- test_virtualizable_hierarchy = skip
- test_non_virtual_on_always_virtual = skip
- test_external_pass = skip
- test_always_virtual_with_origfields = skip
- test_pass_always_virtual_to_bridge = skip
+ pass
From antocuni at codespeak.net Thu May 21 21:51:08 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 21 May 2009 21:51:08 +0200 (CEST)
Subject: [pypy-svn] r65351 - pypy/branch/pyjitpl5/pypy/config
Message-ID: <20090521195108.B4EF9169F51@codespeak.net>
Author: antocuni
Date: Thu May 21 21:51:06 2009
New Revision: 65351
Modified:
pypy/branch/pyjitpl5/pypy/config/translationoption.py
Log:
use "boehm" as a dummy value, else it conflicts with tl/pypyjit.py
Modified: pypy/branch/pyjitpl5/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/config/translationoption.py (original)
+++ pypy/branch/pyjitpl5/pypy/config/translationoption.py Thu May 21 21:51:06 2009
@@ -30,7 +30,7 @@
("translation.backendopt.heap2stack", False),
("translation.backendopt.clever_malloc_removal", False),
("translation.list_comprehension_operations", False),
- ("translation.gc", "generation"), # it's not really used, but some jit code expects a value here
+ ("translation.gc", "boehm"), # it's not really used, but some jit code expects a value here
]
}),
ChoiceOption("backend", "Backend to use for code generation",
From antocuni at codespeak.net Fri May 22 00:47:35 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 22 May 2009 00:47:35 +0200 (CEST)
Subject: [pypy-svn] r65352 - pypy/branch/pyjitpl5/pypy/jit/backend/cli
Message-ID: <20090521224735.6BE41169F01@codespeak.net>
Author: antocuni
Date: Fri May 22 00:47:33 2009
New Revision: 65352
Modified:
pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
Log:
implement sort_key() for all CLI descrs
Modified: pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/backend/cli/runner.py Fri May 22 00:47:33 2009
@@ -220,6 +220,16 @@
# ----------------------------------------------------------------------
key_manager = KeyManager()
+class DescrWithKey(AbstractDescr):
+ key = -1
+
+ def __init__(self, key):
+ self.key = key_manager.getkey(key)
+
+ def sort_key(self):
+ return self.key
+
+
def get_class_for_type(T):
if T is ootype.Void:
return ootype.nullruntimeclass
@@ -238,10 +248,10 @@
else:
assert False
-
-class TypeDescr(AbstractDescr):
+class TypeDescr(DescrWithKey):
def __init__(self, TYPE):
+ DescrWithKey.__init__(self, TYPE)
from pypy.jit.backend.llgraph.runner import boxresult
from pypy.jit.metainterp.warmspot import unwrap
ARRAY = ootype.Array(TYPE)
@@ -288,13 +298,14 @@
clitype = self.get_clitype()
return clitype.GetConstructor(dotnet.new_array(System.Type, 0))
-class StaticMethDescr(AbstractDescr):
+class StaticMethDescr(DescrWithKey):
callfunc = None
funcclass = ootype.nullruntimeclass
has_result = False
def __init__(self, FUNC, ARGS, RESULT):
+ DescrWithKey.__init__(self, (FUNC, ARGS, RESULT))
from pypy.jit.backend.llgraph.runner import boxresult, make_getargs
getargs = make_getargs(FUNC.ARGS)
def callfunc(funcbox, argboxes):
@@ -331,6 +342,7 @@
selfclass = ootype.nullruntimeclass
methname = ''
has_result = False
+ key = -1
def __init__(self, SELFTYPE, methname):
from pypy.jit.backend.llgraph.runner import boxresult, make_getargs
@@ -348,6 +360,10 @@
self.selfclass = ootype.runtimeClass(SELFTYPE)
self.methname = methname
self.has_result = (METH.RESULT != ootype.Void)
+ self.key = key_manager.getkey((SELFTYPE, methname))
+
+ def sort_key(self):
+ return self.key
def get_self_clitype(self):
return dotnet.class2type(self.selfclass)
@@ -370,15 +386,15 @@
return OpCodes.Call
-class FieldDescr(AbstractDescr):
+class FieldDescr(DescrWithKey):
getfield = None
setfield = None
selfclass = ootype.nullruntimeclass
fieldname = ''
- key = -1
def __init__(self, TYPE, fieldname):
+ DescrWithKey.__init__(self, (TYPE, fieldname))
from pypy.jit.backend.llgraph.runner import boxresult
from pypy.jit.metainterp.warmspot import unwrap
_, T = TYPE._lookup_field(fieldname)
@@ -397,9 +413,6 @@
self.fieldname = fieldname
self.key = key_manager.getkey((TYPE, fieldname))
- def sort_key(self):
- return self.key
-
def equals(self, other):
assert isinstance(other, FieldDescr)
return self.key == other.key
From pedronis at codespeak.net Fri May 22 12:40:03 2009
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Fri, 22 May 2009 12:40:03 +0200 (CEST)
Subject: [pypy-svn] r65356 - pypy/extradoc/sprintinfo/ep2009
Message-ID: <20090522104003.B1BF0169F4C@codespeak.net>
Author: pedronis
Date: Fri May 22 12:40:01 2009
New Revision: 65356
Modified:
pypy/extradoc/sprintinfo/ep2009/announcement.txt
Log:
slightly more pre-puplication friendly
Modified: pypy/extradoc/sprintinfo/ep2009/announcement.txt
==============================================================================
--- pypy/extradoc/sprintinfo/ep2009/announcement.txt (original)
+++ pypy/extradoc/sprintinfo/ep2009/announcement.txt Fri May 22 12:40:01 2009
@@ -13,7 +13,7 @@
during the conference since it will give you a good overview of the
status of development.
-XXX When/if tutorial?
+.. xxx When/if tutorial?
On the morning of the first sprint day we will also have a
tutorial session for those new to PyPy development.
@@ -24,7 +24,7 @@
There are many possible and interesting sprint topics to work on - here
we list some possible task areas:
-XXX
+TBA
------------
Registration
@@ -73,4 +73,4 @@
.. _`pypy-sprint mailing list`: http://codespeak.net/mailman/listinfo/pypy-sprint
.. _`the technical reports available and other relevant documentation`: http://codespeak.net/pypy/dist/pypy/doc/docindex.html
-.. _`EuroPython schedule`: http://europython.eu/XXX
+.. _`EuroPython schedule`: http://europython.eu/xxx
From cfbolz at codespeak.net Fri May 22 13:45:13 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 22 May 2009 13:45:13 +0200 (CEST)
Subject: [pypy-svn] r65357 - pypy/extradoc/sprintinfo/ep2009
Message-ID: <20090522114513.213EB169FA7@codespeak.net>
Author: cfbolz
Date: Fri May 22 13:45:12 2009
New Revision: 65357
Modified:
pypy/extradoc/sprintinfo/ep2009/people.txt
Log:
my dates
Modified: pypy/extradoc/sprintinfo/ep2009/people.txt
==============================================================================
--- pypy/extradoc/sprintinfo/ep2009/people.txt (original)
+++ pypy/extradoc/sprintinfo/ep2009/people.txt Fri May 22 13:45:12 2009
@@ -12,6 +12,7 @@
==================== ============== ============================
Samuele Pedroni 28/5 ?
Antonio Cuni 28/4 ETAPS Hotel (shared with cfbolz)
+Carl Friedrich Bolz 28/4 ETAPS Hotel
==================== ============== ============================
People on the following list were present at previous sprints:
@@ -31,7 +32,6 @@
Bert Freudenberg ? ?
Boris Feigin ? ?
Camillo Bruni ? ?
-Carl Friedrich Bolz ? ?
Christian Tismer ? ?
Eric van Riet Paap ? ?
Guido Wesdorp ? ?
From antocuni at codespeak.net Fri May 22 13:56:38 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 22 May 2009 13:56:38 +0200 (CEST)
Subject: [pypy-svn] r65358 - pypy/branch/pyjitpl5/pypy/jit/metainterp/test
Message-ID: <20090522115638.A6D4F169EB1@codespeak.net>
Author: antocuni
Date: Fri May 22 13:56:38 2009
New Revision: 65358
Modified:
pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py
Log:
these two tests pass also on ootype nowadays
Modified: pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py (original)
+++ pypy/branch/pyjitpl5/pypy/jit/metainterp/test/test_tl.py Fri May 22 13:56:38 2009
@@ -95,8 +95,6 @@
def test_tl_base(self):
res = self.meta_interp(self.main.im_func, [0, 6], listops=True)
assert res == 5040
- if self.type_system == 'ootype':
- py.test.skip('optimizing problem')
self.check_loops({'int_mul':1, 'jump':1,
'int_sub':1, 'int_is_true':1, 'int_le':1,
'guard_false':1, 'guard_value':1})
@@ -104,8 +102,6 @@
def test_tl_2(self):
res = self.meta_interp(self.main.im_func, [1, 10], listops=True)
assert res == self.main.im_func(1, 10)
- if self.type_system == 'ootype':
- py.test.skip('optimizing problem')
self.check_loops({'int_sub':1, 'int_le':1,
'int_is_true':1, 'guard_false':1, 'jump':1,
'guard_value':1})
From cfbolz at codespeak.net Fri May 22 18:43:46 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 22 May 2009 18:43:46 +0200 (CEST)
Subject: [pypy-svn] r65359 - pypy/branch/speedup-global2
Message-ID: <20090522164346.5F61E169F29@codespeak.net>
Author: cfbolz
Date: Fri May 22 18:43:44 2009
New Revision: 65359
Added:
pypy/branch/speedup-global2/
- copied from r65358, pypy/trunk/
Log:
Make a new branch for fixing globals, to have a new enough py-lib on it to be
able to start a buildbot run.
From cfbolz at codespeak.net Fri May 22 18:53:15 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 22 May 2009 18:53:15 +0200 (CEST)
Subject: [pypy-svn] r65360 - in pypy/branch/speedup-global2/pypy: config
interpreter objspace objspace/fake objspace/std
objspace/std/test translator/microbench
Message-ID: <20090522165315.42F1F16A004@codespeak.net>
Author: cfbolz
Date: Fri May 22 18:53:13 2009
New Revision: 65360
Added:
pypy/branch/speedup-global2/pypy/objspace/std/celldict.py (contents, props changed)
pypy/branch/speedup-global2/pypy/objspace/std/test/test_celldict.py (contents, props changed)
Modified:
pypy/branch/speedup-global2/pypy/config/pypyoption.py
pypy/branch/speedup-global2/pypy/interpreter/module.py
pypy/branch/speedup-global2/pypy/interpreter/pycode.py
pypy/branch/speedup-global2/pypy/objspace/fake/objspace.py
pypy/branch/speedup-global2/pypy/objspace/reflective.py
pypy/branch/speedup-global2/pypy/objspace/std/dictmultiobject.py
pypy/branch/speedup-global2/pypy/objspace/std/objspace.py
pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictmultiobject.py
pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictobject.py
pypy/branch/speedup-global2/pypy/translator/microbench/test_count1.py
Log:
Port over changes from old speedup-globals branch:
------------------------------------------------------------------------
r62765 | cfbolz | 2009-03-09 17:53:28 +0100 (Mon, 09 Mar 2009) | 3 lines
Changed paths:
A /pypy/branch/speedup-globals (from /pypy/trunk:62764)
A branch to try Armin's and mine newest idea about how to speed up global
lookups.
------------------------------------------------------------------------
r62773 | cfbolz | 2009-03-09 19:02:50 +0100 (Mon, 09 Mar 2009) | 5 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/config/pypyoption.py
M /pypy/branch/speedup-globals/pypy/interpreter/module.py
M /pypy/branch/speedup-globals/pypy/objspace/fake/objspace.py
M /pypy/branch/speedup-globals/pypy/objspace/reflective.py
M /pypy/branch/speedup-globals/pypy/objspace/std/dictmultiobject.py
M /pypy/branch/speedup-globals/pypy/objspace/std/objspace.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_dictmultiobject.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_dictobject.py
First step to make global lookups faster: Introduce a special dict
implementation for modules, where every value in the RPython-level dict is a
cell that contains the real value. As long as the "valid" flag on such a cell is
set, it is safe to store the cell somewhere else.
------------------------------------------------------------------------
r62811 | cfbolz | 2009-03-10 16:00:52 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
A /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/dictmultiobject.py
M /pypy/branch/speedup-globals/pypy/objspace/std/objspace.py
A /pypy/branch/speedup-globals/pypy/objspace/std/test/test_celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_dictmultiobject.py
Actually use the cell-dict stuff to cache global lookups in frames.
------------------------------------------------------------------------
r62816 | cfbolz | 2009-03-10 16:34:17 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
help flow space
------------------------------------------------------------------------
r62819 | cfbolz | 2009-03-10 17:54:44 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/translator/benchmark/benchmarks.py
fix typo
------------------------------------------------------------------------
r62823 | cfbolz | 2009-03-10 17:57:56 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/translator/benchmark/benchmarks.py
fix gadfly
------------------------------------------------------------------------
r62827 | cfbolz | 2009-03-10 19:07:12 +0100 (Tue, 10 Mar 2009) | 4 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/interpreter/pycode.py
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
It turns out that using one additional dict lookup per call negates many of the
benefits of this optimization. Therefore, attach the cache to the code object
directly.
------------------------------------------------------------------------
r62830 | cfbolz | 2009-03-10 20:38:30 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/translator/microbench/test_count1.py
two more microbenchmarks
------------------------------------------------------------------------
r62845 | cfbolz | 2009-03-11 11:54:45 +0100 (Wed, 11 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_celldict.py
get rid of invalid flag
------------------------------------------------------------------------
r62856 | cfbolz | 2009-03-11 13:16:33 +0100 (Wed, 11 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_celldict.py
fix a corner-case
------------------------------------------------------------------------
Modified: pypy/branch/speedup-global2/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/config/pypyoption.py (original)
+++ pypy/branch/speedup-global2/pypy/config/pypyoption.py Fri May 22 18:53:13 2009
@@ -228,6 +228,13 @@
"use dictionaries optimized for flexibility",
default=False),
+ BoolOption("withcelldict",
+ "use dictionaries that are opimized for being used as module dicts",
+ default=False,
+ requires=[("objspace.std.withmultidict", True),
+ ("objspace.opcodes.CALL_LIKELY_BUILTIN", False),
+ ("objspace.honor__builtins__", False)]),
+
BoolOption("withsharingdict",
"use dictionaries that share the keys part",
default=False,
Modified: pypy/branch/speedup-global2/pypy/interpreter/module.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/interpreter/module.py (original)
+++ pypy/branch/speedup-global2/pypy/interpreter/module.py Fri May 22 18:53:13 2009
@@ -11,7 +11,7 @@
def __init__(self, space, w_name, w_dict=None):
self.space = space
if w_dict is None:
- w_dict = space.newdict(track_builtin_shadowing=True)
+ w_dict = space.newdict(module=True)
self.w_dict = w_dict
self.w_name = w_name
if w_name is not None:
Modified: pypy/branch/speedup-global2/pypy/interpreter/pycode.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/interpreter/pycode.py (original)
+++ pypy/branch/speedup-global2/pypy/interpreter/pycode.py Fri May 22 18:53:13 2009
@@ -111,6 +111,10 @@
self._compute_flatcall()
+ if space.config.objspace.std.withcelldict:
+ from pypy.objspace.std.celldict import init_code
+ init_code(self)
+
co_names = property(lambda self: [self.space.unwrap(w_name) for w_name in self.co_names_w]) # for trace
def signature(self):
Modified: pypy/branch/speedup-global2/pypy/objspace/fake/objspace.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/objspace/fake/objspace.py (original)
+++ pypy/branch/speedup-global2/pypy/objspace/fake/objspace.py Fri May 22 18:53:13 2009
@@ -93,7 +93,7 @@
newint = make_dummy()
newlong = make_dummy()
newfloat = make_dummy()
- def newdict(self, track_builtin_shadowing=False):
+ def newdict(self, module=False):
return self.newfloat()
newlist = make_dummy()
emptylist = make_dummy()
Modified: pypy/branch/speedup-global2/pypy/objspace/reflective.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/objspace/reflective.py (original)
+++ pypy/branch/speedup-global2/pypy/objspace/reflective.py Fri May 22 18:53:13 2009
@@ -137,8 +137,8 @@
return None
if opname == "newdict": # grr grr kwargs
- def fn(track_builtin_shadowing=False):
- w_obj = parentfn(track_builtin_shadowing)
+ def fn(module=False):
+ w_obj = parentfn(module)
w_newobj = user_hook(w_obj)
if w_newobj is not None:
return w_newobj
Added: pypy/branch/speedup-global2/pypy/objspace/std/celldict.py
==============================================================================
--- (empty file)
+++ pypy/branch/speedup-global2/pypy/objspace/std/celldict.py Fri May 22 18:53:13 2009
@@ -0,0 +1,248 @@
+from pypy.objspace.std.dictmultiobject import DictImplementation
+from pypy.objspace.std.dictmultiobject import IteratorImplementation
+from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash
+
+class ModuleCell(object):
+ def __init__(self, w_value=None):
+ self.w_value = w_value
+
+ def invalidate(self):
+ w_value = self.w_value
+ self.w_value = None
+ return w_value
+
+ def __repr__(self):
+ return "" % (self.w_value, )
+
+class ModuleDictImplementation(DictImplementation):
+ def __init__(self, space):
+ self.space = space
+ self.content = {}
+ self.unshadowed_builtins = {}
+
+ def getcell(self, key, make_new=True):
+ try:
+ return self.content[key]
+ except KeyError:
+ if not make_new:
+ raise
+ result = self.content[key] = ModuleCell()
+ return result
+
+ def add_unshadowed_builtin(self, name, builtin_impl):
+ assert isinstance(builtin_impl, ModuleDictImplementation)
+ self.unshadowed_builtins[name] = builtin_impl
+
+ def invalidate_unshadowed_builtin(self, name):
+ impl = self.unshadowed_builtins[name]
+ try:
+ cell = impl.content[name]
+ except KeyError:
+ pass
+ else:
+ w_value = cell.invalidate()
+ cell = impl.content[name] = ModuleCell(w_value)
+
+ def setitem(self, w_key, w_value):
+ space = self.space
+ if space.is_w(space.type(w_key), space.w_str):
+ return self.setitem_str(w_key, w_value)
+ else:
+ return self._as_rdict().setitem(w_key, w_value)
+
+ def setitem_str(self, w_key, w_value, shadows_type=True):
+ name = self.space.str_w(w_key)
+ self.getcell(name).w_value = w_value
+
+ if name in self.unshadowed_builtins:
+ self.invalidate_unshadowed_builtin(name)
+ del self.unshadowed_builtins[name]
+
+ return self
+
+ def delitem(self, w_key):
+ space = self.space
+ w_key_type = space.type(w_key)
+ if space.is_w(w_key_type, space.w_str):
+ key = space.str_w(w_key)
+ cell = self.getcell(key, False)
+ cell.invalidate()
+ del self.content[key]
+ return self
+ elif _is_sane_hash(space, w_key_type):
+ raise KeyError
+ else:
+ return self._as_rdict().delitem(w_key)
+
+ def length(self):
+ return len(self.content)
+
+ def get(self, w_lookup):
+ space = self.space
+ w_lookup_type = space.type(w_lookup)
+ if space.is_w(w_lookup_type, space.w_str):
+ try:
+ return self.getcell(space.str_w(w_lookup), False).w_value
+ except KeyError:
+ return None
+ elif _is_sane_hash(space, w_lookup_type):
+ return None
+ else:
+ return self._as_rdict().get(w_lookup)
+
+ def iteritems(self):
+ return ModuleDictItemIteratorImplementation(self.space, self)
+
+ def iterkeys(self):
+ return ModuleDictKeyIteratorImplementation(self.space, self)
+
+ def itervalues(self):
+ return ModuleDictValueIteratorImplementation(self.space, self)
+
+ def keys(self):
+ space = self.space
+ return [space.wrap(key) for key in self.content.iterkeys()]
+
+ def values(self):
+ return [cell.w_value for cell in self.content.itervalues()]
+
+ def items(self):
+ space = self.space
+ return [space.newtuple([space.wrap(key), cell.w_value])
+ for (key, cell) in self.content.iteritems()]
+
+ def _as_rdict(self):
+ newimpl = self.space.DefaultDictImpl(self.space)
+ for k, cell in self.content.iteritems():
+ newimpl.setitem(self.space.wrap(k), cell.w_value)
+ cell.invalidate()
+ for k in self.unshadowed_builtins:
+ self.invalidate_unshadowed_builtin(k)
+ return newimpl
+
+# grrrrr. just a copy-paste from StrKeyIteratorImplementation in dictmultiobject
+class ModuleDictKeyIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iterkeys()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key in self.iterator:
+ return self.space.wrap(key)
+ else:
+ return None
+
+class ModuleDictValueIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.itervalues()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for cell in self.iterator:
+ return cell.w_value
+ else:
+ return None
+
+class ModuleDictItemIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key, cell in self.iterator:
+ return self.space.newtuple([self.space.wrap(key), cell.w_value])
+ else:
+ return None
+
+
+
+
+
+
+
+class State(object):
+ def __init__(self, space):
+ self.space = space
+ self.invalidcell = ModuleCell()
+ self.always_invalid_cache = []
+ self.neverused_dictimpl = ModuleDictImplementation(space)
+
+class GlobalCacheHolder(object):
+ def __init__(self, space):
+ self.cache = None
+ state = space.fromcache(State)
+ self.dictimpl = state.neverused_dictimpl
+
+ def getcache(self, space, code, w_globals):
+ implementation = getimplementation(w_globals)
+ if self.dictimpl is implementation:
+ return self.cache
+ return self.getcache_slow(space, code, w_globals, implementation)
+ getcache._always_inline_ = True
+
+ def getcache_slow(self, space, code, w_globals, implementation):
+ state = space.fromcache(State)
+ if not isinstance(implementation, ModuleDictImplementation):
+ missing_length = max(len(code.co_names_w) - len(state.always_invalid_cache), 0)
+ state.always_invalid_cache.extend([state.invalidcell] * missing_length)
+ cache = state.always_invalid_cache
+ else:
+ cache = [state.invalidcell] * len(code.co_names_w)
+ self.cache = cache
+ self.dictimpl = implementation
+ return cache
+ getcache_slow._dont_inline_ = True
+
+def init_code(code):
+ code.globalcacheholder = GlobalCacheHolder(code.space)
+
+
+def get_global_cache(space, code, w_globals):
+ from pypy.interpreter.pycode import PyCode
+ if not isinstance(code, PyCode):
+ return []
+ holder = code.globalcacheholder
+ return holder.getcache(space, code, w_globals)
+
+def getimplementation(w_dict):
+ if type(w_dict) is W_DictMultiObject:
+ return w_dict.implementation
+ else:
+ return None
+
+def LOAD_GLOBAL(f, nameindex, *ignored):
+ cell = f.cache_for_globals[nameindex]
+ w_value = cell.w_value
+ if w_value is None:
+ # slow path
+ w_value = load_global_fill_cache(f, nameindex)
+ f.pushvalue(w_value)
+LOAD_GLOBAL._always_inline_ = True
+
+def find_cell_from_dict(implementation, name):
+ if isinstance(implementation, ModuleDictImplementation):
+ try:
+ return implementation.getcell(name, False)
+ except KeyError:
+ return None
+ return None
+
+def load_global_fill_cache(f, nameindex):
+ name = f.space.str_w(f.getname_w(nameindex))
+ implementation = getimplementation(f.w_globals)
+ if isinstance(implementation, ModuleDictImplementation):
+ cell = find_cell_from_dict(implementation, name)
+ if cell is None:
+ builtin_impl = getimplementation(f.get_builtin().getdict())
+ cell = find_cell_from_dict(builtin_impl, name)
+ if cell is not None:
+ implementation.add_unshadowed_builtin(name, builtin_impl)
+
+ if cell is not None:
+ f.cache_for_globals[nameindex] = cell
+ return cell.w_value
+ return f._load_global(f.getname_w(nameindex))
+load_global_fill_cache._dont_inline_ = True
Modified: pypy/branch/speedup-global2/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/branch/speedup-global2/pypy/objspace/std/dictmultiobject.py Fri May 22 18:53:13 2009
@@ -865,7 +865,6 @@
else:
return None
-
import time, py
class DictInfo(object):
@@ -1038,8 +1037,11 @@
class W_DictMultiObject(W_Object):
from pypy.objspace.std.dicttype import dict_typedef as typedef
- def __init__(w_self, space, wary=False, sharing=False):
- if space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and wary:
+ def __init__(w_self, space, wary=False, sharing=False, module=False):
+ if space.config.objspace.std.withcelldict and wary:
+ from pypy.objspace.std.celldict import ModuleDictImplementation
+ w_self.implementation = ModuleDictImplementation(space)
+ elif space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and wary:
w_self.implementation = WaryDictImplementation(space)
elif space.config.objspace.std.withdictmeasurement:
w_self.implementation = MeasuringDictImplementation(space)
Modified: pypy/branch/speedup-global2/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/objspace/std/objspace.py (original)
+++ pypy/branch/speedup-global2/pypy/objspace/std/objspace.py Fri May 22 18:53:13 2009
@@ -72,7 +72,16 @@
# Import all the object types and implementations
self.model = StdTypeModel(self.config)
+ from pypy.objspace.std.celldict import get_global_cache
+
class StdObjSpaceFrame(pyframe.PyFrame):
+ if self.config.objspace.std.withcelldict:
+ def __init__(self, space, code, w_globals, closure):
+ pyframe.PyFrame.__init__(self, space, code, w_globals, closure)
+ self.cache_for_globals = get_global_cache(space, code, w_globals)
+
+ from pypy.objspace.std.celldict import LOAD_GLOBAL
+
if self.config.objspace.std.optimized_int_add:
if self.config.objspace.std.withsmallint:
def BINARY_ADD(f, oparg, *ignored):
@@ -580,8 +589,8 @@
from pypy.objspace.std.listobject import W_ListObject
return W_ListObject(list_w)
- def newdict(self, track_builtin_shadowing=False):
- if self.config.objspace.opcodes.CALL_LIKELY_BUILTIN and track_builtin_shadowing:
+ def newdict(self, module=False):
+ if self.config.objspace.std.withmultidict and module:
from pypy.objspace.std.dictmultiobject import W_DictMultiObject
return W_DictMultiObject(self, wary=True)
return self.DictObjectCls(self)
Added: pypy/branch/speedup-global2/pypy/objspace/std/test/test_celldict.py
==============================================================================
--- (empty file)
+++ pypy/branch/speedup-global2/pypy/objspace/std/test/test_celldict.py Fri May 22 18:53:13 2009
@@ -0,0 +1,259 @@
+from pypy.conftest import gettestobjspace
+from pypy.objspace.std.celldict import get_global_cache, ModuleCell, ModuleDictImplementation
+from pypy.interpreter import gateway
+
+# this file tests mostly the effects of caching global lookup. The dict
+# implementation itself is tested in test_dictmultiobject.py
+
+
+class AppTestCellDict(object):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withcelldict": True})
+ cls.w_impl_used = cls.space.appexec([], """():
+ import __pypy__
+ def impl_used(obj):
+ assert "ModuleDictImplementation" in __pypy__.internal_repr(obj)
+ return impl_used
+ """)
+ def is_in_cache(space, w_code, w_globals, w_name):
+ name = space.str_w(w_name)
+ cache = get_global_cache(space, w_code, w_globals)
+ index = [space.str_w(w_n) for w_n in w_code.co_names_w].index(name)
+ return space.wrap(cache[index].w_value is not None)
+ is_in_cache = gateway.interp2app(is_in_cache)
+ cls.w_is_in_cache = cls.space.wrap(is_in_cache)
+ stored_builtins = []
+ def rescue_builtins(space):
+ w_dict = space.builtin.getdict()
+ content = {}
+ for key, cell in w_dict.implementation.content.iteritems():
+ newcell = ModuleCell()
+ newcell.w_value = cell.w_value
+ content[key] = newcell
+ stored_builtins.append(content)
+ rescue_builtins = gateway.interp2app(rescue_builtins)
+ cls.w_rescue_builtins = cls.space.wrap(rescue_builtins)
+ def restore_builtins(space):
+ w_dict = space.builtin.getdict()
+ if not isinstance(w_dict.implementation, ModuleDictImplementation):
+ w_dict.implementation = ModuleDictImplementation(space)
+ w_dict.implementation.content = stored_builtins.pop()
+ restore_builtins = gateway.interp2app(restore_builtins)
+ cls.w_restore_builtins = cls.space.wrap(restore_builtins)
+
+ def test_same_code_in_different_modules(self):
+ import sys
+ mod1 = type(sys)("abc")
+ self.impl_used(mod1.__dict__)
+ glob1 = mod1.__dict__
+ mod2 = type(sys)("abc")
+ self.impl_used(mod2.__dict__)
+ glob2 = mod2.__dict__
+ def f():
+ return x + 1
+ code = f.func_code
+ f1 = type(f)(code, glob1)
+ mod1.x = 1
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ mod1.x = 2
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "x")
+ f2 = type(f)(code, glob2)
+ mod2.x = 5
+ assert not self.is_in_cache(code, glob2, "x")
+ assert f2() == 6
+ assert self.is_in_cache(code, glob2, "x")
+ assert f2() == 6
+ assert self.is_in_cache(code, glob2, "x")
+ mod2.x = 7
+ assert f2() == 8
+ assert self.is_in_cache(code, glob2, "x")
+ assert f2() == 8
+ assert self.is_in_cache(code, glob2, "x")
+
+ def test_override_builtins(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ glob1 = mod1.__dict__
+ self.impl_used(mod1.__dict__)
+ def f():
+ return len(x)
+ code = f.func_code
+ f1 = type(f)(f.func_code, glob1)
+ mod1.x = []
+ assert not self.is_in_cache(code, glob1, "len")
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ assert self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ mod1.x.append(1)
+ assert f1() == 1
+ assert self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+ mod1.len = lambda x: 15
+ assert not self.is_in_cache(code, glob1, "len")
+ mod1.x.append(1)
+ assert f1() == 15
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 15
+ assert self.is_in_cache(code, glob1, "len")
+ del mod1.len
+ mod1.x.append(1)
+ assert not self.is_in_cache(code, glob1, "len")
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "len")
+ orig_len = __builtins__.len
+ try:
+ __builtins__.len = lambda x: 12
+ mod1.x.append(1)
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 12
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 12
+ assert self.is_in_cache(code, glob1, "len")
+ finally:
+ __builtins__.len = orig_len
+
+ def test_override_builtins2(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ glob1 = mod1.__dict__
+ self.impl_used(mod1.__dict__)
+ def f():
+ return l(x)
+ code = f.func_code
+ f1 = type(f)(f.func_code, glob1)
+ mod1.x = []
+ __builtin__.l = len
+ try:
+ assert not self.is_in_cache(code, glob1, "l")
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ assert self.is_in_cache(code, glob1, "l")
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ mod1.x.append(1)
+ assert f1() == 1
+ assert self.is_in_cache(code, glob1, "l")
+ assert self.is_in_cache(code, glob1, "x")
+ del __builtin__.l
+ mod1.l = len
+ mod1.x.append(1)
+ assert not self.is_in_cache(code, glob1, "l")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "l")
+ assert self.is_in_cache(code, glob1, "x")
+ finally:
+ if hasattr(__builtins__, "l"):
+ del __builtins__.l
+
+ def test_generator(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ glob1 = mod1.__dict__
+ self.impl_used(mod1.__dict__)
+ def f():
+ yield 1
+ yield x
+ yield len(x)
+ code = f.func_code
+ f1 = type(f)(f.func_code, glob1)
+ mod1.x = []
+ gen = f1()
+ assert not self.is_in_cache(code, glob1, "len")
+ assert not self.is_in_cache(code, glob1, "x")
+ v = gen.next()
+ assert v == 1
+ assert not self.is_in_cache(code, glob1, "len")
+ assert not self.is_in_cache(code, glob1, "x")
+ v = gen.next()
+ assert v is mod1.x
+ assert not self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+ v = gen.next()
+ assert v == 0
+ assert self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+
+ def test_degenerate_to_rdict(self):
+ import sys
+ mod1 = type(sys)("abc")
+ self.impl_used(mod1.__dict__)
+ glob1 = mod1.__dict__
+ def f():
+ return x + 1
+ code = f.func_code
+ f1 = type(f)(code, glob1)
+ mod1.x = 1
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ glob1[1] = 2
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert not self.is_in_cache(code, glob1, "x")
+
+ def test_degenerate_builtin_to_rdict(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ self.impl_used(mod1.__dict__)
+ glob1 = mod1.__dict__
+ def f():
+ return len(x)
+ code = f.func_code
+ f1 = type(f)(code, glob1)
+ mod1.x = [1, 2]
+ assert not self.is_in_cache(code, glob1, "x")
+ assert not self.is_in_cache(code, glob1, "len")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ assert self.is_in_cache(code, glob1, "len")
+ self.rescue_builtins()
+ try:
+ __builtin__.__dict__[1] = 2
+ assert not self.is_in_cache(code, glob1, "len")
+ assert f1() == 2
+ assert not self.is_in_cache(code, glob1, "len")
+ finally:
+ self.restore_builtins()
+
+ def test_mapping_as_locals(self):
+ import sys
+ if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'):
+ skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements")
+ class M(object):
+ def __getitem__(self, key):
+ return key
+ def __setitem__(self, key, value):
+ self.result[key] = value
+ m = M()
+ m.result = {}
+ exec "x=m" in {}, m
+ assert m.result == {'x': 'm'}
+ exec "y=n" in m # NOTE: this doesn't work in CPython 2.4
+ assert m.result == {'x': 'm', 'y': 'n'}
+
+ def test_subclass_of_dict_as_locals(self):
+ import sys
+ if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'):
+ skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements")
+ class M(dict):
+ def __getitem__(self, key):
+ return key
+ def __setitem__(self, key, value):
+ dict.__setitem__(self, key, value)
+ m = M()
+ exec "x=m" in {}, m
+ assert m == {'x': 'm'}
+ exec "y=n" in m # NOTE: this doesn't work in CPython 2.4
+ assert m == {'x': 'm', 'y': 'n'}
+
Modified: pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictmultiobject.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictmultiobject.py (original)
+++ pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictmultiobject.py Fri May 22 18:53:13 2009
@@ -3,6 +3,8 @@
W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \
EmptyDictImplementation, RDictImplementation, StrDictImplementation, \
SmallDictImplementation, SmallStrDictImplementation, MeasuringDictImplementation
+
+from pypy.objspace.std.celldict import ModuleDictImplementation
from pypy.conftest import gettestobjspace
from pypy.objspace.std.test import test_dictobject
@@ -58,6 +60,26 @@
a.__dict__.items() == [("abc", 12)]
+class AppTestModuleDict(object):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withcelldict": True})
+ cls.w_impl_used = cls.space.appexec([], """():
+ import __pypy__
+ def impl_used(obj):
+ assert "ModuleDictImplementation" in __pypy__.internal_repr(obj)
+ return impl_used
+ """)
+
+
+ def test_check_module_uses_module_dict(self):
+ m = type(__builtins__)("abc")
+ self.impl_used(m.__dict__)
+
+ def test_key_not_there(self):
+ d = type(__builtins__)("abc").__dict__
+ raises(KeyError, "d['def']")
+
+
class TestW_DictSmall(test_dictobject.TestW_DictObject):
def setup_class(cls):
@@ -233,3 +255,15 @@
def get_impl(self):
return self.ImplementionClass(self.space, self.string, self.string2)
+
+class TestModuleDictImplementation(TestRDictImplementation):
+ ImplementionClass = ModuleDictImplementation
+ EmptyClass = ModuleDictImplementation
+
+class TestModuleDictImplementationWithBuiltinNames(TestRDictImplementation):
+ ImplementionClass = ModuleDictImplementation
+ EmptyClass = ModuleDictImplementation
+
+ string = "int"
+ string2 = "isinstance"
+
Modified: pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictobject.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictobject.py (original)
+++ pypy/branch/speedup-global2/pypy/objspace/std/test/test_dictobject.py Fri May 22 18:53:13 2009
@@ -489,6 +489,7 @@
FakeSpace.config.objspace.std.withdictmeasurement = False
FakeSpace.config.objspace.std.withsharingdict = False
FakeSpace.config.objspace.std.withsmalldicts = False
+FakeSpace.config.objspace.std.withcelldict = False
FakeSpace.config.objspace.opcodes = Config()
FakeSpace.config.objspace.opcodes.CALL_LIKELY_BUILTIN = False
Modified: pypy/branch/speedup-global2/pypy/translator/microbench/test_count1.py
==============================================================================
--- pypy/branch/speedup-global2/pypy/translator/microbench/test_count1.py (original)
+++ pypy/branch/speedup-global2/pypy/translator/microbench/test_count1.py Fri May 22 18:53:13 2009
@@ -201,3 +201,15 @@
y = y + 1
c += 1
+def test_count_with_True():
+ x = 0
+ n = N
+ while x < n:
+ x = x + True
+
+increment = 1
+def test_count_with_global_increment():
+ x = 0
+ n = N
+ while x < n:
+ x = x + increment
From fijal at codespeak.net Fri May 22 21:18:48 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 22 May 2009 21:18:48 +0200 (CEST)
Subject: [pypy-svn] r65361 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/doc
Message-ID: <20090522191848.58F19169FEC@codespeak.net>
Author: fijal
Date: Fri May 22 21:18:45 2009
New Revision: 65361
Added:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/doc/simple_virtualizables.txt (contents, props changed)
Log:
start a document explaining simplified approach to virtualizables
Added: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/doc/simple_virtualizables.txt
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/doc/simple_virtualizables.txt Fri May 22 21:18:45 2009
@@ -0,0 +1,24 @@
+Simplified virtualizables
+=========================
+
+As a first step for speeding up code, we plan to implement simplified version
+of virtualizables. Simplified in a sense that it won't support virtuals stored
+on virtualizables.
+
+For those unaware:
+
+* Virtuals are objects which are known not to escape from jit code, hence
+ they're not allocated at all and their fields are stored in registers and or
+ on the stack.
+
+* Virtualizables are objects that are known to escape (for example the frame
+ object), but they're stored anyway on the stack with a way to access and
+ modify from outside the jit code. So the jit knows where they're and have
+ a way to reconstruct them if necessary.
+
+The way to implement virtualizables would be as follows:
+
+* During translation, all field accesses to virtualizables are replace by
+ calls to helpers that read/write fields via the jit.
+
+XXX
From antocuni at codespeak.net Sat May 23 15:10:30 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 23 May 2009 15:10:30 +0200 (CEST)
Subject: [pypy-svn] r65362 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090523131030.C2139169F4D@codespeak.net>
Author: antocuni
Date: Sat May 23 15:10:28 2009
New Revision: 65362
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
port tests to ootype
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Sat May 23 15:10:28 2009
@@ -1,95 +1,122 @@
-
import py
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.ootypesystem import ootype
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.history import ConstAddr, BoxPtr, TreeLoop,\
- ConstInt, BoxInt
+ ConstInt, BoxInt, BoxObj, ConstObj
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp.optimize2 import optimize_loop
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
-node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
-node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
-cpu = runner.LLtypeCPU(None)
-vtable_box = ConstAddr(node_vtable_adr, cpu)
-
-NODE = lltype.GcForwardReference()
-NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT),
- ('value', lltype.Signed),
- ('next', lltype.Ptr(NODE))))
-node = lltype.malloc(NODE)
-nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
-nodedescr = cpu.fielddescrof(NODE, 'value')
-
-def newloop(inputargs, operations):
- loop = TreeLoop("test")
- loop.inputargs = inputargs
- loop.operations = operations
- return loop
-
-def test_remove_guard_class():
- ops = [
- ResOperation(rop.GUARD_CLASS, [nodebox, vtable_box], None),
- ResOperation(rop.GUARD_CLASS, [nodebox, vtable_box], None),
- ]
- ops[0].suboperations = [ResOperation(rop.FAIL, [], None)]
- ops[1].suboperations = [ResOperation(rop.FAIL, [], None)]
- loop = newloop([nodebox], ops)
- optimize_loop(None, [], loop)
- assert len(loop.operations) == 1
-
-def test_remove_consecutive_guard_value_constfold():
- n = BoxInt(0)
- n1 = BoxInt(1)
- n2 = BoxInt(3)
- ops = [
- ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
- ResOperation(rop.INT_ADD, [n, ConstInt(1)], n1),
- ResOperation(rop.GUARD_VALUE, [n1, ConstInt(1)], None),
- ResOperation(rop.INT_ADD, [n1, ConstInt(2)], n2),
- ]
- ops[0].suboperations = [ResOperation(rop.FAIL, [], None)]
- ops[2].suboperations = [ResOperation(rop.FAIL, [], None)]
- loop = newloop([n], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
- ])
-
-def test_remove_consecutive_getfields():
- n1 = BoxInt()
- n2 = BoxInt()
- n3 = BoxInt()
- ops = [
- ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
- ResOperation(rop.GETFIELD_GC, [nodebox], n2, nodedescr),
- ResOperation(rop.INT_ADD, [n1, n2], n3),
- ]
- loop = newloop([nodebox], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
- ResOperation(rop.INT_ADD, [n1, n1], n3),
- ])
-
-def test_setfield_getfield_clean_cache():
- n1 = BoxInt()
- n2 = BoxInt()
- n3 = BoxInt()
- ops = [
- ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
- ResOperation(rop.SETFIELD_GC, [nodebox, ConstInt(3)], None, nodedescr),
- ResOperation(rop.GETFIELD_GC, [nodebox], n2, nodedescr),
- ResOperation(rop.CALL, [n2], None),
- ]
- loop = newloop([nodebox], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GETFIELD_GC, [nodebox], n1, nodedescr),
- ResOperation(rop.SETFIELD_GC, [nodebox, ConstInt(3)], None, nodedescr),
- ResOperation(rop.CALL, [ConstInt(3)], None),
- ])
+class LLtypeMixin(object):
+
+ node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
+ node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
+ cpu = runner.LLtypeCPU(None)
+ vtable_box = ConstAddr(node_vtable_adr, cpu)
+
+ NODE = lltype.GcForwardReference()
+ NODE.become(lltype.GcStruct('NODE', ('parent', OBJECT),
+ ('value', lltype.Signed),
+ ('next', lltype.Ptr(NODE))))
+ node = lltype.malloc(NODE)
+ nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
+ nodedescr = cpu.fielddescrof(NODE, 'value')
+
+class OOtypeMixin(object):
+ cpu = runner.OOtypeCPU(None)
+
+ NODE = ootype.Instance('NODE', ootype.ROOT, {})
+ NODE._add_fields({'value': ootype.Signed,
+ 'next': NODE})
+
+ node_vtable = ootype.runtimeClass(NODE)
+ vtable_box = ConstObj(ootype.cast_to_object(node_vtable))
+
+ node = ootype.new(NODE)
+ nodebox = BoxObj(ootype.cast_to_object(node))
+ nodedescr = cpu.fielddescrof(NODE, 'value')
+
+
+
+class BaseTestOptimize2(object):
+
+ @staticmethod
+ def newloop(inputargs, operations):
+ loop = TreeLoop("test")
+ loop.inputargs = inputargs
+ loop.operations = operations
+ return loop
+
+ def test_remove_guard_class(self):
+ ops = [
+ ResOperation(rop.GUARD_CLASS, [self.nodebox, self.vtable_box], None),
+ ResOperation(rop.GUARD_CLASS, [self.nodebox, self.vtable_box], None),
+ ]
+ ops[0].suboperations = [ResOperation(rop.FAIL, [], None)]
+ ops[1].suboperations = [ResOperation(rop.FAIL, [], None)]
+ loop = self.newloop([self.nodebox], ops)
+ optimize_loop(None, [], loop)
+ assert len(loop.operations) == 1
+
+ def test_remove_consecutive_guard_value_constfold(self):
+ n = BoxInt(0)
+ n1 = BoxInt(1)
+ n2 = BoxInt(3)
+ ops = [
+ ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
+ ResOperation(rop.INT_ADD, [n, ConstInt(1)], n1),
+ ResOperation(rop.GUARD_VALUE, [n1, ConstInt(1)], None),
+ ResOperation(rop.INT_ADD, [n1, ConstInt(2)], n2),
+ ]
+ ops[0].suboperations = [ResOperation(rop.FAIL, [], None)]
+ ops[2].suboperations = [ResOperation(rop.FAIL, [], None)]
+ loop = self.newloop([n], ops)
+ optimize_loop(None, [], loop)
+ equaloplists(loop.operations, [
+ ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
+ ])
+
+ def test_remove_consecutive_getfields(self):
+ n1 = BoxInt()
+ n2 = BoxInt()
+ n3 = BoxInt()
+ ops = [
+ ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
+ ResOperation(rop.GETFIELD_GC, [self.nodebox], n2, self.nodedescr),
+ ResOperation(rop.INT_ADD, [n1, n2], n3),
+ ]
+ loop = self.newloop([self.nodebox], ops)
+ optimize_loop(None, [], loop)
+ equaloplists(loop.operations, [
+ ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
+ ResOperation(rop.INT_ADD, [n1, n1], n3),
+ ])
+
+ def test_setfield_getfield_clean_cache(self):
+ n1 = BoxInt()
+ n2 = BoxInt()
+ n3 = BoxInt()
+ ops = [
+ ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
+ ResOperation(rop.SETFIELD_GC, [self.nodebox, ConstInt(3)], None, self.nodedescr),
+ ResOperation(rop.GETFIELD_GC, [self.nodebox], n2, self.nodedescr),
+ ResOperation(rop.CALL, [n2], None),
+ ]
+ loop = self.newloop([self.nodebox], ops)
+ optimize_loop(None, [], loop)
+ equaloplists(loop.operations, [
+ ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
+ ResOperation(rop.SETFIELD_GC, [self.nodebox, ConstInt(3)], None, self.nodedescr),
+ ResOperation(rop.CALL, [ConstInt(3)], None),
+ ])
+
+
+class TestLLtype(LLtypeMixin, BaseTestOptimize2):
+ pass
+class TestOOtype(OOtypeMixin, BaseTestOptimize2):
+ pass
From antocuni at codespeak.net Sat May 23 17:49:30 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 23 May 2009 17:49:30 +0200 (CEST)
Subject: [pypy-svn] r65363 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090523154930.AA41C169E97@codespeak.net>
Author: antocuni
Date: Sat May 23 17:49:29 2009
New Revision: 65363
Added:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
- copied, changed from r65361, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
- copied, changed from r65362, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
yet another optimize*.py. The idea is that you can write a new class for each
optimization, and methods of the class will be called for each corresponding
operation.
Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (from r65361, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 17:49:29 2009
@@ -1,6 +1,3 @@
-
-""" Simplified optimize.py
-"""
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.history import Const, Box
@@ -27,6 +24,9 @@
loop = None
nodes = None
+ def __init__(self, optlist):
+ self.optlist = optlist
+
def getnode(self, box):
try:
return self.nodes[box]
@@ -75,74 +75,16 @@
newboxes.append(box)
return newboxes
- def optimize_guard(self, op):
- assert len(op.suboperations) == 1
- op_fail = op.suboperations[0]
- op_fail.args = self.new_arguments(op_fail)
- # modification in place. Reason for this is explained in mirror
- # in optimize.py
- op.suboperations = [op_fail]
-
def optimize_operations(self):
newoperations = []
for op in self.loop.operations:
- if op.is_guard():
- if op.opnum == rop.GUARD_NONVIRTUALIZED:
- continue
- elif op.opnum == rop.GUARD_CLASS:
- node = self.getnode(op.args[0])
- if node.cls is not None:
- # assert that they're equal maybe
- continue
- node.cls = InstanceNode(op.args[1], const=True)
- elif op.opnum == rop.GUARD_VALUE:
- instnode = self.nodes[op.args[0]]
- assert isinstance(op.args[1], Const)
- if instnode.const:
- continue
- self.optimize_guard(op)
- instnode.const = True
- instnode.source = op.args[0].constbox()
- newoperations.append(op)
- continue
- self.optimize_guard(op)
- newoperations.append(op)
- continue
- elif op.opnum == rop.GETFIELD_GC:
- instnode = self.getnode(op.args[0])
- descr = op.descr
- node = instnode.cleanfields.get(descr, None)
- if node is not None:
- self.nodes[op.result] = node
- continue
- else:
- instnode.cleanfields[descr] = self.getnode(op.result)
- elif op.opnum == rop.SETFIELD_GC:
- instnode = self.getnode(op.args[0])
- descr = op.descr
- node = self.getnode(op.args[1])
- instnode.dirtyfields[descr] = node
- instnode.cleanfields[descr] = node
- l = self.field_caches.setdefault(descr, [])
- l.append((instnode, node))
- continue
- # default handler
- op = op.clone()
- op.args = self.new_arguments(op)
- if op.is_always_pure():
- for box in op.args:
- if isinstance(box, Box):
- break
- else:
- # all constant arguments: constant-fold away
- box = op.result
- assert box is not None
- instnode = InstanceNode(box.constbox(), const=True)
- self.nodes[box] = instnode
- continue
- elif not op.has_no_side_effect():
- self.clean_up_caches(newoperations)
- newoperations.append(op)
+ newop = op
+ for optimization in self.optlist:
+ newop = optimization.handle_op(self, newop)
+ if newop is None:
+ break
+ if newop is not None:
+ newoperations.append(newop)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
@@ -161,7 +103,77 @@
self.find_nodes()
self.optimize_operations()
-specializer = Specializer()
+# -------------------------------------------------------------------
+
+class AbstractOptimization(object):
+
+ def __init__(self):
+ 'NOT_RPYTHON'
+ operations = [None] * (rop._LAST+1)
+ for key, value in rop.__dict__.items():
+ if key.startswith('_'):
+ continue
+ methname = key.lower()
+ if hasattr(self, methname):
+ func = getattr(self, methname).im_func
+ else:
+ func = getattr(self, 'handle_default_op').im_func
+ operations[value] = func
+ self.operations = operations
+
+ def handle_op(self, spec, op):
+ func = self.operations[op.opnum]
+ return func(self, spec, op)
+
+ def handle_default_op(self, spec, op):
+ return op
+
+
+class OptimizeGuards(AbstractOptimization):
+
+ def optimize_guard(self, spec, op):
+ assert len(op.suboperations) == 1
+ op_fail = op.suboperations[0]
+ op_fail.args = spec.new_arguments(op_fail)
+ # modification in place. Reason for this is explained in mirror
+ # in optimize.py
+ op.suboperations = [op_fail]
+ return op
+
+ def guard_class(self, spec, op):
+ node = spec.getnode(op.args[0])
+ if node.cls is not None:
+ # assert that they're equal maybe
+ return
+ node.cls = InstanceNode(op.args[1], const=True)
+ return self.optimize_guard(spec, op)
+
+## def guard_value(self, spec, op):
+## instnode = spec.nodes[op.args[0]]
+## assert isinstance(op.args[1], Const)
+## if instnode.const:
+## return
+## self.optimize_guard(spec, op)
+## instnode.const = True
+## instnode.source = op.args[0].constbox()
+## return op
+
+## def guard_nonvirtualized(self, spec, op):
+## return
+
+## def handle_default_op(self, spec, op):
+## if op.is_guard():
+## return self.optimize_guard(op)
+## return op
+
+
+
+# -------------------------------------------------------------------
+
+OPTLIST = [
+ OptimizeGuards(),
+ ]
+specializer = Specializer(OPTLIST)
def optimize_loop(options, old_loops, loop, cpu=None):
if old_loops:
Copied: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py (from r65362, pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py)
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py Sat May 23 17:49:29 2009
@@ -8,9 +8,31 @@
ConstInt, BoxInt, BoxObj, ConstObj
from pypy.jit.backend.llgraph import runner
-from pypy.jit.metainterp.optimize2 import optimize_loop
+from pypy.jit.metainterp.optimize3 import AbstractOptimization
+from pypy.jit.metainterp.optimize3 import optimize_loop
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
+def test_AbstractOptimization():
+
+ class MyOpt(AbstractOptimization):
+ def int_add(self, spec, op):
+ return 'hello world', op
+
+ class MyOpt2(MyOpt):
+ def handle_default_op(self, spec, op):
+ return 'default op', op
+
+ myopt = MyOpt()
+ myopt2 = MyOpt2()
+ op = ResOperation(rop.INT_ADD, [], None)
+ assert myopt.handle_op(None, op) == ('hello world', op)
+ assert myopt2.handle_op(None, op) == ('hello world', op)
+
+ op = ResOperation(rop.INT_SUB, [], None)
+ assert myopt.handle_op(None, op) == op
+ assert myopt2.handle_op(None, op) == ('default op', op)
+
+
class LLtypeMixin(object):
node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
@@ -42,7 +64,7 @@
-class BaseTestOptimize2(object):
+class BaseTestOptimize3(object):
@staticmethod
def newloop(inputargs, operations):
@@ -51,6 +73,7 @@
loop.operations = operations
return loop
+
def test_remove_guard_class(self):
ops = [
ResOperation(rop.GUARD_CLASS, [self.nodebox, self.vtable_box], None),
@@ -63,6 +86,7 @@
assert len(loop.operations) == 1
def test_remove_consecutive_guard_value_constfold(self):
+ py.test.skip('in-progress')
n = BoxInt(0)
n1 = BoxInt(1)
n2 = BoxInt(3)
@@ -81,6 +105,7 @@
])
def test_remove_consecutive_getfields(self):
+ py.test.skip('in-progress')
n1 = BoxInt()
n2 = BoxInt()
n3 = BoxInt()
@@ -97,6 +122,7 @@
])
def test_setfield_getfield_clean_cache(self):
+ py.test.skip('in-progress')
n1 = BoxInt()
n2 = BoxInt()
n3 = BoxInt()
@@ -115,8 +141,8 @@
])
-class TestLLtype(LLtypeMixin, BaseTestOptimize2):
+class TestLLtype(LLtypeMixin, BaseTestOptimize3):
pass
-class TestOOtype(OOtypeMixin, BaseTestOptimize2):
+class TestOOtype(OOtypeMixin, BaseTestOptimize3):
pass
From antocuni at codespeak.net Sat May 23 18:05:45 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 23 May 2009 18:05:45 +0200 (CEST)
Subject: [pypy-svn] r65364 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090523160545.D58E3169EAB@codespeak.net>
Author: antocuni
Date: Sat May 23 18:05:43 2009
New Revision: 65364
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
Log:
implement constant folding, and add a test for it
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 18:05:43 2009
@@ -129,6 +129,29 @@
return op
+class ConstFold(AbstractOptimization):
+
+ def handle_default_op(self, spec, op):
+ op = op.clone()
+ op.args = spec.new_arguments(op)
+ if op.is_always_pure():
+ for box in op.args:
+ if isinstance(box, Box):
+ break
+ else:
+ # all constant arguments: constant-fold away
+ box = op.result
+ assert box is not None
+ instnode = InstanceNode(box.constbox(), const=True)
+ spec.nodes[box] = instnode
+ return
+ elif not op.has_no_side_effect():
+ # XXX
+ pass
+ #spec.clean_up_caches(newoperations)
+ return op
+
+
class OptimizeGuards(AbstractOptimization):
def optimize_guard(self, spec, op):
@@ -172,6 +195,7 @@
OPTLIST = [
OptimizeGuards(),
+ ConstFold(),
]
specializer = Specializer(OPTLIST)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py Sat May 23 18:05:43 2009
@@ -73,6 +73,13 @@
loop.operations = operations
return loop
+ def test_constfold(self):
+ ops = [
+ ResOperation(rop.INT_ADD, [ConstInt(10), ConstInt(20)], ConstInt(30)),
+ ]
+ loop = self.newloop([], ops)
+ optimize_loop(None, [], loop)
+ assert len(loop.operations) == 0
def test_remove_guard_class(self):
ops = [
From antocuni at codespeak.net Sat May 23 18:33:23 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 23 May 2009 18:33:23 +0200 (CEST)
Subject: [pypy-svn] r65365 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090523163323.A837A168464@codespeak.net>
Author: antocuni
Date: Sat May 23 18:33:23 2009
New Revision: 65365
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
Log:
(antocuni, after discussion with fijal): move op.clone/spec.new_arguments to
the main optimization loop, as it is something which needs to be done in
general, not only for constant folding. Tests still pass
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 18:33:23 2009
@@ -83,6 +83,8 @@
newop = optimization.handle_op(self, newop)
if newop is None:
break
+ newop = newop.clone()
+ newop.args = self.new_arguments(op)
if newop is not None:
newoperations.append(newop)
print "Length of the loop:", len(newoperations)
@@ -132,8 +134,6 @@
class ConstFold(AbstractOptimization):
def handle_default_op(self, spec, op):
- op = op.clone()
- op.args = spec.new_arguments(op)
if op.is_always_pure():
for box in op.args:
if isinstance(box, Box):
From fijal at codespeak.net Sat May 23 18:37:21 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 23 May 2009 18:37:21 +0200 (CEST)
Subject: [pypy-svn] r65366 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090523163721.8B7EE16850F@codespeak.net>
Author: fijal
Date: Sat May 23 18:37:20 2009
New Revision: 65366
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
Log:
I think this is what you meant
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 18:37:20 2009
@@ -83,9 +83,9 @@
newop = optimization.handle_op(self, newop)
if newop is None:
break
+ if newop is not None:
newop = newop.clone()
newop.args = self.new_arguments(op)
- if newop is not None:
newoperations.append(newop)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
From antocuni at codespeak.net Sat May 23 19:09:46 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 23 May 2009 19:09:46 +0200 (CEST)
Subject: [pypy-svn] r65367 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090523170946.71AE3169EFD@codespeak.net>
Author: antocuni
Date: Sat May 23 19:09:44 2009
New Revision: 65367
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
Log:
move new_arguments back to ConstFold, which has been renamed. The specializer
relies on it to be the last item of the list to work correctly.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 19:09:44 2009
@@ -25,6 +25,9 @@
nodes = None
def __init__(self, optlist):
+ for opt in optlist:
+ assert not isinstance(opt, CloneAndConstFold), 'automatically added'
+ optlist.append(CloneAndConstFold())
self.optlist = optlist
def getnode(self, box):
@@ -84,8 +87,6 @@
if newop is None:
break
if newop is not None:
- newop = newop.clone()
- newop.args = self.new_arguments(op)
newoperations.append(newop)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
@@ -131,9 +132,16 @@
return op
-class ConstFold(AbstractOptimization):
+class CloneAndConstFold(AbstractOptimization):
+ """
+ Automatically inserted as the last optimization of the list.
+ """
def handle_default_op(self, spec, op):
+ if op.is_guard():
+ return op # TODO
+ op = op.clone()
+ op.args = spec.new_arguments(op)
if op.is_always_pure():
for box in op.args:
if isinstance(box, Box):
@@ -145,10 +153,6 @@
instnode = InstanceNode(box.constbox(), const=True)
spec.nodes[box] = instnode
return
- elif not op.has_no_side_effect():
- # XXX
- pass
- #spec.clean_up_caches(newoperations)
return op
@@ -195,7 +199,6 @@
OPTLIST = [
OptimizeGuards(),
- ConstFold(),
]
specializer = Specializer(OPTLIST)
From antocuni at codespeak.net Sat May 23 19:10:29 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 23 May 2009 19:10:29 +0200 (CEST)
Subject: [pypy-svn] r65368 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090523171029.21CD6169EFC@codespeak.net>
Author: antocuni
Date: Sat May 23 19:10:29 2009
New Revision: 65368
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
Log:
implement guard_value, test passes
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 19:10:29 2009
@@ -175,15 +175,15 @@
node.cls = InstanceNode(op.args[1], const=True)
return self.optimize_guard(spec, op)
-## def guard_value(self, spec, op):
-## instnode = spec.nodes[op.args[0]]
-## assert isinstance(op.args[1], Const)
-## if instnode.const:
-## return
-## self.optimize_guard(spec, op)
-## instnode.const = True
-## instnode.source = op.args[0].constbox()
-## return op
+ def guard_value(self, spec, op):
+ instnode = spec.nodes[op.args[0]]
+ assert isinstance(op.args[1], Const)
+ if instnode.const:
+ return
+ self.optimize_guard(spec, op)
+ instnode.const = True
+ instnode.source = op.args[0].constbox()
+ return op
## def guard_nonvirtualized(self, spec, op):
## return
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py Sat May 23 19:10:29 2009
@@ -93,7 +93,6 @@
assert len(loop.operations) == 1
def test_remove_consecutive_guard_value_constfold(self):
- py.test.skip('in-progress')
n = BoxInt(0)
n1 = BoxInt(1)
n2 = BoxInt(3)
From antocuni at codespeak.net Sat May 23 19:11:38 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 23 May 2009 19:11:38 +0200 (CEST)
Subject: [pypy-svn] r65369 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090523171138.719E4169EFC@codespeak.net>
Author: antocuni
Date: Sat May 23 19:11:37 2009
New Revision: 65369
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
Log:
remove all references to the getfield optimizations, as fijal says it's broken
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize3.py Sat May 23 19:11:37 2009
@@ -8,8 +8,6 @@
assert isinstance(source, Const)
self.const = const
self.cls = None
- self.cleanfields = {}
- self.dirtyfields = {}
def __repr__(self):
flags = ''
@@ -90,14 +88,6 @@
newoperations.append(newop)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
-
- def clean_up_caches(self, newoperations):
- for descr, v in self.field_caches.iteritems():
- for instnode, fieldnode in v:
- newoperations.append(ResOperation(rop.SETFIELD_GC,
- [instnode.source, fieldnode.source], None, descr))
- del instnode.cleanfields[descr]
- del instnode.dirtyfields[descr]
def optimize_loop(self, loop):
self.nodes = {}
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize3.py Sat May 23 19:11:37 2009
@@ -110,42 +110,6 @@
ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
])
- def test_remove_consecutive_getfields(self):
- py.test.skip('in-progress')
- n1 = BoxInt()
- n2 = BoxInt()
- n3 = BoxInt()
- ops = [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n2, self.nodedescr),
- ResOperation(rop.INT_ADD, [n1, n2], n3),
- ]
- loop = self.newloop([self.nodebox], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.INT_ADD, [n1, n1], n3),
- ])
-
- def test_setfield_getfield_clean_cache(self):
- py.test.skip('in-progress')
- n1 = BoxInt()
- n2 = BoxInt()
- n3 = BoxInt()
- ops = [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.SETFIELD_GC, [self.nodebox, ConstInt(3)], None, self.nodedescr),
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n2, self.nodedescr),
- ResOperation(rop.CALL, [n2], None),
- ]
- loop = self.newloop([self.nodebox], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.SETFIELD_GC, [self.nodebox, ConstInt(3)], None, self.nodedescr),
- ResOperation(rop.CALL, [ConstInt(3)], None),
- ])
-
class TestLLtype(LLtypeMixin, BaseTestOptimize3):
pass
From fijal at codespeak.net Sat May 23 19:22:01 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 23 May 2009 19:22:01 +0200 (CEST)
Subject: [pypy-svn] r65370 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090523172201.26DBA168556@codespeak.net>
Author: fijal
Date: Sat May 23 19:22:00 2009
New Revision: 65370
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
kill all optimizations for now, will try to readd them in a modular manner
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Sat May 23 19:22:00 2009
@@ -87,45 +87,9 @@
newoperations = []
for op in self.loop.operations:
if op.is_guard():
- if op.opnum == rop.GUARD_NONVIRTUALIZED:
- continue
- elif op.opnum == rop.GUARD_CLASS:
- node = self.getnode(op.args[0])
- if node.cls is not None:
- # assert that they're equal maybe
- continue
- node.cls = InstanceNode(op.args[1], const=True)
- elif op.opnum == rop.GUARD_VALUE:
- instnode = self.nodes[op.args[0]]
- assert isinstance(op.args[1], Const)
- if instnode.const:
- continue
- self.optimize_guard(op)
- instnode.const = True
- instnode.source = op.args[0].constbox()
- newoperations.append(op)
- continue
self.optimize_guard(op)
newoperations.append(op)
continue
- elif op.opnum == rop.GETFIELD_GC:
- instnode = self.getnode(op.args[0])
- descr = op.descr
- node = instnode.cleanfields.get(descr, None)
- if node is not None:
- self.nodes[op.result] = node
- continue
- else:
- instnode.cleanfields[descr] = self.getnode(op.result)
- elif op.opnum == rop.SETFIELD_GC:
- instnode = self.getnode(op.args[0])
- descr = op.descr
- node = self.getnode(op.args[1])
- instnode.dirtyfields[descr] = node
- instnode.cleanfields[descr] = node
- l = self.field_caches.setdefault(descr, [])
- l.append((instnode, node))
- continue
# default handler
op = op.clone()
op.args = self.new_arguments(op)
@@ -140,19 +104,9 @@
instnode = InstanceNode(box.constbox(), const=True)
self.nodes[box] = instnode
continue
- elif not op.has_no_side_effect():
- self.clean_up_caches(newoperations)
newoperations.append(op)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
-
- def clean_up_caches(self, newoperations):
- for descr, v in self.field_caches.iteritems():
- for instnode, fieldnode in v:
- newoperations.append(ResOperation(rop.SETFIELD_GC,
- [instnode.source, fieldnode.source], None, descr))
- del instnode.cleanfields[descr]
- del instnode.dirtyfields[descr]
def optimize_loop(self, loop):
self.nodes = {}
From benjamin at codespeak.net Sat May 23 20:11:39 2009
From: benjamin at codespeak.net (benjamin at codespeak.net)
Date: Sat, 23 May 2009 20:11:39 +0200 (CEST)
Subject: [pypy-svn] r65371 - in pypy/trunk/pypy/interpreter:
astcompiler/test pyparser/test pyparser/test/samples stablecompiler
Message-ID: <20090523181139.BDC4C169DFF@codespeak.net>
Author: benjamin
Date: Sat May 23 20:11:37 2009
New Revision: 65371
Added:
pypy/trunk/pypy/interpreter/pyparser/test/support.py
- copied, changed from r65367, pypy/trunk/pypy/interpreter/pyparser/test/fakes.py
Removed:
pypy/trunk/pypy/interpreter/pyparser/test/fakes.py
pypy/trunk/pypy/interpreter/pyparser/test/samples/
pypy/trunk/pypy/interpreter/pyparser/test/test_astbuilder.py
pypy/trunk/pypy/interpreter/pyparser/test/test_samples.py
pypy/trunk/pypy/interpreter/stablecompiler/
Modified:
pypy/trunk/pypy/interpreter/astcompiler/test/test_ast.py
pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py
Log:
remove stablecompiler and the tests that relied upon it
Modified: pypy/trunk/pypy/interpreter/astcompiler/test/test_ast.py
==============================================================================
--- pypy/trunk/pypy/interpreter/astcompiler/test/test_ast.py (original)
+++ pypy/trunk/pypy/interpreter/astcompiler/test/test_ast.py Sat May 23 20:11:37 2009
@@ -1,5 +1,5 @@
from pypy.interpreter.astcompiler import ast#_temp as ast
-from pypy.interpreter.pyparser.test.test_astbuilder import source2ast
+from pypy.interpreter.pyparser.test.support import source2ast
class BaseVisitor(ast.ASTVisitor):
def default(self, node):
Modified: pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py
==============================================================================
--- pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py (original)
+++ pypy/trunk/pypy/interpreter/astcompiler/test/test_compiler.py Sat May 23 20:11:37 2009
@@ -1,6 +1,6 @@
import py
from pypy.interpreter.astcompiler import misc, pycodegen, opt
-from pypy.interpreter.pyparser.test.test_astbuilder import source2ast
+from pypy.interpreter.pyparser.test.support import source2ast
from pypy.interpreter.pyparser.test import expressions
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.pyparser.error import SyntaxError, IndentationError
Copied: pypy/trunk/pypy/interpreter/pyparser/test/support.py (from r65367, pypy/trunk/pypy/interpreter/pyparser/test/fakes.py)
==============================================================================
--- pypy/trunk/pypy/interpreter/pyparser/test/fakes.py (original)
+++ pypy/trunk/pypy/interpreter/pyparser/test/support.py Sat May 23 20:11:37 2009
@@ -1,3 +1,5 @@
+from pypy.interpreter.pyparser import pythonparse
+from pypy.interpreter.pyparser.astbuilder import AstBuilder
class FakeSpace:
w_None = None
@@ -40,3 +42,10 @@
def call_function(self, func, *args):
return func(*args)
+
+def source2ast(source, mode, space=FakeSpace(), version='2.5'):
+ python_parser = pythonparse.make_pyparser(version)
+ builder = AstBuilder(python_parser, version, space=space)
+ python_parser.parse_source(source, mode, builder)
+ return builder.rule_stack[-1]
+
From benjamin at codespeak.net Sat May 23 23:10:08 2009
From: benjamin at codespeak.net (benjamin at codespeak.net)
Date: Sat, 23 May 2009 23:10:08 +0200 (CEST)
Subject: [pypy-svn] r65372 - in pypy/trunk/pypy: module/posix
module/posix/test rpython/module
Message-ID: <20090523211008.0B663169EC5@codespeak.net>
Author: benjamin
Date: Sat May 23 23:10:06 2009
New Revision: 65372
Modified:
pypy/trunk/pypy/module/posix/__init__.py
pypy/trunk/pypy/module/posix/interp_posix.py
pypy/trunk/pypy/module/posix/test/test_posix2.py
pypy/trunk/pypy/rpython/module/ll_os.py
Log:
implement os.fsync() and os.fdatasync()
Modified: pypy/trunk/pypy/module/posix/__init__.py
==============================================================================
--- pypy/trunk/pypy/module/posix/__init__.py (original)
+++ pypy/trunk/pypy/module/posix/__init__.py Sat May 23 23:10:06 2009
@@ -69,6 +69,10 @@
interpleveldefs['chown'] = 'interp_posix.chown'
if hasattr(os, 'ftruncate'):
interpleveldefs['ftruncate'] = 'interp_posix.ftruncate'
+ if hasattr(os, 'fsync'):
+ interpleveldefs['fsync'] = 'interp_posix.fsync'
+ if hasattr(os, 'fdatasync'):
+ interpleveldefs['fdatasync'] = 'interp_posix.fdatasync'
if hasattr(os, 'putenv'):
interpleveldefs['putenv'] = 'interp_posix.putenv'
if hasattr(posix, 'unsetenv'): # note: emulated in os
Modified: pypy/trunk/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/trunk/pypy/module/posix/interp_posix.py (original)
+++ pypy/trunk/pypy/module/posix/interp_posix.py Sat May 23 23:10:06 2009
@@ -87,6 +87,20 @@
raise wrap_oserror(space, e)
ftruncate.unwrap_spec = [ObjSpace, int, r_longlong]
+def fsync(space, fd):
+ try:
+ os.fsync(fd)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+fsync.unwrap_spec = [ObjSpace, int]
+
+def fdatasync(space, fd):
+ try:
+ os.fdatasync(fd)
+ except OSError, e:
+ raise wrap_oserror(space, e)
+fdatasync.unwrap_spec = [ObjSpace, int]
+
# ____________________________________________________________
# For LL backends, expose all fields.
Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py
==============================================================================
--- pypy/trunk/pypy/module/posix/test/test_posix2.py (original)
+++ pypy/trunk/pypy/module/posix/test/test_posix2.py Sat May 23 23:10:06 2009
@@ -365,6 +365,38 @@
os = self.posix
raises(ValueError, os.sysconf, "!@#$%!#$!@#")
+ if hasattr(os, 'fsync'):
+ def test_fsync(self):
+ os = self.posix
+ f = open(self.path2, "w")
+ try:
+ fd = f.fileno()
+ os.fsync(fd)
+ finally:
+ f.close()
+ try:
+ os.fsync(fd)
+ except OSError:
+ pass
+ else:
+ raise AssertionError("os.fsync didn't raise")
+
+ if hasattr(os, 'fdatasync'):
+ def test_fdatasync(self):
+ os = self.posix
+ f = open(self.path2)
+ try:
+ fd = f.fileno()
+ os.fdatasync(fd)
+ finally:
+ f.close()
+ try:
+ os.fdatasync(fd)
+ except OSError:
+ pass
+ else:
+ raise AssertionError("os.fdatasync didn't raise")
+
def test_largefile(self):
os = self.posix
fd = os.open(self.path2 + 'test_largefile', os.O_RDWR | os.O_CREAT, 0666)
Modified: pypy/trunk/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/trunk/pypy/rpython/module/ll_os.py (original)
+++ pypy/trunk/pypy/rpython/module/ll_os.py Sat May 23 23:10:06 2009
@@ -830,6 +830,30 @@
llimpl = ftruncate_llimpl,
export_name = "ll_os.ll_os_ftruncate")
+ @registering_if(os, 'fsync')
+ def register_os_fsync(self):
+ os_fsync = self.llexternal('fsync', [rffi.INT], rffi.INT)
+
+ def fsync_llimpl(fd):
+ res = rffi.cast(rffi.LONG, os_fsync(rffi.cast(rffi.INT, fd)))
+ if res < 0:
+ raise OSError(rposix.get_errno(), "fsync failed")
+ return extdef([int], s_None,
+ llimpl=fsync_llimpl,
+ export_name="ll_os.ll_os_fsync")
+
+ @registering_if(os, 'fdatasync')
+ def register_os_fdatasync(self):
+ os_fdatasync = self.llexternal('fdatasync', [rffi.INT], rffi.INT)
+
+ def fdatasync_llimpl(fd):
+ res = rffi.cast(rffi.LONG, os_fdatasync(rffi.cast(rffi.INT, fd)))
+ if res < 0:
+ raise OSError(rposix.get_errno(), "fdatasync failed")
+ return extdef([int], s_None,
+ llimpl=fdatasync_llimpl,
+ export_name="ll_os.ll_os_fdatasync")
+
@registering(os.access)
def register_os_access(self):
os_access = self.llexternal(underscore_on_windows + 'access',
From fijal at codespeak.net Sat May 23 23:33:19 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 23 May 2009 23:33:19 +0200 (CEST)
Subject: [pypy-svn] r65373 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090523213319.34282168556@codespeak.net>
Author: fijal
Date: Sat May 23 23:33:18 2009
New Revision: 65373
Added:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (contents, props changed)
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py (contents, props changed)
Log:
A start of framework for a reasonable writing of tests
Added: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Sat May 23 23:33:18 2009
@@ -0,0 +1,110 @@
+
+""" Simplify optimize tests by allowing to write them
+in a nicer fashion
+"""
+
+from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt
+from pypy.jit.metainterp.resoperation import rop, ResOperation
+
+class ParseError(Exception):
+ pass
+
+class OpParser(object):
+ def __init__(self, descr):
+ self.descr = descr
+ self.vars = {}
+
+ def box_for_var(self, elem):
+ if elem.startswith('i'):
+ # integer
+ box = BoxInt()
+ elif elem.startswith('p'):
+ # pointer
+ box = BoxPtr()
+ else:
+ raise ParseError("Unknown variable type: %s" % elem)
+ return box
+
+ def parse_header_line(self, line):
+ elements = line.split(",")
+ vars = []
+ for elem in elements:
+ elem = elem.strip()
+ box = self.box_for_var(elem)
+ vars.append(box)
+ self.vars[elem] = box
+ return vars
+
+ def getvar(self, arg):
+ try:
+ return ConstInt(int(arg))
+ except ValueError:
+ return self.vars[arg]
+
+ def parse_op(self, line):
+ num = line.find('(')
+ if num == -1:
+ raise ParseError("invalid line: %s" % line)
+ opname = line[:num]
+ try:
+ opnum = getattr(rop, opname.upper())
+ except AttributeError:
+ raise ParseError("unknown op: %s" % opname)
+ endnum = line.find(')')
+ if endnum == -1:
+ raise ParseError("invalid line: %s" % line)
+ argspec = line[num + 1:endnum]
+ if not argspec.strip():
+ return opnum, [], None
+ allargs = argspec.split(",")
+ args = []
+ for arg in allargs:
+ arg = arg.strip()
+ try:
+ args.append(self.getvar(arg))
+ except KeyError:
+ raise ParseError("Unknown var: %s" % arg)
+ return opnum, args, None
+
+ def parse_result_op(self, line):
+ res, op = line.split("=")
+ res = res.strip()
+ op = op.strip()
+ opnum, args, descr = self.parse_op(op)
+ if res in self.vars:
+ raise ParseError("Double assign to var %s in line: %s" % (res, line))
+ rvar = self.box_for_var(res)
+ self.vars[res] = rvar
+ return ResOperation(opnum, args, rvar, descr)
+
+ def parse_op_no_result(self, line):
+ opnum, args, descr = self.parse_op(line)
+ return ResOperation(opnum, args, None, descr)
+
+ def parse_next_op(self, line):
+ if "=" in line:
+ return self.parse_result_op(line)
+ else:
+ return self.parse_op_no_result(line)
+
+ def parse(self):
+ lines = self.descr.split("\n")
+ inpargs = None
+ ops = []
+ for line in lines:
+ line = line.strip()
+ if not line or line.startswith("#"):
+ continue # a comment
+ if inpargs is None:
+ if not line.startswith('[') or not line.endswith(']'):
+ raise ParseError("Wrong header: %s" % line)
+ inpargs = self.parse_header_line(line[1:-1])
+ else:
+ ops.append(self.parse_next_op(line))
+ loop = TreeLoop("loop")
+ loop.operations = ops
+ loop.inputargs = inpargs
+ return loop
+
+def parse(descr):
+ return OpParser(descr).parse()
Added: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py Sat May 23 23:33:18 2009
@@ -0,0 +1,17 @@
+
+from pypy.jit.metainterp.test.oparser import parse
+from pypy.jit.metainterp.resoperation import rop
+
+def test_basic_parse():
+ x = """
+ [i0, i1]
+ i2 = int_add(i0, i1)
+ # a comment
+ i3 = int_sub(i2, 3)
+ fail()
+ """
+ loop = parse(x)
+ assert len(loop.operations) == 3
+ assert [op.opnum for op in loop.operations] == [rop.INT_ADD, rop.INT_SUB,
+ rop.FAIL]
+ assert len(loop.inputargs) == 2
From fijal at codespeak.net Sun May 24 02:41:36 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 02:41:36 +0200 (CEST)
Subject: [pypy-svn] r65374 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524004136.34439169E97@codespeak.net>
Author: fijal
Date: Sun May 24 02:41:34 2009
New Revision: 65374
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
Log:
Progress on a parser
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Sun May 24 02:41:34 2009
@@ -3,16 +3,20 @@
in a nicer fashion
"""
-from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt
+from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt,\
+ ConstAddr
from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.rpython.lltypesystem import lltype, llmemory
class ParseError(Exception):
pass
class OpParser(object):
- def __init__(self, descr):
+ def __init__(self, descr, cpu, namespace):
self.descr = descr
self.vars = {}
+ self.cpu = cpu
+ self.consts = namespace
def box_for_var(self, elem):
if elem.startswith('i'):
@@ -39,6 +43,10 @@
try:
return ConstInt(int(arg))
except ValueError:
+ if arg.startswith('ConstAddr('):
+ name = arg[len('ConstAddr('):-1]
+ return ConstAddr(llmemory.cast_ptr_to_adr(self.consts[name]),
+ self.cpu)
return self.vars[arg]
def parse_op(self, line):
@@ -50,7 +58,7 @@
opnum = getattr(rop, opname.upper())
except AttributeError:
raise ParseError("unknown op: %s" % opname)
- endnum = line.find(')')
+ endnum = line.rfind(')')
if endnum == -1:
raise ParseError("invalid line: %s" % line)
argspec = line[num + 1:endnum]
@@ -89,22 +97,47 @@
def parse(self):
lines = self.descr.split("\n")
- inpargs = None
ops = []
+ newlines = []
for line in lines:
- line = line.strip()
- if not line or line.startswith("#"):
+ if not line.strip() or line.strip().startswith("#"):
continue # a comment
- if inpargs is None:
- if not line.startswith('[') or not line.endswith(']'):
- raise ParseError("Wrong header: %s" % line)
- inpargs = self.parse_header_line(line[1:-1])
- else:
- ops.append(self.parse_next_op(line))
+ newlines.append(line)
+ base_indent, inpargs = self.parse_inpargs(newlines[0])
+ newlines = newlines[1:]
+ num, ops = self.parse_ops(base_indent, newlines, 0)
+ if num < len(newlines):
+ raise ParseError("unexpected dedent at line: %s" % newlines[num])
loop = TreeLoop("loop")
loop.operations = ops
loop.inputargs = inpargs
return loop
-def parse(descr):
- return OpParser(descr).parse()
+ def parse_ops(self, indent, lines, start):
+ num = start
+ ops = []
+ while num < len(lines):
+ line = lines[num]
+ if not line.startswith(" " * indent):
+ # dedent
+ return num, ops
+ elif line.startswith(" "*(indent + 1)):
+ # suboperations
+ new_indent = len(line) - len(line.lstrip())
+ num, suboperations = self.parse_ops(new_indent, lines, num)
+ ops[-1].suboperations = suboperations
+ else:
+ ops.append(self.parse_next_op(lines[num].strip()))
+ num += 1
+ return num, ops
+
+ def parse_inpargs(self, line):
+ base_indent = line.find('[')
+ line = line.strip()
+ if base_indent == -1 or not line.endswith(']'):
+ raise ParseError("Wrong header: %s" % line)
+ inpargs = self.parse_header_line(line[1:-1])
+ return base_indent, inpargs
+
+def parse(descr, cpu=None, namespace={}):
+ return OpParser(descr, cpu, namespace).parse()
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py Sun May 24 02:41:34 2009
@@ -1,4 +1,6 @@
+from pypy.rpython.lltypesystem import lltype
+
from pypy.jit.metainterp.test.oparser import parse
from pypy.jit.metainterp.resoperation import rop
@@ -15,3 +17,16 @@
assert [op.opnum for op in loop.operations] == [rop.INT_ADD, rop.INT_SUB,
rop.FAIL]
assert len(loop.inputargs) == 2
+
+def test_const_ptr_subops():
+ x = """
+ [p0]
+ guard_class(p0, ConstAddr(vtable))
+ fail()
+ """
+ S = lltype.Struct('S')
+ vtable = lltype.nullptr(S)
+ loop = parse(x, None, locals())
+ assert len(loop.operations) == 1
+ assert len(loop.operations[0].suboperations) == 1
+
From fijal at codespeak.net Sun May 24 02:50:32 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 02:50:32 +0200 (CEST)
Subject: [pypy-svn] r65375 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090524005032.99CFF169E97@codespeak.net>
Author: fijal
Date: Sun May 24 02:50:32 2009
New Revision: 65375
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
Start using new framework for basic optimizations. Right now only constant
folding
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Sun May 24 02:50:32 2009
@@ -1,7 +1,7 @@
""" Simplified optimize.py
"""
-from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.jit.metainterp.resoperation import rop, ResOperation, opname
from pypy.jit.metainterp.history import Const, Box
class InstanceNode(object):
@@ -27,6 +27,15 @@
loop = None
nodes = None
+ def __init__(self, opts):
+ # NOT_RPYTHON
+ self.optimizations = [[] for i in range(rop._LAST)]
+ for opt in opts:
+ for name, opnum in opname.iteritems():
+ meth = getattr(opt, 'optimize_' + name, None)
+ if meth is not None:
+ self.optimizations[opnum].append(meth)
+
def getnode(self, box):
try:
return self.nodes[box]
@@ -86,6 +95,9 @@
def optimize_operations(self):
newoperations = []
for op in self.loop.operations:
+ for opt in self.optimizations[op.opnum]:
+ if opt(op, self) is None:
+ continue
if op.is_guard():
self.optimize_guard(op)
newoperations.append(op)
@@ -115,18 +127,18 @@
self.find_nodes()
self.optimize_operations()
-specializer = Specializer()
+specializer = Specializer([])
-def optimize_loop(options, old_loops, loop, cpu=None):
+def optimize_loop(options, old_loops, loop, cpu=None, spec=specializer):
if old_loops:
assert len(old_loops) == 1
return old_loops[0]
else:
- specializer.optimize_loop(loop)
+ spec.optimize_loop(loop)
return None
-def optimize_bridge(options, old_loops, loop, cpu=None):
- optimize_loop(options, [], loop, cpu)
+def optimize_bridge(options, old_loops, loop, cpu=None, spec=specializer):
+ optimize_loop(options, [], loop, cpu, spec)
return old_loops[0]
class Optimizer:
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Sun May 24 02:50:32 2009
@@ -11,6 +11,8 @@
from pypy.jit.metainterp.optimize2 import optimize_loop
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
+from pypy.jit.metainterp.test.oparser import parse
+
class LLtypeMixin(object):
node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
@@ -44,25 +46,41 @@
class BaseTestOptimize2(object):
- @staticmethod
- def newloop(inputargs, operations):
- loop = TreeLoop("test")
- loop.inputargs = inputargs
- loop.operations = operations
- return loop
+ def optimize(self, lst):
+ loop = parse(lst, self.cpu, self.__dict__)
+ optimize_loop(None, [], loop)
+ return loop.operations
+ def assert_equal(self, optimized, expected):
+ equaloplists(optimized,
+ parse(expected, self.cpu, self.__dict__).operations)
+
+ def test_basic_constant_folding(self):
+ pre_op = """
+ []
+ i1 = int_add(3, 2)
+ """
+ expected = "[]"
+ self.assert_equal(self.optimize(pre_op), expected)
+
def test_remove_guard_class(self):
- ops = [
- ResOperation(rop.GUARD_CLASS, [self.nodebox, self.vtable_box], None),
- ResOperation(rop.GUARD_CLASS, [self.nodebox, self.vtable_box], None),
- ]
- ops[0].suboperations = [ResOperation(rop.FAIL, [], None)]
- ops[1].suboperations = [ResOperation(rop.FAIL, [], None)]
- loop = self.newloop([self.nodebox], ops)
- optimize_loop(None, [], loop)
- assert len(loop.operations) == 1
+ py.test.skip("not yet")
+ pre_op = """
+ [p0]
+ guard_class(p0, Const(vtable))
+ fail()
+ guard_class(p0, Const(vtable))
+ fail()
+ """
+ expected = """
+ [p0]
+ guard_class(p0, Const(vtable))
+ fail()
+ """
+ self.equal(self.optimize(pre_op, []), expected)
def test_remove_consecutive_guard_value_constfold(self):
+ py.test.skip("not yet")
n = BoxInt(0)
n1 = BoxInt(1)
n2 = BoxInt(3)
@@ -81,6 +99,7 @@
])
def test_remove_consecutive_getfields(self):
+ py.test.skip("not yet")
n1 = BoxInt()
n2 = BoxInt()
n3 = BoxInt()
@@ -97,6 +116,7 @@
])
def test_setfield_getfield_clean_cache(self):
+ py.test.skip("not yet")
n1 = BoxInt()
n2 = BoxInt()
n3 = BoxInt()
From fijal at codespeak.net Sun May 24 03:06:00 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 03:06:00 +0200 (CEST)
Subject: [pypy-svn] r65376 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524010600.AC1A2169EB6@codespeak.net>
Author: fijal
Date: Sun May 24 03:05:56 2009
New Revision: 65376
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
Log:
* Fix trivial bug
* Add a cache for names, so the same name will have the same box.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Sun May 24 03:05:56 2009
@@ -8,6 +8,8 @@
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.rpython.lltypesystem import lltype, llmemory
+_cache = {}
+
class ParseError(Exception):
pass
@@ -19,6 +21,10 @@
self.consts = namespace
def box_for_var(self, elem):
+ try:
+ return _cache[elem]
+ except KeyError:
+ pass
if elem.startswith('i'):
# integer
box = BoxInt()
@@ -27,6 +33,7 @@
box = BoxPtr()
else:
raise ParseError("Unknown variable type: %s" % elem)
+ _cache[elem] = box
return box
def parse_header_line(self, line):
@@ -134,6 +141,8 @@
def parse_inpargs(self, line):
base_indent = line.find('[')
line = line.strip()
+ if line == '[]':
+ return base_indent, []
if base_indent == -1 or not line.endswith(']'):
raise ParseError("Wrong header: %s" % line)
inpargs = self.parse_header_line(line[1:-1])
From fijal at codespeak.net Sun May 24 03:06:55 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 03:06:55 +0200 (CEST)
Subject: [pypy-svn] r65377 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090524010655.79D80169ECE@codespeak.net>
Author: fijal
Date: Sun May 24 03:06:55 2009
New Revision: 65377
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
Add a guard_class removal
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Sun May 24 03:06:55 2009
@@ -31,8 +31,8 @@
# NOT_RPYTHON
self.optimizations = [[] for i in range(rop._LAST)]
for opt in opts:
- for name, opnum in opname.iteritems():
- meth = getattr(opt, 'optimize_' + name, None)
+ for opnum, name in opname.iteritems():
+ meth = getattr(opt, 'optimize_' + name.lower(), None)
if meth is not None:
self.optimizations[opnum].append(meth)
@@ -127,6 +127,14 @@
self.find_nodes()
self.optimize_operations()
+class ConsecutiveGuardClassRemoval(object):
+ def optimize_guard_class(self, op, spec):
+ instnode = spec.getnode(op.args[0])
+ if instnode.cls is not None:
+ return None
+ instnode.cls = op.args[1]
+ return op
+
specializer = Specializer([])
def optimize_loop(options, old_loops, loop, cpu=None, spec=specializer):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Sun May 24 03:06:55 2009
@@ -8,7 +8,8 @@
ConstInt, BoxInt, BoxObj, ConstObj
from pypy.jit.backend.llgraph import runner
-from pypy.jit.metainterp.optimize2 import optimize_loop
+from pypy.jit.metainterp.optimize2 import (optimize_loop,
+ ConsecutiveGuardClassRemoval, Specializer)
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
from pypy.jit.metainterp.test.oparser import parse
@@ -28,6 +29,8 @@
nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodedescr = cpu.fielddescrof(NODE, 'value')
+ namespace = locals()
+
class OOtypeMixin(object):
cpu = runner.OOtypeCPU(None)
@@ -42,18 +45,19 @@
nodebox = BoxObj(ootype.cast_to_object(node))
nodedescr = cpu.fielddescrof(NODE, 'value')
-
+ namespace = locals()
class BaseTestOptimize2(object):
- def optimize(self, lst):
- loop = parse(lst, self.cpu, self.__dict__)
- optimize_loop(None, [], loop)
+ def optimize(self, lst, optimizations_enabled=[]):
+ loop = parse(lst, self.cpu, self.namespace)
+ optimize_loop(None, [], loop, self.cpu,
+ spec=Specializer(optimizations_enabled))
return loop.operations
def assert_equal(self, optimized, expected):
equaloplists(optimized,
- parse(expected, self.cpu, self.__dict__).operations)
+ parse(expected, self.cpu, self.namespace).operations)
def test_basic_constant_folding(self):
pre_op = """
@@ -64,20 +68,21 @@
self.assert_equal(self.optimize(pre_op), expected)
def test_remove_guard_class(self):
- py.test.skip("not yet")
pre_op = """
[p0]
- guard_class(p0, Const(vtable))
+ guard_class(p0, ConstAddr(node_vtable))
fail()
- guard_class(p0, Const(vtable))
+ guard_class(p0, ConstAddr(node_vtable))
fail()
"""
expected = """
[p0]
- guard_class(p0, Const(vtable))
+ guard_class(p0, ConstAddr(node_vtable))
fail()
"""
- self.equal(self.optimize(pre_op, []), expected)
+ self.assert_equal(self.optimize(pre_op,
+ [ConsecutiveGuardClassRemoval()]),
+ expected)
def test_remove_consecutive_guard_value_constfold(self):
py.test.skip("not yet")
@@ -139,4 +144,5 @@
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
- pass
+ def setup_class(cls):
+ py.test.skip("XXX Fix me")
From fijal at codespeak.net Sun May 24 05:06:19 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 05:06:19 +0200 (CEST)
Subject: [pypy-svn] r65378 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524030619.90F0316851C@codespeak.net>
Author: fijal
Date: Sun May 24 05:06:15 2009
New Revision: 65378
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
Log:
Support for descrs
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Sun May 24 05:06:15 2009
@@ -73,16 +73,21 @@
return opnum, [], None
allargs = argspec.split(",")
args = []
+ descr = None
+ poss_descr = allargs[-1].strip()
+ if poss_descr.startswith('descr='):
+ descr = self.consts[poss_descr[len('descr='):]]
+ allargs = allargs[:-1]
for arg in allargs:
arg = arg.strip()
try:
args.append(self.getvar(arg))
except KeyError:
raise ParseError("Unknown var: %s" % arg)
- return opnum, args, None
+ return opnum, args, descr
def parse_result_op(self, line):
- res, op = line.split("=")
+ res, op = line.split("=", 1)
res = res.strip()
op = op.strip()
opnum, args, descr = self.parse_op(op)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py Sun May 24 05:06:15 2009
@@ -3,6 +3,7 @@
from pypy.jit.metainterp.test.oparser import parse
from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.metainterp.history import AbstractDescr
def test_basic_parse():
x = """
@@ -30,3 +31,14 @@
assert len(loop.operations) == 1
assert len(loop.operations[0].suboperations) == 1
+def test_descr():
+ class Xyz(AbstractDescr):
+ pass
+
+ x = """
+ [p0]
+ i1 = getfield_gc(p0, descr=stuff)
+ """
+ stuff = Xyz()
+ loop = parse(x, None, locals())
+ assert loop.operations[0].descr is stuff
From fijal at codespeak.net Sun May 24 16:44:11 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 16:44:11 +0200 (CEST)
Subject: [pypy-svn] r65379 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524144411.8AF0716840E@codespeak.net>
Author: fijal
Date: Sun May 24 16:44:09 2009
New Revision: 65379
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
Log:
A test and a fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Sun May 24 16:44:09 2009
@@ -140,7 +140,7 @@
ops[-1].suboperations = suboperations
else:
ops.append(self.parse_next_op(lines[num].strip()))
- num += 1
+ num += 1
return num, ops
def parse_inpargs(self, line):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py Sun May 24 16:44:09 2009
@@ -42,3 +42,13 @@
stuff = Xyz()
loop = parse(x, None, locals())
assert loop.operations[0].descr is stuff
+
+def test_after_fail():
+ x = """
+ [i0]
+ guard_value(i0, 3)
+ fail()
+ i1 = int_add(1, 2)
+ """
+ loop = parse(x, None, {})
+ assert len(loop.operations) == 2
From fijal at codespeak.net Sun May 24 16:51:28 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 16:51:28 +0200 (CEST)
Subject: [pypy-svn] r65380 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090524145128.23E67169F34@codespeak.net>
Author: fijal
Date: Sun May 24 16:51:27 2009
New Revision: 65380
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
After fixing the runner logic, test started failing, fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Sun May 24 16:51:27 2009
@@ -95,9 +95,13 @@
def optimize_operations(self):
newoperations = []
for op in self.loop.operations:
+ newop = op
for opt in self.optimizations[op.opnum]:
- if opt(op, self) is None:
- continue
+ newop = opt(op, self)
+ if newop is None:
+ break
+ if newop is None:
+ continue
if op.is_guard():
self.optimize_guard(op)
newoperations.append(op)
@@ -135,6 +139,10 @@
instnode.cls = op.args[1]
return op
+class SimpleVirtualizableOpt(object):
+ def optimize_guard_nonvirtualized(self, op, spec):
+ xxx
+
specializer = Specializer([])
def optimize_loop(options, old_loops, loop, cpu=None, spec=specializer):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Sun May 24 16:51:27 2009
@@ -9,7 +9,7 @@
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp.optimize2 import (optimize_loop,
- ConsecutiveGuardClassRemoval, Specializer)
+ ConsecutiveGuardClassRemoval, Specializer, SimpleVirtualizableOpt)
from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
from pypy.jit.metainterp.test.oparser import parse
@@ -29,6 +29,10 @@
nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodedescr = cpu.fielddescrof(NODE, 'value')
+ XY = lltype.GcStruct('XY', ('field', lltype.Signed),
+ hints= {'virtualizable2': True})
+ field_desc = cpu.fielddescrof(XY, 'field')
+
namespace = locals()
class OOtypeMixin(object):
@@ -84,6 +88,25 @@
[ConsecutiveGuardClassRemoval()]),
expected)
+ def test_basic_virtualizable(self):
+ py.test.skip("xxx")
+ pre_op = """
+ [p0]
+ guard_nonvirtualized(p0)
+ fail()
+ i1 = getfield_gc(p0, descr=field_desc)
+ i2 = getfield_gc(p0, descr=field_desc)
+ i3 = int_add(i1, i2)
+ """
+ expected = """
+ [p0]
+ i1 = getfield_gc(p0, descr=field_desc)
+ i3 = int_add(i1, i1)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+ expected)
+
+
def test_remove_consecutive_guard_value_constfold(self):
py.test.skip("not yet")
n = BoxInt(0)
From pedronis at codespeak.net Sun May 24 17:04:35 2009
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Sun, 24 May 2009 17:04:35 +0200 (CEST)
Subject: [pypy-svn] r65381 - pypy/build/bot2/pypybuildbot
Message-ID: <20090524150435.20FB0169E3F@codespeak.net>
Author: pedronis
Date: Sun May 24 17:04:32 2009
New Revision: 65381
Modified:
pypy/build/bot2/pypybuildbot/master.py
Log:
don't run these anymore, doesn't seem will need a micro-release soon
Modified: pypy/build/bot2/pypybuildbot/master.py
==============================================================================
--- pypy/build/bot2/pypybuildbot/master.py (original)
+++ pypy/build/bot2/pypybuildbot/master.py Sun May 24 17:04:32 2009
@@ -51,10 +51,6 @@
'change_source': [],
'schedulers': [
- Nightly("nightly-1.1.x", [LINUX32, CPYLINUX32, APPLVLLINUX32, CPYWIN32,
- STACKLESSAPPLVLLINUX32],
- hour=0, minute=45, branch="release/1.1.x",
- ),
Nightly("nightly", [LINUX32, CPYLINUX32, APPLVLLINUX32, CPYWIN32,
STACKLESSAPPLVLLINUX32],
hour=4, minute=45),
From afa at codespeak.net Sun May 24 18:13:22 2009
From: afa at codespeak.net (afa at codespeak.net)
Date: Sun, 24 May 2009 18:13:22 +0200 (CEST)
Subject: [pypy-svn] r65382 - pypy/trunk/pypy/module/posix/test
Message-ID: <20090524161322.16A9C169F3C@codespeak.net>
Author: afa
Date: Sun May 24 18:13:20 2009
New Revision: 65382
Modified:
pypy/trunk/pypy/module/posix/test/test_posix2.py
Log:
"import os.path" masks the previous value of "os".
Be sure to test the right module.
Modified: pypy/trunk/pypy/module/posix/test/test_posix2.py
==============================================================================
--- pypy/trunk/pypy/module/posix/test/test_posix2.py (original)
+++ pypy/trunk/pypy/module/posix/test/test_posix2.py Sun May 24 18:13:20 2009
@@ -286,9 +286,9 @@
def test_utime(self):
os = self.posix
- import os.path
+ from os.path import join
# XXX utimes & float support
- path = os.path.join(self.pdir, "test_utime.txt")
+ path = join(self.pdir, "test_utime.txt")
fh = open(path, "w")
fh.write("x")
fh.close()
From afa at codespeak.net Sun May 24 19:33:13 2009
From: afa at codespeak.net (afa at codespeak.net)
Date: Sun, 24 May 2009 19:33:13 +0200 (CEST)
Subject: [pypy-svn] r65383 - pypy/trunk/pypy/rpython/module
Message-ID: <20090524173313.0335A16847C@codespeak.net>
Author: afa
Date: Sun May 24 19:33:11 2009
New Revision: 65383
Modified:
pypy/trunk/pypy/rpython/module/ll_os.py
Log:
On Windows, fsync() spells _commit()
Modified: pypy/trunk/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/trunk/pypy/rpython/module/ll_os.py (original)
+++ pypy/trunk/pypy/rpython/module/ll_os.py Sun May 24 19:33:11 2009
@@ -832,7 +832,10 @@
@registering_if(os, 'fsync')
def register_os_fsync(self):
- os_fsync = self.llexternal('fsync', [rffi.INT], rffi.INT)
+ if not _WIN32:
+ os_fsync = self.llexternal('fsync', [rffi.INT], rffi.INT)
+ else:
+ os_fsync = self.llexternal('_commit', [rffi.INT], rffi.INT)
def fsync_llimpl(fd):
res = rffi.cast(rffi.LONG, os_fsync(rffi.cast(rffi.INT, fd)))
From fijal at codespeak.net Sun May 24 23:18:19 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 23:18:19 +0200 (CEST)
Subject: [pypy-svn] r65387 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524211819.5E6FC169F35@codespeak.net>
Author: fijal
Date: Sun May 24 23:18:16 2009
New Revision: 65387
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
Log:
A test and a fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Sun May 24 23:18:16 2009
@@ -102,7 +102,7 @@
return ResOperation(opnum, args, None, descr)
def parse_next_op(self, line):
- if "=" in line:
+ if "=" in line and line.find('(') > line.find('='):
return self.parse_result_op(line)
else:
return self.parse_op_no_result(line)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py Sun May 24 23:18:16 2009
@@ -52,3 +52,15 @@
"""
loop = parse(x, None, {})
assert len(loop.operations) == 2
+
+def test_descr_setfield():
+ class Xyz(AbstractDescr):
+ pass
+
+ x = """
+ [p0]
+ setfield_gc(p0, 3, descr=stuff)
+ """
+ stuff = Xyz()
+ loop = parse(x, None, locals())
+ assert loop.operations[0].descr is stuff
From fijal at codespeak.net Sun May 24 23:18:52 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 24 May 2009 23:18:52 +0200 (CEST)
Subject: [pypy-svn] r65388 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090524211852.73316169F40@codespeak.net>
Author: fijal
Date: Sun May 24 23:18:51 2009
New Revision: 65388
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/virtualizable.py
Log:
fix mro
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/virtualizable.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/virtualizable.py Sun May 24 23:18:51 2009
@@ -7,7 +7,7 @@
from pypy.annotation.model import lltype_to_annotation
from pypy.rlib.objectmodel import we_are_translated
-class VirtualizableDesc(history.AbstractValue):
+class VirtualizableDesc(history.AbstractDescr):
hash = 0
def __init__(self, cpu, TOPSTRUCT, STRUCTTYPE):
From fijal at codespeak.net Mon May 25 00:37:21 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 00:37:21 +0200 (CEST)
Subject: [pypy-svn] r65389 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090524223721.AF255169F4F@codespeak.net>
Author: fijal
Date: Mon May 25 00:37:16 2009
New Revision: 65389
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
implement setfield/getfield optimization for fields marked as virtuals
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 00:37:16 2009
@@ -13,6 +13,7 @@
self.cls = None
self.cleanfields = {}
self.dirtyfields = {}
+ self.virtualized = False
def __repr__(self):
flags = ''
@@ -20,7 +21,7 @@
#if self.startbox: flags += 's'
if self.const: flags += 'c'
#if self.virtual: flags += 'v'
- #if self.virtualized: flags += 'V'
+ if self.virtualized: flags += 'V'
return "" % (self.source, flags)
class Specializer(object):
@@ -62,7 +63,7 @@
if is_pure:
box = op.result
assert box is not None
- self.nodes[box] = InstanceNode(box.constbox(), const=True)
+ self.nodes[box] = self.getnode(box.constbox())
continue
else:
if op.is_guard():
@@ -73,7 +74,7 @@
self.getnode(box)
box = op.result
if box is not None:
- self.nodes[box] = InstanceNode(box)
+ self.nodes[box] = self.getnode(box)
def new_arguments(self, op):
newboxes = []
@@ -90,9 +91,15 @@
op_fail.args = self.new_arguments(op_fail)
# modification in place. Reason for this is explained in mirror
# in optimize.py
- op.suboperations = [op_fail]
+ op.suboperations = []
+ for node, field in self.additional_stores:
+ op.suboperations.append(ResOperation(rop.SETFIELD_GC,
+ [node.source, node.cleanfields[field].source], None, field))
+ op.suboperations.append(op_fail)
+ op.args = self.new_arguments(op)
def optimize_operations(self):
+ self.additional_stores = []
newoperations = []
for op in self.loop.operations:
newop = op
@@ -141,7 +148,36 @@
class SimpleVirtualizableOpt(object):
def optimize_guard_nonvirtualized(self, op, spec):
- xxx
+ instnode = spec.getnode(op.args[0])
+ instnode.virtualized = True
+ instnode.vdesc = op.descr
+ return None
+
+ def optimize_getfield_gc(self, op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtualized:
+ return op
+ field = op.descr
+ if field not in instnode.vdesc.virtuals:
+ return op
+ node = instnode.cleanfields.get(field, None)
+ if node is not None:
+ spec.nodes[op.result] = node
+ return None
+ instnode.cleanfields[field] = spec.getnode(op.result)
+ return op
+
+ def optimize_setfield_gc(self, op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtualized:
+ return op
+ field = op.descr
+ if field not in instnode.vdesc.virtuals:
+ return op
+ instnode.cleanfields[field] = spec.getnode(op.args[1])
+ # we never set it here
+ spec.additional_stores.append((instnode, field))
+ return None
specializer = Specializer([])
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Mon May 25 00:37:16 2009
@@ -10,9 +10,36 @@
from pypy.jit.metainterp.optimize2 import (optimize_loop,
ConsecutiveGuardClassRemoval, Specializer, SimpleVirtualizableOpt)
-from pypy.jit.metainterp.test.test_optimize import equaloplists, ANY
+from pypy.jit.metainterp.test.test_optimize import ANY
from pypy.jit.metainterp.test.oparser import parse
+from pypy.jit.metainterp.virtualizable import VirtualizableDesc
+
+def equaloplists(oplist1, oplist2):
+ #saved = Box._extended_display
+ #try:
+ # Box._extended_display = False
+ print '-'*20, 'Comparing lists', '-'*20
+ for op1, op2 in zip(oplist1, oplist2):
+ txt1 = str(op1)
+ txt2 = str(op2)
+ while txt1 or txt2:
+ print '%-39s| %s' % (txt1[:39], txt2[:39])
+ txt1 = txt1[39:]
+ txt2 = txt2[39:]
+ assert op1.opnum == op2.opnum
+ assert len(op1.args) == len(op2.args)
+ for x, y in zip(op1.args, op2.args):
+ assert x == y or y == x # for ANY object :-(
+ assert op1.result == op2.result
+ assert op1.descr == op2.descr
+ if op1.suboperations or op2.suboperations:
+ equaloplists(op1.suboperations, op2.suboperations)
+ assert len(oplist1) == len(oplist2)
+ print '-'*57
+ #finally:
+ # Box._extended_display = saved
+ return True
class LLtypeMixin(object):
@@ -29,9 +56,13 @@
nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodedescr = cpu.fielddescrof(NODE, 'value')
- XY = lltype.GcStruct('XY', ('field', lltype.Signed),
- hints= {'virtualizable2': True})
- field_desc = cpu.fielddescrof(XY, 'field')
+ XY = lltype.GcStruct('XY', ('inst_field', lltype.Signed),
+ ('inst_other_field', lltype.Signed),
+ hints= {'virtualizable2': True,
+ 'virtuals': ('field',)})
+ field_desc = cpu.fielddescrof(XY, 'inst_field')
+ other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
+ vdesc = VirtualizableDesc(cpu, XY, XY)
namespace = locals()
@@ -89,10 +120,9 @@
expected)
def test_basic_virtualizable(self):
- py.test.skip("xxx")
pre_op = """
[p0]
- guard_nonvirtualized(p0)
+ guard_nonvirtualized(p0, descr=vdesc)
fail()
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=field_desc)
@@ -105,6 +135,31 @@
"""
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
expected)
+
+ def test_virtualizable_setfield_rebuild_ops(self):
+ pre_op = """
+ [p0]
+ guard_nonvirtualized(p0, descr=vdesc)
+ fail()
+ i1 = getfield_gc(p0, descr=field_desc)
+ i2 = getfield_gc(p0, descr=other_field_desc)
+ setfield_gc(p0, i2, descr=field_desc)
+ # ^^^ this should be gone
+ i3 = getfield_gc(p0, descr=field_desc)
+ # ^^^ this one as well
+ guard_true(i3)
+ fail()
+ """
+ expected = """
+ [p0]
+ i1 = getfield_gc(p0, descr=field_desc)
+ i2 = getfield_gc(p0, descr=other_field_desc)
+ guard_true(i2)
+ setfield_gc(p0, i2, descr=field_desc)
+ fail()
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+ expected)
def test_remove_consecutive_guard_value_constfold(self):
From fijal at codespeak.net Mon May 25 00:45:21 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 00:45:21 +0200 (CEST)
Subject: [pypy-svn] r65390 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524224521.2CD21169F53@codespeak.net>
Author: fijal
Date: Mon May 25 00:45:20 2009
New Revision: 65390
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
Log:
fix for vdesc
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Mon May 25 00:45:20 2009
@@ -70,13 +70,18 @@
raise ParseError("invalid line: %s" % line)
argspec = line[num + 1:endnum]
if not argspec.strip():
- return opnum, [], None
+ return opnum, [], None, None
allargs = argspec.split(",")
args = []
descr = None
+ vdesc = None
poss_descr = allargs[-1].strip()
if poss_descr.startswith('descr='):
descr = self.consts[poss_descr[len('descr='):]]
+ allargs = allargs[:-1]
+ poss_vdesc = allargs[-1].strip()
+ if poss_vdesc.startswith('vdesc='):
+ descr = self.consts[poss_descr[len('vdesc='):]]
allargs = allargs[:-1]
for arg in allargs:
arg = arg.strip()
@@ -84,22 +89,26 @@
args.append(self.getvar(arg))
except KeyError:
raise ParseError("Unknown var: %s" % arg)
- return opnum, args, descr
+ return opnum, args, descr, vdesc
def parse_result_op(self, line):
res, op = line.split("=", 1)
res = res.strip()
op = op.strip()
- opnum, args, descr = self.parse_op(op)
+ opnum, args, descr, vdesc = self.parse_op(op)
if res in self.vars:
raise ParseError("Double assign to var %s in line: %s" % (res, line))
rvar = self.box_for_var(res)
self.vars[res] = rvar
- return ResOperation(opnum, args, rvar, descr)
+ res = ResOperation(opnum, args, rvar, descr)
+ res.vdesc = vdesc
+ return res
def parse_op_no_result(self, line):
- opnum, args, descr = self.parse_op(line)
- return ResOperation(opnum, args, None, descr)
+ opnum, args, descr, vdesc = self.parse_op(line)
+ res = ResOperation(opnum, args, None, descr)
+ res.vdesc = vdesc
+ return res
def parse_next_op(self, line):
if "=" in line and line.find('(') > line.find('='):
From fijal at codespeak.net Mon May 25 00:47:26 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 00:47:26 +0200 (CEST)
Subject: [pypy-svn] r65391 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524224726.7494F168031@codespeak.net>
Author: fijal
Date: Mon May 25 00:47:25 2009
New Revision: 65391
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
Log:
A test and a proper fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Mon May 25 00:47:25 2009
@@ -81,7 +81,7 @@
allargs = allargs[:-1]
poss_vdesc = allargs[-1].strip()
if poss_vdesc.startswith('vdesc='):
- descr = self.consts[poss_descr[len('vdesc='):]]
+ vdesc = self.consts[poss_descr[len('vdesc='):]]
allargs = allargs[:-1]
for arg in allargs:
arg = arg.strip()
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py Mon May 25 00:47:25 2009
@@ -64,3 +64,18 @@
stuff = Xyz()
loop = parse(x, None, locals())
assert loop.operations[0].descr is stuff
+
+def test_vdesc():
+ class Xyz(AbstractDescr):
+ pass
+
+ x = """
+ [p0]
+ guard_nonvirtualized(p0, vdesc=stuff)
+ fail()
+ """
+ stuff = Xyz()
+ loop = parse(x, None, locals())
+ assert loop.operations[0].vdesc is stuff
+
+
From fijal at codespeak.net Mon May 25 00:50:43 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 00:50:43 +0200 (CEST)
Subject: [pypy-svn] r65392 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090524225043.0A2D9169F0D@codespeak.net>
Author: fijal
Date: Mon May 25 00:50:42 2009
New Revision: 65392
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
Log:
harmless change
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Mon May 25 00:50:42 2009
@@ -81,7 +81,7 @@
allargs = allargs[:-1]
poss_vdesc = allargs[-1].strip()
if poss_vdesc.startswith('vdesc='):
- vdesc = self.consts[poss_descr[len('vdesc='):]]
+ vdesc = self.consts[poss_vdesc[len('vdesc='):]]
allargs = allargs[:-1]
for arg in allargs:
arg = arg.strip()
From fijal at codespeak.net Mon May 25 00:52:54 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 00:52:54 +0200 (CEST)
Subject: [pypy-svn] r65393 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090524225254.D475E169F52@codespeak.net>
Author: fijal
Date: Mon May 25 00:52:54 2009
New Revision: 65393
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
a fix how it works in RL
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 00:52:54 2009
@@ -150,7 +150,7 @@
def optimize_guard_nonvirtualized(self, op, spec):
instnode = spec.getnode(op.args[0])
instnode.virtualized = True
- instnode.vdesc = op.descr
+ instnode.vdesc = op.vdesc
return None
def optimize_getfield_gc(self, op, spec):
@@ -179,7 +179,8 @@
spec.additional_stores.append((instnode, field))
return None
-specializer = Specializer([])
+specializer = Specializer([SimpleVirtualizableOpt(),
+ ConsecutiveGuardClassRemoval()])
def optimize_loop(options, old_loops, loop, cpu=None, spec=specializer):
if old_loops:
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Mon May 25 00:52:54 2009
@@ -122,7 +122,7 @@
def test_basic_virtualizable(self):
pre_op = """
[p0]
- guard_nonvirtualized(p0, descr=vdesc)
+ guard_nonvirtualized(p0, vdesc=vdesc)
fail()
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=field_desc)
@@ -139,7 +139,7 @@
def test_virtualizable_setfield_rebuild_ops(self):
pre_op = """
[p0]
- guard_nonvirtualized(p0, descr=vdesc)
+ guard_nonvirtualized(p0, vdesc=vdesc)
fail()
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=other_field_desc)
From fijal at codespeak.net Mon May 25 00:55:26 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 00:55:26 +0200 (CEST)
Subject: [pypy-svn] r65394 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090524225526.2AB3D169F55@codespeak.net>
Author: fijal
Date: Mon May 25 00:55:25 2009
New Revision: 65394
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
Log:
I suppose we're mature enough to print a dot per graph instead :)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py Mon May 25 00:55:25 2009
@@ -293,7 +293,7 @@
if self.debug:
self.bytecode.dump()
else:
- print repr(self.bytecode)
+ log.dot()
dir = udir.ensure("jitcodes", dir=1)
if self.portal:
name = "portal_runner"
From fijal at codespeak.net Mon May 25 00:59:54 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 00:59:54 +0200 (CEST)
Subject: [pypy-svn] r65395 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090524225954.7068D169F5B@codespeak.net>
Author: fijal
Date: Mon May 25 00:59:54 2009
New Revision: 65395
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
Log:
print info each 500 jitcodes
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py Mon May 25 00:59:54 2009
@@ -92,6 +92,7 @@
self.cpu = metainterp_sd.cpu
self.policy = policy
self.ts = ts
+ self.counter = 0
def make_portal_bytecode(self, graph):
log.info("making JitCodes...")
@@ -111,6 +112,9 @@
maker = BytecodeMaker(self, graph_key, portal)
if not hasattr(maker.bytecode, 'code'):
maker.assemble()
+ self.counter += 1
+ if not self.counter % 500:
+ log.info("Produced %d jitcodes" % self.counter)
return maker.bytecode
def get_jitcode(self, graph, called_from=None, oosend_methdescr=None):
From fijal at codespeak.net Mon May 25 02:04:50 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 02:04:50 +0200 (CEST)
Subject: [pypy-svn] r65396 -
pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit
Message-ID: <20090525000450.4686A169F28@codespeak.net>
Author: fijal
Date: Mon May 25 02:04:47 2009
New Revision: 65396
Modified:
pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/interp_jit.py
Log:
change a bit fields. They have different meaning right now though
Modified: pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/interp_jit.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/interp_jit.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/interp_jit.py Mon May 25 02:04:47 2009
@@ -17,7 +17,7 @@
from pypy.interpreter.pyopcode import ExitFrame
PyFrame._virtualizable2_ = True
-PyFrame._always_virtual_ = ['valuestack_w', 'fastlocals_w']
+PyFrame._always_virtual_ = ['valuestack_w', 'valuestackdepth']
class PyPyJitDriver(JitDriver):
reds = ['frame', 'ec']
@@ -70,7 +70,7 @@
# ____________________________________________________________
#
-# Public interface
+# Public interface
def set_param(space, args):
'''Configure the tunable JIT parameters.
From fijal at codespeak.net Mon May 25 02:15:49 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 02:15:49 +0200 (CEST)
Subject: [pypy-svn] r65397 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090525001549.7DE36169E82@codespeak.net>
Author: fijal
Date: Mon May 25 02:15:44 2009
New Revision: 65397
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
oops, avoid consecutive stores
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 02:15:44 2009
@@ -92,14 +92,14 @@
# modification in place. Reason for this is explained in mirror
# in optimize.py
op.suboperations = []
- for node, field in self.additional_stores:
+ for (node, field), fieldnode in self.additional_stores.iteritems():
op.suboperations.append(ResOperation(rop.SETFIELD_GC,
[node.source, node.cleanfields[field].source], None, field))
op.suboperations.append(op_fail)
op.args = self.new_arguments(op)
def optimize_operations(self):
- self.additional_stores = []
+ self.additional_stores = {}
newoperations = []
for op in self.loop.operations:
newop = op
@@ -174,9 +174,10 @@
field = op.descr
if field not in instnode.vdesc.virtuals:
return op
- instnode.cleanfields[field] = spec.getnode(op.args[1])
+ node = spec.getnode(op.args[1])
+ instnode.cleanfields[field] = node
# we never set it here
- spec.additional_stores.append((instnode, field))
+ spec.additional_stores[instnode, field] = node
return None
specializer = Specializer([SimpleVirtualizableOpt(),
From fijal at codespeak.net Mon May 25 04:31:47 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 04:31:47 +0200 (CEST)
Subject: [pypy-svn] r65398 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090525023147.B6744169F64@codespeak.net>
Author: fijal
Date: Mon May 25 04:31:44 2009
New Revision: 65398
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
move constant folding of guards into specializer
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 04:31:44 2009
@@ -4,6 +4,9 @@
from pypy.jit.metainterp.resoperation import rop, ResOperation, opname
from pypy.jit.metainterp.history import Const, Box
+class VirtualizedListAccessedWithVariableArg(Exception):
+ pass
+
class InstanceNode(object):
def __init__(self, source, const=False):
self.source = source
@@ -14,6 +17,7 @@
self.cleanfields = {}
self.dirtyfields = {}
self.virtualized = False
+ self.possibly_virtualized_list = False
def __repr__(self):
flags = ''
@@ -86,6 +90,11 @@
return newboxes
def optimize_guard(self, op):
+ for arg in op.args:
+ if not self.getnode(arg).const:
+ break
+ else:
+ return None
assert len(op.suboperations) == 1
op_fail = op.suboperations[0]
op_fail.args = self.new_arguments(op_fail)
@@ -95,11 +104,16 @@
for (node, field), fieldnode in self.additional_stores.iteritems():
op.suboperations.append(ResOperation(rop.SETFIELD_GC,
[node.source, node.cleanfields[field].source], None, field))
+ for (node, field), (fieldnode, descr) in self.additional_setarrayitems.iteritems():
+ op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
+ [node.source, field, node.cleanfields[field].source], None, descr))
op.suboperations.append(op_fail)
op.args = self.new_arguments(op)
+ return op
def optimize_operations(self):
self.additional_stores = {}
+ self.additional_setarrayitems = {}
newoperations = []
for op in self.loop.operations:
newop = op
@@ -110,13 +124,14 @@
if newop is None:
continue
if op.is_guard():
- self.optimize_guard(op)
- newoperations.append(op)
+ op = self.optimize_guard(op)
+ if op is not None:
+ newoperations.append(op)
continue
# default handler
op = op.clone()
op.args = self.new_arguments(op)
- if op.is_always_pure():
+ if op.is_always_pure() or op.is_guard():
for box in op.args:
if isinstance(box, Box):
break
@@ -164,7 +179,9 @@
if node is not None:
spec.nodes[op.result] = node
return None
- instnode.cleanfields[field] = spec.getnode(op.result)
+ node = spec.getnode(op.result)
+ node.possibly_virtualized_list = True
+ instnode.cleanfields[field] = node
return op
def optimize_setfield_gc(self, op, spec):
@@ -180,6 +197,35 @@
spec.additional_stores[instnode, field] = node
return None
+ def optimize_getarrayitem_gc(self, op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.possibly_virtualized_list:
+ return op
+ if not spec.getnode(op.args[1]).const:
+ raise VirtualizedListAccessedWithVariableArg()
+ field = spec.getnode(op.args[1]).source
+ node = instnode.cleanfields.get(field, None)
+ if node is not None:
+ spec.nodes[op.result] = node
+ return None
+ node = spec.getnode(op.result)
+ instnode.cleanfields[field] = node
+ return op
+
+
+ def optimize_setarrayitem_gc(self, op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.possibly_virtualized_list:
+ return op
+ fieldnode = spec.getnode(op.args[1])
+ if not fieldnode.const:
+ raise VirtualizedListAccessedWithVariableArg()
+ node = spec.getnode(op.args[2])
+ field = fieldnode.source
+ instnode.cleanfields[field] = node
+ spec.additional_setarrayitems[instnode, field] = (node, op.descr)
+ return None
+
specializer = Specializer([SimpleVirtualizableOpt(),
ConsecutiveGuardClassRemoval()])
@@ -200,3 +246,4 @@
optimize_bridge = staticmethod(optimize_bridge)
+
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Mon May 25 04:31:44 2009
@@ -56,11 +56,16 @@
nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodedescr = cpu.fielddescrof(NODE, 'value')
+ TP = lltype.GcArray(lltype.Signed)
+
XY = lltype.GcStruct('XY', ('inst_field', lltype.Signed),
('inst_other_field', lltype.Signed),
+ ('inst_list', lltype.Ptr(TP)),
hints= {'virtualizable2': True,
- 'virtuals': ('field',)})
+ 'virtuals': ('field','list')})
field_desc = cpu.fielddescrof(XY, 'inst_field')
+ array_descr = cpu.arraydescrof(TP)
+ list_desc = cpu.fielddescrof(XY, 'inst_list')
other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
vdesc = VirtualizableDesc(cpu, XY, XY)
@@ -85,7 +90,10 @@
class BaseTestOptimize2(object):
def optimize(self, lst, optimizations_enabled=[]):
- loop = parse(lst, self.cpu, self.namespace)
+ if not isinstance(lst, TreeLoop):
+ loop = parse(lst, self.cpu, self.namespace)
+ else:
+ loop = lst
optimize_loop(None, [], loop, self.cpu,
spec=Specializer(optimizations_enabled))
return loop.operations
@@ -160,7 +168,67 @@
"""
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
expected)
-
+
+ def test_const_guard_value(self):
+ pre_op = """
+ []
+ guard_value(0, 0)
+ fail()
+ """
+ expected = "[]"
+ self.assert_equal(self.optimize(pre_op, []), expected)
+
+ def test_virtualized_list_on_virtualizable(self):
+ pre_op = """
+ [p0]
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ p1 = getfield_gc(p0, descr=list_desc)
+ setarrayitem_gc(p1, 0, 1, descr=array_descr)
+ i1 = getarrayitem_gc(p1, 0)
+ i2 = int_add(i1, i1)
+ i3 = int_is_true(i2)
+ guard_true(i3)
+ fail()
+ """
+ pre_op = parse(pre_op, self.cpu, self.namespace)
+ # cheat
+ pre_op.operations[-2].result.value = 1
+ expected = """
+ [p0]
+ p1 = getfield_gc(p0, descr=list_desc)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+ expected)
+
+
+ def test_virtualized_list_on_virtualizable_2(self):
+ pre_op = """
+ [p0, i0]
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ p1 = getfield_gc(p0, descr=list_desc)
+ setarrayitem_gc(p1, 0, i0, descr=array_descr)
+ i1 = getarrayitem_gc(p1, 0)
+ i2 = int_add(i1, i1)
+ i3 = int_is_true(i2)
+ guard_true(i3)
+ fail()
+ """
+ pre_op = parse(pre_op, self.cpu, self.namespace)
+ # cheat
+ pre_op.operations[-2].result.value = 1
+ expected = """
+ [p0, i0]
+ p1 = getfield_gc(p0, descr=list_desc)
+ i2 = int_add(i0, i0)
+ i3 = int_is_true(i2)
+ guard_true(i3)
+ setarrayitem_gc(p1, 0, i0, descr=array_descr)
+ fail()
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+ expected)
def test_remove_consecutive_guard_value_constfold(self):
py.test.skip("not yet")
From fijal at codespeak.net Mon May 25 04:48:15 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 04:48:15 +0200 (CEST)
Subject: [pypy-svn] r65399 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090525024815.3A220169F55@codespeak.net>
Author: fijal
Date: Mon May 25 04:48:12 2009
New Revision: 65399
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
oops. This element of if is always false, but kill it anyway to avoid confusion
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 04:48:12 2009
@@ -131,7 +131,7 @@
# default handler
op = op.clone()
op.args = self.new_arguments(op)
- if op.is_always_pure() or op.is_guard():
+ if op.is_always_pure():
for box in op.args:
if isinstance(box, Box):
break
From fijal at codespeak.net Mon May 25 04:49:12 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 04:49:12 +0200 (CEST)
Subject: [pypy-svn] r65400 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090525024912.AED5F169F55@codespeak.net>
Author: fijal
Date: Mon May 25 04:49:12 2009
New Revision: 65400
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py
Log:
improve repr
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py Mon May 25 04:49:12 2009
@@ -42,13 +42,18 @@
return self.repr()
def repr(self):
+ from pypy.rlib.objectmodel import we_are_translated
# RPython-friendly version
if self.result is not None:
sres = '%s = ' % (self.result,)
else:
sres = ''
- return '%s%s(%s)' % (sres, self.getopname(),
- ', '.join([str(a) for a in self.args]))
+ if self.descr is None or we_are_translated():
+ return '%s%s(%s)' % (sres, self.getopname(),
+ ', '.join([str(a) for a in self.args]))
+ else:
+ return '%s%s(%s, descr=%r)' % (sres, self.getopname(),
+ ', '.join([str(a) for a in self.args]), self.descr)
def getopname(self):
try:
From fijal at codespeak.net Mon May 25 05:42:33 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 05:42:33 +0200 (CEST)
Subject: [pypy-svn] r65401 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090525034233.16C78169F28@codespeak.net>
Author: fijal
Date: Mon May 25 05:42:31 2009
New Revision: 65401
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
Fix annotation by providing a common superclass
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 05:42:31 2009
@@ -153,7 +153,10 @@
self.find_nodes()
self.optimize_operations()
-class ConsecutiveGuardClassRemoval(object):
+class AbstractOptimization(object):
+ pass
+
+class ConsecutiveGuardClassRemoval(AbstractOptimization):
def optimize_guard_class(self, op, spec):
instnode = spec.getnode(op.args[0])
if instnode.cls is not None:
@@ -161,7 +164,7 @@
instnode.cls = op.args[1]
return op
-class SimpleVirtualizableOpt(object):
+class SimpleVirtualizableOpt(AbstractOptimization):
def optimize_guard_nonvirtualized(self, op, spec):
instnode = spec.getnode(op.args[0])
instnode.virtualized = True
From fijal at codespeak.net Mon May 25 05:47:00 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 05:47:00 +0200 (CEST)
Subject: [pypy-svn] r65402 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090525034700.C4B1C169F28@codespeak.net>
Author: fijal
Date: Mon May 25 05:46:59 2009
New Revision: 65402
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
hack differently
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 05:46:59 2009
@@ -153,25 +153,25 @@
self.find_nodes()
self.optimize_operations()
-class AbstractOptimization(object):
- pass
-
-class ConsecutiveGuardClassRemoval(AbstractOptimization):
- def optimize_guard_class(self, op, spec):
+class ConsecutiveGuardClassRemoval(object):
+ @staticmethod
+ def optimize_guard_class(op, spec):
instnode = spec.getnode(op.args[0])
if instnode.cls is not None:
return None
instnode.cls = op.args[1]
return op
-class SimpleVirtualizableOpt(AbstractOptimization):
- def optimize_guard_nonvirtualized(self, op, spec):
+class SimpleVirtualizableOpt(object):
+ @staticmethod
+ def optimize_guard_nonvirtualized(op, spec):
instnode = spec.getnode(op.args[0])
instnode.virtualized = True
instnode.vdesc = op.vdesc
return None
- def optimize_getfield_gc(self, op, spec):
+ @staticmethod
+ def optimize_getfield_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.virtualized:
return op
@@ -187,7 +187,8 @@
instnode.cleanfields[field] = node
return op
- def optimize_setfield_gc(self, op, spec):
+ @staticmethod
+ def optimize_setfield_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.virtualized:
return op
@@ -200,7 +201,8 @@
spec.additional_stores[instnode, field] = node
return None
- def optimize_getarrayitem_gc(self, op, spec):
+ @staticmethod
+ def optimize_getarrayitem_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.possibly_virtualized_list:
return op
@@ -214,9 +216,9 @@
node = spec.getnode(op.result)
instnode.cleanfields[field] = node
return op
-
- def optimize_setarrayitem_gc(self, op, spec):
+ @staticmethod
+ def optimize_setarrayitem_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.possibly_virtualized_list:
return op
From fijal at codespeak.net Mon May 25 06:57:36 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 06:57:36 +0200 (CEST)
Subject: [pypy-svn] r65403 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090525045736.B3BF0169F35@codespeak.net>
Author: fijal
Date: Mon May 25 06:57:34 2009
New Revision: 65403
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
rpython fixes and minor cleanup
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Mon May 25 06:57:34 2009
@@ -101,12 +101,15 @@
# modification in place. Reason for this is explained in mirror
# in optimize.py
op.suboperations = []
- for (node, field), fieldnode in self.additional_stores.iteritems():
- op.suboperations.append(ResOperation(rop.SETFIELD_GC,
- [node.source, node.cleanfields[field].source], None, field))
- for (node, field), (fieldnode, descr) in self.additional_setarrayitems.iteritems():
- op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
- [node.source, field, node.cleanfields[field].source], None, descr))
+ for node, d in self.additional_stores.iteritems():
+ for field, fieldnode in d.iteritems():
+ op.suboperations.append(ResOperation(rop.SETFIELD_GC,
+ [node.source, fieldnode.source], None, field))
+ for node, d in self.additional_setarrayitems.iteritems():
+ for field, (fieldnode, descr) in d.iteritems():
+ box = fieldnode.source
+ op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
+ [node.source, field, box], None, descr))
op.suboperations.append(op_fail)
op.args = self.new_arguments(op)
return op
@@ -198,7 +201,8 @@
node = spec.getnode(op.args[1])
instnode.cleanfields[field] = node
# we never set it here
- spec.additional_stores[instnode, field] = node
+ d = spec.additional_stores.setdefault(instnode, {})
+ d[field] = node
return None
@staticmethod
@@ -222,13 +226,14 @@
instnode = spec.getnode(op.args[0])
if not instnode.possibly_virtualized_list:
return op
- fieldnode = spec.getnode(op.args[1])
- if not fieldnode.const:
+ argnode = spec.getnode(op.args[1])
+ if not argnode.const:
raise VirtualizedListAccessedWithVariableArg()
- node = spec.getnode(op.args[2])
- field = fieldnode.source
- instnode.cleanfields[field] = node
- spec.additional_setarrayitems[instnode, field] = (node, op.descr)
+ fieldnode = spec.getnode(op.args[2])
+ field = argnode.source
+ instnode.cleanfields[field] = fieldnode
+ d = spec.additional_setarrayitems.setdefault(instnode, {})
+ d[field] = (fieldnode, op.descr)
return None
specializer = Specializer([SimpleVirtualizableOpt(),
From fijal at codespeak.net Mon May 25 07:07:51 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 25 May 2009 07:07:51 +0200 (CEST)
Subject: [pypy-svn] r65404 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86
Message-ID: <20090525050751.C0E0A169F94@codespeak.net>
Author: fijal
Date: Mon May 25 07:07:49 2009
New Revision: 65404
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
Log:
for unclear reason this sometimes explodes when annotating
(saying that it cannot run compute_unique_id on None).
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py Mon May 25 07:07:49 2009
@@ -188,7 +188,11 @@
if op.is_guard():
self.eventually_log_operations(None, op.suboperations, memo)
if operations[-1].opnum == rop.JUMP:
- jump_target = compute_unique_id(operations[-1].jump_target)
+ if operations[-1].jump_target is not None:
+ jump_target = compute_unique_id(operations[-1].jump_target)
+ else:
+ # XXX hack for the annotator
+ jump_target = 13
os.write(self._log_fd, 'JUMPTO:%s\n' % jump_target)
if inputargs is None:
os.write(self._log_fd, "END\n")
From antocuni at codespeak.net Mon May 25 10:34:19 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 25 May 2009 10:34:19 +0200 (CEST)
Subject: [pypy-svn] r65405 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090525083419.CFCF5169FA1@codespeak.net>
Author: antocuni
Date: Mon May 25 10:34:18 2009
New Revision: 65405
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
start to port test_optimize2.py to ootype
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Mon May 25 10:34:18 2009
@@ -4,9 +4,10 @@
"""
from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt,\
- ConstAddr
+ ConstAddr, ConstObj
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.ootypesystem import ootype
_cache = {}
@@ -14,11 +15,12 @@
pass
class OpParser(object):
- def __init__(self, descr, cpu, namespace):
+ def __init__(self, descr, cpu, namespace, type_system):
self.descr = descr
self.vars = {}
self.cpu = cpu
self.consts = namespace
+ self.type_system = type_system
def box_for_var(self, elem):
try:
@@ -50,10 +52,13 @@
try:
return ConstInt(int(arg))
except ValueError:
- if arg.startswith('ConstAddr('):
- name = arg[len('ConstAddr('):-1]
- return ConstAddr(llmemory.cast_ptr_to_adr(self.consts[name]),
- self.cpu)
+ if arg.startswith('ConstClass('):
+ name = arg[len('ConstClass('):-1]
+ if self.type_system == 'lltype':
+ return ConstAddr(llmemory.cast_ptr_to_adr(self.consts[name]),
+ self.cpu)
+ else:
+ return ConstObj(ootype.cast_to_object(self.consts[name]))
return self.vars[arg]
def parse_op(self, line):
@@ -162,5 +167,5 @@
inpargs = self.parse_header_line(line[1:-1])
return base_indent, inpargs
-def parse(descr, cpu=None, namespace={}):
- return OpParser(descr, cpu, namespace).parse()
+def parse(descr, cpu=None, namespace={}, type_system='lltype'):
+ return OpParser(descr, cpu, namespace, type_system).parse()
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_oparser.py Mon May 25 10:34:18 2009
@@ -22,7 +22,7 @@
def test_const_ptr_subops():
x = """
[p0]
- guard_class(p0, ConstAddr(vtable))
+ guard_class(p0, ConstClass(vtable))
fail()
"""
S = lltype.Struct('S')
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Mon May 25 10:34:18 2009
@@ -42,6 +42,7 @@
return True
class LLtypeMixin(object):
+ type_system = 'lltype'
node_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
node_vtable_adr = llmemory.cast_ptr_to_adr(node_vtable)
@@ -72,6 +73,8 @@
namespace = locals()
class OOtypeMixin(object):
+ type_system = 'ootype'
+
cpu = runner.OOtypeCPU(None)
NODE = ootype.Instance('NODE', ootype.ROOT, {})
@@ -85,13 +88,32 @@
nodebox = BoxObj(ootype.cast_to_object(node))
nodedescr = cpu.fielddescrof(NODE, 'value')
+ TP = ootype.Array(ootype.Signed)
+
+ XY = ootype.Instance('XY', ootype.ROOT,
+ {'inst_field': ootype.Signed,
+ 'inst_other_field': ootype.Signed,
+ 'inst_list': TP},
+ _hints = {'virtualizable2': True,
+ 'virtuals': ('field','list')})
+
+ field_desc = cpu.fielddescrof(XY, 'inst_field')
+ array_descr = cpu.arraydescrof(TP)
+ list_desc = cpu.fielddescrof(XY, 'inst_list')
+ other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
+ vdesc = VirtualizableDesc(cpu, XY, XY)
+
namespace = locals()
class BaseTestOptimize2(object):
+ def parse(self, s):
+ return parse(s, self.cpu, self.namespace,
+ type_system=self.type_system)
+
def optimize(self, lst, optimizations_enabled=[]):
if not isinstance(lst, TreeLoop):
- loop = parse(lst, self.cpu, self.namespace)
+ loop = self.parse(lst)
else:
loop = lst
optimize_loop(None, [], loop, self.cpu,
@@ -99,8 +121,7 @@
return loop.operations
def assert_equal(self, optimized, expected):
- equaloplists(optimized,
- parse(expected, self.cpu, self.namespace).operations)
+ equaloplists(optimized, self.parse(expected).operations)
def test_basic_constant_folding(self):
pre_op = """
@@ -113,14 +134,14 @@
def test_remove_guard_class(self):
pre_op = """
[p0]
- guard_class(p0, ConstAddr(node_vtable))
+ guard_class(p0, ConstClass(node_vtable))
fail()
- guard_class(p0, ConstAddr(node_vtable))
+ guard_class(p0, ConstClass(node_vtable))
fail()
"""
expected = """
[p0]
- guard_class(p0, ConstAddr(node_vtable))
+ guard_class(p0, ConstClass(node_vtable))
fail()
"""
self.assert_equal(self.optimize(pre_op,
@@ -290,5 +311,11 @@
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
- def setup_class(cls):
- py.test.skip("XXX Fix me")
+
+ def skip(self):
+ py.test.skip('in-progress')
+
+ test_basic_virtualizable = skip
+ test_virtualizable_setfield_rebuild_ops = skip
+ test_virtualized_list_on_virtualizable = skip
+ test_virtualized_list_on_virtualizable_2 = skip
From antocuni at codespeak.net Mon May 25 10:44:04 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 25 May 2009 10:44:04 +0200 (CEST)
Subject: [pypy-svn] r65406 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090525084404.3A34E169FCA@codespeak.net>
Author: antocuni
Date: Mon May 25 10:44:03 2009
New Revision: 65406
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
fix ootype virtualizable tests
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Mon May 25 10:44:03 2009
@@ -91,16 +91,16 @@
TP = ootype.Array(ootype.Signed)
XY = ootype.Instance('XY', ootype.ROOT,
- {'inst_field': ootype.Signed,
- 'inst_other_field': ootype.Signed,
- 'inst_list': TP},
+ {'ofield': ootype.Signed,
+ 'oother_field': ootype.Signed,
+ 'olist': TP},
_hints = {'virtualizable2': True,
'virtuals': ('field','list')})
- field_desc = cpu.fielddescrof(XY, 'inst_field')
+ field_desc = cpu.fielddescrof(XY, 'ofield')
array_descr = cpu.arraydescrof(TP)
- list_desc = cpu.fielddescrof(XY, 'inst_list')
- other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
+ list_desc = cpu.fielddescrof(XY, 'olist')
+ other_field_desc = cpu.fielddescrof(XY, 'oother_field')
vdesc = VirtualizableDesc(cpu, XY, XY)
namespace = locals()
@@ -311,11 +311,4 @@
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
-
- def skip(self):
- py.test.skip('in-progress')
-
- test_basic_virtualizable = skip
- test_virtualizable_setfield_rebuild_ops = skip
- test_virtualized_list_on_virtualizable = skip
- test_virtualized_list_on_virtualizable_2 = skip
+ pass
From antocuni at codespeak.net Mon May 25 12:43:35 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 25 May 2009 12:43:35 +0200 (CEST)
Subject: [pypy-svn] r65407 - in pypy/branch/pyjitpl5-experiments/pypy/jit: .
metainterp
Message-ID: <20090525104335.BE8FE169FCA@codespeak.net>
Author: antocuni
Date: Mon May 25 12:43:33 2009
New Revision: 65407
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/conftest.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py
Log:
add an option to show only the loops, ignoring the annotated/rtyped graphs
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/conftest.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/conftest.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/conftest.py Mon May 25 12:43:33 2009
@@ -9,5 +9,9 @@
group.addoption('--slow', action="store_true",
default=False, dest="run_slow_tests",
help="run all the compiled tests (instead of just a few)")
+ group.addoption('--viewloops', action="store_true",
+ default=False, dest="viewloops",
+ help="show only the compiled loops")
+
ConftestPlugin = JitTestPlugin
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py Mon May 25 12:43:33 2009
@@ -66,7 +66,7 @@
def show_loop(metainterp, loop=None, error=None):
# debugging
- if option.view:
+ if option.view or option.viewloops:
if error:
errmsg = error.__class__.__name__
if str(error):
From antocuni at codespeak.net Mon May 25 14:09:46 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 25 May 2009 14:09:46 +0200 (CEST)
Subject: [pypy-svn] r65408 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph
Message-ID: <20090525120946.A537F169F68@codespeak.net>
Author: antocuni
Date: Mon May 25 14:09:44 2009
New Revision: 65408
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py
Log:
make reprs of oo descrs more readable
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py Mon May 25 14:09:44 2009
@@ -593,6 +593,9 @@
return boxresult(RESULT, res)
self.callmeth = callmeth
+ def __repr__(self):
+ return '' % self.methname
+
class TypeDescr(OODescr):
create = None
@@ -633,6 +636,9 @@
self.getarraylength = getarraylength
self.instanceof = instanceof
+ def __repr__(self):
+ return '' % self.TYPE._short_name()
+
class FieldDescr(OODescr):
getfield = None
@@ -662,6 +668,9 @@
return self.TYPE == other.TYPE and \
self.fieldname == other.fieldname
+ def __repr__(self):
+ return '' % self.fieldname
+
# ____________________________________________________________
From cfbolz at codespeak.net Mon May 25 14:25:21 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 25 May 2009 14:25:21 +0200 (CEST)
Subject: [pypy-svn] r65409 - in
pypy/branch/tagged-pointers-framework/pypy/rpython:
lltypesystem memory/gc memory/test test
Message-ID: <20090525122521.C506C169F41@codespeak.net>
Author: cfbolz
Date: Mon May 25 14:25:19 2009
New Revision: 65409
Modified:
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py
pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py
Log:
- fix casting of opaque pointers to ints. Needed for correct GCREF handing
- allowing casting of addresses of dead objects to int. Fixes some
test_transformed_gc tests
- proper id handling of tagged pointers in moving GCs
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/llmemory.py Mon May 25 14:25:19 2009
@@ -461,8 +461,10 @@
return lltype.nullptr(EXPECTED_TYPE.TO)
def _cast_to_int(self):
+ # This is a bit annoying. We want this method to still work when the
+ # pointed-to object is dead
if self:
- return self.ptr._cast_to_int()
+ return self.ptr._cast_to_int(False)
else:
return 0
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/lltype.py Mon May 25 14:25:19 2009
@@ -816,6 +816,7 @@
if not ptr:
return nullptr(PTRTYPE.TO)
return opaqueptr(PTRTYPE.TO, 'hidden', container = ptr._obj,
+ ORIGTYPE = CURTYPE,
solid = ptr._solid)
elif (isinstance(CURTYPE.TO, OpaqueType)
and isinstance(PTRTYPE.TO, OpaqueType)):
@@ -899,7 +900,7 @@
top_parent = parent
return top_parent
-def normalizeptr(p):
+def normalizeptr(p, check=True):
# If p is a pointer, returns the same pointer casted to the largest
# containing structure (for the cast where p points to the header part).
# Also un-hides pointers to opaque. Null pointers become None.
@@ -907,12 +908,17 @@
T = typeOf(p)
if not isinstance(T, Ptr):
return p # primitive
- if not p:
+ obj = p._getobj(check)
+ if not obj:
return None # null pointer
if type(p._obj0) is int:
return p # a pointer obtained by cast_int_to_ptr
- container = p._obj._normalizedcontainer()
- if container is not p._obj:
+ container = obj._normalizedcontainer()
+ if type(container) is int:
+ # this must be an opaque ptr originating from an integer
+ assert isinstance(obj, _opaque)
+ return cast_int_to_ptr(obj.ORIGTYPE, container)
+ if container is not obj:
p = _ptr(Ptr(typeOf(container)), container, p._solid)
return p
@@ -1171,13 +1177,15 @@
raise RuntimeError("widening %r inside %r instead of %r" % (CURTYPE, PARENTTYPE, PTRTYPE.TO))
return _ptr(PTRTYPE, struc, solid=self._solid)
- def _cast_to_int(self):
- if not self:
+ def _cast_to_int(self, check=True):
+ obj = self._getobj(check)
+ if not obj:
return 0 # NULL pointer
- obj = self._obj
if isinstance(obj, int):
return obj # special case for cast_int_to_ptr() results
- obj = normalizeptr(self)._obj
+ obj = normalizeptr(self, check)._getobj(check)
+ if isinstance(obj, int):
+ return obj # special case for cast_int_to_ptr() results put into opaques
result = intmask(obj._getid())
# assume that id() returns an addressish value which is
# not zero and aligned to at least a multiple of 4
@@ -1718,6 +1726,9 @@
# if we are an opaque containing a normal Struct/GcStruct,
# unwrap it
if hasattr(self, 'container'):
+ # an integer, cast to a ptr, cast to an opaque
+ if type(self.container) is int:
+ return self.container
return self.container._normalizedcontainer()
else:
return _parentable._normalizedcontainer(self)
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/base.py Mon May 25 14:25:19 2009
@@ -243,6 +243,8 @@
GCBase.setup(self)
self.objects_with_id = self.AddressDict()
self.id_free_list = self.AddressStack()
+ # XXX XXX XXX think of something sane:
+ # how do we prevent clashing with tagged pointers?
self.next_free_id = 1
def can_move(self, addr):
@@ -252,6 +254,11 @@
# Default implementation for id(), assuming that "external" objects
# never move. Overriden in the HybridGC.
obj = llmemory.cast_ptr_to_adr(ptr)
+
+ # is it a tagged pointer?
+ if not self.is_valid_gc_object(obj):
+ return llmemory.cast_adr_to_int(obj) // 2
+
if self._is_external(obj):
result = obj
else:
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gc/hybrid.py Mon May 25 14:25:19 2009
@@ -553,6 +553,11 @@
def id(self, ptr):
obj = llmemory.cast_ptr_to_adr(ptr)
+
+ # is it a tagged pointer?
+ if not self.is_valid_gc_object(obj):
+ return llmemory.cast_adr_to_int(obj)
+
if self._is_external(obj):
# a prebuilt or rawmalloced object
if self.is_last_generation(obj):
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py Mon May 25 14:25:19 2009
@@ -514,6 +514,35 @@
res = self.interpret(fn, [-1000])
assert res == -897
+ def test_tagged_id(self):
+ from pypy.rlib.objectmodel import UnboxedValue, compute_unique_id
+
+ class Unrelated(object):
+ pass
+
+ u = Unrelated()
+ u.x = UnboxedObject(47)
+ def fn(n):
+ id_prebuilt1 = compute_unique_id(u.x)
+ if n > 0:
+ x = BoxedObject(n)
+ else:
+ x = UnboxedObject(n)
+ id_x1 = compute_unique_id(x)
+ rgc.collect() # check that a prebuilt tagged pointer doesn't explode
+ id_prebuilt2 = compute_unique_id(u.x)
+ id_x2 = compute_unique_id(x)
+ print u.x, id_prebuilt1, id_prebuilt2
+ print x, id_x1, id_x2
+ return ((id_x1 == id_x2) * 1 +
+ (id_prebuilt1 == id_prebuilt2) * 10 +
+ (id_x1 != id_prebuilt1) * 100)
+ res = self.interpret(fn, [1000])
+ assert res == 111
+ res = self.interpret(fn, [-1000])
+ assert res == 111
+
+
from pypy.rlib.objectmodel import UnboxedValue
class TaggedBase(object):
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py Mon May 25 14:25:19 2009
@@ -525,7 +525,7 @@
res = fn([])
assert res == 'y'
- def test_tagged(self):
+ def test_tagged_simple(self):
class Unrelated(object):
pass
@@ -546,6 +546,27 @@
res = func([])
assert res == fn(1000) + fn(-1000)
+ def test_tagged_prebuilt(self):
+
+ class F:
+ pass
+
+ f = F()
+ f.l = [UnboxedObject(10)]
+ def fn(n):
+ if n > 0:
+ x = BoxedObject(n)
+ else:
+ x = UnboxedObject(n)
+ f.l.append(x)
+ rgc.collect()
+ return f.l[-1].meth(100)
+ def func():
+ return fn(1000) ^ fn(-1000)
+ func = self.runner(func)
+ res = func([])
+ assert res == fn(1000) ^ fn(-1000)
+
from pypy.rlib.objectmodel import UnboxedValue
class TaggedBase(object):
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/test/test_rptr.py Mon May 25 14:25:19 2009
@@ -112,6 +112,20 @@
interpret(fn, [11521])
+def test_odd_ints_opaque():
+ T = GcStruct('T')
+ Q = GcOpaqueType('Q')
+ PT = Ptr(T)
+ PQ = Ptr(Q)
+ def fn(n):
+ t = cast_int_to_ptr(PT, n)
+ assert typeOf(t) == PT
+ assert cast_ptr_to_int(t) == n
+ o = cast_opaque_ptr(PQ, t)
+ assert cast_ptr_to_int(o) == n
+
+ fn(13)
+ interpret(fn, [11521])
def test_Ptr():
S = GcStruct('s')
From cfbolz at codespeak.net Mon May 25 14:34:08 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 25 May 2009 14:34:08 +0200 (CEST)
Subject: [pypy-svn] r65410 - pypy/branch/speedup-global2/pypy/doc/config
Message-ID: <20090525123408.CC7B5169F77@codespeak.net>
Author: cfbolz
Date: Mon May 25 14:34:08 2009
New Revision: 65410
Added:
pypy/branch/speedup-global2/pypy/doc/config/objspace.std.withcelldict.txt (contents, props changed)
Log:
add missing documentation
Added: pypy/branch/speedup-global2/pypy/doc/config/objspace.std.withcelldict.txt
==============================================================================
--- (empty file)
+++ pypy/branch/speedup-global2/pypy/doc/config/objspace.std.withcelldict.txt Mon May 25 14:34:08 2009
@@ -0,0 +1,2 @@
+Enable cell-dicts. This makes global lookups nearly as fast as the lookup of a
+local.
From antocuni at codespeak.net Mon May 25 15:03:41 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 25 May 2009 15:03:41 +0200 (CEST)
Subject: [pypy-svn] r65411 - pypy/branch/pyjitpl5-experiments/pypy/jit/tl
Message-ID: <20090525130341.E7AA0169FD7@codespeak.net>
Author: antocuni
Date: Mon May 25 15:03:40 2009
New Revision: 65411
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/tl/tlc.py
Log:
framestack was an artifact introduced in the oo-jit branch to avoid recursive calls. Remove it, as it's not needed anymore
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/tl/tlc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/tl/tlc.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/tl/tlc.py Mon May 25 15:03:40 2009
@@ -225,16 +225,11 @@
self.pc = pc
self.stack = []
-class Framestack(object):
- _virtualizable2_ = True
-
- def __init__(self):
- self.s = []
def make_interp(supports_call, jitted=True):
myjitdriver = JitDriver(greens = ['code', 'pc'],
- reds = ['frame', 'framestack', 'pool'],
- virtualizables = ['frame', 'framestack'])
+ reds = ['frame', 'pool'],
+ virtualizables = ['frame'])
def interp(code='', pc=0, inputarg=0, pool=None):
if not isinstance(code,str):
raise TypeError("code '%s' should be a string" % str(code))
@@ -246,13 +241,12 @@
def interp_eval(code, pc, args, pool):
assert isinstance(pc, int)
- framestack = Framestack()
frame = Frame(args, pc)
pc = frame.pc
while pc < len(code):
if jitted:
- myjitdriver.jit_merge_point(frame=frame, framestack=framestack,
+ myjitdriver.jit_merge_point(frame=frame,
code=code, pc=pc, pool=pool)
opcode = ord(code[pc])
pc += 1
@@ -355,7 +349,6 @@
pc += 1
if jitted and old_pc > pc:
myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
- framestack=framestack,
pool=pool)
elif opcode == BR_COND:
@@ -365,7 +358,6 @@
pc += char2int(code[pc]) + 1
if jitted and old_pc > pc:
myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
- framestack=framestack,
pool=pool)
else:
pc += 1
@@ -377,31 +369,19 @@
pc += offset
if jitted and old_pc > pc:
myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
- framestack=framestack,
pool=pool)
elif supports_call and opcode == CALL:
offset = char2int(code[pc])
pc += 1
- frame.pc = pc
- framestack.s.append(frame)
- frame = Frame([zero], pc + offset)
- pc = frame.pc
-
- elif opcode == RETURN:
- if not framestack.s:
- break
- if stack:
- res = stack.pop()
- else:
- res = None
- frame = framestack.s.pop()
- stack = frame.stack
- pc = frame.pc
+ res = interp_eval(code, pc + offset, [zero], pool)
if res:
stack.append(res)
+ elif opcode == RETURN:
+ break
+
elif opcode == PUSHARG:
stack.append(frame.args[0])
@@ -444,10 +424,9 @@
meth_args[num_args] = stack.pop()
a = meth_args[0]
meth_pc = a.send(name)
- frame.pc = pc
- framestack.s.append(frame)
- frame = Frame(meth_args, meth_pc)
- pc = meth_pc
+ res = interp_eval(code, meth_pc, meth_args, pool)
+ if res:
+ stack.append(res)
elif opcode == PRINT:
if not we_are_translated():
@@ -464,7 +443,10 @@
else:
raise RuntimeError("unknown opcode: " + str(opcode))
- return frame.stack[-1]
+ if frame.stack:
+ return frame.stack[-1]
+ else:
+ return None
return interp, interp_eval
From cfbolz at codespeak.net Mon May 25 17:22:31 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 25 May 2009 17:22:31 +0200 (CEST)
Subject: [pypy-svn] r65412 - in pypy/branch/tagged-pointers-framework/pypy:
config rpython/lltypesystem rpython/lltypesystem/test
rpython/memory/test
Message-ID: <20090525152231.A2BCA169F14@codespeak.net>
Author: cfbolz
Date: Mon May 25 17:22:29 2009
New Revision: 65412
Modified:
pypy/branch/tagged-pointers-framework/pypy/config/pypyoption.py
pypy/branch/tagged-pointers-framework/pypy/config/translationoption.py
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rclass.py
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_gc.py
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/test/test_transformed_gc.py
Log:
Add a translation config option to use pointer tagging. This should make it
possible for e.g. the Smalltalk VM to make pointer tagging a translate.py (as it
is not really natural there to have to different classes as in the Python
interpreter).
Modified: pypy/branch/tagged-pointers-framework/pypy/config/pypyoption.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/config/pypyoption.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/config/pypyoption.py Mon May 25 17:22:29 2009
@@ -186,7 +186,8 @@
BoolOption("withsmallint", "use tagged integers",
default=False,
- requires=[("objspace.std.withprebuiltint", False)]),
+ requires=[("objspace.std.withprebuiltint", False),
+ ("translation.taggedpointers", True)]),
BoolOption("withprebuiltint", "prebuild commonly used int objects",
default=False),
Modified: pypy/branch/tagged-pointers-framework/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/config/translationoption.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/config/translationoption.py Mon May 25 17:22:29 2009
@@ -162,6 +162,10 @@
IntOption("withsmallfuncsets",
"Represent groups of less funtions than this as indices into an array",
default=0),
+ BoolOption("taggedpointers",
+ "When true, enable the use of tagged pointers. "
+ "If false, use normal boxing",
+ default=False),
# options for ootype
OptionDescription("ootype", "Object Oriented Typesystem options", [
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rclass.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rclass.py Mon May 25 17:22:29 2009
@@ -619,17 +619,19 @@
Constant(False)).value
virtualizable2 = classdef.classdesc.read_attribute('_virtualizable2_',
Constant(False)).value
+ config = rtyper.annotator.translator.config
+ usetagging = len(unboxed) != 0 and config.translation.taggedpointers
if virtualizable:
- assert len(unboxed) == 0
+ assert not usetagging
assert gcflavor == 'gc'
from pypy.rpython.lltypesystem import rvirtualizable
return rvirtualizable.VirtualizableInstanceRepr(rtyper, classdef)
elif virtualizable2:
- assert len(unboxed) == 0
+ assert not usetagging
assert gcflavor == 'gc'
from pypy.rpython.lltypesystem import rvirtualizable2
return rvirtualizable2.Virtualizable2InstanceRepr(rtyper, classdef)
- elif len(unboxed) == 0:
+ elif not usetagging:
return InstanceRepr(rtyper, classdef, gcflavor)
else:
# the UnboxedValue class and its parent classes need a
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py Mon May 25 17:22:29 2009
@@ -33,20 +33,20 @@
def test_instantiate():
def fn1(n):
return C(n)
- res = interpret(fn1, [42])
+ res = interpret(fn1, [42], taggedpointers=True)
value = lltype.cast_ptr_to_int(res)
assert value == 42 * 2 + 1 # for now
def test_attribute():
def fn1(n):
return C(n).smallint
- res = interpret(fn1, [42])
+ res = interpret(fn1, [42], taggedpointers=True)
assert res == 42
def test_getvalue():
def fn1(n):
return C(n).getvalue()
- res = interpret(fn1, [42])
+ res = interpret(fn1, [42], taggedpointers=True)
assert res == 42
def test_overflowerror():
@@ -65,11 +65,11 @@
else:
return 'A', 0
- res = interpret(fn2, [-117])
+ res = interpret(fn2, [-117], taggedpointers=True)
assert res.item0 == 'C'
assert res.item1 == -117
- res = interpret(fn2, [sys.maxint])
+ res = interpret(fn2, [sys.maxint], taggedpointers=True)
assert res.item0 == 'B'
assert res.item1 == sys.maxint
@@ -95,13 +95,13 @@
else:
return 'A', 0
- res = interpret(fn, [12])
+ res = interpret(fn, [12], taggedpointers=True)
assert res.item0 == 'C'
assert res.item1 == 12
- res = interpret(fn, [-1])
+ res = interpret(fn, [-1], taggedpointers=True)
assert res.item0 == 'C'
assert res.item1 == 111
- res = interpret(fn, [0])
+ res = interpret(fn, [0], taggedpointers=True)
assert res.item0 == 'B'
assert res.item1 == 939393
@@ -118,9 +118,9 @@
x = C(n)
return g(x)
- res = interpret(fn, [-1])
+ res = interpret(fn, [-1], taggedpointers=True)
assert res == sys.maxint
- res = interpret(fn, [56])
+ res = interpret(fn, [56], taggedpointers=True)
assert res == 56
def test_type():
@@ -131,9 +131,9 @@
x = C(n)
return type(x) is B, type(x) is C
- res = interpret(fn, [-212])
+ res = interpret(fn, [-212], taggedpointers=True)
assert res.item0 and not res.item1
- res = interpret(fn, [9874])
+ res = interpret(fn, [9874], taggedpointers=True)
assert res.item1 and not res.item0
def test_str():
@@ -143,9 +143,9 @@
else:
x = C(n)
return str(x)
- res = interpret(fn, [-832])
+ res = interpret(fn, [-832], taggedpointers=True)
assert ''.join(res.chars) == ''
- res = interpret(fn, [1])
+ res = interpret(fn, [1], taggedpointers=True)
assert ''.join(res.chars).startswith(''
- res = interpret(fn, [1])
+ res = interpret(fn, [1], taggedpointers=True)
assert ''.join(res.chars).startswith('
Author: cfbolz
Date: Mon May 25 17:26:28 2009
New Revision: 65413
Modified:
pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_boehm.py
pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_newgc.py
Log:
Fix translating tagging tests to use the new option.
Modified: pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_boehm.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_boehm.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_boehm.py Mon May 25 17:26:28 2009
@@ -24,7 +24,7 @@
self._cleanups.pop()()
def getcompiled(self, func, argstypelist = [],
- annotatorpolicy=None):
+ annotatorpolicy=None, **extraconfigopts):
from pypy.config.pypyoption import get_pypy_config
config = get_pypy_config(translating=True)
config.translation.gc = self.gcpolicy
@@ -32,6 +32,7 @@
if self.stacklessgc:
config.translation.gcrootfinder = "stackless"
config.translation.simplifying = True
+ config.set(**extraconfigopts)
t = TranslationContext(config=config)
self.t = t
a = t.buildannotator(policy=annotatorpolicy)
Modified: pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_newgc.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_newgc.py Mon May 25 17:26:28 2009
@@ -15,6 +15,7 @@
from pypy.rlib.rstring import StringBuilder, UnicodeBuilder
from pypy import conftest
from pypy.tool.udir import udir
+from pypy.rlib import rgc
def compile_func(fn, inputtypes, t=None, gcpolicy="ref"):
from pypy.config.pypyoption import get_pypy_config
@@ -584,7 +585,6 @@
def test_weakref(self):
import weakref
- from pypy.rlib import rgc
class A:
pass
@@ -620,7 +620,6 @@
def test_prebuilt_weakref(self):
import weakref
- from pypy.rlib import rgc
class A:
pass
a = A()
@@ -844,7 +843,6 @@
from pypy.rlib.libffi import ffi_type_pointer, cast_type_to_ffitype,\
CDLL, ffi_type_void, CallbackFuncPtr, ffi_type_sint
from pypy.rpython.lltypesystem import rffi, ll2ctypes
- from pypy.rlib import rgc
import gc
slong = cast_type_to_ffitype(rffi.LONG)
@@ -891,7 +889,6 @@
assert c_fn() == 1
def test_can_move(self):
- from pypy.rlib import rgc
class A:
pass
def fn():
@@ -904,7 +901,6 @@
TP = lltype.GcArray(lltype.Char)
def func():
try:
- from pypy.rlib import rgc
a = rgc.malloc_nonmovable(TP, 3)
rgc.collect()
if a:
@@ -920,7 +916,6 @@
def test_resizable_buffer(self):
from pypy.rpython.lltypesystem.rstr import STR
from pypy.rpython.annlowlevel import hlstr
- from pypy.rlib import rgc
def f():
ptr = rgc.resizable_buffer_of_shape(STR, 2)
@@ -932,6 +927,45 @@
run = self.getcompiled(f)
assert run() == True
+ def test_tagged(self):
+ class Unrelated(object):
+ pass
+
+ u = Unrelated()
+ u.x = UnboxedObject(47)
+ def fn(n):
+ rgc.collect() # check that a prebuilt tagged pointer doesn't explode
+ if n > 0:
+ x = BoxedObject(n)
+ else:
+ x = UnboxedObject(n)
+ u.x = x # invoke write barrier
+ rgc.collect()
+ return x.meth(100)
+ def func():
+ return fn(1000) + fn(-1000)
+ func = self.getcompiled(func, taggedpointers=True)
+ res = func()
+ assert res == fn(1000) + fn(-1000)
+
+from pypy.rlib.objectmodel import UnboxedValue
+
+class TaggedBase(object):
+ __slots__ = ()
+ def meth(self, x):
+ raise NotImplementedError
+
+class BoxedObject(TaggedBase):
+ attrvalue = 66
+ def __init__(self, normalint):
+ self.normalint = normalint
+ def meth(self, x):
+ return self.normalint + x + 2
+
+class UnboxedObject(TaggedBase, UnboxedValue):
+ __slots__ = 'smallint'
+ def meth(self, x):
+ return self.smallint + x + 3
class TestSemiSpaceGC(TestUsingFramework, snippet.SemiSpaceGCTests):
gcpolicy = "semispace"
should_be_moving = True
@@ -975,7 +1009,6 @@
def fn():
# the semispace size starts at 8MB for now, so setting a
# smaller limit has no effect
- from pypy.rlib import rgc
rgc.set_max_heap_size(20000000) # almost 20 MB
s1 = s2 = s3 = None
try:
From cfbolz at codespeak.net Mon May 25 17:39:36 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 25 May 2009 17:39:36 +0200 (CEST)
Subject: [pypy-svn] r65414 - pypy/branch/tagged-pointers-framework/pypy/rlib
Message-ID: <20090525153936.37004169F2E@codespeak.net>
Author: cfbolz
Date: Mon May 25 17:39:35 2009
New Revision: 65414
Modified:
pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py
Log:
update comment
Modified: pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py Mon May 25 17:39:35 2009
@@ -227,7 +227,8 @@
class UnboxedValue(object):
"""A mixin class to use for classes that have exactly one field which
- is an integer. They are represented as a tagged pointer."""
+ is an integer. They are represented as a tagged pointer, if the
+ translation.taggedpointers config option is used."""
_mixin_ = True
def __new__(cls, value):
From cfbolz at codespeak.net Mon May 25 17:44:47 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 25 May 2009 17:44:47 +0200 (CEST)
Subject: [pypy-svn] r65415 - in pypy/branch/tagged-pointers-framework/pypy:
rlib rpython/lltypesystem rpython/lltypesystem/test
Message-ID: <20090525154447.180141684EF@codespeak.net>
Author: cfbolz
Date: Mon May 25 17:44:47 2009
New Revision: 65415
Modified:
pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py
Log:
Rename the very generic method name "getvalue" to get_untagged_value. So far
it's not really used much anyway, only in tests.
Modified: pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rlib/objectmodel.py Mon May 25 17:44:47 2009
@@ -248,9 +248,9 @@
raise OverflowError("UnboxedValue: argument out of range")
def __repr__(self):
- return '' % (self.getvalue(),)
+ return '' % (self.get_untagged_value(),)
- def getvalue(self): # helper, equivalent to reading the custom field
+ def get_untagged_value(self): # helper, equivalent to reading the custom field
if isinstance(self.__class__.__slots__, str):
return getattr(self, self.__class__.__slots__)
else:
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py Mon May 25 17:44:47 2009
@@ -53,7 +53,7 @@
def convert_const_exact(self, value):
self.setup()
- number = value.getvalue()
+ number = value.get_untagged_value()
return ll_int_to_unboxed(self.lowleveltype, number)
def getvalue_from_unboxed(self, llops, vinst):
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py Mon May 25 17:44:47 2009
@@ -43,9 +43,9 @@
res = interpret(fn1, [42], taggedpointers=True)
assert res == 42
-def test_getvalue():
+def test_get_untagged_value():
def fn1(n):
- return C(n).getvalue()
+ return C(n).get_untagged_value()
res = interpret(fn1, [42], taggedpointers=True)
assert res == 42
From benjamin at codespeak.net Tue May 26 02:01:28 2009
From: benjamin at codespeak.net (benjamin at codespeak.net)
Date: Tue, 26 May 2009 02:01:28 +0200 (CEST)
Subject: [pypy-svn] r65416 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526000128.256A8169E9F@codespeak.net>
Author: benjamin
Date: Tue May 26 02:01:26 2009
New Revision: 65416
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
change optimize methods to return True to remove the operation
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 02:01:26 2009
@@ -119,12 +119,12 @@
self.additional_setarrayitems = {}
newoperations = []
for op in self.loop.operations:
- newop = op
+ remove_op = False
for opt in self.optimizations[op.opnum]:
- newop = opt(op, self)
- if newop is None:
+ remove_op = opt(op, self)
+ if remove_op:
break
- if newop is None:
+ if remove_op:
continue
if op.is_guard():
op = self.optimize_guard(op)
@@ -161,9 +161,9 @@
def optimize_guard_class(op, spec):
instnode = spec.getnode(op.args[0])
if instnode.cls is not None:
- return None
+ return True
instnode.cls = op.args[1]
- return op
+ return False
class SimpleVirtualizableOpt(object):
@staticmethod
@@ -171,61 +171,61 @@
instnode = spec.getnode(op.args[0])
instnode.virtualized = True
instnode.vdesc = op.vdesc
- return None
+ return True
@staticmethod
def optimize_getfield_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.virtualized:
- return op
+ return False
field = op.descr
if field not in instnode.vdesc.virtuals:
- return op
+ return False
node = instnode.cleanfields.get(field, None)
if node is not None:
spec.nodes[op.result] = node
- return None
+ return True
node = spec.getnode(op.result)
node.possibly_virtualized_list = True
instnode.cleanfields[field] = node
- return op
+ return False
@staticmethod
def optimize_setfield_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.virtualized:
- return op
+ return False
field = op.descr
if field not in instnode.vdesc.virtuals:
- return op
+ return False
node = spec.getnode(op.args[1])
instnode.cleanfields[field] = node
# we never set it here
d = spec.additional_stores.setdefault(instnode, {})
d[field] = node
- return None
+ return True
@staticmethod
def optimize_getarrayitem_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.possibly_virtualized_list:
- return op
+ return False
if not spec.getnode(op.args[1]).const:
raise VirtualizedListAccessedWithVariableArg()
field = spec.getnode(op.args[1]).source
node = instnode.cleanfields.get(field, None)
if node is not None:
spec.nodes[op.result] = node
- return None
+ return True
node = spec.getnode(op.result)
instnode.cleanfields[field] = node
- return op
+ return False
@staticmethod
def optimize_setarrayitem_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.possibly_virtualized_list:
- return op
+ return False
argnode = spec.getnode(op.args[1])
if not argnode.const:
raise VirtualizedListAccessedWithVariableArg()
@@ -234,7 +234,7 @@
instnode.cleanfields[field] = fieldnode
d = spec.additional_setarrayitems.setdefault(instnode, {})
d[field] = (fieldnode, op.descr)
- return None
+ return True
specializer = Specializer([SimpleVirtualizableOpt(),
ConsecutiveGuardClassRemoval()])
From fijal at codespeak.net Tue May 26 04:13:59 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 04:13:59 +0200 (CEST)
Subject: [pypy-svn] r65417 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090526021359.5CD9B169F10@codespeak.net>
Author: fijal
Date: Tue May 26 04:13:56 2009
New Revision: 65417
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
a test and a fix that not all guards can be constant folded away only
based on their args
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 04:13:56 2009
@@ -90,11 +90,12 @@
return newboxes
def optimize_guard(self, op):
- for arg in op.args:
- if not self.getnode(arg).const:
- break
- else:
- return None
+ if op.is_foldable_guard():
+ for arg in op.args:
+ if not self.getnode(arg).const:
+ break
+ else:
+ return None
assert len(op.suboperations) == 1
op_fail = op.suboperations[0]
op_fail.args = self.new_arguments(op_fail)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/resoperation.py Tue May 26 04:13:56 2009
@@ -64,6 +64,9 @@
def is_guard(self):
return rop._GUARD_FIRST <= self.opnum <= rop._GUARD_LAST
+ def is_foldable_guard(self):
+ return rop._GUARD_FOLDABLE_FIRST <= self.opnum <= rop._GUARD_FOLDABLE_LAST
+
def is_guard_exception(self):
return (self.opnum == rop.GUARD_EXCEPTION or
self.opnum == rop.GUARD_NO_EXCEPTION)
@@ -98,10 +101,12 @@
_FINAL_LAST = 3
_GUARD_FIRST = 8 # ----- start of guard operations -----
+ _GUARD_FOLDABLE_FIRST = 8
GUARD_TRUE = 8
GUARD_FALSE = 9
GUARD_VALUE = 10
GUARD_CLASS = 11
+ _GUARD_FOLDABLE_LAST = 11
GUARD_NONVIRTUALIZED = 12
GUARD_NO_EXCEPTION = 13
GUARD_EXCEPTION = 14
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Tue May 26 04:13:56 2009
@@ -199,6 +199,14 @@
expected = "[]"
self.assert_equal(self.optimize(pre_op, []), expected)
+ def test_don_t_fold_guard_no_exception(self):
+ pre_op = """
+ []
+ guard_no_exception()
+ fail()
+ """
+ self.assert_equal(self.optimize(pre_op, []), pre_op)
+
def test_virtualized_list_on_virtualizable(self):
pre_op = """
[p0]
From fijal at codespeak.net Tue May 26 05:29:08 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 05:29:08 +0200 (CEST)
Subject: [pypy-svn] r65418 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090526032908.D7DA3169F3A@codespeak.net>
Author: fijal
Date: Tue May 26 05:29:06 2009
New Revision: 65418
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
a passing test
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Tue May 26 05:29:06 2009
@@ -245,8 +245,6 @@
fail()
"""
pre_op = parse(pre_op, self.cpu, self.namespace)
- # cheat
- pre_op.operations[-2].result.value = 1
expected = """
[p0, i0]
p1 = getfield_gc(p0, descr=list_desc)
@@ -259,6 +257,34 @@
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
expected)
+ def test_virtualized_list_on_virtualizable_3(self):
+ pre_op = """
+ [p0, i0, i1]
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ p1 = getfield_gc(p0, descr=list_desc)
+ setarrayitem_gc(p1, 0, i0, descr=array_descr)
+ i2 = getarrayitem_gc(p1, 0)
+ setarrayitem_gc(p1, 0, i1, descr=array_descr)
+ i3 = getarrayitem_gc(p1, 0)
+ i4 = int_add(i2, i3)
+ i5 = int_is_true(i4)
+ guard_true(i5)
+ fail()
+ """
+ pre_op = parse(pre_op, self.cpu, self.namespace)
+ expected = """
+ [p0, i0, i1]
+ p1 = getfield_gc(p0, descr=list_desc)
+ i4 = int_add(i0, i1)
+ i5 = int_is_true(i4)
+ guard_true(i5)
+ setarrayitem_gc(p1, 0, i1, descr=array_descr)
+ fail()
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+ expected)
+
def test_remove_consecutive_guard_value_constfold(self):
py.test.skip("not yet")
n = BoxInt(0)
From fijal at codespeak.net Tue May 26 05:37:32 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 05:37:32 +0200 (CEST)
Subject: [pypy-svn] r65419 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526033732.011AB169F49@codespeak.net>
Author: fijal
Date: Tue May 26 05:37:32 2009
New Revision: 65419
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
Leave a comment what to do next
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 05:37:32 2009
@@ -2,7 +2,12 @@
""" Simplified optimize.py
"""
from pypy.jit.metainterp.resoperation import rop, ResOperation, opname
-from pypy.jit.metainterp.history import Const, Box
+from pypy.jit.metainterp.history import Const, Box, ConstInt
+
+# For anybody reading.
+# Next step is to fix this so cleanfields and dicts on specializer
+# (additional_*) would be r_dicts so they can consider
+# two different constants as the same.
class VirtualizedListAccessedWithVariableArg(Exception):
pass
@@ -110,7 +115,7 @@
for field, (fieldnode, descr) in d.iteritems():
box = fieldnode.source
op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
- [node.source, field, box], None, descr))
+ [node.source, field, box], None, descr))
op.suboperations.append(op_fail)
op.args = self.new_arguments(op)
return op
From cfbolz at codespeak.net Tue May 26 15:10:35 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 26 May 2009 15:10:35 +0200 (CEST)
Subject: [pypy-svn] r65420 -
pypy/branch/tagged-pointers-framework/pypy/lang/prolog/interpreter
Message-ID: <20090526131035.A81A9168569@codespeak.net>
Author: cfbolz
Date: Tue May 26 15:10:34 2009
New Revision: 65420
Modified:
pypy/branch/tagged-pointers-framework/pypy/lang/prolog/interpreter/term.py
Log:
make it possible to use tagged pointers in the prolog implementation.
Modified: pypy/branch/tagged-pointers-framework/pypy/lang/prolog/interpreter/term.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/lang/prolog/interpreter/term.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/lang/prolog/interpreter/term.py Tue May 26 15:10:34 2009
@@ -25,10 +25,6 @@
__slots__ = ()
_immutable_ = True
- def __init__(self):
- raise NotImplementedError("abstract base class")
- return self
-
def getvalue(self, heap):
return self
@@ -269,12 +265,11 @@
error.throw_type_error("evaluable", self.get_prolog_signature())
-class Number(NonVar):
+class Number(NonVar, UnboxedValue):
TAG = tag()
STANDARD_ORDER = 2
_immutable_ = True
- def __init__(self, num):
- self.num = num
+ __slots__ = ("num", )
@specialize.arg(3)
def basic_unify(self, other, heap, occurs_check=False):
From antocuni at codespeak.net Tue May 26 16:08:40 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 26 May 2009 16:08:40 +0200 (CEST)
Subject: [pypy-svn] r65421 -
pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template
Message-ID: <20090526140840.4CD21169E19@codespeak.net>
Author: antocuni
Date: Tue May 26 16:08:37 2009
New Revision: 65421
Modified:
pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/class_.py
Log:
skip this test, as it cannot really work after translation
Modified: pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/class_.py
==============================================================================
--- pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/class_.py (original)
+++ pypy/branch/pyjitpl5/pypy/translator/oosupport/test_template/class_.py Tue May 26 16:08:37 2009
@@ -64,5 +64,8 @@
return a.x + b.x
assert self.interpret(fn, [1, 2]) == 3
+ def test_cast_object_mix_null(self):
+ py.test.skip('cannot return ootype.NULL from translated functions')
+
class BaseTestSpecialcase(BaseTestRspecialcase):
pass
From cfbolz at codespeak.net Tue May 26 17:40:47 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 26 May 2009 17:40:47 +0200 (CEST)
Subject: [pypy-svn] r65422 - in
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem:
. test
Message-ID: <20090526154047.3C5BA169DFC@codespeak.net>
Author: cfbolz
Date: Tue May 26 17:40:45 2009
New Revision: 65422
Modified:
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py
Log:
waaaaaa, how could this ever have worked? type(x) where x=None but x could also
be a tagged pointer segfaulted so far.
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py Tue May 26 17:40:45 2009
@@ -1,7 +1,7 @@
from pypy.objspace.flow.model import Constant
from pypy.rpython.rclass import getclassrepr, getinstancerepr, get_type_repr
from pypy.rpython.lltypesystem import lltype
-from pypy.rpython.lltypesystem.rclass import InstanceRepr, CLASSTYPE
+from pypy.rpython.lltypesystem.rclass import InstanceRepr, CLASSTYPE, ll_inst_type
from pypy.rpython.lltypesystem.rclass import MissingRTypeAttribute
from pypy.rpython.lltypesystem.rclass import ll_issubclass_const
from pypy.rpython.rmodel import TyperError, inputconst
@@ -62,7 +62,7 @@
c_one = inputconst(lltype.Signed, 1)
return llops.genop('int_rshift', [v2, c_one], resulttype=lltype.Signed)
- def gettype_from_unboxed(self, llops, vinst):
+ def gettype_from_unboxed(self, llops, vinst, can_be_none=False):
unboxedclass_repr = getclassrepr(self.rtyper, self.unboxedclassdef)
cunboxedcls = inputconst(CLASSTYPE, unboxedclass_repr.getvtable())
if self.is_parent:
@@ -81,8 +81,12 @@
vinst = llops.genop('cast_pointer', [vinst],
resulttype=self.common_repr())
if can_be_tagged:
+ # XXX do we care about optimizing the case where vinst cannot
+ # be None here?
return llops.gendirectcall(ll_unboxed_getclass, vinst,
cunboxedcls)
+ elif can_be_none:
+ return llops.gendirectcall(ll_inst_type, vinst)
else:
ctypeptr = inputconst(lltype.Void, 'typeptr')
return llops.genop('getfield', [vinst, ctypeptr],
@@ -100,7 +104,8 @@
def rtype_type(self, hop):
[vinst] = hop.inputargs(self)
- return self.gettype_from_unboxed(hop.llops, vinst)
+ return self.gettype_from_unboxed(
+ hop.llops, vinst, can_be_none=hop.args_s[0].can_be_none())
def rtype_setattr(self, hop):
# only for UnboxedValue.__init__(), which is not actually called
@@ -144,8 +149,10 @@
def ll_unboxed_getclass(instance, class_if_unboxed):
if lltype.cast_ptr_to_int(instance) & 1:
return class_if_unboxed
- else:
+ elif instance:
return instance.typeptr
+ else:
+ return lltype.nullptr(lltype.typeOf(instance).TO.typeptr.TO)
def ll_unboxed_isinstance_const(obj, minid, maxid, answer_if_unboxed):
if not obj:
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/test/test_rtagged.py Tue May 26 17:40:45 2009
@@ -136,6 +136,27 @@
res = interpret(fn, [9874], taggedpointers=True)
assert res.item1 and not res.item0
+def test_type_of_None():
+ # use extra function to prevent flow graph cleverness
+ def g(n):
+ if n < 0:
+ x = B(n)
+ elif n == 0:
+ x = None
+ else:
+ x = C(n)
+ return x
+ def fn(n):
+ x= g(n)
+ return type(x) is B, type(x) is C
+
+ res = interpret(fn, [-212], taggedpointers=True)
+ assert res.item0 and not res.item1
+ res = interpret(fn, [9874], taggedpointers=True)
+ assert res.item1 and not res.item0
+ res = interpret(fn, [0], taggedpointers=True)
+ assert not res.item1 and not res.item0
+
def test_str():
def fn(n):
if n > 0:
From fijal at codespeak.net Tue May 26 17:47:56 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 17:47:56 +0200 (CEST)
Subject: [pypy-svn] r65423 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526154756.352BE169DFA@codespeak.net>
Author: fijal
Date: Tue May 26 17:47:55 2009
New Revision: 65423
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
Attempt to fix the issue with different constants with the same value.
Store different dicts for arrays and structs
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 17:47:55 2009
@@ -20,7 +20,7 @@
self.const = const
self.cls = None
self.cleanfields = {}
- self.dirtyfields = {}
+ self.arrayfields = {}
self.virtualized = False
self.possibly_virtualized_list = False
@@ -115,7 +115,7 @@
for field, (fieldnode, descr) in d.iteritems():
box = fieldnode.source
op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
- [node.source, field, box], None, descr))
+ [node.source, ConstInt(field), box], None, descr))
op.suboperations.append(op_fail)
op.args = self.new_arguments(op)
return op
@@ -218,13 +218,13 @@
return False
if not spec.getnode(op.args[1]).const:
raise VirtualizedListAccessedWithVariableArg()
- field = spec.getnode(op.args[1]).source
- node = instnode.cleanfields.get(field, None)
+ field = spec.getnode(op.args[1]).source.getint()
+ node = instnode.arrayfields.get(field, None)
if node is not None:
spec.nodes[op.result] = node
return True
node = spec.getnode(op.result)
- instnode.cleanfields[field] = node
+ instnode.arrayfields[field] = node
return False
@staticmethod
@@ -236,8 +236,8 @@
if not argnode.const:
raise VirtualizedListAccessedWithVariableArg()
fieldnode = spec.getnode(op.args[2])
- field = argnode.source
- instnode.cleanfields[field] = fieldnode
+ field = argnode.source.getint()
+ instnode.arrayfields[field] = fieldnode
d = spec.additional_setarrayitems.setdefault(instnode, {})
d[field] = (fieldnode, op.descr)
return True
From fijal at codespeak.net Tue May 26 18:52:21 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 18:52:21 +0200 (CEST)
Subject: [pypy-svn] r65424 -
pypy/branch/pyjitpl5-experiments/pypy/interpreter
Message-ID: <20090526165221.69A3116857F@codespeak.net>
Author: fijal
Date: Tue May 26 18:52:20 2009
New Revision: 65424
Modified:
pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py
Log:
promote valuestackdepth everywhere. if we don't we cannot perform optimizations
Modified: pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py Tue May 26 18:52:20 2009
@@ -131,14 +131,14 @@
def pushvalue(self, w_object):
depth = self.valuestackdepth
self.valuestack_w[depth] = w_object
- self.valuestackdepth = depth + 1
+ self.valuestackdepth = hint(depth + 1, promote=True)
def popvalue(self):
depth = self.valuestackdepth - 1
assert depth >= 0, "pop from empty value stack"
w_object = self.valuestack_w[depth]
self.valuestack_w[depth] = None
- self.valuestackdepth = depth
+ self.valuestackdepth = hint(depth, promote=True)
return w_object
def popstrdictvalues(self, n):
@@ -188,7 +188,7 @@
if n < 0:
break
self.valuestack_w[finaldepth+n] = None
- self.valuestackdepth = finaldepth
+ self.valuestackdepth = hint(finaldepth, promote=True)
def pushrevvalues(self, n, values_w): # n should be len(values_w)
while True:
@@ -221,7 +221,7 @@
while depth >= finaldepth:
self.valuestack_w[depth] = None
depth -= 1
- self.valuestackdepth = finaldepth
+ self.valuestackdepth = hint(finaldepth, promote=True)
def savevaluestack(self):
return self.valuestack_w[:self.valuestackdepth]
From antocuni at codespeak.net Tue May 26 20:06:46 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 26 May 2009 20:06:46 +0200 (CEST)
Subject: [pypy-svn] r65425 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526180646.CE819169E19@codespeak.net>
Author: antocuni
Date: Tue May 26 20:06:38 2009
New Revision: 65425
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py
Log:
make a better repr for static methods
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py Tue May 26 20:06:38 2009
@@ -48,6 +48,8 @@
try:
if box.value.obj._TYPE is ootype.String:
return '(%r)' % box.value.obj._str
+ if isinstance(box.value.obj._TYPE, ootype.StaticMethod):
+ return '(%r)' % box.value.obj
if isinstance(box.value.obj, ootype._view):
return repr(box.value.obj._inst._TYPE)
else:
From antocuni at codespeak.net Tue May 26 20:07:06 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 26 May 2009 20:07:06 +0200 (CEST)
Subject: [pypy-svn] r65426 - pypy/branch/pyjitpl5-experiments/pypy/jit/tl
Message-ID: <20090526180706.B0CB0169E25@codespeak.net>
Author: antocuni
Date: Tue May 26 20:07:05 2009
New Revision: 65426
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_child.py
Log:
use optimize2 by default
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_child.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_child.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_child.py Tue May 26 20:07:05 2009
@@ -2,7 +2,8 @@
from pypy.rpython.lltypesystem import lltype
from pypy.jit.metainterp import warmspot
#from pypy.jit.metainterp.simple_optimize import Optimizer
-from pypy.jit.metainterp import optimize as Optimizer
+#from pypy.jit.metainterp import optimize as Optimizer
+from pypy.jit.metainterp.optimize2 import Optimizer
from pypy.module.pypyjit.policy import PyPyJitPolicy
# Current output: http://paste.pocoo.org/show/106540/
From fijal at codespeak.net Tue May 26 20:16:20 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 20:16:20 +0200 (CEST)
Subject: [pypy-svn] r65427 - pypy/branch/pyjitpl5-experiments/pypy/jit/tl
Message-ID: <20090526181620.3862C169EC9@codespeak.net>
Author: fijal
Date: Tue May 26 20:16:17 2009
New Revision: 65427
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py
Log:
a currently exploding loop
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py Tue May 26 20:16:17 2009
@@ -13,10 +13,17 @@
i = i + step
print i
+def g(i):
+ for k in range(i, i +2):
+ pass
+
+def loop():
+ for i in range(10000):
+ g(i)
try:
#do()
- simple_loop()
+ loop()
print "---ending 2---"
except BaseException, e:
print "---ending 0---"
From fijal at codespeak.net Tue May 26 20:27:54 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 20:27:54 +0200 (CEST)
Subject: [pypy-svn] r65428 - pypy/branch/pyjitpl5-experiments/pypy/jit/tl
Message-ID: <20090526182754.6C257169E84@codespeak.net>
Author: fijal
Date: Tue May 26 20:27:52 2009
New Revision: 65428
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py
Log:
a test checkin
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py Tue May 26 20:27:52 2009
@@ -1,5 +1,6 @@
TESTNAME = 'test_builtin'
+
def do():
__import__('test.' + TESTNAME)
print "---ending 1---"
From fijal at codespeak.net Tue May 26 20:49:08 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 20:49:08 +0200 (CEST)
Subject: [pypy-svn] r65429 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090526184908.90C89169E83@codespeak.net>
Author: fijal
Date: Tue May 26 20:49:08 2009
New Revision: 65429
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
put some extra guards on a rebuild path. backend will kill them away anyway
and we can deduce what kind of operations those are. We have no way of passing
this kind of information some other way so far
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 20:49:08 2009
@@ -22,7 +22,7 @@
self.cleanfields = {}
self.arrayfields = {}
self.virtualized = False
- self.possibly_virtualized_list = False
+ self.vdesc = None
def __repr__(self):
flags = ''
@@ -109,11 +109,19 @@
op.suboperations = []
for node, d in self.additional_stores.iteritems():
for field, fieldnode in d.iteritems():
+ gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
+ [node.source], None)
+ gop.vdesc = node.vdesc
+ op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETFIELD_GC,
[node.source, fieldnode.source], None, field))
for node, d in self.additional_setarrayitems.iteritems():
for field, (fieldnode, descr) in d.iteritems():
box = fieldnode.source
+ gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
+ [node.source], None)
+ gop.vdesc = node.vdesc
+ op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
[node.source, ConstInt(field), box], None, descr))
op.suboperations.append(op_fail)
@@ -192,7 +200,7 @@
spec.nodes[op.result] = node
return True
node = spec.getnode(op.result)
- node.possibly_virtualized_list = True
+ node.virtualized = True
instnode.cleanfields[field] = node
return False
@@ -214,7 +222,7 @@
@staticmethod
def optimize_getarrayitem_gc(op, spec):
instnode = spec.getnode(op.args[0])
- if not instnode.possibly_virtualized_list:
+ if not instnode.virtualized:
return False
if not spec.getnode(op.args[1]).const:
raise VirtualizedListAccessedWithVariableArg()
@@ -230,7 +238,7 @@
@staticmethod
def optimize_setarrayitem_gc(op, spec):
instnode = spec.getnode(op.args[0])
- if not instnode.possibly_virtualized_list:
+ if not instnode.virtualized:
return False
argnode = spec.getnode(op.args[1])
if not argnode.const:
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Tue May 26 20:49:08 2009
@@ -184,6 +184,7 @@
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=other_field_desc)
guard_true(i2)
+ guard_nonvirtualized(p0)
setfield_gc(p0, i2, descr=field_desc)
fail()
"""
@@ -251,6 +252,7 @@
i2 = int_add(i0, i0)
i3 = int_is_true(i2)
guard_true(i3)
+ guard_nonvirtualized(p1)
setarrayitem_gc(p1, 0, i0, descr=array_descr)
fail()
"""
@@ -279,6 +281,7 @@
i4 = int_add(i0, i1)
i5 = int_is_true(i4)
guard_true(i5)
+ guard_nonvirtualized(p1)
setarrayitem_gc(p1, 0, i1, descr=array_descr)
fail()
"""
From fijal at codespeak.net Tue May 26 20:52:51 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 20:52:51 +0200 (CEST)
Subject: [pypy-svn] r65430 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526185251.F1F04169EB8@codespeak.net>
Author: fijal
Date: Tue May 26 20:52:51 2009
New Revision: 65430
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
append a dummy suboperations to that GUARD
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 20:52:51 2009
@@ -112,6 +112,7 @@
gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
[node.source], None)
gop.vdesc = node.vdesc
+ gop.suboperations = [ResOperation(rop.FAIL, [], None)]
op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETFIELD_GC,
[node.source, fieldnode.source], None, field))
@@ -120,6 +121,7 @@
box = fieldnode.source
gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
[node.source], None)
+ gop.suboperations = [ResOperation(rop.FAIL, [], None)]
gop.vdesc = node.vdesc
op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
From antocuni at codespeak.net Tue May 26 21:04:22 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 26 May 2009 21:04:22 +0200 (CEST)
Subject: [pypy-svn] r65431 - in pypy/branch/pyjitpl5-experiments/pypy:
config jit/backend/cli jit/backend/cli/test jit/backend/test
jit/metainterp/test rpython/ootypesystem translator/cli
translator/cli/src translator/oosupport/test_template
Message-ID: <20090526190422.951331684BF@codespeak.net>
Author: antocuni
Date: Tue May 26 21:04:20 2009
New Revision: 65431
Added:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_loop.py
- copied unchanged from r65430, pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_loop.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_vlist.py
- copied unchanged from r65430, pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_vlist.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_loop.py
- copied unchanged from r65430, pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_loop.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py
- copied unchanged from r65430, pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_virtualizable.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_vlist.py
- copied unchanged from r65430, pypy/branch/pyjitpl5/pypy/jit/backend/cli/test/test_zrpy_vlist.py
Modified:
pypy/branch/pyjitpl5-experiments/pypy/config/translationoption.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/methodfactory.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_basic.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_exception.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_send.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/support.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_tl.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py
pypy/branch/pyjitpl5-experiments/pypy/rpython/ootypesystem/rpbc.py
pypy/branch/pyjitpl5-experiments/pypy/translator/cli/opcodes.py
pypy/branch/pyjitpl5-experiments/pypy/translator/cli/src/pypylib.cs
pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/test_template/class_.py
Log:
merge changes from pyjitpl5 to pyjitpl5-experiments
svn merge svn+ssh://codespeak.net/svn/pypy/branch/pyjitpl5/pypy -r65302:HEAD
------------------------------------------------------------------------
r65304 | antocuni | 2009-05-19 10:31:13 +0200 (Tue, 19 May 2009) | 5 lines
don't print stuff on stdout, as it breaks the minimal and cli backends
(because the spawn an external process and read the result as printed on
stdout)
------------------------------------------------------------------------
r65314 | antocuni | 2009-05-19 17:28:40 +0200 (Tue, 19 May 2009) | 7 lines
implement bridges; so far the implementation is very simple, just a tailcall
to the method containing the next loop; hopefully, the speed penalty
associated to the tail call is not too heavy, because we don't expect bridges
to be so frequent (thanks cfbolz for the idea). In the future, we might think
of other techniques to avoid tail calls.
------------------------------------------------------------------------
r65331 | antocuni | 2009-05-20 16:21:28 +0200 (Wed, 20 May 2009) | 10 lines
the code to implement bridges was broken, fix it:
- don't put a 'ret' in emit_store_opargs, else the jump is never taken
- put the array of failing ops on the cpu, not on the method, else the
"failed_op" index stored in inputargs is meaningless
- add a bunch of debugging stuff
------------------------------------------------------------------------
r65335 | antocuni | 2009-05-20 18:19:29 +0200 (Wed, 20 May 2009) | 3 lines
update test status: two more tests pass, one fails only on mono but not on windows, another is not a translation test
------------------------------------------------------------------------
r65336 | antocuni | 2009-05-20 18:32:07 +0200 (Wed, 20 May 2009) | 3 lines
good, all these tests pass now
------------------------------------------------------------------------
r65337 | antocuni | 2009-05-20 18:36:30 +0200 (Wed, 20 May 2009) | 4 lines
more passing tests. test_int_lshift_ovf still fails because of a
NotImplementedError (will investigate later)
------------------------------------------------------------------------
r65338 | antocuni | 2009-05-20 18:42:01 +0200 (Wed, 20 May 2009) | 2 lines
implement set_overflow_error to make test_int_lshift_ovf passing
------------------------------------------------------------------------
r65339 | antocuni | 2009-05-20 18:51:57 +0200 (Wed, 20 May 2009) | 2 lines
be explicit on which operation we don't expect in the cli backend. Only few "real" operations are left now
------------------------------------------------------------------------
r65341 | antocuni | 2009-05-21 10:06:38 +0200 (Thu, 21 May 2009) | 3 lines
add new tests (to be run directly through Python for .NET); most of them pass, a bunch can be run only after translation, only one seems to be related to a real failure
------------------------------------------------------------------------
r65342 | antocuni | 2009-05-21 10:09:51 +0200 (Thu, 21 May 2009) | 2 lines
I was wrong, this test also has no chances to pass without translation
------------------------------------------------------------------------
r65343 | antocuni | 2009-05-21 10:19:59 +0200 (Thu, 21 May 2009) | 2 lines
more tests, most of them pass :-)
------------------------------------------------------------------------
r65344 | antocuni | 2009-05-21 11:46:23 +0200 (Thu, 21 May 2009) | 7 lines
- add a new test to test_loop to test string operations
- fix oosends to String and Unicode objects
- test_loop_{string,unicode} pass
------------------------------------------------------------------------
r65345 | antocuni | 2009-05-21 12:39:34 +0200 (Thu, 21 May 2009) | 2 lines
port more tests, implement do_oonewarray; test_simple_array passes
------------------------------------------------------------------------
r65346 | antocuni | 2009-05-21 13:55:06 +0200 (Thu, 21 May 2009) | 3 lines
implement emit_op_new_arry, but comment it out as it cannot be tested without translation.
------------------------------------------------------------------------
r65347 | antocuni | 2009-05-21 14:05:47 +0200 (Thu, 21 May 2009) | 2 lines
implement emit_op_new_arry to make almost all these tests passing
------------------------------------------------------------------------
r65348 | antocuni | 2009-05-21 14:12:41 +0200 (Thu, 21 May 2009) | 4 lines
delay the call to get_concrete_calltable, so that the low level types of the
methods arguments have been fully computed, much like r65288. test_ll_fixed_setitem_fast passes
------------------------------------------------------------------------
r65349 | antocuni | 2009-05-21 14:31:03 +0200 (Thu, 21 May 2009) | 2 lines
port more tests, ignore 'promote_virtualizable' in the normal cli backend.
------------------------------------------------------------------------
r65350 | antocuni | 2009-05-21 14:50:55 +0200 (Thu, 21 May 2009) | 5 lines
implement emit_op_instanceof, and all the remaining virtualizable tests pass.
Moreover, add stubs for all the few still missing operations, so that we can
kill the warning and put an assert instead
------------------------------------------------------------------------
r65351 | antocuni | 2009-05-21 21:51:06 +0200 (Thu, 21 May 2009) | 2 lines
use "boehm" as a dummy value, else it conflicts with tl/pypyjit.py
------------------------------------------------------------------------
r65352 | antocuni | 2009-05-22 00:47:33 +0200 (Fri, 22 May 2009) | 3 lines
implement sort_key() for all CLI descrs
------------------------------------------------------------------------
r65358 | antocuni | 2009-05-22 13:56:38 +0200 (Fri, 22 May 2009) | 2 lines
these two tests pass also on ootype nowadays
------------------------------------------------------------------------
r65421 | antocuni | 2009-05-26 16:08:37 +0200 (Tue, 26 May 2009) | 2 lines
skip this test, as it cannot really work after translation
------------------------------------------------------------------------
Modified: pypy/branch/pyjitpl5-experiments/pypy/config/translationoption.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/config/translationoption.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/config/translationoption.py Tue May 26 21:04:20 2009
@@ -30,7 +30,7 @@
("translation.backendopt.heap2stack", False),
("translation.backendopt.clever_malloc_removal", False),
("translation.list_comprehension_operations", False),
- ("translation.gc", "generation"), # it's not really used, but some jit code expects a value here
+ ("translation.gc", "boehm"), # it's not really used, but some jit code expects a value here
]
}),
ChoiceOption("backend", "Backend to use for code generation",
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py Tue May 26 21:04:20 2009
@@ -14,6 +14,7 @@
System = CLR.System
OpCodes = System.Reflection.Emit.OpCodes
LoopDelegate = CLR.pypy.runtime.LoopDelegate
+DelegateHolder = CLR.pypy.runtime.DelegateHolder
InputArgs = CLR.pypy.runtime.InputArgs
cVoid = ootype.nullruntimeclass
@@ -51,12 +52,40 @@
def store(self, meth):
assert False, 'cannot store() to Constant'
+ def get_cliobj(self):
+ return dotnet.cast_to_native_object(self.getobj())
+
class __extend__(ConstInt):
__metaclass__ = extendabletype
def load(self, meth):
meth.il.Emit(OpCodes.Ldc_I4, self.value)
+
+class ConstFunction(Const):
+
+ def __init__(self, name):
+ self.name = name
+ self.holder = DelegateHolder()
+
+ def get_cliobj(self):
+ return dotnet.cliupcast(self.holder, System.Object)
+
+ def load(self, meth):
+ holdertype = self.holder.GetType()
+ funcfield = holdertype.GetField('func')
+ Const.load(self, meth)
+ meth.il.Emit(OpCodes.Castclass, holdertype)
+ meth.il.Emit(OpCodes.Ldfld, funcfield)
+ meth.il.Emit(OpCodes.Castclass, dotnet.typeof(LoopDelegate))
+
+ def _getrepr_(self):
+ return '' % self.name
+
+ def __hash__(self):
+ return hash(self.holder)
+
+
class MethodArgument(AbstractValue):
def __init__(self, index, cliType):
self.index = index
@@ -87,6 +116,7 @@
class Method(object):
operations = [] # overwritten at the end of the module
+ tailcall = True
debug = False
def __init__(self, cpu, name, loop):
@@ -94,7 +124,6 @@
self.name = name
self.loop = loop
self.boxes = {} # box --> local var
- self.failing_ops = [] # index --> op
self.branches = []
self.branchlabels = []
self.consts = {} # object --> index
@@ -124,10 +153,12 @@
# initialize the array of genconsts
consts = dotnet.new_array(System.Object, len(self.consts))
for av_const, i in self.consts.iteritems():
- consts[i] = dotnet.cast_to_native_object(av_const.getobj())
+ #consts[i] = dotnet.cast_to_native_object(av_const.getobj())
+ consts[i] = av_const.get_cliobj()
# build the delegate
func = self.meth_wrapper.create_delegate(delegatetype, consts)
- self.func = dotnet.clidowncast(func, LoopDelegate)
+ func = dotnet.clidowncast(func, LoopDelegate)
+ self.loop._cli_funcbox.holder.SetFunc(func)
def _get_meth_wrapper(self):
restype = dotnet.class2type(cVoid)
@@ -151,10 +182,10 @@
def get_index_for_failing_op(self, op):
try:
- return self.failing_ops.index(op)
+ return self.cpu.failing_ops.index(op)
except ValueError:
- self.failing_ops.append(op)
- return len(self.failing_ops)-1
+ self.cpu.failing_ops.append(op)
+ return len(self.cpu.failing_ops)-1
def get_index_for_constant(self, obj):
try:
@@ -199,6 +230,7 @@
self.il.Emit(OpCodes.Stelem, clitype)
def emit_load_inputargs(self):
+ self.emit_debug("executing: " + self.name)
i = 0
for box in self.loop.inputargs:
self.load_inputarg(i, box.type, box.getCliType())
@@ -211,8 +243,7 @@
def emit_operations(self, operations):
for op in operations:
- if self.debug:
- self.il.EmitWriteLine(op.repr())
+ self.emit_debug(op.repr())
func = self.operations[op.opnum]
assert func is not None
func(self, op)
@@ -246,6 +277,10 @@
def store_result(self, op):
op.result.store(self)
+ def emit_debug(self, msg):
+ if self.debug:
+ self.il.EmitWriteLine(msg)
+
def emit_clear_exception(self):
self.av_inputargs.load(self)
self.il.Emit(OpCodes.Ldnull)
@@ -282,12 +317,15 @@
self.il.Emit(OpCodes.Ldc_I4, index_op)
field = dotnet.typeof(InputArgs).GetField('failed_op')
self.il.Emit(OpCodes.Stfld, field)
- # store the lates values
+ self.emit_store_opargs(op)
+ self.il.Emit(OpCodes.Ret)
+
+ def emit_store_opargs(self, op):
+ # store the latest values
i = 0
for box in op.args:
self.store_inputarg(i, box.type, box.getCliType(), box)
i+=1
- self.il.Emit(OpCodes.Ret)
def emit_guard_bool(self, op, opcode):
assert op.suboperations
@@ -344,13 +382,24 @@
def emit_op_jump(self, op):
target = op.jump_target
- assert target is self.loop, 'TODO'
assert len(op.args) == len(target.inputargs)
- i = 0
- for i in range(len(op.args)):
- op.args[i].load(self)
- target.inputargs[i].store(self)
- self.il.Emit(OpCodes.Br, self.il_loop_start)
+ if target is self.loop:
+ i = 0
+ for i in range(len(op.args)):
+ op.args[i].load(self)
+ target.inputargs[i].store(self)
+ self.il.Emit(OpCodes.Br, self.il_loop_start)
+ else:
+ # it's a real bridge
+ self.emit_debug('jumping to ' + target.name)
+ self.emit_store_opargs(op)
+ target._cli_funcbox.load(self)
+ self.av_inputargs.load(self)
+ methinfo = dotnet.typeof(LoopDelegate).GetMethod('Invoke')
+ if self.tailcall:
+ self.il.Emit(OpCodes.Tailcall)
+ self.il.Emit(OpCodes.Callvirt, methinfo)
+ self.il.Emit(OpCodes.Ret)
def emit_op_new_with_vtable(self, op):
assert isinstance(op.args[0], ConstObj) # ignored, using the descr instead
@@ -361,6 +410,19 @@
self.il.Emit(OpCodes.Newobj, ctor_info)
self.store_result(op)
+ def emit_op_runtimenew(self, op):
+ raise NotImplementedError
+
+ def emit_op_instanceof(self, op):
+ descr = op.descr
+ assert isinstance(descr, runner.TypeDescr)
+ clitype = descr.get_clitype()
+ op.args[0].load(self)
+ self.il.Emit(OpCodes.Isinst, clitype)
+ self.il.Emit(OpCodes.Ldnull)
+ self.il.Emit(OpCodes.Cgt_Un)
+ self.store_result(op)
+
def emit_op_ooidentityhash(self, op):
raise NotImplementedError
@@ -369,7 +431,8 @@
assert isinstance(descr, runner.StaticMethDescr)
delegate_type = descr.get_delegate_clitype()
meth_invoke = descr.get_meth_info()
- self._emit_call(op, delegate_type, meth_invoke, descr.has_result)
+ self._emit_call(op, OpCodes.Callvirt, delegate_type,
+ meth_invoke, descr.has_result)
def emit_op_call(self, op):
emit_op = Method.emit_op_call_impl.im_func
@@ -383,17 +446,18 @@
assert isinstance(descr, runner.MethDescr)
clitype = descr.get_self_clitype()
methinfo = descr.get_meth_info()
- self._emit_call(op, clitype, methinfo, descr.has_result)
+ opcode = descr.get_call_opcode()
+ self._emit_call(op, opcode, clitype, methinfo, descr.has_result)
emit_op_oosend_pure = emit_op_oosend
- def _emit_call(self, op, clitype, methinfo, has_result):
+ def _emit_call(self, op, opcode, clitype, methinfo, has_result):
av_sm, args_av = op.args[0], op.args[1:]
av_sm.load(self)
self.il.Emit(OpCodes.Castclass, clitype)
for av_arg in args_av:
av_arg.load(self)
- self.il.Emit(OpCodes.Callvirt, methinfo)
+ self.il.Emit(opcode, methinfo)
if has_result:
self.store_result(op)
@@ -451,25 +515,36 @@
self.il.Emit(OpCodes.Castclass, clitype)
self.il.Emit(OpCodes.Ldlen)
self.store_result(op)
-
- def not_implemented(self, op):
+
+ def emit_op_new_array(self, op):
+ descr = op.descr
+ assert isinstance(descr, runner.TypeDescr)
+ item_clitype = descr.get_clitype()
+ op.args[0].load(self)
+ self.il.Emit(OpCodes.Newarr, item_clitype)
+ self.store_result(op)
+
+ def emit_op_guard_nonvirtualized(self, op):
+ raise NotImplementedError
+
+ def lltype_only(self, op):
+ print 'Operation %s is lltype specific, should not get here!' % op.getopname()
raise NotImplementedError
- emit_op_cast_int_to_ptr = not_implemented
- emit_op_guard_nonvirtualized = not_implemented
- emit_op_unicodelen = not_implemented
- emit_op_setfield_raw = not_implemented
- emit_op_cast_ptr_to_int = not_implemented
- emit_op_newunicode = not_implemented
- emit_op_new_array = not_implemented
- emit_op_unicodegetitem = not_implemented
- emit_op_strgetitem = not_implemented
- emit_op_getfield_raw = not_implemented
- emit_op_unicodesetitem = not_implemented
- emit_op_getfield_raw_pure = not_implemented
- emit_op_strlen = not_implemented
- emit_op_newstr = not_implemented
- emit_op_strsetitem = not_implemented
+ emit_op_new = lltype_only
+ emit_op_setfield_raw = lltype_only
+ emit_op_getfield_raw = lltype_only
+ emit_op_getfield_raw_pure = lltype_only
+ emit_op_strsetitem = lltype_only
+ emit_op_unicodesetitem = lltype_only
+ emit_op_cast_int_to_ptr = lltype_only
+ emit_op_cast_ptr_to_int = lltype_only
+ emit_op_newstr = lltype_only
+ emit_op_strlen = lltype_only
+ emit_op_strgetitem = lltype_only
+ emit_op_newunicode = lltype_only
+ emit_op_unicodelen = lltype_only
+ emit_op_unicodegetitem = lltype_only
# --------------------------------------------------------------------
@@ -507,10 +582,7 @@
elif isinstance(instr, opcodes.PushArg):
lines.append('self.push_arg(op, %d)' % instr.n)
else:
- if not isinstance(instr, str):
- print 'WARNING: unknown instruction %s' % instr
- return
-
+ assert isinstance(instr, str), 'unknown instruction %s' % instr
if instr.startswith('call '):
signature = instr[len('call '):]
renderCall(lines, signature)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/methodfactory.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/methodfactory.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/methodfactory.py Tue May 26 21:04:20 2009
@@ -71,7 +71,7 @@
def create_delegate(self, delegatetype, consts):
t = self.typeBuilder.CreateType()
methinfo = t.GetMethod("invoke")
-## if self.name == 'generated_case_1':
+## if self.name == 'Loop #0(r1)_2':
## assemblyData.auto_save_assembly.Save()
return System.Delegate.CreateDelegate(delegatetype,
consts,
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py Tue May 26 21:04:20 2009
@@ -1,6 +1,9 @@
+from pypy.tool.pairtype import extendabletype
from pypy.rpython.ootypesystem import ootype
+from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp.history import AbstractDescr, AbstractMethDescr
-from pypy.jit.metainterp.history import Box, BoxInt, BoxObj
+from pypy.jit.metainterp.history import Box, BoxInt, BoxObj, ConstObj, Const
+from pypy.jit.metainterp.history import TreeLoop
from pypy.jit.metainterp import executor
from pypy.jit.metainterp.resoperation import rop, opname
from pypy.jit.backend import model
@@ -10,7 +13,19 @@
from pypy.translator.cli.dotnet import CLR
System = CLR.System
+OpCodes = System.Reflection.Emit.OpCodes
InputArgs = CLR.pypy.runtime.InputArgs
+cpypyString = dotnet.classof(CLR.pypy.runtime.String)
+
+class __extend__(TreeLoop):
+ __metaclass__ = extendabletype
+
+ _cli_funcbox = None
+ _cli_meth = None
+ _cli_count = 0
+
+ def _get_cli_name(self):
+ return '%s(r%d)' % (self.name, self._cli_count)
class CliCPU(model.AbstractCPU):
@@ -25,6 +40,7 @@
self.stats = stats
self.translate_support_code = translate_support_code
self.inputargs = None
+ self.failing_ops = [] # index --> op
self.ll_ovf_exc = self._get_prebuilt_exc(OverflowError)
self.ll_zero_exc = self._get_prebuilt_exc(ZeroDivisionError)
@@ -48,6 +64,8 @@
@cached_method('_methcache')
def methdescrof(self, SELFTYPE, methname):
+ if SELFTYPE in (ootype.String, ootype.Unicode):
+ return StringMethDescr(SELFTYPE, methname)
return MethDescr(SELFTYPE, methname)
@cached_method('_typecache')
@@ -67,14 +85,19 @@
# ----------------------
def compile_operations(self, loop):
- from pypy.jit.backend.cli.method import Method
- meth = Method(self, loop.name, loop)
- loop._cli_meth = meth
+ from pypy.jit.backend.cli.method import Method, ConstFunction
+ if loop._cli_funcbox is None:
+ loop._cli_funcbox = ConstFunction(loop.name)
+ else:
+ # discard previously compiled loop
+ loop._cli_funcbox.holder.SetFunc(None)
+ loop._cli_meth = Method(self, loop._get_cli_name(), loop)
+ loop._cli_count += 1
def execute_operations(self, loop):
- meth = loop._cli_meth
- meth.func(self.get_inputargs())
- return meth.failing_ops[self.inputargs.get_failed_op()]
+ func = loop._cli_funcbox.holder.GetFunc()
+ func(self.get_inputargs())
+ return self.failing_ops[self.inputargs.get_failed_op()]
def set_future_value_int(self, index, intvalue):
self.get_inputargs().set_int(index, intvalue)
@@ -110,10 +133,14 @@
self.get_inputargs().set_exc_value(None)
def set_overflow_error(self):
- raise NotImplementedError
+ exc_obj = ootype.cast_to_object(self.ll_ovf_exc)
+ exc_value = dotnet.cast_to_native_object(exc_obj)
+ self.get_inputargs().set_exc_value(exc_value)
def set_zero_division_error(self):
- raise NotImplementedError
+ exc_obj = ootype.cast_to_object(self.ll_zero_exc)
+ exc_value = dotnet.cast_to_native_object(exc_obj)
+ self.get_inputargs().set_exc_value(exc_value)
# ----------------------
@@ -122,6 +149,11 @@
assert len(args) == 1 # but we don't need it, so ignore
return typedescr.create()
+ def do_new_array(self, args, typedescr):
+ assert isinstance(typedescr, TypeDescr)
+ assert len(args) == 1
+ return typedescr.create_array(args[0])
+
def do_runtimenew(self, args, descr):
classbox = args[0]
classobj = ootype.cast_from_object(ootype.Class, classbox.getobj())
@@ -188,6 +220,16 @@
# ----------------------------------------------------------------------
key_manager = KeyManager()
+class DescrWithKey(AbstractDescr):
+ key = -1
+
+ def __init__(self, key):
+ self.key = key_manager.getkey(key)
+
+ def sort_key(self):
+ return self.key
+
+
def get_class_for_type(T):
if T is ootype.Void:
return ootype.nullruntimeclass
@@ -206,10 +248,10 @@
else:
assert False
-
-class TypeDescr(AbstractDescr):
+class TypeDescr(DescrWithKey):
def __init__(self, TYPE):
+ DescrWithKey.__init__(self, TYPE)
from pypy.jit.backend.llgraph.runner import boxresult
from pypy.jit.metainterp.warmspot import unwrap
ARRAY = ootype.Array(TYPE)
@@ -245,25 +287,25 @@
self.getarraylength = getarraylength
self.instanceof = instanceof
self.ooclass = get_class_for_type(TYPE)
- self.ooarrayclass = get_class_for_type(ARRAY)
def get_clitype(self):
return dotnet.class2type(self.ooclass)
def get_array_clitype(self):
- return dotnet.class2type(self.ooarrayclass)
+ return self.get_clitype().MakeArrayType()
def get_constructor_info(self):
clitype = self.get_clitype()
return clitype.GetConstructor(dotnet.new_array(System.Type, 0))
-class StaticMethDescr(AbstractDescr):
+class StaticMethDescr(DescrWithKey):
callfunc = None
funcclass = ootype.nullruntimeclass
has_result = False
def __init__(self, FUNC, ARGS, RESULT):
+ DescrWithKey.__init__(self, (FUNC, ARGS, RESULT))
from pypy.jit.backend.llgraph.runner import boxresult, make_getargs
getargs = make_getargs(FUNC.ARGS)
def callfunc(funcbox, argboxes):
@@ -300,6 +342,7 @@
selfclass = ootype.nullruntimeclass
methname = ''
has_result = False
+ key = -1
def __init__(self, SELFTYPE, methname):
from pypy.jit.backend.llgraph.runner import boxresult, make_getargs
@@ -317,6 +360,10 @@
self.selfclass = ootype.runtimeClass(SELFTYPE)
self.methname = methname
self.has_result = (METH.RESULT != ootype.Void)
+ self.key = key_manager.getkey((SELFTYPE, methname))
+
+ def sort_key(self):
+ return self.key
def get_self_clitype(self):
return dotnet.class2type(self.selfclass)
@@ -325,16 +372,29 @@
clitype = self.get_self_clitype()
return clitype.GetMethod(self.methname+'')
+ def get_call_opcode(self):
+ return OpCodes.Callvirt
-class FieldDescr(AbstractDescr):
+
+class StringMethDescr(MethDescr):
+
+ def get_meth_info(self):
+ clitype = dotnet.class2type(cpypyString)
+ return clitype.GetMethod(self.methname+'')
+
+ def get_call_opcode(self):
+ return OpCodes.Call
+
+
+class FieldDescr(DescrWithKey):
getfield = None
setfield = None
selfclass = ootype.nullruntimeclass
fieldname = ''
- key = -1
def __init__(self, TYPE, fieldname):
+ DescrWithKey.__init__(self, (TYPE, fieldname))
from pypy.jit.backend.llgraph.runner import boxresult
from pypy.jit.metainterp.warmspot import unwrap
_, T = TYPE._lookup_field(fieldname)
@@ -353,9 +413,6 @@
self.fieldname = fieldname
self.key = key_manager.getkey((TYPE, fieldname))
- def sort_key(self):
- return self.key
-
def equals(self, other):
assert isinstance(other, FieldDescr)
return self.key == other.key
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py Tue May 26 21:04:20 2009
@@ -37,7 +37,4 @@
test_oostring_instance = skip
test_long_long = skip
test_free_object = skip
-
- test_stopatxpolicy = _skip
- test_bridge_from_interpreter = _skip
- test_bridge_from_interpreter_4 = _skip
+ test_stopatxpolicy = skip
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_basic.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_basic.py Tue May 26 21:04:20 2009
@@ -16,17 +16,21 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_basic.py
+ def mono_bug(self):
+ py.test.skip('mono bug?')
+
def skip(self):
py.test.skip('in-progress')
- test_stopatxpolicy = skip
+ test_stopatxpolicy = mono_bug
+
test_print = skip
test_bridge_from_interpreter = skip
test_bridge_from_interpreter_2 = skip
- test_bridge_from_interpreter_3 = skip
- test_bridge_from_interpreter_4 = skip
- test_bridge_leaving_interpreter_5 = skip
test_free_object = skip
+ def test_bridge_from_interpreter_4(self):
+ pass # not a translation test
+
def test_we_are_jitted(self):
py.test.skip("it seems to fail even with the x86 backend, didn't investigate the problem")
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_exception.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_exception.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_exception.py Tue May 26 21:04:20 2009
@@ -7,17 +7,5 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_exception.py
- def skip_loop(self):
- py.test.skip('jump across loops not implemented yet')
-
- def skip(self):
- py.test.skip('in-progress')
-
- test_bridge_from_guard_exception = skip_loop
- test_exception_four_cases = skip_loop
- test_bridge_from_interpreter_exc = skip_loop
- test_bridge_from_interpreter_exc_2 = skip_loop
- test_int_lshift_ovf = skip_loop
-
-
+ pass
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_send.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_send.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_zrpy_send.py Tue May 26 21:04:20 2009
@@ -7,12 +7,6 @@
# for the individual tests see
# ====> ../../../metainterp/test/test_send.py
- def skip_loop(self):
- py.test.skip('jump across loops not implemented yet')
-
- test_three_receivers = skip_loop
- test_three_classes = skip_loop
- test_recursive_call_to_portal_from_blackhole = skip_loop
- test_indirect_call_unknown_object_1 = skip_loop
- test_three_cases = skip_loop
+ def test_recursive_call_to_portal_from_blackhole(self):
+ py.test.skip('string return values are not supported')
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/support.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/support.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/support.py Tue May 26 21:04:20 2009
@@ -104,3 +104,9 @@
from pypy.translator.cli.test.runtest import compile_graph
func = compile_graph(entry_point_graph, t, nowrap=True, standalone=True)
return func(*args)
+
+ def run_directly(self, fn, args):
+ from pypy.translator.cli.test.runtest import compile_function, get_annotation
+ ann = [get_annotation(x) for x in args]
+ clifunc = compile_function(fn, ann)
+ return clifunc(*args)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_loop.py Tue May 26 21:04:20 2009
@@ -16,6 +16,9 @@
CPUClass=self.CPUClass,
type_system=self.type_system)
+ def run_directly(self, f, args):
+ return f(*args)
+
def test_simple_loop(self):
myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
def f(x, y):
@@ -348,7 +351,21 @@
x += unichr(n)
n -= 1
return hash(x)
- expected = f(100)
+ expected = self.run_directly(f, [100])
+ res = self.meta_interp(f, [100])
+ assert res == expected
+
+ def test_loop_string(self):
+ myjitdriver = JitDriver(greens = [], reds = ['x', 'n'])
+ def f(n):
+ x = ''
+ while n > 13:
+ myjitdriver.can_enter_jit(n=n, x=x)
+ myjitdriver.jit_merge_point(n=n, x=x)
+ x += chr(n)
+ n -= 1
+ return hash(x)
+ expected = self.run_directly(f, [100])
res = self.meta_interp(f, [100])
assert res == expected
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_tl.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_tl.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_tl.py Tue May 26 21:04:20 2009
@@ -95,8 +95,6 @@
def test_tl_base(self):
res = self.meta_interp(self.main.im_func, [0, 6], listops=True)
assert res == 5040
- if self.type_system == 'ootype':
- py.test.skip('optimizing problem')
self.check_loops({'int_mul':1, 'jump':1,
'int_sub':1, 'int_is_true':1, 'int_le':1,
'guard_false':1, 'guard_value':1})
@@ -104,8 +102,6 @@
def test_tl_2(self):
res = self.meta_interp(self.main.im_func, [1, 10], listops=True)
assert res == self.main.im_func(1, 10)
- if self.type_system == 'ootype':
- py.test.skip('optimizing problem')
self.check_loops({'int_sub':1, 'int_le':1,
'int_is_true':1, 'guard_false':1, 'jump':1,
'guard_value':1})
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py Tue May 26 21:04:20 2009
@@ -617,3 +617,11 @@
ImplicitVirtualizableTests,
LLJitMixin):
pass
+
+
+class TestOptimize2(ImplicitVirtualizableTests, LLJitMixin):
+
+ def meta_interp(self, *args, **kwds):
+ from pypy.jit.metainterp.optimize2 import Optimizer
+ kwds['optimizer'] = Optimizer
+ return LLJitMixin.meta_interp(self, *args, **kwds)
Modified: pypy/branch/pyjitpl5-experiments/pypy/rpython/ootypesystem/rpbc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/rpython/ootypesystem/rpbc.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/rpython/ootypesystem/rpbc.py Tue May 26 21:04:20 2009
@@ -116,10 +116,11 @@
class MethodsPBCRepr(AbstractMethodsPBCRepr):
- def __init__(self, rtyper, s_pbc):
- AbstractMethodsPBCRepr.__init__(self, rtyper, s_pbc)
- sampledesc = s_pbc.descriptions.iterkeys().next()
- self.concretetable, _ = get_concrete_calltable(rtyper,
+ concretetable = None # set by _setup_repr_final
+
+ def _setup_repr_final(self):
+ sampledesc = self.s_pbc.descriptions.iterkeys().next()
+ self.concretetable, _ = get_concrete_calltable(self.rtyper,
sampledesc.funcdesc.getcallfamily())
def rtype_simple_call(self, hop):
Modified: pypy/branch/pyjitpl5-experiments/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/translator/cli/opcodes.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/translator/cli/opcodes.py Tue May 26 21:04:20 2009
@@ -80,6 +80,7 @@
'keepalive': Ignore,
'is_early_constant': [PushPrimitive(ootype.Bool, False)],
'jit_marker': Ignore,
+ 'promote_virtualizable': Ignore,
}
# __________ numeric operations __________
Modified: pypy/branch/pyjitpl5-experiments/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/translator/cli/src/pypylib.cs (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/translator/cli/src/pypylib.cs Tue May 26 21:04:20 2009
@@ -291,24 +291,25 @@
return default_blockid;
}
}
+ */
public class DelegateHolder
{
- public Delegate func;
+ public LoopDelegate func;
// we need getter and setter because we can't directly access fields from RPython
- public void SetFunc(Delegate func)
+ public void SetFunc(LoopDelegate func)
{
this.func = func;
}
- public Delegate GetFunc()
+ public LoopDelegate GetFunc()
{
return this.func;
}
}
- */
+
public class AutoSaveAssembly
{
Modified: pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/test_template/class_.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/test_template/class_.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/test_template/class_.py Tue May 26 21:04:20 2009
@@ -64,5 +64,8 @@
return a.x + b.x
assert self.interpret(fn, [1, 2]) == 3
+ def test_cast_object_mix_null(self):
+ py.test.skip('cannot return ootype.NULL from translated functions')
+
class BaseTestSpecialcase(BaseTestRspecialcase):
pass
From fijal at codespeak.net Tue May 26 21:10:06 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:10:06 +0200 (CEST)
Subject: [pypy-svn] r65432 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090526191006.411FF1684BF@codespeak.net>
Author: fijal
Date: Tue May 26 21:10:04 2009
New Revision: 65432
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
make guard_nonvirtualizable yield a class. That's mostly to make llgraph
backend a bit happier, I'm not too happy about it
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 21:10:04 2009
@@ -110,7 +110,7 @@
for node, d in self.additional_stores.iteritems():
for field, fieldnode in d.iteritems():
gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
- [node.source], None)
+ [node.source, node.cls], None)
gop.vdesc = node.vdesc
gop.suboperations = [ResOperation(rop.FAIL, [], None)]
op.suboperations.append(gop)
@@ -120,7 +120,7 @@
for field, (fieldnode, descr) in d.iteritems():
box = fieldnode.source
gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
- [node.source], None)
+ [node.source, node.cls], None)
gop.suboperations = [ResOperation(rop.FAIL, [], None)]
gop.vdesc = node.vdesc
op.suboperations.append(gop)
@@ -186,6 +186,7 @@
def optimize_guard_nonvirtualized(op, spec):
instnode = spec.getnode(op.args[0])
instnode.virtualized = True
+ instnode.cls = op.args[1]
instnode.vdesc = op.vdesc
return True
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Tue May 26 21:10:04 2009
@@ -4,7 +4,7 @@
"""
from pypy.jit.metainterp.history import TreeLoop, BoxInt, BoxPtr, ConstInt,\
- ConstAddr, ConstObj
+ ConstAddr, ConstObj, ConstPtr
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.ootypesystem import ootype
@@ -59,6 +59,8 @@
self.cpu)
else:
return ConstObj(ootype.cast_to_object(self.consts[name]))
+ elif arg == 'None':
+ return None
return self.vars[arg]
def parse_op(self, line):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Tue May 26 21:10:04 2009
@@ -59,7 +59,8 @@
TP = lltype.GcArray(lltype.Signed)
- XY = lltype.GcStruct('XY', ('inst_field', lltype.Signed),
+ XY = lltype.GcStruct('XY', ('parent', OBJECT),
+ ('inst_field', lltype.Signed),
('inst_other_field', lltype.Signed),
('inst_list', lltype.Ptr(TP)),
hints= {'virtualizable2': True,
@@ -69,6 +70,7 @@
list_desc = cpu.fielddescrof(XY, 'inst_list')
other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
vdesc = VirtualizableDesc(cpu, XY, XY)
+ xy_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
namespace = locals()
@@ -102,6 +104,7 @@
list_desc = cpu.fielddescrof(XY, 'olist')
other_field_desc = cpu.fielddescrof(XY, 'oother_field')
vdesc = VirtualizableDesc(cpu, XY, XY)
+ xy_vtable = ootype.runtimeClass(XY)
namespace = locals()
@@ -151,7 +154,7 @@
def test_basic_virtualizable(self):
pre_op = """
[p0]
- guard_nonvirtualized(p0, vdesc=vdesc)
+ guard_nonvirtualized(p0, ConstClass(xy_vtable), vdesc=vdesc)
fail()
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=field_desc)
@@ -168,7 +171,7 @@
def test_virtualizable_setfield_rebuild_ops(self):
pre_op = """
[p0]
- guard_nonvirtualized(p0, vdesc=vdesc)
+ guard_nonvirtualized(p0, ConstClass(xy_vtable), vdesc=vdesc)
fail()
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=other_field_desc)
@@ -184,7 +187,8 @@
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=other_field_desc)
guard_true(i2)
- guard_nonvirtualized(p0)
+ guard_nonvirtualized(p0, ConstClass(xy_vtable))
+ fail()
setfield_gc(p0, i2, descr=field_desc)
fail()
"""
@@ -211,7 +215,7 @@
def test_virtualized_list_on_virtualizable(self):
pre_op = """
[p0]
- guard_nonvirtualized(p0, vdesc=vdesc)
+ guard_nonvirtualized(p0, ConstClass(xy_vtable), vdesc=vdesc)
fail()
p1 = getfield_gc(p0, descr=list_desc)
setarrayitem_gc(p1, 0, 1, descr=array_descr)
@@ -235,7 +239,7 @@
def test_virtualized_list_on_virtualizable_2(self):
pre_op = """
[p0, i0]
- guard_nonvirtualized(p0, vdesc=vdesc)
+ guard_nonvirtualized(p0, ConstClass(xy_vtable), vdesc=vdesc)
fail()
p1 = getfield_gc(p0, descr=list_desc)
setarrayitem_gc(p1, 0, i0, descr=array_descr)
@@ -252,7 +256,8 @@
i2 = int_add(i0, i0)
i3 = int_is_true(i2)
guard_true(i3)
- guard_nonvirtualized(p1)
+ guard_nonvirtualized(p1, None)
+ fail()
setarrayitem_gc(p1, 0, i0, descr=array_descr)
fail()
"""
@@ -262,7 +267,7 @@
def test_virtualized_list_on_virtualizable_3(self):
pre_op = """
[p0, i0, i1]
- guard_nonvirtualized(p0, vdesc=vdesc)
+ guard_nonvirtualized(p0, ConstClass(xy_vtable), vdesc=vdesc)
fail()
p1 = getfield_gc(p0, descr=list_desc)
setarrayitem_gc(p1, 0, i0, descr=array_descr)
@@ -281,7 +286,8 @@
i4 = int_add(i0, i1)
i5 = int_is_true(i4)
guard_true(i5)
- guard_nonvirtualized(p1)
+ guard_nonvirtualized(p1, None)
+ fail()
setarrayitem_gc(p1, 0, i1, descr=array_descr)
fail()
"""
@@ -348,4 +354,5 @@
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
- pass
+ def setup_class(cls):
+ py.test.skip("XXX")
From fijal at codespeak.net Tue May 26 21:10:56 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:10:56 +0200 (CEST)
Subject: [pypy-svn] r65433 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph
Message-ID: <20090526191056.705561684BF@codespeak.net>
Author: fijal
Date: Tue May 26 21:10:55 2009
New Revision: 65433
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
Log:
don't complain if class is None
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py Tue May 26 21:10:55 2009
@@ -555,7 +555,8 @@
def op_guard_nonvirtualized(self, for_accessing_field,
value, expected_class):
- self.op_guard_class(-1, value, expected_class)
+ if expected_class is not None:
+ self.op_guard_class(-1, value, expected_class)
if heaptracker.cast_vable(value).vable_rti:
raise GuardFailed # some other code is already in control
From fijal at codespeak.net Tue May 26 21:13:31 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:13:31 +0200 (CEST)
Subject: [pypy-svn] r65434 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph
Message-ID: <20090526191331.6B8C8169DB2@codespeak.net>
Author: fijal
Date: Tue May 26 21:13:30 2009
New Revision: 65434
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
Log:
seems this won't work
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py Tue May 26 21:13:30 2009
@@ -555,8 +555,7 @@
def op_guard_nonvirtualized(self, for_accessing_field,
value, expected_class):
- if expected_class is not None:
- self.op_guard_class(-1, value, expected_class)
+ self.op_guard_class(-1, value, expected_class)
if heaptracker.cast_vable(value).vable_rti:
raise GuardFailed # some other code is already in control
From fijal at codespeak.net Tue May 26 21:16:14 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:16:14 +0200 (CEST)
Subject: [pypy-svn] r65435 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090526191614.B352A168556@codespeak.net>
Author: fijal
Date: Tue May 26 21:16:14 2009
New Revision: 65435
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
remove the hack about guard_nonvirtualized
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 21:16:14 2009
@@ -94,6 +94,13 @@
newboxes.append(box)
return newboxes
+ def _guard_for_node(self, node):
+ gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
+ [node.source], None)
+ gop.vdesc = node.vdesc
+ gop.suboperations = [ResOperation(rop.FAIL, [], None)]
+ return gop
+
def optimize_guard(self, op):
if op.is_foldable_guard():
for arg in op.args:
@@ -109,20 +116,14 @@
op.suboperations = []
for node, d in self.additional_stores.iteritems():
for field, fieldnode in d.iteritems():
- gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
- [node.source, node.cls], None)
- gop.vdesc = node.vdesc
- gop.suboperations = [ResOperation(rop.FAIL, [], None)]
+ gop = self._guard_for_node(node)
op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETFIELD_GC,
[node.source, fieldnode.source], None, field))
for node, d in self.additional_setarrayitems.iteritems():
for field, (fieldnode, descr) in d.iteritems():
box = fieldnode.source
- gop = ResOperation(rop.GUARD_NONVIRTUALIZED,
- [node.source, node.cls], None)
- gop.suboperations = [ResOperation(rop.FAIL, [], None)]
- gop.vdesc = node.vdesc
+ gop = self._guard_for_node(node)
op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
[node.source, ConstInt(field), box], None, descr))
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Tue May 26 21:16:14 2009
@@ -187,7 +187,7 @@
i1 = getfield_gc(p0, descr=field_desc)
i2 = getfield_gc(p0, descr=other_field_desc)
guard_true(i2)
- guard_nonvirtualized(p0, ConstClass(xy_vtable))
+ guard_nonvirtualized(p0)
fail()
setfield_gc(p0, i2, descr=field_desc)
fail()
@@ -256,7 +256,7 @@
i2 = int_add(i0, i0)
i3 = int_is_true(i2)
guard_true(i3)
- guard_nonvirtualized(p1, None)
+ guard_nonvirtualized(p1)
fail()
setarrayitem_gc(p1, 0, i0, descr=array_descr)
fail()
@@ -286,7 +286,7 @@
i4 = int_add(i0, i1)
i5 = int_is_true(i4)
guard_true(i5)
- guard_nonvirtualized(p1, None)
+ guard_nonvirtualized(p1)
fail()
setarrayitem_gc(p1, 0, i1, descr=array_descr)
fail()
From fijal at codespeak.net Tue May 26 21:17:03 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:17:03 +0200 (CEST)
Subject: [pypy-svn] r65436 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph
Message-ID: <20090526191703.BB545168548@codespeak.net>
Author: fijal
Date: Tue May 26 21:17:00 2009
New Revision: 65436
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
Log:
try yo make llgraph backend happy
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py Tue May 26 21:17:00 2009
@@ -554,8 +554,9 @@
raise GuardFailed
def op_guard_nonvirtualized(self, for_accessing_field,
- value, expected_class):
- self.op_guard_class(-1, value, expected_class)
+ value, expected_class=None):
+ if expected_class is None:
+ self.op_guard_class(-1, value, expected_class)
if heaptracker.cast_vable(value).vable_rti:
raise GuardFailed # some other code is already in control
From fijal at codespeak.net Tue May 26 21:20:53 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:20:53 +0200 (CEST)
Subject: [pypy-svn] r65437 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph
Message-ID: <20090526192053.BE69D168556@codespeak.net>
Author: fijal
Date: Tue May 26 21:20:53 2009
New Revision: 65437
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
Log:
oops
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py Tue May 26 21:20:53 2009
@@ -555,7 +555,7 @@
def op_guard_nonvirtualized(self, for_accessing_field,
value, expected_class=None):
- if expected_class is None:
+ if expected_class is not None:
self.op_guard_class(-1, value, expected_class)
if heaptracker.cast_vable(value).vable_rti:
raise GuardFailed # some other code is already in control
From fijal at codespeak.net Tue May 26 21:23:46 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:23:46 +0200 (CEST)
Subject: [pypy-svn] r65438 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526192346.1936E1684BF@codespeak.net>
Author: fijal
Date: Tue May 26 21:23:45 2009
New Revision: 65438
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
remove this as it might not be there right now
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 21:23:45 2009
@@ -187,7 +187,6 @@
def optimize_guard_nonvirtualized(op, spec):
instnode = spec.getnode(op.args[0])
instnode.virtualized = True
- instnode.cls = op.args[1]
instnode.vdesc = op.vdesc
return True
From fijal at codespeak.net Tue May 26 21:37:20 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:37:20 +0200 (CEST)
Subject: [pypy-svn] r65439 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526193720.AE864168556@codespeak.net>
Author: fijal
Date: Tue May 26 21:37:19 2009
New Revision: 65439
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
add counting of operations
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Tue May 26 21:37:19 2009
@@ -135,7 +135,9 @@
self.additional_stores = {}
self.additional_setarrayitems = {}
newoperations = []
+ opnum = 0
for op in self.loop.operations:
+ opnum += 1
remove_op = False
for opt in self.optimizations[op.opnum]:
remove_op = opt(op, self)
From fijal at codespeak.net Tue May 26 21:44:48 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 21:44:48 +0200 (CEST)
Subject: [pypy-svn] r65440 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090526194448.11F8B169E27@codespeak.net>
Author: fijal
Date: Tue May 26 21:44:47 2009
New Revision: 65440
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py
Log:
don't show suboperations for guard_nonvirtualized
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py Tue May 26 21:44:47 2009
@@ -2,7 +2,7 @@
from pypy.translator.tool.graphpage import GraphPage
from pypy.translator.tool.make_dot import DotGen
from pypy.jit.metainterp.history import Box
-
+from pypy.jit.metainterp.resoperation import rop
class SubGraph:
def __init__(self, suboperations):
@@ -16,7 +16,7 @@
graphs = [(loop, loop in highlight_loops) for loop in loops]
for graph, highlight in graphs:
for op in graph.get_operations():
- if op.is_guard():
+ if op.is_guard() and op.opnum != rop.GUARD_NONVIRTUALIZED:
graphs.append((SubGraph(op.suboperations), highlight))
graphpage = ResOpGraphPage(graphs, errmsg)
graphpage.display()
From fijal at codespeak.net Tue May 26 23:51:10 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 26 May 2009 23:51:10 +0200 (CEST)
Subject: [pypy-svn] r65441 -
pypy/branch/pyjitpl5-experiments/pypy/interpreter
Message-ID: <20090526215110.0DC88169EEB@codespeak.net>
Author: fijal
Date: Tue May 26 23:51:09 2009
New Revision: 65441
Modified:
pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py
Log:
Move hints around.
Modified: pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py Tue May 26 23:51:09 2009
@@ -181,6 +181,7 @@
return values_w
def dropvalues(self, n):
+ n = hint(n, promote=True)
finaldepth = self.valuestackdepth - n
assert finaldepth >= 0, "stack underflow in dropvalues()"
while True:
@@ -188,7 +189,7 @@
if n < 0:
break
self.valuestack_w[finaldepth+n] = None
- self.valuestackdepth = hint(finaldepth, promote=True)
+ self.valuestackdepth = finaldepth
def pushrevvalues(self, n, values_w): # n should be len(values_w)
while True:
@@ -207,21 +208,24 @@
self.pushvalue(w_value)
def peekvalue(self, index_from_top=0):
+ index_from_top = hint(index_from_top, promote=True)
index = self.valuestackdepth + ~index_from_top
assert index >= 0, "peek past the bottom of the stack"
return self.valuestack_w[index]
def settopvalue(self, w_object, index_from_top=0):
+ index_from_top = hint(index_from_top, promote=True)
index = self.valuestackdepth + ~index_from_top
assert index >= 0, "settop past the bottom of the stack"
self.valuestack_w[index] = w_object
def dropvaluesuntil(self, finaldepth):
depth = self.valuestackdepth - 1
+ finaldepth = hint(finaldepth, promote=True)
while depth >= finaldepth:
self.valuestack_w[depth] = None
depth -= 1
- self.valuestackdepth = hint(finaldepth, promote=True)
+ self.valuestackdepth = finaldepth
def savevaluestack(self):
return self.valuestack_w[:self.valuestackdepth]
From fijal at codespeak.net Wed May 27 00:14:49 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 00:14:49 +0200 (CEST)
Subject: [pypy-svn] r65442 - pypy/trunk/dotviewer
Message-ID: <20090526221449.5F9E6169EC8@codespeak.net>
Author: fijal
Date: Wed May 27 00:14:47 2009
New Revision: 65442
Modified:
pypy/trunk/dotviewer/graphclient.py
pypy/trunk/dotviewer/graphserver.py
Log:
De-arminize. s/connexion/connection/
Modified: pypy/trunk/dotviewer/graphclient.py
==============================================================================
--- pypy/trunk/dotviewer/graphclient.py (original)
+++ pypy/trunk/dotviewer/graphclient.py Wed May 27 00:14:47 2009
@@ -92,7 +92,7 @@
if msg[0] == msgstruct.MSG_OK:
break
except EOFError:
- ioerror = ioerror or IOError("connexion unexpectedly closed "
+ ioerror = ioerror or IOError("connection unexpectedly closed "
"(graphserver crash?)")
if ioerror is not None:
raise ioerror
Modified: pypy/trunk/dotviewer/graphserver.py
==============================================================================
--- pypy/trunk/dotviewer/graphserver.py (original)
+++ pypy/trunk/dotviewer/graphserver.py Wed May 27 00:14:47 2009
@@ -126,7 +126,7 @@
print 'listening on %r...' % (s1.getsockname(),)
while True:
conn, addr = s1.accept()
- print 'accepted connexion from %r' % (addr,)
+ print 'accepted connection from %r' % (addr,)
sock_io = msgstruct.SocketIO(conn)
handler_io = graphclient.spawn_local_handler()
thread.start_new_thread(copy_all, (sock_io, handler_io))
From fijal at codespeak.net Wed May 27 02:41:09 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 02:41:09 +0200 (CEST)
Subject: [pypy-svn] r65443 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090527004109.0280D169F1A@codespeak.net>
Author: fijal
Date: Wed May 27 02:41:07 2009
New Revision: 65443
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
cheat - don't virtualize virtualizables that are allocated in a loop. The
reason behind it is that if it does so, it's going to be an argument of a
portal call
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Wed May 27 02:41:07 2009
@@ -22,6 +22,7 @@
self.cleanfields = {}
self.arrayfields = {}
self.virtualized = False
+ self.allocated_in_loop = False
self.vdesc = None
def __repr__(self):
@@ -83,7 +84,10 @@
self.getnode(box)
box = op.result
if box is not None:
- self.nodes[box] = self.getnode(box)
+ node = self.getnode(box)
+ if op.opnum == rop.NEW or op.opnum == rop.NEW_WITH_VTABLE:
+ node.allocated_in_loop = True
+ self.nodes[box] = node
def new_arguments(self, op):
newboxes = []
@@ -188,8 +192,9 @@
@staticmethod
def optimize_guard_nonvirtualized(op, spec):
instnode = spec.getnode(op.args[0])
- instnode.virtualized = True
- instnode.vdesc = op.vdesc
+ if not instnode.allocated_in_loop:
+ instnode.virtualized = True
+ instnode.vdesc = op.vdesc
return True
@staticmethod
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py Wed May 27 02:41:07 2009
@@ -667,7 +667,6 @@
res = self.meta_interp(f, [30])
assert res == 1
-
class TestOOtype(BasicTests, OOJitMixin):
def test_oohash(self):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Wed May 27 02:41:07 2009
@@ -279,7 +279,6 @@
guard_true(i5)
fail()
"""
- pre_op = parse(pre_op, self.cpu, self.namespace)
expected = """
[p0, i0, i1]
p1 = getfield_gc(p0, descr=list_desc)
@@ -294,6 +293,23 @@
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
expected)
+ def test_newly_allocated_virtualizable_is_not_virtualized(self):
+ pre_op = """
+ []
+ p0 = new_with_vtable(13, ConstClass(xy_vtable))
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ setfield_gc(p0, 3, descr=field_desc)
+ """
+ expected = """
+ []
+ p0 = new_with_vtable(13, ConstClass(xy_vtable))
+ setfield_gc(p0, 3, descr=field_desc)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
+ expected)
+
+
def test_remove_consecutive_guard_value_constfold(self):
py.test.skip("not yet")
n = BoxInt(0)
From cfbolz at codespeak.net Wed May 27 14:03:01 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 14:03:01 +0200 (CEST)
Subject: [pypy-svn] r65444 - in pypy/trunk/pypy: config doc/config
interpreter objspace objspace/fake objspace/std
objspace/std/test translator/microbench
Message-ID: <20090527120301.CE691169F82@codespeak.net>
Author: cfbolz
Date: Wed May 27 14:03:00 2009
New Revision: 65444
Added:
pypy/trunk/pypy/doc/config/objspace.std.withcelldict.txt (contents, props changed)
pypy/trunk/pypy/objspace/std/celldict.py (contents, props changed)
pypy/trunk/pypy/objspace/std/test/test_celldict.py (contents, props changed)
Modified:
pypy/trunk/pypy/config/pypyoption.py
pypy/trunk/pypy/interpreter/module.py
pypy/trunk/pypy/interpreter/pycode.py
pypy/trunk/pypy/objspace/fake/objspace.py
pypy/trunk/pypy/objspace/reflective.py
pypy/trunk/pypy/objspace/std/dictmultiobject.py
pypy/trunk/pypy/objspace/std/objspace.py
pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py
pypy/trunk/pypy/objspace/std/test/test_dictobject.py
pypy/trunk/pypy/translator/microbench/test_count1.py
Log:
merge speedup-global2 branch:
------------------------------------------------------------------------
r62765 | cfbolz | 2009-03-09 17:53:28 +0100 (Mon, 09 Mar 2009) | 3 lines
Changed paths:
A /pypy/branch/speedup-globals (from /pypy/trunk:62764)
A branch to try Armin's and mine newest idea about how to speed up global
lookups.
------------------------------------------------------------------------
r62773 | cfbolz | 2009-03-09 19:02:50 +0100 (Mon, 09 Mar 2009) | 5 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/config/pypyoption.py
M /pypy/branch/speedup-globals/pypy/interpreter/module.py
M /pypy/branch/speedup-globals/pypy/objspace/fake/objspace.py
M /pypy/branch/speedup-globals/pypy/objspace/reflective.py
M /pypy/branch/speedup-globals/pypy/objspace/std/dictmultiobject.py
M /pypy/branch/speedup-globals/pypy/objspace/std/objspace.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_dictmultiobject.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_dictobject.py
First step to make global lookups faster: Introduce a special dict
implementation for modules, where every value in the RPython-level dict is a
cell that contains the real value. As long as the "valid" flag on such a cell is
set, it is safe to store the cell somewhere else.
------------------------------------------------------------------------
r62811 | cfbolz | 2009-03-10 16:00:52 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
A /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/dictmultiobject.py
M /pypy/branch/speedup-globals/pypy/objspace/std/objspace.py
A /pypy/branch/speedup-globals/pypy/objspace/std/test/test_celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_dictmultiobject.py
Actually use the cell-dict stuff to cache global lookups in frames.
------------------------------------------------------------------------
r62816 | cfbolz | 2009-03-10 16:34:17 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
help flow space
------------------------------------------------------------------------
r62819 | cfbolz | 2009-03-10 17:54:44 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/translator/benchmark/benchmarks.py
fix typo
------------------------------------------------------------------------
r62823 | cfbolz | 2009-03-10 17:57:56 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/translator/benchmark/benchmarks.py
fix gadfly
------------------------------------------------------------------------
r62827 | cfbolz | 2009-03-10 19:07:12 +0100 (Tue, 10 Mar 2009) | 4 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/interpreter/pycode.py
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
It turns out that using one additional dict lookup per call negates many of the
benefits of this optimization. Therefore, attach the cache to the code object
directly.
------------------------------------------------------------------------
r62830 | cfbolz | 2009-03-10 20:38:30 +0100 (Tue, 10 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/translator/microbench/test_count1.py
two more microbenchmarks
------------------------------------------------------------------------
r62845 | cfbolz | 2009-03-11 11:54:45 +0100 (Wed, 11 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_celldict.py
get rid of invalid flag
------------------------------------------------------------------------
r62856 | cfbolz | 2009-03-11 13:16:33 +0100 (Wed, 11 Mar 2009) | 2 lines
Changed paths:
M /pypy/branch/speedup-globals/pypy/objspace/std/celldict.py
M /pypy/branch/speedup-globals/pypy/objspace/std/test/test_celldict.py
fix a corner-case
------------------------------------------------------------------------
r65410 | cfbolz | 2009-05-25 14:34:08 +0200 (Mon, 25 May 2009) | 2 lines
Changed paths:
A /pypy/branch/speedup-global2/pypy/doc/config/objspace.std.withcelldict.txt
add missing documentation
Modified: pypy/trunk/pypy/config/pypyoption.py
==============================================================================
--- pypy/trunk/pypy/config/pypyoption.py (original)
+++ pypy/trunk/pypy/config/pypyoption.py Wed May 27 14:03:00 2009
@@ -228,6 +228,13 @@
"use dictionaries optimized for flexibility",
default=False),
+ BoolOption("withcelldict",
+ "use dictionaries that are opimized for being used as module dicts",
+ default=False,
+ requires=[("objspace.std.withmultidict", True),
+ ("objspace.opcodes.CALL_LIKELY_BUILTIN", False),
+ ("objspace.honor__builtins__", False)]),
+
BoolOption("withsharingdict",
"use dictionaries that share the keys part",
default=False,
Added: pypy/trunk/pypy/doc/config/objspace.std.withcelldict.txt
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/doc/config/objspace.std.withcelldict.txt Wed May 27 14:03:00 2009
@@ -0,0 +1,2 @@
+Enable cell-dicts. This makes global lookups nearly as fast as the lookup of a
+local.
Modified: pypy/trunk/pypy/interpreter/module.py
==============================================================================
--- pypy/trunk/pypy/interpreter/module.py (original)
+++ pypy/trunk/pypy/interpreter/module.py Wed May 27 14:03:00 2009
@@ -11,7 +11,7 @@
def __init__(self, space, w_name, w_dict=None):
self.space = space
if w_dict is None:
- w_dict = space.newdict(track_builtin_shadowing=True)
+ w_dict = space.newdict(module=True)
self.w_dict = w_dict
self.w_name = w_name
if w_name is not None:
Modified: pypy/trunk/pypy/interpreter/pycode.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pycode.py (original)
+++ pypy/trunk/pypy/interpreter/pycode.py Wed May 27 14:03:00 2009
@@ -111,6 +111,10 @@
self._compute_flatcall()
+ if space.config.objspace.std.withcelldict:
+ from pypy.objspace.std.celldict import init_code
+ init_code(self)
+
co_names = property(lambda self: [self.space.unwrap(w_name) for w_name in self.co_names_w]) # for trace
def signature(self):
Modified: pypy/trunk/pypy/objspace/fake/objspace.py
==============================================================================
--- pypy/trunk/pypy/objspace/fake/objspace.py (original)
+++ pypy/trunk/pypy/objspace/fake/objspace.py Wed May 27 14:03:00 2009
@@ -93,7 +93,7 @@
newint = make_dummy()
newlong = make_dummy()
newfloat = make_dummy()
- def newdict(self, track_builtin_shadowing=False):
+ def newdict(self, module=False):
return self.newfloat()
newlist = make_dummy()
emptylist = make_dummy()
Modified: pypy/trunk/pypy/objspace/reflective.py
==============================================================================
--- pypy/trunk/pypy/objspace/reflective.py (original)
+++ pypy/trunk/pypy/objspace/reflective.py Wed May 27 14:03:00 2009
@@ -137,8 +137,8 @@
return None
if opname == "newdict": # grr grr kwargs
- def fn(track_builtin_shadowing=False):
- w_obj = parentfn(track_builtin_shadowing)
+ def fn(module=False):
+ w_obj = parentfn(module)
w_newobj = user_hook(w_obj)
if w_newobj is not None:
return w_newobj
Added: pypy/trunk/pypy/objspace/std/celldict.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/objspace/std/celldict.py Wed May 27 14:03:00 2009
@@ -0,0 +1,248 @@
+from pypy.objspace.std.dictmultiobject import DictImplementation
+from pypy.objspace.std.dictmultiobject import IteratorImplementation
+from pypy.objspace.std.dictmultiobject import W_DictMultiObject, _is_sane_hash
+
+class ModuleCell(object):
+ def __init__(self, w_value=None):
+ self.w_value = w_value
+
+ def invalidate(self):
+ w_value = self.w_value
+ self.w_value = None
+ return w_value
+
+ def __repr__(self):
+ return "" % (self.w_value, )
+
+class ModuleDictImplementation(DictImplementation):
+ def __init__(self, space):
+ self.space = space
+ self.content = {}
+ self.unshadowed_builtins = {}
+
+ def getcell(self, key, make_new=True):
+ try:
+ return self.content[key]
+ except KeyError:
+ if not make_new:
+ raise
+ result = self.content[key] = ModuleCell()
+ return result
+
+ def add_unshadowed_builtin(self, name, builtin_impl):
+ assert isinstance(builtin_impl, ModuleDictImplementation)
+ self.unshadowed_builtins[name] = builtin_impl
+
+ def invalidate_unshadowed_builtin(self, name):
+ impl = self.unshadowed_builtins[name]
+ try:
+ cell = impl.content[name]
+ except KeyError:
+ pass
+ else:
+ w_value = cell.invalidate()
+ cell = impl.content[name] = ModuleCell(w_value)
+
+ def setitem(self, w_key, w_value):
+ space = self.space
+ if space.is_w(space.type(w_key), space.w_str):
+ return self.setitem_str(w_key, w_value)
+ else:
+ return self._as_rdict().setitem(w_key, w_value)
+
+ def setitem_str(self, w_key, w_value, shadows_type=True):
+ name = self.space.str_w(w_key)
+ self.getcell(name).w_value = w_value
+
+ if name in self.unshadowed_builtins:
+ self.invalidate_unshadowed_builtin(name)
+ del self.unshadowed_builtins[name]
+
+ return self
+
+ def delitem(self, w_key):
+ space = self.space
+ w_key_type = space.type(w_key)
+ if space.is_w(w_key_type, space.w_str):
+ key = space.str_w(w_key)
+ cell = self.getcell(key, False)
+ cell.invalidate()
+ del self.content[key]
+ return self
+ elif _is_sane_hash(space, w_key_type):
+ raise KeyError
+ else:
+ return self._as_rdict().delitem(w_key)
+
+ def length(self):
+ return len(self.content)
+
+ def get(self, w_lookup):
+ space = self.space
+ w_lookup_type = space.type(w_lookup)
+ if space.is_w(w_lookup_type, space.w_str):
+ try:
+ return self.getcell(space.str_w(w_lookup), False).w_value
+ except KeyError:
+ return None
+ elif _is_sane_hash(space, w_lookup_type):
+ return None
+ else:
+ return self._as_rdict().get(w_lookup)
+
+ def iteritems(self):
+ return ModuleDictItemIteratorImplementation(self.space, self)
+
+ def iterkeys(self):
+ return ModuleDictKeyIteratorImplementation(self.space, self)
+
+ def itervalues(self):
+ return ModuleDictValueIteratorImplementation(self.space, self)
+
+ def keys(self):
+ space = self.space
+ return [space.wrap(key) for key in self.content.iterkeys()]
+
+ def values(self):
+ return [cell.w_value for cell in self.content.itervalues()]
+
+ def items(self):
+ space = self.space
+ return [space.newtuple([space.wrap(key), cell.w_value])
+ for (key, cell) in self.content.iteritems()]
+
+ def _as_rdict(self):
+ newimpl = self.space.DefaultDictImpl(self.space)
+ for k, cell in self.content.iteritems():
+ newimpl.setitem(self.space.wrap(k), cell.w_value)
+ cell.invalidate()
+ for k in self.unshadowed_builtins:
+ self.invalidate_unshadowed_builtin(k)
+ return newimpl
+
+# grrrrr. just a copy-paste from StrKeyIteratorImplementation in dictmultiobject
+class ModuleDictKeyIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iterkeys()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key in self.iterator:
+ return self.space.wrap(key)
+ else:
+ return None
+
+class ModuleDictValueIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.itervalues()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for cell in self.iterator:
+ return cell.w_value
+ else:
+ return None
+
+class ModuleDictItemIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key, cell in self.iterator:
+ return self.space.newtuple([self.space.wrap(key), cell.w_value])
+ else:
+ return None
+
+
+
+
+
+
+
+class State(object):
+ def __init__(self, space):
+ self.space = space
+ self.invalidcell = ModuleCell()
+ self.always_invalid_cache = []
+ self.neverused_dictimpl = ModuleDictImplementation(space)
+
+class GlobalCacheHolder(object):
+ def __init__(self, space):
+ self.cache = None
+ state = space.fromcache(State)
+ self.dictimpl = state.neverused_dictimpl
+
+ def getcache(self, space, code, w_globals):
+ implementation = getimplementation(w_globals)
+ if self.dictimpl is implementation:
+ return self.cache
+ return self.getcache_slow(space, code, w_globals, implementation)
+ getcache._always_inline_ = True
+
+ def getcache_slow(self, space, code, w_globals, implementation):
+ state = space.fromcache(State)
+ if not isinstance(implementation, ModuleDictImplementation):
+ missing_length = max(len(code.co_names_w) - len(state.always_invalid_cache), 0)
+ state.always_invalid_cache.extend([state.invalidcell] * missing_length)
+ cache = state.always_invalid_cache
+ else:
+ cache = [state.invalidcell] * len(code.co_names_w)
+ self.cache = cache
+ self.dictimpl = implementation
+ return cache
+ getcache_slow._dont_inline_ = True
+
+def init_code(code):
+ code.globalcacheholder = GlobalCacheHolder(code.space)
+
+
+def get_global_cache(space, code, w_globals):
+ from pypy.interpreter.pycode import PyCode
+ if not isinstance(code, PyCode):
+ return []
+ holder = code.globalcacheholder
+ return holder.getcache(space, code, w_globals)
+
+def getimplementation(w_dict):
+ if type(w_dict) is W_DictMultiObject:
+ return w_dict.implementation
+ else:
+ return None
+
+def LOAD_GLOBAL(f, nameindex, *ignored):
+ cell = f.cache_for_globals[nameindex]
+ w_value = cell.w_value
+ if w_value is None:
+ # slow path
+ w_value = load_global_fill_cache(f, nameindex)
+ f.pushvalue(w_value)
+LOAD_GLOBAL._always_inline_ = True
+
+def find_cell_from_dict(implementation, name):
+ if isinstance(implementation, ModuleDictImplementation):
+ try:
+ return implementation.getcell(name, False)
+ except KeyError:
+ return None
+ return None
+
+def load_global_fill_cache(f, nameindex):
+ name = f.space.str_w(f.getname_w(nameindex))
+ implementation = getimplementation(f.w_globals)
+ if isinstance(implementation, ModuleDictImplementation):
+ cell = find_cell_from_dict(implementation, name)
+ if cell is None:
+ builtin_impl = getimplementation(f.get_builtin().getdict())
+ cell = find_cell_from_dict(builtin_impl, name)
+ if cell is not None:
+ implementation.add_unshadowed_builtin(name, builtin_impl)
+
+ if cell is not None:
+ f.cache_for_globals[nameindex] = cell
+ return cell.w_value
+ return f._load_global(f.getname_w(nameindex))
+load_global_fill_cache._dont_inline_ = True
Modified: pypy/trunk/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/trunk/pypy/objspace/std/dictmultiobject.py Wed May 27 14:03:00 2009
@@ -865,7 +865,6 @@
else:
return None
-
import time, py
class DictInfo(object):
@@ -1038,8 +1037,11 @@
class W_DictMultiObject(W_Object):
from pypy.objspace.std.dicttype import dict_typedef as typedef
- def __init__(w_self, space, wary=False, sharing=False):
- if space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and wary:
+ def __init__(w_self, space, wary=False, sharing=False, module=False):
+ if space.config.objspace.std.withcelldict and wary:
+ from pypy.objspace.std.celldict import ModuleDictImplementation
+ w_self.implementation = ModuleDictImplementation(space)
+ elif space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and wary:
w_self.implementation = WaryDictImplementation(space)
elif space.config.objspace.std.withdictmeasurement:
w_self.implementation = MeasuringDictImplementation(space)
Modified: pypy/trunk/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/objspace.py (original)
+++ pypy/trunk/pypy/objspace/std/objspace.py Wed May 27 14:03:00 2009
@@ -72,7 +72,16 @@
# Import all the object types and implementations
self.model = StdTypeModel(self.config)
+ from pypy.objspace.std.celldict import get_global_cache
+
class StdObjSpaceFrame(pyframe.PyFrame):
+ if self.config.objspace.std.withcelldict:
+ def __init__(self, space, code, w_globals, closure):
+ pyframe.PyFrame.__init__(self, space, code, w_globals, closure)
+ self.cache_for_globals = get_global_cache(space, code, w_globals)
+
+ from pypy.objspace.std.celldict import LOAD_GLOBAL
+
if self.config.objspace.std.optimized_int_add:
if self.config.objspace.std.withsmallint:
def BINARY_ADD(f, oparg, *ignored):
@@ -580,8 +589,8 @@
from pypy.objspace.std.listobject import W_ListObject
return W_ListObject(list_w)
- def newdict(self, track_builtin_shadowing=False):
- if self.config.objspace.opcodes.CALL_LIKELY_BUILTIN and track_builtin_shadowing:
+ def newdict(self, module=False):
+ if self.config.objspace.std.withmultidict and module:
from pypy.objspace.std.dictmultiobject import W_DictMultiObject
return W_DictMultiObject(self, wary=True)
return self.DictObjectCls(self)
Added: pypy/trunk/pypy/objspace/std/test/test_celldict.py
==============================================================================
--- (empty file)
+++ pypy/trunk/pypy/objspace/std/test/test_celldict.py Wed May 27 14:03:00 2009
@@ -0,0 +1,259 @@
+from pypy.conftest import gettestobjspace
+from pypy.objspace.std.celldict import get_global_cache, ModuleCell, ModuleDictImplementation
+from pypy.interpreter import gateway
+
+# this file tests mostly the effects of caching global lookup. The dict
+# implementation itself is tested in test_dictmultiobject.py
+
+
+class AppTestCellDict(object):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withcelldict": True})
+ cls.w_impl_used = cls.space.appexec([], """():
+ import __pypy__
+ def impl_used(obj):
+ assert "ModuleDictImplementation" in __pypy__.internal_repr(obj)
+ return impl_used
+ """)
+ def is_in_cache(space, w_code, w_globals, w_name):
+ name = space.str_w(w_name)
+ cache = get_global_cache(space, w_code, w_globals)
+ index = [space.str_w(w_n) for w_n in w_code.co_names_w].index(name)
+ return space.wrap(cache[index].w_value is not None)
+ is_in_cache = gateway.interp2app(is_in_cache)
+ cls.w_is_in_cache = cls.space.wrap(is_in_cache)
+ stored_builtins = []
+ def rescue_builtins(space):
+ w_dict = space.builtin.getdict()
+ content = {}
+ for key, cell in w_dict.implementation.content.iteritems():
+ newcell = ModuleCell()
+ newcell.w_value = cell.w_value
+ content[key] = newcell
+ stored_builtins.append(content)
+ rescue_builtins = gateway.interp2app(rescue_builtins)
+ cls.w_rescue_builtins = cls.space.wrap(rescue_builtins)
+ def restore_builtins(space):
+ w_dict = space.builtin.getdict()
+ if not isinstance(w_dict.implementation, ModuleDictImplementation):
+ w_dict.implementation = ModuleDictImplementation(space)
+ w_dict.implementation.content = stored_builtins.pop()
+ restore_builtins = gateway.interp2app(restore_builtins)
+ cls.w_restore_builtins = cls.space.wrap(restore_builtins)
+
+ def test_same_code_in_different_modules(self):
+ import sys
+ mod1 = type(sys)("abc")
+ self.impl_used(mod1.__dict__)
+ glob1 = mod1.__dict__
+ mod2 = type(sys)("abc")
+ self.impl_used(mod2.__dict__)
+ glob2 = mod2.__dict__
+ def f():
+ return x + 1
+ code = f.func_code
+ f1 = type(f)(code, glob1)
+ mod1.x = 1
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ mod1.x = 2
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "x")
+ f2 = type(f)(code, glob2)
+ mod2.x = 5
+ assert not self.is_in_cache(code, glob2, "x")
+ assert f2() == 6
+ assert self.is_in_cache(code, glob2, "x")
+ assert f2() == 6
+ assert self.is_in_cache(code, glob2, "x")
+ mod2.x = 7
+ assert f2() == 8
+ assert self.is_in_cache(code, glob2, "x")
+ assert f2() == 8
+ assert self.is_in_cache(code, glob2, "x")
+
+ def test_override_builtins(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ glob1 = mod1.__dict__
+ self.impl_used(mod1.__dict__)
+ def f():
+ return len(x)
+ code = f.func_code
+ f1 = type(f)(f.func_code, glob1)
+ mod1.x = []
+ assert not self.is_in_cache(code, glob1, "len")
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ assert self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ mod1.x.append(1)
+ assert f1() == 1
+ assert self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+ mod1.len = lambda x: 15
+ assert not self.is_in_cache(code, glob1, "len")
+ mod1.x.append(1)
+ assert f1() == 15
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 15
+ assert self.is_in_cache(code, glob1, "len")
+ del mod1.len
+ mod1.x.append(1)
+ assert not self.is_in_cache(code, glob1, "len")
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 3
+ assert self.is_in_cache(code, glob1, "len")
+ orig_len = __builtins__.len
+ try:
+ __builtins__.len = lambda x: 12
+ mod1.x.append(1)
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 12
+ assert self.is_in_cache(code, glob1, "len")
+ assert f1() == 12
+ assert self.is_in_cache(code, glob1, "len")
+ finally:
+ __builtins__.len = orig_len
+
+ def test_override_builtins2(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ glob1 = mod1.__dict__
+ self.impl_used(mod1.__dict__)
+ def f():
+ return l(x)
+ code = f.func_code
+ f1 = type(f)(f.func_code, glob1)
+ mod1.x = []
+ __builtin__.l = len
+ try:
+ assert not self.is_in_cache(code, glob1, "l")
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ assert self.is_in_cache(code, glob1, "l")
+ assert self.is_in_cache(code, glob1, "x")
+ assert f1() == 0
+ mod1.x.append(1)
+ assert f1() == 1
+ assert self.is_in_cache(code, glob1, "l")
+ assert self.is_in_cache(code, glob1, "x")
+ del __builtin__.l
+ mod1.l = len
+ mod1.x.append(1)
+ assert not self.is_in_cache(code, glob1, "l")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "l")
+ assert self.is_in_cache(code, glob1, "x")
+ finally:
+ if hasattr(__builtins__, "l"):
+ del __builtins__.l
+
+ def test_generator(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ glob1 = mod1.__dict__
+ self.impl_used(mod1.__dict__)
+ def f():
+ yield 1
+ yield x
+ yield len(x)
+ code = f.func_code
+ f1 = type(f)(f.func_code, glob1)
+ mod1.x = []
+ gen = f1()
+ assert not self.is_in_cache(code, glob1, "len")
+ assert not self.is_in_cache(code, glob1, "x")
+ v = gen.next()
+ assert v == 1
+ assert not self.is_in_cache(code, glob1, "len")
+ assert not self.is_in_cache(code, glob1, "x")
+ v = gen.next()
+ assert v is mod1.x
+ assert not self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+ v = gen.next()
+ assert v == 0
+ assert self.is_in_cache(code, glob1, "len")
+ assert self.is_in_cache(code, glob1, "x")
+
+ def test_degenerate_to_rdict(self):
+ import sys
+ mod1 = type(sys)("abc")
+ self.impl_used(mod1.__dict__)
+ glob1 = mod1.__dict__
+ def f():
+ return x + 1
+ code = f.func_code
+ f1 = type(f)(code, glob1)
+ mod1.x = 1
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ glob1[1] = 2
+ assert not self.is_in_cache(code, glob1, "x")
+ assert f1() == 2
+ assert not self.is_in_cache(code, glob1, "x")
+
+ def test_degenerate_builtin_to_rdict(self):
+ import sys, __builtin__
+ mod1 = type(sys)("abc")
+ self.impl_used(mod1.__dict__)
+ glob1 = mod1.__dict__
+ def f():
+ return len(x)
+ code = f.func_code
+ f1 = type(f)(code, glob1)
+ mod1.x = [1, 2]
+ assert not self.is_in_cache(code, glob1, "x")
+ assert not self.is_in_cache(code, glob1, "len")
+ assert f1() == 2
+ assert self.is_in_cache(code, glob1, "x")
+ assert self.is_in_cache(code, glob1, "len")
+ self.rescue_builtins()
+ try:
+ __builtin__.__dict__[1] = 2
+ assert not self.is_in_cache(code, glob1, "len")
+ assert f1() == 2
+ assert not self.is_in_cache(code, glob1, "len")
+ finally:
+ self.restore_builtins()
+
+ def test_mapping_as_locals(self):
+ import sys
+ if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'):
+ skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements")
+ class M(object):
+ def __getitem__(self, key):
+ return key
+ def __setitem__(self, key, value):
+ self.result[key] = value
+ m = M()
+ m.result = {}
+ exec "x=m" in {}, m
+ assert m.result == {'x': 'm'}
+ exec "y=n" in m # NOTE: this doesn't work in CPython 2.4
+ assert m.result == {'x': 'm', 'y': 'n'}
+
+ def test_subclass_of_dict_as_locals(self):
+ import sys
+ if sys.version_info < (2,5) or not hasattr(sys, 'pypy_objspaceclass'):
+ skip("need CPython 2.5 or PyPy for non-dictionaries in exec statements")
+ class M(dict):
+ def __getitem__(self, key):
+ return key
+ def __setitem__(self, key, value):
+ dict.__setitem__(self, key, value)
+ m = M()
+ exec "x=m" in {}, m
+ assert m == {'x': 'm'}
+ exec "y=n" in m # NOTE: this doesn't work in CPython 2.4
+ assert m == {'x': 'm', 'y': 'n'}
+
Modified: pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py (original)
+++ pypy/trunk/pypy/objspace/std/test/test_dictmultiobject.py Wed May 27 14:03:00 2009
@@ -3,6 +3,8 @@
W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \
EmptyDictImplementation, RDictImplementation, StrDictImplementation, \
SmallDictImplementation, SmallStrDictImplementation, MeasuringDictImplementation
+
+from pypy.objspace.std.celldict import ModuleDictImplementation
from pypy.conftest import gettestobjspace
from pypy.objspace.std.test import test_dictobject
@@ -58,6 +60,26 @@
a.__dict__.items() == [("abc", 12)]
+class AppTestModuleDict(object):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withcelldict": True})
+ cls.w_impl_used = cls.space.appexec([], """():
+ import __pypy__
+ def impl_used(obj):
+ assert "ModuleDictImplementation" in __pypy__.internal_repr(obj)
+ return impl_used
+ """)
+
+
+ def test_check_module_uses_module_dict(self):
+ m = type(__builtins__)("abc")
+ self.impl_used(m.__dict__)
+
+ def test_key_not_there(self):
+ d = type(__builtins__)("abc").__dict__
+ raises(KeyError, "d['def']")
+
+
class TestW_DictSmall(test_dictobject.TestW_DictObject):
def setup_class(cls):
@@ -233,3 +255,15 @@
def get_impl(self):
return self.ImplementionClass(self.space, self.string, self.string2)
+
+class TestModuleDictImplementation(TestRDictImplementation):
+ ImplementionClass = ModuleDictImplementation
+ EmptyClass = ModuleDictImplementation
+
+class TestModuleDictImplementationWithBuiltinNames(TestRDictImplementation):
+ ImplementionClass = ModuleDictImplementation
+ EmptyClass = ModuleDictImplementation
+
+ string = "int"
+ string2 = "isinstance"
+
Modified: pypy/trunk/pypy/objspace/std/test/test_dictobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/test/test_dictobject.py (original)
+++ pypy/trunk/pypy/objspace/std/test/test_dictobject.py Wed May 27 14:03:00 2009
@@ -489,6 +489,7 @@
FakeSpace.config.objspace.std.withdictmeasurement = False
FakeSpace.config.objspace.std.withsharingdict = False
FakeSpace.config.objspace.std.withsmalldicts = False
+FakeSpace.config.objspace.std.withcelldict = False
FakeSpace.config.objspace.opcodes = Config()
FakeSpace.config.objspace.opcodes.CALL_LIKELY_BUILTIN = False
Modified: pypy/trunk/pypy/translator/microbench/test_count1.py
==============================================================================
--- pypy/trunk/pypy/translator/microbench/test_count1.py (original)
+++ pypy/trunk/pypy/translator/microbench/test_count1.py Wed May 27 14:03:00 2009
@@ -201,3 +201,15 @@
y = y + 1
c += 1
+def test_count_with_True():
+ x = 0
+ n = N
+ while x < n:
+ x = x + True
+
+increment = 1
+def test_count_with_global_increment():
+ x = 0
+ n = N
+ while x < n:
+ x = x + increment
From cfbolz at codespeak.net Wed May 27 14:03:21 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 14:03:21 +0200 (CEST)
Subject: [pypy-svn] r65445 - pypy/branch/speedup-global2
Message-ID: <20090527120321.6C3FB169F85@codespeak.net>
Author: cfbolz
Date: Wed May 27 14:03:21 2009
New Revision: 65445
Removed:
pypy/branch/speedup-global2/
Log:
kill merged branch
From cfbolz at codespeak.net Wed May 27 14:03:36 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 14:03:36 +0200 (CEST)
Subject: [pypy-svn] r65446 - pypy/branch/speedup-globals
Message-ID: <20090527120336.764A1169F8A@codespeak.net>
Author: cfbolz
Date: Wed May 27 14:03:35 2009
New Revision: 65446
Removed:
pypy/branch/speedup-globals/
Log:
kill precursor of merged branch
From cfbolz at codespeak.net Wed May 27 14:16:23 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 14:16:23 +0200 (CEST)
Subject: [pypy-svn] r65447 -
pypy/branch/tagged-pointers-framework/pypy/rlib/test
Message-ID: <20090527121623.622DC169EEF@codespeak.net>
Author: cfbolz
Date: Wed May 27 14:16:22 2009
New Revision: 65447
Modified:
pypy/branch/tagged-pointers-framework/pypy/rlib/test/test_objectmodel.py
Log:
forgot to fix a test
Modified: pypy/branch/tagged-pointers-framework/pypy/rlib/test/test_objectmodel.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rlib/test/test_objectmodel.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rlib/test/test_objectmodel.py Wed May 27 14:16:22 2009
@@ -124,13 +124,13 @@
__slots__ = 'smallint'
assert C(17).smallint == 17
- assert C(17).getvalue() == 17
+ assert C(17).get_untagged_value() == 17
class A(UnboxedValue):
__slots__ = ['value']
assert A(12098).value == 12098
- assert A(12098).getvalue() == 12098
+ assert A(12098).get_untagged_value() == 12098
def test_symbolic():
py.test.skip("xxx no test here")
From cfbolz at codespeak.net Wed May 27 14:18:40 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 14:18:40 +0200 (CEST)
Subject: [pypy-svn] r65448 -
pypy/branch/tagged-pointers-framework/pypy/translator/c/test
Message-ID: <20090527121840.824DB169F6B@codespeak.net>
Author: cfbolz
Date: Wed May 27 14:18:39 2009
New Revision: 65448
Modified:
pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_rtagged.py
Log:
fix another test
Modified: pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_rtagged.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_rtagged.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/translator/c/test/test_rtagged.py Wed May 27 14:18:39 2009
@@ -38,7 +38,7 @@
def entry_point(argv):
n = 100 + len(argv)
- assert C(n).getvalue() == n
+ assert C(n).get_untagged_value() == n
x = makeint(42)
assert isinstance(x, C)
@@ -67,7 +67,7 @@
from pypy import conftest
def test_tagged_boehm():
- t = Translation(entry_point, standalone=True, gc='boehm')
+ t = Translation(entry_point, standalone=True, gc='boehm', taggedpointers=True)
try:
exename = str(t.compile_c())
finally:
From cfbolz at codespeak.net Wed May 27 14:41:48 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 14:41:48 +0200 (CEST)
Subject: [pypy-svn] r65449 - pypy/trunk/pypy/objspace/std
Message-ID: <20090527124148.D7092169F80@codespeak.net>
Author: cfbolz
Date: Wed May 27 14:41:46 2009
New Revision: 65449
Modified:
pypy/trunk/pypy/objspace/std/dictmultiobject.py
pypy/trunk/pypy/objspace/std/objspace.py
Log:
Get rid of a superfluous argument to __init__. Thanks Amaury for being wary.
Modified: pypy/trunk/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/trunk/pypy/objspace/std/dictmultiobject.py Wed May 27 14:41:46 2009
@@ -1037,11 +1037,11 @@
class W_DictMultiObject(W_Object):
from pypy.objspace.std.dicttype import dict_typedef as typedef
- def __init__(w_self, space, wary=False, sharing=False, module=False):
- if space.config.objspace.std.withcelldict and wary:
+ def __init__(w_self, space, module=False, sharing=False):
+ if space.config.objspace.std.withcelldict and module:
from pypy.objspace.std.celldict import ModuleDictImplementation
w_self.implementation = ModuleDictImplementation(space)
- elif space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and wary:
+ elif space.config.objspace.opcodes.CALL_LIKELY_BUILTIN and module:
w_self.implementation = WaryDictImplementation(space)
elif space.config.objspace.std.withdictmeasurement:
w_self.implementation = MeasuringDictImplementation(space)
Modified: pypy/trunk/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/trunk/pypy/objspace/std/objspace.py (original)
+++ pypy/trunk/pypy/objspace/std/objspace.py Wed May 27 14:41:46 2009
@@ -592,7 +592,7 @@
def newdict(self, module=False):
if self.config.objspace.std.withmultidict and module:
from pypy.objspace.std.dictmultiobject import W_DictMultiObject
- return W_DictMultiObject(self, wary=True)
+ return W_DictMultiObject(self, module=True)
return self.DictObjectCls(self)
def newslice(self, w_start, w_end, w_step):
From afa at codespeak.net Wed May 27 14:49:31 2009
From: afa at codespeak.net (afa at codespeak.net)
Date: Wed, 27 May 2009 14:49:31 +0200 (CEST)
Subject: [pypy-svn] r65450 - pypy/trunk/pypy/config
Message-ID: <20090527124931.96331169F94@codespeak.net>
Author: afa
Date: Wed May 27 14:49:31 2009
New Revision: 65450
Modified:
pypy/trunk/pypy/config/pypyoption.py
Log:
Typo in option description
Modified: pypy/trunk/pypy/config/pypyoption.py
==============================================================================
--- pypy/trunk/pypy/config/pypyoption.py (original)
+++ pypy/trunk/pypy/config/pypyoption.py Wed May 27 14:49:31 2009
@@ -229,7 +229,7 @@
default=False),
BoolOption("withcelldict",
- "use dictionaries that are opimized for being used as module dicts",
+ "use dictionaries that are optimized for being used as module dicts",
default=False,
requires=[("objspace.std.withmultidict", True),
("objspace.opcodes.CALL_LIKELY_BUILTIN", False),
From antocuni at codespeak.net Wed May 27 14:51:04 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 27 May 2009 14:51:04 +0200 (CEST)
Subject: [pypy-svn] r65451 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090527125104.ACF85169F99@codespeak.net>
Author: antocuni
Date: Wed May 27 14:51:04 2009
New Revision: 65451
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
fix ootype tests
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Wed May 27 14:51:04 2009
@@ -225,7 +225,7 @@
guard_true(i3)
fail()
"""
- pre_op = parse(pre_op, self.cpu, self.namespace)
+ pre_op = self.parse(pre_op)
# cheat
pre_op.operations[-2].result.value = 1
expected = """
@@ -249,7 +249,7 @@
guard_true(i3)
fail()
"""
- pre_op = parse(pre_op, self.cpu, self.namespace)
+ pre_op = self.parse(pre_op)
expected = """
[p0, i0]
p1 = getfield_gc(p0, descr=list_desc)
@@ -370,5 +370,4 @@
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
- def setup_class(cls):
- py.test.skip("XXX")
+ pass
From cfbolz at codespeak.net Wed May 27 15:02:22 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 15:02:22 +0200 (CEST)
Subject: [pypy-svn] r65452 -
pypy/branch/tagged-pointers-framework/pypy/doc/config
Message-ID: <20090527130222.45A3C169EBC@codespeak.net>
Author: cfbolz
Date: Wed May 27 15:02:21 2009
New Revision: 65452
Added:
pypy/branch/tagged-pointers-framework/pypy/doc/config/translation.taggedpointers.txt (contents, props changed)
Log:
add documentation
Added: pypy/branch/tagged-pointers-framework/pypy/doc/config/translation.taggedpointers.txt
==============================================================================
--- (empty file)
+++ pypy/branch/tagged-pointers-framework/pypy/doc/config/translation.taggedpointers.txt Wed May 27 15:02:21 2009
@@ -0,0 +1,3 @@
+Enable tagged pointers. This option is mostly useful for the Smalltalk and
+Prolog interpreters. For the Python interpreter the option
+:config:`objspace.std.withsmallint` should be used.
From cfbolz at codespeak.net Wed May 27 15:03:15 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 15:03:15 +0200 (CEST)
Subject: [pypy-svn] r65453 -
pypy/branch/tagged-pointers-framework/pypy/lang/smalltalk
Message-ID: <20090527130315.37F95169EBC@codespeak.net>
Author: cfbolz
Date: Wed May 27 15:03:14 2009
New Revision: 65453
Modified:
pypy/branch/tagged-pointers-framework/pypy/lang/smalltalk/model.py
Log:
Adapt smalltalk vm to make the translation.taggedpointers option do something.
Modified: pypy/branch/tagged-pointers-framework/pypy/lang/smalltalk/model.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/lang/smalltalk/model.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/lang/smalltalk/model.py Wed May 27 15:03:14 2009
@@ -19,7 +19,7 @@
from pypy.rlib.rarithmetic import intmask
from pypy.lang.smalltalk import constants, error
from pypy.tool.pairtype import extendabletype
-from pypy.rlib.objectmodel import instantiate
+from pypy.rlib.objectmodel import instantiate, UnboxedValue
from pypy.lang.smalltalk.tool.bitmanipulation import splitter
class W_Object(object):
@@ -96,14 +96,15 @@
False means swapping failed"""
return False
-class W_SmallInteger(W_Object):
+
+# the UnboxedValue mixin means the object can potentially be stored in unboxed
+# form
+
+class W_SmallInteger(W_Object, UnboxedValue):
"""Boxed integer value"""
# TODO can we tell pypy that its never larger then 31-bit?
__slots__ = ('value',) # the only allowed slot here
- def __init__(self, value):
- self.value = value
-
def getclass(self, space):
"""Return SmallInteger from special objects array."""
return space.w_SmallInteger
From cfbolz at codespeak.net Wed May 27 15:04:33 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 15:04:33 +0200 (CEST)
Subject: [pypy-svn] r65454 - in pypy/branch/tagged-pointers-framework/pypy:
rpython/memory/gctransform translator/c/gcc/test
Message-ID: <20090527130433.A348A169E9A@codespeak.net>
Author: cfbolz
Date: Wed May 27 15:04:33 2009
New Revision: 65454
Modified:
pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gctransform/asmgcroot.py
pypy/branch/tagged-pointers-framework/pypy/translator/c/gcc/test/test_asmgcroot.py
Log:
Fix asmgcroot stack walker in conjunction with tagged pointers.
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gctransform/asmgcroot.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gctransform/asmgcroot.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/memory/gctransform/asmgcroot.py Wed May 27 15:04:33 2009
@@ -154,7 +154,7 @@
if location == 0:
break
addr = self.getlocation(callee, location)
- if addr.address[0] != llmemory.NULL:
+ if gc.points_to_valid_gc_object(addr):
collect_stack_root(gc, addr)
#
# track where the caller_frame saved the registers from its own
Modified: pypy/branch/tagged-pointers-framework/pypy/translator/c/gcc/test/test_asmgcroot.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/translator/c/gcc/test/test_asmgcroot.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/translator/c/gcc/test/test_asmgcroot.py Wed May 27 15:04:33 2009
@@ -14,7 +14,7 @@
# instructions:
should_be_moving = False
- def getcompiled(self, func):
+ def getcompiled(self, func, **extraargs):
def main(argv):
try:
res = func()
@@ -30,6 +30,7 @@
config = get_pypy_config(translating=True)
config.translation.gc = self.gcpolicy
config.translation.gcrootfinder = "asmgcc"
+ config.set(**extraargs)
t = TranslationContext(config=config)
self.t = t
a = t.buildannotator()
From antocuni at codespeak.net Wed May 27 15:52:38 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 27 May 2009 15:52:38 +0200 (CEST)
Subject: [pypy-svn] r65455 - in pypy/branch/pyjitpl5-experiments/pypy:
jit/backend jit/backend/cli jit/metainterp jit/tl translator
translator/oosupport
Message-ID: <20090527135238.12C5C169F52@codespeak.net>
Author: antocuni
Date: Wed May 27 15:52:37 2009
New Revision: 65455
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/detect_cpu.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/warmspot.py
pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py
pypy/branch/pyjitpl5-experiments/pypy/jit/tl/targetpypyjit.py
pypy/branch/pyjitpl5-experiments/pypy/translator/driver.py
pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/constant.py
Log:
make it possible to translate targetpypyjit with the cli backend
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py Wed May 27 15:52:37 2009
@@ -241,7 +241,7 @@
return dotnet.classof(System.Double)
## elif T is ootype.String:
## return dotnet.classof(System.String)
- elif T is ootype.Char:
+ elif T in (ootype.Char, ootype.UniChar):
return dotnet.classof(System.Char)
elif isinstance(T, ootype.OOType):
return ootype.runtimeClass(T)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/detect_cpu.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/detect_cpu.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/detect_cpu.py Wed May 27 15:52:37 2009
@@ -47,6 +47,8 @@
from pypy.jit.backend.x86.runner import CPU
elif backend_name == 'minimal':
from pypy.jit.backend.minimal.runner import LLtypeCPU as CPU
+ elif backend_name == 'cli':
+ from pypy.jit.backend.cli.runner import CliCPU as CPU
else:
raise ProcessorAutodetectError, "unsupported cpu '%s'" % backend_name
return CPU
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/warmspot.py Wed May 27 15:52:37 2009
@@ -30,6 +30,7 @@
def apply_jit(translator, backend_name="auto", **kwds):
from pypy.jit.metainterp.simple_optimize import Optimizer
+ #from pypy.jit.metainterp.optimize2 import Optimizer
if 'CPUClass' not in kwds:
from pypy.jit.backend.detect_cpu import getcpuclass
kwds['CPUClass'] = getcpuclass(backend_name)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/tl/pypyjit_demo.py Wed May 27 15:52:37 2009
@@ -7,12 +7,17 @@
def simple_loop():
print "simple loop"
+ import time
i = 0
N = 100
+ #N = 10000000
step = 3
+ start = time.clock()
while i < N:
i = i + step
+ end = time.clock()
print i
+ print end-start, 'seconds'
def g(i):
for k in range(i, i +2):
@@ -24,7 +29,8 @@
try:
#do()
- loop()
+ #loop()
+ simple_loop()
print "---ending 2---"
except BaseException, e:
print "---ending 0---"
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/tl/targetpypyjit.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/tl/targetpypyjit.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/tl/targetpypyjit.py Wed May 27 15:52:37 2009
@@ -65,8 +65,15 @@
config.objspace.usemodules.pypyjit = True
config.objspace.usemodules._weakref = False
config.objspace.usemodules._sre = False
- config.objspace.std.multimethods = 'mrd'
- multimethod.Installer = multimethod.InstallerVersion2
+ if config.translation.type_system == 'lltype':
+ config.objspace.std.multimethods = 'mrd'
+ multimethod.Installer = multimethod.InstallerVersion2
+ else:
+ from pypy.rlib import jit
+ jit.PARAMETERS['hash_bits'] = 6 # XXX: this is a hack, should be fixed at some point
+ config.objspace.std.multimethods = 'doubledispatch'
+ multimethod.Installer = multimethod.InstallerVersion1
+
config.objspace.std.builtinshortcut = True
config.objspace.opcodes.CALL_LIKELY_BUILTIN = True
config.objspace.std.withrangelist = True
@@ -76,6 +83,7 @@
w_dict = space.newdict()
return entry_point, None, PyPyAnnotatorPolicy(single_space = space)
+
def jitpolicy(driver):
"""Returns the JIT policy to use when translating."""
from pypy.module.pypyjit.policy import PyPyJitPolicy
Modified: pypy/branch/pyjitpl5-experiments/pypy/translator/driver.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/translator/driver.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/translator/driver.py Wed May 27 15:52:37 2009
@@ -369,6 +369,20 @@
[RTYPE],
"Backendopt before jitting")
+ def task_prejitbackendopt_ootype(self):
+ from pypy.translator.backendopt.all import backend_optimizations
+ backend_optimizations(self.translator,
+ inline_threshold=0,
+ merge_if_blocks=True,
+ constfold=False, # XXX?
+ raisingop2direct_call=False,
+ remove_asserts=False)
+ #
+ task_prejitbackendopt_ootype = taskdef(
+ task_prejitbackendopt_ootype,
+ [OOTYPE],
+ "Backendopt before jitting")
+
def task_pyjitpl_lltype(self):
get_policy = self.extra['jitpolicy']
self.jitpolicy = get_policy(self)
@@ -383,6 +397,20 @@
[RTYPE, '?prejitbackendopt_lltype'],
"JIT compiler generation")
+ def task_pyjitpl_ootype(self):
+ get_policy = self.extra['jitpolicy']
+ self.jitpolicy = get_policy(self)
+ #
+ from pypy.jit.metainterp.warmspot import apply_jit
+ apply_jit(self.translator, policy=self.jitpolicy,
+ backend_name='cli') #XXX
+ #
+ self.log.info("the JIT compiler was generated")
+ #
+ task_pyjitpl_ootype = taskdef(task_pyjitpl_ootype,
+ [OOTYPE, '?prejitbackendopt_ootype'],
+ "JIT compiler generation")
+
def task_backendopt_lltype(self):
from pypy.translator.backendopt.all import backend_optimizations
backend_optimizations(self.translator)
Modified: pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/constant.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/constant.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/translator/oosupport/constant.py Wed May 27 15:52:37 2009
@@ -28,7 +28,7 @@
from pypy.rpython.ootypesystem import ootype
import operator
-MAX_CONST_PER_STEP = 100
+MAX_CONST_PER_STEP = 50
PRIMITIVE_TYPES = set([ootype.Void, ootype.Bool, ootype.Char, ootype.UniChar,
ootype.Float, ootype.Signed, ootype.Unsigned,
From cfbolz at codespeak.net Wed May 27 15:59:42 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 27 May 2009 15:59:42 +0200 (CEST)
Subject: [pypy-svn] r65456 -
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem
Message-ID: <20090527135942.ECBE5169F90@codespeak.net>
Author: cfbolz
Date: Wed May 27 15:59:42 2009
New Revision: 65456
Modified:
pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py
Log:
Be more precise about getting the type of tagged-or-normal-or-None. Gets rid of
a lot of warnings when translating.
Modified: pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py
==============================================================================
--- pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py (original)
+++ pypy/branch/tagged-pointers-framework/pypy/rpython/lltypesystem/rtagged.py Wed May 27 15:59:42 2009
@@ -81,9 +81,11 @@
vinst = llops.genop('cast_pointer', [vinst],
resulttype=self.common_repr())
if can_be_tagged:
- # XXX do we care about optimizing the case where vinst cannot
- # be None here?
- return llops.gendirectcall(ll_unboxed_getclass, vinst,
+ if can_be_none:
+ func = ll_unboxed_getclass_canbenone
+ else:
+ func = ll_unboxed_getclass
+ return llops.gendirectcall(func, vinst,
cunboxedcls)
elif can_be_none:
return llops.gendirectcall(ll_inst_type, vinst)
@@ -146,13 +148,15 @@
def ll_unboxed_to_int(p):
return lltype.cast_ptr_to_int(p) >> 1
+def ll_unboxed_getclass_canbenone(instance, class_if_unboxed):
+ if instance:
+ return ll_unboxed_getclass(instance, class_if_unboxed)
+ return lltype.nullptr(lltype.typeOf(instance).TO.typeptr.TO)
+
def ll_unboxed_getclass(instance, class_if_unboxed):
if lltype.cast_ptr_to_int(instance) & 1:
return class_if_unboxed
- elif instance:
- return instance.typeptr
- else:
- return lltype.nullptr(lltype.typeOf(instance).TO.typeptr.TO)
+ return instance.typeptr
def ll_unboxed_isinstance_const(obj, minid, maxid, answer_if_unboxed):
if not obj:
From david at codespeak.net Wed May 27 17:16:34 2009
From: david at codespeak.net (david at codespeak.net)
Date: Wed, 27 May 2009 17:16:34 +0200 (CEST)
Subject: [pypy-svn] r65457 - pypy/branch/io-lang/pypy/lang/io
Message-ID: <20090527151634.7D90C169F6B@codespeak.net>
Author: david
Date: Wed May 27 17:16:32 2009
New Revision: 65457
Modified:
pypy/branch/io-lang/pypy/lang/io/parserhack.py
Log:
Removed debug print
Modified: pypy/branch/io-lang/pypy/lang/io/parserhack.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/parserhack.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/parserhack.py Wed May 27 17:16:32 2009
@@ -10,7 +10,7 @@
child_in.write(input)
child_in.close()
s = child_out_err.read().strip()
- print s
+ # print s
return eval(s)
def interpret(code):
From david at codespeak.net Wed May 27 17:18:09 2009
From: david at codespeak.net (david at codespeak.net)
Date: Wed, 27 May 2009 17:18:09 +0200 (CEST)
Subject: [pypy-svn] r65458 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090527151809.EF862169F82@codespeak.net>
Author: david
Date: Wed May 27 17:18:09 2009
New Revision: 65458
Modified:
pypy/branch/io-lang/pypy/lang/io/list.py
pypy/branch/io-lang/pypy/lang/io/test/test_list.py
Log:
(cfbolz, david) List foreach implementation
Modified: pypy/branch/io-lang/pypy/lang/io/list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/list.py Wed May 27 17:18:09 2009
@@ -9,4 +9,31 @@
@register_method('List', 'at', unwrap_spec=[object, int])
def list_at(space, target, argument):
- return target[argument]
\ No newline at end of file
+ return target[argument]
+
+ at register_method('List', 'foreach')
+def list_foreach(space, w_target, w_message, w_context):
+ argcount = len(w_message.arguments)
+ assert argcount > 0
+
+ body = w_message.arguments[-1]
+ if argcount == 3:
+ key = w_message.arguments[0].name
+ value = w_message.arguments[1].name
+
+ for i in range(len(w_target.items)):
+ w_context.slots[key] = W_Number(space, i)
+ w_context.slots[value] = w_target.items[i]
+ t = body.eval(space, w_context, w_context)
+ elif argcount == 2:
+ value = w_message.arguments[0].name
+
+ for i in range(len(w_target.items)):
+ w_context.slots[value] = w_target.items[i]
+ t = body.eval(space, w_context, w_context)
+
+ elif argcount == 1:
+ for i in range(len(w_target.items)):
+ t = body.eval(space, w_context, w_context)
+
+ return t
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_list.py Wed May 27 17:18:09 2009
@@ -46,4 +46,29 @@
inp = 'a := list(1,2,3); a at("2")'
# Unspecified exception until error handling are introduced
assert py.test.raises(Exception, 'interpret(inp)')
-
\ No newline at end of file
+
+def test_list_foreach_key_value_returns_last():
+ inp = 'a := list(1, 2, 3); a foreach(key, value, key+value)'
+ res,space = interpret(inp)
+ assert res.value == 5
+
+def test_list_foreach_value_returns_last():
+ inp = 'c := 99; a := list(1, 2, 3); a foreach(value, c)'
+ res,space = interpret(inp)
+ assert res.value == 99
+
+def test_list_foreach_wo_args_returns_last():
+ inp = 'c := 99; a := list(1, 2, 3); a foreach(c)'
+ res,space = interpret(inp)
+ assert res.value == 99
+
+def test_list_key_value():
+ inp = 'b := list(); a := list(99, 34); a foreach(key, value, b append(list(key, value))); b'
+ res,space = interpret(inp)
+ value = [(x.items[0].value, x.items[1].value) for x in res.items]
+ assert value == [(0, 99), (1, 34)]
+
+def test_list_foreach_leaks_variables():
+ inp = 'b := list(); a := list(99, 34); a foreach(key, value, b append(list(key, value))); key+value'
+ res,space = interpret(inp)
+ assert res.value == 35
\ No newline at end of file
From david at codespeak.net Wed May 27 17:32:15 2009
From: david at codespeak.net (david at codespeak.net)
Date: Wed, 27 May 2009 17:32:15 +0200 (CEST)
Subject: [pypy-svn] r65459 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090527153215.8C4C4169EDF@codespeak.net>
Author: david
Date: Wed May 27 17:32:13 2009
New Revision: 65459
Modified:
pypy/branch/io-lang/pypy/lang/io/list.py
pypy/branch/io-lang/pypy/lang/io/model.py
pypy/branch/io-lang/pypy/lang/io/test/test_list.py
Log:
(cfbolz, david) fixed list append operation
Modified: pypy/branch/io-lang/pypy/lang/io/list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/list.py Wed May 27 17:32:13 2009
@@ -3,8 +3,8 @@
@register_method('List', 'append')
def list_append(space, w_target, w_message, w_context):
assert w_message.arguments, 'requires at least one argument'
- w_items = [x.eval(space, w_target, w_context) for x in w_message.arguments]
- w_target.append(w_items)
+ items_w = [x.eval(space, w_target, w_context) for x in w_message.arguments]
+ w_target.extend(items_w)
return w_target
@register_method('List', 'at', unwrap_spec=[object, int])
Modified: pypy/branch/io-lang/pypy/lang/io/model.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/model.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/model.py Wed May 27 17:32:13 2009
@@ -55,8 +55,8 @@
W_Object.__init__(self, space, protos)
self.items = items
- def append(self, w_items):
- self.items += w_items
+ def extend(self, items_w):
+ self.items.extend(items_w)
def __getitem__(self, index):
try:
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_list.py Wed May 27 17:32:13 2009
@@ -26,6 +26,15 @@
inp = "a := list(); a append(1)"
res,space = interpret(inp)
assert res.items == [W_Number(space, 1)]
+
+def test_list_append_multiple():
+ inp = "a := list(1,2); a append(3,4,5)"
+ res,space = interpret(inp)
+ assert res.items == [W_Number(space, 1),
+ W_Number(space, 2),
+ W_Number(space, 3),
+ W_Number(space, 4),
+ W_Number(space, 5)]
def test_list_at():
inp = "a := list(1,2,3); a at(2)"
From fijal at codespeak.net Wed May 27 18:22:56 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 18:22:56 +0200 (CEST)
Subject: [pypy-svn] r65460 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph
Message-ID: <20090527162256.2E964169F92@codespeak.net>
Author: fijal
Date: Wed May 27 18:22:55 2009
New Revision: 65460
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
Log:
ignore guard_nonvirtualized, with explanation
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/llimpl.py Wed May 27 18:22:55 2009
@@ -555,6 +555,11 @@
def op_guard_nonvirtualized(self, for_accessing_field,
value, expected_class=None):
+ # XXX
+ # We completely ignore guard_nonvirtualized
+ # right now, nobody can devirtualize a virtualizable anyway
+ # and we abuse guard_nonvirtualized for propagating properties
+ return
if expected_class is not None:
self.op_guard_class(-1, value, expected_class)
if heaptracker.cast_vable(value).vable_rti:
From fijal at codespeak.net Wed May 27 18:25:50 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 18:25:50 +0200 (CEST)
Subject: [pypy-svn] r65461 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090527162550.AD680169F98@codespeak.net>
Author: fijal
Date: Wed May 27 18:25:50 2009
New Revision: 65461
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py
Log:
Fix graphpage
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py Wed May 27 18:25:50 2009
@@ -138,7 +138,7 @@
while True:
op = operations[opindex]
lines.append(repr(op))
- if op.is_guard():
+ if op.is_guard() and op.opnum != rop.GUARD_NONVIRTUALIZED:
tgt = op.suboperations[0]
tgt_g, tgt_i = self.all_operations[tgt]
self.genedge((graphindex, opstartindex),
From fijal at codespeak.net Wed May 27 21:47:46 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 21:47:46 +0200 (CEST)
Subject: [pypy-svn] r65462 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090527194746.21EC6169F94@codespeak.net>
Author: fijal
Date: Wed May 27 21:47:39 2009
New Revision: 65462
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
kill old tests
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Wed May 27 21:47:39 2009
@@ -308,62 +308,6 @@
"""
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
expected)
-
-
- def test_remove_consecutive_guard_value_constfold(self):
- py.test.skip("not yet")
- n = BoxInt(0)
- n1 = BoxInt(1)
- n2 = BoxInt(3)
- ops = [
- ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
- ResOperation(rop.INT_ADD, [n, ConstInt(1)], n1),
- ResOperation(rop.GUARD_VALUE, [n1, ConstInt(1)], None),
- ResOperation(rop.INT_ADD, [n1, ConstInt(2)], n2),
- ]
- ops[0].suboperations = [ResOperation(rop.FAIL, [], None)]
- ops[2].suboperations = [ResOperation(rop.FAIL, [], None)]
- loop = self.newloop([n], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GUARD_VALUE, [n, ConstInt(0)], None),
- ])
-
- def test_remove_consecutive_getfields(self):
- py.test.skip("not yet")
- n1 = BoxInt()
- n2 = BoxInt()
- n3 = BoxInt()
- ops = [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n2, self.nodedescr),
- ResOperation(rop.INT_ADD, [n1, n2], n3),
- ]
- loop = self.newloop([self.nodebox], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.INT_ADD, [n1, n1], n3),
- ])
-
- def test_setfield_getfield_clean_cache(self):
- py.test.skip("not yet")
- n1 = BoxInt()
- n2 = BoxInt()
- n3 = BoxInt()
- ops = [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.SETFIELD_GC, [self.nodebox, ConstInt(3)], None, self.nodedescr),
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n2, self.nodedescr),
- ResOperation(rop.CALL, [n2], None),
- ]
- loop = self.newloop([self.nodebox], ops)
- optimize_loop(None, [], loop)
- equaloplists(loop.operations, [
- ResOperation(rop.GETFIELD_GC, [self.nodebox], n1, self.nodedescr),
- ResOperation(rop.SETFIELD_GC, [self.nodebox, ConstInt(3)], None, self.nodedescr),
- ResOperation(rop.CALL, [ConstInt(3)], None),
- ])
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
From fijal at codespeak.net Wed May 27 22:02:00 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 22:02:00 +0200 (CEST)
Subject: [pypy-svn] r65463 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090527200200.01F51169FB7@codespeak.net>
Author: fijal
Date: Wed May 27 22:02:00 2009
New Revision: 65463
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py
Log:
try to not create a new block for guard_nonvirtualized
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/graphpage.py Wed May 27 22:02:00 2009
@@ -64,7 +64,7 @@
self.block_starters[graphindex] = {0: True}
for graphindex, graph in enumerate(self.graphs):
for i, op in enumerate(graph.get_operations()):
- if op.is_guard():
+ if op.is_guard() and op.opnum != rop.GUARD_NONVIRTUALIZED:
self.mark_starter(graphindex, i+1)
def set_errmsg(self, errmsg):
From fijal at codespeak.net Wed May 27 23:27:06 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 23:27:06 +0200 (CEST)
Subject: [pypy-svn] r65464 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090527212706.6275F169FAD@codespeak.net>
Author: fijal
Date: Wed May 27 23:27:02 2009
New Revision: 65464
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
implement escape analysis (all startboxes do escape as of now)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Wed May 27 23:27:02 2009
@@ -13,7 +13,7 @@
pass
class InstanceNode(object):
- def __init__(self, source, const=False):
+ def __init__(self, source, const=False, escaped=False):
self.source = source
if const:
assert isinstance(source, Const)
@@ -24,10 +24,11 @@
self.virtualized = False
self.allocated_in_loop = False
self.vdesc = None
+ self.escaped = escaped
def __repr__(self):
flags = ''
- #if self.escaped: flags += 'e'
+ if self.escaped: flags += 'e'
#if self.startbox: flags += 's'
if self.const: flags += 'c'
#if self.virtual: flags += 'v'
@@ -41,11 +42,17 @@
def __init__(self, opts):
# NOT_RPYTHON
self.optimizations = [[] for i in range(rop._LAST)]
+ self.find_nodes_funcs = [[] for i in range(rop._LAST)]
for opt in opts:
for opnum, name in opname.iteritems():
meth = getattr(opt, 'optimize_' + name.lower(), None)
if meth is not None:
self.optimizations[opnum].append(meth)
+ for opt in opts:
+ for opnum, name in opname.iteritems():
+ meth = getattr(opt, 'find_nodes_' + name.lower(), None)
+ if meth is not None:
+ self.find_nodes_funcs[opnum].append(meth)
def getnode(self, box):
try:
@@ -54,7 +61,7 @@
if isinstance(box, Const):
node = InstanceNode(box, const=True)
else:
- node = InstanceNode(box)
+ node = InstanceNode(box, escaped=True)
self.nodes[box] = node
return node
@@ -65,6 +72,13 @@
def find_nodes(self):
for op in self.loop.operations:
+ res = False
+ for f in self.find_nodes_funcs[op.opnum]:
+ res = f(op, self)
+ if res:
+ break
+ if res:
+ continue
if op.is_always_pure():
is_pure = True
for arg in op.args:
@@ -81,10 +95,13 @@
self.getnode(arg)
# default case
for box in op.args:
- self.getnode(box)
+ node = self.getnode(box)
+ if not op.has_no_side_effect() and not op.is_guard():
+ node.escaped = True
box = op.result
if box is not None:
node = self.getnode(box)
+ node.escaped = False
if op.opnum == rop.NEW or op.opnum == rop.NEW_WITH_VTABLE:
node.allocated_in_loop = True
self.nodes[box] = node
@@ -190,11 +207,40 @@
class SimpleVirtualizableOpt(object):
@staticmethod
- def optimize_guard_nonvirtualized(op, spec):
+ def find_nodes_setfield_gc(op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtualized:
+ return False
+ field = op.descr
+ if field not in instnode.vdesc.virtuals:
+ return False
+ return True
+
+ @staticmethod
+ def find_nodes_getfield_gc(op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtualized:
+ return False
+ field = op.descr
+ if field not in instnode.vdesc.virtuals:
+ return False
+ spec.getnode(op.result).virtualized = True
+ return False
+
+ @staticmethod
+ def find_nodes_setarrayitem_gc(op, spec):
+ return False
+
+ @staticmethod
+ def find_nodes_guard_nonvirtualized(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.allocated_in_loop:
instnode.virtualized = True
instnode.vdesc = op.vdesc
+ return False
+
+ @staticmethod
+ def optimize_guard_nonvirtualized(op, spec):
return True
@staticmethod
@@ -210,7 +256,6 @@
spec.nodes[op.result] = node
return True
node = spec.getnode(op.result)
- node.virtualized = True
instnode.cleanfields[field] = node
return False
@@ -260,6 +305,12 @@
d[field] = (fieldnode, op.descr)
return True
+class SimpleVirtualOpt(object):
+ def optimize_new_with_vtable(op, spec):
+ xxx
+ node = spec.getnode(op.result)
+ node.escaped = False
+
specializer = Specializer([SimpleVirtualizableOpt(),
ConsecutiveGuardClassRemoval()])
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Wed May 27 23:27:02 2009
@@ -9,7 +9,8 @@
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp.optimize2 import (optimize_loop,
- ConsecutiveGuardClassRemoval, Specializer, SimpleVirtualizableOpt)
+ ConsecutiveGuardClassRemoval, Specializer, SimpleVirtualizableOpt,
+ SimpleVirtualOpt)
from pypy.jit.metainterp.test.test_optimize import ANY
from pypy.jit.metainterp.test.oparser import parse
@@ -309,6 +310,72 @@
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
expected)
+ def test_escape_analysis(self):
+ ops = """
+ [i0]
+ i1 = int_add(i0, i0)
+ """
+ spec = Specializer([])
+ loop = self.parse(ops)
+ optimize_loop(None, [], loop, self.cpu, spec=spec)
+ assert spec.nodes[loop.operations[0].args[0]].escaped
+ ops = """
+ [p0]
+ i1 = getfield_gc(p0, descr=field_desc)
+ i2 = int_add(i1, i1)
+ """
+ spec = Specializer([])
+ loop = self.parse(ops)
+ optimize_loop(None, [], loop, self.cpu, spec=spec)
+ assert not spec.nodes[loop.operations[0].result].escaped
+ ops = """
+ [p0]
+ i1 = getfield_gc(p0, descr=field_desc)
+ fail(i1)
+ """
+ spec = Specializer([])
+ loop = self.parse(ops)
+ optimize_loop(None, [], loop, self.cpu, spec=spec)
+ assert spec.nodes[loop.operations[0].result].escaped
+ ops = """
+ [p0]
+ i1 = getfield_gc(p0, descr=field_desc)
+ guard_true(i1)
+ fail()
+ """
+ spec = Specializer([])
+ loop = self.parse(ops)
+ optimize_loop(None, [], loop, self.cpu, spec=spec)
+ assert not spec.nodes[loop.operations[0].result].escaped
+
+ def test_escape_analysis_on_virtualizable(self):
+ ops = """
+ [p0]
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ i1 = getfield_gc(p0, descr=field_desc)
+ setfield_gc(p0, i1, descr=field_desc)
+ i2 = int_add(i1, i1)
+ """
+ spec = Specializer([SimpleVirtualizableOpt()])
+ loop = self.parse(ops)
+ optimize_loop(None, [], loop, self.cpu, spec=spec)
+ assert not spec.nodes[loop.operations[0].result].escaped
+
+# def test_simple_virtual(self):
+# pre_op = """
+# []
+# p0 = new_with_vtable(13, ConstClass(node_vtable))
+# setfield_gc(p0, 1, descr=field_desc)
+# i2 = getfield_gc(p0, descr=field_desc)
+# fail(i2)
+# """
+# expected = """
+# []
+# fail(1)
+# """
+# self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
+# expected)
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
pass
From fijal at codespeak.net Wed May 27 23:53:51 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 27 May 2009 23:53:51 +0200 (CEST)
Subject: [pypy-svn] r65465 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090527215351.8A87B169FC1@codespeak.net>
Author: fijal
Date: Wed May 27 23:53:49 2009
New Revision: 65465
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
a super-basic virtual
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Wed May 27 23:53:49 2009
@@ -25,13 +25,14 @@
self.allocated_in_loop = False
self.vdesc = None
self.escaped = escaped
+ self.virtual = False
def __repr__(self):
flags = ''
if self.escaped: flags += 'e'
#if self.startbox: flags += 's'
if self.const: flags += 'c'
- #if self.virtual: flags += 'v'
+ if self.virtual: flags += 'v'
if self.virtualized: flags += 'V'
return "" % (self.source, flags)
@@ -94,9 +95,17 @@
for arg in op.suboperations[0].args:
self.getnode(arg)
# default case
+ nodes = []
for box in op.args:
- node = self.getnode(box)
- if not op.has_no_side_effect() and not op.is_guard():
+ nodes.append(self.getnode(box))
+ if op.has_no_side_effect() or op.is_guard():
+ pass
+ elif (op.opnum in [rop.SETFIELD_GC, rop.SETFIELD_RAW,
+ rop.SETARRAYITEM_GC]):
+ for i in range(1, len(nodes)):
+ nodes[i].escaped = True
+ else:
+ for node in nodes:
node.escaped = True
box = op.result
if box is not None:
@@ -306,10 +315,32 @@
return True
class SimpleVirtualOpt(object):
+ @staticmethod
def optimize_new_with_vtable(op, spec):
- xxx
node = spec.getnode(op.result)
- node.escaped = False
+ if node.escaped:
+ return False
+ node.virtual = True
+ return True
+
+ @staticmethod
+ def optimize_setfield_gc(op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtual:
+ return False
+ field = op.descr
+ node = spec.getnode(op.args[1])
+ instnode.cleanfields[field] = node
+ return True
+
+ @staticmethod
+ def optimize_getfield_gc(op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtual:
+ return False
+ field = op.descr
+ spec.nodes[op.result] = instnode.cleanfields[field]
+ return True
specializer = Specializer([SimpleVirtualizableOpt(),
ConsecutiveGuardClassRemoval()])
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Wed May 27 23:53:49 2009
@@ -362,20 +362,20 @@
optimize_loop(None, [], loop, self.cpu, spec=spec)
assert not spec.nodes[loop.operations[0].result].escaped
-# def test_simple_virtual(self):
-# pre_op = """
-# []
-# p0 = new_with_vtable(13, ConstClass(node_vtable))
-# setfield_gc(p0, 1, descr=field_desc)
-# i2 = getfield_gc(p0, descr=field_desc)
-# fail(i2)
-# """
-# expected = """
-# []
-# fail(1)
-# """
-# self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
-# expected)
+ def test_simple_virtual(self):
+ pre_op = """
+ []
+ p0 = new_with_vtable(13, ConstClass(node_vtable))
+ setfield_gc(p0, 1, descr=field_desc)
+ i2 = getfield_gc(p0, descr=field_desc)
+ fail(i2)
+ """
+ expected = """
+ []
+ fail(1)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
+ expected)
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
pass
From antocuni at codespeak.net Thu May 28 00:09:53 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 00:09:53 +0200 (CEST)
Subject: [pypy-svn] r65466 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090527220953.9445C169FB1@codespeak.net>
Author: antocuni
Date: Thu May 28 00:09:53 2009
New Revision: 65466
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py
Log:
ops, TestOptimize2 was not meant to be checked in. Anyway, some tests pass, skip the other that are failing
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py Thu May 28 00:09:53 2009
@@ -625,3 +625,12 @@
from pypy.jit.metainterp.optimize2 import Optimizer
kwds['optimizer'] = Optimizer
return LLJitMixin.meta_interp(self, *args, **kwds)
+
+ def skip(self):
+ py.test.skip('in-progress')
+
+ test_simple_implicit = skip
+ test_virtual_on_virtualizable = skip
+ test_no_virtual_on_virtualizable = skip
+ test_virtualizable_hierarchy = skip
+ test_non_virtual_on_always_virtual = skip
From antocuni at codespeak.net Thu May 28 00:12:07 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 00:12:07 +0200 (CEST)
Subject: [pypy-svn] r65467 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090527221207.6E974169E6C@codespeak.net>
Author: antocuni
Date: Thu May 28 00:12:06 2009
New Revision: 65467
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py
Log:
test ootype too
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_virtualizable.py Thu May 28 00:12:06 2009
@@ -619,7 +619,7 @@
pass
-class TestOptimize2(ImplicitVirtualizableTests, LLJitMixin):
+class TestOptimize2LLtype(ImplicitVirtualizableTests, LLJitMixin):
def meta_interp(self, *args, **kwds):
from pypy.jit.metainterp.optimize2 import Optimizer
@@ -634,3 +634,20 @@
test_no_virtual_on_virtualizable = skip
test_virtualizable_hierarchy = skip
test_non_virtual_on_always_virtual = skip
+
+
+class TestOptimize2OOtype(ImplicitVirtualizableTests, OOJitMixin):
+
+ def meta_interp(self, *args, **kwds):
+ from pypy.jit.metainterp.optimize2 import Optimizer
+ kwds['optimizer'] = Optimizer
+ return OOJitMixin.meta_interp(self, *args, **kwds)
+
+ def skip(self):
+ py.test.skip('in-progress')
+
+ test_simple_implicit = skip
+ test_virtual_on_virtualizable = skip
+ test_no_virtual_on_virtualizable = skip
+ test_virtualizable_hierarchy = skip
+ test_non_virtual_on_always_virtual = skip
From fijal at codespeak.net Thu May 28 00:20:59 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 28 May 2009 00:20:59 +0200 (CEST)
Subject: [pypy-svn] r65468 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090527222059.3927E169FB1@codespeak.net>
Author: fijal
Date: Thu May 28 00:20:58 2009
New Revision: 65468
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
a test and a fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Thu May 28 00:20:58 2009
@@ -238,7 +238,10 @@
@staticmethod
def find_nodes_setarrayitem_gc(op, spec):
- return False
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtualized:
+ return False
+ return True
@staticmethod
def find_nodes_guard_nonvirtualized(op, spec):
@@ -343,6 +346,7 @@
return True
specializer = Specializer([SimpleVirtualizableOpt(),
+ SimpleVirtualOpt(),
ConsecutiveGuardClassRemoval()])
def optimize_loop(options, old_loops, loop, cpu=None, spec=specializer):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Thu May 28 00:20:58 2009
@@ -59,16 +59,19 @@
nodedescr = cpu.fielddescrof(NODE, 'value')
TP = lltype.GcArray(lltype.Signed)
+ NODE_ARRAY = lltype.GcArray(lltype.Ptr(NODE))
XY = lltype.GcStruct('XY', ('parent', OBJECT),
('inst_field', lltype.Signed),
('inst_other_field', lltype.Signed),
('inst_list', lltype.Ptr(TP)),
+ ('inst_item_list', lltype.Ptr(NODE_ARRAY)),
hints= {'virtualizable2': True,
- 'virtuals': ('field','list')})
+ 'virtuals': ('field','list', 'item_list')})
field_desc = cpu.fielddescrof(XY, 'inst_field')
array_descr = cpu.arraydescrof(TP)
list_desc = cpu.fielddescrof(XY, 'inst_list')
+ list_node_desc = cpu.fielddescrof(XY, 'inst_item_list')
other_field_desc = cpu.fielddescrof(XY, 'inst_other_field')
vdesc = VirtualizableDesc(cpu, XY, XY)
xy_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
@@ -377,8 +380,31 @@
self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
expected)
+ def test_virtual_with_virtualizable(self):
+ pre_op = """
+ [p0]
+ p1 = new_with_vtable(13, ConstClass(node_vtable))
+ setfield_gc(p1, 1, descr=nodedescr)
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ p2 = getfield_gc(p0, descr=list_node_desc)
+ setarrayitem_gc(p2, 0, p1)
+ p3 = getarrayitem_gc(p2, 0)
+ i3 = getfield_gc(p3, descr=nodedescr)
+ fail(i3)
+ """
+ expected = """
+ [p0]
+ p2 = getfield_gc(p0, descr=list_node_desc)
+ fail(1)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt(),
+ SimpleVirtualOpt()]),
+ expected)
+
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
- pass
+ def test_virtual_with_virtualizable(self):
+ py.test.skip("XXX")
From benjamin at codespeak.net Thu May 28 00:34:14 2009
From: benjamin at codespeak.net (benjamin at codespeak.net)
Date: Thu, 28 May 2009 00:34:14 +0200 (CEST)
Subject: [pypy-svn] r65469 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090527223414.83CC5169FB7@codespeak.net>
Author: benjamin
Date: Thu May 28 00:34:10 2009
New Revision: 65469
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
Log:
when somebody tries to use this on Windows, they'll thank me
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/oparser.py Thu May 28 00:34:10 2009
@@ -124,7 +124,7 @@
return self.parse_op_no_result(line)
def parse(self):
- lines = self.descr.split("\n")
+ lines = self.descr.splitlines()
ops = []
newlines = []
for line in lines:
From fijal at codespeak.net Thu May 28 00:36:40 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 28 May 2009 00:36:40 +0200 (CEST)
Subject: [pypy-svn] r65470 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090527223640.7B64E169FC0@codespeak.net>
Author: fijal
Date: Thu May 28 00:36:39 2009
New Revision: 65470
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
rebuild ops. Needs more tests
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Thu May 28 00:36:39 2009
@@ -26,6 +26,7 @@
self.vdesc = None
self.escaped = escaped
self.virtual = False
+ self.size = 0
def __repr__(self):
flags = ''
@@ -131,6 +132,16 @@
gop.suboperations = [ResOperation(rop.FAIL, [], None)]
return gop
+ def rebuild_virtual(self, ops, node):
+ assert node.virtual
+ ops.append(ResOperation(rop.NEW_WITH_VTABLE, [node.size, node.cls],
+ node.source))
+ for field, valuenode in node.cleanfields.iteritems():
+ if valuenode.virtual:
+ self.rebuild_virtual(ops, valuenode)
+ ops.append(ResOperation(rop.SETFIELD_GC,
+ [node.source, valuenode.source], None, field))
+
def optimize_guard(self, op):
if op.is_foldable_guard():
for arg in op.args:
@@ -140,12 +151,19 @@
return None
assert len(op.suboperations) == 1
op_fail = op.suboperations[0]
+ op.suboperations = []
+ self.already_build_nodes = {}
+ for arg in op_fail.args:
+ node = self.getnode(arg)
+ if node.virtual:
+ self.rebuild_virtual(op.suboperations, node)
op_fail.args = self.new_arguments(op_fail)
# modification in place. Reason for this is explained in mirror
# in optimize.py
- op.suboperations = []
for node, d in self.additional_stores.iteritems():
for field, fieldnode in d.iteritems():
+ if fieldnode.virtual:
+ self.rebuild_virtual(op.suboperations, fieldnode)
gop = self._guard_for_node(node)
op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETFIELD_GC,
@@ -153,6 +171,8 @@
for node, d in self.additional_setarrayitems.iteritems():
for field, (fieldnode, descr) in d.iteritems():
box = fieldnode.source
+ if fieldnode.virtual:
+ self.rebuild_virtual(op.suboperations, fieldnode)
gop = self._guard_for_node(node)
op.suboperations.append(gop)
op.suboperations.append(ResOperation(rop.SETARRAYITEM_GC,
@@ -324,6 +344,8 @@
if node.escaped:
return False
node.virtual = True
+ node.cls = op.args[1]
+ node.size = op.args[0]
return True
@staticmethod
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Thu May 28 00:36:39 2009
@@ -402,6 +402,24 @@
SimpleVirtualOpt()]),
expected)
+ def test_rebuild_ops(self):
+ pre_op = """
+ [i1]
+ p1 = new_with_vtable(13, ConstClass(node_vtable))
+ setfield_gc(p1, 1, descr=field_desc)
+ guard_true(i1)
+ fail(p1)
+ """
+ expected = """
+ [i1]
+ guard_true(i1)
+ p1 = new_with_vtable(13, ConstClass(node_vtable))
+ setfield_gc(p1, 1, descr=field_desc)
+ fail(p1)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
+ expected)
+
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
pass
From benjamin at codespeak.net Thu May 28 00:50:33 2009
From: benjamin at codespeak.net (benjamin at codespeak.net)
Date: Thu, 28 May 2009 00:50:33 +0200 (CEST)
Subject: [pypy-svn] r65471 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090527225033.9ED72169F91@codespeak.net>
Author: benjamin
Date: Thu May 28 00:50:32 2009
New Revision: 65471
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
drill more int operations for constant folding
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Thu May 28 00:50:32 2009
@@ -3,7 +3,7 @@
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
-from pypy.jit.metainterp.resoperation import rop, ResOperation
+from pypy.jit.metainterp.resoperation import rop, ResOperation, opname
from pypy.jit.metainterp.history import ConstAddr, BoxPtr, TreeLoop,\
ConstInt, BoxInt, BoxObj, ConstObj
from pypy.jit.backend.llgraph import runner
@@ -131,13 +131,18 @@
equaloplists(optimized, self.parse(expected).operations)
def test_basic_constant_folding(self):
- pre_op = """
- []
- i1 = int_add(3, 2)
- """
- expected = "[]"
- self.assert_equal(self.optimize(pre_op), expected)
-
+ for op in range(rop.INT_ADD, rop._COMPARISON_FIRST):
+ try:
+ op = opname[op]
+ except KeyError:
+ continue
+ pre_op = """
+ []
+ i1 = %s(3, 2)
+ """ % op.lower()
+ expected = "[]"
+ self.assert_equal(self.optimize(pre_op), expected)
+
def test_remove_guard_class(self):
pre_op = """
[p0]
From fijal at codespeak.net Thu May 28 00:53:44 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 28 May 2009 00:53:44 +0200 (CEST)
Subject: [pypy-svn] r65472 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090527225344.1A3A8169F91@codespeak.net>
Author: fijal
Date: Thu May 28 00:53:43 2009
New Revision: 65472
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
oops, make this more real world
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Thu May 28 00:53:43 2009
@@ -134,8 +134,8 @@
def rebuild_virtual(self, ops, node):
assert node.virtual
- ops.append(ResOperation(rop.NEW_WITH_VTABLE, [node.size, node.cls],
- node.source))
+ ops.append(ResOperation(rop.NEW_WITH_VTABLE, [node.cls],
+ node.source, node.size))
for field, valuenode in node.cleanfields.iteritems():
if valuenode.virtual:
self.rebuild_virtual(ops, valuenode)
@@ -344,8 +344,8 @@
if node.escaped:
return False
node.virtual = True
- node.cls = op.args[1]
- node.size = op.args[0]
+ node.cls = op.args[0]
+ node.size = op.descr
return True
@staticmethod
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Thu May 28 00:53:43 2009
@@ -57,6 +57,7 @@
node = lltype.malloc(NODE)
nodebox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, node))
nodedescr = cpu.fielddescrof(NODE, 'value')
+ nodesize = cpu.sizeof(NODE)
TP = lltype.GcArray(lltype.Signed)
NODE_ARRAY = lltype.GcArray(lltype.Ptr(NODE))
@@ -93,6 +94,7 @@
node = ootype.new(NODE)
nodebox = BoxObj(ootype.cast_to_object(node))
nodedescr = cpu.fielddescrof(NODE, 'value')
+ nodesize = cpu.sizeof(node)
TP = ootype.Array(ootype.Signed)
@@ -305,14 +307,14 @@
def test_newly_allocated_virtualizable_is_not_virtualized(self):
pre_op = """
[]
- p0 = new_with_vtable(13, ConstClass(xy_vtable))
+ p0 = new_with_vtable(ConstClass(xy_vtable))
guard_nonvirtualized(p0, vdesc=vdesc)
fail()
setfield_gc(p0, 3, descr=field_desc)
"""
expected = """
[]
- p0 = new_with_vtable(13, ConstClass(xy_vtable))
+ p0 = new_with_vtable(ConstClass(xy_vtable))
setfield_gc(p0, 3, descr=field_desc)
"""
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt()]),
@@ -373,7 +375,7 @@
def test_simple_virtual(self):
pre_op = """
[]
- p0 = new_with_vtable(13, ConstClass(node_vtable))
+ p0 = new_with_vtable(ConstClass(node_vtable))
setfield_gc(p0, 1, descr=field_desc)
i2 = getfield_gc(p0, descr=field_desc)
fail(i2)
@@ -388,7 +390,7 @@
def test_virtual_with_virtualizable(self):
pre_op = """
[p0]
- p1 = new_with_vtable(13, ConstClass(node_vtable))
+ p1 = new_with_vtable(ConstClass(node_vtable))
setfield_gc(p1, 1, descr=nodedescr)
guard_nonvirtualized(p0, vdesc=vdesc)
fail()
@@ -410,7 +412,7 @@
def test_rebuild_ops(self):
pre_op = """
[i1]
- p1 = new_with_vtable(13, ConstClass(node_vtable))
+ p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
setfield_gc(p1, 1, descr=field_desc)
guard_true(i1)
fail(p1)
@@ -418,7 +420,7 @@
expected = """
[i1]
guard_true(i1)
- p1 = new_with_vtable(13, ConstClass(node_vtable))
+ p1 = new_with_vtable(ConstClass(node_vtable), descr=nodesize)
setfield_gc(p1, 1, descr=field_desc)
fail(p1)
"""
From fijal at codespeak.net Thu May 28 02:04:17 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 28 May 2009 02:04:17 +0200 (CEST)
Subject: [pypy-svn] r65473 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090528000417.D3325169FC5@codespeak.net>
Author: fijal
Date: Thu May 28 02:04:15 2009
New Revision: 65473
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
a next test to fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Thu May 28 02:04:15 2009
@@ -20,6 +20,7 @@
self.const = const
self.cls = None
self.cleanfields = {}
+ self.origfields = {}
self.arrayfields = {}
self.virtualized = False
self.allocated_in_loop = False
@@ -253,7 +254,8 @@
field = op.descr
if field not in instnode.vdesc.virtuals:
return False
- spec.getnode(op.result).virtualized = True
+ node = spec.getnode(op.result)
+ node.virtualized = True
return False
@staticmethod
@@ -270,7 +272,7 @@
instnode.virtualized = True
instnode.vdesc = op.vdesc
return False
-
+
@staticmethod
def optimize_guard_nonvirtualized(op, spec):
return True
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Thu May 28 02:04:15 2009
@@ -427,9 +427,36 @@
self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
expected)
+
+ def test_virtual_with_virtualizable_escapes(self):
+ py.test.skip("FIXME")
+ pre_op = """
+ [p0]
+ p1 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p1, 1, descr=nodedescr)
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ p2 = getfield_gc(p0, descr=list_node_desc)
+ setarrayitem_gc(p2, 0, p1)
+ p3 = getarrayitem_gc(p2, 0)
+ fail(p3)
+ """
+ expected = """
+ [p0]
+ p1 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p1, 1, descr=nodedescr)
+ p2 = getfield_gc(p0, descr=list_node_desc)
+ fail(p1)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt(),
+ SimpleVirtualOpt()]),
+ expected)
+
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
def test_virtual_with_virtualizable(self):
py.test.skip("XXX")
+
+ test_virtual_with_virtualizable_escapes = test_virtual_with_virtualizable
From antocuni at codespeak.net Thu May 28 11:12:43 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 11:12:43 +0200 (CEST)
Subject: [pypy-svn] r65474 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090528091243.10A57169FEA@codespeak.net>
Author: antocuni
Date: Thu May 28 11:12:43 2009
New Revision: 65474
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py
Log:
enhance the repr of ootype.Class objects
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/history.py Thu May 28 11:12:43 2009
@@ -46,14 +46,15 @@
def repr_object(box):
try:
- if box.value.obj._TYPE is ootype.String:
+ TYPE = box.value.obj._TYPE
+ if TYPE is ootype.String:
return '(%r)' % box.value.obj._str
- if isinstance(box.value.obj._TYPE, ootype.StaticMethod):
+ if TYPE is ootype.Class or isinstance(TYPE, ootype.StaticMethod):
return '(%r)' % box.value.obj
if isinstance(box.value.obj, ootype._view):
return repr(box.value.obj._inst._TYPE)
else:
- return repr(box.value.obj._TYPE)
+ return repr(TYPE)
except AttributeError:
return box.value
From antocuni at codespeak.net Thu May 28 11:54:11 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 11:54:11 +0200 (CEST)
Subject: [pypy-svn] r65475 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph: . test
Message-ID: <20090528095411.68457169FE1@codespeak.net>
Author: antocuni
Date: Thu May 28 11:54:10 2009
New Revision: 65475
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/test/test_llgraph.py
Log:
make sure that you return the always same descr for fields defined in the superclasses
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/runner.py Thu May 28 11:54:10 2009
@@ -402,7 +402,9 @@
@staticmethod
def fielddescrof(T, fieldname):
- return FieldDescr.new(T, fieldname)
+ # use class where the field is really defined as a key
+ T1, _ = T._lookup_field(fieldname)
+ return FieldDescr.new(T1, fieldname)
@staticmethod
def calldescrof(FUNC, ARGS, RESULT):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/test/test_llgraph.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/test/test_llgraph.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llgraph/test/test_llgraph.py Thu May 28 11:54:10 2009
@@ -224,3 +224,13 @@
## these tests never worked
## class TestOOTypeLLGraph(LLGraphTest):
## from pypy.jit.backend.llgraph.runner import OOtypeCPU as cpu_type
+
+def test_fielddescr_ootype():
+ from pypy.rpython.ootypesystem import ootype
+ from pypy.jit.backend.llgraph.runner import OOtypeCPU
+ A = ootype.Instance("A", ootype.ROOT, {"foo": ootype.Signed})
+ B = ootype.Instance("B", A)
+ cpu = OOtypeCPU(None)
+ descr1 = cpu.fielddescrof(A, "foo")
+ descr2 = cpu.fielddescrof(B, "foo")
+ assert descr1 is descr2
From david at codespeak.net Thu May 28 13:41:00 2009
From: david at codespeak.net (david at codespeak.net)
Date: Thu, 28 May 2009 13:41:00 +0200 (CEST)
Subject: [pypy-svn] r65476 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090528114100.2C1EF169FE1@codespeak.net>
Author: david
Date: Thu May 28 13:40:58 2009
New Revision: 65476
Modified:
pypy/branch/io-lang/pypy/lang/io/object.py
pypy/branch/io-lang/pypy/lang/io/test/test_object.py
Log:
Added Object substract which returns negative version of a given number
Modified: pypy/branch/io-lang/pypy/lang/io/object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/object.py Thu May 28 13:40:58 2009
@@ -1,5 +1,5 @@
from pypy.lang.io.register import register_method
-from pypy.lang.io.model import W_ImmutableSequence, W_Block
+from pypy.lang.io.model import W_ImmutableSequence, W_Block, W_Number
@register_method('Object', 'setSlot', unwrap_spec=[object, str, object])
def w_object_set_slot(space, w_target, name, w_value):
@@ -61,4 +61,8 @@
@register_method('Object', 'message')
def object_message(space, w_target, w_message, w_context):
- return w_message.arguments[0]
\ No newline at end of file
+ return w_message.arguments[0]
+
+ at register_method('Object', '-', unwrap_spec=[object, float])
+def object_minus(space, w_target, argument):
+ return W_Number(space, -argument)
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_object.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_object.py Thu May 28 13:40:58 2009
@@ -43,4 +43,12 @@
inp = 'message(foo)'
res, space = interpret(inp)
assert isinstance(res, W_Message)
- assert res.name == 'foo'
\ No newline at end of file
+ assert res.name == 'foo'
+
+def test_object_substract():
+ inp = '-1'
+ res, space = interpret(inp)
+ assert res.value == -1
+
+ inp = '-"a"'
+ py.test.raises(Exception, "interpret(inp)")
\ No newline at end of file
From david at codespeak.net Thu May 28 13:59:06 2009
From: david at codespeak.net (david at codespeak.net)
Date: Thu, 28 May 2009 13:59:06 +0200 (CEST)
Subject: [pypy-svn] r65477 - pypy/branch/io-lang/pypy/lang/io
Message-ID: <20090528115906.6B8C1169FE0@codespeak.net>
Author: david
Date: Thu May 28 13:59:05 2009
New Revision: 65477
Modified:
pypy/branch/io-lang/pypy/lang/io/register.py
Log:
add option to pass a list of aliases for a method name
Modified: pypy/branch/io-lang/pypy/lang/io/register.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/register.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/register.py Thu May 28 13:59:05 2009
@@ -1,7 +1,13 @@
from pypy.lang.io import model
cfunction_definitions = {}
-def register_method(type_name, slot_name, unwrap_spec=None):
+def register_method(type_name, slot_name, unwrap_spec=None, alias=None):
+ if alias is None:
+ alias = [slot_name]
+ else:
+ alias.append(slot_name)
+
def register(function):
+
if unwrap_spec is None:
wrapper = function
else:
@@ -34,7 +40,10 @@
raise ValueError, 'Unknown unwrap spec'
return function(space, *args)
subdict = cfunction_definitions.setdefault(type_name, {})
- subdict[slot_name] = wrapper
+
+
+ for slotn in alias:
+ subdict[slotn] = wrapper
return function
From david at codespeak.net Thu May 28 14:20:39 2009
From: david at codespeak.net (david at codespeak.net)
Date: Thu, 28 May 2009 14:20:39 +0200 (CEST)
Subject: [pypy-svn] r65478 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090528122039.928C3169FF9@codespeak.net>
Author: david
Date: Thu May 28 14:20:38 2009
New Revision: 65478
Modified:
pypy/branch/io-lang/pypy/lang/io/number.py
pypy/branch/io-lang/pypy/lang/io/test/test_number.py
Log:
Some Number built-method (mod, ceil, floor, round, pow)
Modified: pypy/branch/io-lang/pypy/lang/io/number.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/number.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/number.py Thu May 28 14:20:38 2009
@@ -1,3 +1,4 @@
+from math import ceil, floor
from pypy.lang.io.register import register_method
from pypy.lang.io.model import W_Number
@@ -7,4 +8,32 @@
@register_method("Number", '-', unwrap_spec=[float, float])
def w_number_minus(space, target, argument):
- return W_Number(space, target - argument)
\ No newline at end of file
+ return W_Number(space, target - argument)
+
+ at register_method('Number', '%', unwrap_spec=[float, float], alias=['mod'])
+def w_number_modulo(space, target, argument):
+ argument = abs(argument)
+ return W_Number(space, target % argument)
+
+ at register_method('Number', '**', unwrap_spec=[float, float], alias=['pow'])
+def w_number_modulo(space, target, argument):
+ return W_Number(space, target ** argument)
+
+ at register_method('Number', 'ceil', unwrap_spec=[float])
+def w_number_modulo(space, target):
+ return W_Number(space, ceil(target))
+
+ at register_method('Number', 'floor', unwrap_spec=[float])
+def w_number_modulo(space, target):
+ return W_Number(space, floor(target))
+
+ at register_method('Number', 'round', unwrap_spec=[float])
+def w_number_modulo(space, target):
+ if target < 0:
+ n = ceil(target - 0.5)
+ else:
+ n = floor(target + 0.5)
+
+ return W_Number(space, n)
+
+
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_number.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_number.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_number.py Thu May 28 14:20:38 2009
@@ -29,3 +29,93 @@
res, space = interpret(inp)
assert res.value == 8
+def test_modulo_int_int():
+ inp = '5 % 3'
+ res, space = interpret(inp)
+ assert res.value == 2
+
+def test_modulo_int_float():
+ inp = '5 % 3.2'
+ res, space = interpret(inp)
+ assert res.value == 1.7999999999999998
+
+def test_module_float_float():
+ inp = '5.3 % 3.2'
+ res, space = interpret(inp)
+ assert res.value == 2.0999999999999996
+
+def test_modulo_neg_int_int():
+ inp = '-8 % 3'
+ res, space = interpret(inp)
+ assert res.value == -2
+
+def test_modulo_int_neg_int():
+ inp = '8 % -3'
+ res, space = interpret(inp)
+ assert res.value == 2
+
+def test_modulo_int_neg_int_neg():
+ inp = '-8 % -3'
+ res, space = interpret(inp)
+ assert res.value == -2
+
+def test_modulo_float_float():
+ inp = '8.3 % 3.2'
+ res, space = interpret(inp)
+ assert res.value == 1.9000000000000004
+
+def test_modulo_neg_float_float():
+ inp = '-8.3 % 3.2'
+ res, space = interpret(inp)
+ assert res.value == -1.9000000000000004
+
+def test_modulo_float_neg_float():
+ inp = '8.3 % -3.2'
+ res, space = interpret(inp)
+ assert res.value == 1.9000000000000004
+
+def test_modulo_neg_float_neg_float():
+ inp = '-8.3 % -3.2'
+ res, space = interpret(inp)
+ assert res.value == -1.9000000000000004
+
+def test_alias_modulo():
+ inp = '-8.3 mod(-3.2)'
+ res, space = interpret(inp)
+ assert res.value == -1.9000000000000004
+
+def test_pow():
+ inp1 = '5 ** -2.2'
+ inp2 = '5 pow(-2.2)'
+ res1, space = interpret(inp1)
+ res2, space = interpret(inp2)
+ assert res1.value >= 0.0289911865471078 \
+ and res1.value <= 0.0289911865471079 \
+ and res2.value == res1.value
+
+def test_ceil():
+ inp = '3.3 ceil'
+ res, space = interpret(inp)
+ assert res.value == 4
+
+def test_floor():
+ inp = '3.9 floor'
+ res, space = interpret(inp)
+ assert res.value == 3
+
+def test_round():
+ inp = '3.3 round'
+ res, space = interpret(inp)
+ assert res.value == 3
+
+ inp = '3.7 round'
+ res, space = interpret(inp)
+ assert res.value == 4
+
+ inp = '3.5 round'
+ res, space = interpret(inp)
+ assert res.value == 4
+
+ inp = '-3.4 round'
+ res, space = interpret(inp)
+ assert res.value == -3
\ No newline at end of file
From david at codespeak.net Thu May 28 15:00:22 2009
From: david at codespeak.net (david at codespeak.net)
Date: Thu, 28 May 2009 15:00:22 +0200 (CEST)
Subject: [pypy-svn] r65479 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090528130022.B7741169F8A@codespeak.net>
Author: david
Date: Thu May 28 15:00:20 2009
New Revision: 65479
Modified:
pypy/branch/io-lang/pypy/lang/io/list.py
pypy/branch/io-lang/pypy/lang/io/test/test_list.py
Log:
Implemented some built-in operations on lists (with, indexOf, contains, size, first)
Modified: pypy/branch/io-lang/pypy/lang/io/list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/list.py Thu May 28 15:00:20 2009
@@ -36,4 +36,49 @@
for i in range(len(w_target.items)):
t = body.eval(space, w_context, w_context)
- return t
\ No newline at end of file
+ return t
+
+ at register_method('List', 'with')
+def list_with(space, w_target, w_message, w_context):
+ new_w_list = w_target.clone()
+ items_w = [x.eval(space, w_target, w_context) for x in w_message.arguments]
+ new_w_list.extend(items_w)
+ return new_w_list
+
+# TODO: Not sure if this is rpython
+ at register_method('List', 'indexOf', unwrap_spec=[object, object])
+def list_index_of(space, w_target, item):
+ try:
+ return W_Number(space, w_target.items.index(item))
+ except ValueError, e:
+ return space.w_nil
+
+# TODO: Not sure if this is rpython
+ at register_method('List', 'contains', unwrap_spec=[object, object])
+def list_contains(space, w_target, item):
+ if item in w_target.items:
+ return space.w_true
+ return space.w_false
+
+ at register_method('List', 'size')
+def list_size(space, w_target, w_message, w_context):
+ return W_Number(space, len(w_target.items))
+
+ at register_method('List', 'first')
+def list_size(space, w_target, w_message, w_context):
+ if len(w_message.arguments) != 0:
+ t = w_message.arguments[0].eval(space, w_target, w_context)
+ assert isinstance(t, W_Number)
+ nfirst = t.value
+ else:
+ nfirst = 1
+
+ if len(w_target.items) == 0 and nfirst == 1:
+ return space.w_nil
+
+ flist_w = w_target.clone()
+ if nfirst < 1:
+ flist_w.items = []
+ else:
+ flist_w.items = flist_w.items[0:nfirst]
+ return flist_w
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_list.py Thu May 28 15:00:20 2009
@@ -80,4 +80,63 @@
def test_list_foreach_leaks_variables():
inp = 'b := list(); a := list(99, 34); a foreach(key, value, b append(list(key, value))); key+value'
res,space = interpret(inp)
- assert res.value == 35
\ No newline at end of file
+ assert res.value == 35
+
+def test_list_with():
+ inp = 'a := list(1,2,3); b := a with(99, 34); list(a,b)'
+ res, space = interpret(inp)
+ a, b = res.items
+ # a is proto of b
+ assert b.protos == [a]
+
+ # b has 1,2,3,99,34 as element
+ assert [x.value for x in b.items] == [1, 2, 3, 99, 34]
+
+def test_list_index_of():
+ inp = 'list(9,8,7,7) indexOf(7)'
+ res, _ = interpret(inp)
+ assert res.value == 2
+
+ inp = 'list(9,8,7,7) indexOf(42)'
+ res, space = interpret(inp)
+ assert res == space.w_nil
+
+def test_list_contains():
+ inp = 'list(9,8,7,7) contains(7)'
+ res, space = interpret(inp)
+ assert res == space.w_true
+
+ inp = 'list(9,8,7,7) contains(42)'
+ res, space = interpret(inp)
+ assert res == space.w_false
+
+def test_list_size():
+ inp = 'list(9,8,7,7) size'
+ res, _ = interpret(inp)
+ assert res.value == 4
+
+ inp = 'list() size'
+ res, _ = interpret(inp)
+ assert res.value == 0
+
+def test_list_first_empty():
+ inp = 'list() first'
+ res, space = interpret(inp)
+ assert res == space.w_nil
+
+ inp = 'list() first(3)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert len(res.items) == 0
+
+def test_list_first():
+ inp = 'list(9,8,7,6,5,4,3,2,1,1) first'
+ res, _ = interpret(inp)
+ assert isinstance(res, W_List)
+ assert res.items[0].value == 9
+
+def test_list_first_n():
+ inp = 'list(9,8,7,6,5,4,3,2,1,1) first(3)'
+ res, _ = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == [9,8,7]
\ No newline at end of file
From david at codespeak.net Thu May 28 15:06:08 2009
From: david at codespeak.net (david at codespeak.net)
Date: Thu, 28 May 2009 15:06:08 +0200 (CEST)
Subject: [pypy-svn] r65480 - pypy/branch/io-lang/pypy/lang/io/test
Message-ID: <20090528130608.29434169F8A@codespeak.net>
Author: david
Date: Thu May 28 15:06:07 2009
New Revision: 65480
Modified:
pypy/branch/io-lang/pypy/lang/io/test/test_list.py
Log:
Ensure list receiving the call of "first" is proto of resulting list
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_list.py Thu May 28 15:06:07 2009
@@ -124,19 +124,22 @@
res, space = interpret(inp)
assert res == space.w_nil
- inp = 'list() first(3)'
+ inp = 'a := list(); a first(3)'
res, space = interpret(inp)
assert isinstance(res, W_List)
assert len(res.items) == 0
+ assert res.protos == [space.w_lobby.slots['a']]
def test_list_first():
- inp = 'list(9,8,7,6,5,4,3,2,1,1) first'
- res, _ = interpret(inp)
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,1); a first'
+ res, space = interpret(inp)
assert isinstance(res, W_List)
assert res.items[0].value == 9
+ assert res.protos == [space.w_lobby.slots['a']]
def test_list_first_n():
- inp = 'list(9,8,7,6,5,4,3,2,1,1) first(3)'
- res, _ = interpret(inp)
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,1); a first(3)'
+ res, space = interpret(inp)
assert isinstance(res, W_List)
- assert [x.value for x in res.items] == [9,8,7]
\ No newline at end of file
+ assert [x.value for x in res.items] == [9,8,7]
+ assert res.protos == [space.w_lobby.slots['a']]
\ No newline at end of file
From antocuni at codespeak.net Thu May 28 22:27:27 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 22:27:27 +0200 (CEST)
Subject: [pypy-svn] r65481 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli
Message-ID: <20090528202727.5126E169F71@codespeak.net>
Author: antocuni
Date: Thu May 28 22:27:24 2009
New Revision: 65481
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
Log:
make sure to return the same FieldDescr for all subclasses
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py Thu May 28 22:27:24 2009
@@ -80,7 +80,8 @@
@cached_method('_fieldcache')
def fielddescrof(self, T, fieldname):
- return FieldDescr(T, fieldname)
+ T1, _ = T._lookup_field(fieldname)
+ return FieldDescr(T1, fieldname)
# ----------------------
From antocuni at codespeak.net Thu May 28 22:28:27 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 22:28:27 +0200 (CEST)
Subject: [pypy-svn] r65482 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/backend: . x86
Message-ID: <20090528202827.9A40C169F78@codespeak.net>
Author: antocuni
Date: Thu May 28 22:28:22 2009
New Revision: 65482
Added:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/loopparser.py
- copied unchanged from r65473, pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/loopparser.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/support.py (contents, props changed)
Removed:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/loopparser.py
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py
Log:
factor the loop logger out of the x86 backend and put it in support.py, so
that it can be used by other backends as well
Added: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/support.py
==============================================================================
--- (empty file)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/support.py Thu May 28 22:28:22 2009
@@ -0,0 +1,107 @@
+import os
+from pypy.rlib.objectmodel import compute_unique_id
+from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.metainterp.history import Const, ConstInt, Box, ConstPtr, BoxPtr,\
+ BoxInt, ConstAddr
+
+def repr_of_arg(memo, arg):
+ try:
+ mv = memo[arg]
+ except KeyError:
+ mv = len(memo)
+ memo[arg] = mv
+ if isinstance(arg, ConstInt):
+ return "ci(%d,%d)" % (mv, arg.value)
+ elif isinstance(arg, ConstPtr):
+ return "cp(%d,%d)" % (mv, arg.get_())
+ elif isinstance(arg, BoxInt):
+ return "bi(%d,%d)" % (mv, arg.value)
+ elif isinstance(arg, BoxPtr):
+ return "bp(%d,%d)" % (mv, arg.get_())
+ elif isinstance(arg, ConstAddr):
+ return "ca(%d,%d)" % (mv, arg.get_())
+ else:
+ #raise NotImplementedError
+ return "?%r" % (arg,)
+
+class Logger(object):
+
+ def __init__(self):
+ self._log_fd = -1
+
+ def create_log(self):
+ s = os.environ.get('PYPYJITLOG')
+ if not s:
+ return -1
+ s += '.ops'
+ try:
+ flags = os.O_WRONLY|os.O_CREAT|os.O_TRUNC
+ self._log_fd = os.open(s, flags, 0666)
+ except OSError:
+ os.write(2, "could not create log file\n")
+ return -1
+ return self._log_fd
+
+ def repr_for_descr(self, descr):
+ return ''
+
+ def eventually_log_operations(self, inputargs, operations, memo=None,
+ myid=0):
+ if self._log_fd == -1:
+ return
+ if memo is None:
+ memo = {}
+ if inputargs is None:
+ os.write(self._log_fd, "BEGIN(%s)\n" % myid)
+ else:
+ args = ",".join([repr_of_arg(memo, arg) for arg in inputargs])
+ os.write(self._log_fd, "LOOP %s\n" % args)
+ for i in range(len(operations)):
+ op = operations[i]
+ args = ",".join([repr_of_arg(memo, arg) for arg in op.args])
+ if op.descr is not None:
+ descr = self.repr_for_descr(op.descr)
+ os.write(self._log_fd, "%d:%s %s[%s]\n" % (i, op.getopname(),
+ args, descr))
+ else:
+ os.write(self._log_fd, "%d:%s %s\n" % (i, op.getopname(), args))
+ if op.result is not None:
+ os.write(self._log_fd, " => %s\n" % repr_of_arg(memo,
+ op.result))
+ if op.is_guard():
+ self.eventually_log_operations(None, op.suboperations, memo)
+ if operations[-1].opnum == rop.JUMP:
+ if operations[-1].jump_target is not None:
+ jump_target = compute_unique_id(operations[-1].jump_target)
+ else:
+ # XXX hack for the annotator
+ jump_target = 13
+ os.write(self._log_fd, 'JUMPTO:%s\n' % jump_target)
+ if inputargs is None:
+ os.write(self._log_fd, "END\n")
+ else:
+ os.write(self._log_fd, "LOOP END\n")
+
+ def log_failure_recovery(self, gf, guard_index):
+ if self._log_fd == -1:
+ return
+ return # XXX
+ os.write(self._log_fd, 'xxxxxxxxxx\n')
+ memo = {}
+ reprs = []
+ for j in range(len(gf.guard_op.liveboxes)):
+ valuebox = gf.cpu.getvaluebox(gf.frame, gf.guard_op, j)
+ reprs.append(repr_of_arg(memo, valuebox))
+ jmp = gf.guard_op._jmp_from
+ os.write(self._log_fd, "%d %d %s\n" % (guard_index, jmp,
+ ",".join(reprs)))
+ os.write(self._log_fd, 'xxxxxxxxxx\n')
+
+ def log_call(self, valueboxes):
+ if self._log_fd == -1:
+ return
+ return # XXX
+ memo = {}
+ args_s = ','.join([repr_of_arg(memo, box) for box in valueboxes])
+ os.write(self._log_fd, "CALL\n")
+ os.write(self._log_fd, "%s %s\n" % (name, args_s))
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py Thu May 28 22:28:22 2009
@@ -1,8 +1,7 @@
import sys, os
import ctypes
from pypy.jit.backend.x86 import symbolic
-from pypy.jit.metainterp.history import Const, ConstInt, Box, ConstPtr, BoxPtr,\
- BoxInt, ConstAddr
+from pypy.jit.metainterp.history import Const, Box, BoxPtr
from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory
from pypy.rpython.lltypesystem.rclass import OBJECT
from pypy.rpython.lltypesystem.lloperation import llop
@@ -14,31 +13,22 @@
from pypy.jit.backend.x86 import codebuf
from pypy.jit.backend.x86.ri386 import *
from pypy.jit.metainterp.resoperation import rop
+from pypy.jit.backend.support import Logger
# our calling convention - we pass three first args as edx, ecx and eax
# and the rest stays on the stack
MAX_FAIL_BOXES = 1000
-def repr_of_arg(memo, arg):
- try:
- mv = memo[arg]
- except KeyError:
- mv = len(memo)
- memo[arg] = mv
- if isinstance(arg, ConstInt):
- return "ci(%d,%d)" % (mv, arg.value)
- elif isinstance(arg, ConstPtr):
- return "cp(%d,%d)" % (mv, arg.get_())
- elif isinstance(arg, BoxInt):
- return "bi(%d,%d)" % (mv, arg.value)
- elif isinstance(arg, BoxPtr):
- return "bp(%d,%d)" % (mv, arg.get_())
- elif isinstance(arg, ConstAddr):
- return "ca(%d,%d)" % (mv, arg.get_())
- else:
- #raise NotImplementedError
- return "?%r" % (arg,)
+class x86Logger(Logger):
+
+ def repr_for_descr(self, descr):
+ from pypy.jit.backend.x86.runner import ConstDescr3
+ if isinstance(descr, ConstDescr3):
+ return (str(op.descr.v0) + "," + str(op.descr.v1) +
+ "," + str(op.descr.flag2))
+ return Logger.repr_for_descr(descr)
+
class MachineCodeBlockWrapper(object):
MC_SIZE = 1024*1024
@@ -91,7 +81,6 @@
self.counter -= 1
class Assembler386(object):
- log_fd = -1
mc = None
mc2 = None
debug_markers = True
@@ -104,19 +93,7 @@
self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed))
self._exception_addr = 0
self.mcstack = MachineCodeStack()
-
- def _get_log(self):
- s = os.environ.get('PYPYJITLOG')
- if not s:
- return -1
- s += '.ops'
- try:
- flags = os.O_WRONLY|os.O_CREAT|os.O_TRUNC
- log_fd = os.open(s, flags, 0666)
- except OSError:
- os.write(2, "could not create log file\n")
- return -1
- return log_fd
+ self.logger = Logger()
def make_sure_mc_exists(self):
if self.mc is None:
@@ -126,7 +103,7 @@
MAX_FAIL_BOXES, flavor='raw')
self.fail_box_addr = self.cpu.cast_ptr_to_int(self.fail_boxes)
- self._log_fd = self._get_log()
+ self.logger.create_log()
# we generate the loop body in 'mc'
# 'mc2' is for guard recovery code
if we_are_translated():
@@ -159,69 +136,6 @@
if self.gcrootmap:
self.gcrootmap.initialize()
- def eventually_log_operations(self, inputargs, operations, memo=None,
- myid=0):
- from pypy.jit.backend.x86.runner import ConstDescr3
-
- if self._log_fd == -1:
- return
- if memo is None:
- memo = {}
- if inputargs is None:
- os.write(self._log_fd, "BEGIN(%s)\n" % myid)
- else:
- args = ",".join([repr_of_arg(memo, arg) for arg in inputargs])
- os.write(self._log_fd, "LOOP %s\n" % args)
- for i in range(len(operations)):
- op = operations[i]
- args = ",".join([repr_of_arg(memo, arg) for arg in op.args])
- if op.descr is not None and isinstance(op.descr, ConstDescr3):
- descr = (str(op.descr.v0) + "," + str(op.descr.v1) +
- "," + str(op.descr.flag2))
- os.write(self._log_fd, "%d:%s %s[%s]\n" % (i, op.getopname(),
- args, descr))
- else:
- os.write(self._log_fd, "%d:%s %s\n" % (i, op.getopname(), args))
- if op.result is not None:
- os.write(self._log_fd, " => %s\n" % repr_of_arg(memo,
- op.result))
- if op.is_guard():
- self.eventually_log_operations(None, op.suboperations, memo)
- if operations[-1].opnum == rop.JUMP:
- if operations[-1].jump_target is not None:
- jump_target = compute_unique_id(operations[-1].jump_target)
- else:
- # XXX hack for the annotator
- jump_target = 13
- os.write(self._log_fd, 'JUMPTO:%s\n' % jump_target)
- if inputargs is None:
- os.write(self._log_fd, "END\n")
- else:
- os.write(self._log_fd, "LOOP END\n")
-
- def log_failure_recovery(self, gf, guard_index):
- if self._log_fd == -1:
- return
- return # XXX
- os.write(self._log_fd, 'xxxxxxxxxx\n')
- memo = {}
- reprs = []
- for j in range(len(gf.guard_op.liveboxes)):
- valuebox = gf.cpu.getvaluebox(gf.frame, gf.guard_op, j)
- reprs.append(repr_of_arg(memo, valuebox))
- jmp = gf.guard_op._jmp_from
- os.write(self._log_fd, "%d %d %s\n" % (guard_index, jmp,
- ",".join(reprs)))
- os.write(self._log_fd, 'xxxxxxxxxx\n')
-
- def log_call(self, valueboxes):
- if self._log_fd == -1:
- return
- return # XXX
- memo = {}
- args_s = ','.join([repr_of_arg(memo, box) for box in valueboxes])
- os.write(self._log_fd, "CALL\n")
- os.write(self._log_fd, "%s %s\n" % (name, args_s))
def _compute_longest_fail_op(self, ops):
max_so_far = 0
@@ -244,8 +158,8 @@
self.tree = tree
self.make_sure_mc_exists()
inputargs = tree.inputargs
- self.eventually_log_operations(tree.inputargs, tree.operations, None,
- compute_unique_id(tree))
+ self.logger.eventually_log_operations(tree.inputargs, tree.operations, None,
+ compute_unique_id(tree))
regalloc = RegAlloc(self, tree, self.cpu.translate_support_code)
self._regalloc = regalloc
regalloc.walk_operations(tree)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/runner.py Thu May 28 22:28:22 2009
@@ -168,7 +168,7 @@
# # llop.debug_print(lltype.Void, '.. calling back from',
# # guard_op, 'to the jit')
# gf = GuardFailed(self, frame_addr, guard_op)
-# self.assembler.log_failure_recovery(gf, guard_index)
+# self.assembler.logger.log_failure_recovery(gf, guard_index)
# self.metainterp.handle_guard_failure(gf)
# self.return_value_type = gf.return_value_type
# #if self.debug:
@@ -279,7 +279,7 @@
# values_repr = ", ".join([str(values_as_int[i]) for i in
# range(len(valueboxes))])
# llop.debug_print(lltype.Void, 'exec:', name, values_repr)
- #self.assembler.log_call(valueboxes) --- XXX
+ #self.assembler.logger.log_call(valueboxes) --- XXX
guard_index = self.execute_call(loop, func, verbose)
self._guard_index = guard_index # for tests
op = self._guard_list[guard_index]
From antocuni at codespeak.net Thu May 28 22:31:15 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 22:31:15 +0200 (CEST)
Subject: [pypy-svn] r65483 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86
Message-ID: <20090528203115.37149169F72@codespeak.net>
Author: antocuni
Date: Thu May 28 22:31:14 2009
New Revision: 65483
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
Log:
typo
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py Thu May 28 22:31:14 2009
@@ -93,7 +93,7 @@
self._exception_data = lltype.nullptr(rffi.CArray(lltype.Signed))
self._exception_addr = 0
self.mcstack = MachineCodeStack()
- self.logger = Logger()
+ self.logger = x86Logger()
def make_sure_mc_exists(self):
if self.mc is None:
From antocuni at codespeak.net Thu May 28 23:15:13 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 28 May 2009 23:15:13 +0200 (CEST)
Subject: [pypy-svn] r65484 - in pypy/branch/pyjitpl5-experiments/pypy/jit:
backend backend/cli backend/x86 metainterp
Message-ID: <20090528211513.9BFB9169F8A@codespeak.net>
Author: antocuni
Date: Thu May 28 23:15:13 2009
New Revision: 65484
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/support.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py
Log:
add support for loop logging to the cli backend
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/method.py Thu May 28 23:15:13 2009
@@ -1,5 +1,6 @@
import py
from pypy.tool.pairtype import extendabletype
+from pypy.rlib.objectmodel import compute_unique_id
from pypy.rpython.ootypesystem import ootype
from pypy.translator.cli import dotnet
from pypy.translator.cli.dotnet import CLR
@@ -8,6 +9,7 @@
from pypy.jit.metainterp.history import (AbstractValue, Const, ConstInt,
ConstObj)
from pypy.jit.metainterp.resoperation import rop, opname
+from pypy.jit.backend.support import AbstractLogger
from pypy.jit.backend.cli import runner
from pypy.jit.backend.cli.methodfactory import get_method_wrapper
@@ -19,6 +21,16 @@
cVoid = ootype.nullruntimeclass
+class CliLogger(AbstractLogger):
+ is_oo = True
+
+ def repr_of_descr(self, descr):
+ from pypy.jit.backend.cli.runner import DescrWithKey
+ if isinstance(descr, DescrWithKey):
+ return descr.short_repr()
+ return AbstractLogger.repr_of_descr(self, descr)
+
+logger = CliLogger()
class __extend__(AbstractValue):
__metaclass__ = extendabletype
@@ -139,6 +151,11 @@
else:
self.av_OverflowError = None
self.av_ZeroDivisionError = None
+
+ # ----
+ logger.create_log()
+ logger.eventually_log_operations(loop.inputargs, loop.operations, None,
+ compute_unique_id(loop))
# ----
self.emit_load_inputargs()
self.emit_preamble()
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py Thu May 28 23:15:13 2009
@@ -230,6 +230,9 @@
def sort_key(self):
return self.key
+ def short_repr(self):
+ return ''
+
def get_class_for_type(T):
if T is ootype.Void:
@@ -288,6 +291,7 @@
self.getarraylength = getarraylength
self.instanceof = instanceof
self.ooclass = get_class_for_type(TYPE)
+ self.typename = TYPE._short_name()
def get_clitype(self):
return dotnet.class2type(self.ooclass)
@@ -299,6 +303,9 @@
clitype = self.get_clitype()
return clitype.GetConstructor(dotnet.new_array(System.Type, 0))
+ def short_repr(self):
+ return self.typename
+
class StaticMethDescr(DescrWithKey):
callfunc = None
@@ -425,6 +432,8 @@
clitype = self.get_self_clitype()
return clitype.GetField(self.fieldname+'')
+ def short_repr(self):
+ return "'%s'" % self.fieldname
CPU = CliCPU
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/support.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/support.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/support.py Thu May 28 23:15:13 2009
@@ -2,34 +2,18 @@
from pypy.rlib.objectmodel import compute_unique_id
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp.history import Const, ConstInt, Box, ConstPtr, BoxPtr,\
- BoxInt, ConstAddr
+ BoxInt, ConstAddr, BoxObj, ConstObj
-def repr_of_arg(memo, arg):
- try:
- mv = memo[arg]
- except KeyError:
- mv = len(memo)
- memo[arg] = mv
- if isinstance(arg, ConstInt):
- return "ci(%d,%d)" % (mv, arg.value)
- elif isinstance(arg, ConstPtr):
- return "cp(%d,%d)" % (mv, arg.get_())
- elif isinstance(arg, BoxInt):
- return "bi(%d,%d)" % (mv, arg.value)
- elif isinstance(arg, BoxPtr):
- return "bp(%d,%d)" % (mv, arg.get_())
- elif isinstance(arg, ConstAddr):
- return "ca(%d,%d)" % (mv, arg.get_())
- else:
- #raise NotImplementedError
- return "?%r" % (arg,)
-
-class Logger(object):
+class AbstractLogger(object):
+ # is_oo = ... ## need to be set by concrete classes
+
def __init__(self):
self._log_fd = -1
def create_log(self):
+ if self._log_fd != -1:
+ return self._log_fd
s = os.environ.get('PYPYJITLOG')
if not s:
return -1
@@ -42,9 +26,33 @@
return -1
return self._log_fd
- def repr_for_descr(self, descr):
+ def repr_of_descr(self, descr):
return ''
+ def repr_of_arg(self, memo, arg):
+ try:
+ mv = memo[arg]
+ except KeyError:
+ mv = len(memo)
+ memo[arg] = mv
+ if isinstance(arg, ConstInt):
+ return "ci(%d,%d)" % (mv, arg.value)
+ elif isinstance(arg, BoxInt):
+ return "bi(%d,%d)" % (mv, arg.value)
+ elif not self.is_oo and isinstance(arg, ConstPtr):
+ return "cp(%d,%d)" % (mv, arg.get_())
+ elif not self.is_oo and isinstance(arg, BoxPtr):
+ return "bp(%d,%d)" % (mv, arg.get_())
+ elif not self.is_oo and isinstance(arg, ConstAddr):
+ return "ca(%d,%d)" % (mv, arg.get_())
+ elif self.is_oo and isinstance(arg, ConstObj):
+ return "co(%d,%d)" % (mv, arg.get_())
+ elif self.is_oo and isinstance(arg, BoxObj):
+ return "bo(%d,%d)" % (mv, arg.get_())
+ else:
+ #raise NotImplementedError
+ return "?%r" % (arg,)
+
def eventually_log_operations(self, inputargs, operations, memo=None,
myid=0):
if self._log_fd == -1:
@@ -54,20 +62,20 @@
if inputargs is None:
os.write(self._log_fd, "BEGIN(%s)\n" % myid)
else:
- args = ",".join([repr_of_arg(memo, arg) for arg in inputargs])
+ args = ",".join([self.repr_of_arg(memo, arg) for arg in inputargs])
os.write(self._log_fd, "LOOP %s\n" % args)
for i in range(len(operations)):
op = operations[i]
- args = ",".join([repr_of_arg(memo, arg) for arg in op.args])
+ args = ",".join([self.repr_of_arg(memo, arg) for arg in op.args])
if op.descr is not None:
- descr = self.repr_for_descr(op.descr)
+ descr = self.repr_of_descr(op.descr)
os.write(self._log_fd, "%d:%s %s[%s]\n" % (i, op.getopname(),
args, descr))
else:
os.write(self._log_fd, "%d:%s %s\n" % (i, op.getopname(), args))
if op.result is not None:
- os.write(self._log_fd, " => %s\n" % repr_of_arg(memo,
- op.result))
+ os.write(self._log_fd, " => %s\n" % self.repr_of_arg(memo,
+ op.result))
if op.is_guard():
self.eventually_log_operations(None, op.suboperations, memo)
if operations[-1].opnum == rop.JUMP:
@@ -91,7 +99,7 @@
reprs = []
for j in range(len(gf.guard_op.liveboxes)):
valuebox = gf.cpu.getvaluebox(gf.frame, gf.guard_op, j)
- reprs.append(repr_of_arg(memo, valuebox))
+ reprs.append(self.repr_of_arg(memo, valuebox))
jmp = gf.guard_op._jmp_from
os.write(self._log_fd, "%d %d %s\n" % (guard_index, jmp,
",".join(reprs)))
@@ -102,6 +110,6 @@
return
return # XXX
memo = {}
- args_s = ','.join([repr_of_arg(memo, box) for box in valueboxes])
+ args_s = ','.join([self.repr_of_arg(memo, box) for box in valueboxes])
os.write(self._log_fd, "CALL\n")
os.write(self._log_fd, "%s %s\n" % (name, args_s))
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/assembler.py Thu May 28 23:15:13 2009
@@ -13,21 +13,23 @@
from pypy.jit.backend.x86 import codebuf
from pypy.jit.backend.x86.ri386 import *
from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.backend.support import Logger
+from pypy.jit.backend.support import AbstractLogger
# our calling convention - we pass three first args as edx, ecx and eax
# and the rest stays on the stack
MAX_FAIL_BOXES = 1000
-class x86Logger(Logger):
+class x86Logger(AbstractLogger):
- def repr_for_descr(self, descr):
+ is_oo = False
+
+ def repr_of_descr(self, descr):
from pypy.jit.backend.x86.runner import ConstDescr3
if isinstance(descr, ConstDescr3):
- return (str(op.descr.v0) + "," + str(op.descr.v1) +
- "," + str(op.descr.flag2))
- return Logger.repr_for_descr(descr)
+ return (str(descr.v0) + "," + str(descr.v1) +
+ "," + str(descr.flag2))
+ return AbstractLogger.repr_of_descr(self, descr)
class MachineCodeBlockWrapper(object):
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/compile.py Thu May 28 23:15:13 2009
@@ -272,7 +272,7 @@
if isinstance(box, BoxInt):
srcvalue = cpu.get_latest_value_int(i)
box.changevalue_int(srcvalue)
- elif isinstance(box, BoxPtr):
+ elif not cpu.is_oo and isinstance(box, BoxPtr):
srcvalue = cpu.get_latest_value_ptr(i)
box.changevalue_ptr(srcvalue)
elif cpu.is_oo and isinstance(box, BoxObj):
@@ -290,7 +290,7 @@
dstbox = fail_op.args[i]
if isinstance(dstbox, BoxInt):
dstbox.changevalue_int(srcbox.getint())
- elif isinstance(dstbox, BoxPtr):
+ elif not metainterp_sd.cpu.is_oo and isinstance(dstbox, BoxPtr):
dstbox.changevalue_ptr(srcbox.getptr_base())
elif isinstance(dstbox, Const):
pass
From antocuni at codespeak.net Fri May 29 00:12:36 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 29 May 2009 00:12:36 +0200 (CEST)
Subject: [pypy-svn] r65485 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli: . test
Message-ID: <20090528221236.CB154169FF5@codespeak.net>
Author: antocuni
Date: Fri May 29 00:12:35 2009
New Revision: 65485
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py
Log:
we cannot use cached_method to cache FieldDescr, because we want to use the
class where the field is really defined as a key, while cached_method blindly
use the actual arguments. Instead, use the same approach as the llgraph
backend.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/runner.py Fri May 29 00:12:35 2009
@@ -7,7 +7,6 @@
from pypy.jit.metainterp import executor
from pypy.jit.metainterp.resoperation import rop, opname
from pypy.jit.backend import model
-from pypy.jit.backend.minimal.runner import cached_method
from pypy.jit.backend.llgraph.runner import KeyManager
from pypy.translator.cli import dotnet
from pypy.translator.cli.dotnet import CLR
@@ -58,30 +57,30 @@
self.inputargs = InputArgs()
return self.inputargs
- @cached_method('_callcache')
- def calldescrof(self, FUNC, ARGS, RESULT):
- return StaticMethDescr(FUNC, ARGS, RESULT)
+ @staticmethod
+ def calldescrof(FUNC, ARGS, RESULT):
+ return StaticMethDescr.new(FUNC, ARGS, RESULT)
- @cached_method('_methcache')
- def methdescrof(self, SELFTYPE, methname):
+ @staticmethod
+ def methdescrof(SELFTYPE, methname):
if SELFTYPE in (ootype.String, ootype.Unicode):
- return StringMethDescr(SELFTYPE, methname)
- return MethDescr(SELFTYPE, methname)
+ return StringMethDescr.new(SELFTYPE, methname)
+ return MethDescr.new(SELFTYPE, methname)
- @cached_method('_typecache')
- def typedescrof(self, TYPE):
- return TypeDescr(TYPE)
+ @staticmethod
+ def typedescrof(TYPE):
+ return TypeDescr.new(TYPE)
- @cached_method('_arraycache')
- def arraydescrof(self, A):
+ @staticmethod
+ def arraydescrof(A):
assert isinstance(A, ootype.Array)
TYPE = A.ITEM
- return TypeDescr(TYPE)
+ return TypeDescr.new(TYPE)
- @cached_method('_fieldcache')
- def fielddescrof(self, T, fieldname):
+ @staticmethod
+ def fielddescrof(T, fieldname):
T1, _ = T._lookup_field(fieldname)
- return FieldDescr(T1, fieldname)
+ return FieldDescr.new(T1, fieldname)
# ----------------------
@@ -221,9 +220,22 @@
# ----------------------------------------------------------------------
key_manager = KeyManager()
+descr_cache = {}
class DescrWithKey(AbstractDescr):
key = -1
+ @classmethod
+ def new(cls, *args):
+ 'NOT_RPYTHON'
+ key = (cls, args)
+ try:
+ return descr_cache[key]
+ except KeyError:
+ res = cls(*args)
+ descr_cache[key] = res
+ return res
+
+
def __init__(self, key):
self.key = key_manager.getkey(key)
@@ -351,7 +363,9 @@
methname = ''
has_result = False
key = -1
-
+
+ new = classmethod(DescrWithKey.new.im_func)
+
def __init__(self, SELFTYPE, methname):
from pypy.jit.backend.llgraph.runner import boxresult, make_getargs
_, meth = SELFTYPE._lookup(methname)
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/cli/test/test_basic.py Fri May 29 00:12:35 2009
@@ -38,3 +38,13 @@
test_long_long = skip
test_free_object = skip
test_stopatxpolicy = skip
+
+
+def test_fielddescr_ootype():
+ from pypy.rpython.ootypesystem import ootype
+ from pypy.jit.backend.cli.runner import CliCPU
+ A = ootype.Instance("A", ootype.ROOT, {"foo": ootype.Signed})
+ B = ootype.Instance("B", A)
+ descr1 = CliCPU.fielddescrof(A, "foo")
+ descr2 = CliCPU.fielddescrof(B, "foo")
+ assert descr1 is descr2
From fijal at codespeak.net Fri May 29 03:08:07 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 03:08:07 +0200 (CEST)
Subject: [pypy-svn] r65486 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090529010807.65E7C169E04@codespeak.net>
Author: fijal
Date: Fri May 29 03:08:04 2009
New Revision: 65486
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
Fix the issue, unskip the test.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Fri May 29 03:08:04 2009
@@ -218,12 +218,18 @@
newoperations.append(op)
print "Length of the loop:", len(newoperations)
self.loop.operations = newoperations
+
+ def cleanup_nodes(self):
+ for node in self.nodes.values():
+ node.arrayfields.clear()
+ node.cleanfields.clear()
def optimize_loop(self, loop):
self.nodes = {}
self.field_caches = {}
self.loop = loop
self.find_nodes()
+ self.cleanup_nodes()
self.optimize_operations()
class ConsecutiveGuardClassRemoval(object):
@@ -244,6 +250,8 @@
field = op.descr
if field not in instnode.vdesc.virtuals:
return False
+ node = spec.getnode(op.args[1])
+ instnode.cleanfields[field] = node
return True
@staticmethod
@@ -254,6 +262,11 @@
field = op.descr
if field not in instnode.vdesc.virtuals:
return False
+ node = instnode.cleanfields.get(field, None)
+ if node:
+ spec.nodes[op.result] = node
+ node.virtualized = True
+ return True
node = spec.getnode(op.result)
node.virtualized = True
return False
@@ -263,9 +276,24 @@
instnode = spec.getnode(op.args[0])
if not instnode.virtualized:
return False
+ field = op.args[1].getint()
+ node = spec.getnode(op.args[2])
+ instnode.arrayfields[field] = node
return True
@staticmethod
+ def find_nodes_getarrayitem_gc(op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtualized:
+ return False
+ field = op.args[1].getint()
+ node = instnode.arrayfields.get(field, None)
+ if node is not None:
+ spec.nodes[op.result] = node
+ return True
+ return False
+
+ @staticmethod
def find_nodes_guard_nonvirtualized(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.allocated_in_loop:
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Fri May 29 03:08:04 2009
@@ -429,7 +429,6 @@
def test_virtual_with_virtualizable_escapes(self):
- py.test.skip("FIXME")
pre_op = """
[p0]
p1 = new_with_vtable(ConstClass(node_vtable))
From fijal at codespeak.net Fri May 29 03:22:04 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 03:22:04 +0200 (CEST)
Subject: [pypy-svn] r65487 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090529012204.29F0C169FDB@codespeak.net>
Author: fijal
Date: Fri May 29 03:22:03 2009
New Revision: 65487
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
a test and a fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Fri May 29 03:22:03 2009
@@ -268,6 +268,7 @@
node.virtualized = True
return True
node = spec.getnode(op.result)
+ instnode.cleanfields[field] = node
node.virtualized = True
return False
@@ -291,6 +292,7 @@
if node is not None:
spec.nodes[op.result] = node
return True
+ instnode.arrayfields[field] = node
return False
@staticmethod
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Fri May 29 03:22:03 2009
@@ -451,6 +451,29 @@
SimpleVirtualOpt()]),
expected)
+ def test_virtualizable_double_read(self):
+ pre_op = """
+ [p0]
+ p3 = new_with_vtable(ConstClass(node_vtable))
+ guard_nonvirtualized(p0, vdesc=vdesc)
+ fail()
+ p1 = getfield_gc(p0, descr=list_node_desc)
+ setarrayitem_gc(p1, 0, p3)
+ p2 = getfield_gc(p0, descr=list_node_desc)
+ p4 = getarrayitem_gc(p2, 0)
+ fail(p4)
+ """
+ expected = """
+ [p0]
+ p3 = new_with_vtable(ConstClass(node_vtable))
+ p1 = getfield_gc(p0, descr=list_node_desc)
+ fail(p3)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt(),
+ SimpleVirtualOpt()]),
+ expected)
+
+
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
pass
@@ -459,3 +482,4 @@
py.test.skip("XXX")
test_virtual_with_virtualizable_escapes = test_virtual_with_virtualizable
+ test_virtualizable_double_read = test_virtual_with_virtualizable
From fijal at codespeak.net Fri May 29 03:31:15 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 03:31:15 +0200 (CEST)
Subject: [pypy-svn] r65488 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090529013115.2CD93169FE7@codespeak.net>
Author: fijal
Date: Fri May 29 03:31:12 2009
New Revision: 65488
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
A trivial test and a fix for node without vtable
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Fri May 29 03:31:12 2009
@@ -135,8 +135,11 @@
def rebuild_virtual(self, ops, node):
assert node.virtual
- ops.append(ResOperation(rop.NEW_WITH_VTABLE, [node.cls],
- node.source, node.size))
+ if node.cls is not None:
+ ops.append(ResOperation(rop.NEW_WITH_VTABLE, [node.cls],
+ node.source, node.size))
+ else:
+ ops.append(ResOperation(rop.NEW, [], node.source, node.size))
for field, valuenode in node.cleanfields.iteritems():
if valuenode.virtual:
self.rebuild_virtual(ops, valuenode)
@@ -381,6 +384,15 @@
return True
@staticmethod
+ def optimize_new(op, spec):
+ node = spec.getnode(op.result)
+ if node.escaped:
+ return False
+ node.virtual = True
+ node.size = op.descr
+ return True
+
+ @staticmethod
def optimize_setfield_gc(op, spec):
instnode = spec.getnode(op.args[0])
if not instnode.virtual:
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Fri May 29 03:31:12 2009
@@ -472,6 +472,22 @@
self.assert_equal(self.optimize(pre_op, [SimpleVirtualizableOpt(),
SimpleVirtualOpt()]),
expected)
+
+ def test_virtual_without_vtable(self):
+ pre_op = """
+ [i1]
+ p0 = new()
+ guard_true(i1)
+ fail(p0)
+ """
+ expected = """
+ [i1]
+ guard_true(i1)
+ p0 = new()
+ fail(p0)
+ """
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
+ expected)
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
From fijal at codespeak.net Fri May 29 04:04:21 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 04:04:21 +0200 (CEST)
Subject: [pypy-svn] r65489 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090529020421.441CE169F4A@codespeak.net>
Author: fijal
Date: Fri May 29 04:04:20 2009
New Revision: 65489
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
more simple stuff. oononnull/ooisnull on virtuals
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Fri May 29 04:04:20 2009
@@ -411,6 +411,23 @@
spec.nodes[op.result] = instnode.cleanfields[field]
return True
+ @staticmethod
+ def optimize_oononnull(op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtual:
+ return False
+ spec.nodes[op.result] = InstanceNode(ConstInt(1), const=True)
+ return True
+
+ @staticmethod
+ def optimize_ooisnull(op, spec):
+ instnode = spec.getnode(op.args[0])
+ if not instnode.virtual:
+ return False
+ spec.nodes[op.result] = InstanceNode(ConstInt(0), const=True)
+ return True
+
+
specializer = Specializer([SimpleVirtualizableOpt(),
SimpleVirtualOpt(),
ConsecutiveGuardClassRemoval()])
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Fri May 29 04:04:20 2009
@@ -488,7 +488,21 @@
"""
self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
expected)
-
+
+ def test_oononnull_on_virtual(self):
+ pre_op = """
+ []
+ p0 = new()
+ i1 = oononnull(p0)
+ guard_true(i1)
+ fail()
+ i2 = ooisnull(p0)
+ guard_false(i2)
+ fail()
+ """
+ expected = "[]"
+ self.assert_equal(self.optimize(pre_op, [SimpleVirtualOpt()]),
+ expected)
class TestLLtype(LLtypeMixin, BaseTestOptimize2):
pass
From fijal at codespeak.net Fri May 29 04:04:56 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 04:04:56 +0200 (CEST)
Subject: [pypy-svn] r65490 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090529020456.49DC1169F4A@codespeak.net>
Author: fijal
Date: Fri May 29 04:04:55 2009
New Revision: 65490
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
getfield_gc_pure and getfield_gc are the same when it comes to virtuals
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Fri May 29 04:04:55 2009
@@ -411,6 +411,8 @@
spec.nodes[op.result] = instnode.cleanfields[field]
return True
+ optimize_getfield_gc_pure = optimize_getfield_gc
+
@staticmethod
def optimize_oononnull(op, spec):
instnode = spec.getnode(op.args[0])
From fijal at codespeak.net Fri May 29 04:14:54 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 04:14:54 +0200 (CEST)
Subject: [pypy-svn] r65491 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090529021454.0DA81169E7D@codespeak.net>
Author: fijal
Date: Fri May 29 04:14:53 2009
New Revision: 65491
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
Log:
translation fix
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/optimize2.py Fri May 29 04:14:53 2009
@@ -27,7 +27,7 @@
self.vdesc = None
self.escaped = escaped
self.virtual = False
- self.size = 0
+ self.size = None
def __repr__(self):
flags = ''
From fijal at codespeak.net Fri May 29 06:04:22 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 06:04:22 +0200 (CEST)
Subject: [pypy-svn] r65492 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090529040422.C2BF4169F4A@codespeak.net>
Author: fijal
Date: Fri May 29 06:04:20 2009
New Revision: 65492
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/jitprof.py
Log:
Swallow broken data. Profiler seems to work, but _end is called when
handling exception, which means that other exception is not displayed.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/jitprof.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/jitprof.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/jitprof.py Fri May 29 06:04:20 2009
@@ -69,10 +69,12 @@
t0 = self.t1
self.t1 = self.timer()
if not self.current:
- raise BrokenProfilerData
+ print "BROKEN PROFILER DATA!"
+ return
ev1 = self.current.pop()
if ev1 != event:
- raise BrokenProfilerData
+ print "BROKEN PROFILER DATA!"
+ return
self.times[ev1] += self.t1 - t0
def start_tracing(self): self._start(TRACING)
From david at codespeak.net Fri May 29 12:26:19 2009
From: david at codespeak.net (david at codespeak.net)
Date: Fri, 29 May 2009 12:26:19 +0200 (CEST)
Subject: [pypy-svn] r65493 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090529102619.AD355169FD2@codespeak.net>
Author: david
Date: Fri May 29 12:26:17 2009
New Revision: 65493
Added:
pypy/branch/io-lang/pypy/lang/io/map.py
pypy/branch/io-lang/pypy/lang/io/test/test_map.py
Modified:
pypy/branch/io-lang/pypy/lang/io/model.py
pypy/branch/io-lang/pypy/lang/io/objspace.py
Log:
Added map type for key value collections and two methods (clone, atPut)
Added: pypy/branch/io-lang/pypy/lang/io/map.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/map.py Fri May 29 12:26:17 2009
@@ -0,0 +1,6 @@
+from pypy.lang.io.register import register_method
+
+ at register_method('Map', 'atPut', unwrap_spec=[object, object, object])
+def map_at_put(space, target, key, value):
+ target.items[key] = value
+ return target
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/model.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/model.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/model.py Fri May 29 12:26:17 2009
@@ -73,6 +73,15 @@
l.items += items
return l
+class W_Map(W_Object):
+ """A key/value dictionary appropriate for holding large key/value collections."""
+ def __init__(self, space, protos = [], items = {}):
+ W_Object.__init__(self, space, protos)
+ self.items = items
+
+ def clone(self):
+ return W_Map(self.space, [self], dict(self.items))
+
class W_ImmutableSequence(W_Object):
def __init__(self, space, string):
self.value = string
Modified: pypy/branch/io-lang/pypy/lang/io/objspace.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/objspace.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/objspace.py Fri May 29 12:26:17 2009
@@ -1,5 +1,5 @@
from pypy.rlib.objectmodel import instantiate
-from pypy.lang.io.model import W_Number, W_Object, W_CFunction, W_Block, W_Message, W_List
+from pypy.lang.io.model import W_Number, W_Object, W_CFunction, W_Block, W_Message, W_List, W_Map
from pypy.lang.io.register import cfunction_definitions
import pypy.lang.io.number
@@ -8,6 +8,8 @@
import pypy.lang.io.list
import pypy.lang.io.call
import pypy.lang.io.message
+import pypy.lang.io.map
+
class ObjSpace(object):
"""docstring for ObjSpace"""
def __init__(self):
@@ -22,7 +24,7 @@
self.w_nil = W_Object(self, [self.w_object])
self.w_list = W_List(self, [self.w_object])
self.w_call = W_Object(self)
-
+ self.w_map = W_Map(self, [self.w_object])
self.init_w_object()
@@ -44,6 +46,12 @@
self.init_w_call()
+ self.init_w_map()
+
+ def init_w_map(self):
+ for key, function in cfunction_definitions['Map'].items():
+ self.w_map.slots[key] = W_CFunction(self, function)
+
def init_w_call(self):
for key, function in cfunction_definitions['Call'].items():
self.w_call.slots[key] = W_CFunction(self, function)
@@ -70,6 +78,7 @@
self.w_core.slots['nil'] = self.w_nil
self.w_core.slots['List'] = self.w_list
self.w_core.slots['Call'] = self.w_call
+ self.w_core.slots['Map'] = self.w_map
def init_w_number(self):
self.w_number = instantiate(W_Number)
Added: pypy/branch/io-lang/pypy/lang/io/test/test_map.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_map.py Fri May 29 12:26:17 2009
@@ -0,0 +1,24 @@
+from pypy.lang.io.parserhack import parse, interpret
+from pypy.lang.io.model import W_Map, W_Number, W_ImmutableSequence
+import py.test
+
+def test_map_proto():
+ inp = 'Lobby Core Map'
+ res, space = interpret(inp)
+ assert res == space.w_map
+ assert isinstance(res, W_Map)
+
+def test_map_clone():
+ inp = 'Map clone'
+ res, space = interpret(inp)
+ assert isinstance(res, W_Map)
+ assert res.protos == [space.w_map]
+ assert space.w_map.protos == [space.w_object]
+
+def test_at_put():
+ inp = 'Map clone atPut("foo", "bar")'
+ res, space = interpret(inp)
+ keys = [(key.value) for key in res.items.keys()]
+ assert keys == ['foo']
+ values = [(val.value) for val in res.items.values()]
+ assert values == ['bar']
\ No newline at end of file
From antocuni at codespeak.net Fri May 29 14:22:02 2009
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 29 May 2009 14:22:02 +0200 (CEST)
Subject: [pypy-svn] r65494 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090529122202.DBA15169EB0@codespeak.net>
Author: antocuni
Date: Fri May 29 14:22:01 2009
New Revision: 65494
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
Log:
fix ootype tests
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_optimize2.py Fri May 29 14:22:01 2009
@@ -97,17 +97,21 @@
nodesize = cpu.sizeof(node)
TP = ootype.Array(ootype.Signed)
+ NODE_ARRAY = ootype.Array(NODE)
XY = ootype.Instance('XY', ootype.ROOT,
{'ofield': ootype.Signed,
'oother_field': ootype.Signed,
- 'olist': TP},
+ 'olist': TP,
+ 'oitem_list': NODE_ARRAY,
+ },
_hints = {'virtualizable2': True,
- 'virtuals': ('field','list')})
+ 'virtuals': ('field','list', 'item_list')})
field_desc = cpu.fielddescrof(XY, 'ofield')
array_descr = cpu.arraydescrof(TP)
list_desc = cpu.fielddescrof(XY, 'olist')
+ list_node_desc = cpu.fielddescrof(XY, 'oitem_list')
other_field_desc = cpu.fielddescrof(XY, 'oother_field')
vdesc = VirtualizableDesc(cpu, XY, XY)
xy_vtable = ootype.runtimeClass(XY)
@@ -508,8 +512,4 @@
pass
class TestOOtype(OOtypeMixin, BaseTestOptimize2):
- def test_virtual_with_virtualizable(self):
- py.test.skip("XXX")
-
- test_virtual_with_virtualizable_escapes = test_virtual_with_virtualizable
- test_virtualizable_double_read = test_virtual_with_virtualizable
+ pass
From cfbolz at codespeak.net Fri May 29 17:06:00 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 29 May 2009 17:06:00 +0200 (CEST)
Subject: [pypy-svn] r65495 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp: . test
Message-ID: <20090529150600.7B42C169F86@codespeak.net>
Author: cfbolz
Date: Fri May 29 17:05:58 2009
New Revision: 65495
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
Log:
support for functions that are annotated to be pure
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py Fri May 29 17:05:58 2009
@@ -270,7 +270,8 @@
assert not portal, "portal has been hidden!"
graph = make_calling_stub(codewriter.rtyper, graph)
self.graph = graph
- self.raise_analyzer = RaiseAnalyzer(self.cpu.rtyper.annotator.translator)
+ self.translator = self.cpu.rtyper.annotator.translator
+ self.raise_analyzer = RaiseAnalyzer(self.translator)
def assemble(self):
"""Assemble the opcodes for self.bytecode."""
@@ -928,12 +929,18 @@
calldescr, non_void_args = self.codewriter.getcalldescr(op.args[0],
args,
op.result)
+ pure = False
+ if op.opname == "direct_call":
+ func = get_funcobj(op.args[0].value)._callable
+ pure = getattr(func, "_pure_function_", False)
try:
canraise = self.raise_analyzer.can_raise(op)
except lltype.DelayedPointer:
canraise = True # if we need to look into the delayed ptr that is
# the portal, then it's certainly going to raise
- if canraise:
+ if pure:
+ self.emit('residual_call_pure')
+ elif canraise:
self.emit('residual_call')
else:
self.emit('residual_call_noexception')
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py Fri May 29 17:05:58 2009
@@ -1,5 +1,5 @@
import py
-from pypy.rlib.jit import JitDriver, we_are_jitted
+from pypy.rlib.jit import JitDriver, we_are_jitted, hint
from pypy.jit.metainterp.warmspot import ll_meta_interp, get_stats
from pypy.jit.backend.llgraph import runner
from pypy.jit.metainterp import support, codewriter, pyjitpl, history
@@ -265,6 +265,17 @@
assert res == 42
self.check_history_(int_add=1, int_mul=0, call=1, guard_no_exception=0)
+ def test_residual_call_pure(self):
+ def externfn(x, y):
+ return x * y
+ externfn._pure_function_ = True
+ def f(n):
+ n = hint(n, promote=True)
+ return externfn(n, n+1)
+ res = self.interp_operations(f, [6])
+ assert res == 42
+ self.check_history_(int_add=0, int_mul=0, call=0)
+
def test_constant_across_mp(self):
myjitdriver = JitDriver(greens = [], reds = ['n'])
class X(object):
From pedronis at codespeak.net Fri May 29 17:24:57 2009
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Fri, 29 May 2009 17:24:57 +0200 (CEST)
Subject: [pypy-svn] r65496 - pypy/extradoc/sprintinfo/ep2009
Message-ID: <20090529152457.D69DD16A008@codespeak.net>
Author: pedronis
Date: Fri May 29 17:24:57 2009
New Revision: 65496
Modified:
pypy/extradoc/sprintinfo/ep2009/announcement.txt
Log:
proper talks link
Modified: pypy/extradoc/sprintinfo/ep2009/announcement.txt
==============================================================================
--- pypy/extradoc/sprintinfo/ep2009/announcement.txt (original)
+++ pypy/extradoc/sprintinfo/ep2009/announcement.txt Fri May 29 17:24:57 2009
@@ -73,4 +73,4 @@
.. _`pypy-sprint mailing list`: http://codespeak.net/mailman/listinfo/pypy-sprint
.. _`the technical reports available and other relevant documentation`: http://codespeak.net/pypy/dist/pypy/doc/docindex.html
-.. _`EuroPython schedule`: http://europython.eu/xxx
+.. _`EuroPython schedule`: http://europython.eu/talks/timetable
From cfbolz at codespeak.net Fri May 29 17:57:35 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 29 May 2009 17:57:35 +0200 (CEST)
Subject: [pypy-svn] r65497 - pypy/extradoc/sprintinfo/ep2009
Message-ID: <20090529155735.3758816A016@codespeak.net>
Author: cfbolz
Date: Fri May 29 17:57:33 2009
New Revision: 65497
Modified:
pypy/extradoc/sprintinfo/ep2009/announcement.txt
Log:
(pedronis, cfbolz): trying to flesh out the announcement.
Modified: pypy/extradoc/sprintinfo/ep2009/announcement.txt
==============================================================================
--- pypy/extradoc/sprintinfo/ep2009/announcement.txt (original)
+++ pypy/extradoc/sprintinfo/ep2009/announcement.txt Fri May 29 17:57:33 2009
@@ -13,18 +13,30 @@
during the conference since it will give you a good overview of the
status of development.
-.. xxx When/if tutorial?
-On the morning of the first sprint day we will also have a
-tutorial session for those new to PyPy development.
-
-------------------------------
Goals and topics of the sprint
------------------------------
There are many possible and interesting sprint topics to work on - here
we list some possible task areas:
-TBA
+ - trying out software on PyPy's Python interpreter:
+ the CPython test suite is not all that complete, therefore the fact that we
+ pass most tests is no real indication of bug-freeness. We have tried and
+ know that frameworks like Django and Twisted work with PyPy. Therefore we would
+ like to try running more "real application" on top of the Python interpreter
+ (ideally ones that have a good test suite themselves and that don't need
+ unusual extension modules). Running things on windows is also interesting,
+ we know our coverage there is not as good as on Linux.
+
+ - check and improve Mac OS X support
+
+ - starting to work on porting 2.6 features to PyPy's Python interpreter
+
+ - ongoing JIT generator work
+
+ - of course we are open to other ideas for what to work on. Examples could
+ be working on other language interpreters, sandboxing, ...
+
------------
Registration
From cfbolz at codespeak.net Fri May 29 18:02:11 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 29 May 2009 18:02:11 +0200 (CEST)
Subject: [pypy-svn] r65498 - pypy/extradoc/sprintinfo/ep2009
Message-ID: <20090529160211.056BE16A013@codespeak.net>
Author: cfbolz
Date: Fri May 29 18:02:10 2009
New Revision: 65498
Modified:
pypy/extradoc/sprintinfo/ep2009/announcement.txt
Log:
(arigo) typos.
Modified: pypy/extradoc/sprintinfo/ep2009/announcement.txt
==============================================================================
--- pypy/extradoc/sprintinfo/ep2009/announcement.txt (original)
+++ pypy/extradoc/sprintinfo/ep2009/announcement.txt Fri May 29 18:02:10 2009
@@ -23,9 +23,9 @@
the CPython test suite is not all that complete, therefore the fact that we
pass most tests is no real indication of bug-freeness. We have tried and
know that frameworks like Django and Twisted work with PyPy. Therefore we would
- like to try running more "real application" on top of the Python interpreter
+ like to try running more "real applications" on top of the Python interpreter
(ideally ones that have a good test suite themselves and that don't need
- unusual extension modules). Running things on windows is also interesting,
+ unusual extension modules). Running things on Windows is also interesting,
we know our coverage there is not as good as on Linux.
- check and improve Mac OS X support
From cfbolz at codespeak.net Fri May 29 18:38:06 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 29 May 2009 18:38:06 +0200 (CEST)
Subject: [pypy-svn] r65499 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test
Message-ID: <20090529163806.C7A1E169E8E@codespeak.net>
Author: cfbolz
Date: Fri May 29 18:38:04 2009
New Revision: 65499
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
Log:
a skipped test that I am not sure what to do with
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/test/test_basic.py Fri May 29 18:38:04 2009
@@ -276,6 +276,27 @@
assert res == 42
self.check_history_(int_add=0, int_mul=0, call=0)
+ def test_residual_call_pure_exception(self):
+ py.test.skip("fix this")
+ def externfn(x, y):
+ if x == 0:
+ raise IndexError
+ return x * y
+ externfn._pure_function_ = True
+ def f(n):
+ try:
+ n = hint(n, promote=True)
+ return externfn(n, n+1)
+ except IndexError:
+ return 5
+ res = self.interp_operations(f, [6])
+ assert res == 42
+ self.check_history_(int_add=0, int_mul=0, call=0)
+ res = self.interp_operations(f, [0])
+ assert res == 5
+ # XXX what should go to the next line?
+ # self.check_history_(int_add=0, int_mul=0, call=0)
+
def test_constant_across_mp(self):
myjitdriver = JitDriver(greens = [], reds = ['n'])
class X(object):
From cfbolz at codespeak.net Fri May 29 19:27:17 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 29 May 2009 19:27:17 +0200 (CEST)
Subject: [pypy-svn] r65500 -
pypy/branch/pyjitpl5-experiments/pypy/objspace/std
Message-ID: <20090529172717.07909169ED4@codespeak.net>
Author: cfbolz
Date: Fri May 29 19:27:14 2009
New Revision: 65500
Modified:
pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py
Log:
Rewrite shared dicts to be a bit more regular. Slightly slower in some cases,
but less confusing and easier for the JIT.
Modified: pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py Fri May 29 19:27:14 2009
@@ -4,6 +4,7 @@
from pypy.module.__builtin__.__init__ import BUILTIN_TO_INDEX, OPTIMIZED_BUILTINS
from pypy.rlib.objectmodel import r_dict, we_are_translated
+from pypy.rlib.jit import purefunction
def _is_str(space, w_key):
return space.is_w(space.type(w_key), space.w_str)
@@ -695,7 +696,7 @@
self.length = length
self.back_struct = back_struct
if other_structs is None:
- other_structs = []
+ other_structs = {}
self.other_structs = other_structs
self.last_key = last_key
if last_key is not None:
@@ -703,16 +704,11 @@
self.propagating = False
def new_structure(self, added_key):
- keys = {}
- for key, item in self.keys.iteritems():
- if item >= 0:
- keys[key] = item
+ keys = self.keys.copy()
+ keys[added_key] = len(self.keys)
new_structure = SharedStructure(keys, self.length + 1,
- [], added_key, self)
- new_index = len(keys)
- new_structure.keys[added_key] = new_index
- self.keys[added_key] = ~len(self.other_structs)
- self.other_structs.append(new_structure)
+ {}, added_key, self)
+ self.other_structs[added_key] = new_structure
return new_structure
@@ -751,18 +747,17 @@
return self._as_rdict().setitem(w_key, w_value)
def setitem_str(self, w_key, w_value, shadows_type=True):
- m = ~len(self.structure.other_structs)
key = self.space.str_w(w_key)
- i = self.structure.keys.get(key, m)
+ i = self.structure.keys.get(key, -1)
if i >= 0:
self.entries[i] = w_value
return self
if not self.structure.propagating:
return self._as_rdict(as_strdict=True).setitem_str(w_key, w_value)
- if i == m:
+ new_structure = self.structure.other_structs.get(key, None)
+ if new_structure is None:
new_structure = self.structure.new_structure(key)
else:
- new_structure = self.structure.other_structs[~i]
new_structure.propagating = True
self.entries.append(w_value)
assert self.structure.length + 1 == new_structure.length
@@ -845,9 +840,8 @@
implementation = self.dictimplementation
assert isinstance(implementation, SharedDictImplementation)
for key, index in self.iterator:
- if index >= 0:
- w_value = implementation.entries[index]
- return self.space.newtuple([self.space.wrap(key), w_value])
+ w_value = implementation.entries[index]
+ return self.space.newtuple([self.space.wrap(key), w_value])
else:
return None
@@ -860,8 +854,7 @@
implementation = self.dictimplementation
assert isinstance(implementation, SharedDictImplementation)
for key, index in self.iterator:
- if index >= 0:
- return self.space.wrap(key)
+ return self.space.wrap(key)
else:
return None
From cfbolz at codespeak.net Fri May 29 20:12:15 2009
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 29 May 2009 20:12:15 +0200 (CEST)
Subject: [pypy-svn] r65501 - in pypy/branch/pyjitpl5-experiments/pypy:
module/pypyjit objspace/std
Message-ID: <20090529181215.7672816A029@codespeak.net>
Author: cfbolz
Date: Fri May 29 20:12:14 2009
New Revision: 65501
Modified:
pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/policy.py
pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py
Log:
Remove one dictionary lookup in the residual code for an attribute access when
using shared dicts.
Modified: pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/policy.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/policy.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/module/pypyjit/policy.py Fri May 29 20:12:14 2009
@@ -35,7 +35,6 @@
# gc_id operation
if func.__name__ == 'id__ANY':
return False
- return True
# floats
if mod == 'pypy.rlib.rbigint':
#if func.__name__ == '_bigint_true_divide':
Modified: pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/objspace/std/dictmultiobject.py Fri May 29 20:12:14 2009
@@ -711,6 +711,16 @@
self.other_structs[added_key] = new_structure
return new_structure
+ def lookup_position(self, key):
+ # jit helper
+ self = hint(self, promote=True)
+ key = hint(key, promote=True)
+ return _lookup_position_shared(self, key)
+
+ at purefunction
+def _lookup_position_shared(self, key):
+ return self.keys.get(key, -1)
+
class State(object):
def __init__(self, space):
@@ -730,8 +740,8 @@
w_lookup_type = space.type(w_lookup)
if space.is_w(w_lookup_type, space.w_str):
lookup = space.str_w(w_lookup)
- i = self.structure.keys.get(lookup, -1)
- if i < 0:
+ i = self.structure.lookup_position(lookup)
+ if i == -1:
return None
return self.entries[i]
elif _is_sane_hash(space, w_lookup_type):
@@ -748,8 +758,8 @@
def setitem_str(self, w_key, w_value, shadows_type=True):
key = self.space.str_w(w_key)
- i = self.structure.keys.get(key, -1)
- if i >= 0:
+ i = self.structure.lookup_position(key)
+ if i != -1:
self.entries[i] = w_value
return self
if not self.structure.propagating:
From fijal at codespeak.net Fri May 29 20:27:49 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 20:27:49 +0200 (CEST)
Subject: [pypy-svn] r65502 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86
Message-ID: <20090529182749.8137416A030@codespeak.net>
Author: fijal
Date: Fri May 29 20:27:46 2009
New Revision: 65502
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
Log:
different register allocator. it's horribly inneficient in terms of time it
takes, but I want to measure the difference of resulting assembler first
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py Fri May 29 20:27:46 2009
@@ -285,6 +285,7 @@
def _walk_operations(self, operations):
i = 0
+ self.operations = operations
while i < len(operations):
op = operations[i]
self.position = i
@@ -572,6 +573,14 @@
except KeyError:
return self.stack_bindings[v]
+ def _compute_next_usage(self, v, pos):
+ for i in range(pos, len(self.operations)):
+ if v in self.operations[i].args:
+ return i
+ if i > self.longevity[v][1]:
+ return -1
+ return -1
+
def pick_variable_to_spill(self, v, forbidden_vars, selected_reg=None):
# XXX could be improved
if v in self.jump_reg_candidates and (selected_reg is None or
@@ -580,12 +589,24 @@
if (reg is self.jump_reg_candidates[v] and
var not in forbidden_vars):
return var
- iter = self.reg_bindings.iterkeys()
- while 1:
- next = iter.next()
+ candidates = []
+ for next in self.reg_bindings:
if (next not in forbidden_vars and selected_reg is None or
self.reg_bindings[next] is selected_reg):
- return next
+ candidates.append(next)
+ assert candidates
+ if len(candidates) == 1:
+ return candidates[0]
+ max = 0
+ choosen = None
+ for one in candidates:
+ next_usage = self._compute_next_usage(one, self.position)
+ if next_usage == -1:
+ return one
+ elif next_usage > max:
+ next_usage = max
+ chosen = one
+ return chosen
def move_variable_away(self, v, prev_loc):
reg = None
From fijal at codespeak.net Fri May 29 20:29:50 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 20:29:50 +0200 (CEST)
Subject: [pypy-svn] r65503 -
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86
Message-ID: <20090529182950.59CA216A033@codespeak.net>
Author: fijal
Date: Fri May 29 20:29:48 2009
New Revision: 65503
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
Log:
typo
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/x86/regalloc.py Fri May 29 20:29:48 2009
@@ -598,7 +598,7 @@
if len(candidates) == 1:
return candidates[0]
max = 0
- choosen = None
+ chosen = None
for one in candidates:
next_usage = self._compute_next_usage(one, self.position)
if next_usage == -1:
From fijal at codespeak.net Fri May 29 20:31:09 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 20:31:09 +0200 (CEST)
Subject: [pypy-svn] r65504 -
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp
Message-ID: <20090529183109.D196E16A020@codespeak.net>
Author: fijal
Date: Fri May 29 20:31:09 2009
New Revision: 65504
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
Log:
Ekhem
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/metainterp/codewriter.py Fri May 29 20:31:09 2009
@@ -931,8 +931,11 @@
op.result)
pure = False
if op.opname == "direct_call":
- func = get_funcobj(op.args[0].value)._callable
- pure = getattr(func, "_pure_function_", False)
+ func = getattr(get_funcobj(op.args[0].value), '_callable', None)
+ if func is None:
+ pure = getattr(func, "_pure_function_", False)
+ else:
+ pure = False # a portal, likely
try:
canraise = self.raise_analyzer.can_raise(op)
except lltype.DelayedPointer:
From fijal at codespeak.net Fri May 29 21:19:06 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 21:19:06 +0200 (CEST)
Subject: [pypy-svn] r65505 -
pypy/branch/pyjitpl5-experiments/pypy/interpreter
Message-ID: <20090529191906.2DB0B16A020@codespeak.net>
Author: fijal
Date: Fri May 29 21:19:03 2009
New Revision: 65505
Modified:
pypy/branch/pyjitpl5-experiments/pypy/interpreter/function.py
Log:
reintroduce the hint, it might have been a bad idea to remove
Modified: pypy/branch/pyjitpl5-experiments/pypy/interpreter/function.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/interpreter/function.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/interpreter/function.py Fri May 29 21:19:03 2009
@@ -11,6 +11,7 @@
from pypy.interpreter.baseobjspace import Wrappable
from pypy.interpreter.eval import Code
from pypy.interpreter.argument import Arguments, ArgumentsFromValuestack
+from pypy.rlib.jit import hint
funccallunrolling = unrolling_iterable(range(4))
@@ -45,7 +46,7 @@
return self.code.funcrun_obj(self, w_obj, args)
def getcode(self):
- return self.code
+ return hint(self.code, promote=True)
def funccall(self, *args_w): # speed hack
from pypy.interpreter import gateway
From fijal at codespeak.net Fri May 29 21:27:15 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 21:27:15 +0200 (CEST)
Subject: [pypy-svn] r65506 - in
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm: . test
Message-ID: <20090529192715.DAF5F16A050@codespeak.net>
Author: fijal
Date: Fri May 29 21:27:12 2009
New Revision: 65506
Modified:
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/conftest.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py
pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_runner.py
Log:
unskip the test and disable tail calls.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/conftest.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/conftest.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/conftest.py Fri May 29 21:27:12 2009
@@ -1,5 +1 @@
import py
-
-class Directory(py.test.collect.Directory):
- def consider_dir(self, path):
- py.test.skip("llvm-jit tests skipped")
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/demo2.cpp Fri May 29 21:27:12 2009
@@ -1,7 +1,5 @@
/* LLVM includes */
-
#include
-#include "llvm/LinkAllPasses.h"
#include "llvm-c/ExecutionEngine.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
@@ -15,7 +13,7 @@
*/
void _LLVM_SetFlags(void)
{
- PerformTailCallOpt = true;
+ //PerformTailCallOpt = true;
}
/* This piece of code regroups conveniently a part of the initialization.
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/llvm_rffi.py Fri May 29 21:27:12 2009
@@ -31,10 +31,10 @@
o1name = os.path.join(dirname, 'demo1.o')
o2name = os.path.join(dirname, 'demo2.o')
- do("gcc -c '%s' -o '%s' -I/home/fijal/load/llvm/include" % (cname, o1name))
- do("g++ -c '%s' -o '%s' `%s --cppflags`" % (cppname, o2name, llvm_config))
- do("g++ -shared '%s' '%s' -o '%s' " % (o1name, o2name, libname) +
- " `%s --cflags --ldflags --libs jit engine` -lLLVMInstrumentation -lLLVMipo -lLLVMipa -lLLVMTransformUtils -lLLVMAnalysis -lLLVMCore" % llvm_config)
+ do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cname, o1name, llvm_config))
+ do("g++ -g -c '%s' -o '%s' `%s --cppflags`" % (cppname, o2name, llvm_config))
+ do("g++ -g -shared '%s' '%s' -o '%s'" % (o1name, o2name, libname) +
+ " `%s --cflags --ldflags --libs jit engine`" % llvm_config)
compilation_info = ExternalCompilationInfo(
library_dirs = [dirname],
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py Fri May 29 21:27:12 2009
@@ -26,8 +26,8 @@
def setup_once(self):
if not we_are_translated():
teardown_now()
- self.module = llvm_rffi.LLVMModuleCreateWithName("pypyjit")
llvm_rffi.LLVM_SetFlags()
+ self.module = llvm_rffi.LLVMModuleCreateWithName("pypyjit")
if sys.maxint == 2147483647:
self.ty_int = llvm_rffi.LLVMInt32Type()
else:
@@ -269,7 +269,7 @@
def execute_operations(self, loop):
print 'execute_operations: %s' % (loop._llvm_func_addr,)
- import time; time.sleep(2)
+ #import time; time.sleep(2)
res = loop._llvm_entry_stub(loop._llvm_func_addr)
print '\t--->', res
return self.fail_ops[res]
Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_runner.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/test/test_runner.py Fri May 29 21:27:12 2009
@@ -50,6 +50,7 @@
cpu.set_future_value_int(2, 0)
cpu.execute_operations(loop)
assert cpu.get_latest_value_int(0) == 3*(2**11)
+ py.test.skip("fails because tail-recursion is not handled yet")
cpu.set_future_value_int(0, 2**29)
cpu.set_future_value_int(1, 3)
cpu.set_future_value_int(2, 0)
From fijal at codespeak.net Fri May 29 22:20:58 2009
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 29 May 2009 22:20:58 +0200 (CEST)
Subject: [pypy-svn] r65507 -
pypy/branch/pyjitpl5-experiments/pypy/interpreter
Message-ID: <20090529202058.07AC5169E97@codespeak.net>
Author: fijal
Date: Fri May 29 22:20:58 2009
New Revision: 65507
Modified:
pypy/branch/pyjitpl5-experiments/pypy/interpreter/nestedscope.py
pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py
Log:
move a hints a bit around, change the way things are called to pass
args instead of attributes on self
Modified: pypy/branch/pyjitpl5-experiments/pypy/interpreter/nestedscope.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/interpreter/nestedscope.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/interpreter/nestedscope.py Fri May 29 22:20:58 2009
@@ -82,9 +82,8 @@
cells = None
- def initialize_frame_scopes(self, closure):
- super_initialize_frame_scopes(self, closure)
- code = self.pycode
+ def initialize_frame_scopes(self, closure, code):
+ super_initialize_frame_scopes(self, closure, code)
ncellvars = len(code.co_cellvars)
nfreevars = len(code.co_freevars)
if not nfreevars:
Modified: pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py (original)
+++ pypy/branch/pyjitpl5-experiments/pypy/interpreter/pyframe.py Fri May 29 22:20:58 2009
@@ -58,10 +58,10 @@
self.builtin = space.builtin.pick_builtin(w_globals)
# regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
# class bodies only have CO_NEWLOCALS.
- self.initialize_frame_scopes(closure)
+ self.initialize_frame_scopes(closure, code)
self.fastlocals_w = [None]*self.numlocals
make_sure_not_resized(self.fastlocals_w)
- self.f_lineno = self.pycode.co_firstlineno
+ self.f_lineno = code.co_firstlineno
def get_builtin(self):
if self.space.config.objspace.honor__builtins__:
@@ -69,13 +69,13 @@
else:
return self.space.builtin
- def initialize_frame_scopes(self, closure):
+ def initialize_frame_scopes(self, closure, code):
# regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
# class bodies only have CO_NEWLOCALS.
# CO_NEWLOCALS: make a locals dict unless optimized is also set
# CO_OPTIMIZED: no locals dict needed at all
# NB: this method is overridden in nestedscope.py
- flags = self.pycode.co_flags
+ flags = code.co_flags
if flags & pycode.CO_OPTIMIZED:
return
if flags & pycode.CO_NEWLOCALS:
@@ -86,7 +86,7 @@
def run(self):
"""Start this frame's execution."""
- if self.pycode.co_flags & pycode.CO_GENERATOR:
+ if self.getcode().co_flags & pycode.CO_GENERATOR:
from pypy.interpreter.generator import GeneratorIterator
return self.space.wrap(GeneratorIterator(self))
else:
@@ -361,7 +361,7 @@
return self.pycode.hidden_applevel
def getcode(self):
- return self.pycode
+ return hint(self.pycode, promote=True)
def getfastscope(self):
"Get the fast locals as a list."
From david at codespeak.net Sat May 30 15:57:31 2009
From: david at codespeak.net (david at codespeak.net)
Date: Sat, 30 May 2009 15:57:31 +0200 (CEST)
Subject: [pypy-svn] r65508 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090530135731.751A216A054@codespeak.net>
Author: david
Date: Sat May 30 15:57:28 2009
New Revision: 65508
Modified:
pypy/branch/io-lang/pypy/lang/io/map.py
pypy/branch/io-lang/pypy/lang/io/model.py
pypy/branch/io-lang/pypy/lang/io/test/test_map.py
Log:
Added Map type for key value based collections, extended all types by a hash method and impelemented some Map methods
Modified: pypy/branch/io-lang/pypy/lang/io/map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/map.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/map.py Sat May 30 15:57:28 2009
@@ -1,6 +1,10 @@
from pypy.lang.io.register import register_method
@register_method('Map', 'atPut', unwrap_spec=[object, object, object])
-def map_at_put(space, target, key, value):
- target.items[key] = value
- return target
\ No newline at end of file
+def map_at_put(space, w_target, w_key, w_value):
+ w_target.at_put(w_key, w_value)
+ return w_target
+
+ at register_method('Map', 'at', unwrap_spec=[object, object])
+def map_at(space, w_target, w_key):
+ return w_target.at(w_key)
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/model.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/model.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/model.py Sat May 30 15:57:28 2009
@@ -11,7 +11,16 @@
def __ne__(self, other):
return not self == other
-
+
+ def hash(self):
+ h = 0
+ for w_x in self.slots:
+ h += w_x.hash()
+ for x in self.protos:
+ h += hash(x)
+
+ return h
+
def lookup(self, name, seen=None):
if seen is None:
seen = {}
@@ -49,6 +58,9 @@
cloned = W_Number(self.space, self.value)
cloned.protos = [self]
return cloned
+
+ def hash(self):
+ return hash(self.value)
class W_List(W_Object):
def __init__(self, space, protos = [], items = []):
@@ -72,6 +84,12 @@
l = self.clone()
l.items += items
return l
+
+ def hash(self):
+ h = 0
+ for x in self.items:
+ h += x.hash()
+ return h
class W_Map(W_Object):
"""A key/value dictionary appropriate for holding large key/value collections."""
@@ -82,10 +100,30 @@
def clone(self):
return W_Map(self.space, [self], dict(self.items))
+ def hash(self):
+ h = 0
+ for key, val in self.items:
+ h += key + val.hash()
+ return h
+
+ def at(self, w_key):
+ return self.items[w_key.hash()].value
+
+ def at_put(self, w_key, w_value):
+ self.items[w_key.hash()] = MapEntry(w_key, w_value)
+
+class MapEntry(object):
+ def __init__(self, w_key, w_value):
+ self.key = w_key
+ self.value = w_value
+
+
class W_ImmutableSequence(W_Object):
def __init__(self, space, string):
self.value = string
-
+
+ def hash(self):
+ return hash(self.value)
class W_CFunction(W_Object):
def __init__(self, space, function):
@@ -95,6 +133,9 @@
def apply(self, space, w_receiver, w_message, w_context):
return self.function(space, w_receiver, w_message, w_context)
+ def hash(self):
+ return hash(self.function)
+
class W_Message(W_Object):
def __init__(self, space, name, arguments, next = None):
self.name = name
@@ -106,7 +147,12 @@
def __repr__(self):
return "Message(%r, %r, %r)" % (self.name, self.arguments, self.next)
-
+ def hash(self):
+ h = hash(self.name)
+ for x in self.arguments:
+ h += x.hash()
+ return h
+
def eval(self, space, w_receiver, w_context):
if self.name == ';':
# xxx is this correct?
@@ -168,6 +214,13 @@
def clone_and_init(self, space, arguments, body, activateable):
return W_Block(space, arguments, body, activateable, [self])
+ def hash(self):
+ h = self.body.hash()
+ for x in self.arguments:
+ h += x.hash()
+ return h
+
+
def parse_hex(string):
if not string.startswith("0x"):
raise ValueError
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_map.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_map.py Sat May 30 15:57:28 2009
@@ -18,7 +18,17 @@
def test_at_put():
inp = 'Map clone atPut("foo", "bar")'
res, space = interpret(inp)
- keys = [(key.value) for key in res.items.keys()]
+ keys = [(entry.key.value) for entry in res.items.values()]
assert keys == ['foo']
- values = [(val.value) for val in res.items.values()]
- assert values == ['bar']
\ No newline at end of file
+ values = [(entry.value.value) for entry in res.items.values()]
+ assert values == ['bar']
+
+def test_at():
+ inp = 'Map clone atPut("foo", "bar") atPut("lorem", "ipsum") at("foo")'
+ res, space = interpret(inp)
+ assert res.value == 'bar'
+
+def test_key_hashing():
+ inp = 'Map clone atPut(1, "bar") atPut(nil, "ipsum") atPut("foo", 123) at(nil)'
+ res, space = interpret(inp)
+ assert res.value == 'ipsum'
\ No newline at end of file
From david at codespeak.net Sat May 30 16:10:58 2009
From: david at codespeak.net (david at codespeak.net)
Date: Sat, 30 May 2009 16:10:58 +0200 (CEST)
Subject: [pypy-svn] r65509 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090530141058.ED1C516A03F@codespeak.net>
Author: david
Date: Sat May 30 16:10:56 2009
New Revision: 65509
Modified:
pypy/branch/io-lang/pypy/lang/io/map.py
pypy/branch/io-lang/pypy/lang/io/test/test_map.py
Log:
Restricted keys in maps to strings
Modified: pypy/branch/io-lang/pypy/lang/io/map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/map.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/map.py Sat May 30 16:10:56 2009
@@ -1,10 +1,12 @@
from pypy.lang.io.register import register_method
-
+from pypy.lang.io.model import W_ImmutableSequence
@register_method('Map', 'atPut', unwrap_spec=[object, object, object])
def map_at_put(space, w_target, w_key, w_value):
+ assert isinstance(w_key, W_ImmutableSequence)
w_target.at_put(w_key, w_value)
return w_target
@register_method('Map', 'at', unwrap_spec=[object, object])
def map_at(space, w_target, w_key):
+ assert isinstance(w_key, W_ImmutableSequence)
return w_target.at(w_key)
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_map.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_map.py Sat May 30 16:10:56 2009
@@ -29,6 +29,6 @@
assert res.value == 'bar'
def test_key_hashing():
- inp = 'Map clone atPut(1, "bar") atPut(nil, "ipsum") atPut("foo", 123) at(nil)'
+ inp = 'Map clone atPut("1", "bar") atPut("nil", "ipsum") atPut("foo", 123) at("nil")'
res, space = interpret(inp)
assert res.value == 'ipsum'
\ No newline at end of file
From david at codespeak.net Sat May 30 17:14:44 2009
From: david at codespeak.net (david at codespeak.net)
Date: Sat, 30 May 2009 17:14:44 +0200 (CEST)
Subject: [pypy-svn] r65510 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090530151444.9A259169FD1@codespeak.net>
Author: david
Date: Sat May 30 17:14:42 2009
New Revision: 65510
Modified:
pypy/branch/io-lang/pypy/lang/io/map.py
pypy/branch/io-lang/pypy/lang/io/model.py
pypy/branch/io-lang/pypy/lang/io/test/test_map.py
Log:
Implemented Builtin Map CFunction methods
Modified: pypy/branch/io-lang/pypy/lang/io/map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/map.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/map.py Sat May 30 17:14:42 2009
@@ -1,5 +1,6 @@
from pypy.lang.io.register import register_method
-from pypy.lang.io.model import W_ImmutableSequence
+from pypy.lang.io.model import W_ImmutableSequence, W_Number, W_List
+
@register_method('Map', 'atPut', unwrap_spec=[object, object, object])
def map_at_put(space, w_target, w_key, w_value):
assert isinstance(w_key, W_ImmutableSequence)
@@ -9,4 +10,57 @@
@register_method('Map', 'at', unwrap_spec=[object, object])
def map_at(space, w_target, w_key):
assert isinstance(w_key, W_ImmutableSequence)
- return w_target.at(w_key)
\ No newline at end of file
+ return w_target.at(w_key)
+
+ at register_method('Map', 'empty')
+def map_empty(space, w_target, w_message, w_context):
+ w_target.empty()
+ return w_target
+
+ at register_method('Map', 'atIfAbsentPut', unwrap_spec=[object, object, object])
+def map_at_if_absent_put(space, w_target, w_key, w_value):
+ assert isinstance(w_key, W_ImmutableSequence)
+ if w_target.has_key(w_key):
+ return w_target.at(w_key)
+ w_target.at_put(w_key, w_value)
+ return w_value
+
+ at register_method('Map', 'hasKey', unwrap_spec=[object, object])
+def map_has_key(space, w_target, w_key):
+ assert isinstance(w_key, W_ImmutableSequence)
+ if w_target.has_key(w_key):
+ return space.w_true
+ return space.w_false
+
+ at register_method('Map', 'size')
+def map_size(space, w_target, w_message, w_context):
+ return W_Number(space, w_target.size())
+
+ at register_method('Map', 'removeAt', unwrap_spec=[object, object])
+def map_has_key(space, w_target, w_key):
+ assert isinstance(w_key, W_ImmutableSequence)
+ w_target.remove_at(w_key)
+ return w_target
+
+ at register_method('Map', 'hasValue', unwrap_spec=[object, object])
+def map_has_value(space, w_target, w_value):
+ if w_target.has_value(w_value):
+ return space.w_true
+ return space.w_false
+
+ at register_method('Map', 'values')
+def map_values(space, w_target, w_message, w_context):
+ return space.w_list.clone_and_init(space, w_target.values())
+
+ at register_method('Map', 'foreach')
+def map_foreach(space, w_target, w_message, w_context):
+ argcount = len(w_message.arguments)
+ assert argcount == 3
+ key = w_message.arguments[0].name
+ value = w_message.arguments[1].name
+
+ return w_target.foreach(space, key, value, w_message.arguments[2], w_context)
+
+ at register_method('Map', 'keys')
+def map_keys(space, w_target, w_message, w_context):
+ return space.w_list.clone_and_init(space, w_target.keys())
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/model.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/model.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/model.py Sat May 30 17:14:42 2009
@@ -112,6 +112,40 @@
def at_put(self, w_key, w_value):
self.items[w_key.hash()] = MapEntry(w_key, w_value)
+ def empty(self):
+ self.items.clear()
+
+ def has_key(self, w_key):
+ return w_key.hash() in self.items
+
+ def size(self):
+ return len(self.items)
+
+ def remove_at(self, w_key):
+ try:
+ del(self.items[w_key.hash()])
+ except Exception, e:
+ pass
+
+ def has_value(self, w_value):
+ for x in self.items.values():
+ if x.value == x:
+ return True
+ return False
+
+ def values(self):
+ return [x.value for x in self.items.values()]
+
+ def foreach(self, space, key_name, value_name, w_body, w_context):
+ for item in self.items.values():
+ w_context.slots[key_name] = item.key
+ w_context.slots[value_name] = item.value
+ t = w_body.eval(space, w_context, w_context)
+ return t
+
+ def keys(self):
+ return [x.key for x in self.items.values()]
+
class MapEntry(object):
def __init__(self, w_key, w_value):
self.key = w_key
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_map.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_map.py Sat May 30 17:14:42 2009
@@ -1,5 +1,5 @@
from pypy.lang.io.parserhack import parse, interpret
-from pypy.lang.io.model import W_Map, W_Number, W_ImmutableSequence
+from pypy.lang.io.model import W_Map, W_Number, W_ImmutableSequence, W_List
import py.test
def test_map_proto():
@@ -31,4 +31,88 @@
def test_key_hashing():
inp = 'Map clone atPut("1", "bar") atPut("nil", "ipsum") atPut("foo", 123) at("nil")'
res, space = interpret(inp)
- assert res.value == 'ipsum'
\ No newline at end of file
+ assert res.value == 'ipsum'
+
+def test_empty():
+ inp = 'Map clone atPut("1", "bar") atPut("nil", "ipsum") atPut("foo", 123) empty'
+ res, space = interpret(inp)
+ assert res.items == {}
+
+def test_atIfAbsentPut():
+ inp = 'Map clone atPut("1", nil) atIfAbsentPut("1", "lorem")'
+ res, space = interpret(inp)
+ assert res == space.w_nil
+
+ inp = 'Map clone atPut("2", "bar") atIfAbsentPut("1", "lorem")'
+ res, space = interpret(inp)
+ assert res.value == 'lorem'
+
+def test_has_key():
+ inp = 'Map clone atPut("1", nil) atPut("2", "lorem") hasKey("1")'
+ res, space = interpret(inp)
+ assert res == space.w_true
+
+ inp = 'Map clone atPut("1", nil) atPut("2", "lorem") hasKey("99")'
+ res, space = interpret(inp)
+ assert res == space.w_false
+
+def test_size():
+ inp = 'Map clone size'
+ res, space = interpret(inp)
+ assert res.value == 0
+
+ inp = 'Map clone atPut("1", nil) atPut("2", "lorem") size'
+ res, space = interpret(inp)
+ assert res.value == 2
+
+def test_remve_at():
+ inp = 'Map clone atPut("1", "nil") atPut("2", "lorem") atPut("3", 3) atPut("4", 234) removeAt("2")'
+ res, space = interpret(inp)
+ keys = [(entry.key.value) for entry in res.items.values()]
+ assert keys == ['1', '3', '4']
+ values = [(entry.value.value) for entry in res.items.values()]
+ assert values == ['nil', 3, 234]
+
+def test_has_value():
+ inp = 'Map clone atPut("1", "nil") atPut("2", "lorem") atPut("3", 3) atPut("4", 234) hasValue("234")'
+ res, space = interpret(inp)
+ assert res == space.w_true
+
+ inp = 'Map clone atPut("1", "nil") atPut("2", "lorem") atPut("3", 3) atPut("4", 234) hasValue("1234567890")'
+ res, space = interpret(inp)
+ assert res == space.w_false
+
+def test_values():
+ inp = 'Map clone atPut("1", 12345) atPut("2", 99) atPut("3", 3) atPut("4", 234) values'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ values = [x.value for x in res.items]
+ should = [12345, 99, 3, 234]
+ assert len(should) == len(values)
+ for x in values:
+ assert x in should
+
+def test_foreach():
+ inp = """b := Map clone do(
+ atPut("1", 12345)
+ atPut("2", 99)
+ atPut("3", 3)
+ atPut("4", 234)
+ )
+ c := list()
+ b foreach(key, value, c append(list(key, value))); c"""
+ res,space = interpret(inp)
+ value = sorted([(x.items[0].value, x.items[1].value) for x in res.items])
+ assert value == [('1', 12345), ('2', 99), ('3', 3), ('4', 234)]
+
+def test_keys():
+ inp = """b := Map clone do(
+ atPut("1", 12345)
+ atPut("2", 99)
+ atPut("3", 3)
+ atPut("4", 234)
+ )
+ b keys"""
+ res, space = interpret(inp)
+ keys = sorted([x.value for x in res.items])
+ assert keys == ['1', '2', '3', '4']
\ No newline at end of file
From david at codespeak.net Sun May 31 18:06:24 2009
From: david at codespeak.net (david at codespeak.net)
Date: Sun, 31 May 2009 18:06:24 +0200 (CEST)
Subject: [pypy-svn] r65515 - in pypy/branch/io-lang/pypy/lang/io: . test
Message-ID: <20090531160624.2033C169F53@codespeak.net>
Author: david
Date: Sun May 31 18:06:24 2009
New Revision: 65515
Modified:
pypy/branch/io-lang/pypy/lang/io/list.py
pypy/branch/io-lang/pypy/lang/io/test/test_list.py
Log:
fixed List first, when called w/o a number, added last, reverseInPlace, removeAll, atPut methods to list
Modified: pypy/branch/io-lang/pypy/lang/io/list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/list.py Sun May 31 18:06:24 2009
@@ -65,7 +65,7 @@
return W_Number(space, len(w_target.items))
@register_method('List', 'first')
-def list_size(space, w_target, w_message, w_context):
+def list_first(space, w_target, w_message, w_context):
if len(w_message.arguments) != 0:
t = w_message.arguments[0].eval(space, w_target, w_context)
assert isinstance(t, W_Number)
@@ -75,10 +75,61 @@
if len(w_target.items) == 0 and nfirst == 1:
return space.w_nil
-
+
+ if nfirst == 1:
+ return w_target.items[0]
flist_w = w_target.clone()
if nfirst < 1:
flist_w.items = []
else:
flist_w.items = flist_w.items[0:nfirst]
- return flist_w
\ No newline at end of file
+ return flist_w
+
+ at register_method('List', 'last')
+def list_last(space, w_target, w_message, w_context):
+ if len(w_message.arguments) != 0:
+ t = w_message.arguments[0].eval(space, w_target, w_context)
+ assert isinstance(t, W_Number)
+ nlast = t.value
+ else:
+ nlast = 1
+
+ if len(w_target.items) == 0 and nlast == 1:
+ return space.w_nil
+
+ if nlast == 1:
+ return w_target.items[-1]
+ flist_w = w_target.clone()
+ if nlast < 1:
+ flist_w.items = []
+ else:
+ flist_w.items = flist_w.items[len(flist_w.items)-nlast:]
+ return flist_w
+
+ at register_method('List', 'reverseInPlace')
+def list_reverse_in_place(space, w_target, w_message, w_context):
+ w_target.items.reverse()
+ return w_target
+
+ at register_method('List', 'removeAll')
+def list_remove_all(space, w_target, w_message, w_context):
+ try:
+ w_target.items = []
+ except Exception, e:
+ raise Exception, 'index out of bounds'
+
+ return w_target
+
+ at register_method('List', 'atPut')
+def list_reverse_in_place(space, w_target, w_message, w_context):
+ w_key = w_message.arguments[0].eval(space, w_target, w_context)
+ assert isinstance(w_key, W_Number), "argument 0 to method 'atPut' must be a Number"
+ key = w_key.value
+ if len(w_message.arguments) > 1:
+ w_value = w_message.arguments[1].eval(space, w_target, w_context)
+ else:
+ w_value = space.w_nil
+
+ w_target.items[key] = w_value
+ return w_target
+
\ No newline at end of file
Modified: pypy/branch/io-lang/pypy/lang/io/test/test_list.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_list.py (original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_list.py Sun May 31 18:06:24 2009
@@ -133,13 +133,86 @@
def test_list_first():
inp = 'a := list(9,8,7,6,5,4,3,2,1,1); a first'
res, space = interpret(inp)
- assert isinstance(res, W_List)
- assert res.items[0].value == 9
- assert res.protos == [space.w_lobby.slots['a']]
+ assert isinstance(res, W_Number)
+ assert res.value == 9
def test_list_first_n():
inp = 'a := list(9,8,7,6,5,4,3,2,1,1); a first(3)'
res, space = interpret(inp)
assert isinstance(res, W_List)
assert [x.value for x in res.items] == [9,8,7]
- assert res.protos == [space.w_lobby.slots['a']]
\ No newline at end of file
+ assert res.protos == [space.w_lobby.slots['a']]
+
+def test_list_last():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a last'
+ res, space = interpret(inp)
+ assert isinstance(res, W_Number)
+ assert res.value == 100
+
+def test_list_last_n():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a last(3)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == [2, 1, 100]
+ assert res.protos == [space.w_lobby.slots['a']]
+
+def test_list_first_n_overflow():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a first(20)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == [9,8,7,6,5,4,3,2,1,100]
+ assert res.protos == [space.w_lobby.slots['a']]
+
+
+def test_list_last_n_overflow():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a last(20)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == [9,8,7,6,5,4,3,2,1,100]
+ assert res.protos == [space.w_lobby.slots['a']]
+
+
+def test_empty_list_first_n():
+ inp = 'a := list(); a first(20)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == []
+ assert res.protos == [space.w_lobby.slots['a']]
+
+def test_empty_list_last_n():
+ inp = 'a := list(); a last(20)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == []
+ assert res.protos == [space.w_lobby.slots['a']]
+
+def test_reverse_in_place():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a reverseInPlace'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == [100,1,2,3,4,5,6,7,8,9]
+
+def test_remove_all():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a removeAll; a'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == []
+
+def test_at_put():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a atPut(3, 1045)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ assert [x.value for x in res.items] == [9,8,7, 1045, 5, 4, 3, 2, 1, 100]
+
+def test_at_put_raises():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a atPut(1000, 1045)'
+ py.test.raises(Exception, 'interpret(inp)')
+
+def test_at_put_wo_value():
+ inp = 'a := list(9,8,7,6,5,4,3,2,1,100); a atPut(3)'
+ res, space = interpret(inp)
+ assert isinstance(res, W_List)
+ nums = [W_Number(space, i) for i in range(9, 0, -1)]
+ nums[3] = space.w_nil
+ nums.append(W_Number(space, 100))
+ assert [x for x in res.items] == nums
From arigo at codespeak.net Sun May 31 18:57:09 2009
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sun, 31 May 2009 18:57:09 +0200 (CEST)
Subject: [pypy-svn] r65516 - pypy/trunk/pypy/rpython/memory/gc
Message-ID: <20090531165709.95253169F87@codespeak.net>
Author: arigo
Date: Sun May 31 18:57:08 2009
New Revision: 65516
Modified:
pypy/trunk/pypy/rpython/memory/gc/semispace.py
Log:
Fix nonsense output when config.gcconfig.debugprint is set.
Modified: pypy/trunk/pypy/rpython/memory/gc/semispace.py
==============================================================================
--- pypy/trunk/pypy/rpython/memory/gc/semispace.py (original)
+++ pypy/trunk/pypy/rpython/memory/gc/semispace.py Sun May 31 18:57:08 2009
@@ -208,11 +208,12 @@
"| used before collection: ",
start_usage, "bytes")
start_time = time.time()
+ else:
+ start_time = 0 # Help the flow space
+ start_usage = 0 # Help the flow space
#llop.debug_print(lltype.Void, 'semispace_collect', int(size_changing))
tospace = self.fromspace
fromspace = self.tospace
- start_time = 0 # Help the flow space
- start_usage = 0 # Help the flow space
self.fromspace = fromspace
self.tospace = tospace
self.top_of_space = tospace + self.space_size
From pedronis at codespeak.net Sun May 31 22:21:23 2009
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Sun, 31 May 2009 22:21:23 +0200 (CEST)
Subject: [pypy-svn] r65518 - pypy/build/bot2/pypybuildbot
Message-ID: <20090531202123.2B806169E44@codespeak.net>
Author: pedronis
Date: Sun May 31 22:21:21 2009
New Revision: 65518
Modified:
pypy/build/bot2/pypybuildbot/master.py
Log:
try the current jit branch tonight
Modified: pypy/build/bot2/pypybuildbot/master.py
==============================================================================
--- pypy/build/bot2/pypybuildbot/master.py (original)
+++ pypy/build/bot2/pypybuildbot/master.py Sun May 31 22:21:21 2009
@@ -54,8 +54,10 @@
Nightly("nightly", [LINUX32, CPYLINUX32, APPLVLLINUX32, CPYWIN32,
STACKLESSAPPLVLLINUX32],
hour=4, minute=45),
+ #Nightly("nightly-jit", [LINUX32, JITLINUX32],
+ # hour=1, minute=45, branch="branch/pyjitpl5"),
Nightly("nightly-jit", [LINUX32, JITLINUX32],
- hour=1, minute=45, branch="branch/pyjitpl5"),
+ hour=1, minute=45, branch="branch/pyjitpl5-experiments"),
],
'status': [status],