mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
[ VM ] Ignore contexts which have been optimized out during stack overflow checks
Fixes https://github.com/dart-lang/sdk/issues/38182 Change-Id: I2b042b9a320e16fc88bee6ea2c0c93598e574c00 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115880 Reviewed-by: Ryan Macnak <rmacnak@google.com> Reviewed-by: Aart Bik <ajcbik@google.com> Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
parent
dabfda5770
commit
e6887536aa
35
runtime/tests/vm/dart/regress_38182_test.dart
Normal file
35
runtime/tests/vm/dart/regress_38182_test.dart
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// VMOptions=--stacktrace_every=1 --deterministic
|
||||||
|
|
||||||
|
void foo1(par) {
|
||||||
|
try {
|
||||||
|
() {
|
||||||
|
// The parameter `par` has to be captured within a closure, but it doesn't
|
||||||
|
// matter whether or not it's actually used.
|
||||||
|
print(par.runtimeType);
|
||||||
|
};
|
||||||
|
// We need to throw, otherwise the crash doesn't happen. We don't need to
|
||||||
|
// catch it explicitly, however.
|
||||||
|
throw '';
|
||||||
|
} finally {
|
||||||
|
// We need to trigger a lot of stack overflow checks. Somewhere around
|
||||||
|
// 20000 seems to work.
|
||||||
|
int x = 0;
|
||||||
|
for (int loc1 = 0; loc1 < 20000; loc1++) {
|
||||||
|
x += loc1;
|
||||||
|
}
|
||||||
|
print(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
try {
|
||||||
|
// Parameter isn't important.
|
||||||
|
foo1(null);
|
||||||
|
} catch (e) {
|
||||||
|
print('foo1 threw');
|
||||||
|
}
|
||||||
|
}
|
|
@ -1156,7 +1156,8 @@ const Context& ActivationFrame::GetSavedCurrentContext() {
|
||||||
} else if (obj.IsContext()) {
|
} else if (obj.IsContext()) {
|
||||||
ctx_ = Context::Cast(obj).raw();
|
ctx_ = Context::Cast(obj).raw();
|
||||||
} else {
|
} else {
|
||||||
ASSERT(obj.IsNull());
|
ASSERT(obj.IsNull() || obj.raw() == Symbols::OptimizedOut().raw());
|
||||||
|
ctx_ = Context::null();
|
||||||
}
|
}
|
||||||
return ctx_;
|
return ctx_;
|
||||||
}
|
}
|
||||||
|
@ -1431,7 +1432,12 @@ RawObject* ActivationFrame::GetRelativeContextVar(intptr_t var_ctx_level,
|
||||||
intptr_t ctx_slot,
|
intptr_t ctx_slot,
|
||||||
intptr_t frame_ctx_level) {
|
intptr_t frame_ctx_level) {
|
||||||
const Context& ctx = GetSavedCurrentContext();
|
const Context& ctx = GetSavedCurrentContext();
|
||||||
ASSERT(!ctx.IsNull());
|
|
||||||
|
// It's possible that ctx was optimized out as no locals were captured by the
|
||||||
|
// context. See issue #38182.
|
||||||
|
if (ctx.IsNull()) {
|
||||||
|
return Symbols::OptimizedOut().raw();
|
||||||
|
}
|
||||||
|
|
||||||
intptr_t level_diff = frame_ctx_level - var_ctx_level;
|
intptr_t level_diff = frame_ctx_level - var_ctx_level;
|
||||||
if (level_diff == 0) {
|
if (level_diff == 0) {
|
||||||
|
|
Loading…
Reference in a new issue