this repo has no description
at trunk 124 lines 3.4 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "cpython-func.h" 3 4#include "api-handle.h" 5#include "extension-object.h" 6#include "linked-list.h" 7#include "runtime.h" 8 9namespace py { 10 11PY_EXPORT int _PyObject_DebugMallocStats(FILE* /*out*/) { 12 // A return value of 0 means no debugging hooks are installed. 13 return 0; 14} 15 16PY_EXPORT void* PyObject_Malloc(size_t size) { 17 ListEntry* entry = 18 static_cast<ListEntry*>(PyMem_RawMalloc(sizeof(ListEntry) + size)); 19 entry->prev = nullptr; 20 entry->next = nullptr; 21 return reinterpret_cast<void*>(entry + 1); 22} 23 24PY_EXPORT void PyMem_Del(void* ptr) { return PyMem_RawFree(ptr); } 25 26PY_EXPORT void* PyObject_Calloc(size_t nelem, size_t size) { 27 if (size == 0 || nelem == 0) { 28 nelem = 1; 29 size = 1; 30 } 31 void* buffer = PyObject_Malloc(nelem * size); 32 std::memset(buffer, 0, nelem * size); 33 return buffer; 34} 35 36PY_EXPORT void* PyObject_Realloc(void* ptr, size_t size) { 37 if (ptr == nullptr) return PyObject_Malloc(size); 38 ListEntry* entry = static_cast<ListEntry*>(ptr) - 1; 39 Runtime* runtime = Thread::current()->runtime(); 40 bool removed = untrackExtensionObject(runtime, entry); 41 entry = static_cast<ListEntry*>( 42 PyMem_RawRealloc(entry, sizeof(ListEntry) + size)); 43 entry->prev = nullptr; 44 entry->next = nullptr; 45 if (removed) { 46 trackExtensionObject(runtime, entry); 47 } 48 return reinterpret_cast<void*>(entry + 1); 49} 50 51PY_EXPORT void PyObject_Free(void* ptr) { 52 if (ptr == nullptr) return; 53 ListEntry* entry = static_cast<ListEntry*>(ptr) - 1; 54 Runtime* runtime = Thread::current()->runtime(); 55 bool removed = untrackExtensionObject(runtime, entry); 56 if (removed) { 57 // Set native pointer to `None` to signal the `finalizeExtensionObject` code 58 // that the object memory was freed. 59 PyObject* obj = reinterpret_cast<PyObject*>(ptr); 60 ApiHandle::asNativeProxy(ApiHandle::fromPyObject(obj)).setNative(NoneType::object()); 61 } 62 return PyMem_RawFree(entry); 63} 64 65PY_EXPORT void* PyMem_Malloc(size_t size) { return PyMem_RawMalloc(size); } 66 67PY_EXPORT void* PyMem_Calloc(size_t nelem, size_t size) { 68 return PyMem_RawCalloc(nelem, size); 69} 70 71PY_EXPORT void* PyMem_Realloc(void* ptr, size_t size) { 72 return PyMem_RawRealloc(ptr, size); 73} 74 75PY_EXPORT void PyMem_Free(void* ptr) { return PyMem_RawFree(ptr); } 76 77PY_EXPORT void* PyMem_RawMalloc(size_t size) { 78 if (size == 0) { 79 size = 1; 80 } 81 return std::malloc(size); 82} 83 84PY_EXPORT void* PyMem_RawCalloc(size_t nelem, size_t size) { 85 if (size == 0 || nelem == 0) { 86 nelem = 1; 87 size = 1; 88 } 89 return std::calloc(nelem, size); 90} 91 92PY_EXPORT void* PyMem_RawRealloc(void* ptr, size_t size) { 93 if (size == 0) { 94 size = 1; 95 } 96 return std::realloc(ptr, size); 97} 98 99PY_EXPORT void PyMem_RawFree(void* ptr) { return std::free(ptr); } 100 101PY_EXPORT void* PyMem_New_Func(size_t size, size_t n) { 102 if (n > kMaxWord / size) return nullptr; 103 return PyMem_Malloc(n * size); 104} 105 106PY_EXPORT char* _PyMem_RawStrdup(const char* str) { 107 size_t size = std::strlen(str) + 1; 108 char* result = static_cast<char*>(PyMem_RawMalloc(size)); 109 if (result != nullptr) { 110 std::memcpy(result, str, size); 111 } 112 return result; 113} 114 115PY_EXPORT char* _PyMem_Strdup(const char* str) { 116 size_t size = std::strlen(str) + 1; 117 char* result = static_cast<char*>(PyMem_Malloc(size)); 118 if (result != nullptr) { 119 std::memcpy(result, str, size); 120 } 121 return result; 122} 123 124} // namespace py