|
43 | 43 | import java.util.concurrent.CountDownLatch;
|
44 | 44 | import java.util.concurrent.TimeUnit;
|
45 | 45 |
|
46 |
| -import com.oracle.truffle.api.object.DynamicObjectFactory; |
47 | 46 | import org.jcodings.specific.USASCIIEncoding;
|
48 | 47 | import org.jcodings.specific.UTF8Encoding;
|
49 | 48 | import org.truffleruby.Layouts;
|
@@ -155,64 +154,28 @@ protected DynamicObject backtraceLocations(
|
155 | 154 | @TruffleBoundary
|
156 | 155 | private DynamicObject backtraceLocationsInternal(DynamicObject rubyThread, int omit, int length) {
|
157 | 156 | final Memo<Backtrace> backtraceMemo = new Memo<>(null);
|
158 |
| - final Memo<Integer> stackTraceLengthMemo = new Memo<>(null); |
| 157 | + |
| 158 | + // We can't set an effective limit when dealing with negative range endings. |
| 159 | + final int stackTraceElementsLimit = length < 0 |
| 160 | + ? GetBacktraceException.UNLIMITED |
| 161 | + : omit + length; |
159 | 162 |
|
160 | 163 | final SafepointAction safepointAction = (thread1, currentNode) -> {
|
161 | 164 | final Backtrace backtrace = getContext().getCallStack().getBacktrace(this, omit);
|
162 | 165 | backtraceMemo.set(backtrace);
|
163 |
| - |
164 |
| - // NOTE (norswap, 18 Dec 2019) |
165 |
| - // This is not entirely accurate, as a negative length does entail a limit. |
166 |
| - // However this limit can only determined by looking at the length of full |
167 |
| - // stack trace, which necessitates passing an exception with the limit set. |
168 |
| - // However, that field is only used to fill in the stack trace in the first place. |
169 |
| - final int stackTraceElementsLimit = length < 0 |
170 |
| - ? GetBacktraceException.UNLIMITED |
171 |
| - : omit + length; |
172 |
| - |
173 |
| - final GetBacktraceException exception = new GetBacktraceException(this, stackTraceElementsLimit); |
174 |
| - |
175 |
| - // NOTE(norswap, 20 Dec 2019) |
176 |
| - // This will also cause the stack trace to be filled. |
177 |
| - // We must call this rather than TruffleStackTrace#getStackTrace because |
178 |
| - // it does some additional filtering. |
179 |
| - // TODO(norswap, 20 Dec 2019) |
180 |
| - // Currently, only the filtering at the end is taken into account (as length reduction). |
181 |
| - // Filtering in the middle will be ignored because of how we build backtrace locations. |
182 |
| - // TODO (norswap, 24 Dec 2019) |
183 |
| - // Could we actually move this out of the safepointAction? |
184 |
| - stackTraceLengthMemo.set(backtrace.getActivations(exception).length); |
| 166 | + // Fill in the stack trace. |
| 167 | + backtrace.getActivations(new GetBacktraceException(this, stackTraceElementsLimit)); |
185 | 168 | };
|
186 | 169 |
|
187 |
| - getContext() |
188 |
| - .getSafepointManager() |
189 |
| - .pauseRubyThreadAndExecute(rubyThread, this, safepointAction); |
| 170 | + getContext().getSafepointManager() |
| 171 | + .pauseRubyThreadAndExecute(rubyThread, this, safepointAction); |
190 | 172 |
|
191 | 173 | // If the thread is dead or aborting the SafepointAction will not run.
|
192 |
| - if (backtraceMemo.get() == null || stackTraceLengthMemo.get() == null) |
193 |
| - return nil(); |
194 |
| - |
195 |
| - final Backtrace backtrace = backtraceMemo.get(); |
196 |
| - final int stackTraceLength = stackTraceLengthMemo.get(); |
197 |
| - |
198 |
| - if (omit > stackTraceLength) { |
| 174 | + if (backtraceMemo.get() == null) { |
199 | 175 | return nil();
|
200 | 176 | }
|
201 | 177 |
|
202 |
| - // NOTE (norswap, 18 Dec 2019) |
203 |
| - // TruffleStackTrace#getStackTrace (hence Backtrace#getActivations too) does not |
204 |
| - // always respect the limit, so we need to use Math#min. Haven't yet investigated why. |
205 |
| - final int locationsLimit = length < 0 |
206 |
| - ? stackTraceLength + 1 + length |
207 |
| - : Math.min(stackTraceLength, length); |
208 |
| - |
209 |
| - final Object[] locations = new Object[locationsLimit]; |
210 |
| - final DynamicObjectFactory factory = coreLibrary().threadBacktraceLocationFactory; |
211 |
| - for (int i = 0; i < locationsLimit; i++) { |
212 |
| - locations[i] = Layouts.THREAD_BACKTRACE_LOCATION.createThreadBacktraceLocation( |
213 |
| - factory, backtrace, i); |
214 |
| - } |
215 |
| - return createArray(locations, locations.length); |
| 178 | + return backtraceMemo.get().getBacktraceLocations(length); |
216 | 179 | }
|
217 | 180 | }
|
218 | 181 |
|
|
0 commit comments