Author: Armin Rigo <ar...@tunes.org> Branch: int-float-list-strategy Changeset: r78386:d38f6591e679 Date: 2015-07-01 19:18 +0200 http://bitbucket.org/pypy/pypy/changeset/d38f6591e679/
Log: in-progress diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py --- a/pypy/objspace/std/listobject.py +++ b/pypy/objspace/std/listobject.py @@ -14,6 +14,7 @@ from rpython.rlib.listsort import make_timsort_class from rpython.rlib.objectmodel import ( import_from_mixin, instantiate, newlist_hint, resizelist_hint, specialize) +from rpython.rlib import longlong2float from rpython.tool.sourcetools import func_with_new_name from pypy.interpreter.baseobjspace import W_Root @@ -73,33 +74,56 @@ return SizeListStrategy(space, sizehint) return space.fromcache(EmptyListStrategy) - # check for ints - for w_obj in list_w: - if not type(w_obj) is W_IntObject: + w_firstobj = list_w[0] + check_int_or_float = False + + if type(w_firstobj) is W_IntObject: + # check for all-ints + for i in range(1, len(list_w)): + w_obj = list_w[i] + if type(w_obj) is not W_IntObject: + check_int_or_float = (type(w_obj) is W_FloatObject) + break + else: + return space.fromcache(IntegerListStrategy) + + elif type(w_firstobj) is W_BytesObject: + # check for all-strings + for i in range(1, len(list_w)): + if type(list_w[i]) is not W_BytesObject: + break + else: + return space.fromcache(BytesListStrategy) + + elif type(w_firstobj) is W_UnicodeObject: + # check for all-unicodes + for i in range(1, len(list_w)): + if type(list_w[i]) is not W_UnicodeObject: + break + else: + return space.fromcache(UnicodeListStrategy) + + elif type(w_firstobj) is W_FloatObject: + # check for all-floats + for i in range(1, len(list_w)): + w_obj = list_w[i] + if type(w_obj) is not W_FloatObject: + check_int_or_float = (type(w_obj) is W_IntObject) + break + else: + return space.fromcache(FloatListStrategy) + + if check_int_or_float: + for w_obj in list_w: + if type(w_obj) is W_IntObject: + if longlong2float.can_encode_int32(space.int_w(w_obj)): + continue # ok + elif type(w_obj) is W_FloatObject: + if longlong2float.can_encode_float(space.float_w(w_obj)): + continue # ok break - else: - return space.fromcache(IntegerListStrategy) - - # check for strings - for w_obj in list_w: - if not type(w_obj) is W_BytesObject: - break - else: - return space.fromcache(BytesListStrategy) - - # check for unicode - for w_obj in list_w: - if not type(w_obj) is W_UnicodeObject: - break - else: - return space.fromcache(UnicodeListStrategy) - - # check for floats - for w_obj in list_w: - if not type(w_obj) is W_FloatObject: - break - else: - return space.fromcache(FloatListStrategy) + else: + return space.fromcache(IntOrFloatListStrategy) return space.fromcache(ObjectListStrategy) @@ -1382,12 +1406,15 @@ return W_ListObject.from_storage_and_strategy( self.space, storage, self) + def switch_to_next_strategy(self, w_list, w_sample_item): + w_list.switch_to_object_strategy() + def append(self, w_list, w_item): if self.is_correct_type(w_item): self.unerase(w_list.lstorage).append(self.unwrap(w_item)) return - w_list.switch_to_object_strategy() + self.switch_to_next_strategy(w_list, w_item) w_list.append(w_item) def insert(self, w_list, index, w_item): @@ -1397,7 +1424,7 @@ l.insert(index, self.unwrap(w_item)) return - w_list.switch_to_object_strategy() + self.switch_to_next_strategy(w_list, w_item) w_list.insert(index, w_item) def _extend_from_list(self, w_list, w_other): @@ -1673,7 +1700,6 @@ def _safe_find(self, w_list, obj, start, stop): from rpython.rlib.rfloat import isnan - from rpython.rlib.longlong2float import float2longlong # l = self.unerase(w_list.lstorage) stop = min(stop, len(l)) @@ -1683,10 +1709,10 @@ if val == obj: return i else: - search = float2longlong(obj) + search = longlong2float.float2longlong(obj) for i in range(start, stop): val = l[i] - if float2longlong(val) == search: + if longlong2float.float2longlong(val) == search: return i raise ValueError diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py --- a/pypy/objspace/std/test/test_liststrategies.py +++ b/pypy/objspace/std/test/test_liststrategies.py @@ -733,6 +733,11 @@ list_copy[0] = 42 assert list_orig == [1, 2, 3] + def test_int_or_float(self): + space = self.space + w_l = W_ListObject(space, [space.wrap(1), space.wrap(2.3)]) + xxxxx + class TestW_ListStrategiesDisabled: spaceconfig = {"objspace.std.withliststrategies": False} diff --git a/rpython/rlib/longlong2float.py b/rpython/rlib/longlong2float.py --- a/rpython/rlib/longlong2float.py +++ b/rpython/rlib/longlong2float.py @@ -7,6 +7,7 @@ """ from __future__ import with_statement +import sys from rpython.annotator import model as annmodel from rpython.rlib.rarithmetic import r_int64 from rpython.rtyper.lltypesystem import lltype, rffi @@ -99,3 +100,29 @@ [v_longlong] = hop.inputargs(lltype.SignedLongLong) hop.exception_cannot_occur() return hop.genop("convert_longlong_bytes_to_float", [v_longlong], resulttype=lltype.Float) + +# ____________________________________________________________ + + +# For encoding integers inside nonstandard NaN bit patterns. +# ff ff ff fe xx xx xx xx (signed 32-bit int) +nan_high_word_int32 = -2 # -2 == (int)0xfffffffe +nan_encoded_zero = rffi.cast(rffi.LONGLONG, nan_high_word_int32 << 32) + +def encode_int32_into_longlong_nan(value): + return (nan_encoded_zero + + rffi.cast(rffi.LONGLONG, rffi.cast(rffi.UINT, value))) + +def decode_int32_from_longlong_nan(value): + return rffi.cast(lltype.Signed, rffi.cast(rffi.INT, value)) + +def is_int32_from_longlong_nan(value): + return (value >> 32) == nan_high_word_int32 + +def can_encode_int32(value): + if sys.maxint == 2147483647: + return True + return value == rffi.cast(lltype.Signed, rffi.cast(rffi.INT, value)) + +def can_encode_float(value): + return (float2longlong(value) >> 32) != nan_high_word_int32 _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit