-
Notifications
You must be signed in to change notification settings - Fork 23
/
SnapshotPrim.cpp
119 lines (94 loc) · 3 KB
/
SnapshotPrim.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/******************************************************************************
File: SnapshotPrim.cpp
Description:
Implementation of the Interpreter class' snapshot/quit primitive methods
******************************************************************************/
#include "Ist.h"
#ifndef _DEBUG
#pragma optimize("s", on)
#pragma auto_inline(off)
#endif
#include "ObjMem.h"
#include "Interprt.h"
#include "InterprtPrim.inl"
#include "InterprtProc.inl"
// Smalltalk classes
#include "STString.h"
#include "Utf16StringBuf.h"
#pragma auto_inline(off)
#if defined(CANSAVEIMAGE)
Oop* __fastcall Interpreter::primitiveSnapshot(Oop* const sp, unsigned)
{
Oop arg = *(sp-3);
if (ObjectMemoryIsIntegerObject(arg))
return primitiveFailure(0);
OTE* oteArg = reinterpret_cast<OTE*>(arg);
const wchar_t* szFileName;
if (oteArg == Pointers.Nil)
{
szFileName = nullptr;
}
else if (!oteArg->isNullTerminated())
{
return primitiveFailure(0);
}
Utf16StringBuf buf;
StringEncoding encoding = String::GetEncoding(oteArg);
switch (encoding)
{
case StringEncoding::Ansi:
buf.FromBytes(Interpreter::m_ansiCodePage, reinterpret_cast<AnsiStringOTE*>(oteArg)->m_location->m_characters, oteArg->getSize());
szFileName = buf;
break;
case StringEncoding::Utf8:
buf.FromBytes(CP_UTF8, (LPCCH)reinterpret_cast<Utf8StringOTE*>(oteArg)->m_location->m_characters, oteArg->getSize());
szFileName = buf;
break;
case StringEncoding::Utf16:
szFileName = (const wchar_t*)reinterpret_cast<Utf16StringOTE*>(oteArg)->m_location->m_characters;
break;
default:
return primitiveFailure(0);
}
bool bBackup = reinterpret_cast<OTE*>(*(sp-2)) == Pointers.True;
SMALLINTEGER nCompressionLevel;
Oop oopCompressionLevel = *(sp-1);
nCompressionLevel = ObjectMemoryIsIntegerObject(oopCompressionLevel) ? ObjectMemoryIntegerValueOf(oopCompressionLevel) : 0;
SMALLUNSIGNED nMaxObjects = 0;
Oop oopMaxObjects = *sp;
if (ObjectMemoryIsIntegerObject(oopMaxObjects))
{
nMaxObjects = ObjectMemoryIntegerValueOf(oopMaxObjects);
}
// N.B. It is not necessary to clear down the memory pools as the free list is rebuild on every image
// load and the pool members, though not on the free list at present, are marked as free entries
// in the object table
// Store the active frame of the active process before saving so available on image reload
// We're not actually suspending the process now, but it appears like that to the snapshotted
// image on restarting
m_registers.PrepareToSuspendProcess();
#ifdef OAD
DWORD timeStart = timeGetTime();
#endif
int saveResult = ObjectMemory::SaveImageFile(szFileName, bBackup, nCompressionLevel, nMaxObjects);
#ifdef OAD
DWORD timeEnd = timeGetTime();
TRACESTREAM<< L"Time to save image: " << (timeEnd - timeStart)<< L" mS" << std::endl;
#endif
if (!saveResult)
{
// Success
return primitiveSuccess(4);
}
else
{
// Failure
return primitiveFailure(saveResult);
}
}
#elif defined(TO_GO)
Oop* __fastcall Interpreter::primitiveSnapshot(Oop* const, unsigned)
{
return NULL;
}
#endif