Skip to content

Commit e81aa94

Browse files
alexeybakhtingnu-andrew
authored andcommittedJul 6, 2024
8322106: Enhance Pack 200 loading
Reviewed-by: mbalao, andrew Backport-of: c94ac4094deb8a170e82f89be6d830c2923fe198
1 parent 42c9f65 commit e81aa94

File tree

5 files changed

+103
-90
lines changed

5 files changed

+103
-90
lines changed
 

‎jdk/src/share/native/com/sun/java/util/jar/pack/defines.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,9 @@ extern int assert_failed(const char*);
8686

8787
#define lengthof(array) (sizeof(array)/sizeof(array[0]))
8888

89-
#define NEW(T, n) (T*) must_malloc((int)(scale_size(n, sizeof(T))))
90-
#define U_NEW(T, n) (T*) u->alloc(scale_size(n, sizeof(T)))
91-
#define T_NEW(T, n) (T*) u->temp_alloc(scale_size(n, sizeof(T)))
89+
#define NEW(T, n) (T*) must_calloc(n, sizeof(T))
90+
#define U_NEW(T, n) (T*) u->calloc(n, sizeof(T))
91+
#define T_NEW(T, n) (T*) u->temp_calloc(n, sizeof(T))
9292

9393

9494
// bytes and byte arrays

‎jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp

+77-64
Original file line numberDiff line numberDiff line change
@@ -507,19 +507,20 @@ static int hash_probes[] = {0, 0};
507507

508508
enum { CHUNK = (1 << 14), SMALL = (1 << 9) };
509509

