Commit 91f8a063 authored by eholk's avatar eholk Committed by Commit bot

[wasm] Move protected instruction info to RelocInfo

Previously this information was encoded in a FixedArray dangling off the
Code object. This extra field seems to be responsible for increased memory
usage, as seen in the linked bugs. In this change, we instead encode this
in the RelocInfo and remove the field from the Code object.

BUG= https://bugs.chromium.org/p/chromium/issues/detail?id=678583
BUG= https://bugs.chromium.org/p/chromium/issues/detail?id=671180
BUG= https://bugs.chromium.org/p/chromium/issues/detail?id=670733

Review-Url: https://codereview.chromium.org/2651833003
Cr-Commit-Position: refs/heads/master@{#42802}
parent bc570817
......@@ -477,7 +477,8 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
WriteData(rinfo->data());
} else if (RelocInfo::IsConstPool(rmode) ||
RelocInfo::IsVeneerPool(rmode) || RelocInfo::IsDeoptId(rmode) ||
RelocInfo::IsDeoptPosition(rmode)) {
RelocInfo::IsDeoptPosition(rmode) ||
RelocInfo::IsWasmProtectedLanding(rmode)) {
WriteIntData(static_cast<int>(rinfo->data()));
}
}
......@@ -626,7 +627,8 @@ void RelocIterator::next() {
} else if (RelocInfo::IsConstPool(rmode) ||
RelocInfo::IsVeneerPool(rmode) ||
RelocInfo::IsDeoptId(rmode) ||
RelocInfo::IsDeoptPosition(rmode)) {
RelocInfo::IsDeoptPosition(rmode) ||
RelocInfo::IsWasmProtectedLanding(rmode)) {
if (SetMode(rmode)) {
AdvanceReadInt();
return;
......@@ -771,6 +773,8 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
return "wasm global value reference";
case WASM_FUNCTION_TABLE_SIZE_REFERENCE:
return "wasm function table size reference";
case WASM_PROTECTED_INSTRUCTION_LANDING:
return "wasm protected instruction landing";
case NUMBER_OF_MODES:
case PC_JUMP:
UNREACHABLE();
......@@ -869,6 +873,8 @@ void RelocInfo::Verify(Isolate* isolate) {
case WASM_MEMORY_SIZE_REFERENCE:
case WASM_GLOBAL_REFERENCE:
case WASM_FUNCTION_TABLE_SIZE_REFERENCE:
case WASM_PROTECTED_INSTRUCTION_LANDING:
// TODO(eholk): make sure the protected instruction is in range.
case NONE32:
case NONE64:
break;
......
......@@ -324,6 +324,7 @@ class RelocInfo {
WASM_GLOBAL_REFERENCE,
WASM_MEMORY_SIZE_REFERENCE,
WASM_FUNCTION_TABLE_SIZE_REFERENCE,
WASM_PROTECTED_INSTRUCTION_LANDING,
CELL,
// Everything after runtime_entry (inclusive) is not GC'ed.
......@@ -474,6 +475,9 @@ class RelocInfo {
static inline bool IsWasmPtrReference(Mode mode) {
return mode == WASM_MEMORY_REFERENCE || mode == WASM_GLOBAL_REFERENCE;
}
static inline bool IsWasmProtectedLanding(Mode mode) {
return mode == WASM_PROTECTED_INSTRUCTION_LANDING;
}
static inline int ModeMask(Mode mode) { return 1 << mode; }
......
......@@ -33,10 +33,8 @@ class CodeGenerator::JumpTable final : public ZoneObject {
size_t const target_count_;
};
CodeGenerator::CodeGenerator(
Frame* frame, Linkage* linkage, InstructionSequence* code,
CompilationInfo* info,
ZoneVector<trap_handler::ProtectedInstructionData>* protected_instructions)
CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
InstructionSequence* code, CompilationInfo* info)
: frame_access_state_(nullptr),
linkage_(linkage),
code_(code),
......@@ -60,8 +58,7 @@ CodeGenerator::CodeGenerator(
osr_pc_offset_(-1),
optimized_out_literal_id_(-1),
source_position_table_builder_(code->zone(),
info->SourcePositionRecordingMode()),
protected_instructions_(protected_instructions) {
info->SourcePositionRecordingMode()) {
for (int i = 0; i < code->InstructionBlockCount(); ++i) {
new (&labels_[i]) Label;
}
......@@ -75,14 +72,6 @@ void CodeGenerator::CreateFrameAccessState(Frame* frame) {
frame_access_state_ = new (code()->zone()) FrameAccessState(frame);
}
void CodeGenerator::AddProtectedInstruction(int instr_offset,
int landing_offset) {
if (protected_instructions_ != nullptr) {
trap_handler::ProtectedInstructionData data = {instr_offset,
landing_offset};
protected_instructions_->emplace_back(data);
}
}
Handle<Code> CodeGenerator::GenerateCode() {
CompilationInfo* info = this->info();
......
......@@ -53,9 +53,7 @@ class InstructionOperandIterator {
class CodeGenerator final : public GapResolver::Assembler {
public:
explicit CodeGenerator(Frame* frame, Linkage* linkage,
InstructionSequence* code, CompilationInfo* info,
ZoneVector<trap_handler::ProtectedInstructionData>*
protected_instructions = nullptr);
InstructionSequence* code, CompilationInfo* info);
// Generate native code.
Handle<Code> GenerateCode();
......@@ -68,8 +66,6 @@ class CodeGenerator final : public GapResolver::Assembler {
Label* GetLabel(RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
void AddProtectedInstruction(int instr_offset, int landing_offset);
void AssembleSourcePosition(Instruction* instr);
void AssembleSourcePosition(SourcePosition source_position);
......@@ -291,7 +287,6 @@ class CodeGenerator final : public GapResolver::Assembler {
int osr_pc_offset_;
int optimized_out_literal_id_;
SourcePositionTableBuilder source_position_table_builder_;
ZoneVector<trap_handler::ProtectedInstructionData>* protected_instructions_;
};
} // namespace compiler
......
......@@ -1423,7 +1423,7 @@ struct GenerateCodePhase {
void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
CodeGenerator generator(data->frame(), linkage, data->sequence(),
data->info(), data->protected_instructions());
data->info());
data->set_code(generator.GenerateCode());
}
};
......
......@@ -4020,27 +4020,9 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() {
compile_ms);
}
Handle<FixedArray> protected_instructions = PackProtectedInstructions();
code->set_protected_instructions(*protected_instructions);
return code;
}
Handle<FixedArray> WasmCompilationUnit::PackProtectedInstructions() const {
const int num_instructions = static_cast<int>(protected_instructions_.size());
Handle<FixedArray> fn_protected = isolate_->factory()->NewFixedArray(
num_instructions * Code::kTrapDataSize, TENURED);
for (unsigned i = 0; i < protected_instructions_.size(); ++i) {
const trap_handler::ProtectedInstructionData& instruction =
protected_instructions_[i];
fn_protected->set(Code::kTrapDataSize * i + Code::kTrapCodeOffset,
Smi::FromInt(instruction.instr_offset));
fn_protected->set(Code::kTrapDataSize * i + Code::kTrapLandingOffset,
Smi::FromInt(instruction.landing_offset));
}
return fn_protected;
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -68,7 +68,6 @@ class WasmCompilationUnit final {
private:
SourcePositionTable* BuildGraphForWasmFunction(double* decode_ms);
Handle<FixedArray> PackProtectedInstructions() const;
wasm::ErrorThrower* thrower_;
Isolate* isolate_;
......
......@@ -280,9 +280,9 @@ class WasmOutOfLineTrap final : public OutOfLineCode {
// TODO(eholk): Refactor this method to take the code generator as a
// parameter.
void Generate() final {
int current_pc = __ pc_offset();
Address current_pc = __ pc();
gen_->AddProtectedInstruction(pc_, current_pc);
__ RecordProtectedInstruction(pc_, current_pc);
if (frame_elided_) {
__ EnterFrame(StackFrame::WASM_COMPILED);
......
......@@ -1680,7 +1680,6 @@ Handle<Code> Factory::NewCode(const CodeDesc& desc,
code->set_prologue_offset(prologue_offset);
code->set_constant_pool_offset(desc.instr_size - desc.constant_pool_size);
code->set_builtin_index(-1);
code->set_protected_instructions(*empty_fixed_array());
if (code->kind() == Code::OPTIMIZED_FUNCTION) {
code->set_marked_for_deoptimization(false);
......
......@@ -361,8 +361,6 @@ class Code::BodyDescriptor final : public BodyDescriptorBase {
STATIC_ASSERT(kSourcePositionTableOffset + kPointerSize ==
kTypeFeedbackInfoOffset);
STATIC_ASSERT(kTypeFeedbackInfoOffset + kPointerSize ==
kProtectedInstructionOffset);
STATIC_ASSERT(kProtectedInstructionOffset + kPointerSize ==
kNextCodeLinkOffset);
static bool IsValidSlot(HeapObject* obj, int offset) {
......
......@@ -6772,7 +6772,6 @@ CODE_ACCESSORS(relocation_info, ByteArray, kRelocationInfoOffset)
CODE_ACCESSORS(handler_table, FixedArray, kHandlerTableOffset)
CODE_ACCESSORS(deoptimization_data, FixedArray, kDeoptimizationDataOffset)
CODE_ACCESSORS(source_position_table, ByteArray, kSourcePositionTableOffset)
CODE_ACCESSORS(protected_instructions, FixedArray, kProtectedInstructionOffset)
CODE_ACCESSORS(raw_type_feedback_info, Object, kTypeFeedbackInfoOffset)
CODE_ACCESSORS(next_code_link, Object, kNextCodeLinkOffset)
#undef CODE_ACCESSORS
......@@ -6788,7 +6787,6 @@ void Code::WipeOutHeader() {
}
WRITE_FIELD(this, kNextCodeLinkOffset, NULL);
WRITE_FIELD(this, kGCMetadataOffset, NULL);
WRITE_FIELD(this, kProtectedInstructionOffset, NULL);
}
......@@ -6872,7 +6870,6 @@ int Code::SizeIncludingMetadata() {
size += deoptimization_data()->Size();
size += handler_table()->Size();
if (kind() == FUNCTION) size += source_position_table()->Size();
size += protected_instructions()->Size();
return size;
}
......
......@@ -5021,10 +5021,6 @@ class Code: public HeapObject {
// [source_position_table]: ByteArray for the source positions table.
DECL_ACCESSORS(source_position_table, ByteArray)
// [protected_instructions]: Fixed array containing protected instruction and
// corresponding landing pad offsets.
DECL_ACCESSORS(protected_instructions, FixedArray)
// [raw_type_feedback_info]: This field stores various things, depending on
// the kind of the code object.
// FUNCTION => type feedback information.
......@@ -5401,10 +5397,7 @@ class Code: public HeapObject {
// For FUNCTION kind, we store the type feedback info here.
static const int kTypeFeedbackInfoOffset =
kSourcePositionTableOffset + kPointerSize;
static const int kProtectedInstructionOffset =
kTypeFeedbackInfoOffset + kPointerSize;
static const int kNextCodeLinkOffset =
kProtectedInstructionOffset + kPointerSize;
static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
......
......@@ -11,12 +11,12 @@ namespace trap_handler {
struct ProtectedInstructionData {
// The offset of this instruction from the start of its code object.
int32_t instr_offset;
intptr_t instr_offset;
// The offset of the landing pad from the start of its code object.
//
// TODO(eholk): Using a single landing pad and store parameters here.
int32_t landing_offset;
intptr_t landing_offset;
};
} // namespace trap_handler
......
......@@ -1407,7 +1407,7 @@ class WasmInstanceBuilder {
//--------------------------------------------------------------------------
// Unpack and notify signal handler of protected instructions.
//--------------------------------------------------------------------------
{
if (FLAG_wasm_trap_handler) {
for (int i = 0; i < code_table->length(); ++i) {
Handle<Code> code = code_table->GetValueChecked<Code>(isolate_, i);
......@@ -1415,21 +1415,17 @@ class WasmInstanceBuilder {
continue;
}
FixedArray* protected_instructions = code->protected_instructions();
DCHECK(protected_instructions != nullptr);
const intptr_t base = reinterpret_cast<intptr_t>(code->entry());
Zone zone(isolate_->allocator(), "Wasm Module");
ZoneVector<trap_handler::ProtectedInstructionData> unpacked(&zone);
for (int i = 0; i < protected_instructions->length();
i += Code::kTrapDataSize) {
const int mode_mask =
RelocInfo::ModeMask(RelocInfo::WASM_PROTECTED_INSTRUCTION_LANDING);
for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
trap_handler::ProtectedInstructionData data;
data.instr_offset =
protected_instructions
->GetValueChecked<Smi>(isolate_, i + Code::kTrapCodeOffset)
->value();
data.instr_offset = it.rinfo()->data();
data.landing_offset =
protected_instructions
->GetValueChecked<Smi>(isolate_, i + Code::kTrapLandingOffset)
->value();
reinterpret_cast<intptr_t>(it.rinfo()->pc()) - base;
unpacked.emplace_back(data);
}
// TODO(eholk): Register the protected instruction information once the
......
......@@ -4664,6 +4664,14 @@ void Assembler::emit_sse_operand(XMMRegister dst) {
emit(0xD8 | dst.low_bits());
}
void Assembler::RecordProtectedInstruction(int pc_offset, byte* landing) {
EnsureSpace ensure_space(this);
RelocInfo rinfo(isolate(), landing,
RelocInfo::WASM_PROTECTED_INSTRUCTION_LANDING, pc_offset,
nullptr);
reloc_info_writer.Write(&rinfo);
}
void Assembler::db(uint8_t data) {
EnsureSpace ensure_space(this);
......
......@@ -2000,6 +2000,8 @@ class Assembler : public AssemblerBase {
UNREACHABLE();
}
void RecordProtectedInstruction(int pc_offset, byte* landing_offset);
// Writes a single word of data in the code stream.
// Used for inline tables, e.g., jump-tables.
void db(uint8_t data);
......
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