There are several reasons. Two of the most important are
1) PyPy's internal representation of objects is different from
CPython's, so a conversion cost must be payed every time objects pass
between pure Python and C. Unlike CPython, extensions with PyPy can't
poke around directly in data structures. Macros like PyList_SET_ITEM
have to become function calls.
2) Bridging the gap between PyPy's GC and CPython's ref counting
requires a lot of bookkeeping.