pypy / pypy / rpython / memory /

Full commit
Maciej Fijalkows… 66e4dc3 

Armin Rigo 96e2837 
Maciej Fijalkows… 66e4dc3 

Armin Rigo 96e2837 

Maciej Fijalkows… 66e4dc3 

Armin Rigo aab5186 
Maciej Fijalkows… 66e4dc3 

from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.lltypesystem import rdict
from pypy.rlib.objectmodel import we_are_translated
from import mangle_hash

# This is a low-level AddressDict, reusing a lot of the logic from
# xxx this is very dependent on the details of

alloc_count = 0     # for debugging

def count_alloc(delta):
    global alloc_count
    alloc_count += delta

def newdict(length_estimate=0):
    return rdict.ll_newdict_size(DICT, length_estimate)

def dict_allocate():
    if not we_are_translated(): count_alloc(+1)
    return lltype.malloc(DICT, flavor="raw")

def dict_delete(d):
    dict_delete_entries(d.entries), flavor="raw")
    if not we_are_translated(): count_alloc(-1)

def dict_allocate_entries(n):
    if not we_are_translated(): count_alloc(+1)
    # 'raw zero varsize malloc with length field' is not really implemented.
    # we can initialize the memory to zero manually
    entries = lltype.malloc(ENTRIES, n, flavor="raw")
    i = 0
    while i < n:
        entries[i].key = llmemory.NULL
        i += 1
    return entries

def dict_delete_entries(entries):, flavor="raw")
    if not we_are_translated(): count_alloc(-1)

def _hash(adr):
    return mangle_hash(llmemory.cast_adr_to_int(adr))

def dict_keyhash(d, key):
    return _hash(key)

def dict_entry_valid(entries, i):
    return entries[i].key != llmemory.NULL

def dict_entry_hash(entries, i):
    return _hash(entries[i].key)

def dict_get(d, key, default=llmemory.NULL):
    return rdict.ll_get(d, key, default)

def dict_add(d, key):
    rdict.ll_dict_setitem(d, key, llmemory.NULL)

def dict_insertclean(d, key, value):
    rdict.ll_dict_insertclean(d, key, value, _hash(key))

def dict_foreach(d, callback, arg):
    entries = d.entries
    i = len(entries) - 1
    while i >= 0:
        if dict_entry_valid(entries, i):
            callback(entries[i].key, entries[i].value, arg)
        i -= 1
dict_foreach._annspecialcase_ = 'specialize:arg(1)'

ENTRY = lltype.Struct('ENTRY', ('key', llmemory.Address),
                               ('value', llmemory.Address))
ENTRIES = lltype.Array(ENTRY,
                       adtmeths = {
                           'allocate': dict_allocate_entries,
                           'delete': dict_delete_entries,
                           'valid': dict_entry_valid,
                           'everused': dict_entry_valid,
                           'hash': dict_entry_hash,
DICT = lltype.Struct('DICT', ('entries', lltype.Ptr(ENTRIES)),
                             ('num_items', lltype.Signed),
                             ('resize_counter', lltype.Signed),
                     adtmeths = {
                         'allocate': dict_allocate,
                         'delete': dict_delete,
                         'length': rdict.ll_dict_len,
                         'contains': rdict.ll_contains,
                         'setitem': rdict.ll_dict_setitem,
                         'get': dict_get,
                         'add': dict_add,
                         'insertclean': dict_insertclean,
                         'clear': rdict.ll_clear,
                         'foreach': dict_foreach,
                         'keyhash': dict_keyhash,
                         'keyeq': None,