1
1
/*
2
- * Copyright (c) 2017, 2022 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2017, 2025 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
39
39
import com .oracle .objectfile .ObjectFile ;
40
40
import com .oracle .svm .core .SubstrateOptions ;
41
41
import com .oracle .svm .core .config .ConfigurationValues ;
42
+ import com .oracle .svm .core .graal .code .SharedCompilationResult ;
42
43
import com .oracle .svm .core .util .VMError ;
43
44
import com .oracle .svm .hosted .DeadlockWatchdog ;
44
45
import com .oracle .svm .hosted .code .HostedDirectCallTrampolineSupport ;
@@ -96,9 +97,9 @@ public int codeSizeFor(HostedMethod method) {
96
97
if (orderedTrampolineMap .containsKey (method )) {
97
98
List <Pair <HostedMethod , Integer >> trampolineList = orderedTrampolineMap .get (method );
98
99
int lastTrampolineStart = trampolineList .get (trampolineList .size () - 1 ).getRight ();
99
- methodEnd = computeNextMethodStart (lastTrampolineStart , HostedDirectCallTrampolineSupport .singleton ().getTrampolineSize ());
100
+ methodEnd = addOffset (lastTrampolineStart , HostedDirectCallTrampolineSupport .singleton ().getTrampolineSize ());
100
101
} else {
101
- methodEnd = computeNextMethodStart (methodStart , compilationResultFor (method ).getTargetCodeSize ());
102
+ methodEnd = addOffset (methodStart , compilationResultFor (method ).getTargetCodeSize ());
102
103
}
103
104
104
105
return methodEnd - methodStart ;
@@ -112,22 +113,22 @@ private boolean verifyMethodLayout() {
112
113
CompilationResult compilation = entry .getRight ();
113
114
114
115
int methodStart = method .getCodeAddressOffset ();
116
+ currentPos = align (currentPos , SharedCompilationResult .getCodeAlignment (compilation ));
115
117
assert currentPos == methodStart ;
116
118
117
- currentPos += compilation .getTargetCodeSize ();
119
+ currentPos = addOffset ( currentPos , compilation .getTargetCodeSize () );
118
120
119
121
if (orderedTrampolineMap .containsKey (method )) {
120
122
for (var trampoline : orderedTrampolineMap .get (method )) {
121
123
int trampolineOffset = trampoline .getRight ();
122
124
123
- currentPos = NumUtil . roundUp (currentPos , trampolineSupport .getTrampolineAlignment ());
125
+ currentPos = align (currentPos , trampolineSupport .getTrampolineAlignment ());
124
126
assert trampolineOffset == currentPos ;
125
127
126
128
currentPos += trampolineSupport .getTrampolineSize ();
127
129
}
128
130
}
129
131
130
- currentPos = computeNextMethodStart (currentPos , 0 );
131
132
int size = currentPos - method .getCodeAddressOffset ();
132
133
assert codeSizeFor (method ) == size ;
133
134
}
@@ -148,13 +149,14 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
148
149
for (Pair <HostedMethod , CompilationResult > entry : getOrderedCompilations ()) {
149
150
HostedMethod method = entry .getLeft ();
150
151
CompilationResult compilation = entry .getRight ();
152
+ curPos = align (curPos , SharedCompilationResult .getCodeAlignment (compilation ));
151
153
152
154
if (!trampolineSupport .mayNeedTrampolines ()) {
153
155
method .setCodeAddressOffset (curPos );
154
156
} else {
155
157
curOffsetMap .put (method , curPos );
156
158
}
157
- curPos = computeNextMethodStart (curPos , compilation .getTargetCodeSize ());
159
+ curPos = addOffset (curPos , compilation .getTargetCodeSize ());
158
160
}
159
161
160
162
if (trampolineSupport .mayNeedTrampolines ()) {
@@ -168,7 +170,7 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
168
170
int methodStartOffset = curOffsetMap .get (method );
169
171
method .setCodeAddressOffset (methodStartOffset );
170
172
Map <HostedMethod , Integer > trampolines = trampolineMap .get (method );
171
- if (trampolines .size () != 0 ) {
173
+ if (! trampolines .isEmpty () ) {
172
174
// assign an offset to each trampoline
173
175
List <Pair <HostedMethod , Integer >> sortedTrampolines = new ArrayList <>(trampolines .size ());
174
176
int position = methodStartOffset + pair .getRight ().getTargetCodeSize ();
@@ -177,10 +179,10 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
177
179
* positions.
178
180
*/
179
181
for (HostedMethod callTarget : trampolines .keySet ().toArray (HostedMethod .EMPTY_ARRAY )) {
180
- position = NumUtil . roundUp (position , trampolineSupport .getTrampolineAlignment ());
182
+ position = align (position , trampolineSupport .getTrampolineAlignment ());
181
183
trampolines .put (callTarget , position );
182
184
sortedTrampolines .add (Pair .create (callTarget , position ));
183
- position += trampolineSupport .getTrampolineSize ();
185
+ position = addOffset ( position , trampolineSupport .getTrampolineSize () );
184
186
}
185
187
orderedTrampolineMap .put (method , sortedTrampolines );
186
188
}
@@ -192,15 +194,16 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
192
194
Pair <HostedMethod , CompilationResult > lastCompilation = getLastCompilation ();
193
195
HostedMethod lastMethod = lastCompilation .getLeft ();
194
196
195
- // the total code size is the hypothetical start of the next method
197
+ // the total code size is aligned up to SubstrateOptions.codeAlignment()
196
198
int totalSize ;
197
199
if (orderedTrampolineMap .containsKey (lastMethod )) {
198
200
var trampolines = orderedTrampolineMap .get (lastMethod );
199
201
int lastTrampolineStart = trampolines .get (trampolines .size () - 1 ).getRight ();
200
- totalSize = computeNextMethodStart (lastTrampolineStart , trampolineSupport .getTrampolineSize ());
202
+ totalSize = addOffset (lastTrampolineStart , trampolineSupport .getTrampolineSize ());
201
203
} else {
202
- totalSize = computeNextMethodStart (lastCompilation .getLeft ().getCodeAddressOffset (), lastCompilation .getRight ().getTargetCodeSize ());
204
+ totalSize = addOffset (lastCompilation .getLeft ().getCodeAddressOffset (), lastCompilation .getRight ().getTargetCodeSize ());
203
205
}
206
+ totalSize = align (totalSize , SubstrateOptions .codeAlignment ());
204
207
205
208
setCodeAreaSize (totalSize );
206
209
@@ -209,14 +212,21 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
209
212
}
210
213
}
211
214
212
- private static int computeNextMethodStart (int current , int addend ) {
213
- int result ;
214
- try {
215
- result = NumUtil .roundUp (Math .addExact (current , addend ), SubstrateOptions .codeAlignment ());
216
- } catch (ArithmeticException e ) {
215
+ private static int align (int current , int alignment ) {
216
+ VMError .guarantee (current >= 0 && alignment > 0 && NumUtil .isUnsignedPowerOf2 (alignment ), "invalid argument %d - %d" , current , alignment );
217
+ int result = NumUtil .roundUp (current , alignment );
218
+ if (result < current ) {
217
219
throw VMError .shouldNotReachHere ("Code size is larger than 2GB" );
218
220
}
221
+ return result ;
222
+ }
219
223
224
+ private static int addOffset (int current , int offset ) {
225
+ VMError .guarantee (current >= 0 && offset >= 0 , "invalid argument %d - %d" , current , offset );
226
+ int result = current + offset ;
227
+ if (result < 0 ) {
228
+ throw VMError .shouldNotReachHere ("Code size is larger than 2GB" );
229
+ }
220
230
return result ;
221
231
}
222
232
@@ -236,21 +246,22 @@ private void addDirectCallTrampolines(Map<HostedMethod, Integer> curOffsetMap) {
236
246
for (Pair <HostedMethod , CompilationResult > entry : getOrderedCompilations ()) {
237
247
HostedMethod caller = entry .getLeft ();
238
248
CompilationResult compilation = entry .getRight ();
249
+ curPos = align (curPos , SharedCompilationResult .getCodeAlignment (compilation ));
239
250
240
251
int originalStart = curOffsetMap .get (caller );
241
252
int newStart = curPos ;
242
253
curOffsetMap .put (caller , newStart );
243
254
244
255
// move curPos to the end of the method code
245
- curPos += compilation .getTargetCodeSize ();
256
+ curPos = addOffset ( curPos , compilation .getTargetCodeSize () );
246
257
int newEnd = curPos ;
247
258
248
259
Map <HostedMethod , Integer > trampolines = trampolineMap .computeIfAbsent (caller , k -> new HashMap <>());
249
260
250
261
// update curPos to account for current trampolines
251
262
for (int j = 0 ; j < trampolines .size (); j ++) {
252
- curPos = NumUtil . roundUp (curPos , trampolineSupport .getTrampolineAlignment ());
253
- curPos += trampolineSupport .getTrampolineSize ();
263
+ curPos = align (curPos , trampolineSupport .getTrampolineAlignment ());
264
+ curPos = addOffset ( curPos , trampolineSupport .getTrampolineSize () );
254
265
}
255
266
for (Infopoint infopoint : compilation .getInfopoints ()) {
256
267
if (infopoint instanceof Call && ((Call ) infopoint ).direct ) {
@@ -289,13 +300,11 @@ private void addDirectCallTrampolines(Map<HostedMethod, Integer> curOffsetMap) {
289
300
// need to add another trampoline
290
301
changed = true ;
291
302
trampolines .put (callee , 0 );
292
- curPos = NumUtil . roundUp (curPos , trampolineSupport .getTrampolineAlignment ());
293
- curPos += trampolineSupport .getTrampolineSize ();
303
+ curPos = align (curPos , trampolineSupport .getTrampolineAlignment ());
304
+ curPos = addOffset ( curPos , trampolineSupport .getTrampolineSize () );
294
305
}
295
306
}
296
307
}
297
- // align curPos for start of next method
298
- curPos = computeNextMethodStart (curPos , 0 );
299
308
callerCompilationNum ++;
300
309
}
301
310
0 commit comments