diff options
| author | Paul Eggert | 2015-11-19 20:09:11 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-11-19 20:09:59 -0800 |
| commit | aa7dac899804727875cdb8fe267d37adcbe9705a (patch) | |
| tree | 7418cf4365ac5a647fe7d91cc818852671ac770b /src/eval.c | |
| parent | de67fa4258293e18d8aacd6e0c3298f70dbafe32 (diff) | |
| download | emacs-aa7dac899804727875cdb8fe267d37adcbe9705a.tar.gz emacs-aa7dac899804727875cdb8fe267d37adcbe9705a.zip | |
Simplify push_handler and profile its malloc
* src/lisp.h (PUSH_HANDLER): Remove.
All callers changed to use push_handler directly.
* src/eval.c (internal_condition_case)
(internal_condition_case_1, internal_condition_case_2)
(internal_condition_case_n):
Use same pattern as for other invokers of push_handler.
(push_handler, push_handler_nosignal): Use call-by-value
instead of call-by-reference. All uses changed.
(push_handler): Simplify by rewriting in terms of
push_handler_nosignal.
(push_handler_nosignal): Profile any newly allocated memory.
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 147 |
1 files changed, 62 insertions, 85 deletions
diff --git a/src/eval.c b/src/eval.c index 22ee4d1afd1..023c2ef6aab 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -226,9 +226,8 @@ init_eval (void) | |||
| 226 | { /* Put a dummy catcher at top-level so that handlerlist is never NULL. | 226 | { /* Put a dummy catcher at top-level so that handlerlist is never NULL. |
| 227 | This is important since handlerlist->nextfree holds the freelist | 227 | This is important since handlerlist->nextfree holds the freelist |
| 228 | which would otherwise leak every time we unwind back to top-level. */ | 228 | which would otherwise leak every time we unwind back to top-level. */ |
| 229 | struct handler *c; | ||
| 230 | handlerlist = handlerlist_sentinel.nextfree = &handlerlist_sentinel; | 229 | handlerlist = handlerlist_sentinel.nextfree = &handlerlist_sentinel; |
| 231 | PUSH_HANDLER (c, Qunbound, CATCHER); | 230 | struct handler *c = push_handler (Qunbound, CATCHER); |
| 232 | eassert (c == &handlerlist_sentinel); | 231 | eassert (c == &handlerlist_sentinel); |
| 233 | handlerlist_sentinel.nextfree = NULL; | 232 | handlerlist_sentinel.nextfree = NULL; |
| 234 | handlerlist_sentinel.next = NULL; | 233 | handlerlist_sentinel.next = NULL; |
| @@ -1059,18 +1058,16 @@ usage: (catch TAG BODY...) */) | |||
| 1059 | This is how catches are done from within C code. */ | 1058 | This is how catches are done from within C code. */ |
| 1060 | 1059 | ||
| 1061 | Lisp_Object | 1060 | Lisp_Object |
| 1062 | internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1061 | internal_catch (Lisp_Object tag, |
| 1062 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | ||
| 1063 | { | 1063 | { |
| 1064 | /* This structure is made part of the chain `catchlist'. */ | 1064 | /* This structure is made part of the chain `catchlist'. */ |
| 1065 | struct handler *c; | 1065 | struct handler *c = push_handler (tag, CATCHER); |
| 1066 | |||
| 1067 | /* Fill in the components of c, and put it on the list. */ | ||
| 1068 | PUSH_HANDLER (c, tag, CATCHER); | ||
| 1069 | 1066 | ||
| 1070 | /* Call FUNC. */ | 1067 | /* Call FUNC. */ |
| 1071 | if (! sys_setjmp (c->jmp)) | 1068 | if (! sys_setjmp (c->jmp)) |
| 1072 | { | 1069 | { |
| 1073 | Lisp_Object val = (*func) (arg); | 1070 | Lisp_Object val = func (arg); |
| 1074 | clobbered_eassert (handlerlist == c); | 1071 | clobbered_eassert (handlerlist == c); |
| 1075 | handlerlist = handlerlist->next; | 1072 | handlerlist = handlerlist->next; |
| 1076 | return val; | 1073 | return val; |
| @@ -1147,7 +1144,7 @@ Both TAG and VALUE are evalled. */ | |||
| 1147 | { | 1144 | { |
| 1148 | if (c->type == CATCHER_ALL) | 1145 | if (c->type == CATCHER_ALL) |
| 1149 | unwind_to_catch (c, Fcons (tag, value)); | 1146 | unwind_to_catch (c, Fcons (tag, value)); |
| 1150 | if (c->type == CATCHER && EQ (c->tag_or_ch, tag)) | 1147 | if (c->type == CATCHER && EQ (c->tag_or_ch, tag)) |
| 1151 | unwind_to_catch (c, value); | 1148 | unwind_to_catch (c, value); |
| 1152 | } | 1149 | } |
| 1153 | xsignal2 (Qno_catch, tag, value); | 1150 | xsignal2 (Qno_catch, tag, value); |
| @@ -1213,7 +1210,6 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1213 | Lisp_Object handlers) | 1210 | Lisp_Object handlers) |
| 1214 | { | 1211 | { |
| 1215 | Lisp_Object val; | 1212 | Lisp_Object val; |
| 1216 | struct handler *c; | ||
| 1217 | struct handler *oldhandlerlist = handlerlist; | 1213 | struct handler *oldhandlerlist = handlerlist; |
| 1218 | int clausenb = 0; | 1214 | int clausenb = 0; |
| 1219 | 1215 | ||
| @@ -1248,7 +1244,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1248 | Lisp_Object condition = XCAR (clause); | 1244 | Lisp_Object condition = XCAR (clause); |
| 1249 | if (!CONSP (condition)) | 1245 | if (!CONSP (condition)) |
| 1250 | condition = Fcons (condition, Qnil); | 1246 | condition = Fcons (condition, Qnil); |
| 1251 | PUSH_HANDLER (c, condition, CONDITION_CASE); | 1247 | struct handler *c = push_handler (condition, CONDITION_CASE); |
| 1252 | if (sys_setjmp (c->jmp)) | 1248 | if (sys_setjmp (c->jmp)) |
| 1253 | { | 1249 | { |
| 1254 | ptrdiff_t count = SPECPDL_INDEX (); | 1250 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -1296,46 +1292,45 @@ Lisp_Object | |||
| 1296 | internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers, | 1292 | internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers, |
| 1297 | Lisp_Object (*hfun) (Lisp_Object)) | 1293 | Lisp_Object (*hfun) (Lisp_Object)) |
| 1298 | { | 1294 | { |
| 1299 | Lisp_Object val; | 1295 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1300 | struct handler *c; | ||
| 1301 | |||
| 1302 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1303 | if (sys_setjmp (c->jmp)) | 1296 | if (sys_setjmp (c->jmp)) |
| 1304 | { | 1297 | { |
| 1305 | Lisp_Object val = handlerlist->val; | 1298 | Lisp_Object val = handlerlist->val; |
| 1306 | clobbered_eassert (handlerlist == c); | 1299 | clobbered_eassert (handlerlist == c); |
| 1307 | handlerlist = handlerlist->next; | 1300 | handlerlist = handlerlist->next; |
| 1308 | return (*hfun) (val); | 1301 | return hfun (val); |
| 1302 | } | ||
| 1303 | else | ||
| 1304 | { | ||
| 1305 | Lisp_Object val = bfun (); | ||
| 1306 | clobbered_eassert (handlerlist == c); | ||
| 1307 | handlerlist = handlerlist->next; | ||
| 1308 | return val; | ||
| 1309 | } | 1309 | } |
| 1310 | |||
| 1311 | val = (*bfun) (); | ||
| 1312 | clobbered_eassert (handlerlist == c); | ||
| 1313 | handlerlist = handlerlist->next; | ||
| 1314 | return val; | ||
| 1315 | } | 1310 | } |
| 1316 | 1311 | ||
| 1317 | /* Like internal_condition_case but call BFUN with ARG as its argument. */ | 1312 | /* Like internal_condition_case but call BFUN with ARG as its argument. */ |
| 1318 | 1313 | ||
| 1319 | Lisp_Object | 1314 | Lisp_Object |
| 1320 | internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, | 1315 | internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, |
| 1321 | Lisp_Object handlers, Lisp_Object (*hfun) (Lisp_Object)) | 1316 | Lisp_Object handlers, |
| 1317 | Lisp_Object (*hfun) (Lisp_Object)) | ||
| 1322 | { | 1318 | { |
| 1323 | Lisp_Object val; | 1319 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1324 | struct handler *c; | ||
| 1325 | |||
| 1326 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1327 | if (sys_setjmp (c->jmp)) | 1320 | if (sys_setjmp (c->jmp)) |
| 1328 | { | 1321 | { |
| 1329 | Lisp_Object val = handlerlist->val; | 1322 | Lisp_Object val = handlerlist->val; |
| 1330 | clobbered_eassert (handlerlist == c); | 1323 | clobbered_eassert (handlerlist == c); |
| 1331 | handlerlist = handlerlist->next; | 1324 | handlerlist = handlerlist->next; |
| 1332 | return (*hfun) (val); | 1325 | return hfun (val); |
| 1326 | } | ||
| 1327 | else | ||
| 1328 | { | ||
| 1329 | Lisp_Object val = bfun (arg); | ||
| 1330 | clobbered_eassert (handlerlist == c); | ||
| 1331 | handlerlist = handlerlist->next; | ||
| 1332 | return val; | ||
| 1333 | } | 1333 | } |
| 1334 | |||
| 1335 | val = (*bfun) (arg); | ||
| 1336 | clobbered_eassert (handlerlist == c); | ||
| 1337 | handlerlist = handlerlist->next; | ||
| 1338 | return val; | ||
| 1339 | } | 1334 | } |
| 1340 | 1335 | ||
| 1341 | /* Like internal_condition_case_1 but call BFUN with ARG1 and ARG2 as | 1336 | /* Like internal_condition_case_1 but call BFUN with ARG1 and ARG2 as |
| @@ -1348,22 +1343,21 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object), | |||
| 1348 | Lisp_Object handlers, | 1343 | Lisp_Object handlers, |
| 1349 | Lisp_Object (*hfun) (Lisp_Object)) | 1344 | Lisp_Object (*hfun) (Lisp_Object)) |
| 1350 | { | 1345 | { |
| 1351 | Lisp_Object val; | 1346 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1352 | struct handler *c; | ||
| 1353 | |||
| 1354 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1355 | if (sys_setjmp (c->jmp)) | 1347 | if (sys_setjmp (c->jmp)) |
| 1356 | { | 1348 | { |
| 1357 | Lisp_Object val = handlerlist->val; | 1349 | Lisp_Object val = handlerlist->val; |
| 1358 | clobbered_eassert (handlerlist == c); | 1350 | clobbered_eassert (handlerlist == c); |
| 1359 | handlerlist = handlerlist->next; | 1351 | handlerlist = handlerlist->next; |
| 1360 | return (*hfun) (val); | 1352 | return hfun (val); |
| 1353 | } | ||
| 1354 | else | ||
| 1355 | { | ||
| 1356 | Lisp_Object val = bfun (arg1, arg2); | ||
| 1357 | clobbered_eassert (handlerlist == c); | ||
| 1358 | handlerlist = handlerlist->next; | ||
| 1359 | return val; | ||
| 1361 | } | 1360 | } |
| 1362 | |||
| 1363 | val = (*bfun) (arg1, arg2); | ||
| 1364 | clobbered_eassert (handlerlist == c); | ||
| 1365 | handlerlist = handlerlist->next; | ||
| 1366 | return val; | ||
| 1367 | } | 1361 | } |
| 1368 | 1362 | ||
| 1369 | /* Like internal_condition_case but call BFUN with NARGS as first, | 1363 | /* Like internal_condition_case but call BFUN with NARGS as first, |
| @@ -1378,64 +1372,46 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1378 | ptrdiff_t nargs, | 1372 | ptrdiff_t nargs, |
| 1379 | Lisp_Object *args)) | 1373 | Lisp_Object *args)) |
| 1380 | { | 1374 | { |
| 1381 | Lisp_Object val; | 1375 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1382 | struct handler *c; | ||
| 1383 | |||
| 1384 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1385 | if (sys_setjmp (c->jmp)) | 1376 | if (sys_setjmp (c->jmp)) |
| 1386 | { | 1377 | { |
| 1387 | Lisp_Object val = handlerlist->val; | 1378 | Lisp_Object val = handlerlist->val; |
| 1388 | clobbered_eassert (handlerlist == c); | 1379 | clobbered_eassert (handlerlist == c); |
| 1389 | handlerlist = handlerlist->next; | 1380 | handlerlist = handlerlist->next; |
| 1390 | return (*hfun) (val, nargs, args); | 1381 | return hfun (val, nargs, args); |
| 1391 | } | 1382 | } |
| 1392 | |||
| 1393 | val = (*bfun) (nargs, args); | ||
| 1394 | clobbered_eassert (handlerlist == c); | ||
| 1395 | handlerlist = handlerlist->next; | ||
| 1396 | return val; | ||
| 1397 | } | ||
| 1398 | |||
| 1399 | static void init_handler (struct handler *c, Lisp_Object tag_ch_val, | ||
| 1400 | enum handlertype handlertype); | ||
| 1401 | |||
| 1402 | void | ||
| 1403 | push_handler (struct handler **c, Lisp_Object tag_ch_val, | ||
| 1404 | enum handlertype handlertype) | ||
| 1405 | { | ||
| 1406 | if (handlerlist->nextfree) | ||
| 1407 | *c = handlerlist->nextfree; | ||
| 1408 | else | 1383 | else |
| 1409 | { | 1384 | { |
| 1410 | *c = xmalloc (sizeof (struct handler)); | 1385 | Lisp_Object val = bfun (nargs, args); |
| 1411 | (*c)->nextfree = NULL; | 1386 | clobbered_eassert (handlerlist == c); |
| 1412 | handlerlist->nextfree = *c; | 1387 | handlerlist = handlerlist->next; |
| 1388 | return val; | ||
| 1413 | } | 1389 | } |
| 1414 | init_handler (*c, tag_ch_val, handlertype); | ||
| 1415 | } | 1390 | } |
| 1416 | 1391 | ||
| 1417 | bool | 1392 | struct handler * |
| 1418 | push_handler_nosignal (struct handler **c, Lisp_Object tag_ch_val, | 1393 | push_handler (Lisp_Object tag_ch_val, enum handlertype handlertype) |
| 1419 | enum handlertype handlertype) | ||
| 1420 | { | 1394 | { |
| 1421 | if (handlerlist->nextfree) | 1395 | struct handler *c = push_handler_nosignal (tag_ch_val, handlertype); |
| 1422 | *c = handlerlist->nextfree; | 1396 | if (!c) |
| 1423 | else | 1397 | memory_full (sizeof *c); |
| 1424 | { | 1398 | return c; |
| 1425 | struct handler *h = malloc (sizeof (struct handler)); | ||
| 1426 | if (! h) return false; | ||
| 1427 | *c = h; | ||
| 1428 | h->nextfree = NULL; | ||
| 1429 | handlerlist->nextfree = h; | ||
| 1430 | } | ||
| 1431 | init_handler (*c, tag_ch_val, handlertype); | ||
| 1432 | return true; | ||
| 1433 | } | 1399 | } |
| 1434 | 1400 | ||
| 1435 | static void | 1401 | struct handler * |
| 1436 | init_handler (struct handler *c, Lisp_Object tag_ch_val, | 1402 | push_handler_nosignal (Lisp_Object tag_ch_val, enum handlertype handlertype) |
| 1437 | enum handlertype handlertype) | ||
| 1438 | { | 1403 | { |
| 1404 | struct handler *c = handlerlist->nextfree; | ||
| 1405 | if (!c) | ||
| 1406 | { | ||
| 1407 | c = malloc (sizeof *c); | ||
| 1408 | if (!c) | ||
| 1409 | return c; | ||
| 1410 | if (profiler_memory_running) | ||
| 1411 | malloc_probe (sizeof *c); | ||
| 1412 | c->nextfree = NULL; | ||
| 1413 | handlerlist->nextfree = c; | ||
| 1414 | } | ||
| 1439 | c->type = handlertype; | 1415 | c->type = handlertype; |
| 1440 | c->tag_or_ch = tag_ch_val; | 1416 | c->tag_or_ch = tag_ch_val; |
| 1441 | c->val = Qnil; | 1417 | c->val = Qnil; |
| @@ -1446,6 +1422,7 @@ init_handler (struct handler *c, Lisp_Object tag_ch_val, | |||
| 1446 | c->interrupt_input_blocked = interrupt_input_blocked; | 1422 | c->interrupt_input_blocked = interrupt_input_blocked; |
| 1447 | c->byte_stack = byte_stack_list; | 1423 | c->byte_stack = byte_stack_list; |
| 1448 | handlerlist = c; | 1424 | handlerlist = c; |
| 1425 | return c; | ||
| 1449 | } | 1426 | } |
| 1450 | 1427 | ||
| 1451 | 1428 | ||