155ac440f7
Change-Id: I8264b340ee91d883afc52a52e83cda504f552e37 TEST=CI Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/191302 Commit-Queue: Liam Appelbe <liama@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
109 lines
3.9 KiB
C++
109 lines
3.9 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"
|
|
#include "vm/stub_code.h"
|
|
|
|
namespace dart {
|
|
|
|
ObjectPtr ReversePc::FindCodeDescriptorInGroup(IsolateGroup* group,
|
|
uword pc,
|
|
bool is_return_address,
|
|
uword* code_start) {
|
|
#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 (one per loading unit), 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()->instructions_tables();
|
|
intptr_t tables_length = Smi::Value(tables->untag()->length());
|
|
for (intptr_t i = 0; i < tables_length; i++) {
|
|
InstructionsTablePtr table = static_cast<InstructionsTablePtr>(
|
|
tables->untag()->data()->untag()->element(i));
|
|
intptr_t index = InstructionsTable::FindEntry(table, pc);
|
|
if (index >= 0) {
|
|
*code_start = InstructionsTable::PayloadStartAt(table, index);
|
|
return InstructionsTable::DescriptorAt(table, index);
|
|
}
|
|
}
|
|
#endif // defined(DART_PRECOMPILED_RUNTIME)
|
|
|
|
*code_start = 0;
|
|
return Object::null();
|
|
}
|
|
|
|
ObjectPtr ReversePc::FindCodeDescriptor(IsolateGroup* group,
|
|
uword pc,
|
|
bool is_return_address,
|
|
uword* code_start) {
|
|
ASSERT(FLAG_precompiled_mode && FLAG_use_bare_instructions);
|
|
NoSafepointScope no_safepoint;
|
|
|
|
ObjectPtr code_descriptor =
|
|
FindCodeDescriptorInGroup(group, pc, is_return_address, code_start);
|
|
if (code_descriptor == Object::null()) {
|
|
code_descriptor = FindCodeDescriptorInGroup(Dart::vm_isolate_group(), pc,
|
|
is_return_address, code_start);
|
|
}
|
|
return code_descriptor;
|
|
}
|
|
|
|
CodePtr ReversePc::Lookup(IsolateGroup* group,
|
|
uword pc,
|
|
bool is_return_address) {
|
|
ASSERT(FLAG_precompiled_mode && FLAG_use_bare_instructions);
|
|
NoSafepointScope no_safepoint;
|
|
|
|
uword code_start;
|
|
ObjectPtr code_descriptor =
|
|
FindCodeDescriptor(group, pc, is_return_address, &code_start);
|
|
if (code_descriptor != Object::null()) {
|
|
if (!code_descriptor->IsCode()) {
|
|
ASSERT(StubCode::UnknownDartCode().PayloadStart() == 0);
|
|
ASSERT(StubCode::UnknownDartCode().Size() == kUwordMax);
|
|
ASSERT(StubCode::UnknownDartCode().IsFunctionCode());
|
|
ASSERT(StubCode::UnknownDartCode().IsUnknownDartCode());
|
|
code_descriptor = StubCode::UnknownDartCode().ptr();
|
|
}
|
|
}
|
|
return static_cast<CodePtr>(code_descriptor);
|
|
}
|
|
|
|
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;
|
|
|
|
ObjectPtr code_descriptor =
|
|
FindCodeDescriptor(group, pc, is_return_address, code_start);
|
|
if (code_descriptor != Object::null()) {
|
|
if (code_descriptor->IsCode()) {
|
|
CodePtr code = static_cast<CodePtr>(code_descriptor);
|
|
ASSERT(*code_start == Code::PayloadStartOf(code));
|
|
return code->untag()->compressed_stackmaps();
|
|
} else {
|
|
ASSERT(code_descriptor->IsCompressedStackMaps());
|
|
return static_cast<CompressedStackMapsPtr>(code_descriptor);
|
|
}
|
|
}
|
|
|
|
*code_start = 0;
|
|
return CompressedStackMaps::null();
|
|
}
|
|
|
|
} // namespace dart
|