Author: Tim Felgentreff <[email protected]>
Branch: rbitblt
Changeset: r561:b804692b36b8
Date: 2014-01-09 16:22 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/b804692b36b8/
Log: add cache flushing, and store selector strings in methoddict
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -801,6 +801,7 @@
QUIT = 113
EXIT_TO_DEBUGGER = 114
CHANGE_CLASS = 115 # Blue Book: primitiveOopsLeft
+COMPILED_METHOD_FLUSH_CACHE = 116
EXTERNAL_CALL = 117
SYMBOL_FLUSH_CACHE = 119
@@ -886,6 +887,17 @@
return IProxy.call(signature, interp, s_frame, argcount, s_method)
raise PrimitiveFailedError
+@expose_primitive(COMPILED_METHOD_FLUSH_CACHE, unwrap_spec=[object])
+def func(interp, s_frame, w_rcvr):
+ if not isinstance(w_rcvr, model.W_CompiledMethod):
+ raise PrimitiveFailedError()
+ s_cm = w_rcvr.as_compiledmethod_get_shadow(interp.space)
+ w_class = s_cm.w_compiledin
+ if w_class:
+ assert isinstance(w_class, model.W_PointersObject)
+ w_class.as_class_get_shadow(interp.space).flush_caches()
+ return w_rcvr
+
@expose_primitive(SYMBOL_FLUSH_CACHE, unwrap_spec=[object])
def func(interp, s_frame, w_rcvr):
raise PrimitiveFailedError()
@@ -1367,8 +1379,10 @@
@expose_primitive(FLUSH_CACHE, unwrap_spec=[object])
def func(interp, s_frame, w_rcvr):
- # XXX we currently don't care about bad flushes :) XXX
- # raise PrimitiveNotYetWrittenError()
+ if not isinstance(w_rcvr, model.W_PointersObject):
+ raise PrimitiveFailedError()
+ s_class = w_rcvr.as_class_get_shadow(interp.space)
+ s_class.flush_caches()
return w_rcvr
# ___________________________________________________________________________
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -169,6 +169,13 @@
self.store_w_superclass(w_superclass)
self.changed()
+ @jit.unroll_safe
+ def flush_caches(self):
+ look_in_shadow = self
+ while look_in_shadow is not None:
+ s_method = look_in_shadow.s_methoddict().sync_cache()
+ look_in_shadow = look_in_shadow._s_superclass
+
def guess_class_name(self):
if self.name != '':
return self.name
@@ -355,8 +362,8 @@
def find_selector(self, w_selector):
if self.invalid:
- return None
- return self.methoddict.get(w_selector, None)
+ return None # we may be invalid if Smalltalk code did not call
flushCache
+ return self.methoddict.get(self._as_md_entry(w_selector), None)
def update(self): return self.sync_cache()
@@ -370,6 +377,12 @@
AbstractShadow.store(self, n0, w_value)
self.invalid = True
+ def _as_md_entry(self, w_selector):
+ if isinstance(w_selector, model.W_BytesObject):
+ return w_selector.as_string()
+ else:
+ return "%r" % w_selector # use the pointer for this
+
def sync_cache(self):
if self.w_self().size() == 0:
return
@@ -394,11 +407,8 @@
"CompiledMethods only, for now. "
"If the value observed is nil, our "
"invalidating mechanism may be broken.")
- self.methoddict[w_selector] =
w_compiledmethod.as_compiledmethod_get_shadow(self.space)
- if isinstance(w_selector, model.W_BytesObject):
- selector = w_selector.as_string()
- else:
- selector = w_selector.as_repr_string()
+ selector = self._as_md_entry(w_selector)
+ self.methoddict[selector] =
w_compiledmethod.as_compiledmethod_get_shadow(self.space)
w_compiledmethod._likely_methodname = selector
if self.s_class:
self.s_class.changed()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit