this repo has no description
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