Commit 19eb7234 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[arm64] Ensure pools are emitted before emitting large branch tables

Change-Id: Iedb78a62886177f5c603b2f3ce9b586ac1320d31
Bug: chromium:968078
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1664067Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62244}
parent fd074f9a
......@@ -4418,7 +4418,7 @@ bool Assembler::ShouldEmitVeneer(int max_reachable_pc, size_t margin) {
}
void Assembler::RecordVeneerPool(int location_offset, int size) {
Assembler::BlockPoolsScope block_pools(this);
Assembler::BlockPoolsScope block_pools(this, PoolEmissionCheck::kSkip);
RelocInfo rinfo(reinterpret_cast<Address>(buffer_start_) + location_offset,
RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), Code());
reloc_info_writer.Write(&rinfo);
......@@ -4426,7 +4426,7 @@ void Assembler::RecordVeneerPool(int location_offset, int size) {
void Assembler::EmitVeneers(bool force_emit, bool need_protection,
size_t margin) {
BlockPoolsScope scope(this, ConstantPool::PoolEmissionCheck::kSkip);
BlockPoolsScope scope(this, PoolEmissionCheck::kSkip);
RecordComment("[ Veneers");
// The exact size of the veneer pool must be recorded (see the comment at the
......
......@@ -2371,12 +2371,15 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
class BlockPoolsScope {
public:
explicit BlockPoolsScope(Assembler* assem)
: assem_(assem), block_const_pool_(assem) {
// Block veneer and constant pool. Emits pools if necessary to ensure that
// {margin} more bytes can be emitted without triggering pool emission.
explicit BlockPoolsScope(Assembler* assem, size_t margin = 0)
: assem_(assem), block_const_pool_(assem, margin) {
assem_->CheckVeneerPool(false, true, margin);
assem_->StartBlockVeneerPool();
}
BlockPoolsScope(Assembler* assem, ConstantPool::PoolEmissionCheck check)
BlockPoolsScope(Assembler* assem, PoolEmissionCheck check)
: assem_(assem), block_const_pool_(assem, check) {
assem_->StartBlockVeneerPool();
}
......
......@@ -235,6 +235,7 @@ enum class Jump { kOmitted, kRequired };
enum class Emission { kIfNeeded, kForced };
enum class Alignment { kOmitted, kRequired };
enum class RelocInfoStatus { kMustRecord, kMustOmitForDuplicate };
enum class PoolEmissionCheck { kSkip };
// Pools are emitted in the instruction stream, preferably after unconditional
// jumps or after returns from functions (in dead code locations).
......@@ -279,7 +280,6 @@ class ConstantPool {
void SetNextCheckIn(size_t instructions);
// Class for scoping postponing the constant pool generation.
enum class PoolEmissionCheck { kSkip };
class V8_EXPORT_PRIVATE BlockScope {
public:
// BlockScope immediatelly emits the pool if necessary to ensure that
......
......@@ -2401,7 +2401,8 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ Add(temp, temp, Operand(input, UXTW, 2));
__ Br(temp);
{
TurboAssembler::BlockPoolsScope block_pools(tasm());
TurboAssembler::BlockPoolsScope block_pools(tasm(),
case_count * kInstrSize);
__ Bind(&table);
for (size_t index = 0; index < case_count; ++index) {
__ B(GetLabel(i.InputRpo(index + 2)));
......
// Copyright 2019 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.
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-module-builder.js");
(function() {
function repeat(value, length) {
var arr = new Array(length);
for (let i = 0; i < length; i++) {
arr[i] = value;
}
return arr;
}
function br_table(block_index, length, def_block) {
const bytes = new Binary();
bytes.emit_bytes([kExprBrTable]);
// Functions count (different than the count in the functions section.
bytes.emit_u32v(length);
bytes.emit_bytes(repeat(block_index, length));
bytes.emit_bytes([def_block]);
return Array.from(bytes.trunc_buffer());
}
var builder = new WasmModuleBuilder();
builder.addMemory(12, 12, false);
builder.addFunction("foo", kSig_v_iii)
.addBody([].concat([
kExprBlock, kWasmStmt,
kExprGetLocal, 0x2,
kExprI32Const, 0x01,
kExprI32And,
// Generate a test branch (which has 32k limited reach).
kExprIf, kWasmStmt,
kExprGetLocal, 0x0,
kExprI32Const, 0x01,
kExprI32And,
kExprBrIf, 0x1,
kExprGetLocal, 0x0,
// Emit a br_table that is long enough to make the test branch go out of range.
], br_table(0x1, 9000, 0x00), [
kExprEnd,
kExprEnd,
])).exportFunc();
builder.instantiate();
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment