-
Notifications
You must be signed in to change notification settings - Fork 65
/
VMAbstractPrimitiveTest.class.st
171 lines (127 loc) · 5.29 KB
/
VMAbstractPrimitiveTest.class.st
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
Class {
#name : #VMAbstractPrimitiveTest,
#superclass : #VMSpurMemoryManagerTest,
#pools : [
'VMBasicConstants',
'VMBytecodeConstants',
'VMClassIndices',
'VMObjectIndices'
],
#category : #VMMakerTests
}
{ #category : #running }
VMAbstractPrimitiveTest >> createProcessFor: newMethod priority: aPriority [
| aProcess |
aProcess := self createSuspendedProcessFor: newMethod priority: aPriority.
interpreter preemptionYields: false.
interpreter putToSleep: aProcess yieldingIf: interpreter preemptionYields.
^ aProcess
]
{ #category : #running }
VMAbstractPrimitiveTest >> createSuspendedProcessFor: newMethod priority: aPriority [
| suspendedContext aProcess |
"Create a new process with given priority and put it to sleep"
suspendedContext := self
newSmallContextReceiver: memory nilObject
method: newMethod
arguments: #()
temporaries: #()
ip: self wordSize + 1.
aProcess := self newObjectWithSlots: 4.
memory storeInteger: PriorityIndex ofObject: aProcess withValue: aPriority.
memory storePointer: SuspendedContextIndex ofObject: aProcess withValue: suspendedContext.
^ aProcess
]
{ #category : #'as yet unclassified' }
VMAbstractPrimitiveTest >> newArrayWith: aCollection [
| array |
array := self newObjectWithSlots: aCollection size format: memory arrayFormat classIndex: memory arrayClassIndexPun.
aCollection withIndexDo: [ :item :index |
memory storePointer: index - 1 ofObject: array withValue: item
].
^ array
]
{ #category : #'as yet unclassified' }
VMAbstractPrimitiveTest >> newMethodWithBytecodes: aCollection [
^ methodBuilder
newMethod;
bytecodes: aCollection;
buildMethod
]
{ #category : #'helpers - frames' }
VMAbstractPrimitiveTest >> newSmallContextReceiver: anOop method: aMethodOop arguments: aCollectionOfArgumentsOop temporaries: aCollectionOfTemporariesOop ip: anIp [
| newCtx numArgs numTemps |
newCtx := memory
allocateSlots: SmallContextSlots
format: memory indexablePointersFormat
classIndex: ClassMethodContextCompactIndex.
numArgs := aCollectionOfArgumentsOop size.
numTemps := aCollectionOfTemporariesOop size.
memory storePointerUnchecked: SenderIndex
ofObject: newCtx
withValue: memory nilObject.
memory storePointerUnchecked: InstructionPointerIndex
ofObject: newCtx
withValue: (memory integerObjectOf: anIp).
memory storePointerUnchecked: StackPointerIndex
ofObject: newCtx
withValue: (memory integerObjectOf: numArgs + numTemps).
memory storePointerUnchecked: MethodIndex
ofObject: newCtx
withValue: aMethodOop.
memory storePointerUnchecked: ClosureIndex ofObject: newCtx withValue: memory nilObject.
memory storePointerUnchecked: ReceiverIndex
ofObject: newCtx
withValue: anOop.
1 to: numArgs do:
[:i|
memory storePointerUnchecked: ReceiverIndex + i
ofObject: newCtx
withValue: (aCollectionOfArgumentsOop at: i)].
1 to: numTemps do:
[:i|
memory storePointerUnchecked: ReceiverIndex + i + numArgs
ofObject: newCtx
withValue: (aCollectionOfTemporariesOop at: i)].
^ newCtx
]
{ #category : #running }
VMAbstractPrimitiveTest >> setUp [
"taken from VMSimpleStackBasedCogitBytecodeTest >> #setup"
| newMethod ctx page classFloat |
super setUp.
memory nilObject: (self newObjectWithSlots: 0).
memory trueObject: (self newObjectWithSlots: 0).
memory falseObject: (self newObjectWithSlots: 0).
"We don't access its contents, but we need it to be after nil, true and false"
memory hiddenRootsObject: (self newArrayWithSlots: 0).
interpreter := memory interpreter.
"stackMemoryStartAddress := initialAddress + self initialCodeSize.
stackMemoryEndAddress := stackMemoryStartAddress + stackSpaceSize."
self initializeOldSpaceForScavenger.
"Create the root context with a valid method"
"Let's create a method with enough size. It should have at least a literal (4 or 8 bytes depending the word size) and some bytecodes, so we can put the IP inside the method"
newMethod := self newMethodWithBytecodes: #[ 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 ].
"The context has 5 (in 32 bits) or 9 (in 64 bits) as initial IP, as method has at least one literal"
ctx := self newSmallContextReceiver: memory nilObject method: newMethod arguments: #() temporaries: #() ip: self wordSize + 1.
page := interpreter makeBaseFrameFor: ctx.
interpreter setStackPageAndLimit: page.
interpreter setStackPointersFromPage: page.
self createActiveProcess.
"The current instruction pointer is an absolute address pointing to the current bytecode inside the method"
interpreter instructionPointer: newMethod + memory baseHeaderSize + memory wordSize + 1.
interpreter method: newMethod.
memory flushNewSpace.
self createProcessFor: newMethod priority: 1.
self createProcessFor: newMethod priority: 1.
memory classExternalAddress: (self newClassInOldSpaceWithSlots: 0 instSpec: (memory byteFormatForNumBytes: 0) ).
memory classArray: (self newClassInOldSpaceWithSlots: 0 instSpec: memory arrayFormat ).
memory classByteArray: (self newClassInOldSpaceWithSlots: 0 instSpec: (memory byteFormatForNumBytes: 0) ).
classFloat := self newClassInOldSpaceWithSlots: 0 instSpec: memory firstLongFormat.
memory setHashBitsOf: classFloat to: ClassFloatCompactIndex.
memory
storePointer: ClassFloatCompactIndex
ofObject: memory classTableFirstPage
withValue: classFloat.
self createLargeIntegerClasses.
]