diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-08-01 08:38:30 +0200 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-08-01 12:53:56 +0200 |
commit | 2dcc3665abf57c3607cebffdeeca062f5894885d (patch) | |
tree | 4f560748132edcfb4c22d6f967a7e80d23d7ea2c /deps/v8/src/codegen/constant-pool.cc | |
parent | 1ee47d550c6de132f06110aa13eceb7551d643b3 (diff) | |
download | node-new-2dcc3665abf57c3607cebffdeeca062f5894885d.tar.gz |
deps: update V8 to 7.6.303.28
PR-URL: https://github.com/nodejs/node/pull/28016
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Refael Ackermann (רפאל פלחי) <refack@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Diffstat (limited to 'deps/v8/src/codegen/constant-pool.cc')
-rw-r--r-- | deps/v8/src/codegen/constant-pool.cc | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/deps/v8/src/codegen/constant-pool.cc b/deps/v8/src/codegen/constant-pool.cc new file mode 100644 index 0000000000..613a142f24 --- /dev/null +++ b/deps/v8/src/codegen/constant-pool.cc @@ -0,0 +1,214 @@ +// 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/codegen/constant-pool.h" +#include "src/codegen/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 * kSystemPointerSize + 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 - kSystemPointerSize, + 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 == kSystemPointerSize) + ? 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 == kSystemPointerSize) { + 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 == kSystemPointerSize) { + 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 |