Skip to content

Commit e74d4b7

Browse files
author
Nicolas Laurent
committed
simplify Backtrace#getBacktraceLocations usage
1 parent 7614713 commit e74d4b7

File tree

4 files changed

+28
-17
lines changed

4 files changed

+28
-17
lines changed

src/main/java/org/truffleruby/core/exception/ExceptionNodes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ protected Object backtraceLocations(DynamicObject exception,
187187
DynamicObject backtraceLocations = Layouts.EXCEPTION.getBacktraceLocations(exception);
188188
if (hasLocationsProfile.profile(backtraceLocations == null)) {
189189
Backtrace backtrace = Layouts.EXCEPTION.getBacktrace(exception);
190-
backtraceLocations = backtrace.getBacktraceLocations(GetBacktraceException.UNLIMITED);
190+
backtraceLocations = backtrace.getBacktraceLocations(GetBacktraceException.UNLIMITED, this);
191191
Layouts.EXCEPTION.setBacktraceLocations(exception, backtraceLocations);
192192
}
193193
return backtraceLocations;

src/main/java/org/truffleruby/core/kernel/KernelNodes.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,7 @@ private DynamicObject innerCallerLocations(int omit, int length) {
324324
? GetBacktraceException.UNLIMITED
325325
: omitted + length;
326326

327-
// Fill in the stack trace.
328-
backtrace.getActivations(new GetBacktraceException(this, limit));
329-
330-
return backtrace.getBacktraceLocations(length);
327+
return backtrace.getBacktraceLocations(length, this);
331328
}
332329
}
333330

src/main/java/org/truffleruby/core/thread/ThreadNodes.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ protected DynamicObject backtraceLocations(
153153

154154
@TruffleBoundary
155155
private DynamicObject backtraceLocationsInternal(DynamicObject rubyThread, int omit, int length) {
156-
final Memo<Backtrace> backtraceMemo = new Memo<>(null);
156+
final Memo<DynamicObject> backtraceLocationsMemo = new Memo<>(null);
157157

158158
// We can't set an effective limit when dealing with negative range endings.
159159
final int stackTraceElementsLimit = length < 0
@@ -162,21 +162,17 @@ private DynamicObject backtraceLocationsInternal(DynamicObject rubyThread, int o
162162

163163
final SafepointAction safepointAction = (thread1, currentNode) -> {
164164
final Backtrace backtrace = getContext().getCallStack().getBacktrace(this, omit);
165-
backtraceMemo.set(backtrace);
166-
// Fill in the stack trace.
167-
backtrace.getActivations(new GetBacktraceException(this, stackTraceElementsLimit));
165+
backtraceLocationsMemo.set(backtrace.getBacktraceLocations(length, this));
168166
};
169167

170168
getContext()
171169
.getSafepointManager()
172170
.pauseRubyThreadAndExecute(rubyThread, this, safepointAction);
173171

174172
// If the thread is dead or aborting the SafepointAction will not run.
175-
if (backtraceMemo.get() == null) {
176-
return nil();
177-
}
178-
179-
return backtraceMemo.get().getBacktraceLocations(length);
173+
return backtraceLocationsMemo.get() == null
174+
? nil()
175+
: backtraceLocationsMemo.get();
180176
}
181177
}
182178

src/main/java/org/truffleruby/language/backtrace/Backtrace.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,17 +269,35 @@ public Activation[] getActivations() {
269269
* <p>The length can be negative, in which case it is treated as a range ending. Use -1 to
270270
* get the maximum length.
271271
*
272-
* <p>If the stack trace hasn't been filled yet, this method will fill it.
272+
* <p>This causes the activations to be computed if not yet the case.
273273
*
274274
* @param length the maximum number of locations to return (if positive), or -1 minus the
275275
* number of items to exclude at the end. You can use
276276
* {@link GetBacktraceException#UNLIMITED} to signal that you want all locations.
277277
*
278+
* @param node the node at which we're requiring the backtrace. Can be null if the backtrace
279+
* is associated with a ruby exception or if we are sure the activations have
280+
* already been computed.
281+
*
278282
*/
279-
public DynamicObject getBacktraceLocations(int length) {
283+
public DynamicObject getBacktraceLocations(int length, Node node) {
280284

281285
final RubyContext context = RubyLanguage.getCurrentContext();
282-
final int activationsLength = getActivations().length;
286+
287+
final int activationsLength;
288+
if (this.raiseException != null) {
289+
// When dealing with the backtrace of a Ruby exception, we use the wrapping
290+
// exception and we don't set a limit on the retrieved activations.
291+
activationsLength = getActivations().length;
292+
}
293+
else {
294+
// We can't set an effective limit when dealing with negative range endings.
295+
final int stackTraceElementsLimit = length < 0
296+
? GetBacktraceException.UNLIMITED
297+
: omitted + length;
298+
final Throwable e = new GetBacktraceException(node, stackTraceElementsLimit);
299+
activationsLength = getActivations(e).length;
300+
}
283301

284302
// Omitting more locations than available should return nil.
285303
if (activationsLength == 0) {

0 commit comments

Comments
 (0)