Skip to content

Commit 8887042

Browse files
author
Nicolas Laurent
committed
refactor Thread#backtrace_locations and Exception#backtrace_locations to use Backtrace#getBacktraceLocations
1 parent 93bc92f commit 8887042

File tree

3 files changed

+15
-63
lines changed

3 files changed

+15
-63
lines changed

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

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
*/
1010
package org.truffleruby.core.exception;
1111

12-
import com.oracle.truffle.api.object.DynamicObjectFactory;
1312
import org.truffleruby.Layouts;
1413
import org.truffleruby.builtins.CoreModule;
1514
import org.truffleruby.builtins.CoreMethod;
@@ -182,23 +181,14 @@ private ReadObjectFieldNode getReadCustomBacktraceNode() {
182181
public abstract static class BacktraceLocationsNode extends CoreMethodArrayArgumentsNode {
183182

184183
@Specialization
185-
protected Object backtrace_locations(DynamicObject exception,
186-
@Cached("createBinaryProfile()") ConditionProfile hasBacktraceProfile,
187-
@Cached("createBinaryProfile()") ConditionProfile hasLocationsProfile) {
184+
protected Object backtraceLocations(DynamicObject exception,
185+
@Cached("createBinaryProfile()") ConditionProfile hasBacktraceProfile,
186+
@Cached("createBinaryProfile()") ConditionProfile hasLocationsProfile) {
188187
if (hasBacktraceProfile.profile(Layouts.EXCEPTION.getBacktrace(exception) != null)) {
189188
DynamicObject backtraceLocations = Layouts.EXCEPTION.getBacktraceLocations(exception);
190189
if (hasLocationsProfile.profile(backtraceLocations == null)) {
191190
Backtrace backtrace = Layouts.EXCEPTION.getBacktrace(exception);
192-
int locationsCount = backtrace.getActivations().length;
193-
Object[] locations = new Object[locationsCount];
194-
DynamicObjectFactory factory = coreLibrary().threadBacktraceLocationFactory;
195-
for (int i = 0; i < locationsCount; i++) {
196-
locations[i] = Layouts.THREAD_BACKTRACE_LOCATION.createThreadBacktraceLocation(
197-
factory,
198-
backtrace,
199-
i);
200-
}
201-
backtraceLocations = createArray(locations, locations.length);
191+
backtraceLocations = backtrace.getBacktraceLocations(GetBacktraceException.UNLIMITED);
202192
Layouts.EXCEPTION.setBacktraceLocations(exception, backtraceLocations);
203193
}
204194
return backtraceLocations;

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import org.truffleruby.builtins.Primitive;
3131
import org.truffleruby.builtins.PrimitiveArrayArgumentsNode;
3232
import org.truffleruby.builtins.UnaryCoreMethodNode;
33-
import org.truffleruby.core.array.ArrayHelpers;
3433
import org.truffleruby.core.array.ArrayStrategy;
3534
import org.truffleruby.core.array.ArrayUtils;
3635
import org.truffleruby.core.basicobject.BasicObjectNodes.ObjectIDNode;

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

Lines changed: 11 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import java.util.concurrent.CountDownLatch;
4444
import java.util.concurrent.TimeUnit;
4545

46-
import com.oracle.truffle.api.object.DynamicObjectFactory;
4746
import org.jcodings.specific.USASCIIEncoding;
4847
import org.jcodings.specific.UTF8Encoding;
4948
import org.truffleruby.Layouts;
@@ -155,64 +154,28 @@ protected DynamicObject backtraceLocations(
155154
@TruffleBoundary
156155
private DynamicObject backtraceLocationsInternal(DynamicObject rubyThread, int omit, int length) {
157156
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;
159162

160163
final SafepointAction safepointAction = (thread1, currentNode) -> {
161164
final Backtrace backtrace = getContext().getCallStack().getBacktrace(this, omit);
162165
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));
185168
};
186169

187-
getContext()
188-
.getSafepointManager()
189-
.pauseRubyThreadAndExecute(rubyThread, this, safepointAction);
170+
getContext().getSafepointManager()
171+
.pauseRubyThreadAndExecute(rubyThread, this, safepointAction);
190172

191173
// 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) {
199175
return nil();
200176
}
201177

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);
216179
}
217180
}
218181

0 commit comments

Comments
 (0)