-
Notifications
You must be signed in to change notification settings - Fork 68
/
CogMethod.class.st
180 lines (141 loc) · 4.96 KB
/
CogMethod.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
"
I am a native Cog method or polymorphic inline cache. If the former I have been produced by compiling a bytecoded CompiledMethod into machine code by the JIT, and I have a circular reference to that CompiledMethod. The CompiledMethod's header field is a pointer to me, the CogMethod, and my methodHeader field holds the compiled method's actual header. My objectHeader field looks like a single word object with a compact header with the mark bit set so as to placate the GC, i.e. make a CogMethod look like an object so that the reference to a CogMethod from a compiled method doesn't break the GC. The cmType, stackCheckOffset, cmNumArgs & cmNumTemps fields are early in the structure because we place dummy two-word CogMethod headers within a method for each block within it to record this information for each block method (see my superclass CogBlockMethod). In this case the objectHeader field is overlaid by the homeOffset and startpc fields. The objectHeader field is also used to hold the relocation distance when compacting methods since when functioning as an obhject header it is a constant value and so can easily be reinitialized. See Cogit class>>structureOfACogMethod for more information.
In C I look like
typedef struct {
sqInt objectHeader;
unsigned cmNumArgs : 8;
unsigned cmType : 3;
unsigned cmRefersToYoung : 1;
unsigned cmIsUnlinked : 1;
unsigned cmUsageCount : 3;
unsigned stackCheckOffset : 16;
unsigned short blockSize;
unsigned short blockEntryOffset;
sqInt methodObject;
sqInt methodHeader;
sqInt selector;
} CogMethod;
Note that in a 64-bit system all fields from cmNumArgs through blockEntry fit in a single 64-bit word.
My instances are not actually used. The methods exist only as input to Slang. The simulator uses my surrogates (CogMethodSurrogate32 and CogMethodSurrogate64.
"
Class {
#name : #CogMethod,
#superclass : #CogBlockMethod,
#instVars : [
'blockSize',
'blockEntryOffset',
'methodObject',
'methodHeader',
'selector'
],
#category : #'VMMaker-JIT'
}
{ #category : #accessing }
CogMethod class >> alignedByteSizeOf: anObject forClient: aVMClass [
^aVMClass cogit cogMethodSurrogateClass alignedByteSize
]
{ #category : #translation }
CogMethod class >> cogMethodHeader [
^String streamContents:
[:s|
CogBlockMethod printTypedefOn: s.
s cr.
self printTypedefOn: s]
]
{ #category : #'class initialization' }
CogMethod class >> initialize [
"self initialize"
(Smalltalk classNamed: #CogMethodSurrogate32) ifNotNil:
[:cms32|
self checkGenerateSurrogate: cms32 bytesPerWord: 4].
(Smalltalk classNamed: #CogMethodSurrogate64) ifNotNil:
[:cms64|
self checkGenerateSurrogate: cms64 bytesPerWord: 8]
]
{ #category : #accessing }
CogMethod class >> surrogateClass [
self shouldNotImplement
]
{ #category : #accessing }
CogMethod >> blockEntryOffset [
"Answer the value of blockEntryOffset"
^blockEntryOffset
]
{ #category : #accessing }
CogMethod >> blockEntryOffset: anObject [
"Set the value of blockEntryOffset"
^blockEntryOffset := anObject
]
{ #category : #accessing }
CogMethod >> blockSize [
"Answer the value of blockSize"
^ blockSize
]
{ #category : #accessing }
CogMethod >> blockSize: anObject [
"Set the value of blockSize"
^blockSize := anObject
]
{ #category : #testing }
CogMethod >> containsAddress: anAddress [
"is anAddress within my bounds; not a test of addresses referred to within instructions in the method"
<inline: true>
^self asUnsignedInteger <= anAddress asUnsignedInteger
and: [self asUnsignedInteger + self blockSize >= anAddress asUnsignedInteger]
]
{ #category : #accessing }
CogMethod >> counters [
^ 0
]
{ #category : #accessing }
CogMethod >> methodHeader [
"Answer the value of methodHeader"
^ methodHeader
]
{ #category : #accessing }
CogMethod >> methodHeader: anObject [
"Set the value of methodHeader"
^methodHeader := anObject
]
{ #category : #accessing }
CogMethod >> methodObject [
"Answer the value of methodObject"
^methodObject
]
{ #category : #accessing }
CogMethod >> methodObject: anObject [
"Set the value of methodObject"
^methodObject := anObject
]
{ #category : #accessing }
CogMethod >> nextOpenPIC [
"Answer the value of nextOpenPIC (a.k.a. methodObject)"
<cmacro: ' methodObject'>
^methodObject
]
{ #category : #accessing }
CogMethod >> nextOpenPIC: anObject [
"Set the value of nextOpenPIC (a.k.a. methodObject)"
<cmacro: 'Hack hack hack hack i.e. the getter macro does all the work'>
^methodObject := anObject
]
{ #category : #accessing }
CogMethod >> objectHeader [
"Answer the value of objectHeader"
^objectHeader
]
{ #category : #accessing }
CogMethod >> objectHeader: anObject [
"Set the value of objectHeader"
^objectHeader := anObject
]
{ #category : #accessing }
CogMethod >> selector [
"Answer the value of selector"
^ selector
]
{ #category : #accessing }
CogMethod >> selector: anObject [
"Set the value of selector"
^selector := anObject
]