b55dd17f19
This is a reland of9c0a48580b
Original change's description: > Reland "Reland "[code-comments] Put code comments into the code object"" > > This is a reland ofed3d647284
> > This reland fixes that padding at the end of Wasm instruction streams > triggered asserts in the code printer. > > Original change's description: > > Reland "[code-comments] Put code comments into the code object" > > > > This is a reland ofe774cffe2b
> > > > This reland disables a test as v8:8548 is blocking it, which was > > broken by a recent CL. CQ did not catch this because the merge-base > > CQ used did not yet contain the CL that caused v8:8548. > > > > Original change's description: > > > [code-comments] Put code comments into the code object > > > > > > Code comments in the snapshot can now be enabled with gn > > > arg 'v8_enable_snapshot_code_comments' > > > > > > Bug: v8:7989 > > > Change-Id: I8bd00cafa63132d00d849394c311ba15e6b6daf3 > > > Reviewed-on: https://chromium-review.googlesource.com/c/1329173 > > > Commit-Queue: Sigurd Schneider <sigurds@chromium.org> > > > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > > > Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> > > > Reviewed-by: Michael Stanton <mvstanton@chromium.org> > > > Cr-Commit-Position: refs/heads/master@{#58020} > > > > TBR=mvstanton@chromium.org,mstarzinger@chromium.org,jgruber@chromium.org,tebbi@chromium.org > > > > Bug: v8:7989, v8:8548 > > Change-Id: I464fc897205fefdf2dfc2eadc54d699c4e08a0e9 > > Reviewed-on: https://chromium-review.googlesource.com/c/1361166 > > Reviewed-by: Sigurd Schneider <sigurds@chromium.org> > > Commit-Queue: Sigurd Schneider <sigurds@chromium.org> > > Cr-Commit-Position: refs/heads/master@{#58028} > > Bug: v8:7989, v8:8548 > Change-Id: I254f55ff687ad049f8d92b09331ed26a2bd05d7d > Reviewed-on: https://chromium-review.googlesource.com/c/1371784 > Commit-Queue: Sigurd Schneider <sigurds@chromium.org> > Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Cr-Commit-Position: refs/heads/master@{#58221} TBR=jgruber@chromium.org,mstarzinger@chromium.org Bug: v8:7989, v8:8548, v8:8593 Change-Id: I4f7ffc98e0281c7b744eb4a04ba0763896c7b59b Reviewed-on: https://chromium-review.googlesource.com/c/1375919 Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Cr-Commit-Position: refs/heads/master@{#58232}
213 lines
7.3 KiB
C++
213 lines
7.3 KiB
C++
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "src/constant-pool.h"
|
|
#include "src/assembler-inl.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
#if defined(V8_TARGET_ARCH_PPC)
|
|
|
|
ConstantPoolBuilder::ConstantPoolBuilder(int ptr_reach_bits,
|
|
int double_reach_bits) {
|
|
info_[ConstantPoolEntry::INTPTR].entries.reserve(64);
|
|
info_[ConstantPoolEntry::INTPTR].regular_reach_bits = ptr_reach_bits;
|
|
info_[ConstantPoolEntry::DOUBLE].regular_reach_bits = double_reach_bits;
|
|
}
|
|
|
|
ConstantPoolEntry::Access ConstantPoolBuilder::NextAccess(
|
|
ConstantPoolEntry::Type type) const {
|
|
const PerTypeEntryInfo& info = info_[type];
|
|
|
|
if (info.overflow()) return ConstantPoolEntry::OVERFLOWED;
|
|
|
|
int dbl_count = info_[ConstantPoolEntry::DOUBLE].regular_count;
|
|
int dbl_offset = dbl_count * kDoubleSize;
|
|
int ptr_count = info_[ConstantPoolEntry::INTPTR].regular_count;
|
|
int ptr_offset = ptr_count * kPointerSize + dbl_offset;
|
|
|
|
if (type == ConstantPoolEntry::DOUBLE) {
|
|
// Double overflow detection must take into account the reach for both types
|
|
int ptr_reach_bits = info_[ConstantPoolEntry::INTPTR].regular_reach_bits;
|
|
if (!is_uintn(dbl_offset, info.regular_reach_bits) ||
|
|
(ptr_count > 0 &&
|
|
!is_uintn(ptr_offset + kDoubleSize - kPointerSize, ptr_reach_bits))) {
|
|
return ConstantPoolEntry::OVERFLOWED;
|
|
}
|
|
} else {
|
|
DCHECK(type == ConstantPoolEntry::INTPTR);
|
|
if (!is_uintn(ptr_offset, info.regular_reach_bits)) {
|
|
return ConstantPoolEntry::OVERFLOWED;
|
|
}
|
|
}
|
|
|
|
return ConstantPoolEntry::REGULAR;
|
|
}
|
|
|
|
ConstantPoolEntry::Access ConstantPoolBuilder::AddEntry(
|
|
ConstantPoolEntry& entry, ConstantPoolEntry::Type type) {
|
|
DCHECK(!emitted_label_.is_bound());
|
|
PerTypeEntryInfo& info = info_[type];
|
|
const int entry_size = ConstantPoolEntry::size(type);
|
|
bool merged = false;
|
|
|
|
if (entry.sharing_ok()) {
|
|
// Try to merge entries
|
|
std::vector<ConstantPoolEntry>::iterator it = info.shared_entries.begin();
|
|
int end = static_cast<int>(info.shared_entries.size());
|
|
for (int i = 0; i < end; i++, it++) {
|
|
if ((entry_size == kPointerSize) ? entry.value() == it->value()
|
|
: entry.value64() == it->value64()) {
|
|
// Merge with found entry.
|
|
entry.set_merged_index(i);
|
|
merged = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// By definition, merged entries have regular access.
|
|
DCHECK(!merged || entry.merged_index() < info.regular_count);
|
|
ConstantPoolEntry::Access access =
|
|
(merged ? ConstantPoolEntry::REGULAR : NextAccess(type));
|
|
|
|
// Enforce an upper bound on search time by limiting the search to
|
|
// unique sharable entries which fit in the regular section.
|
|
if (entry.sharing_ok() && !merged && access == ConstantPoolEntry::REGULAR) {
|
|
info.shared_entries.push_back(entry);
|
|
} else {
|
|
info.entries.push_back(entry);
|
|
}
|
|
|
|
// We're done if we found a match or have already triggered the
|
|
// overflow state.
|
|
if (merged || info.overflow()) return access;
|
|
|
|
if (access == ConstantPoolEntry::REGULAR) {
|
|
info.regular_count++;
|
|
} else {
|
|
info.overflow_start = static_cast<int>(info.entries.size()) - 1;
|
|
}
|
|
|
|
return access;
|
|
}
|
|
|
|
void ConstantPoolBuilder::EmitSharedEntries(Assembler* assm,
|
|
ConstantPoolEntry::Type type) {
|
|
PerTypeEntryInfo& info = info_[type];
|
|
std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
|
|
const int entry_size = ConstantPoolEntry::size(type);
|
|
int base = emitted_label_.pos();
|
|
DCHECK_GT(base, 0);
|
|
int shared_end = static_cast<int>(shared_entries.size());
|
|
std::vector<ConstantPoolEntry>::iterator shared_it = shared_entries.begin();
|
|
for (int i = 0; i < shared_end; i++, shared_it++) {
|
|
int offset = assm->pc_offset() - base;
|
|
shared_it->set_offset(offset); // Save offset for merged entries.
|
|
if (entry_size == kPointerSize) {
|
|
assm->dp(shared_it->value());
|
|
} else {
|
|
assm->dq(shared_it->value64());
|
|
}
|
|
DCHECK(is_uintn(offset, info.regular_reach_bits));
|
|
|
|
// Patch load sequence with correct offset.
|
|
assm->PatchConstantPoolAccessInstruction(shared_it->position(), offset,
|
|
ConstantPoolEntry::REGULAR, type);
|
|
}
|
|
}
|
|
|
|
void ConstantPoolBuilder::EmitGroup(Assembler* assm,
|
|
ConstantPoolEntry::Access access,
|
|
ConstantPoolEntry::Type type) {
|
|
PerTypeEntryInfo& info = info_[type];
|
|
const bool overflow = info.overflow();
|
|
std::vector<ConstantPoolEntry>& entries = info.entries;
|
|
std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
|
|
const int entry_size = ConstantPoolEntry::size(type);
|
|
int base = emitted_label_.pos();
|
|
DCHECK_GT(base, 0);
|
|
int begin;
|
|
int end;
|
|
|
|
if (access == ConstantPoolEntry::REGULAR) {
|
|
// Emit any shared entries first
|
|
EmitSharedEntries(assm, type);
|
|
}
|
|
|
|
if (access == ConstantPoolEntry::REGULAR) {
|
|
begin = 0;
|
|
end = overflow ? info.overflow_start : static_cast<int>(entries.size());
|
|
} else {
|
|
DCHECK(access == ConstantPoolEntry::OVERFLOWED);
|
|
if (!overflow) return;
|
|
begin = info.overflow_start;
|
|
end = static_cast<int>(entries.size());
|
|
}
|
|
|
|
std::vector<ConstantPoolEntry>::iterator it = entries.begin();
|
|
if (begin > 0) std::advance(it, begin);
|
|
for (int i = begin; i < end; i++, it++) {
|
|
// Update constant pool if necessary and get the entry's offset.
|
|
int offset;
|
|
ConstantPoolEntry::Access entry_access;
|
|
if (!it->is_merged()) {
|
|
// Emit new entry
|
|
offset = assm->pc_offset() - base;
|
|
entry_access = access;
|
|
if (entry_size == kPointerSize) {
|
|
assm->dp(it->value());
|
|
} else {
|
|
assm->dq(it->value64());
|
|
}
|
|
} else {
|
|
// Retrieve offset from shared entry.
|
|
offset = shared_entries[it->merged_index()].offset();
|
|
entry_access = ConstantPoolEntry::REGULAR;
|
|
}
|
|
|
|
DCHECK(entry_access == ConstantPoolEntry::OVERFLOWED ||
|
|
is_uintn(offset, info.regular_reach_bits));
|
|
|
|
// Patch load sequence with correct offset.
|
|
assm->PatchConstantPoolAccessInstruction(it->position(), offset,
|
|
entry_access, type);
|
|
}
|
|
}
|
|
|
|
// Emit and return size of pool.
|
|
int ConstantPoolBuilder::Emit(Assembler* assm) {
|
|
bool emitted = emitted_label_.is_bound();
|
|
bool empty = IsEmpty();
|
|
|
|
if (!emitted) {
|
|
// Mark start of constant pool. Align if necessary.
|
|
if (!empty) assm->DataAlign(kDoubleSize);
|
|
assm->bind(&emitted_label_);
|
|
if (!empty) {
|
|
// Emit in groups based on access and type.
|
|
// Emit doubles first for alignment purposes.
|
|
EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::DOUBLE);
|
|
EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::INTPTR);
|
|
if (info_[ConstantPoolEntry::DOUBLE].overflow()) {
|
|
assm->DataAlign(kDoubleSize);
|
|
EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
|
|
ConstantPoolEntry::DOUBLE);
|
|
}
|
|
if (info_[ConstantPoolEntry::INTPTR].overflow()) {
|
|
EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
|
|
ConstantPoolEntry::INTPTR);
|
|
}
|
|
}
|
|
}
|
|
|
|
return !empty ? (assm->pc_offset() - emitted_label_.pos()) : 0;
|
|
}
|
|
|
|
#endif // defined(V8_TARGET_ARCH_PPC)
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|