[pypy-commit] lang-smalltalk 64bit-c2: Merged default
Hubert Hesse
noreply at buildbot.pypy.org
Fri May 2 12:52:21 CEST 2014
Author: Hubert Hesse <hubert.hesse at student.hpi.uni-potsdam.de>
Branch: 64bit-c2
Changeset: r796:e6c406381c28
Date: 2014-04-24 14:41 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/e6c406381c28/
Log: Merged default
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -12,3 +12,5 @@
versions
coglinux
*.orig
+spy-*.log
+SDL.dll
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -15,12 +15,14 @@
that create W_PointersObjects of correct size with attached shadows.
"""
import sys, weakref
-from spyvm import constants, error, system
+from spyvm import constants, error, version, system
+from spyvm.version import elidable_for_version
from rpython.rlib import rrandom, objectmodel, jit, signature
from rpython.rlib.rarithmetic import intmask, r_uint32, r_uint, r_int
+from rpython.rlib.debug import make_sure_not_resized
from rpython.tool.pairtype import extendabletype
-from rpython.rlib.objectmodel import instantiate, compute_hash
+from rpython.rlib.objectmodel import instantiate, compute_hash, import_from_mixin
from rpython.rtyper.lltypesystem import lltype, rffi
from rsdl import RSDL, RSDL_helper
@@ -448,7 +450,7 @@
def __str__(self):
if isinstance(self, W_PointersObject) and self.has_shadow():
- return self._shadow.getname()
+ return self._get_shadow().getname()
else:
name = None
if self.has_class():
@@ -488,15 +490,20 @@
class W_AbstractPointersObject(W_AbstractObjectWithClassReference):
"""Common object."""
- _attrs_ = ['_shadow']
+ _attrs_ = ['shadow']
+
+ def changed(self):
+ # This is invoked when an instance-variable is changed.
+ # Kept here in case it might be usefull in the future.
+ pass
- _shadow = None # Default value
+ shadow = None # Default value
@jit.unroll_safe
def __init__(self, space, w_class, size):
"""Create new object with size = fixed + variable size."""
W_AbstractObjectWithClassReference.__init__(self, space, w_class)
- self._shadow = None # Default value
+ self.store_shadow(None)
def fillin(self, space, g_self):
from spyvm.fieldtypes import fieldtypes_of
@@ -514,12 +521,12 @@
def fetch(self, space, n0):
if self.has_shadow():
- return self._shadow.fetch(n0)
+ return self._get_shadow().fetch(n0)
return self._fetch(n0)
def store(self, space, n0, w_value):
if self.has_shadow():
- return self._shadow.store(n0, w_value)
+ return self._get_shadow().store(n0, w_value)
return self._store(n0, w_value)
def varsize(self, space):
@@ -533,13 +540,17 @@
def size(self):
if self.has_shadow():
- return self._shadow.size()
+ return self._get_shadow().size()
return self.basic_size()
def store_shadow(self, shadow):
- assert self._shadow is None or self._shadow is shadow
- self._shadow = shadow
+ assert self.shadow is None or self.shadow is shadow
+ self.shadow = shadow
+ self.changed()
+ def _get_shadow(self):
+ return self.shadow
+
@objectmodel.specialize.arg(2)
def attach_shadow_of_class(self, space, TheClass):
shadow = TheClass(space, self)
@@ -549,7 +560,7 @@
@objectmodel.specialize.arg(2)
def as_special_get_shadow(self, space, TheClass):
- shadow = self._shadow
+ shadow = self._get_shadow()
if not isinstance(shadow, TheClass):
if shadow is not None:
raise DetachingShadowError(shadow, TheClass)
@@ -568,7 +579,7 @@
# Should only be used during squeak-image loading.
def as_class_get_penumbra(self, space):
from spyvm.shadow import ClassShadow
- s_class = self._shadow
+ s_class = self._get_shadow()
if s_class is None:
s_class = ClassShadow(space, self)
self.store_shadow(s_class)
@@ -587,7 +598,7 @@
def as_context_get_shadow(self, space):
from spyvm.shadow import ContextPartShadow
# XXX TODO should figure out itself if its method or block context
- if self._shadow is None:
+ if self._get_shadow() is None:
if ContextPartShadow.is_block_context(self, space):
return self.as_blockcontext_get_shadow(space)
return self.as_methodcontext_get_shadow(space)
@@ -606,17 +617,19 @@
return self.as_special_get_shadow(space, ObserveeShadow)
def has_shadow(self):
- return self._shadow is not None
+ return self._get_shadow() is not None
def become(self, w_other):
if not isinstance(w_other, W_AbstractPointersObject):
return False
# switching means also switching shadows
- self._shadow, w_other._shadow = w_other._shadow, self._shadow
+ self.shadow, w_other.shadow = w_other.shadow, self.shadow
# shadow links are in both directions -> also update shadows
- if self.has_shadow(): self._shadow._w_self = self
- if w_other.has_shadow(): w_other._shadow._w_self = w_other
+ if self.shadow is not None: self.shadow._w_self = self
+ if w_other.shadow is not None: w_other.shadow._w_self = w_other
W_AbstractObjectWithClassReference._become(self, w_other)
+ self.changed()
+ w_other.changed()
return True
@jit.elidable
@@ -633,24 +646,27 @@
from spyvm.fieldtypes import fieldtypes_of_length
"""Create new object with size = fixed + variable size."""
W_AbstractPointersObject.__init__(self, space, w_class, size)
- vars = self._vars = [None] * size
+ vars = [None] * size
+ self.set_vars(vars)
self.fieldtypes = fieldtypes_of_length(self.s_class, size)
for i in range(size): # do it by hand for the JIT's sake
vars[i] = w_nil
-
+
+ def set_vars(self, new_vars):
+ self._vars = new_vars
+ make_sure_not_resized(self._vars)
+
def fillin(self, space, g_self):
W_AbstractPointersObject.fillin(self, space, g_self)
from spyvm.fieldtypes import fieldtypes_of
- self._vars = g_self.get_pointers()
+ self.set_vars(g_self.get_pointers())
self.fieldtypes = fieldtypes_of(self)
def _fetch(self, n0):
- # return self._vars[n0]
fieldtypes = jit.promote(self.fieldtypes)
return fieldtypes.fetch(self, n0)
def _store(self, n0, w_value):
- # self._vars[n0] = w_value
fieldtypes = jit.promote(self.fieldtypes)
return fieldtypes.store(self, n0, w_value)
@@ -671,7 +687,7 @@
def clone(self, space):
w_result = W_PointersObject(self.space, self.getclass(space),
len(self._vars))
- w_result._vars = [self.fetch(space, i) for i in range(len(self._vars))]
+ w_result.set_vars([self.fetch(space, i) for i in range(len(self._vars))])
return w_result
def fieldtype(self):
@@ -996,6 +1012,8 @@
_attrs_ = ['pixelbuffer', '_realsize', '_real_depth_buffer', 'display', '_depth']
_immutable_fields_ = ['_realsize', 'display', '_depth', '_real_depth_buffer']
+ pixelbuffer = None
+
@staticmethod
def create(space, w_class, size, depth, display):
if depth < 8:
@@ -1202,11 +1220,11 @@
if len(self.literals) > 0:
w_candidate = self.literals[-1]
if isinstance(w_candidate, W_PointersObject):
- c_shadow = w_candidate._shadow
+ c_shadow = w_candidate._get_shadow()
if c_shadow is None and w_candidate.size() >= 2:
w_class = w_candidate._fetch(1)
if isinstance(w_class, W_PointersObject):
- d_shadow = w_class._shadow
+ d_shadow = w_class._get_shadow()
if isinstance(d_shadow, shadow.ClassShadow):
classname = d_shadow.getname()
elif isinstance(shadow, shadow.ClassShadow):
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -1,6 +1,6 @@
import os
-from spyvm import constants, model, shadow, wrapper, system
+from spyvm import constants, model, shadow, wrapper, system, version
from spyvm.error import UnwrappingError, WrappingError, PrimitiveFailedError
from rpython.rlib import jit, rpath
from rpython.rlib.objectmodel import instantiate, specialize
@@ -79,7 +79,7 @@
w_Class = self.classtable["w_Class"]
s_Metaclass = self.classtable["w_Metaclass"].as_class_get_penumbra(self)
# XXX
- proto_shadow = w_ProtoObjectClass._shadow
+ proto_shadow = w_ProtoObjectClass.shadow
proto_shadow.store_w_superclass(w_Class)
# at this point, all classes that still lack a w_class are themselves
# metaclasses
@@ -335,7 +335,7 @@
# XXX
s = instantiate(shadow.ClassShadow)
s.space = space
- s.version = shadow.Version()
+ s.version = version.Version()
s._w_self = w_class
s.subclass_s = {}
s._s_superclass = None
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -1,17 +1,10 @@
import weakref
-from spyvm import model, constants, error, wrapper
+from spyvm import model, constants, error, wrapper, version
+from spyvm.version import elidable_for_version, constant_for_version
from rpython.tool.pairtype import extendabletype
from rpython.rlib import rarithmetic, jit
-
-def make_elidable_after_versioning(func):
- @jit.elidable
- def elidable_func(self, version, *args):
- return func(self, *args)
- def meth(self, *args):
- jit.promote(self)
- version = jit.promote(self.version)
- return elidable_func(self, version, *args)
- return meth
+from rpython.rlib.objectmodel import import_from_mixin
+from rpython.rlib.debug import make_sure_not_resized
class AbstractShadow(object):
"""A shadow is an optional extra bit of information that
@@ -38,10 +31,13 @@
class AbstractCachingShadow(AbstractShadow):
_immutable_fields_ = ['version?']
_attrs_ = ['version']
+ import_from_mixin(version.VersionMixin)
+ version = None
+
def __init__(self, space, w_self):
AbstractShadow.__init__(self, space, w_self)
- self.version = Version()
+ self.changed()
def attach_shadow(self):
self.w_self().store_shadow(self)
@@ -59,11 +55,6 @@
AbstractShadow.store(self, n0, w_value)
self.update()
- def change(self):
- self.version = Version()
-
-class Version:
- pass
# ____________________________________________________________
POINTERS = 0
@@ -87,7 +78,7 @@
_attrs_ = ["name", "_instance_size", "instance_varsized", "instance_kind",
"_s_methoddict", "_s_superclass", "subclass_s"]
-
+
def __init__(self, space, w_self):
# fields added here should also be in objspace.py:56ff, 300ff
self.name = ''
@@ -263,12 +254,12 @@
" True if instances of this class have data stored as numerical bytes "
return self.format == BYTES
- @make_elidable_after_versioning
+ @constant_for_version
def isvariable(self):
" True if instances of this class have indexed inst variables "
return self.instance_varsized
- @make_elidable_after_versioning
+ @constant_for_version
def instsize(self):
" Number of named instance variables for each instance of this class "
return self._instance_size
@@ -293,7 +284,7 @@
del self.subclass_s[s_other]
def changed(self):
- self.superclass_changed(Version())
+ self.superclass_changed(version.Version())
# this is done, because the class-hierarchy contains cycles
def superclass_changed(self, version):
@@ -308,7 +299,7 @@
def __repr__(self):
return "<ClassShadow %s>" % (self.name or '?',)
- @make_elidable_after_versioning
+ @constant_for_version
def lookup(self, w_selector):
look_in_shadow = self
while look_in_shadow is not None:
@@ -646,6 +637,7 @@
stacksize = self.stackend() - self.stackstart()
tempsize = self.tempsize()
self._temps_and_stack = [None] * (stacksize + tempsize)
+ make_sure_not_resized(self._temps_and_stack)
for i in range(tempsize):
self._temps_and_stack[i] = self.space.w_nil
self._stack_ptr = rarithmetic.r_uint(tempsize) # we point after the last element
@@ -1033,6 +1025,7 @@
"argsize", "islarge",
"w_compiledin", "version"]
_immutable_fields_ = ["version?", "_w_self"]
+ import_from_mixin(version.VersionMixin)
def __init__(self, w_compiledmethod):
self._w_self = w_compiledmethod
@@ -1041,11 +1034,11 @@
def w_self(self):
return self._w_self
- @make_elidable_after_versioning
+ @constant_for_version
def getliteral(self, index):
return self.literals[index]
- @make_elidable_after_versioning
+ @constant_for_version
def compute_frame_size(self):
# From blue book: normal mc have place for 12 temps+maxstack
# mc for methods with islarge flag turned on 32
@@ -1058,7 +1051,7 @@
def update(self):
w_compiledmethod = self._w_self
- self.version = Version()
+ self.changed()
self.bytecode = "".join(w_compiledmethod.bytes)
self.bytecodeoffset = w_compiledmethod.bytecodeoffset()
self.literalsize = w_compiledmethod.getliteralsize()
@@ -1081,11 +1074,11 @@
association = wrapper.AssociationWrapper(None, w_association)
self.w_compiledin = association.value()
- @make_elidable_after_versioning
+ @constant_for_version
def tempsize(self):
return self._tempsize
- @make_elidable_after_versioning
+ @constant_for_version
def primitive(self):
return self._primitive
@@ -1095,26 +1088,20 @@
space, self, receiver, arguments, sender)
return s_new
- @make_elidable_after_versioning
+ @constant_for_version
def getbytecode(self, pc):
return self.bytecode[pc]
class CachedObjectShadow(AbstractCachingShadow):
+ @elidable_for_version
def fetch(self, n0):
- jit.promote(self)
- version = self.version
- jit.promote(version)
- return self.safe_fetch(n0, version)
-
- @jit.elidable
- def safe_fetch(self, n0, version):
- assert version is self.version
return self._w_self._fetch(n0)
def store(self, n0, w_value):
- self.version = Version()
- return self._w_self._store(n0, w_value)
+ res = self._w_self._store(n0, w_value)
+ self.changed()
+ return res
def update(self): pass
diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py
--- a/spyvm/squeakimage.py
+++ b/spyvm/squeakimage.py
@@ -308,7 +308,7 @@
for chunk in self.chunks.itervalues():
casted = chunk.g_object.w_object
if isinstance(casted, model.W_PointersObject) and casted.has_shadow():
- casted._shadow.update()
+ casted.shadow.update()
def init_compactclassesarray(self):
""" from the blue book (CompiledMethod Symbol Array PseudoContext LargePositiveInteger nil MethodDictionary Association Point Rectangle nil TranslatedMethod BlockContext MethodContext nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil ) """
diff --git a/spyvm/test/jittest/base.py b/spyvm/test/jittest/base.py
--- a/spyvm/test/jittest/base.py
+++ b/spyvm/test/jittest/base.py
@@ -2,8 +2,8 @@
import os
# TODO:
-from pypy.tool.jitlogparser.parser import SimpleParser, Op
-from pypy.tool.jitlogparser.storage import LoopStorage
+from rpython.tool.jitlogparser.parser import SimpleParser, Op
+from rpython.tool.jitlogparser.storage import LoopStorage
from rpython.jit.metainterp.resoperation import opname
from rpython.jit.tool import oparser
diff --git a/spyvm/test/jittest/test_basic.py b/spyvm/test/jittest/test_basic.py
--- a/spyvm/test/jittest/test_basic.py
+++ b/spyvm/test/jittest/test_basic.py
@@ -368,6 +368,123 @@
jump(p0, p3, p8, i557, p538, i562, p18, i545, p38, p40, p42, p44, p46, p48, p50, p52, p54, p56, p58, p60, p62, p64, p66, p68, p70, p72, p74, p76, p78, p80, p82, p84, p86, p88, p90, p92, p94, p96, p98, p100, p102, p104, p106, p108, p110, p112, p114, p116, p118, p120, p122, p124, p126, p128, p130, p132, p134, 1, p148, p717, i158, p156, p718, i165, p163, p146, i715, i179, p178, p719, i197, p188, p213, i221, p220, p228, p140, p242, i250, i252, i282, i293, i328, i315, i349, i510, p509, p538, p521, descr=TargetToken(169555520))]
""")
+ # TODO: there shouldnt be allocations in this
+ def test_range_asOrderedCollection(self, spy, tmpdir):
+ traces = self.run(spy, tmpdir,
+ """
+ (1 to: 10000) asOrderedCollection.
+ """)
+ self.assert_matches(traces[0].loop, """
+ guard_not_invalidated(descr=<Guard0x2b713d0>),
+ p173 = getarrayitem_gc(p53, 1, descr=<ArrayP 4>),
+ i174 = getfield_gc_pure(p173, descr=<FieldS spyvm.model.W_SmallInteger.inst_value 8>),
+ i175 = int_ge(i174, i167),
+ guard_true(i175, descr=<Guard0x2b81490>),
+ cond_call(i75, 4712800, p67, descr=<Callv 0 r EF=2 OS=121>),
+ cond_call(i103, 4712800, p91, descr=<Callv 0 r EF=2 OS=121>),
+ cond_call(i103, 4712800, p91, descr=<Callv 0 r EF=2 OS=121>),
+ p176 = getarrayitem_gc(p105, 0, descr=<ArrayP 4>),
+ cond_call(i103, 4712800, p91, descr=<Callv 0 r EF=2 OS=121>),
+ p178 = new_with_vtable(ConstClass(W_SmallInteger)),
+ setfield_gc(p178, i167, descr=<FieldS spyvm.model.W_SmallInteger.inst_value 8>),
+ setarrayitem_gc(p105, 1, p178, descr=<ArrayP 4>),
+ setarrayitem_gc(p79, 0, p176, descr=<ArrayP 4>),
+ setfield_gc(p67, 2, descr=<FieldU spyvm.shadow.ContextPartShadow.inst__stack_ptr 32>),
+ setfield_gc(p67, 15, descr=<FieldS spyvm.shadow.ContextPartShadow.inst__pc 24>),
+ setfield_gc(p67, p0, descr=<FieldP spyvm.shadow.ContextPartShadow.inst__s_sender 28>),
+ setfield_gc(ConstPtr(ptr81), i88, descr=<FieldS spyvm.interpreter.Interpreter.inst_remaining_stack_depth 40>),
+ setarrayitem_gc(p79, 1, p178, descr=<ArrayP 4>),
+ guard_class(p176, 6040288, descr=<Guard0x2b81410>),
+ p179 = getfield_gc(p176, descr=<FieldP spyvm.model.W_AbstractObjectWithClassReference.inst_s_class 12>),
+ guard_value(p179, ConstPtr(ptr117), descr=<Guard0x2b81390>),
+ p180 = getfield_gc(p176, descr=<FieldP spyvm.model.W_AbstractPointersObject.inst__shadow 20>),
+ setarrayitem_gc(p79, 0, ConstPtr(null), descr=<ArrayP 4>),
+ setfield_gc(p67, 0, descr=<FieldU spyvm.shadow.ContextPartShadow.inst__stack_ptr 32>),
+ setfield_gc(ConstPtr(ptr81), i129, descr=<FieldS spyvm.interpreter.Interpreter.inst_remaining_stack_depth 40>),
+ setarrayitem_gc(p79, 1, ConstPtr(null), descr=<ArrayP 4>),
+ guard_isnull(p180, descr=<Guard0x2b81310>),
+ p183 = getfield_gc(p176, descr=<FieldP spyvm.model.W_PointersObject.inst_fieldtypes 28>),
+ guard_value(p183, ConstPtr(ptr133), descr=<Guard0x2b81290>),
+ p184 = getfield_gc(p176, descr=<FieldP spyvm.model.W_PointersObject.inst__vars 24>),
+ p185 = getarrayitem_gc(p184, 2, descr=<ArrayP 4>),
+ p186 = getarrayitem_gc(p184, 0, descr=<ArrayP 4>),
+ guard_class(p186, 6040288, descr=<Guard0x2b81210>),
+ p187 = getfield_gc(p186, descr=<FieldP spyvm.model.W_AbstractObjectWithClassReference.inst_s_class 12>),
+ guard_value(p187, ConstPtr(ptr144), descr=<Guard0x2b81190>),
+ p188 = getfield_gc(p186, descr=<FieldP spyvm.model.W_AbstractPointersObject.inst__shadow 20>),
+ guard_isnull(p188, descr=<Guard0x2b81110>),
+ p189 = getfield_gc(p186, descr=<FieldP spyvm.model.W_PointersObject.inst__vars 24>),
+ i190 = arraylen_gc(p189, descr=<ArrayP 4>),
+ i191 = getfield_gc_pure(p185, descr=<FieldS spyvm.model.W_SmallInteger.inst_value 8>),
+ i192 = int_eq(i191, i190),
+ guard_false(i192, descr=<Guard0x2b81090>),
+ i193 = int_add_ovf(i191, 1),
+ guard_no_overflow(descr=<Guard0x2b81010>),
+ i194 = int_ge(i191, 0),
+ guard_true(i194, descr=<Guard0x2b71f50>),
+ i195 = int_lt(i191, i190),
+ guard_true(i195, descr=<Guard0x2b71ed0>),
+ p196 = getfield_gc(p186, descr=<FieldP spyvm.model.W_PointersObject.inst_fieldtypes 28>),
+ guard_value(p196, ConstPtr(ptr156), descr=<Guard0x2b71e50>),
+ p197 = new_with_vtable(ConstClass(W_SmallInteger)),
+ setfield_gc(p197, i193, descr=<FieldS spyvm.model.W_SmallInteger.inst_value 8>),
+ setarrayitem_gc(p184, 2, p197, descr=<ArrayP 4>),
+ setarrayitem_gc(p189, i191, p178, descr=<ArrayP 4>),
+ p198 = getarrayitem_gc(p53, 2, descr=<ArrayP 4>),
+ i199 = getfield_gc_pure(p198, descr=<FieldS spyvm.model.W_SmallInteger.inst_value 8>),
+ setarrayitem_gc(p79, 0, ConstPtr(null), descr=<ArrayP 4>),
+ setfield_gc(p67, -1, descr=<FieldS spyvm.shadow.ContextPartShadow.inst__pc 24>),
+ setfield_gc(p67, ConstPtr(null), descr=<FieldP spyvm.shadow.ContextPartShadow.inst__s_sender 28>),
+ setfield_gc(ConstPtr(ptr81), i84, descr=<FieldS spyvm.interpreter.Interpreter.inst_remaining_stack_depth 40>),
+ i200 = int_add_ovf(i167, i199),
+ guard_no_overflow(descr=<Guard0x2b71dd0>),
+ i201 = int_sub(i170, 8),
+ setfield_gc(ConstPtr(ptr81), i201, descr=<FieldS spyvm.interpreter.Interpreter.inst_interrupt_check_counter 24>),
+ i202 = int_le(i201, 0),
+ guard_false(i202, descr=<Guard0x2b71d50>),
+ i203 = arraylen_gc(p53, descr=<ArrayP 4>),
+ i204 = arraylen_gc(p79, descr=<ArrayP 4>),
+ i205 = arraylen_gc(p105, descr=<ArrayP 4>),
+ jump(p0, p3, p6, i200, p14, p16, p18, p20, p22, p24, p26, p28, p30, p32, p34, p36, p38, p40, p42, p53, i75, p67, i103, p91, p105, p79, i88, i90, i129, i84, i201, descr=TargetToken(45055856))]
+ """)
+
+ def test_indexOf(self, spy, tmpdir):
+ traces = self.run(spy, tmpdir,
+ """
+ (1 to: 10000000) asOrderedCollection indexOf: 9999999.
+ """)
+ # First loop: asOrderedCollection, second loop: makeRoomAtLast
+ self.assert_matches(traces[2].loop, """
+ guard_not_invalidated(descr=<Guard0x2bac7d0>),
+ i127 = int_le(i121, i61),
+ guard_true(i127, descr=<Guard0x2bac790>),
+ setfield_gc(ConstPtr(ptr74), i81, descr=<FieldS spyvm.interpreter.Interpreter.inst_remaining_stack_depth 40>),
+ i128 = int_add_ovf(i121, i91),
+ guard_no_overflow(descr=<Guard0x2bac750>),
+ i129 = int_sub(i128, 1),
+ i130 = int_gt(i129, i97),
+ guard_false(i130, descr=<Guard0x2bac710>),
+ i131 = int_sub(i129, 1),
+ i132 = int_ge(i131, 0),
+ guard_true(i132, descr=<Guard0x2bac6d0>),
+ i133 = int_lt(i131, i110),
+ guard_true(i133, descr=<Guard0x2bac690>),
+ p134 = getarrayitem_gc(p109, i131, descr=<ArrayP 4>),
+ setfield_gc(ConstPtr(ptr74), i77, descr=<FieldS spyvm.interpreter.Interpreter.inst_remaining_stack_depth 40>),
+ guard_nonnull_class(p134, ConstClass(W_SmallInteger), descr=<Guard0x2bac650>),
+ i135 = getfield_gc_pure(p134, descr=<FieldS spyvm.model.W_SmallInteger.inst_value 8>),
+ i136 = int_eq(i135, i118),
+ guard_false(i136, descr=<Guard0x2bac610>),
+ i137 = int_add_ovf(i121, 1),
+ guard_no_overflow(descr=<Guard0x2bac5d0>),
+ i138 = int_sub(i124, 6),
+ setfield_gc(ConstPtr(ptr74), i138, descr=<FieldS spyvm.interpreter.Interpreter.inst_interrupt_check_counter 24>),
+ i139 = int_le(i138, 0),
+ guard_false(i139, descr=<Guard0x2bac590>),
+ i140 = arraylen_gc(p88, descr=<ArrayP 4>),
+ jump(p0, p3, p6, p8, p10, i137, p14, p20, p22, p24, p26, p28, p30, p32, p34, p36, p38, p40, p42, p44, p46, p48, p50, p52, i61, i81, i91, p63, p90, i67, i97, p96, p100, i110, p109, i77, i118, i138, p88, descr=TargetToken(45201344))]
+ """)
+
@py.test.mark.skipif("'just dozens of long traces'")
def test_bitblt_draw_windows(self, spy, tmpdir):
# This used to have a call to array comparison in it
diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py
--- a/spyvm/test/test_interpreter.py
+++ b/spyvm/test/test_interpreter.py
@@ -57,12 +57,12 @@
assert space.get_special_selector(methname) is symbol
s_class.installmethod(symbol, prim_meth)
- assert space.w_nil._shadow is None
+ assert space.w_nil.shadow is None
try:
func(active_context) if active_context else func()
finally:
# Uninstall those methods:
- assert space.w_nil._shadow is None
+ assert space.w_nil.shadow is None
for (w_class, _, _, methname) in methods:
s_class = w_class.as_class_get_shadow(space)
s_class.update()
diff --git a/spyvm/test/test_largeinteger.py b/spyvm/test/test_largeinteger.py
--- a/spyvm/test/test_largeinteger.py
+++ b/spyvm/test/test_largeinteger.py
@@ -30,8 +30,7 @@
initialize_class(w("string").getclass(tools.space))
def perform_primitive(rcvr, w_selector, *args):
-
- code = rcvr.getclass(space)._shadow.lookup(w_selector).primitive()
+ code = rcvr.getclass(space).shadow.lookup(w_selector).primitive()
assert code
func = primitives.prim_holder.prim_table[code]
s_frame = MockFrame([rcvr] + list(args)).as_context_get_shadow(space)
@@ -52,7 +51,7 @@
try:
w_selector = space.get_special_selector(selector)
except Exception:
- w_selector = find_symbol_in_methoddict_of(selector, w(intmask(candidates[0])).getclass(space)._shadow)
+ w_selector = find_symbol_in_methoddict_of(selector, w(intmask(candidates[0])).getclass(space).shadow)
interp.trace=trace
for i, v in enumerate(candidates):
diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py
--- a/spyvm/test/test_miniimage.py
+++ b/spyvm/test/test_miniimage.py
@@ -407,7 +407,7 @@
w_o = space.wrap_list([1, 2, 3])
w_methoddict = w_o.shadow_of_my_class(space)._s_superclass._s_superclass.w_methoddict()
w_methoddict.as_methoddict_get_shadow(space).sync_cache()
- selectors_w = w_methoddict._shadow.methoddict.keys()
+ selectors_w = w_methoddict.shadow.methoddict.keys()
w_sel = None
for sel in selectors_w:
if sel.as_string() == 'size':
diff --git a/spyvm/test/test_objectspace.py b/spyvm/test/test_objectspace.py
--- a/spyvm/test/test_objectspace.py
+++ b/spyvm/test/test_objectspace.py
@@ -8,7 +8,7 @@
# Heuristic to detect if this is a metaclass. Don't use apart
# from in this test file, because classtable['w_Metaclass'] is
# bogus after loading an image.
- return w_cls.s_class is space.classtable['w_Metaclass']._shadow
+ return w_cls.s_class is space.classtable['w_Metaclass'].shadow
def test_every_class_is_an_instance_of_a_metaclass():
for (nm, w_cls) in space.classtable.items():
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -23,8 +23,8 @@
self.s_class = space.w_MethodContext.as_class_get_shadow(space)
def as_blockcontext_get_shadow(self):
- self._shadow = shadow.BlockContextShadow(space, self)
- return self._shadow
+ self.shadow = shadow.BlockContextShadow(space, self)
+ return self.shadow
def wrap(x):
if isinstance(x, int): return space.wrap_int(x)
@@ -806,13 +806,13 @@
interp.image = Image()
try:
- monkeypatch.setattr(w_frame._shadow, "_sendSelfSelector", perform_mock)
+ monkeypatch.setattr(w_frame.shadow, "_sendSelfSelector", perform_mock)
monkeypatch.setattr(bitblt.BitBltShadow, "sync_cache", sync_cache_mock)
with py.test.raises(CallCopyBitsSimulation):
prim_table[primitives.BITBLT_COPY_BITS](interp, w_frame.as_context_get_shadow(space), argument_count-1)
finally:
monkeypatch.undo()
- assert w_frame._shadow.pop() is mock_bitblt # the receiver
+ assert w_frame.shadow.pop() is mock_bitblt # the receiver
# Note:
# primitives.NEXT is unimplemented as it is a performance optimization
diff --git a/spyvm/test/test_shadow.py b/spyvm/test/test_shadow.py
--- a/spyvm/test/test_shadow.py
+++ b/spyvm/test/test_shadow.py
@@ -171,11 +171,11 @@
w_object = blockcontext(pc=13)
old_vars = w_object._vars
s_object = w_object.as_blockcontext_get_shadow(space)
- s_object._shadow = None
+ s_object.shadow = None
s_newobject = w_object.as_blockcontext_get_shadow(space)
assert ([s_newobject.fetch(i) for i in range(s_newobject.size())] ==
[s_object.fetch(i) for i in range(s_newobject.size())])
- assert w_object._shadow is s_newobject
+ assert w_object.shadow is s_newobject
def test_compiledmethodshadow():
from test_model import joinbits
@@ -222,7 +222,7 @@
assert o.notified
assert w_o.fetch(space, 0) == 1
try:
- w_o._shadow.notify(Observer())
+ w_o.shadow.notify(Observer())
except RuntimeError:
pass
else:
diff --git a/spyvm/version.py b/spyvm/version.py
new file mode 100644
--- /dev/null
+++ b/spyvm/version.py
@@ -0,0 +1,40 @@
+from rpython.rlib import jit
+
+# This declares the decorated function as "pure" while the self-object
+# has an unchanged version. Neither self nor self.version are promoted to constants.
+def elidable_for_version(func):
+ @jit.elidable
+ def elidable_func(self, version, *args):
+ return func(self, *args)
+ def meth(self, *args):
+ return elidable_func(self, self.version, *args)
+ elidable_func.func_name = "elidable_" + func.func_name
+ meth.func_name = "elidable_meth_" + func.func_name
+ return meth
+
+# In addition to marking the decorated function as "pure", both the receiver
+# and the version of the receiver are promoted to constants. This should only
+# be used in situations where the receiver is very unlikely to change in the same
+# context of the interpreted program (like classes or compiled methods).
+def constant_for_version(func):
+ @jit.elidable
+ def elidable_func(self, version, *args):
+ return func(self, *args)
+ def meth(self, *args):
+ self = jit.promote(self)
+ version = jit.promote(self.version)
+ return elidable_func(self, version, *args)
+ return meth
+
+class Version(object):
+ pass
+
+class VersionMixin(object):
+ # Concrete class must define a pseudo immutable field like the following:
+ # _attrs_ = ['version']
+ # _immutable_fields_ = ['version?']
+
+ version = Version()
+
+ def changed(self):
+ self.version = Version()
More information about the pypy-commit
mailing list