17static char SccsId[] =
"@(#)save.c 1.3 3/15/90";
22#if _MSC_VER || defined(__MINGW32__)
40#define strncat(X, Y, Z) strcat(X, Y)
43#define strncpy(X, Y, Z) strcpy(X, Y)
52#ifdef HAVE_SYS_TYPES_H
62static char end_msg[256] =
"*** End of YAP saved state *****";
88static int myread(FILE *,
char *, Int);
89static Int mywrite(FILE *,
char *, Int);
90static FILE *open_file(
const char *,
int);
91static int close_file(
void);
92static Int putout(CELL);
93static Int putcellptr(CELL *);
94static CELL get_cell(
void);
95static CELL *get_cellptr(
void);
96static int put_info(
int,
int CACHE_TYPE);
97static int save_regs(
int CACHE_TYPE);
98static int save_code_info(
void);
99static int save_heap(
void);
100static int save_stacks(
int CACHE_TYPE);
101static int save_crc(
void);
102static Int do_save(
int CACHE_TYPE);
103static Int p_save2(CACHE_TYPE1);
104static Int p_save_program(CACHE_TYPE1);
105static int check_header(CELL *, CELL *, CELL *, CELL *CACHE_TYPE);
106static int get_heap_info(CACHE_TYPE1);
107static int get_regs(
int CACHE_TYPE);
108static int get_insts(OPCODE[]);
109static int get_hash(
void);
110static int CopyCode(CACHE_TYPE1);
111static int CopyStacks(CACHE_TYPE1);
112static int get_coded(
int, OPCODE[] CACHE_TYPE);
113static void restore_codes(
void);
114static void RestoreDB(
DBEntry *CACHE_TYPE);
115static void RestoreDBTerm(
DBTerm *,
bool,
int CACHE_TYPE);
117static void rehash(CELL *,
int,
int CACHE_TYPE);
118static void CleanCode(
PredEntry *CACHE_TYPE);
119static void RestoreEntries(
PropEntry *,
int CACHE_TYPE);
120static void RestoreFreeSpace(CACHE_TYPE1);
121static void restore_heap(
void);
123static void ShowAtoms(
void);
126static int OpenRestore(
const char *, CELL *, CELL *, CELL *,
128static void CloseRestore(
void);
130static int check_opcodes(OPCODE[]);
132static void RestoreHeap(OPCODE[] CACHE_TYPE);
133static Int p_restore(CACHE_TYPE1);
134static void restore_heap_regs(CACHE_TYPE1);
135static void restore_regs(
int CACHE_TYPE);
137static void NewFileInfo(
long,
long);
152void LightBug(
char *);
154static void LightBug(s)
char *s;
159inline static int myread(FILE *fd,
char *buffer, Int len) {
163 nread = fread(buffer, 1, (
int)len, fd);
165 Yap_ThrowError(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,ARG1,
166 "bad read on saved state: %s", strerror(errno));
174inline static Int mywrite(FILE *fd,
char *buff, Int len) {
178 nwritten = fwrite(buff, 1, (
size_t)len, fd);
179 if ((
long int)nwritten < 0) {
180 Yap_ThrowError(SYSTEM_ERROR_OPERATING_SYSTEM,ARG1,
181 "bad write on saved state: %s",strerror(errno));
193typedef CELL *CELLPOINTER;
195static FILE *splfild = NULL;
202#define errout GLOBAL_stderr
207static Int OldHeapUsed;
209static CELL which_save;
212static FILE *open_file(
const char *my_file,
int flag) {
217 if (flag & O_RDONLY) {
220 if (flag & O_CREAT) {
223 if (flag & O_WRONLY) {
226 if (flag & O_APPEND) {
230 if (flag & O_BINARY) {
235 splfild = fopen(my_file, flags);
237 fprintf(errout,
"Opened file %s\n", my_file);
242static int close_file(
void) {
245 if (fclose(splfild) < 0)
246 Yap_ThrowError(SYSTEM_ERROR_SAVED_STATE,ARG1,
247 "bad close on saved state: %s",strerror(errno));
253static Int putout(CELL l) {
return mywrite(splfild, (
char *)&l,
sizeof(CELL)); }
256static Int putcellptr(CELL *l) {
257 return mywrite(splfild, (
char *)&l,
sizeof(CELLPOINTER));
261static CELL get_cell(
void) {
263 myread(splfild, (
char *)&l, Unsigned(
sizeof(CELL)));
268static CELL get_header_cell(
void) {
272 while (count <
sizeof(CELL)) {
273 if ((n = fread(&l, 1,
sizeof(CELL) - count, splfild)) < 0) {
274 Yap_ThrowError(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,ARG1,
275 "failed to read saved state header");
284static CELL *get_cellptr(
void) {
287 if (myread(splfild, (
char *)&l, Unsigned(
sizeof(CELLPOINTER))) < 0)
296static int put_info(
int info,
int mode USES_REGS) {
300 "#!/bin/sh\nexec_dir=${YAPBINDIR:-%s}\nexec $exec_dir/yap $0 "
302 YAP_BINDIR, 1, YAP_FULL_VERSION);
303 if (mywrite(splfild, msg, strlen(msg) + 1))
305 if (putout(Unsigned(info)) < 0)
308 if (putout(mode) < 0)
312 if (putout(Unsigned(LOCAL_GlobalBase) - Unsigned(Yap_HeapBase)) < 0)
315 if (putout(Unsigned(LOCAL_LocalBase) - Unsigned(LOCAL_GlobalBase)) < 0)
318 if (putout(Unsigned(LOCAL_TrailTop) - Unsigned(LOCAL_TrailBase)) < 0)
321 if (putout(Unsigned(HeapTop) - Unsigned(Yap_HeapBase)) < 0)
324 if (putout(Unsigned(LCL0) - Unsigned(ASP)) < 0)
327 if (putout(Unsigned(HR) - Unsigned(LOCAL_GlobalBase)) < 0)
330 if (putout(Unsigned(TR) - Unsigned(LOCAL_TrailBase)) < 0)
335static int save_regs(
int mode USES_REGS) {
337 if (putout((CELL)compile_arrays) < 0)
339 if (mode == DO_EVERYTHING) {
340 if (putcellptr((CELL *)CP) < 0)
342 if (putcellptr(ENV) < 0)
344 if (putcellptr(ASP) < 0)
348 if (putcellptr(H0) < 0)
350 if (putcellptr(LCL0) < 0)
352 if (putcellptr(HR) < 0)
354 if (putcellptr(HB) < 0)
356 if (putcellptr((CELL *)B) < 0)
358 if (putcellptr((CELL *)TR) < 0)
360 if (putcellptr(YENV) < 0)
362 if (putcellptr(S) < 0)
364 if (putcellptr((CELL *)P) < 0)
366 if (putout(CreepFlag) < 0)
368 if (putout(EventFlag) < 0)
370#if defined(YAPOR_SBA) || defined(TABLING)
371 if (putcellptr(H_FZ) < 0)
373 if (putcellptr((CELL *)B_FZ) < 0)
375 if (putcellptr((CELL *)TR_FZ) < 0)
379 if (putout(CurrentModule) < 0)
381 if (mode == DO_EVERYTHING) {
383 if (putout(LOCAL_WokenGoals) < 0)
387 if (putout(DEPTH) < 0)
390 if (putout(LOCAL_GcGeneration) < 0)
392 if (putout(LOCAL_GcPhase) < 0)
394 if (putout(LOCAL_GcCurrentPhase) < 0)
398 if (putcellptr(CellPtr(XREGS)) < 0)
400 if (putout(which_save) < 0)
404 if (putcellptr(CellPtr(Yap_HeapBase)) < 0)
406 if (putcellptr(CellPtr(HeapTop)) < 0)
409 if (putout(Unsigned(HeapUsed)) < 0)
412 if (putcellptr(CellPtr(FreeBlocks)) < 0)
414 if (putcellptr(CellPtr(AuxBase)) < 0)
416 if (putcellptr(AuxSp) < 0)
418 if (putcellptr(CellPtr(AuxTop)) < 0)
420 if (putcellptr(CellPtr(LOCAL_ScratchPad.ptr)) < 0)
422 if (putout(LOCAL_ScratchPad.sz) < 0)
424 if (putout(LOCAL_ScratchPad.msz) < 0)
426 if (mode == DO_EVERYTHING) {
428 if (putout(ARG1) < 0)
430 if (which_save == 2) {
431 if (putout(ARG2) < 0)
434 if (putcellptr(CellPtr(LOCAL_TrailBase)) < 0)
440static int save_code_info(
void) {
446 OPCODE my_ops[_std_top + 1];
447 for (i = _Ystop; i <= _std_top; ++i)
448 my_ops[i] = Yap_opcode(i);
449 if (mywrite(splfild, (
char *)my_ops,
sizeof(OPCODE) * (_std_top + 1)) < 0)
453 if (mywrite(splfild, (
char *)Yap_chtype,
454 NUMBER_OF_CHARS *
sizeof(char_kind_t)) < 0)
459static int save_heap(
void) {
460#ifdef USE_SYSTEM_MALLOC
465 Yap_ResetConsultStack();
466 j = Unsigned(HeapTop) - Unsigned(Yap_HeapBase);
468 if (mywrite(splfild, (
char *)Yap_HeapBase, j) < 0)
473static int save_stacks(
int mode USES_REGS) {
480 j = Unsigned(LCL0) - Unsigned(ASP);
481 if (mywrite(splfild, (
char *)ASP, j) < 0)
484 j = Unsigned(HR) - Unsigned(LOCAL_GlobalBase);
485 if (mywrite(splfild, (
char *)LOCAL_GlobalBase, j) < 0)
488 j = Unsigned(TR) - Unsigned(LOCAL_TrailBase);
489 if (mywrite(splfild, (
char *)LOCAL_TrailBase, j) < 0)
493 tr_fr_ptr tr_ptr = TR;
494 while (tr_ptr != (tr_fr_ptr)LOCAL_TrailBase) {
495 CELL val = TrailTerm(tr_ptr - 1);
496 if (IsVarTerm(val)) {
497 CELL *d1 = VarOfTerm(val);
498 if (d1 < (CELL *)HeapTop) {
502 }
else if (IsPairTerm(val)) {
503 CELL *d1 = RepPair(val);
504 if (d1 < (CELL *)HeapTop) {
512 if (putcellptr(NULL) < 0)
519static int save_crc(
void) {
521 return mywrite(splfild, end_msg, 256);
524static Int do_save(
int mode USES_REGS) {
525 Term t1 = Deref(ARG1);
528 Yap_ThrowError(SYSTEM_ERROR_INTERNAL,
530 "restore/1: address space has holes of size %ld, cannot save",
531 (
long int)Yap_HoleSize);
534 if (!Yap_GetName((buf=malloc(MAX_PATH+1)), MAX_PATH, t1)) {
535 Yap_Error(TYPE_ERROR_LIST, t1,
"save/1");
539 if ((splfild = open_file(buf, O_WRONLY | O_CREAT)) < 0) {
540 Yap_ThrowError(SYSTEM_ERROR_OPERATING_SYSTEM,
541 MkAtomTerm(Yap_LookupAtom(buf)),
542 "restore/1, open(%s)", strerror(errno));
545 if (put_info(FullSaved, mode PASS_REGS) < 0)
547 if (save_regs(mode PASS_REGS) < 0)
549 if (save_code_info() < 0)
553 if (save_stacks(mode PASS_REGS) < 0)
562static Int p_save2(USES_REGS1) {
564 yhandle_t CurSlot = Yap_StartSlots();
568 if (GLOBAL_number_workers != 1) {
569 Yap_Error(SYSTEM_ERROR, TermNil,
570 "cannot perform save: more than a worker/thread running");
575 if (GLOBAL_NOfThreads != 1) {
576 Yap_Error(SYSTEM_ERROR, TermNil,
577 "cannot perform save: more than a worker/thread running");
582 if (IsNonVarTerm(t = Deref(ARG2)))
584 if (!Yap_unify(ARG2, MkIntTerm(1)))
587 CurSlot = Yap_StartSlots();
588 res = do_save(DO_EVERYTHING PASS_REGS);
589 Yap_CloseSlots(CurSlot);
594static Int p_save_program(USES_REGS1) {
596 return do_save(DO_ONLY_CODE PASS_REGS);
602static int check_header(CELL *info, CELL *ATrail, CELL *AStack,
603 CELL *AHeap USES_REGS) {
606 CELL hp_size, gb_size, lc_size, tr_size, mode;
613 if ((n = fread(pp, 1, 1, splfild)) <= 0) {
614 Yap_ThrowError(PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,
616 "failed to scan first line from saved state");
619 }
while (pp[0] != 1);
621 sprintf(msg,
"YAP-%s", YAP_FULL_VERSION);
623 int count = 0, n, to_read = Unsigned(strlen(msg) + 1);
624 while (count < to_read) {
625 if ((n = fread(pp, 1, to_read - count, splfild)) <= 0) {
628 PERMISSION_ERROR_INPUT_PAST_END_OF_STREAM,
629 "failed to scan version info from saved state");
635 if (strcmp(pp, msg) != 0) {
636 strncpy(LOCAL_ErrorMessage,
"saved state %s failed to match version ID",PATH_MAX);
641 *info = get_header_cell();
642 if (LOCAL_ErrorMessage)
645 mode = get_header_cell();
646 if (LOCAL_ErrorMessage)
648 if (mode != DO_EVERYTHING && mode != DO_ONLY_CODE) {
652 *AHeap = get_header_cell();
653 if (LOCAL_ErrorMessage) {
656 *AStack = get_header_cell();
657 if (LOCAL_ErrorMessage) {
660 *ATrail = get_header_cell();
661 if (LOCAL_ErrorMessage) {
666 hp_size = get_cell();
667 if (LOCAL_ErrorMessage)
669 while (Yap_HeapBase != NULL &&
670 hp_size > Unsigned(HeapLim) - Unsigned(Yap_HeapBase)) {
671 if (!Yap_growheap(FALSE, hp_size, NULL)) {
675 if (mode == DO_EVERYTHING) {
676 lc_size = get_cell();
677 if (LOCAL_ErrorMessage)
679 gb_size = get_cell();
680 if (LOCAL_ErrorMessage)
682 if (Yap_HeapBase != NULL &&
684 Unsigned(LOCAL_LocalBase) - Unsigned(LOCAL_GlobalBase)) {
685 if (LOCAL_ErrorMessage != NULL)
686 LOCAL_ErrorMessage =
"could not allocate enough stack space";
689 if (Yap_HeapBase != NULL &&
690 (tr_size = get_cell()) >
691 Unsigned(LOCAL_TrailTop) - Unsigned(LOCAL_TrailBase)) {
692 if (LOCAL_ErrorMessage != NULL)
693 LOCAL_ErrorMessage =
"could not allocate enough trail space";
699 if (LOCAL_ErrorMessage)
702 if (LOCAL_ErrorMessage)
705 if (LOCAL_ErrorMessage)
712static int get_heap_info(USES_REGS1) {
713 LOCAL_OldHeapBase = (ADDR)get_cellptr();
714 if (LOCAL_ErrorMessage)
716 LOCAL_OldHeapTop = (ADDR)get_cellptr();
718 if (LOCAL_ErrorMessage)
720 OldHeapUsed = (Int)get_cell();
721 if (LOCAL_ErrorMessage)
724 if (LOCAL_ErrorMessage)
726 AuxBase = (ADDR)get_cellptr();
727 if (LOCAL_ErrorMessage)
729 AuxSp = get_cellptr();
730 if (LOCAL_ErrorMessage)
732 AuxTop = (ADDR)get_cellptr();
733 if (LOCAL_ErrorMessage)
735 LOCAL_ScratchPad.ptr = (ADDR)get_cellptr();
736 if (LOCAL_ErrorMessage)
738 LOCAL_ScratchPad.sz = get_cell();
739 if (LOCAL_ErrorMessage)
741 LOCAL_ScratchPad.msz = get_cell();
742 if (LOCAL_ErrorMessage)
744 LOCAL_HDiff = Unsigned(Yap_HeapBase) - Unsigned(LOCAL_OldHeapBase);
751static int get_regs(
int flag USES_REGS) {
752 CELL *NewGlobalBase = (CELL *)LOCAL_GlobalBase;
753 CELL *NewLCL0 = LCL0;
757 compile_arrays = (int)get_cell();
758 if (LOCAL_ErrorMessage)
760 if (flag == DO_EVERYTHING) {
761 CP = (
yamop *)get_cellptr();
762 if (LOCAL_ErrorMessage)
765 if (LOCAL_ErrorMessage)
768 if (LOCAL_ErrorMessage)
772 if (LOCAL_ErrorMessage)
774 LCL0 = get_cellptr();
775 if (LOCAL_ErrorMessage)
778 if (LOCAL_ErrorMessage)
781 if (LOCAL_ErrorMessage)
784 if (LOCAL_ErrorMessage)
786 TR = (tr_fr_ptr)get_cellptr();
787 if (LOCAL_ErrorMessage)
789 YENV = get_cellptr();
790 if (LOCAL_ErrorMessage)
793 if (LOCAL_ErrorMessage)
795 P = (
yamop *)get_cellptr();
796 if (LOCAL_ErrorMessage)
798 CreepFlag = get_cell();
799 if (LOCAL_ErrorMessage)
801 EventFlag = get_cell();
802 if (LOCAL_ErrorMessage)
804#if defined(YAPOR_SBA) || defined(TABLING)
805 H_FZ = get_cellptr();
806 if (LOCAL_ErrorMessage)
809 if (LOCAL_ErrorMessage)
811 TR_FZ = (tr_fr_ptr)get_cellptr();
812 if (LOCAL_ErrorMessage)
816 CurrentModule = get_cell();
817 if (LOCAL_ErrorMessage)
819 if (flag == DO_EVERYTHING) {
821 LOCAL_WokenGoals = get_cell();
822 if (LOCAL_ErrorMessage)
827 if (LOCAL_ErrorMessage)
830 LOCAL_GcGeneration = get_cell();
831 if (LOCAL_ErrorMessage)
833 LOCAL_GcPhase = get_cell();
834 if (LOCAL_ErrorMessage)
836 LOCAL_GcCurrentPhase = get_cell();
837 if (LOCAL_ErrorMessage)
841 OldXREGS = get_cellptr();
842 if (LOCAL_ErrorMessage)
844 which_save = get_cell();
845 if (LOCAL_ErrorMessage)
847 LOCAL_XDiff = (CELL)XREGS - (CELL)OldXREGS;
848 if (LOCAL_ErrorMessage)
850 if (get_heap_info(PASS_REGS1) < 0)
852 if (flag == DO_EVERYTHING) {
854 if (LOCAL_ErrorMessage)
856 if (which_save == 2) {
858 if (LOCAL_ErrorMessage)
862 LOCAL_OldTrailBase = (ADDR)get_cellptr();
863 if (LOCAL_ErrorMessage)
867 LOCAL_OldLCL0 = LCL0;
868 LOCAL_OldGlobalBase = (CELL *)LOCAL_GlobalBase;
871 LOCAL_GDiff = Unsigned(NewGlobalBase) - Unsigned(LOCAL_GlobalBase);
873 LOCAL_LDiff = Unsigned(NewLCL0) - Unsigned(LCL0);
874 LOCAL_TrDiff = LOCAL_LDiff;
875 LOCAL_GlobalBase = (ADDR)NewGlobalBase;
882static int get_insts(OPCODE old_ops[]) {
883 return myread(splfild, (
char *)old_ops,
sizeof(OPCODE) * (_std_top + 1));
887static int get_hash(
void) {
888 return myread(splfild, (
char *)Yap_chtype,
889 NUMBER_OF_CHARS *
sizeof(char_kind_t));
893static int CopyCode(USES_REGS1) {
894 if (myread(splfild, (
char *)Yap_HeapBase,
895 (Unsigned(LOCAL_OldHeapTop) - Unsigned(LOCAL_OldHeapBase))) < 0) {
903static int CopyStacks(USES_REGS1) {
907 j = Unsigned(LOCAL_OldLCL0) - Unsigned(ASP);
908 NewASP = (
char *)(Unsigned(ASP) + (Unsigned(LCL0) - Unsigned(LOCAL_OldLCL0)));
909 if (myread(splfild, (
char *)NewASP, j) < 0)
911 j = Unsigned(HR) - Unsigned(LOCAL_OldGlobalBase);
912 if (myread(splfild, (
char *)LOCAL_GlobalBase, j) < 0)
914 j = Unsigned(TR) - Unsigned(LOCAL_OldTrailBase);
915 if (myread(splfild, LOCAL_TrailBase, j))
922static int CopyTrailEntries(USES_REGS1) {
923 CELL entry, *Entries;
925 Entries = (CELL *)LOCAL_TrailBase;
927 *Entries++ = entry = get_cell();
928 if (LOCAL_ErrorMessage)
930 }
while ((CODEADDR)entry != NULL);
935static int get_coded(
int flag, OPCODE old_ops[] USES_REGS) {
936 char my_end_msg[256];
938 if (get_regs(flag PASS_REGS) < 0)
940 if (get_insts(old_ops) < 0)
944 if (CopyCode(PASS_REGS1) < 0)
948 if (CopyStacks(PASS_REGS1) < 0)
952 if (CopyTrailEntries(PASS_REGS1) < 0)
957 if (myread(splfild, my_end_msg, 256) < 0)
959 if (strcmp(end_msg, my_end_msg) != 0) {
960 LOCAL_ErrorMessage =
"bad trailing CRC in saved state";
967static void restore_heap_regs(USES_REGS1) {
969 HeapTop = AddrAdjust(HeapTop);
973 HeapLim = LOCAL_GlobalBase;
977static void restore_regs(
int flag USES_REGS) {
978 restore_heap_regs(PASS_REGS1);
980 CurrentModule = AtomTermAdjust(CurrentModule);
983 if (flag == DO_EVERYTHING) {
984 CP = PtoOpAdjust(CP);
985 ENV = PtoLocAdjust(ENV);
986 ASP = PtoLocAdjust(ASP);
987 HR = PtoGloAdjust(HR);
989 TR = PtoTRAdjust(TR);
991 HB = PtoLocAdjust(HB);
992 YENV = PtoLocAdjust(YENV);
994 LOCAL_WokenGoals = AbsAppl(PtoGloAdjust(RepAppl(LOCAL_WokenGoals)));
998static void recompute_mask(
DBRef dbr) {
999 if (dbr->Flags & DBNoVars) {
1000 dbr->Mask = Yap_EvalMasks((Term)dbr->DBT.Entry, &(dbr->Key));
1001 }
else if (dbr->Flags & DBComplex) {
1006 CELL *x = (CELL *)HeapTop, *tp;
1007 unsigned int Arity, i;
1009 char *tbase = CharP(dbr->DBT.Contents - 1);
1011 if (IsPairTerm(dbr->DBT.Entry)) {
1015 tp = (CELL *)(tbase + (CELL)RepPair(dbr->DBT.Entry));
1019 tp = (CELL *)(tbase + (CELL)RepAppl(dbr->DBT.Entry));
1022 Arity = ArityOfFunctor(f);
1027 for (i = 0; i < Arity; i++) {
1028 register Term tw = *tp++;
1029 if (IsVarTerm(tw)) {
1031 }
else if (IsApplTerm(tw)) {
1034 CELL offset = (CELL)RepAppl(tw);
1035 if (offset > dbr->DBT.NOfCells *
sizeof(CELL))
1038 *x = AbsAppl((CELL *)(tbase + offset));
1039 }
else if (IsAtomicTerm(tw)) {
1041 }
else if (IsPairTerm(tw)) {
1046 dbr->Mask = Yap_EvalMasks(out, &(dbr->Key));
1058static void rehash(CELL *oldcode,
int NOfE,
int KindOfEntries USES_REGS) {
1059 register CELL *savep, *basep;
1060 CELL *oldp = oldcode;
1061 int TableSize = NOfE - 1, NOfEntries;
1064 CELL WorkTerm, failplace = 0;
1065 CELL *Base = oldcode;
1067 if (LOCAL_HDiff == 0)
1070 if (HR + (NOfE * 2) > ASP) {
1072 if (basep + (NOfE * 2) > (CELL *)LOCAL_TrailTop) {
1073 if (!Yap_growtrail((ADDR)(basep + (NOfE * 2)) - LOCAL_TrailTop, TRUE)) {
1074 Yap_Error(RESOURCE_ERROR_TRAIL, TermNil,
1075 "not enough space to restore hash tables for indexing");
1080 for (i = 0; i < NOfE; ++i) {
1082 failplace = oldp[1];
1089 for (i = 0; i < NOfE; ++i) {
1094 oldp[1] = failplace;
1099 NOfEntries = (savep - basep) / 2;
1101 for (i = 0; i < NOfEntries; ++i) {
1105 WorkTerm = savep[i * 2];
1106 hash = (Unsigned(WorkTerm) >> HASH_SHIFT) & TableSize;
1107 hentry = Base + hash * 2;
1108 d = TableSize & (Unsigned(WorkTerm) | 1);
1115 hash = (hash + d) & TableSize;
1116 hentry = Base + hash * 2;
1118 hentry[0] = WorkTerm;
1119 hentry[1] = savep[i * 2 + 1];
1123static void RestoreFlags(UInt NFlags) {}
1128static void RestoreIOStructures(
void) { Yap_InitStdStreams(); }
1130static void RestoreFreeSpace(USES_REGS1) {
1132 Yap_av = (
struct malloc_state *)AddrAdjust((ADDR)Yap_av);
1133 Yap_RestoreDLMalloc();
1134 if (AuxSp != NULL) {
1135 if (AuxBase < LOCAL_OldHeapBase || AuxBase > LOCAL_OldHeapTop) {
1140 AuxSp = PtoHeapCellAdjust(AuxSp);
1141 AuxBase = AddrAdjust(AuxBase);
1142 AuxTop = AddrAdjust(AuxTop);
1143 LOCAL_ScratchPad.ptr = AddrAdjust(LOCAL_ScratchPad.ptr);
1150 if (FreeBlocks != NULL)
1151 FreeBlocks = BlockAdjust(FreeBlocks);
1154 AuxSp = CellPtoHeapAdjust(AuxSp);
1156 AuxTop = AddrAdjust(AuxTop);
1157 while (bpt != NULL) {
1158 if (bpt->b_next != NULL) {
1159 bsz = bpt->b_next = BlockAdjust(bpt->b_next);
1160 while (bsz != NULL) {
1161 if (bsz->b_next_size != NULL)
1162 bsz->b_next_size = BlockAdjust(bsz->b_next_size);
1163 if (bsz->b_next != NULL)
1164 bsz->b_next = BlockAdjust(bsz->b_next);
1168 if (bpt->b_next_size != NULL)
1169 bpt->b_next_size = BlockAdjust(bpt->b_next_size);
1170 bpt = bpt->b_next_size;
1176static void RestoreAtomList(
Atom atm USES_REGS) {
1180 if (EndOfPAEntr(at))
1183 RestoreAtom(at PASS_REGS);
1184 at = RepAtom(at->NextOfAE);
1185 }
while (!EndOfPAEntr(at));
1188static void RestoreHashPreds(USES_REGS1) {
1189 UInt size = PredHashTableSize;
1190 bool malloced = FALSE;
1198 Yap_Error(SYSTEM_ERROR_FATAL, TermNil,
1199 "Could not allocate space for pred table");
1204 for (i = 0; i < size; i++) {
1207 for (i = 0; i < PredHashTableSize; i++) {
1211 p = PredEntryAdjust(p);
1217 p->NextOfPE = PropAdjust(p->NextOfPE);
1218 nextp = p->NextOfPE;
1219 CleanCode(p PASS_REGS);
1220 hsh = PRED_HASH(p->FunctorOfPred, p->ModuleOfPred, size);
1221 p->NextOfPE = AbsPredProp(np[hsh]);
1223 p = RepPredProp(nextp);
1226 for (i = 0; i < size; i++) {
1227 PredHash[i] = np[i];
1232 Yap_FreeAtomSpace((ADDR)np);
1238static void restore_heap(
void) {
1240 RestoreIOStructures();
1243#ifdef DEBUG_RESTORE3
1244static void ShowEntries(pp)
PropEntry *pp;
1246 while (!EndOfPAEntr(pp)) {
1247 fprintf(GLOBAL_stderr,
"Estou a ver a prop %x em %x\n", pp->KindOfPE, pp);
1248 pp = RepProp(pp->NextOfPE);
1252static void ShowAtoms() {
1255 for (i = 0; i < AtomHashTableSize; ++i) {
1256 if (HashPtr->Entry != NIL) {
1258 at = RepAtom(HashPtr->Entry);
1260 fprintf(GLOBAL_stderr,
"Passei ao %s em %x\n", at->StrOfAE, at);
1261 ShowEntries(RepProp(at->PropsOfAE));
1262 }
while (!EndOfPAEntr(at = RepAtom(at->NextOfAE)));
1266 HashPtr = WideHashChain;
1267 for (i = 0; i < WideAtomHashTableSize; ++i) {
1268 if (HashPtr->Entry != NIL) {
1270 at = RepAtom(HashPtr->Entry);
1272 fprintf(GLOBAL_stderr,
"Passei ao %s em %x\n", at->StrOfAE, at);
1273 ShowEntries(RepProp(at->PropsOfAE));
1274 }
while (!EndOfPAEntr(at = RepAtom(at->NextOfAE)));
1284static int commit_to_saved_state(
const char *s, CELL *Astate, CELL *ATrail,
1285 CELL *AStack, CELL *AHeap) {
1288 char tmp[MAX_PATH+1];
1290 if ((mode = check_header(Astate, ATrail, AStack, AHeap PASS_REGS)) ==
1292 return (FAIL_RESTORE);
1293 LOCAL_PrologMode = BootMode;
1295 if (falseGlobalPrologFlag(HALT_AFTER_CONSULT_FLAG) && !silentMode()) {
1297 fprintf(stderr,
"%% Restoring file %s\n", tmp);
1301#ifdef DEBUG_RESTORE4
1305 errout = GLOBAL_stderr;
1310static int try_open(
const char *inpf, CELL *Astate, CELL *ATrail, CELL *AStack,
1311 CELL *AHeap, FILE **streamp) {
1315 if ((*streamp = fopen(inpf,
"rb"))) {
1316 return DO_ONLY_CODE;
1318 return FAIL_RESTORE;
1320 if ((splfild = open_file(inpf, O_RDONLY)) < 0) {
1321 return FAIL_RESTORE;
1323 if ((mode = commit_to_saved_state(inpf, Astate, ATrail, AStack, AHeap)) !=
1326 LOCAL_ErrorMessage = NULL;
1332static int OpenRestore(
const char *fname, CELL *Astate,
1333 CELL *ATrail, CELL *AStack, CELL *AHeap,
1338 if (fname && fname[0] && (mode = try_open(fname, Astate, ATrail, AStack, AHeap,
1339 streamp)) != FAIL_RESTORE) {
1340 setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG,
1341 MkAtomTerm(Yap_LookupAtom(fname)));
1346 if (LOCAL_ErrorMessage == NULL) {
1347 Yap_ThrowError(PERMISSION_ERROR_OPEN_SOURCE_SINK,
1349 "incorrect saved state ");
1351 Yap_ThrowError(PERMISSION_ERROR_OPEN_SOURCE_SINK,
1352 ARG1,
"could not open saved state %s", fname);
1354 return FAIL_RESTORE;
1357FILE *Yap_OpenRestore(
const char *inpf) {
1358 FILE *stream = NULL;
1361 inpf =
"startup.yss";
1362 OpenRestore(inpf, NULL, NULL, NULL, NULL, &stream);
1366static void CloseRestore(
void) {
1368#ifdef DEBUG_RESTORE3
1372 LOCAL_PrologMode = UserMode;
1376static int check_opcodes(OPCODE old_ops[]) {
1377#if USE_THREADED_CODE
1378 bool have_shifted = FALSE;
1379 op_numbers op = _Ystop;
1380 for (op = _Ystop; op < _std_top; op++) {
1381 if (Yap_opcode(op) != old_ops[op]) {
1382 have_shifted = TRUE;
1386 return have_shifted;
1394static void RestoreHeap(OPCODE old_ops[] USES_REGS) {
1395 bool heap_moved = (LOCAL_OldHeapBase != Yap_HeapBase || LOCAL_XDiff),
1397 Term mod = CurrentModule;
1399 CurrentModule = PROLOG_MODULE;
1403 opcodes_moved = TRUE;
1405 opcodes_moved = check_opcodes(old_ops);
1409 opcodes_moved = TRUE;
1410 RestoreFreeSpace(PASS_REGS1);
1412 if (heap_moved || opcodes_moved) {
1417 if (opcodes_moved) {
1419 Yap_InitBackCPreds();
1421 if (!(Yap_ReInitConstExps() && Yap_ReInitUnaryExps() &&
1422 Yap_ReInitBinaryExps())) {
1423 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
1424 "arithmetic operator not in saved state");
1426#ifdef DEBUG_RESTORE1
1427 fprintf(errout,
"phase 1 done\n");
1429 CurrentModule = mod;
1436int Yap_SavedInfo(
const char *FileName, CELL *ATrail,
1437 CELL *AStack, CELL *AHeap) {
1438 return DO_ONLY_CODE;
1440 CELL MyTrail, MyStack, MyHeap, MyState;
1443 mode = OpenRestore(FileName, &MyState, &MyTrail, &MyStack, &MyHeap,
1445 if (mode == FAIL_RESTORE) {
1450 *AHeap = MyHeap / 1024;
1451 if (mode != DO_ONLY_CODE && *AStack)
1452 *AStack = MyStack / 1024;
1453 if (mode != DO_ONLY_CODE && *ATrail)
1454 *ATrail = MyTrail / 1024;
1458static void UnmarkTrEntries(USES_REGS1) {
1459 CELL entry, *Entries;
1465 Entries = (CELL *)LOCAL_TrailBase;
1466 while ((entry = *Entries++) != (CELL)NULL) {
1467 if (!IsVarTerm(entry)) {
1468 if (IsPairTerm(entry)) {
1469 CELL *ent = CellPtoHeapAdjust(RepPair(entry));
1470 register CELL flags;
1473 ResetFlag(InUseMask, flags);
1475 if (FlagOn((DirtyMask | ErasedMask), flags)) {
1476 if (FlagOn(DBClMask, flags)) {
1477 Yap_ErDBE(DBStructFlagsToDBStruct(ent));
1479 if (flags & LogUpdMask) {
1480 if (flags & IndexMask) {
1481 if (FlagOn(ErasedMask, flags))
1482 Yap_ErLogUpdIndex(ClauseFlagsToLogUpdIndex(ent));
1484 Yap_CleanUpIndex(ClauseFlagsToLogUpdIndex(ent));
1486 Yap_ErLogUpdCl(ClauseFlagsToLogUpdClause(ent));
1489 Yap_ErCl(ClauseFlagsToDynamicClause(ent));
1493#ifdef MULTI_ASSIGNMENT_VARIABLES
1503int in_limbo = FALSE;
1506static void FreeRecords(
void) {
1513 Yap_ReleaseTermFromDB(ptr->dbrecord);
1514 ptr = ptr->next_rec;
1515 Yap_FreeCodeSpace((
void *)optr);
1523static int Restore(
char *s_dir USES_REGS) {
1526 OPCODE old_ops[_std_top + 1];
1527 CELL MyTrail, MyStack, MyHeap, MyState;
1529 if ((restore_mode = OpenRestore(s_dir, &MyState, &MyTrail, &MyStack,
1530 &MyHeap, NULL)) == FAIL_RESTORE)
1532 Yap_ShutdownLoadForeign();
1534 if (get_coded(restore_mode, old_ops PASS_REGS) < 0)
1535 return FAIL_RESTORE;
1536 restore_regs(restore_mode PASS_REGS);
1539 RestoreHeap(old_ops PASS_REGS);
1540 switch (restore_mode) {
1542 if (LOCAL_OldHeapBase != Yap_HeapBase || LOCAL_OldLCL0 != LCL0 ||
1543 LOCAL_OldGlobalBase != (CELL *)LOCAL_GlobalBase ||
1544 LOCAL_OldTrailBase != LOCAL_TrailBase) {
1545 Yap_AdjustStacksAndTrail();
1546 if (which_save == 2) {
1552#ifdef DEBUG_RESTORE2
1553 fprintf(errout,
"phase 2 done\n");
1558 UnmarkTrEntries(PASS_REGS1);
1559 Yap_InitYaamRegs(0,
true);
1563 Yap_ReOpenLoadForeign();
1569#if USE_DL_MALLOC || USE_SYSTEM_MALLOC
1571 Yap_InitPreAllocCodeSpace(0);
1575 if (which_save == 2) {
1576 Yap_unify(ARG2, MkIntTerm(0));
1578 return restore_mode;
1581int Yap_SavedStateRestore(
char *s) {
1583 return Restore(s PASS_REGS);
1586static Int p_restore(USES_REGS1) {
1588 char s[MAX_PATH + 1];
1590 Term t1 = Deref(ARG1);
1592 if (GLOBAL_number_workers != 1) {
1593 Yap_Error(SYSTEM_ERROR, TermNil,
1594 "cannot perform save: more than a worker/thread running");
1599 if (GLOBAL_NOfThreads != 1) {
1600 Yap_Error(SYSTEM_ERROR, TermNil,
1601 "cannot perform save: more than a worker/thread running");
1605 if (!Yap_GetName(s, MAX_PATH, t1)) {
1606 Yap_Error(TYPE_ERROR_LIST, t1,
"restore/1");
1609 if ((mode = Restore(s PASS_REGS)) == DO_ONLY_CODE) {
1612 return (mode != FAIL_RESTORE);
1615void Yap_InitSavePreds(
void) {
1616 Yap_InitCPred(
"$save", 2, p_save2, SyncPredFlag);
1617 Yap_InitCPred(
"$save_program", 1, p_save_program, SyncPredFlag);
1618 Yap_InitCPred(
"$restore", 1, p_restore, SyncPredFlag);
load_foreign_files/3 has works for the following configurations:
const char * Yap_AbsoluteFile(const char *spec, bool ok)
generate absolute path, if ok first expand SICStus Prolog style
CELL YAP_SEG_SIZE
definitions required by saver/restorer and memory manager