510-
// Call malloc. Try to combine small blocks and free much later.
511-
void* unpacker::alloc_heap(size_t size, bool smallOK, bool temp) {
512-
if (!smallOK || size > SMALL) {
513-
void* res = must_malloc((int)size);
510+
// Call calloc. Try to combine small blocks and free much later.
511+
void* unpacker::calloc_heap(size_t count, size_t size, bool smallOK, bool temp) {
512+
size_t ssize = scale_size(count, size);
513+
if (!smallOK || ssize > SMALL) {
514+
void* res = must_calloc(count, size);
514515
(temp ? &tmallocs : &mallocs)->add(res);
515516
return res;
516517
}
517518
fillbytes& xsmallbuf = *(temp ? &tsmallbuf : &smallbuf);
518-
if (!xsmallbuf.canAppend(size+1)) {
519+
if (!xsmallbuf.canAppend(ssize+1)) {
519520
xsmallbuf.init(CHUNK);
520521
(temp ? &tmallocs : &mallocs)->add(xsmallbuf.base());
521522
}
522-
int growBy = (int)size;
523+
int growBy = (int)ssize;
523524
growBy += -growBy & 7; // round up mod 8
524525
return xsmallbuf.grow(growBy);
525526
}
@@ -984,10 +985,6 @@ void cpool::init(unpacker* u_, int counts[CONSTANT_Limit]) {
984985
tag_index[tag].init(tag_count[tag], cpMap, tag);
985986
}
986987

987-
// Initialize *all* our entries once
988-
for (int i = 0 ; i < maxentries ; i++)
989-
entries[i].outputIndex = REQUESTED_NONE;
990-
991988
initGroupIndexes();
992989
// Initialize hashTab to a generous power-of-two size.
993990
uint pow2 = 1;
@@ -1057,7 +1054,7 @@ static int compare_Utf8_chars(bytes& b1, bytes& b2) {
10571054

10581055
// Cf. PackageReader.readUtf8Bands
10591056
local_inline
1060-
void unpacker::read_Utf8_values(entry* cpMap, int len) {
1057+
void unpacker::read_Utf8_values(entry* cpMap, int len, byte tag) {
10611058
// Implicit first Utf8 string is the empty string.
10621059
enum {
10631060
// certain bands begin with implicit zeroes
@@ -1083,10 +1080,11 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) {
10831080
int nbigsuf = 0;
10841081
fillbytes charbuf; // buffer to allocate small strings
10851082
charbuf.init();
1086-
10871083
// Third band: Read the char values in the unshared suffixes:
10881084
cp_Utf8_chars.readData(cp_Utf8_suffix.getIntTotal());
10891085
for (i = 0; i < len; i++) {
1086+
cp.initValues(cpMap[i], tag, i);
1087+
10901088
int suffix = (i < SUFFIX_SKIP_1)? 0: cp_Utf8_suffix.getInt();
10911089
if (suffix < 0) {
10921090
abort("bad utf8 suffix");
@@ -1235,35 +1233,40 @@ void unpacker::read_Utf8_values(entry* cpMap, int len) {
12351233
}
12361234

12371235
local_inline
1238-
void unpacker::read_single_words(band& cp_band, entry* cpMap, int len) {
1236+
void unpacker::read_single_words(band& cp_band, entry* cpMap, int len, byte tag, int loadable_base) {
12391237
cp_band.readData(len);
12401238
for (int i = 0; i < len; i++) {
1241-
cpMap[i].value.i = cp_band.getInt(); // coding handles signs OK
1239+
entry& e = cpMap[i];
1240+
cp.initValues(e, tag, i, loadable_base);
1241+
e.value.i = cp_band.getInt(); // coding handles signs OK
12421242
}
12431243
}
12441244

12451245
maybe_inline
1246-
void unpacker::read_double_words(band& cp_bands, entry* cpMap, int len) {
1246+
void unpacker::read_double_words(band& cp_bands, entry* cpMap, int len, byte tag, int loadable_base) {
12471247
band& cp_band_hi = cp_bands;
12481248
band& cp_band_lo = cp_bands.nextBand();
12491249
cp_band_hi.readData(len);
12501250
cp_band_lo.readData(len);
12511251
for (int i = 0; i < len; i++) {
1252-
cpMap[i].value.l = cp_band_hi.getLong(cp_band_lo, true);
1252+
entry& e = cpMap[i];
1253+
cp.initValues(e, tag, i, loadable_base);
1254+
e.value.l = cp_band_hi.getLong(cp_band_lo, true);
12531255
}
12541256
//cp_band_hi.done();
12551257
//cp_band_lo.done();
12561258
}
12571259

12581260
maybe_inline
1259-
void unpacker::read_single_refs(band& cp_band, byte refTag, entry* cpMap, int len) {
1261+
void unpacker::read_single_refs(band& cp_band, byte refTag, entry* cpMap, int len, byte tag, int loadable_base) {
12601262
assert(refTag == CONSTANT_Utf8);
12611263
cp_band.setIndexByTag(refTag);
12621264
cp_band.readData(len);
12631265
CHECK;
12641266
int indexTag = (cp_band.bn == e_cp_Class) ? CONSTANT_Class : 0;
12651267
for (int i = 0; i < len; i++) {
12661268
entry& e = cpMap[i];
1269+
cp.initValues(e, tag, i, loadable_base);
12671270
e.refs = U_NEW(entry*, e.nrefs = 1);
12681271
entry* utf = cp_band.getRef();
12691272
CHECK;
@@ -1284,7 +1287,7 @@ void unpacker::read_single_refs(band& cp_band, byte refTag, entry* cpMap, int le
12841287

12851288
maybe_inline
12861289
void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag,
1287-
entry* cpMap, int len) {
1290+
entry* cpMap, int len, byte tag) {
12881291
band& cp_band1 = cp_band;
12891292
band& cp_band2 = cp_band.nextBand();
12901293
cp_band1.setIndexByTag(ref1Tag);
@@ -1294,6 +1297,7 @@ void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag,
12941297
CHECK;
12951298
for (int i = 0; i < len; i++) {
12961299
entry& e = cpMap[i];
1300+
cp.initValues(e, tag, i);
12971301
e.refs = U_NEW(entry*, e.nrefs = 2);
12981302
e.refs[0] = cp_band1.getRef();
12991303
CHECK;
@@ -1306,14 +1310,15 @@ void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag,
13061310

13071311
// Cf. PackageReader.readSignatureBands
13081312
maybe_inline
1309-
void unpacker::read_signature_values(entry* cpMap, int len) {
1313+
void unpacker::read_signature_values(entry* cpMap, int len, byte tag) {
13101314
cp_Signature_form.setIndexByTag(CONSTANT_Utf8);
13111315
cp_Signature_form.readData(len);
13121316
CHECK;
13131317
int ncTotal = 0;
13141318
int i;
13151319
for (i = 0; i < len; i++) {
13161320
entry& e = cpMap[i];
1321+
cp.initValues(e, tag, i);
13171322
entry& form = *cp_Signature_form.getRef();
13181323
CHECK;
13191324
int nc = 0;
@@ -1350,7 +1355,7 @@ void unpacker::checkLegacy(const char* name) {
13501355
}
13511356

13521357
maybe_inline
1353-
void unpacker::read_method_handle(entry* cpMap, int len) {
1358+
void unpacker::read_method_handle(entry* cpMap, int len, byte tag, int loadable_base) {
13541359
if (len > 0) {
13551360
checkLegacy(cp_MethodHandle_refkind.name);
13561361
}
@@ -1359,6 +1364,7 @@ void unpacker::read_method_handle(entry* cpMap, int len) {
13591364
cp_MethodHandle_member.readData(len);
13601365
for (int i = 0 ; i < len ; i++) {
13611366
entry& e = cpMap[i];
1367+
cp.initValues(e, tag, i, loadable_base);
13621368
e.value.i = cp_MethodHandle_refkind.getInt();
13631369
e.refs = U_NEW(entry*, e.nrefs = 1);
13641370
e.refs[0] = cp_MethodHandle_member.getRef();
@@ -1367,22 +1373,23 @@ void unpacker::read_method_handle(entry* cpMap, int len) {
13671373
}
13681374

13691375
maybe_inline
1370-
void unpacker::read_method_type(entry* cpMap, int len) {
1376+
void unpacker::read_method_type(entry* cpMap, int len, byte tag, int loadable_base) {
13711377
if (len > 0) {
13721378
checkLegacy(cp_MethodType.name);
13731379
}
13741380
cp_MethodType.setIndexByTag(CONSTANT_Signature);
13751381
cp_MethodType.readData(len);
13761382
for (int i = 0 ; i < len ; i++) {
13771383
entry& e = cpMap[i];
1384+
cp.initValues(e, tag, i, loadable_base);
13781385
e.refs = U_NEW(entry*, e.nrefs = 1);
13791386
e.refs[0] = cp_MethodType.getRef();
13801387
CHECK;
13811388
}
13821389
}
13831390

13841391
maybe_inline
1385-
void unpacker::read_bootstrap_methods(entry* cpMap, int len) {
1392+
void unpacker::read_bootstrap_methods(entry* cpMap, int len, byte tag) {
13861393
if (len > 0) {
13871394
checkLegacy(cp_BootstrapMethod_ref.name);
13881395
}
@@ -1396,6 +1403,7 @@ void unpacker::read_bootstrap_methods(entry* cpMap, int len) {
13961403
for (int i = 0; i < len; i++) {
13971404
entry& e = cpMap[i];
13981405
int argc = cp_BootstrapMethod_arg_count.getInt();
1406+
cp.initValues(e, tag, i);
13991407
e.value.i = argc;
14001408
e.refs = U_NEW(entry*, e.nrefs = argc + 1);
14011409
e.refs[0] = cp_BootstrapMethod_ref.getRef();
@@ -1405,23 +1413,22 @@ void unpacker::read_bootstrap_methods(entry* cpMap, int len) {
14051413
}
14061414
}
14071415
}
1416+
1417+
static bool isLoadableValue(int tag);
14081418
// Cf. PackageReader.readConstantPool
14091419
void unpacker::read_cp() {
14101420
byte* rp0 = rp;
1411-
1412-
int i;
1421+
uint cpentries = 0;
1422+
int loadable_count = 0;
14131423

14141424
for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++) {
14151425
byte tag = TAGS_IN_ORDER[k];
14161426
int len = cp.tag_count[tag];
14171427
int base = cp.tag_base[tag];
1428+
int loadable_base = -1;
14181429

14191430
PRINTCR((1,"Reading %d %s entries...", len, NOT_PRODUCT(TAG_NAME[tag])+0));
14201431
entry* cpMap = &cp.entries[base];
1421-
for (i = 0; i < len; i++) {
1422-
cpMap[i].tag = tag;
1423-
cpMap[i].inord = i;
1424-
}
14251432
// Initialize the tag's CP index right away, since it might be needed
14261433
// in the next pass to initialize the CP for another tag.
14271434
#ifndef PRODUCT
@@ -1431,67 +1438,73 @@ void unpacker::read_cp() {
14311438
assert(ix->base1 == cpMap);
14321439
#endif
14331440

1441+
if (isLoadableValue(tag)) {
1442+
loadable_base = loadable_count;
1443+
loadable_count += len;
1444+
}
1445+
1446+
cpentries += len;
14341447
switch (tag) {
14351448
case CONSTANT_Utf8:
1436-
read_Utf8_values(cpMap, len);
1449+
read_Utf8_values(cpMap, len, tag);
14371450
break;
14381451
case CONSTANT_Integer:
1439-
read_single_words(cp_Int, cpMap, len);
1452+
read_single_words(cp_Int, cpMap, len, tag, loadable_base);
14401453
break;
14411454
case CONSTANT_Float:
1442-
read_single_words(cp_Float, cpMap, len);
1455+
read_single_words(cp_Float, cpMap, len, tag, loadable_base);
14431456
break;
14441457
case CONSTANT_Long:
1445-
read_double_words(cp_Long_hi /*& cp_Long_lo*/, cpMap, len);
1458+
read_double_words(cp_Long_hi /*& cp_Long_lo*/, cpMap, len, tag, loadable_base);
14461459
break;
14471460
case CONSTANT_Double:
1448-
read_double_words(cp_Double_hi /*& cp_Double_lo*/, cpMap, len);
1461+
read_double_words(cp_Double_hi /*& cp_Double_lo*/, cpMap, len, tag, loadable_base);
14491462
break;
14501463
case CONSTANT_String:
1451-
read_single_refs(cp_String, CONSTANT_Utf8, cpMap, len);
1464+
read_single_refs(cp_String, CONSTANT_Utf8, cpMap, len, tag, loadable_base);
14521465
break;
14531466
case CONSTANT_Class:
1454-
read_single_refs(cp_Class, CONSTANT_Utf8, cpMap, len);
1467+
read_single_refs(cp_Class, CONSTANT_Utf8, cpMap, len, tag, loadable_base);
14551468
break;
14561469
case CONSTANT_Signature:
1457-
read_signature_values(cpMap, len);
1470+
read_signature_values(cpMap, len, tag);
14581471
break;
14591472
case CONSTANT_NameandType:
14601473
read_double_refs(cp_Descr_name /*& cp_Descr_type*/,
14611474
CONSTANT_Utf8, CONSTANT_Signature,
1462-
cpMap, len);
1475+
cpMap, len, tag);
14631476
break;
14641477
case CONSTANT_Fieldref:
14651478
read_double_refs(cp_Field_class /*& cp_Field_desc*/,
14661479
CONSTANT_Class, CONSTANT_NameandType,
1467-
cpMap, len);
1480+
cpMap, len, tag);
14681481
break;
14691482
case CONSTANT_Methodref:
14701483
read_double_refs(cp_Method_class /*& cp_Method_desc*/,
14711484
CONSTANT_Class, CONSTANT_NameandType,
1472-
cpMap, len);
1485+
cpMap, len, tag);
14731486
break;
14741487
case CONSTANT_InterfaceMethodref:
14751488
read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/,
14761489
CONSTANT_Class, CONSTANT_NameandType,
1477-
cpMap, len);
1490+
cpMap, len, tag);
14781491
break;
14791492
case CONSTANT_MethodHandle:
14801493
// consumes cp_MethodHandle_refkind and cp_MethodHandle_member
1481-
read_method_handle(cpMap, len);
1494+
read_method_handle(cpMap, len, tag, loadable_base);
14821495
break;
14831496
case CONSTANT_MethodType:
14841497
// consumes cp_MethodType
1485-
read_method_type(cpMap, len);
1498+
read_method_type(cpMap, len, tag, loadable_base);
14861499
break;
14871500
case CONSTANT_InvokeDynamic:
14881501
read_double_refs(cp_InvokeDynamic_spec, CONSTANT_BootstrapMethod,
14891502
CONSTANT_NameandType,
1490-
cpMap, len);
1503+
cpMap, len, tag);
14911504
break;
14921505
case CONSTANT_BootstrapMethod:
14931506
// consumes cp_BootstrapMethod_ref, cp_BootstrapMethod_arg_count and cp_BootstrapMethod_arg
1494-
read_bootstrap_methods(cpMap, len);
1507+
read_bootstrap_methods(cpMap, len, tag);
14951508
break;
14961509
default:
14971510
assert(false);
@@ -1500,6 +1513,11 @@ void unpacker::read_cp() {
15001513
CHECK;
15011514
}
15021515

1516+
// Initialize extra entries
1517+
for (; cpentries < cp.maxentries; cpentries++) {
1518+
cp.entries[cpentries].outputIndex = REQUESTED_NONE;
1519+
}
1520+
15031521
cp.expandSignatures();
15041522
CHECK;
15051523
cp.initMemberIndexes();
@@ -3372,25 +3390,15 @@ bool isLoadableValue(int tag) {
33723390
return false;
33733391
}
33743392
}
3375-
/*
3376-
* this method can be used to size an array using null as the parameter,
3377-
* thereafter can be reused to initialize the array using a valid pointer
3378-
* as a parameter.
3379-
*/
3380-
int cpool::initLoadableValues(entry** loadable_entries) {
3381-
int loadable_count = 0;
3382-
for (int i = 0; i < (int)N_TAGS_IN_ORDER; i++) {
3383-
int tag = TAGS_IN_ORDER[i];
3384-
if (!isLoadableValue(tag))
3385-
continue;
3386-
if (loadable_entries != NULL) {
3387-
for (int n = 0 ; n < tag_count[tag] ; n++) {
3388-
loadable_entries[loadable_count + n] = &entries[tag_base[tag] + n];
3389-
}
3390-
}
3391-
loadable_count += tag_count[tag];
3393+
3394+
void cpool::initValues(entry& e, byte tag, int n, int loadable_base) {
3395+
e.tag = tag;
3396+
e.inord = n;
3397+
e.outputIndex = REQUESTED_NONE;
3398+
if (loadable_base >= 0) {
3399+
entry** loadable_entries = tag_group_index[CONSTANT_LoadableValue - CONSTANT_All].base2;
3400+
loadable_entries[loadable_base + n] = &e;
33923401
}
3393-
return loadable_count;
33943402
}
33953403

33963404
// Initialize various views into the constant pool.
@@ -3405,9 +3413,14 @@ void cpool::initGroupIndexes() {
34053413
tag_group_index[CONSTANT_All - CONSTANT_All].init(all_count, all_entries, CONSTANT_All);
34063414

34073415
// Initialize LoadableValues
3408-
int loadable_count = initLoadableValues(NULL);
3416+
int loadable_count = 0;
3417+
for (int i = 0; i < (int)N_TAGS_IN_ORDER; i++) {
3418+
int tag = TAGS_IN_ORDER[i];
3419+
if (isLoadableValue(tag)) {
3420+
loadable_count += tag_count[tag];
3421+
}
3422+
}
34093423
entry** loadable_entries = U_NEW(entry*, loadable_count);
3410-
initLoadableValues(loadable_entries);
34113424
tag_group_count[CONSTANT_LoadableValue - CONSTANT_All] = loadable_count;
34123425
tag_group_index[CONSTANT_LoadableValue - CONSTANT_All].init(loadable_count,
34133426
loadable_entries, CONSTANT_LoadableValue);

‎jdk/src/share/native/com/sun/java/util/jar/pack/unpack.h

+13-13
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ struct cpool {
130130
void expandSignatures();
131131
void initGroupIndexes();
132132
void initMemberIndexes();
133-
int initLoadableValues(entry** loadable_entries);
133+
void initValues(entry& e, byte tag, int n, int loadable_base=-1);
134134

135135
void computeOutputOrder();
136136
void computeOutputIndexes();
@@ -411,9 +411,9 @@ struct unpacker {
411411
file* get_next_file(); // returns null on last file
412412

413413
// General purpose methods
414-
void* alloc(size_t size) { return alloc_heap(size, true); }
415-
void* temp_alloc(size_t size) { return alloc_heap(size, true, true); }
416-
void* alloc_heap(size_t size, bool smallOK = false, bool temp = false);
414+
void* calloc(size_t count, size_t size) { return calloc_heap(count, size, true); }
415+
void* temp_calloc(size_t count, size_t size) { return calloc_heap(count, size, true, true); }
416+
void* calloc_heap(size_t count, size_t size, bool smallOK = false, bool temp = false);
417417
void saveTo(bytes& b, const char* str) { saveTo(b, (byte*)str, strlen(str)); }
418418
void saveTo(bytes& b, bytes& data) { saveTo(b, data.ptr, data.len); }
419419
void saveTo(bytes& b, byte* ptr, size_t len); //{ b.ptr = U_NEW...}
@@ -494,15 +494,15 @@ struct unpacker {
494494
void read_bcs();
495495
void read_bc_ops();
496496
void read_files();
497-
void read_Utf8_values(entry* cpMap, int len);
498-
void read_single_words(band& cp_band, entry* cpMap, int len);
499-
void read_double_words(band& cp_bands, entry* cpMap, int len);
500-
void read_single_refs(band& cp_band, byte refTag, entry* cpMap, int len);
501-
void read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag, entry* cpMap, int len);
502-
void read_signature_values(entry* cpMap, int len);
503-
void read_method_handle(entry* cpMap, int len);
504-
void read_method_type(entry* cpMap, int len);
505-
void read_bootstrap_methods(entry* cpMap, int len);
497+
void read_Utf8_values(entry* cpMap, int len, byte tag);
498+
void read_single_words(band& cp_band, entry* cpMap, int len, byte tag, int loadable_base);
499+
void read_double_words(band& cp_bands, entry* cpMap, int len, byte tag, int loadable_base);
500+
void read_single_refs(band& cp_band, byte refTag, entry* cpMap, int len, byte tag, int loadable_base);
501+
void read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag, entry* cpMap, int len, byte tag);
502+
void read_signature_values(entry* cpMap, int len, byte tag);
503+
void read_method_handle(entry* cpMap, int len, byte tag, int loadable_base);
504+
void read_method_type(entry* cpMap, int len, byte tag, int loadable_base);
505+
void read_bootstrap_methods(entry* cpMap, int len, byte tag);
506506
};
507507

508508
inline void cpool::abort(const char* msg) { u->abort(msg); }

‎jdk/src/share/native/com/sun/java/util/jar/pack/utils.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,19 @@
4646

4747
#include "unpack.h"
4848

49-
void* must_malloc(size_t size) {
50-
size_t msize = size;
49+
void* must_calloc(size_t count, size_t size) {
50+
size_t msize = scale_size(count, size);
5151
#ifdef USE_MTRACE
52-
if (msize >= 0 && msize < sizeof(int))
53-
msize = sizeof(int); // see 0xbaadf00d below
52+
if (msize >= 0 && msize < sizeof(int)) {
53+
size = msize = sizeof(int); // see 0xbaadf00d below
54+
count = 1;
55+
}
5456
#endif
55-
void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : malloc(msize);
56-
if (ptr != null) {
57-
memset(ptr, 0, size);
58-
} else {
57+
void* ptr = (msize > PSIZE_MAX || msize <= 0) ? null : calloc(count, size);
58+
if (ptr == null) {
5959
unpack_abort(ERROR_ENOMEM);
6060
}
61-
mtrace('m', ptr, size);
61+
mtrace('m', ptr, msize);
6262
return ptr;
6363
}
6464

‎jdk/src/share/native/com/sun/java/util/jar/pack/utils.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
//Definitions of our util functions
2727

28-
void* must_malloc(size_t size);
28+
void* must_calloc(size_t count, size_t size);
2929
#ifndef USE_MTRACE
3030
#define mtrace(c, ptr, size)
3131
#else

0 commit comments

Comments
 (0)
Please sign in to comment.