-
Notifications
You must be signed in to change notification settings - Fork 68
/
VMPinnedObjectTest.class.st
246 lines (204 loc) · 6.55 KB
/
VMPinnedObjectTest.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
Class {
#name : #VMPinnedObjectTest,
#superclass : #VMSpurInitializedOldSpaceTest,
#category : #'VMMakerTests-MemoryTests'
}
{ #category : #helper }
VMPinnedObjectTest >> lastAliveObject [
^ self keptObjectInVMVariable2
]
{ #category : #helper }
VMPinnedObjectTest >> lastPinnedObject [
^ self keptObjectInVMVariable1
]
{ #category : #helper }
VMPinnedObjectTest >> newAliveObject [
| newAliveObject |
newAliveObject := self newOldSpaceObjectWithSlots: 1.
memory storePointer: 0 ofObject: newAliveObject withValue: self keptObjectInVMVariable2.
self keepObjectInVMVariable2: newAliveObject.
^ newAliveObject
]
{ #category : #helper }
VMPinnedObjectTest >> newDeadObject [
^ self newOldSpaceObjectWithSlots: 1
]
{ #category : #helper }
VMPinnedObjectTest >> newKeptPinnedObject [
| newPinned |
newPinned := self newOldSpaceObjectWithSlots: 1.
memory pinObject: newPinned.
memory storePointer: 0 ofObject: newPinned withValue: self keptObjectInVMVariable1.
self keepObjectInVMVariable1: newPinned.
^ newPinned
]
{ #category : #testCompactor }
VMPinnedObjectTest >> testAllocatingObjectAfterAPinObjectShouldSlideAtStartOfOldSpace [
| aliveObject destination shouldBeFreed aliveHash |
"D = Dead
P = Pinned
A = Alive
F = Free
scenario :
before : D D P D A -
after : A F P -"
memory fullGC.
"should allocate two objects to fill two free chunks"
self keepObjectInVMVariable2: self newDeadObject.
self keepObjectInVMVariable3: self newDeadObject.
destination := self newDeadObject.
shouldBeFreed := self newDeadObject.
self newKeptPinnedObject.
self newDeadObject.
aliveObject := self newAliveObject.
aliveHash := memory hashBitsOf: aliveObject.
memory fullGC.
self assert: (memory hashBitsOf: destination) equals: aliveHash.
self assert: self lastAliveObject equals: destination.
self assert: (memory isFreeObject: shouldBeFreed)
]
{ #category : #testCompactor }
VMPinnedObjectTest >> testAllocatingObjectAfterAPinObjectShouldSlideBeforeLastPinnedObject [
| aliveObject destination |
"D = Dead
P = Pinned
A = Alive
F = Free
scenario :
before : D P D A -
after : A P -
"
memory fullGC.
"should allocate two objects to fill two free chunks"
self keepObjectInVMVariable2: self newDeadObject.
self keepObjectInVMVariable3: self newDeadObject.
destination := self newDeadObject.
self newKeptPinnedObject.
self newDeadObject.
aliveObject := self newAliveObject.
memory fullGC.
self assert: (memory isForwarded: aliveObject).
self assert: self lastAliveObject equals: destination.
]
{ #category : #testCompactor }
VMPinnedObjectTest >> testAllocatingObjectAfterManyPinnedObjectShouldSlideAtStartOfOldSpace [
| aliveObject destination shouldBeFreed |
"D = Dead
P = Pinned
A = Alive
F = Free
scenario :
before : D D P P D A -
after : A F P P -"
memory fullGC.
"should allocate two objects to fill two free chunks"
self keepObjectInVMVariable2: self newDeadObject.
self keepObjectInVMVariable3: self newDeadObject.
destination := self newDeadObject.
shouldBeFreed := self newDeadObject.
self newKeptPinnedObject.
self newKeptPinnedObject.
self newDeadObject.
aliveObject := self newAliveObject.
memory fullGC.
self assert: (memory isForwarded: aliveObject).
self assert: self lastAliveObject equals: destination.
self assert: (memory isFreeObject: shouldBeFreed)
]
{ #category : #testCompactor }
VMPinnedObjectTest >> testAllocatingObjectAfterManyPinnedObjectShouldSlideBeforeFirstPinned [
| aliveObject destination |
"D = Dead
P = Pinned
A = Alive
F = Free
scenario :
before : D P P D A -
after : A P P -"
memory fullGC.
"should allocate two objects to fill two free chunks"
self keepObjectInVMVariable2: self newDeadObject.
self keepObjectInVMVariable3: self newDeadObject.
destination := self newDeadObject.
self newKeptPinnedObject.
self newKeptPinnedObject.
self newDeadObject.
aliveObject := self newAliveObject.
memory fullGC.
self assert: (memory isForwarded: aliveObject).
self assert: self lastAliveObject equals: destination.
]
{ #category : #testCompactor }
VMPinnedObjectTest >> testAllocatingObjectAfterTwoPinObjectShouldSlideAtStartOfOldSpace [
| aliveObject destination shouldBeFreed |
"D = Dead
P = Pinned
A = Alive
F = Free
scenario :
before : D P D P D A -
after : A P F P -"
memory fullGC.
"should allocate two objects to fill two free chunks"
self keepObjectInVMVariable2: self newDeadObject.
self keepObjectInVMVariable3: self newDeadObject.
destination := self newDeadObject .
self newKeptPinnedObject.
shouldBeFreed := self newDeadObject.
self newKeptPinnedObject.
self newDeadObject.
aliveObject := self newAliveObject.
memory fullGC.
self assert: (memory isForwarded: aliveObject).
self assert: self lastAliveObject equals: destination.
self assert: (memory isFreeObject: shouldBeFreed)
]
{ #category : #testCompactor }
VMPinnedObjectTest >> testAllocatingObjectRightAfterPinnedShouldMoveItOnFirstDead [
| destination aliveObject aliveObjectHash |
"D = Dead
P = Pinned
A = Alive
F = Free
scenario :
before : D P A-
after : D P A-"
"The garbage collector frees objects only if there is objects to moved
So this object should still be dead"
memory fullGC.
destination := self newDeadObject.
self newKeptPinnedObject.
aliveObject := self newAliveObject.
aliveObjectHash := memory rawHashBitsOf: aliveObject.
memory fullGC.
self assert: aliveObjectHash equals: (memory rawHashBitsOf: destination).
"After the last pinned object, there is now the free tree chunk, which is a big object"
self assert: (memory isFreeObject: (memory objectAfter: self lastPinnedObject)).
]
{ #category : #tests }
VMPinnedObjectTest >> testPinANewObjectShouldMoveItToTheOldSpace [
"if we follow the forwarder, the object is in the old space"
| obj |
obj := self newObjectWithSlots: 0.
self keepObjectInVMVariable1: obj.
memory pinObject: obj.
self assert: (memory isInOldSpace: (memory followForwarded: obj))
]
{ #category : #tests }
VMPinnedObjectTest >> testPinANewObjectShouldMoveItToTheOldSpaceAndLeaveAForwarderBehind [
| obj |
obj := self newObjectWithSlots: 0.
self keepObjectInVMVariable1: obj.
memory pinObject: obj.
self assert: (memory isForwarded: obj)
]
{ #category : #tests }
VMPinnedObjectTest >> testPinnedObjectShouldNotBeMovedByGC [
| pinned |
self newOldSpaceObjectWithSlots: 0. "deadObject, that differenciate the start of the old space to the pin"
pinned := self newObjectWithSlots: 0.
memory pinObject: pinned.
self keepObjectInVMVariable1: (memory followForwarded: pinned).
memory fullGC.
self assert: (memory isForwarded: self keptObjectInVMVariable1) not.
]