@@ -213,6 +213,13 @@ typedef enum {
213
213
JS_GC_PHASE_REMOVE_CYCLES,
214
214
} JSGCPhaseEnum;
215
215
216
+ typedef struct JSMallocState {
217
+ size_t malloc_count;
218
+ size_t malloc_size;
219
+ size_t malloc_limit;
220
+ void *opaque; /* user opaque */
221
+ } JSMallocState;
222
+
216
223
struct JSRuntime {
217
224
JSMallocFunctions mf;
218
225
JSMallocState malloc_state;
@@ -1380,22 +1387,91 @@ static size_t js_malloc_usable_size_unknown(const void *ptr)
1380
1387
1381
1388
void *js_calloc_rt(JSRuntime *rt, size_t count, size_t size)
1382
1389
{
1383
- return rt->mf.js_calloc(&rt->malloc_state, count, size);
1390
+ void *ptr;
1391
+ JSMallocState *s;
1392
+
1393
+ /* Do not allocate zero bytes: behavior is platform dependent */
1394
+ assert(count != 0 && size != 0);
1395
+
1396
+ if (size > 0)
1397
+ if (unlikely(count != (count * size) / size))
1398
+ return NULL;
1399
+
1400
+ s = &rt->malloc_state;
1401
+ /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
1402
+ if (unlikely(s->malloc_size + (count * size) > s->malloc_limit - 1))
1403
+ return NULL;
1404
+
1405
+ ptr = rt->mf.js_calloc(s->opaque, count, size);
1406
+ if (!ptr)
1407
+ return NULL;
1408
+
1409
+ s->malloc_count++;
1410
+ s->malloc_size += js__malloc_usable_size(ptr) + MALLOC_OVERHEAD;
1411
+ return ptr;
1384
1412
}
1385
1413
1386
1414
void *js_malloc_rt(JSRuntime *rt, size_t size)
1387
1415
{
1388
- return rt->mf.js_malloc(&rt->malloc_state, size);
1416
+ void *ptr;
1417
+ JSMallocState *s;
1418
+
1419
+ /* Do not allocate zero bytes: behavior is platform dependent */
1420
+ assert(size != 0);
1421
+
1422
+ s = &rt->malloc_state;
1423
+ /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
1424
+ if (unlikely(s->malloc_size + size > s->malloc_limit - 1))
1425
+ return NULL;
1426
+
1427
+ ptr = rt->mf.js_malloc(s->opaque, size);
1428
+ if (!ptr)
1429
+ return NULL;
1430
+
1431
+ s->malloc_count++;
1432
+ s->malloc_size += js__malloc_usable_size(ptr) + MALLOC_OVERHEAD;
1433
+ return ptr;
1389
1434
}
1390
1435
1391
1436
void js_free_rt(JSRuntime *rt, void *ptr)
1392
1437
{
1393
- rt->mf.js_free(&rt->malloc_state, ptr);
1438
+ JSMallocState *s;
1439
+
1440
+ if (!ptr)
1441
+ return;
1442
+
1443
+ s = &rt->malloc_state;
1444
+ s->malloc_count--;
1445
+ s->malloc_size -= js__malloc_usable_size(ptr) + MALLOC_OVERHEAD;
1446
+ rt->mf.js_free(s->opaque, ptr);
1394
1447
}
1395
1448
1396
1449
void *js_realloc_rt(JSRuntime *rt, void *ptr, size_t size)
1397
1450
{
1398
- return rt->mf.js_realloc(&rt->malloc_state, ptr, size);
1451
+ size_t old_size;
1452
+ JSMallocState *s;
1453
+
1454
+ if (!ptr) {
1455
+ if (size == 0)
1456
+ return NULL;
1457
+ return js_malloc_rt(rt, size);
1458
+ }
1459
+ if (unlikely(size == 0)) {
1460
+ js_free_rt(rt, ptr);
1461
+ return NULL;
1462
+ }
1463
+ old_size = js__malloc_usable_size(ptr);
1464
+ s = &rt->malloc_state;
1465
+ /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
1466
+ if (s->malloc_size + size - old_size > s->malloc_limit - 1)
1467
+ return NULL;
1468
+
1469
+ ptr = rt->mf.js_realloc(s->opaque, ptr, size);
1470
+ if (!ptr)
1471
+ return NULL;
1472
+
1473
+ s->malloc_size += js__malloc_usable_size(ptr) - old_size;
1474
+ return ptr;
1399
1475
}
1400
1476
1401
1477
static void *js_dbuf_realloc(void *opaque, void *ptr, size_t size)
@@ -1651,9 +1727,12 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
1651
1727
ms.opaque = opaque;
1652
1728
ms.malloc_limit = 0;
1653
1729
1654
- rt = mf->js_calloc(&ms , 1, sizeof(JSRuntime));
1730
+ rt = mf->js_calloc(opaque , 1, sizeof(JSRuntime));
1655
1731
if (!rt)
1656
1732
return NULL;
1733
+ /* Inline what js_malloc_rt does since we cannot use it here. */
1734
+ ms.malloc_count++;
1735
+ ms.malloc_size += js__malloc_usable_size(rt) + MALLOC_OVERHEAD;
1657
1736
rt->mf = *mf;
1658
1737
if (!rt->mf.js_malloc_usable_size) {
1659
1738
/* use dummy function if none provided */
@@ -1718,84 +1797,24 @@ void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque)
1718
1797
rt->user_opaque = opaque;
1719
1798
}
1720
1799
1721
- static void *js_def_calloc(JSMallocState *s , size_t count, size_t size)
1800
+ static void *js_def_calloc(void *opaque , size_t count, size_t size)
1722
1801
{
1723
- void *ptr;
1724
-
1725
- /* Do not allocate zero bytes: behavior is platform dependent */
1726
- assert(count != 0 && size != 0);
1727
-
1728
- if (size > 0)
1729
- if (unlikely(count != (count * size) / size))
1730
- return NULL;
1731
-
1732
- /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
1733
- if (unlikely(s->malloc_size + (count * size) > s->malloc_limit - 1))
1734
- return NULL;
1735
-
1736
- ptr = calloc(count, size);
1737
- if (!ptr)
1738
- return NULL;
1739
-
1740
- s->malloc_count++;
1741
- s->malloc_size += js__malloc_usable_size(ptr) + MALLOC_OVERHEAD;
1742
- return ptr;
1802
+ return calloc(count, size);
1743
1803
}
1744
1804
1745
- static void *js_def_malloc(JSMallocState *s , size_t size)
1805
+ static void *js_def_malloc(void *opaque , size_t size)
1746
1806
{
1747
- void *ptr;
1748
-
1749
- /* Do not allocate zero bytes: behavior is platform dependent */
1750
- assert(size != 0);
1751
-
1752
- /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
1753
- if (unlikely(s->malloc_size + size > s->malloc_limit - 1))
1754
- return NULL;
1755
-
1756
- ptr = malloc(size);
1757
- if (!ptr)
1758
- return NULL;
1759
-
1760
- s->malloc_count++;
1761
- s->malloc_size += js__malloc_usable_size(ptr) + MALLOC_OVERHEAD;
1762
- return ptr;
1807
+ return malloc(size);
1763
1808
}
1764
1809
1765
- static void js_def_free(JSMallocState *s , void *ptr)
1810
+ static void js_def_free(void *opaque , void *ptr)
1766
1811
{
1767
- if (!ptr)
1768
- return;
1769
-
1770
- s->malloc_count--;
1771
- s->malloc_size -= js__malloc_usable_size(ptr) + MALLOC_OVERHEAD;
1772
1812
free(ptr);
1773
1813
}
1774
1814
1775
- static void *js_def_realloc(JSMallocState *s , void *ptr, size_t size)
1815
+ static void *js_def_realloc(void *opaque , void *ptr, size_t size)
1776
1816
{
1777
- size_t old_size;
1778
-
1779
- if (!ptr) {
1780
- if (size == 0)
1781
- return NULL;
1782
- return js_def_malloc(s, size);
1783
- }
1784
- if (unlikely(size == 0)) {
1785
- js_def_free(s, ptr);
1786
- return NULL;
1787
- }
1788
- old_size = js__malloc_usable_size(ptr);
1789
- /* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
1790
- if (s->malloc_size + size - old_size > s->malloc_limit - 1)
1791
- return NULL;
1792
-
1793
- ptr = realloc(ptr, size);
1794
- if (!ptr)
1795
- return NULL;
1796
-
1797
- s->malloc_size += js__malloc_usable_size(ptr) - old_size;
1798
- return ptr;
1817
+ return realloc(ptr, size);
1799
1818
}
1800
1819
1801
1820
static const JSMallocFunctions def_malloc_funcs = {
@@ -2159,8 +2178,8 @@ void JS_FreeRuntime(JSRuntime *rt)
2159
2178
#endif
2160
2179
2161
2180
{
2162
- JSMallocState ms = rt->malloc_state;
2163
- rt->mf.js_free(&ms , rt);
2181
+ JSMallocState * ms = & rt->malloc_state;
2182
+ rt->mf.js_free(ms->opaque , rt);
2164
2183
}
2165
2184
}
2166
2185
0 commit comments