1 /* src/vm/jit/mips/patcher.c - MIPS code patching functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
31 $Id: patcher.c 3113 2005-07-27 10:36:38Z twisti $
37 #include "vm/jit/mips/types.h"
39 #include "mm/memory.h"
40 #include "native/native.h"
41 #include "vm/builtin.h"
43 #include "vm/initialize.h"
44 #include "vm/options.h"
45 #include "vm/references.h"
46 #include "vm/jit/asmpart.h"
47 #include "vm/jit/helper.h"
48 #include "vm/jit/patcher.h"
51 /* patcher_get_putstatic *******************************************************
55 <patched call position>
56 dfc1ffb8 ld at,-72(s8)
59 *******************************************************************************/
61 bool patcher_get_putstatic(u1 *sp)
71 /* get stuff from the stack */
73 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
74 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
75 mcode = *((u8 *) (sp + 3 * 8));
76 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
77 disp = *((s4 *) (sp + 1 * 8));
78 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
80 /* calculate and set the new return address */
83 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
87 /* get the fieldinfo */
89 if (!(fi = helper_resolve_fieldinfo(uf))) {
95 /* check if the field's class is initialized */
97 if (!fi->class->initialized)
98 if (!initialize_class(fi->class))
101 /* patch back original code */
103 *((u4 *) (ra + 0 * 4)) = mcode;
104 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
106 /* synchronize instruction cache */
108 docacheflush(ra, 2 * 4);
110 /* patch the field value's address */
112 *((ptrint *) (pv + disp)) = (ptrint) &(fi->value);
114 PATCHER_MARK_PATCHED_MONITOREXIT;
120 /* patcher_get_putfield ********************************************************
124 <patched call position>
125 8ee90020 lw a5,32(s7)
127 *******************************************************************************/
129 bool patcher_get_putfield(u1 *sp)
132 java_objectheader *o;
134 unresolved_field *uf;
137 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
138 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
139 mcode = *((u8 *) (sp + 3 * 8));
140 uf = (unresolved_field *) *((ptrint *) (sp + 2 * 8));
142 /* calculate and set the new return address */
145 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
147 PATCHER_MONITORENTER;
149 /* get the fieldinfo */
151 if (!(fi = helper_resolve_fieldinfo(uf))) {
157 /* patch back original code */
159 *((u4 *) (ra + 0 * 4)) = mcode;
160 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
162 /* if we show disassembly, we have to skip the nop's */
164 if (opt_showdisassemble)
167 /* patch the field's offset */
169 *((u4 *) ra) |= (s2) (fi->offset & 0x0000ffff);
171 /* synchronize instruction cache */
173 docacheflush(ra, 2 * 4);
175 PATCHER_MARK_PATCHED_MONITOREXIT;
181 /* patcher_builtin_new *********************************************************
185 dfc4ff98 ld a0,-104(s8)
186 <patched call postition>
187 dfd9ff90 ld t9,-112(s8)
191 NOTICE: Only the displacement for the function address is passed,
192 but the address of the classinfo pointer is one below (above, in
193 addresses speaking). This is for sure.
195 *******************************************************************************/
197 bool patcher_builtin_new(u1 *sp)
200 java_objectheader *o;
202 constant_classref *cr;
207 /* get stuff from the stack */
209 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
210 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
211 mcode = *((u8 *) (sp + 3 * 8));
212 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
213 disp = *((s4 *) (sp + 1 * 8));
214 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
216 /* calculate and set the new return address */
219 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
221 PATCHER_MONITORENTER;
223 /* get the classinfo */
225 if (!(c = helper_resolve_classinfo(cr))) {
231 /* patch back original code */
233 *((u4 *) (ra + 1 * 4)) = mcode;
234 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
236 /* synchronize instruction cache */
238 docacheflush(ra + 1 * 4, 2 * 4);
240 /* patch the classinfo pointer */
242 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c;
244 /* patch new function address */
246 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_new;
248 PATCHER_MARK_PATCHED_MONITOREXIT;
254 /* patcher_builtin_newarray ****************************************************
258 dfc5ffa0 ld a1,-96(s8)
259 <patched call position>
260 dfd9ff98 ld t9,-104(s8)
264 NOTICE: Only the displacement for the function address is passed,
265 but the address of the classinfo pointer is one below (above, in
266 addresses speaking). This is for sure.
268 *******************************************************************************/
270 bool patcher_builtin_newarray(u1 *sp)
273 java_objectheader *o;
275 constant_classref *cr;
280 /* get stuff from the stack */
282 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
283 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
284 mcode = *((u8 *) (sp + 3 * 8));
285 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
286 disp = *((s4 *) (sp + 1 * 8));
287 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
289 /* calculate and set the new return address */
292 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
294 PATCHER_MONITORENTER;
296 /* get the classinfo */
298 if (!(c = helper_resolve_classinfo(cr))) {
304 /* patch back original code */
306 *((u4 *) (ra + 1 * 4)) = mcode;
307 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
309 /* synchronize instruction cache */
311 docacheflush(ra + 4, 2 * 4);
313 /* patch the class' vftbl pointer */
315 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
317 /* patch new function address */
319 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_newarray;
321 PATCHER_MARK_PATCHED_MONITOREXIT;
327 /* patcher_builtin_multianewarray **********************************************
331 <patched call position>
332 dfc5ff90 ld a1,-112(s8)
334 dfd9ff88 ld t9,-120(s8)
338 *******************************************************************************/
340 bool patcher_builtin_multianewarray(u1 *sp)
343 java_objectheader *o;
345 constant_classref *cr;
350 /* get stuff from the stack */
352 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
353 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
354 mcode = *((u8 *) (sp + 3 * 8));
355 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
356 disp = *((s4 *) (sp + 1 * 8));
357 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
359 /* calculate and set the new return address */
362 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
364 PATCHER_MONITORENTER;
366 /* get the classinfo */
368 if (!(c = helper_resolve_classinfo(cr))) {
374 /* patch back original code */
376 *((u4 *) (ra + 0 * 4)) = mcode;
377 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
379 /* synchronize instruction cache */
381 docacheflush(ra, 2 * 4);
383 /* patch the class' vftbl pointer */
385 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
387 PATCHER_MARK_PATCHED_MONITOREXIT;
393 /* patcher_builtin_arraycheckcast **********************************************
397 <patched call position>
398 dfc5ffc0 ld a1,-64(s8)
399 dfd9ffb8 ld t9,-72(s8)
403 NOTICE: Only the displacement of the vftbl pointer address is
404 passed, but the address of the function pointer is one above
405 (below, in addresses speaking). This is for sure.
407 *******************************************************************************/
409 bool patcher_builtin_arraycheckcast(u1 *sp)
412 java_objectheader *o;
414 constant_classref *cr;
419 /* get stuff from the stack */
421 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
422 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
423 mcode = *((u8 *) (sp + 3 * 8));
424 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
425 disp = *((s4 *) (sp + 1 * 8));
426 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
428 /* calculate and set the new return address */
431 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
433 PATCHER_MONITORENTER;
435 /* get the classinfo */
437 if (!(c = helper_resolve_classinfo(cr))) {
443 /* patch back original code */
445 *((u4 *) (ra + 0 * 4)) = mcode;
446 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
448 /* synchronize instruction cache */
450 docacheflush(ra, 2 * 4);
452 /* patch the class' vftbl pointer */
454 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
456 /* patch new function address */
458 *((ptrint *) (pv + (disp - SIZEOF_VOID_P))) =
459 (ptrint) BUILTIN_arraycheckcast;
461 PATCHER_MARK_PATCHED_MONITOREXIT;
467 /* patcher_builtin_arrayinstanceof *********************************************
471 dfc5fe98 ld a1,-360(s8)
472 <patched call position>
473 dfd9fe90 ld t9,-368(s8)
477 NOTICE: Only the displacement for the function address is passed,
478 but the address of the vftbl pointer is one below (above, in
479 addresses speaking). This is for sure.
481 *******************************************************************************/
483 bool patcher_builtin_arrayinstanceof(u1 *sp)
486 java_objectheader *o;
488 constant_classref *cr;
493 /* get stuff from the stack */
495 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
496 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
497 mcode = *((u8 *) (sp + 3 * 8));
498 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
499 disp = *((s4 *) (sp + 1 * 8));
500 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
502 /* calculate and set the new return address */
505 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
507 PATCHER_MONITORENTER;
509 /* get the classinfo */
511 if (!(c = helper_resolve_classinfo(cr))) {
517 /* patch back original code */
519 *((u4 *) (ra + 1 * 4)) = mcode;
520 *((u4 *) (ra + 2 * 4)) = mcode >> 32;
522 /* synchronize instruction cache */
524 docacheflush(ra + 1 * 4, 2 * 4);
526 /* patch the class' vftbl pointer */
528 *((ptrint *) (pv + (disp + SIZEOF_VOID_P))) = (ptrint) c->vftbl;
530 /* patch new function address */
532 *((ptrint *) (pv + disp)) = (ptrint) BUILTIN_arrayinstanceof;
534 PATCHER_MARK_PATCHED_MONITOREXIT;
540 /* patcher_invokestatic_special ************************************************
544 <patched call position>
545 dfdeffc0 ld s8,-64(s8)
549 ******************************************************************************/
551 bool patcher_invokestatic_special(u1 *sp)
554 java_objectheader *o;
556 unresolved_method *um;
561 /* get stuff from the stack */
563 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
564 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
565 mcode = *((u8 *) (sp + 3 * 8));
566 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
567 disp = *((s4 *) (sp + 1 * 8));
568 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
570 /* calculate and set the new return address */
573 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
575 PATCHER_MONITORENTER;
577 /* get the fieldinfo */
579 if (!(m = helper_resolve_methodinfo(um))) {
585 /* patch back original code */
587 *((u4 *) (ra + 0 * 4)) = mcode;
588 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
590 /* synchronize instruction cache */
592 docacheflush(ra, 2 * 4);
594 /* patch stubroutine */
596 *((ptrint *) (pv + disp)) = (ptrint) m->stubroutine;
598 PATCHER_MARK_PATCHED_MONITOREXIT;
604 /* patcher_invokevirtual *******************************************************
608 <patched call position>
610 df3e0040 ld s8,64(t9)
614 *******************************************************************************/
616 bool patcher_invokevirtual(u1 *sp)
619 java_objectheader *o;
621 unresolved_method *um;
624 /* get stuff from the stack */
626 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
627 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
628 mcode = *((u8 *) (sp + 3 * 8));
629 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
631 /* calculate and set the new return address */
634 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
636 PATCHER_MONITORENTER;
638 /* get the fieldinfo */
640 if (!(m = helper_resolve_methodinfo(um))) {
646 /* patch back original code */
648 *((u4 *) (ra + 0 * 4)) = mcode;
649 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
651 /* if we show disassembly, we have to skip the nop's */
653 if (opt_showdisassemble)
656 /* patch vftbl index */
658 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, table[0]) +
659 sizeof(methodptr) * m->vftblindex) & 0x0000ffff);
661 /* synchronize instruction cache */
663 docacheflush(ra, 2 * 4);
665 PATCHER_MARK_PATCHED_MONITOREXIT;
671 /* patcher_invokeinterface *****************************************************
675 <patched call position>
677 df39ffa0 ld t9,-96(t9)
678 df3e0018 ld s8,24(t9)
682 *******************************************************************************/
684 bool patcher_invokeinterface(u1 *sp)
687 java_objectheader *o;
689 unresolved_method *um;
692 /* get stuff from the stack */
694 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
695 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
696 mcode = *((u8 *) (sp + 3 * 8));
697 um = (unresolved_method *) *((ptrint *) (sp + 2 * 8));
699 /* calculate and set the new return address */
702 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
704 PATCHER_MONITORENTER;
706 /* get the fieldinfo */
708 if (!(m = helper_resolve_methodinfo(um))) {
714 /* patch back original code */
716 *((u4 *) (ra + 0 * 4)) = mcode;
717 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
719 /* if we show disassembly, we have to skip the nop's */
721 if (opt_showdisassemble)
724 /* patch interfacetable index */
726 *((s4 *) (ra + 1 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
727 sizeof(methodptr*) * m->class->index) & 0x0000ffff);
729 /* patch method offset */
731 *((s4 *) (ra + 2 * 4)) |=
732 (s4) ((sizeof(methodptr) * (m - m->class->methods)) & 0x0000ffff);
734 /* synchronize instruction cache */
736 docacheflush(ra, 2 * 4);
738 PATCHER_MARK_PATCHED_MONITOREXIT;
744 /* patcher_checkcast_instanceof_flags ******************************************
748 <patched call position>
749 8fc3ff24 lw v1,-220(s8)
750 30630200 andi v1,v1,512
751 1060000d beq v1,zero,0x000000001051824c
754 *******************************************************************************/
756 bool patcher_checkcast_instanceof_flags(u1 *sp)
759 java_objectheader *o;
761 constant_classref *cr;
766 /* get stuff from the stack */
768 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
769 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
770 mcode = *((u8 *) (sp + 3 * 8));
771 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
772 disp = *((s4 *) (sp + 1 * 8));
773 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
775 /* calculate and set the new return address */
778 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
780 PATCHER_MONITORENTER;
782 /* get the fieldinfo */
784 if (!(c = helper_resolve_classinfo(cr))) {
790 /* patch back original code */
792 *((u4 *) (ra + 0 * 4)) = mcode;
793 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
795 /* synchronize instruction cache */
797 docacheflush(ra, 2 * 4);
799 /* patch class flags */
801 *((s4 *) (pv + disp)) = (s4) c->flags;
803 PATCHER_MARK_PATCHED_MONITOREXIT;
809 /* patcher_checkcast_instanceof_interface **************************************
813 <patched call position>
815 8c79001c lw t9,28(v1)
816 27390000 addiu t9,t9,0
817 1b200082 blez t9,zero,0x000000001051843c
821 *******************************************************************************/
823 bool patcher_checkcast_instanceof_interface(u1 *sp)
826 java_objectheader *o;
828 constant_classref *cr;
831 /* get stuff from the stack */
833 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
834 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
835 mcode = *((u8 *) (sp + 3 * 8));
836 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
838 /* calculate and set the new return address */
841 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
843 PATCHER_MONITORENTER;
845 /* get the fieldinfo */
847 if (!(c = helper_resolve_classinfo(cr))) {
853 /* patch back original code */
855 *((u4 *) (ra + 0 * 4)) = mcode;
856 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
858 /* if we show disassembly, we have to skip the nop's */
860 if (opt_showdisassemble)
863 /* patch super class index */
865 *((s4 *) (ra + 2 * 4)) |= (s4) (-(c->index) & 0x0000ffff);
867 *((s4 *) (ra + 5 * 4)) |= (s4) ((OFFSET(vftbl_t, interfacetable[0]) -
868 c->index * sizeof(methodptr*)) & 0x0000ffff);
870 /* synchronize instruction cache */
872 docacheflush(ra, 6 * 4);
874 PATCHER_MARK_PATCHED_MONITOREXIT;
880 /* patcher_checkcast_instanceof_class ******************************************
884 <patched call position>
886 dfd9ff18 ld t9,-232(s8)
888 *******************************************************************************/
890 bool patcher_checkcast_instanceof_class(u1 *sp)
893 java_objectheader *o;
895 constant_classref *cr;
900 /* get stuff from the stack */
902 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
903 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
904 mcode = *((u8 *) (sp + 3 * 8));
905 cr = (constant_classref *) *((ptrint *) (sp + 2 * 8));
906 disp = *((s4 *) (sp + 1 * 8));
907 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
909 /* calculate and set the new return address */
912 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
914 PATCHER_MONITORENTER;
916 /* get the fieldinfo */
918 if (!(c = helper_resolve_classinfo(cr))) {
924 /* patch back original code */
926 *((u4 *) (ra + 0 * 4)) = mcode;
927 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
929 /* synchronize instruction cache */
931 docacheflush(ra, 2 * 4);
933 /* patch super class' vftbl */
935 *((ptrint *) (pv + disp)) = (ptrint) c->vftbl;
937 PATCHER_MARK_PATCHED_MONITOREXIT;
943 /* patcher_clinit **************************************************************
947 *******************************************************************************/
949 bool patcher_clinit(u1 *sp)
952 java_objectheader *o;
956 /* get stuff from the stack */
958 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
959 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
960 mcode = *((u8 *) (sp + 3 * 8));
961 c = (classinfo *) *((ptrint *) (sp + 2 * 8));
963 /* calculate and set the new return address */
966 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
968 PATCHER_MONITORENTER;
970 /* check if the class is initialized */
972 if (!c->initialized) {
973 if (!initialize_class(c)) {
980 /* patch back original code */
982 *((u4 *) (ra + 0)) = mcode;
983 *((u4 *) (ra + 4)) = mcode >> 32;
985 /* synchronize instruction cache */
987 docacheflush(ra, 2 * 4);
989 PATCHER_MARK_PATCHED_MONITOREXIT;
995 /* patcher_resolve_native ******************************************************
999 *******************************************************************************/
1001 #if !defined(ENABLE_STATICVM)
1002 bool patcher_resolve_native(u1 *sp)
1005 java_objectheader *o;
1012 /* get stuff from the stack */
1014 ra = (u1 *) *((ptrint *) (sp + 5 * 8));
1015 o = (java_objectheader *) *((ptrint *) (sp + 4 * 8));
1016 mcode = *((u8 *) (sp + 3 * 8));
1017 m = (methodinfo *) *((ptrint *) (sp + 2 * 8));
1018 disp = *((s4 *) (sp + 1 * 8));
1019 pv = (u1 *) *((ptrint *) (sp + 0 * 8));
1021 /* calculate and set the new return address */
1024 *((ptrint *) (sp + 5 * 8)) = (ptrint) ra;
1026 PATCHER_MONITORENTER;
1028 /* resolve native function */
1030 if (!(f = native_resolve_function(m))) {
1031 PATCHER_MONITOREXIT;
1036 /* patch back original code */
1038 *((u4 *) (ra + 0 * 4)) = mcode;
1039 *((u4 *) (ra + 1 * 4)) = mcode >> 32;
1041 /* synchronize instruction cache */
1043 docacheflush(ra, 2 * 4);
1045 /* patch native function pointer */
1047 *((ptrint *) (pv + disp)) = (ptrint) f;
1049 PATCHER_MARK_PATCHED_MONITOREXIT;
1053 #endif /* !defined(ENABLE_STATICVM) */
1057 * These are local overrides for various environment variables in Emacs.
1058 * Please do not remove this and leave it at the end of the file, where
1059 * Emacs will automagically detect them.
1060 * ---------------------------------------------------------------------
1063 * indent-tabs-mode: t
1067 * vim:noexpandtab:sw=4:ts=4: