Author: Anton Gulenko <[email protected]>
Branch: storage
Changeset: r775:493897022dac
Date: 2014-04-04 16:59 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/493897022dac/

Log:    Small consistency fixed in W_CompiledMethod and ClassShadow,
        regarding versioning. Made sure that each time a variable guarded by
        @constant_for_version is changed, self.changed() is called. Using
        jit.elide_promoted() for @constant_for_version. Added descriptive
        funtion name.

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -16,7 +16,7 @@
 """
 import sys, weakref
 from spyvm import constants, error, version, storage_statistics
-from spyvm.version import elidable_for_version, constant_for_version
+from spyvm.version import elidable_for_version, constant_for_version, 
constant_for_version_arg
 
 from rpython.rlib import rrandom, objectmodel, jit, signature
 from rpython.rlib.rarithmetic import intmask, r_uint, r_int
@@ -1164,6 +1164,8 @@
         header (4 bytes)
         literals (4 bytes each)
         bytecodes  (variable)
+    
+    An optional method trailer can be part of the bytecodes part.
     """
 
     repr_classname = "W_CompiledMethod"
@@ -1176,22 +1178,12 @@
                 # Additional info about the method
                 "_likely_methodname", "w_compiledin" ]
 
-### Extension from Squeak 3.9 doc, which we do not implement:
-###        trailer (variable)
-###    The trailer has two variant formats.  In the first variant, the last
-###    byte is at least 252 and the last four bytes represent a source pointer
-###    into one of the sources files (see #sourcePointer).  In the second
-###    variant, the last byte is less than 252, and the last several bytes
-###    are a compressed version of the names of the method's temporary
-###    variables.  The number of bytes used for this purpose is the value of
-###    the last byte in the method.
-
     _likely_methodname = "<unknown>"
     import_from_mixin(version.VersionMixin)
     
     def __init__(self, space, bytecount=0, header=0):
+        self.bytes = ["\x00"] * bytecount
         self.setheader(space, header)
-        self.bytes = ["\x00"] * bytecount
 
     def fillin(self, space, g_self):
         # Implicitely sets the header, including self.literalsize
@@ -1200,7 +1192,7 @@
         self.setbytes(g_self.get_bytes()[self.bytecodeoffset():])
 
     # === Setters ===
-        
+    
     def setheader(self, space, header):
         _primitive, literalsize, islarge, tempsize, argsize = 
constants.decode_compiled_method_header(header)
         self.literalsize = literalsize
@@ -1215,15 +1207,15 @@
         
     def setliteral(self, index, w_lit):
         self.literals[index] = w_lit
-        self.changed()
         if index == len(self.literals):
             self.w_compiledin = None
+        self.changed()
     
     def setliterals(self, literals):
         """NOT RPYTHON""" # Only for testing, not safe.
         self.literals = literals
+        self.w_compiledin = None
         self.changed()
-        self.w_compiledin = None
     
     def setbytes(self, bytes):
         self.bytes = bytes
@@ -1262,7 +1254,7 @@
     def getheader(self):
         return self.header
 
-    @constant_for_version
+    @constant_for_version_arg
     def getliteral(self, index):
         return self.literals[index]
         
@@ -1276,7 +1268,7 @@
         # mc for methods with islarge flag turned on 32
         return 16 + self.islarge * 40 + self.argsize
     
-    @constant_for_version
+    @constant_for_version_arg
     def getbytecode(self, pc):
         assert pc >= 0 and pc < len(self.bytes)
         return self.bytes[pc]
@@ -1368,6 +1360,7 @@
         copy = W_CompiledMethod(space, 0, self.getheader())
         copy.bytes = list(self.bytes)
         copy.literals = list(self.literals)
+        copy.changed()
         return copy
 
     def invariant(self):
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -1,6 +1,6 @@
 import sys, weakref
 from spyvm import model, constants, error, wrapper, version
-from spyvm.version import elidable_for_version, constant_for_version
+from spyvm.version import elidable_for_version, constant_for_version, 
constant_for_version_arg
 from rpython.tool.pairtype import extendabletype
 from rpython.rlib import rarithmetic, objectmodel, jit, longlong2float
 from rpython.rlib.objectmodel import import_from_mixin
@@ -305,14 +305,18 @@
             # In Slang the value is read directly as a boxed integer, so that
             # the code gets a "pointer" whose bits are set as above, but
             # shifted one bit to the left and with the lowest bit set to 1.
-
-            # compute the instance size (really the size, not the number of 
bytes)
+            
+            # Compute the instance size (really the size, not the number of 
bytes)
             instsize_lo = (classformat >> 1) & 0x3F
             instsize_hi = (classformat >> (9 + 1)) & 0xC0
             self._instance_size = (instsize_lo | instsize_hi) - 1  # subtract 
hdr
             # decode the instSpec
             format = (classformat >> 7) & 15
             self.instance_varsized = format >= 2
+            
+            # In case of raised exception below.
+            self.changed()
+            
             if format < 4:
                 self.instance_kind = POINTERS
             elif format == 4:
@@ -470,14 +474,16 @@
     # _______________________________________________________________
     # Other Methods
 
-    @constant_for_version
+    @constant_for_version_arg
     def lookup(self, w_selector):
         look_in_shadow = self
         while look_in_shadow is not None:
             w_method = look_in_shadow.s_methoddict().find_selector(w_selector)
             if w_method is not None:
                 # Old images don't store compiledin-info in literals.
-                w_method.w_compiledin = look_in_shadow.w_self()
+                if not w_method.w_compiledin:
+                    w_method.w_compiledin = look_in_shadow.w_self()
+                    w_method.changed()
                 return w_method
             look_in_shadow = look_in_shadow._s_superclass
         raise MethodNotFound(self, w_selector)
diff --git a/spyvm/version.py b/spyvm/version.py
--- a/spyvm/version.py
+++ b/spyvm/version.py
@@ -17,13 +17,24 @@
 # 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)
+    def versioned_func(self, version):
+        return func(self)
+    versioned_func.func_name = "constant_" + func.func_name
+    elidable_func = jit.elidable_promote()(versioned_func)
+    def meth(self):
+        return elidable_func(self, self.version)
+    meth.func_name = "constant_meth_" + func.func_name
+    return meth
+
+# Same as constant_for_version, but allows for one additional argument.
+def constant_for_version_arg(func):
+    def versioned_func(self, version, arg):
+        return func(self, arg)
+    versioned_func.func_name = "constant_" + func.func_name
+    elidable_func = jit.elidable_promote()(versioned_func)
+    def meth(self, arg):
+        return elidable_func(self, self.version, arg)
+    meth.func_name = "constant_meth_" + func.func_name
     return meth
 
 class Version(object):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to