Files
sdk/runtime/vm/reverse_pc_lookup_cache.cc
T
Alexander Markov ddfc98337b Reland "[vm/aot] Avoid using most Code objects in stack traces with --dwarf-stack-traces"
This is a reland of b6dc4dad4d

TEST=ci

Original change's description:
> [vm/aot] Avoid using most Code objects in stack traces with --dwarf-stack-traces
>
> The following changes are done in preparation for the removal of Code
> objects in AOT with --dwarf-stack-traces:
>
> * Stack trace objects are extended to hold uword PCs (which may not
>   fit into Smi range).
>
> * Scanning stack frames in GC (StackFrame::VisitObjectPointers)
>   now avoids using Code objects.
>   In order to find CompressedStackMaps it now calls
>   ReversePc::FindCompressedStackMaps.
>
> * Singleton Code object (StubCode::UnknownDartCode()) is prepared as
>   a replacement for Code objects in stack traces. It has
>   PayloadStart() == 0 and Size() == kUwordMax so it includes
>   arbitrary PCs.
>
> * In --dwarf-stack-traces mode, most Code objects obtained from stack
>   frames are replaced with StubCode::UnknownDartCode().
>   This simulates future behavior of ReversePc::Lookup when Code objects
>   will be removed.
>
> Issue: https://github.com/dart-lang/sdk/issues/44852
> Change-Id: I7cec7b8b9396c9cfeca3c256a412ba4e82a7e0c4
> TEST=ci
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182720
> Commit-Queue: Alexander Markov <alexmarkov@google.com>
> Reviewed-by: Tess Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>

Change-Id: Ia2fc4672a085cd963b7fc103369851df3603590c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/186202
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
2021-02-22 10:46:28 +00:00

102 lines
3.1 KiB
C++

// Copyright (c) 2018, 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.
#include "vm/reverse_pc_lookup_cache.h"
#include "vm/isolate.h"
#include "vm/object.h"
#include "vm/object_store.h"
namespace dart {
CodePtr ReversePc::LookupInGroup(IsolateGroup* group,
uword pc,
bool is_return_address) {
#if defined(DART_PRECOMPILED_RUNTIME)
// This can run in the middle of GC and must not allocate handles.
NoSafepointScope no_safepoint;
if (is_return_address) {
pc--;
}
// This expected number of tables is low, so we go through them linearly. If
// this changes, would could sort the table list during deserialization and
// binary search for the table.
GrowableObjectArrayPtr tables = group->object_store()->code_order_tables();
intptr_t tables_length = Smi::Value(tables->untag()->length_);
for (intptr_t i = 0; i < tables_length; i++) {
ArrayPtr table =
static_cast<ArrayPtr>(tables->untag()->data_->untag()->data()[i]);
intptr_t lo = 0;
intptr_t hi = Smi::Value(table->untag()->length_) - 1;
// Fast check if pc belongs to this table.
if (lo > hi) {
continue;
}
CodePtr first = static_cast<CodePtr>(table->untag()->data()[lo]);
if (pc < Code::PayloadStartOf(first)) {
continue;
}
CodePtr last = static_cast<CodePtr>(table->untag()->data()[hi]);
if (pc >= (Code::PayloadStartOf(last) + Code::PayloadSizeOf(last))) {
continue;
}
// Binary search within the table for the matching Code.
while (lo <= hi) {
intptr_t mid = (hi - lo + 1) / 2 + lo;
ASSERT(mid >= lo);
ASSERT(mid <= hi);
CodePtr code = static_cast<CodePtr>(table->untag()->data()[mid]);
uword code_start = Code::PayloadStartOf(code);
uword code_end = code_start + Code::PayloadSizeOf(code);
if (pc < code_start) {
hi = mid - 1;
} else if (pc >= code_end) {
lo = mid + 1;
} else {
return code;
}
}
}
#endif // defined(DART_PRECOMPILED_RUNTIME)
return Code::null();
}
CodePtr ReversePc::Lookup(IsolateGroup* group,
uword pc,
bool is_return_address) {
ASSERT(FLAG_precompiled_mode && FLAG_use_bare_instructions);
NoSafepointScope no_safepoint;
CodePtr code = LookupInGroup(group, pc, is_return_address);
if (code == Code::null()) {
code = LookupInGroup(Dart::vm_isolate_group(), pc, is_return_address);
}
return code;
}
CompressedStackMapsPtr ReversePc::FindCompressedStackMaps(
IsolateGroup* group,
uword pc,
bool is_return_address,
uword* code_start) {
ASSERT(FLAG_precompiled_mode && FLAG_use_bare_instructions);
NoSafepointScope no_safepoint;
CodePtr code = Lookup(group, pc, is_return_address);
if (code != Code::null()) {
*code_start = Code::PayloadStartOf(code);
return code->untag()->compressed_stackmaps();
}
*code_start = 0;
return CompressedStackMaps::null();
}
} // namespace dart