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) { ...@@ -4418,7 +4418,7 @@ bool Assembler::ShouldEmitVeneer(int max_reachable_pc, size_t margin) {
} }
void Assembler::RecordVeneerPool(int location_offset, int size) { 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 rinfo(reinterpret_cast<Address>(buffer_start_) + location_offset,
RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), Code()); RelocInfo::VENEER_POOL, static_cast<intptr_t>(size), Code());
reloc_info_writer.Write(&rinfo); reloc_info_writer.Write(&rinfo);
...@@ -4426,7 +4426,7 @@ void Assembler::RecordVeneerPool(int location_offset, int size) { ...@@ -4426,7 +4426,7 @@ void Assembler::RecordVeneerPool(int location_offset, int size) {
void Assembler::EmitVeneers(bool force_emit, bool need_protection, void Assembler::EmitVeneers(bool force_emit, bool need_protection,
size_t margin) { size_t margin) {
BlockPoolsScope scope(this, ConstantPool::PoolEmissionCheck::kSkip); BlockPoolsScope scope(this, PoolEmissionCheck::kSkip);
RecordComment("[ Veneers"); RecordComment("[ Veneers");
// The exact size of the veneer pool must be recorded (see the comment at the // 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 { ...@@ -2371,12 +2371,15 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
class BlockPoolsScope { class BlockPoolsScope {
public: public:
explicit BlockPoolsScope(Assembler* assem) // Block veneer and constant pool. Emits pools if necessary to ensure that
: assem_(assem), block_const_pool_(assem) { // {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(); assem_->StartBlockVeneerPool();
} }
BlockPoolsScope(Assembler* assem, ConstantPool::PoolEmissionCheck check) BlockPoolsScope(Assembler* assem, PoolEmissionCheck check)
: assem_(assem), block_const_pool_(assem, check) { : assem_(assem), block_const_pool_(assem, check) {
assem_->StartBlockVeneerPool(); assem_->StartBlockVeneerPool();
} }
......
...@@ -235,6 +235,7 @@ enum class Jump { kOmitted, kRequired }; ...@@ -235,6 +235,7 @@ enum class Jump { kOmitted, kRequired };
enum class Emission { kIfNeeded, kForced }; enum class Emission { kIfNeeded, kForced };
enum class Alignment { kOmitted, kRequired }; enum class Alignment { kOmitted, kRequired };
enum class RelocInfoStatus { kMustRecord, kMustOmitForDuplicate }; enum class RelocInfoStatus { kMustRecord, kMustOmitForDuplicate };
enum class PoolEmissionCheck { kSkip };
// Pools are emitted in the instruction stream, preferably after unconditional // Pools are emitted in the instruction stream, preferably after unconditional
// jumps or after returns from functions (in dead code locations). // jumps or after returns from functions (in dead code locations).
...@@ -279,7 +280,6 @@ class ConstantPool { ...@@ -279,7 +280,6 @@ class ConstantPool {
void SetNextCheckIn(size_t instructions); void SetNextCheckIn(size_t instructions);
// Class for scoping postponing the constant pool generation. // Class for scoping postponing the constant pool generation.
enum class PoolEmissionCheck { kSkip };
class V8_EXPORT_PRIVATE BlockScope { class V8_EXPORT_PRIVATE BlockScope {
public: public:
// BlockScope immediatelly emits the pool if necessary to ensure that // BlockScope immediatelly emits the pool if necessary to ensure that
......
...@@ -2401,7 +2401,8 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) { ...@@ -2401,7 +2401,8 @@ void CodeGenerator::AssembleArchTableSwitch(Instruction* instr) {
__ Add(temp, temp, Operand(input, UXTW, 2)); __ Add(temp, temp, Operand(input, UXTW, 2));
__ Br(temp); __ Br(temp);
{ {
TurboAssembler::BlockPoolsScope block_pools(tasm()); TurboAssembler::BlockPoolsScope block_pools(tasm(),
case_count * kInstrSize);
__ Bind(&table); __ Bind(&table);
for (size_t index = 0; index < case_count; ++index) { for (size_t index = 0; index < case_count; ++index) {
__ B(GetLabel(i.InputRpo(index + 2))); __ 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