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