forked from dolphinsmalltalk/DolphinVM
-
Notifications
You must be signed in to change notification settings - Fork 0
/
InterprtInit.cpp
121 lines (98 loc) · 3.97 KB
/
InterprtInit.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
120
121
/*
============
InterprtInit.cpp
============
Interpreter initialization
*/
#include "Ist.h"
#ifndef _DEBUG
#pragma optimize("s", on)
#pragma auto_inline(off)
#endif
#include "Interprt.h"
#include "ObjMem.h"
#include "STProcess.h"
#include "STArray.h"
#include "STBlockClosure.h"
///////////////////////////////////
#pragma code_seg(INIT_SEG)
void Interpreter::initializeVMReferences()
{
//CreateVMReferences();
ASSERT(IS_ERROR(EXCEPTION_ACCESS_VIOLATION));
ObjectMemory::ProtectConstSpace(PAGE_READWRITE);
// We must obviously re-establish pointers every time
#if defined(_DEBUG) || defined(_AFX)
if (_Pointers.VMReferences == reinterpret_cast<ArrayOTE*>(Pointers.Nil))
{
ArrayOTE* newArray = Array::New(VMREFSINITIAL);
_Pointers.VMReferences = reinterpret_cast<ArrayOTE*>(newArray);
newArray->beSticky();
}
m_nMaxVMRefs = _Pointers.VMReferences->pointersSize();
m_pVMRefs = _Pointers.VMReferences->m_location->m_elements;
ASSERT(m_nMaxVMRefs >= VMREFSINITIAL);
// Now set up the free list
const int loopEnd = m_nMaxVMRefs;
for (int i=0;i<loopEnd;i++)
m_pVMRefs[i] = ObjectMemoryIntegerObjectOf(i+1);
m_nFreeVMRef = 0;
#else
ObjectMemory::storePointerWithValue((Oop&)_Pointers.VMReferences, _Pointers.Nil);
#endif
// Defensive - if this object is changed, it'll all go horribly wrong, so attempt a repair
if (ObjectMemory::fetchClassOf((Oop)_Pointers.MarkedBlock) != _Pointers.ClassBlockClosure)
{
PointersOTE* markedBlock = ObjectMemory::newPointerObject(_Pointers.ClassBlockClosure, BlockClosure::FixedSize);
_Pointers.MarkedBlock = reinterpret_cast<BlockOTE*>(markedBlock);
_Pointers.MarkedBlock->beImmutable();
}
BlockClosure* block = _Pointers.MarkedBlock->m_location;
block->m_outer = _Pointers.Nil;
block->m_method = reinterpret_cast<MethodOTE*>(_Pointers.Nil);
block->m_receiver = reinterpret_cast<Oop>(_Pointers.Nil);
*reinterpret_cast<Oop*>(&block->m_info) = ZeroPointer;
block->m_initialIP = ZeroPointer;
// Initialize the various VM circular queues
if (_Pointers.SignalQueue->isNil())
_Pointers.SignalQueue = Array::New(SIGNALQSIZE);
ASSERT(_Pointers.SignalQueue->m_oteClass == _Pointers.ClassArray);
m_qAsyncSignals.UseBuffer(_Pointers.SignalQueue, SIGNALQGROWTH, true);
if (_Pointers.InterruptQueue->isNil())
_Pointers.InterruptQueue = Array::New(INTERRUPTQSIZE);
ASSERT(_Pointers.InterruptQueue->m_oteClass == _Pointers.ClassArray);
m_qInterrupts.UseBuffer(_Pointers.InterruptQueue, INTERRUPTQGROWTH, false);
ArrayOTE* finalizeQueue = _Pointers.FinalizeQueue;
ASSERT(finalizeQueue->m_oteClass == Pointers.ClassArray);
m_qForFinalize.UseBuffer(finalizeQueue, FINALIZEQGROWTH, true);
ArrayOTE* bereavementQueue = _Pointers.BereavementQueue;
ASSERT(bereavementQueue->m_oteClass == Pointers.ClassArray);
m_qBereavements.UseBuffer(bereavementQueue, BEREAVEMENTQGROWTH, true);
ObjectMemory::InitializeMemoryManager();
m_pProcessor = _Pointers.Scheduler->m_location;
if (ObjectMemory::fetchClassOf(Oop(_Pointers.EmptyString)) != _Pointers.ClassString)
{
_Pointers.EmptyString = String::New("");
_Pointers.EmptyString->beImmutable();
}
ObjectMemory::ProtectConstSpace(PAGE_READONLY);
ObjectMemory::addVMRefs();
}
void Interpreter::sendStartup(LPCSTR szImagePath, DWORD dwArg)
{
// Boost the priority so runs to exclusion of other processes (except timing and weak
// collection repair)
actualActiveProcess()->SetPriority(8);
// Construct argument array
ArrayOTE* oteArgs = Array::NewUninitialized(2);
Array* args = oteArgs->m_location;
StringOTE* string = String::New(szImagePath);
args->m_elements[0] = reinterpret_cast<Oop>(string);
string->m_flags.m_count = 1;
args->m_elements[1] = Integer::NewUnsigned32(dwArg);
ObjectMemory::countUp(args->m_elements[1]);
// We no longer need to ref. count things we push on the stack, sendVMInterrupt will count
// down the argument after it has pushed it on the stack, possibly causing its addition to the Zct
oteArgs->m_flags.m_count = 1;
sendVMInterrupt(VMI_STARTED, reinterpret_cast<Oop>(oteArgs));
}