aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Friedrich Bolz-Tereick <cfbolz@gmx.de>2021-01-31 20:46:56 +0100
committerCarl Friedrich Bolz-Tereick <cfbolz@gmx.de>2021-01-31 20:46:56 +0100
commit82cdfed640bc716c8a82d5222924d653617d1b08 (patch)
tree5e42a5bfde2514b77ce4c77a7befa34d4f467ac5
parentmerge default (diff)
downloadpypy-82cdfed640bc716c8a82d5222924d653617d1b08.tar.gz
pypy-82cdfed640bc716c8a82d5222924d653617d1b08.tar.bz2
pypy-82cdfed640bc716c8a82d5222924d653617d1b08.zip
only unbox ints on 64 bit machines (otherwise there is no memory saving and
very unclear whether it's a good idea)
-rw-r--r--pypy/objspace/std/mapdict.py5
-rw-r--r--pypy/objspace/std/test/test_mapdict.py96
2 files changed, 60 insertions, 41 deletions
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
index e04266cc98..245aedfb4e 100644
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -1,7 +1,7 @@
import weakref, sys
from rpython.rlib import jit, objectmodel, debug, rerased
-from rpython.rlib.rarithmetic import intmask, r_uint
+from rpython.rlib.rarithmetic import intmask, r_uint, LONG_BIT
from rpython.rlib.longlong2float import longlong2float, float2longlong
from pypy.interpreter.baseobjspace import W_Root
@@ -19,6 +19,7 @@ erase_map, unerase_map = rerased.new_erasing_pair("map")
erase_list, unerase_list = rerased.new_erasing_pair("mapdict storage list")
erase_unboxed, unerase_unboxed = rerased.new_erasing_pair("mapdict unwrapped storage")
+ALLOW_UNBOXING_INTS = LONG_BIT == 64
# ____________________________________________________________
# attribute shapes
@@ -203,7 +204,7 @@ class AbstractAttribute(object):
current = self
unbox_type = None
if self.terminator.allow_unboxing:
- if type(w_value) is self.space.IntObjectCls:
+ if ALLOW_UNBOXING_INTS and type(w_value) is self.space.IntObjectCls:
unbox_type = self.space.IntObjectCls
elif type(w_value) is self.space.FloatObjectCls:
unbox_type = self.space.FloatObjectCls
diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py
index ebc92bc1df..8c61b7ee3f 100644
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -1,6 +1,10 @@
+import pytest
from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictObject
from pypy.objspace.std.mapdict import *
+
+skip_if_no_int_unboxing = pytest.mark.skipif(not ALLOW_UNBOXING_INTS, reason="int unboxing disabled on 32bit")
+
class Config:
class objspace:
class std:
@@ -567,6 +571,7 @@ def test_unboxed_storage_needed():
int)
assert aa.storage_needed() == 2
+@skip_if_no_int_unboxing
def test_unboxed_write_int():
cls = Class(allow_unboxing=True)
w_obj = cls.instantiate(space)
@@ -595,6 +600,7 @@ def test_unboxed_write_float():
assert isinstance(w_obj.map.back, UnboxedPlainAttribute)
assert unerase_unboxed(w_obj.storage[0]) == [15.0, 20.0]
+@skip_if_no_int_unboxing
def test_unboxed_write_mixed():
cls = Class(allow_unboxing=True)
w_obj = cls.instantiate(space)
@@ -607,46 +613,58 @@ def test_unboxed_write_mixed():
w_obj.getdictvalue(space, "c") == 20.1
w_obj.setdictvalue(space, "d", None)
+@skip_if_no_int_unboxing
+def test_no_int_unboxing(monkeypatch):
+ from pypy.objspace.std import mapdict
+ monkeypatch.setattr(mapdict, "ALLOW_UNBOXING_INTS", False)
+ cls = Class(allow_unboxing=True)
+ w_obj = cls.instantiate(space)
+ w_obj.setdictvalue(space, "a", 15)
+ assert type(w_obj.map) is PlainAttribute
+ w_obj.setdictvalue(space, "b", 15.0)
+ assert type(w_obj.map) is UnboxedPlainAttribute
def test_unboxed_type_change():
cls = Class(allow_unboxing=True)
w_obj = cls.instantiate(space)
- w_obj.setdictvalue(space, "b", 15)
- w_obj.setdictvalue(space, "b", 15.5)
- assert w_obj.getdictvalue(space, "b") == 15.5
+ w_obj.setdictvalue(space, "b", 15.12)
+ w_obj.setdictvalue(space, "b", "woopsie")
+ assert w_obj.getdictvalue(space, "b") == "woopsie"
assert type(w_obj.map) is PlainAttribute
assert w_obj.map.terminator.allow_unboxing == False
w_obj = cls.instantiate(space)
- w_obj.setdictvalue(space, "b", 15)
+ w_obj.setdictvalue(space, "b", 15.12)
# next time we won't unbox
assert type(w_obj.map) is PlainAttribute
def test_unboxed_type_change_other_object():
cls = Class(allow_unboxing=True)
w_obj1 = cls.instantiate(space)
- w_obj1.setdictvalue(space, "b", 15)
+ w_obj1.setdictvalue(space, "b", 15.12)
w_obj2 = cls.instantiate(space)
- w_obj2.setdictvalue(space, "b", 16)
+ w_obj2.setdictvalue(space, "b", 16.12)
assert w_obj1.map is w_obj2.map
assert type(w_obj1.map) is UnboxedPlainAttribute
# type change
- w_obj1.setdictvalue(space, "b", 15.5)
- assert w_obj1.getdictvalue(space, "b") == 15.5
+ w_obj1.setdictvalue(space, "b", "woopsie")
+ assert w_obj1.getdictvalue(space, "b") == "woopsie"
assert type(w_obj1.map) is PlainAttribute
assert w_obj1.map.terminator.allow_unboxing == False
# w_obj2 is unaffected so far
assert type(w_obj2.map) is UnboxedPlainAttribute
- assert w_obj2.getdictvalue(space, "b") == 16
+ assert w_obj2.getdictvalue(space, "b") == 16.12
# now it's switched
assert type(w_obj2.map) is PlainAttribute
+ # but the value stays of course
+ assert w_obj2.getdictvalue(space, "b") == 16.12
def test_unboxed_mixed_two_different_instances():
cls = Class(allow_unboxing=True)
w_obj1 = cls.instantiate(space)
- w_obj1.setdictvalue(space, "b", 15)
+ w_obj1.setdictvalue(space, "b", 15.12)
w_obj2 = cls.instantiate(space)
w_obj2.setdictvalue(space, "b", "abc")
@@ -656,9 +674,9 @@ def test_unboxed_mixed_two_different_instances():
def test_unboxed_attr_immutability(monkeypatch):
cls = Class(allow_unboxing=True)
obj = cls.instantiate()
- obj.setdictvalue(space, "a", 10)
- obj.setdictvalue(space, "b", 20)
- obj.setdictvalue(space, "b", 30)
+ obj.setdictvalue(space, "a", 10.12)
+ obj.setdictvalue(space, "b", 20.12)
+ obj.setdictvalue(space, "b", 30.12)
assert obj.map.ever_mutated == True
assert obj.map.back.ever_mutated == False
@@ -666,25 +684,25 @@ def test_unboxed_attr_immutability(monkeypatch):
def _pure_unboxed_read(obj):
indices.append(0)
- return longlong2float(10)
+ return 10.12
obj.map.back._pure_unboxed_read = _pure_unboxed_read
monkeypatch.setattr(jit, "isconstant", lambda c: True)
- assert obj.getdictvalue(space, "a") == 10
- assert obj.getdictvalue(space, "b") == 30
- assert obj.getdictvalue(space, "a") == 10
+ assert obj.getdictvalue(space, "a") == 10.12
+ assert obj.getdictvalue(space, "b") == 30.12
+ assert obj.getdictvalue(space, "a") == 10.12
assert indices == [0, 0]
obj2 = cls.instantiate()
- obj2.setdictvalue(space, "a", 15)
- obj2.setdictvalue(space, "b", 25)
+ obj2.setdictvalue(space, "a", 15.12)
+ obj2.setdictvalue(space, "b", 25.12)
assert obj2.map is obj.map
assert obj2.map.ever_mutated == True
assert obj2.map.back.ever_mutated == False
# mutating obj2 changes the map
- obj2.setdictvalue(space, "a", 50)
+ obj2.setdictvalue(space, "a", 50.12)
assert obj2.map.back.ever_mutated == True
assert obj2.map is obj.map
@@ -692,44 +710,44 @@ def test_unboxed_attr_immutability(monkeypatch):
def test_unboxed_bug():
cls = Class(allow_unboxing=True)
w_obj = cls.instantiate(space)
- w_obj.setdictvalue(space, "flags", 0)
+ w_obj.setdictvalue(space, "flags", 0.0)
w_obj.setdictvalue(space, "open", [])
- w_obj.setdictvalue(space, "groups", 1)
+ w_obj.setdictvalue(space, "groups", 1.0)
w_obj.setdictvalue(space, "groupdict", {})
- w_obj.setdictvalue(space, "lookbehind", 0)
+ w_obj.setdictvalue(space, "lookbehind", 0.0)
- assert w_obj.getdictvalue(space, "flags") == 0
+ assert w_obj.getdictvalue(space, "flags") == 0.0
assert w_obj.getdictvalue(space, "open") == []
- assert w_obj.getdictvalue(space, "groups") == 1
+ assert w_obj.getdictvalue(space, "groups") == 1.0
assert w_obj.getdictvalue(space, "groupdict") == {}
- assert w_obj.getdictvalue(space, "lookbehind") == 0
+ assert w_obj.getdictvalue(space, "lookbehind") == 0.0
def test_unboxed_reorder_add_bug():
cls = Class(allow_unboxing=True)
obj = cls.instantiate()
- obj.setdictvalue(space, "a", 10)
- obj.setdictvalue(space, "b", 20)
- obj.setdictvalue(space, "c", 20)
+ obj.setdictvalue(space, "a", 10.0)
+ obj.setdictvalue(space, "b", 20.0)
+ obj.setdictvalue(space, "c", 20.0)
obj2 = cls.instantiate()
- obj2.setdictvalue(space, "b", 30)
- obj2.setdictvalue(space, "c", 40)
- obj2.setdictvalue(space, "a", 23)
+ obj2.setdictvalue(space, "b", 30.0)
+ obj2.setdictvalue(space, "c", 40.0)
+ obj2.setdictvalue(space, "a", 23.0)
assert obj.map is obj2.map
def test_unboxed_reorder_add_bug2():
cls = Class(allow_unboxing=True)
obj = cls.instantiate()
- obj.setdictvalue(space, "a", 10)
+ obj.setdictvalue(space, "a", 10.0)
obj.setdictvalue(space, "b", "20")
obj.setdictvalue(space, "c", "20")
obj2 = cls.instantiate()
obj2.setdictvalue(space, "b", "30")
obj2.setdictvalue(space, "c", "40")
- obj2.setdictvalue(space, "a", 23)
+ obj2.setdictvalue(space, "a", 23.0)
assert obj.map is obj2.map
@@ -744,22 +762,22 @@ def test_unbox_reorder_bug3():
obj = objectcls()
obj.user_setup(space, cls)
obj.setdictvalue(space, "_frame", "frame") # plain 0
- obj.setdictvalue(space, "_is_started", 0) # unboxed 1 0
+ obj.setdictvalue(space, "_is_started", 0.0) # unboxed 1 0
obj.setdictvalue(space, "func", "func") # plain 2
obj.setdictvalue(space, "alive", "alive") # plain 3
obj.setdictvalue(space, "blocked", "blocked") # plain 4
- obj.setdictvalue(space, "_task_id", 1) # unboxed 1 1
+ obj.setdictvalue(space, "_task_id", 1.0) # unboxed 1 1
obj.setdictvalue(space, "label", "label") # plain 5
obj2 = objectcls()
obj2.user_setup(space, cls)
obj2.setdictvalue(space, "_frame", "frame2") # plain 0
- obj2.setdictvalue(space, "_is_started", 5) # unboxed 1 0
+ obj2.setdictvalue(space, "_is_started", 5.0) # unboxed 1 0
obj2.setdictvalue(space, "func", "func2") # plain 2
obj2.setdictvalue(space, "alive", "alive2") # plain 3
obj2.setdictvalue(space, "blocked", "blocked2") # plain 4
obj2.setdictvalue(space, "label", "label2") # plain 5
- obj2.setdictvalue(space, "_task_id", 6) # reorder
+ obj2.setdictvalue(space, "_task_id", 6.0) # reorder
assert obj2.getdictvalue(space, "blocked") == "blocked2"
@@ -774,7 +792,7 @@ def test_unboxed_insert_different_orders_perm():
obj.setdictvalue(space, attr, str(i*1000))
key = preexisting
for j, attr in enumerate(attributes):
- obj.setdictvalue(space, attr, i*10+j)
+ obj.setdictvalue(space, attr, i*10.0+j)
obj._check_unboxed_storage_consistency()
key = "".join(sorted(key+attr))
if key in seen_maps: