OLD | NEW |
1 #include "Python.h" | 1 #include "Python.h" |
2 | 2 |
3 #ifdef WITH_PYMALLOC | 3 #ifdef WITH_PYMALLOC |
4 | 4 |
5 /* An object allocator for Python. | 5 /* An object allocator for Python. |
6 | 6 |
7 Here is an introduction to the layers of the Python memory architecture, | 7 Here is an introduction to the layers of the Python memory architecture, |
8 showing where the object allocator is actually used (layer +2), It is | 8 showing where the object allocator is actually used (layer +2), It is |
9 called for every object allocation and deallocation (PyObject_New/Del), | 9 called for every object allocation and deallocation (PyObject_New/Del), |
10 unless the object-specific allocators implement a proprietary allocation | 10 unless the object-specific allocators implement a proprietary allocation |
(...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 #undef PyObject_Malloc | 720 #undef PyObject_Malloc |
721 void * | 721 void * |
722 PyObject_Malloc(size_t nbytes) | 722 PyObject_Malloc(size_t nbytes) |
723 { | 723 { |
724 block *bp; | 724 block *bp; |
725 poolp pool; | 725 poolp pool; |
726 poolp next; | 726 poolp next; |
727 uint size; | 727 uint size; |
728 | 728 |
729 /* | 729 /* |
| 730 * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes. |
| 731 * Most python internals blindly use a signed Py_ssize_t to track |
| 732 * things without checking for overflows or negatives. |
| 733 * As size_t is unsigned, checking for nbytes < 0 is not required. |
| 734 */ |
| 735 if (nbytes > PY_SSIZE_T_MAX) |
| 736 return NULL; |
| 737 |
| 738 /* |
730 * This implicitly redirects malloc(0). | 739 * This implicitly redirects malloc(0). |
731 */ | 740 */ |
732 if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) { | 741 if ((nbytes - 1) < SMALL_REQUEST_THRESHOLD) { |
733 LOCK(); | 742 LOCK(); |
734 /* | 743 /* |
735 * Most frequent paths first | 744 * Most frequent paths first |
736 */ | 745 */ |
737 size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT; | 746 size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT; |
738 pool = usedpools[size + size]; | 747 pool = usedpools[size + size]; |
739 if (pool != pool->nextpool) { | 748 if (pool != pool->nextpool) { |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 void * | 1132 void * |
1124 PyObject_Realloc(void *p, size_t nbytes) | 1133 PyObject_Realloc(void *p, size_t nbytes) |
1125 { | 1134 { |
1126 void *bp; | 1135 void *bp; |
1127 poolp pool; | 1136 poolp pool; |
1128 size_t size; | 1137 size_t size; |
1129 | 1138 |
1130 if (p == NULL) | 1139 if (p == NULL) |
1131 return PyObject_Malloc(nbytes); | 1140 return PyObject_Malloc(nbytes); |
1132 | 1141 |
| 1142 /* |
| 1143 * Limit ourselves to PY_SSIZE_T_MAX bytes to prevent security holes. |
| 1144 * Most python internals blindly use a signed Py_ssize_t to track |
| 1145 * things without checking for overflows or negatives. |
| 1146 * As size_t is unsigned, checking for nbytes < 0 is not required. |
| 1147 */ |
| 1148 if (nbytes > PY_SSIZE_T_MAX) |
| 1149 return NULL; |
| 1150 |
1133 pool = POOL_ADDR(p); | 1151 pool = POOL_ADDR(p); |
1134 if (Py_ADDRESS_IN_RANGE(p, pool)) { | 1152 if (Py_ADDRESS_IN_RANGE(p, pool)) { |
1135 /* We're in charge of this block */ | 1153 /* We're in charge of this block */ |
1136 size = INDEX2SIZE(pool->szidx); | 1154 size = INDEX2SIZE(pool->szidx); |
1137 if (nbytes <= size) { | 1155 if (nbytes <= size) { |
1138 /* The block is staying the same or shrinking. If | 1156 /* The block is staying the same or shrinking. If |
1139 * it's shrinking, there's a tradeoff: it costs | 1157 * it's shrinking, there's a tradeoff: it costs |
1140 * cycles to copy the block to a smaller size class, | 1158 * cycles to copy the block to a smaller size class, |
1141 * but it wastes memory not to copy it. The | 1159 * but it wastes memory not to copy it. The |
1142 * compromise here is to copy on shrink only if at | 1160 * compromise here is to copy on shrink only if at |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 * after the reference. | 1754 * after the reference. |
1737 */ | 1755 */ |
1738 int | 1756 int |
1739 Py_ADDRESS_IN_RANGE(void *P, poolp pool) | 1757 Py_ADDRESS_IN_RANGE(void *P, poolp pool) |
1740 { | 1758 { |
1741 return pool->arenaindex < maxarenas && | 1759 return pool->arenaindex < maxarenas && |
1742 (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE && | 1760 (uptr)P - arenas[pool->arenaindex].address < (uptr)ARENA_SIZE && |
1743 arenas[pool->arenaindex].address != 0; | 1761 arenas[pool->arenaindex].address != 0; |
1744 } | 1762 } |
1745 #endif | 1763 #endif |
OLD | NEW |