91ed534139
- Don't use PC-relative calls when calling between loading units. - Sort the contents of the code cluster by loading unit, then by text offset. - Handle binding PC-relatives calls and inserting trampolines per loading unit. - Create one code order table per loading unit to implement PC -> Code lookup. - Read code order tables directly, instead of copying into malloc'd memory. --use_table_dispatch still not yet supported. This slightly shrinks non-split binaries (~2% clustered part, 0.4% total snapshot) due to the new delta encoding when Code references Instructions. Bug: https://github.com/dart-lang/sdk/issues/41974 Change-Id: I51052ebc7b4968b554897d1710135a6c41821302 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/157820 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com> Reviewed-by: Tess Strickland <sstrickl@google.com>
71 lines
2.2 KiB
C++
71 lines
2.2 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::Lookup(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->ptr()->length_);
|
|
for (intptr_t i = 0; i < tables_length; i++) {
|
|
ArrayPtr table =
|
|
static_cast<ArrayPtr>(tables->ptr()->data_->ptr()->data()[i]);
|
|
intptr_t lo = 0;
|
|
intptr_t hi = Smi::Value(table->ptr()->length_) - 1;
|
|
|
|
// Fast check if pc belongs to this table.
|
|
if (lo > hi) {
|
|
continue;
|
|
}
|
|
CodePtr first = static_cast<CodePtr>(table->ptr()->data()[lo]);
|
|
if (pc < Code::PayloadStartOf(first)) {
|
|
continue;
|
|
}
|
|
CodePtr last = static_cast<CodePtr>(table->ptr()->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->ptr()->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();
|
|
}
|
|
|
|
} // namespace dart
|