aboutsummaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/bytecode.c14
-rw-r--r--src/emacs-module.c4
-rw-r--r--src/eval.c147
-rw-r--r--src/lisp.h14
4 files changed, 71 insertions, 108 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 864db1a0bed..464adc633a8 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -1067,17 +1067,13 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1067 type = CATCHER; 1067 type = CATCHER;
1068 goto pushhandler; 1068 goto pushhandler;
1069 CASE (Bpushconditioncase): /* New in 24.4. */ 1069 CASE (Bpushconditioncase): /* New in 24.4. */
1070 type = CONDITION_CASE;
1071 pushhandler:
1070 { 1072 {
1071 struct handler *c; 1073 Lisp_Object tag = POP;
1072 Lisp_Object tag; 1074 int dest = FETCH2;
1073 int dest;
1074 1075
1075 type = CONDITION_CASE; 1076 struct handler *c = push_handler (tag, type);
1076 pushhandler:
1077 tag = POP;
1078 dest = FETCH2;
1079
1080 PUSH_HANDLER (c, tag, type);
1081 c->bytecode_dest = dest; 1077 c->bytecode_dest = dest;
1082 c->bytecode_top = top; 1078 c->bytecode_top = top;
1083 1079
diff --git a/src/emacs-module.c b/src/emacs-module.c
index f611c8ba600..e885af5de8f 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -194,8 +194,8 @@ static void module_wrong_type (emacs_env *, Lisp_Object, Lisp_Object);
194#define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \ 194#define MODULE_SETJMP_1(handlertype, handlerfunc, retval, c, dummy) \
195 do { \ 195 do { \
196 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); \ 196 eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); \
197 struct handler *c; \ 197 struct handler *c = push_handler_nosignal (Qt, handlertype); \
198 if (!push_handler_nosignal (&c, Qt, handlertype)) \ 198 if (!c) \
199 { \ 199 { \
200 module_out_of_memory (env); \ 200 module_out_of_memory (env); \
201 return retval; \ 201 return retval; \
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
diff --git a/src/lisp.h b/src/lisp.h
index 3b7bb40caa2..71dca7201d0 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3183,18 +3183,6 @@ struct handler
3183 struct byte_stack *byte_stack; 3183 struct byte_stack *byte_stack;
3184}; 3184};
3185 3185
3186/* Fill in the components of c, and put it on the list. */
3187#define PUSH_HANDLER(c, tag_ch_val, handlertype) \
3188 push_handler(&(c), (tag_ch_val), (handlertype))
3189
3190extern void push_handler (struct handler **c, Lisp_Object tag_ch_val,
3191 enum handlertype handlertype);
3192
3193/* Like push_handler, but don't signal if the handler could not be
3194 allocated. Instead return false in that case. */
3195extern bool push_handler_nosignal (struct handler **c, Lisp_Object tag_ch_val,
3196 enum handlertype handlertype);
3197
3198extern Lisp_Object memory_signal_data; 3186extern Lisp_Object memory_signal_data;
3199 3187
3200/* An address near the bottom of the stack. 3188/* An address near the bottom of the stack.
@@ -3880,6 +3868,8 @@ extern Lisp_Object internal_condition_case_2 (Lisp_Object (*) (Lisp_Object, Lisp
3880extern Lisp_Object internal_condition_case_n 3868extern Lisp_Object internal_condition_case_n
3881 (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *, 3869 (Lisp_Object (*) (ptrdiff_t, Lisp_Object *), ptrdiff_t, Lisp_Object *,
3882 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *)); 3870 Lisp_Object, Lisp_Object (*) (Lisp_Object, ptrdiff_t, Lisp_Object *));
3871extern struct handler *push_handler (Lisp_Object, enum handlertype);
3872extern struct handler *push_handler_nosignal (Lisp_Object, enum handlertype);
3883extern void specbind (Lisp_Object, Lisp_Object); 3873extern void specbind (Lisp_Object, Lisp_Object);
3884extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object); 3874extern void record_unwind_protect (void (*) (Lisp_Object), Lisp_Object);
3885extern void record_unwind_protect_ptr (void (*) (void *), void *); 3875extern void record_unwind_protect_ptr (void (*) (void *), void *);