mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 16:12:57 +00:00
[vm] Follow up to 4a4eedd860
* Avoid calling memmove(dst, nullptr, 0) as this is flagged by UBSAN. * Avoid hitting a bug[1] in the linker: LLD's identical code folding (ICF) happens to replace RecordCoverageInstr::DebugName() with DispatchTable::LargestSmallOffset() because they happen to contain the same machine code, ICF fails to accomodate that DebugName also contains a relocation to constant string. To avoid this we simply eliminate LargestSmallOffset and replace it with a constant. Same for OriginElement. TEST=manually tested previously failing tests [1]: reported https://github.com/llvm/llvm-project/issues/57693 Change-Id: I38637df6475c7670081b7af0a2de75ca37f6f07c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258801 Reviewed-by: Daco Harkes <dacoharkes@google.com> Commit-Queue: Slava Egorov <vegorov@google.com>
This commit is contained in:
parent
727e792e77
commit
912577baec
|
@ -238,7 +238,7 @@ void DumpObjectPoolJSON(Thread* thread, dart::JSONWriter* js) {
|
|||
// auto dispatch = thread->isolate_group()->dispatch_table();
|
||||
// auto length = dispatch->length();
|
||||
// We must unbias the array entries so we don't crash on null access.
|
||||
// auto entries = dispatch->ArrayOrigin() - DispatchTable::OriginElement();
|
||||
// auto entries = dispatch->ArrayOrigin() - DispatchTable::kOriginElement;
|
||||
// for (intptr_t i = 0; i < length; i++) {
|
||||
// OS::Print("0x%lx at %ld\n", entries[i], i);
|
||||
// }
|
||||
|
|
|
@ -98,6 +98,10 @@ class ClassTableAllocator : public ValueObject {
|
|||
// Clone the given |array| with |size| elements.
|
||||
template <class T>
|
||||
inline T* Clone(T* array, intptr_t size) {
|
||||
if (array == nullptr) {
|
||||
ASSERT(size == 0);
|
||||
return nullptr;
|
||||
}
|
||||
auto result = Alloc<T>(size);
|
||||
memmove(result, array, size * sizeof(T));
|
||||
return result;
|
||||
|
@ -112,7 +116,10 @@ class ClassTableAllocator : public ValueObject {
|
|||
inline T* Realloc(T* array, intptr_t size, intptr_t new_size) {
|
||||
ASSERT(size < new_size);
|
||||
auto result = AllocZeroInitialized<T>(new_size);
|
||||
memmove(result, array, size * sizeof(T));
|
||||
if (size != 0) {
|
||||
ASSERT(result != nullptr);
|
||||
memmove(result, array, size * sizeof(T));
|
||||
}
|
||||
Free(array);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -629,7 +629,7 @@ void DispatchTableGenerator::ComputeSelectorOffsets() {
|
|||
table_rows_.Sort(PopularitySorter::Compare);
|
||||
|
||||
// Try to allocate at optimal offset.
|
||||
const int32_t optimal_offset = DispatchTable::OriginElement();
|
||||
const int32_t optimal_offset = DispatchTable::kOriginElement;
|
||||
for (intptr_t i = 0; i < table_rows_.length(); i++) {
|
||||
fitter.FitAndAllocate(table_rows_[i], optimal_offset, optimal_offset);
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ void DispatchTableGenerator::ComputeSelectorOffsets() {
|
|||
table_rows_.Sort(PopularitySizeRatioSorter::Compare);
|
||||
|
||||
// Try to allocate at small offsets.
|
||||
const int32_t max_offset = DispatchTable::LargestSmallOffset();
|
||||
const int32_t max_offset = DispatchTable::kLargestSmallOffset;
|
||||
for (intptr_t i = 0; i < table_rows_.length(); i++) {
|
||||
fitter.FitAndAllocate(table_rows_[i], 0, max_offset);
|
||||
}
|
||||
|
@ -658,7 +658,7 @@ void DispatchTableGenerator::ComputeSelectorOffsets() {
|
|||
table_rows_.Sort(SizeSorter::Compare);
|
||||
|
||||
// Allocate remaining rows at large offsets.
|
||||
const int32_t min_large_offset = DispatchTable::LargestSmallOffset() + 1;
|
||||
const int32_t min_large_offset = DispatchTable::kLargestSmallOffset + 1;
|
||||
for (intptr_t i = 0; i < table_rows_.length(); i++) {
|
||||
fitter.FitAndAllocate(table_rows_[i], min_large_offset);
|
||||
}
|
||||
|
|
|
@ -695,7 +695,7 @@ void FlowGraphCompiler::EmitDispatchTableCall(
|
|||
if (!arguments_descriptor.IsNull()) {
|
||||
__ LoadObject(ARGS_DESC_REG, arguments_descriptor);
|
||||
}
|
||||
intptr_t offset = (selector_offset - DispatchTable::OriginElement()) *
|
||||
intptr_t offset = (selector_offset - DispatchTable::kOriginElement) *
|
||||
compiler::target::kWordSize;
|
||||
CLOBBERS_LR({
|
||||
// Would like cid_reg to be available on entry to the target function
|
||||
|
|
|
@ -696,7 +696,7 @@ void FlowGraphCompiler::EmitDispatchTableCall(
|
|||
if (!arguments_descriptor.IsNull()) {
|
||||
__ LoadObject(ARGS_DESC_REG, arguments_descriptor);
|
||||
}
|
||||
const intptr_t offset = selector_offset - DispatchTable::OriginElement();
|
||||
const intptr_t offset = selector_offset - DispatchTable::kOriginElement;
|
||||
CLOBBERS_LR({
|
||||
// Would like cid_reg to be available on entry to the target function
|
||||
// for checking purposes.
|
||||
|
|
|
@ -666,7 +666,7 @@ void FlowGraphCompiler::EmitDispatchTableCall(
|
|||
if (!arguments_descriptor.IsNull()) {
|
||||
__ LoadObject(ARGS_DESC_REG, arguments_descriptor);
|
||||
}
|
||||
const intptr_t offset = selector_offset - DispatchTable::OriginElement();
|
||||
const intptr_t offset = selector_offset - DispatchTable::kOriginElement;
|
||||
// Would like cid_reg to be available on entry to the target function
|
||||
// for checking purposes.
|
||||
ASSERT(cid_reg != TMP);
|
||||
|
|
|
@ -682,7 +682,7 @@ void FlowGraphCompiler::EmitDispatchTableCall(
|
|||
if (!arguments_descriptor.IsNull()) {
|
||||
__ LoadObject(ARGS_DESC_REG, arguments_descriptor);
|
||||
}
|
||||
const intptr_t offset = (selector_offset - DispatchTable::OriginElement()) *
|
||||
const intptr_t offset = (selector_offset - DispatchTable::kOriginElement) *
|
||||
compiler::target::kWordSize;
|
||||
__ LoadDispatchTable(table_reg);
|
||||
__ call(compiler::Address(table_reg, cid_reg, TIMES_8, offset));
|
||||
|
|
|
@ -8,54 +8,8 @@
|
|||
|
||||
namespace dart {
|
||||
|
||||
intptr_t DispatchTable::OriginElement() {
|
||||
#if defined(TARGET_ARCH_X64)
|
||||
// Max negative byte offset / 8
|
||||
return 16;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
// Max negative load offset / 4
|
||||
return 1023;
|
||||
#elif defined(TARGET_ARCH_ARM64)
|
||||
// Max consecutive sub immediate value
|
||||
return 4096;
|
||||
#elif defined(TARGET_ARCH_RISCV32)
|
||||
// Max consecutive sub immediate value
|
||||
return 2048 / 4;
|
||||
#elif defined(TARGET_ARCH_RISCV64)
|
||||
// Max consecutive sub immediate value
|
||||
return 2048 / 8;
|
||||
#else
|
||||
// No AOT on IA32
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
intptr_t DispatchTable::LargestSmallOffset() {
|
||||
#if defined(TARGET_ARCH_X64)
|
||||
// Origin + Max positive byte offset / 8
|
||||
return 31;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
// Origin + Max positive load offset / 4
|
||||
return 2046;
|
||||
#elif defined(TARGET_ARCH_ARM64)
|
||||
// Origin + Max consecutive add immediate value
|
||||
return 8192;
|
||||
#elif defined(TARGET_ARCH_RISCV32)
|
||||
// Origin + Max consecutive add immediate value
|
||||
return 4096 / 4;
|
||||
#elif defined(TARGET_ARCH_RISCV64)
|
||||
// Origin + Max consecutive add immediate value
|
||||
return 4096 / 8;
|
||||
#else
|
||||
// No AOT on IA32
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
const uword* DispatchTable::ArrayOrigin() const {
|
||||
return &array_.get()[OriginElement()];
|
||||
return &array_.get()[kOriginElement];
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
|
|
@ -20,8 +20,45 @@ class DispatchTable {
|
|||
|
||||
// The element of the dispatch table array to which the dispatch table
|
||||
// register points.
|
||||
static intptr_t OriginElement();
|
||||
static intptr_t LargestSmallOffset();
|
||||
#if defined(TARGET_ARCH_X64)
|
||||
// Max negative byte offset / 8
|
||||
static constexpr intptr_t kOriginElement = 16;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
// Max negative load offset / 4
|
||||
static constexpr intptr_t kOriginElement = 1023;
|
||||
#elif defined(TARGET_ARCH_ARM64)
|
||||
// Max consecutive sub immediate value
|
||||
static constexpr intptr_t kOriginElement = 4096;
|
||||
#elif defined(TARGET_ARCH_RISCV32)
|
||||
// Max consecutive sub immediate value
|
||||
static constexpr intptr_t kOriginElement = 2048 / 4;
|
||||
#elif defined(TARGET_ARCH_RISCV64)
|
||||
// Max consecutive sub immediate value
|
||||
static constexpr intptr_t kOriginElement = 2048 / 8;
|
||||
#else
|
||||
static constexpr intptr_t kOriginElement = 0;
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_ARCH_X64)
|
||||
// Origin + Max positive byte offset / 8
|
||||
static constexpr intptr_t kLargestSmallOffset = 31;
|
||||
#elif defined(TARGET_ARCH_ARM)
|
||||
// Origin + Max positive load offset / 4
|
||||
static constexpr intptr_t kLargestSmallOffset = 2046;
|
||||
#elif defined(TARGET_ARCH_ARM64)
|
||||
// Origin + Max consecutive add immediate value
|
||||
static constexpr intptr_t kLargestSmallOffset = 8192;
|
||||
#elif defined(TARGET_ARCH_RISCV32)
|
||||
// Origin + Max consecutive add immediate value
|
||||
static constexpr intptr_t kLargestSmallOffset = 4096 / 4;
|
||||
#elif defined(TARGET_ARCH_RISCV64)
|
||||
// Origin + Max consecutive add immediate value
|
||||
static constexpr intptr_t kLargestSmallOffset = 4096 / 8;
|
||||
#else
|
||||
// No AOT on IA32
|
||||
static constexpr intptr_t kLargestSmallOffset = 0;
|
||||
#endif
|
||||
|
||||
// Dispatch table array pointer to put into the dispatch table register.
|
||||
const uword* ArrayOrigin() const;
|
||||
|
||||
|
|
Loading…
Reference in a new issue