aboutsummaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorPaul Eggert2015-11-19 20:09:11 -0800
committerPaul Eggert2015-11-19 20:09:59 -0800
commitaa7dac899804727875cdb8fe267d37adcbe9705a (patch)
tree7418cf4365ac5a647fe7d91cc818852671ac770b /src/eval.c
parentde67fa4258293e18d8aacd6e0c3298f70dbafe32 (diff)
downloademacs-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.c147
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
1061Lisp_Object 1060Lisp_Object
1062internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) 1061internal_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
1296internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers, 1292internal_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
1319Lisp_Object 1314Lisp_Object
1320internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, 1315internal_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
1399static void init_handler (struct handler *c, Lisp_Object tag_ch_val,
1400 enum handlertype handlertype);
1401
1402void
1403push_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
1417bool 1392struct handler *
1418push_handler_nosignal (struct handler **c, Lisp_Object tag_ch_val, 1393push_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
1435static void 1401struct handler *
1436init_handler (struct handler *c, Lisp_Object tag_ch_val, 1402push_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