11/*
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.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
3939import com .oracle .objectfile .ObjectFile ;
4040import com .oracle .svm .core .SubstrateOptions ;
4141import com .oracle .svm .core .config .ConfigurationValues ;
42+ import com .oracle .svm .core .graal .code .SharedCompilationResult ;
4243import com .oracle .svm .core .util .VMError ;
4344import com .oracle .svm .hosted .DeadlockWatchdog ;
4445import com .oracle .svm .hosted .code .HostedDirectCallTrampolineSupport ;
@@ -96,9 +97,9 @@ public int codeSizeFor(HostedMethod method) {
9697 if (orderedTrampolineMap .containsKey (method )) {
9798 List <Pair <HostedMethod , Integer >> trampolineList = orderedTrampolineMap .get (method );
9899 int lastTrampolineStart = trampolineList .get (trampolineList .size () - 1 ).getRight ();
99- methodEnd = computeNextMethodStart (lastTrampolineStart , HostedDirectCallTrampolineSupport .singleton ().getTrampolineSize ());
100+ methodEnd = addOffset (lastTrampolineStart , HostedDirectCallTrampolineSupport .singleton ().getTrampolineSize ());
100101 } else {
101- methodEnd = computeNextMethodStart (methodStart , compilationResultFor (method ).getTargetCodeSize ());
102+ methodEnd = addOffset (methodStart , compilationResultFor (method ).getTargetCodeSize ());
102103 }
103104
104105 return methodEnd - methodStart ;
@@ -112,22 +113,22 @@ private boolean verifyMethodLayout() {
112113 CompilationResult compilation = entry .getRight ();
113114
114115 int methodStart = method .getCodeAddressOffset ();
116+ currentPos = align (currentPos , SharedCompilationResult .getCodeAlignment (compilation ));
115117 assert currentPos == methodStart ;
116118
117- currentPos += compilation .getTargetCodeSize ();
119+ currentPos = addOffset ( currentPos , compilation .getTargetCodeSize () );
118120
119121 if (orderedTrampolineMap .containsKey (method )) {
120122 for (var trampoline : orderedTrampolineMap .get (method )) {
121123 int trampolineOffset = trampoline .getRight ();
122124
123- currentPos = NumUtil . roundUp (currentPos , trampolineSupport .getTrampolineAlignment ());
125+ currentPos = align (currentPos , trampolineSupport .getTrampolineAlignment ());
124126 assert trampolineOffset == currentPos ;
125127
126128 currentPos += trampolineSupport .getTrampolineSize ();
127129 }
128130 }
129131
130- currentPos = computeNextMethodStart (currentPos , 0 );
131132 int size = currentPos - method .getCodeAddressOffset ();
132133 assert codeSizeFor (method ) == size ;
133134 }
@@ -148,13 +149,14 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
148149 for (Pair <HostedMethod , CompilationResult > entry : getOrderedCompilations ()) {
149150 HostedMethod method = entry .getLeft ();
150151 CompilationResult compilation = entry .getRight ();
152+ curPos = align (curPos , SharedCompilationResult .getCodeAlignment (compilation ));
151153
152154 if (!trampolineSupport .mayNeedTrampolines ()) {
153155 method .setCodeAddressOffset (curPos );
154156 } else {
155157 curOffsetMap .put (method , curPos );
156158 }
157- curPos = computeNextMethodStart (curPos , compilation .getTargetCodeSize ());
159+ curPos = addOffset (curPos , compilation .getTargetCodeSize ());
158160 }
159161
160162 if (trampolineSupport .mayNeedTrampolines ()) {
@@ -168,7 +170,7 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
168170 int methodStartOffset = curOffsetMap .get (method );
169171 method .setCodeAddressOffset (methodStartOffset );
170172 Map <HostedMethod , Integer > trampolines = trampolineMap .get (method );
171- if (trampolines .size () != 0 ) {
173+ if (! trampolines .isEmpty () ) {
172174 // assign an offset to each trampoline
173175 List <Pair <HostedMethod , Integer >> sortedTrampolines = new ArrayList <>(trampolines .size ());
174176 int position = methodStartOffset + pair .getRight ().getTargetCodeSize ();
@@ -177,10 +179,10 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
177179 * positions.
178180 */
179181 for (HostedMethod callTarget : trampolines .keySet ().toArray (HostedMethod .EMPTY_ARRAY )) {
180- position = NumUtil . roundUp (position , trampolineSupport .getTrampolineAlignment ());
182+ position = align (position , trampolineSupport .getTrampolineAlignment ());
181183 trampolines .put (callTarget , position );
182184 sortedTrampolines .add (Pair .create (callTarget , position ));
183- position += trampolineSupport .getTrampolineSize ();
185+ position = addOffset ( position , trampolineSupport .getTrampolineSize () );
184186 }
185187 orderedTrampolineMap .put (method , sortedTrampolines );
186188 }
@@ -192,15 +194,16 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
192194 Pair <HostedMethod , CompilationResult > lastCompilation = getLastCompilation ();
193195 HostedMethod lastMethod = lastCompilation .getLeft ();
194196
195- // the total code size is the hypothetical start of the next method
197+ // the total code size is aligned up to SubstrateOptions.codeAlignment()
196198 int totalSize ;
197199 if (orderedTrampolineMap .containsKey (lastMethod )) {
198200 var trampolines = orderedTrampolineMap .get (lastMethod );
199201 int lastTrampolineStart = trampolines .get (trampolines .size () - 1 ).getRight ();
200- totalSize = computeNextMethodStart (lastTrampolineStart , trampolineSupport .getTrampolineSize ());
202+ totalSize = addOffset (lastTrampolineStart , trampolineSupport .getTrampolineSize ());
201203 } else {
202- totalSize = computeNextMethodStart (lastCompilation .getLeft ().getCodeAddressOffset (), lastCompilation .getRight ().getTargetCodeSize ());
204+ totalSize = addOffset (lastCompilation .getLeft ().getCodeAddressOffset (), lastCompilation .getRight ().getTargetCodeSize ());
203205 }
206+ totalSize = align (totalSize , SubstrateOptions .codeAlignment ());
204207
205208 setCodeAreaSize (totalSize );
206209
@@ -209,14 +212,21 @@ public void layoutMethods(DebugContext debug, BigBang bb) {
209212 }
210213 }
211214
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 ) {
217219 throw VMError .shouldNotReachHere ("Code size is larger than 2GB" );
218220 }
221+ return result ;
222+ }
219223
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+ }
220230 return result ;
221231 }
222232
@@ -236,21 +246,22 @@ private void addDirectCallTrampolines(Map<HostedMethod, Integer> curOffsetMap) {
236246 for (Pair <HostedMethod , CompilationResult > entry : getOrderedCompilations ()) {
237247 HostedMethod caller = entry .getLeft ();
238248 CompilationResult compilation = entry .getRight ();
249+ curPos = align (curPos , SharedCompilationResult .getCodeAlignment (compilation ));
239250
240251 int originalStart = curOffsetMap .get (caller );
241252 int newStart = curPos ;
242253 curOffsetMap .put (caller , newStart );
243254
244255 // move curPos to the end of the method code
245- curPos += compilation .getTargetCodeSize ();
256+ curPos = addOffset ( curPos , compilation .getTargetCodeSize () );
246257 int newEnd = curPos ;
247258
248259 Map <HostedMethod , Integer > trampolines = trampolineMap .computeIfAbsent (caller , k -> new HashMap <>());
249260
250261 // update curPos to account for current trampolines
251262 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 () );
254265 }
255266 for (Infopoint infopoint : compilation .getInfopoints ()) {
256267 if (infopoint instanceof Call && ((Call ) infopoint ).direct ) {
@@ -289,13 +300,11 @@ private void addDirectCallTrampolines(Map<HostedMethod, Integer> curOffsetMap) {
289300 // need to add another trampoline
290301 changed = true ;
291302 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 () );
294305 }
295306 }
296307 }
297- // align curPos for start of next method
298- curPos = computeNextMethodStart (curPos , 0 );
299308 callerCompilationNum ++;
300309 }
301310
0 commit comments