-
Notifications
You must be signed in to change notification settings - Fork 65
/
CompiledMethod.extension.st
125 lines (114 loc) · 5.22 KB
/
CompiledMethod.extension.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
Extension { #name : #CompiledMethod }
{ #category : #'*CogAttic-method prototypes' }
CompiledMethod >> CompiledMethodPROTOTYPEencoderClass [
"Answer the encoder class that encoded the bytecodes in this method.
The sign flag bit is used by the VM to select a bytecode set. This formulation
may seem odd but this has to be fast, so no property probe unless needed."
^self header >= 0
ifTrue:
[PrimaryBytecodeSetEncoderClass]
ifFalse:
[PrimaryBytecodeSetEncoderClass == SecondaryBytecodeSetEncoderClass
ifTrue: "Support for testing prior to installing another set"
[(self propertyValueAt: #encoderClass) ifNil: [SecondaryBytecodeSetEncoderClass]]
ifFalse:
[SecondaryBytecodeSetEncoderClass]]
]
{ #category : #'*CogAttic-method prototypes' }
CompiledMethod class >> CompiledMethodclassPROTOTYPEheaderFlagForEncoder: anEncoder [
anEncoder class == PrimaryBytecodeSetEncoderClass ifTrue:
[^0].
anEncoder class == SecondaryBytecodeSetEncoderClass ifTrue:
[^SmallInteger minVal].
self error: 'The encoder is not one of the two installed bytecode sets'
]
{ #category : #'*CogAttic-method prototypes' }
CompiledMethod class >> CompiledMethodclassPROTOTYPEinitialize [ "CompiledMethod initialize"
"Initialize class variables specifying the size of the temporary frame
needed to run instances of me."
SmallFrame := 16. "Context range for temps+stack"
LargeFrame := 56.
PrimaryBytecodeSetEncoderClass ifNil:
[PrimaryBytecodeSetEncoderClass := EncoderForV3PlusClosures].
SecondaryBytecodeSetEncoderClass ifNil:
[SecondaryBytecodeSetEncoderClass := EncoderForV3PlusClosures]
]
{ #category : #'*CogAttic-method prototypes' }
CompiledMethod class >> CompiledMethodclassPROTOTYPEinstallPrimaryBytecodeSet: aBytecodeEncoderSubclass [
PrimaryBytecodeSetEncoderClass == aBytecodeEncoderSubclass ifTrue:
[^self].
(aBytecodeEncoderSubclass inheritsFrom: BytecodeEncoder) ifFalse:
[self error: 'A bytecode set encoder is expected to be a subclass of BytecodeEncoder'].
(self allSubInstances
detect: [:m| m header >= 0 and: [m encoderClass ~~ aBytecodeEncoderSubclass]]
ifNone: []) ifNotNil:
[Warning signal: 'There are existing CompiledMethods with a different encoderClass.'].
PrimaryBytecodeSetEncoderClass := aBytecodeEncoderSubclass
]
{ #category : #'*CogAttic-method prototypes' }
CompiledMethod class >> CompiledMethodclassPROTOTYPEinstallSecondaryBytecodeSet: aBytecodeEncoderSubclass [
PrimaryBytecodeSetEncoderClass == aBytecodeEncoderSubclass ifTrue:
[^self].
(aBytecodeEncoderSubclass inheritsFrom: BytecodeEncoder) ifFalse:
[self error: 'A bytecode set encoder is expected to be a subclass of BytecodeEncoder'].
(self allSubInstances
detect: [:m| m header < 0 and: [m encoderClass ~~ aBytecodeEncoderSubclass]]
ifNone: []) ifNotNil:
[Warning signal: 'There are existing CompiledMethods with a different encoderClass.'].
SecondaryBytecodeSetEncoderClass := aBytecodeEncoderSubclass
]
{ #category : #'*CogAttic-method prototypes' }
CompiledMethod class >> CompiledMethodclassPROTOTYPEnewBytes: numberOfBytes trailerBytes: trailer nArgs: nArgs nTemps: nTemps nStack: stackSize nLits: nLits primitive: primitiveIndex [
"Answer an instance of me. The header is specified by the message
arguments. The remaining parts are not as yet determined."
| method pc |
nArgs > 15 ifTrue:
[^self error: 'Cannot compile -- too many arguments'].
nTemps > 63 ifTrue:
[^self error: 'Cannot compile -- too many temporary variables'].
nLits > 32768 ifTrue:
[^self error: 'Cannot compile -- too many literals'].
method := trailer
createMethod: numberOfBytes
class: self
header: (nArgs bitShift: 24)
+ (nTemps bitShift: 18)
+ ((nTemps + stackSize) > SmallFrame ifTrue: [1 bitShift: 17] ifFalse: [0])
+ nLits
+ (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0]).
primitiveIndex > 0 ifTrue:
[pc := method initialPC.
method
at: pc + 0 put: method encoderClass callPrimitiveCode;
at: pc + 1 put: (primitiveIndex bitAnd: 16rFF);
at: pc + 2 put: (primitiveIndex bitShift: -8)].
^method
]
{ #category : #'*CogAttic-method prototypes' }
CompiledMethod class >> CompiledMethodclassPROTOTYPEnewBytes: numberOfBytes trailerBytes: trailer nArgs: nArgs nTemps: nTemps nStack: stackSize nLits: nLits primitive: primitiveIndex flag: flag [
"Answer an instance of me. The header is specified by the message
arguments. The remaining parts are not as yet determined."
| method pc |
nArgs > 15 ifTrue:
[^self error: 'Cannot compile -- too many arguments'].
nTemps > 63 ifTrue:
[^self error: 'Cannot compile -- too many temporary variables'].
nLits > 32768 ifTrue:
[^self error: 'Cannot compile -- too many literals'].
method := trailer
createMethod: numberOfBytes
class: self
header: (nArgs bitShift: 24)
+ (nTemps bitShift: 18)
+ ((nTemps + stackSize) > SmallFrame ifTrue: [1 bitShift: 17] ifFalse: [0])
+ nLits
+ (primitiveIndex > 0 ifTrue: [1 bitShift: 16] ifFalse: [0])
+ (flag ifTrue: [1 bitShift: 29] ifFalse: [0]).
primitiveIndex > 0 ifTrue:
[pc := method initialPC.
method
at: pc + 0 put: method encoderClass callPrimitiveCode;
at: pc + 1 put: (primitiveIndex bitAnd: 16rFF);
at: pc + 2 put: (primitiveIndex bitShift: -8)].
^method
]