Commit 146c9708 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[code] Make metadata offsets relative to metadata section

This CL makes the metadata offsets stored in Code headers
relative to the start of the metadata section (instead of to
the start of the instructions section).

In a follow-up, metadata for embedded builtins will be moved
from the .text section (with r-x or --x permissions) to the
.rodata section (with r-- permissions).

Drive-by: Simplify invariants around section alignment. A
new invariant is that the end of the instruction section is
aligned to Code::kMetadataAlignment.
Drive-by: Ensure trampoline Code objects contain no metadata
(metadata offsets all refer to the off-heap metadata section).

Tbr: dinfuehr@chromium.org
Bug: v8:11036
Change-Id: Idd0980913bbde9d3d1946b558e3ca58ec6356fcc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2491036Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70788}
parent c20ff735
...@@ -335,7 +335,8 @@ class OffHeapTrampolineGenerator { ...@@ -335,7 +335,8 @@ class OffHeapTrampolineGenerator {
public: public:
explicit OffHeapTrampolineGenerator(Isolate* isolate) explicit OffHeapTrampolineGenerator(Isolate* isolate)
: isolate_(isolate), : isolate_(isolate),
masm_(isolate, CodeObjectRequired::kYes, masm_(isolate, AssemblerOptions::DefaultForOffHeapTrampoline(isolate),
CodeObjectRequired::kYes,
ExternalAssemblerBuffer(buffer_, kBufferSize)) {} ExternalAssemblerBuffer(buffer_, kBufferSize)) {}
CodeDesc Generate(Address off_heap_entry, TrampolineType type) { CodeDesc Generate(Address off_heap_entry, TrampolineType type) {
...@@ -347,6 +348,7 @@ class OffHeapTrampolineGenerator { ...@@ -347,6 +348,7 @@ class OffHeapTrampolineGenerator {
masm_.CodeEntry(); masm_.CodeEntry();
masm_.JumpToInstructionStream(off_heap_entry); masm_.JumpToInstructionStream(off_heap_entry);
} else { } else {
DCHECK_EQ(type, TrampolineType::kAbort);
masm_.Trap(); masm_.Trap();
} }
} }
......
...@@ -552,6 +552,15 @@ Assembler::~Assembler() { DCHECK_EQ(const_pool_blocked_nesting_, 0); } ...@@ -552,6 +552,15 @@ Assembler::~Assembler() { DCHECK_EQ(const_pool_blocked_nesting_, 0); }
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
// Emit constant pool if necessary. // Emit constant pool if necessary.
CheckConstPool(true, false); CheckConstPool(true, false);
DCHECK(pending_32_bit_constants_.empty()); DCHECK(pending_32_bit_constants_.empty());
......
...@@ -372,6 +372,15 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) { ...@@ -372,6 +372,15 @@ void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
// Emit constant pool if necessary. // Emit constant pool if necessary.
ForceConstantPoolEmissionWithoutJump(); ForceConstantPoolEmissionWithoutJump();
DCHECK(constpool_.IsEmpty()); DCHECK(constpool_.IsEmpty());
...@@ -403,7 +412,9 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, ...@@ -403,7 +412,9 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
} }
void Assembler::Align(int m) { void Assembler::Align(int m) {
DCHECK(m >= 4 && base::bits::IsPowerOfTwo(m)); // If not, the loop below won't terminate.
DCHECK(IsAligned(pc_offset(), kInstrSize));
DCHECK(m >= kInstrSize && base::bits::IsPowerOfTwo(m));
while ((pc_offset() & (m - 1)) != 0) { while ((pc_offset() & (m - 1)) != 0) {
nop(); nop();
} }
......
...@@ -76,6 +76,15 @@ AssemblerOptions AssemblerOptions::Default(Isolate* isolate) { ...@@ -76,6 +76,15 @@ AssemblerOptions AssemblerOptions::Default(Isolate* isolate) {
return options; return options;
} }
AssemblerOptions AssemblerOptions::DefaultForOffHeapTrampoline(
Isolate* isolate) {
AssemblerOptions options = AssemblerOptions::Default(isolate);
// Off-heap trampolines may not contain any metadata since their metadata
// offsets refer to the off-heap metadata area.
options.emit_code_comments = false;
return options;
}
namespace { namespace {
class DefaultAssemblerBuffer : public AssemblerBuffer { class DefaultAssemblerBuffer : public AssemblerBuffer {
...@@ -255,7 +264,9 @@ Handle<HeapObject> AssemblerBase::GetEmbeddedObject( ...@@ -255,7 +264,9 @@ Handle<HeapObject> AssemblerBase::GetEmbeddedObject(
int Assembler::WriteCodeComments() { int Assembler::WriteCodeComments() {
if (!FLAG_code_comments || code_comments_writer_.entry_count() == 0) return 0; CHECK_IMPLIES(code_comments_writer_.entry_count() > 0,
options().emit_code_comments);
if (code_comments_writer_.entry_count() == 0) return 0;
int offset = pc_offset(); int offset = pc_offset();
code_comments_writer_.Emit(this); code_comments_writer_.Emit(this);
int size = pc_offset() - offset; int size = pc_offset() - offset;
......
...@@ -180,8 +180,11 @@ struct V8_EXPORT_PRIVATE AssemblerOptions { ...@@ -180,8 +180,11 @@ struct V8_EXPORT_PRIVATE AssemblerOptions {
// info. This is useful in some platform (Win64) where the unwind info depends // info. This is useful in some platform (Win64) where the unwind info depends
// on a function prologue/epilogue. // on a function prologue/epilogue.
bool collect_win64_unwind_info = false; bool collect_win64_unwind_info = false;
// Whether to emit code comments.
bool emit_code_comments = FLAG_code_comments;
static AssemblerOptions Default(Isolate* isolate); static AssemblerOptions Default(Isolate* isolate);
static AssemblerOptions DefaultForOffHeapTrampoline(Isolate* isolate);
}; };
class AssemblerBuffer { class AssemblerBuffer {
...@@ -280,7 +283,7 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced { ...@@ -280,7 +283,7 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced {
// Record an inline code comment that can be used by a disassembler. // Record an inline code comment that can be used by a disassembler.
// Use --code-comments to enable. // Use --code-comments to enable.
void RecordComment(const char* msg) { void RecordComment(const char* msg) {
if (FLAG_code_comments) { if (options().emit_code_comments) {
code_comments_writer_.Add(pc_offset(), std::string(msg)); code_comments_writer_.Add(pc_offset(), std::string(msg));
} }
} }
......
...@@ -67,6 +67,18 @@ class CodeDesc { ...@@ -67,6 +67,18 @@ class CodeDesc {
int body_size() const { return instr_size + unwinding_info_size; } int body_size() const { return instr_size + unwinding_info_size; }
int instruction_size() const { return safepoint_table_offset; } int instruction_size() const { return safepoint_table_offset; }
int metadata_size() const { return body_size() - instruction_size(); } int metadata_size() const { return body_size() - instruction_size(); }
int safepoint_table_offset_relative() const {
return safepoint_table_offset - instruction_size();
}
int handler_table_offset_relative() const {
return handler_table_offset - instruction_size();
}
int constant_pool_offset_relative() const {
return constant_pool_offset - instruction_size();
}
int code_comments_offset_relative() const {
return code_comments_offset - instruction_size();
}
// Relocation info is located at the end of the buffer and not part of the // Relocation info is located at the end of the buffer and not part of the
// instructions area. // instructions area.
...@@ -75,14 +87,13 @@ class CodeDesc { ...@@ -75,14 +87,13 @@ class CodeDesc {
int reloc_size = 0; int reloc_size = 0;
// Unwinding information. // Unwinding information.
// TODO(jgruber): Pack this into the inlined metadata section.
byte* unwinding_info = nullptr; byte* unwinding_info = nullptr;
int unwinding_info_size = 0; int unwinding_info_size = 0;
int unwinding_info_offset() const { int unwinding_info_offset_relative() const {
// TODO(jgruber,v8:11036): Remove this function once unwinding_info setup // TODO(jgruber,v8:11036): Remove this function once unwinding_info setup
// is more consistent with other metadata tables. // is more consistent with other metadata tables.
return code_comments_offset + code_comments_size; return code_comments_offset_relative() + code_comments_size;
} }
Assembler* origin = nullptr; Assembler* origin = nullptr;
......
...@@ -142,7 +142,7 @@ int HandlerTable::LengthForRange(int entries) { ...@@ -142,7 +142,7 @@ int HandlerTable::LengthForRange(int entries) {
// static // static
int HandlerTable::EmitReturnTableStart(Assembler* masm) { int HandlerTable::EmitReturnTableStart(Assembler* masm) {
masm->DataAlign(sizeof(int32_t)); // Make sure entries are aligned. masm->DataAlign(Code::kMetadataAlignment);
masm->RecordComment(";;; Exception handler table."); masm->RecordComment(";;; Exception handler table.");
int table_start = masm->pc_offset(); int table_start = masm->pc_offset();
return table_start; return table_start;
......
...@@ -302,6 +302,15 @@ Assembler::Assembler(const AssemblerOptions& options, ...@@ -302,6 +302,15 @@ Assembler::Assembler(const AssemblerOptions& options,
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
const int code_comments_size = WriteCodeComments(); const int code_comments_size = WriteCodeComments();
// Finalize code (at this point overflow() may be true, but the gap ensures // Finalize code (at this point overflow() may be true, but the gap ensures
......
...@@ -307,6 +307,15 @@ Assembler::Assembler(const AssemblerOptions& options, ...@@ -307,6 +307,15 @@ Assembler::Assembler(const AssemblerOptions& options,
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
EmitForbiddenSlotInstruction(); EmitForbiddenSlotInstruction();
int code_comments_size = WriteCodeComments(); int code_comments_size = WriteCodeComments();
......
...@@ -283,6 +283,15 @@ Assembler::Assembler(const AssemblerOptions& options, ...@@ -283,6 +283,15 @@ Assembler::Assembler(const AssemblerOptions& options,
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
EmitForbiddenSlotInstruction(); EmitForbiddenSlotInstruction();
int code_comments_size = WriteCodeComments(); int code_comments_size = WriteCodeComments();
......
...@@ -248,6 +248,15 @@ Assembler::Assembler(const AssemblerOptions& options, ...@@ -248,6 +248,15 @@ Assembler::Assembler(const AssemblerOptions& options,
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
// Emit constant pool if necessary. // Emit constant pool if necessary.
int constant_pool_size = EmitConstantPool(); int constant_pool_size = EmitConstantPool();
......
...@@ -370,6 +370,15 @@ Assembler::Assembler(const AssemblerOptions& options, ...@@ -370,6 +370,15 @@ Assembler::Assembler(const AssemblerOptions& options,
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
EmitRelocations(); EmitRelocations();
int code_comments_size = WriteCodeComments(); int code_comments_size = WriteCodeComments();
......
...@@ -120,7 +120,7 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) { ...@@ -120,7 +120,7 @@ void SafepointTableBuilder::Emit(Assembler* assembler, int bits_per_entry) {
RemoveDuplicates(); RemoveDuplicates();
// Make sure the safepoint table is properly aligned. Pad with nops. // Make sure the safepoint table is properly aligned. Pad with nops.
assembler->Align(kIntSize); assembler->Align(Code::kMetadataAlignment);
assembler->RecordComment(";;; Safepoint table."); assembler->RecordComment(";;; Safepoint table.");
offset_ = assembler->pc_offset(); offset_ = assembler->pc_offset();
......
...@@ -332,6 +332,15 @@ Assembler::Assembler(const AssemblerOptions& options, ...@@ -332,6 +332,15 @@ Assembler::Assembler(const AssemblerOptions& options,
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc, void Assembler::GetCode(Isolate* isolate, CodeDesc* desc,
SafepointTableBuilder* safepoint_table_builder, SafepointTableBuilder* safepoint_table_builder,
int handler_table_offset) { int handler_table_offset) {
// As a crutch to avoid having to add manual Align calls wherever we use a
// raw workflow to create Code objects (mostly in tests), add another Align
// call here. It does no harm - the end of the Code object is aligned to the
// (larger) kCodeAlignment anyways.
// TODO(jgruber): Consider moving responsibility for proper alignment to
// metadata table builders (safepoint, handler, constant pool, code
// comments).
DataAlign(Code::kMetadataAlignment);
PatchConstPool(); PatchConstPool();
DCHECK(constpool_.IsEmpty()); DCHECK(constpool_.IsEmpty());
......
...@@ -393,6 +393,9 @@ void CodeGenerator::AssembleCode() { ...@@ -393,6 +393,9 @@ void CodeGenerator::AssembleCode() {
// size as reported by perf. // size as reported by perf.
unwinding_info_writer_.Finish(tasm()->pc_offset()); unwinding_info_writer_.Finish(tasm()->pc_offset());
// Final alignment before starting on the metadata section.
tasm()->Align(Code::kMetadataAlignment);
safepoints()->Emit(tasm(), frame()->GetTotalFrameSlotCount()); safepoints()->Emit(tasm(), frame()->GetTotalFrameSlotCount());
// Emit the exception handler table. // Emit the exception handler table.
......
...@@ -948,14 +948,16 @@ void CodeDataContainer::CodeDataContainerVerify(Isolate* isolate) { ...@@ -948,14 +948,16 @@ void CodeDataContainer::CodeDataContainerVerify(Isolate* isolate) {
} }
void Code::CodeVerify(Isolate* isolate) { void Code::CodeVerify(Isolate* isolate) {
CHECK_IMPLIES( CHECK(IsAligned(InstructionSize(),
has_safepoint_table(), static_cast<unsigned>(Code::kMetadataAlignment)));
IsAligned(safepoint_table_offset(), static_cast<unsigned>(kIntSize))); CHECK_EQ(safepoint_table_offset(), 0);
CHECK_LE(safepoint_table_offset(), handler_table_offset()); CHECK_LE(safepoint_table_offset(), handler_table_offset());
CHECK_LE(handler_table_offset(), constant_pool_offset()); CHECK_LE(handler_table_offset(), constant_pool_offset());
CHECK_LE(constant_pool_offset(), code_comments_offset()); CHECK_LE(constant_pool_offset(), code_comments_offset());
CHECK_LE(code_comments_offset(), unwinding_info_offset()); CHECK_LE(code_comments_offset(), unwinding_info_offset());
CHECK_LE(unwinding_info_offset(), BodySize()); CHECK_LE(unwinding_info_offset(), MetadataSize());
CHECK_IMPLIES(!ReadOnlyHeap::Contains(*this),
IsAligned(InstructionStart(), kCodeAlignment));
CHECK_IMPLIES(!ReadOnlyHeap::Contains(*this), CHECK_IMPLIES(!ReadOnlyHeap::Contains(*this),
IsAligned(raw_instruction_start(), kCodeAlignment)); IsAligned(raw_instruction_start(), kCodeAlignment));
// TODO(delphick): Refactor Factory::CodeBuilder::BuildInternal, so that the // TODO(delphick): Refactor Factory::CodeBuilder::BuildInternal, so that the
......
...@@ -233,14 +233,11 @@ void PerfJitLogger::LogRecordedBuffer( ...@@ -233,14 +233,11 @@ void PerfJitLogger::LogRecordedBuffer(
const char* code_name = name; const char* code_name = name;
uint8_t* code_pointer = reinterpret_cast<uint8_t*>(code->InstructionStart()); uint8_t* code_pointer = reinterpret_cast<uint8_t*>(code->InstructionStart());
// Code generated by Turbofan will have the safepoint table directly after
// instructions. There is no need to record the safepoint table itself.
uint32_t code_size = code->ExecutableInstructionSize();
// Unwinding info comes right after debug info. // Unwinding info comes right after debug info.
if (FLAG_perf_prof_unwinding_info) LogWriteUnwindingInfo(*code); if (FLAG_perf_prof_unwinding_info) LogWriteUnwindingInfo(*code);
WriteJitCodeLoadEntry(code_pointer, code_size, code_name, length); WriteJitCodeLoadEntry(code_pointer, code->InstructionSize(), code_name,
length);
} }
void PerfJitLogger::LogRecordedBuffer(const wasm::WasmCode* code, void PerfJitLogger::LogRecordedBuffer(const wasm::WasmCode* code,
......
...@@ -167,10 +167,11 @@ MaybeHandle<Code> Factory::CodeBuilder::BuildInternal( ...@@ -167,10 +167,11 @@ MaybeHandle<Code> Factory::CodeBuilder::BuildInternal(
code->set_code_data_container(*data_container, kReleaseStore); code->set_code_data_container(*data_container, kReleaseStore);
code->set_deoptimization_data(*deoptimization_data_); code->set_deoptimization_data(*deoptimization_data_);
code->set_source_position_table(*source_position_table_); code->set_source_position_table(*source_position_table_);
code->set_handler_table_offset(code_desc_.handler_table_offset); code->set_handler_table_offset(code_desc_.handler_table_offset_relative());
code->set_constant_pool_offset(code_desc_.constant_pool_offset); code->set_constant_pool_offset(code_desc_.constant_pool_offset_relative());
code->set_code_comments_offset(code_desc_.code_comments_offset); code->set_code_comments_offset(code_desc_.code_comments_offset_relative());
code->set_unwinding_info_offset(code_desc_.unwinding_info_offset()); code->set_unwinding_info_offset(
code_desc_.unwinding_info_offset_relative());
// Allow self references to created code object by patching the handle to // Allow self references to created code object by patching the handle to
// point to the newly allocated Code object. // point to the newly allocated Code object.
......
...@@ -297,13 +297,6 @@ int Code::MetadataSize() const { ...@@ -297,13 +297,6 @@ int Code::MetadataSize() const {
: raw_metadata_size(); : raw_metadata_size();
} }
int Code::safepoint_table_offset() const {
// TODO(jgruber,v8:11036): Update once embedded instructions and metadata are
// separate.
STATIC_ASSERT(kBodyIsContiguous);
return InstructionSize();
}
int Code::SizeIncludingMetadata() const { int Code::SizeIncludingMetadata() const {
int size = CodeSize(); int size = CodeSize();
size += relocation_info().Size(); size += relocation_info().Size();
...@@ -560,21 +553,21 @@ int Code::constant_pool_offset() const { ...@@ -560,21 +553,21 @@ int Code::constant_pool_offset() const {
void Code::set_constant_pool_offset(int value) { void Code::set_constant_pool_offset(int value) {
if (!FLAG_enable_embedded_constant_pool) return; if (!FLAG_enable_embedded_constant_pool) return;
DCHECK_LE(value, BodySize()); DCHECK_LE(value, MetadataSize());
WriteField<int>(kConstantPoolOffsetOffset, value); WriteField<int>(kConstantPoolOffsetOffset, value);
} }
Address Code::constant_pool() const { Address Code::constant_pool() const {
if (!has_constant_pool()) return kNullAddress; if (!has_constant_pool()) return kNullAddress;
return InstructionStart() + constant_pool_offset(); return MetadataStart() + constant_pool_offset();
} }
Address Code::code_comments() const { Address Code::code_comments() const {
return InstructionStart() + code_comments_offset(); return MetadataStart() + code_comments_offset();
} }
Address Code::unwinding_info_start() const { Address Code::unwinding_info_start() const {
return InstructionStart() + unwinding_info_offset(); return MetadataStart() + unwinding_info_offset();
} }
Address Code::unwinding_info_end() const { return MetadataEnd(); } Address Code::unwinding_info_end() const { return MetadataEnd(); }
......
...@@ -31,7 +31,7 @@ namespace v8 { ...@@ -31,7 +31,7 @@ namespace v8 {
namespace internal { namespace internal {
Address Code::SafepointTableAddress() const { Address Code::SafepointTableAddress() const {
return InstructionStart() + safepoint_table_offset(); return MetadataStart() + safepoint_table_offset();
} }
int Code::safepoint_table_size() const { int Code::safepoint_table_size() const {
...@@ -42,7 +42,7 @@ int Code::safepoint_table_size() const { ...@@ -42,7 +42,7 @@ int Code::safepoint_table_size() const {
bool Code::has_safepoint_table() const { return safepoint_table_size() > 0; } bool Code::has_safepoint_table() const { return safepoint_table_size() > 0; }
Address Code::HandlerTableAddress() const { Address Code::HandlerTableAddress() const {
return InstructionStart() + handler_table_offset(); return MetadataStart() + handler_table_offset();
} }
int Code::handler_table_size() const { int Code::handler_table_size() const {
...@@ -68,8 +68,6 @@ int Code::code_comments_size() const { ...@@ -68,8 +68,6 @@ int Code::code_comments_size() const {
bool Code::has_code_comments() const { return code_comments_size() > 0; } bool Code::has_code_comments() const { return code_comments_size() > 0; }
int Code::ExecutableInstructionSize() const { return safepoint_table_offset(); }
void Code::ClearEmbeddedObjects(Heap* heap) { void Code::ClearEmbeddedObjects(Heap* heap) {
HeapObject undefined = ReadOnlyRoots(heap).undefined_value(); HeapObject undefined = ReadOnlyRoots(heap).undefined_value();
int mode_mask = RelocInfo::EmbeddedObjectModeMask(); int mode_mask = RelocInfo::EmbeddedObjectModeMask();
...@@ -706,8 +704,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate, ...@@ -706,8 +704,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate,
} }
{ {
// Stop before reaching any embedded tables int code_size = InstructionSize();
int code_size = ExecutableInstructionSize();
os << "Instructions (size = " << code_size << ")\n"; os << "Instructions (size = " << code_size << ")\n";
DisassembleCodeRange(isolate, os, *this, InstructionStart(), code_size, DisassembleCodeRange(isolate, os, *this, InstructionStart(), code_size,
current_pc); current_pc);
...@@ -716,8 +713,8 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate, ...@@ -716,8 +713,8 @@ void Code::Disassemble(const char* name, std::ostream& os, Isolate* isolate,
DCHECK_EQ(pool_size & kPointerAlignmentMask, 0); DCHECK_EQ(pool_size & kPointerAlignmentMask, 0);
os << "\nConstant Pool (size = " << pool_size << ")\n"; os << "\nConstant Pool (size = " << pool_size << ")\n";
Vector<char> buf = Vector<char>::New(50); Vector<char> buf = Vector<char>::New(50);
intptr_t* ptr = reinterpret_cast<intptr_t*>(InstructionStart() + intptr_t* ptr =
constant_pool_offset()); reinterpret_cast<intptr_t*>(MetadataStart() + constant_pool_offset());
for (int i = 0; i < pool_size; i += kSystemPointerSize, ptr++) { for (int i = 0; i < pool_size; i += kSystemPointerSize, ptr++) {
SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr); SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
os << static_cast<const void*>(ptr) << " " << buf.begin() << "\n"; os << static_cast<const void*>(ptr) << " " << buf.begin() << "\n";
......
...@@ -84,16 +84,16 @@ class Code : public HeapObject { ...@@ -84,16 +84,16 @@ class Code : public HeapObject {
// | header | // | header |
// | padded to code alignment | // | padded to code alignment |
// +--------------------------+ <-- raw_body_start() // +--------------------------+ <-- raw_body_start()
// | instructions | == raw_instruction_start() (IS) // | instructions | == raw_instruction_start()
// | ... | // | ... |
// | padded to meta alignment | see kMetadataAlignment
// +--------------------------+ <-- raw_instruction_end() // +--------------------------+ <-- raw_instruction_end()
// | metadata | == raw_metadata_start() // | metadata | == raw_metadata_start() (MS)
// | ... | == IS + safepoint_table_offset() // | ... |
// | | // | | <-- MS + handler_table_offset()
// | | <-- IS + handler_table_offset() // | | <-- MS + constant_pool_offset()
// | | <-- IS + constant_pool_offset() // | | <-- MS + code_comments_offset()
// | | <-- IS + code_comments_offset() // | | <-- MS + unwinding_info_offset()
// | | <-- IS + unwinding_info_offset()
// | padded to obj alignment | // | padded to obj alignment |
// +--------------------------+ <-- raw_metadata_end() == raw_body_end() // +--------------------------+ <-- raw_metadata_end() == raw_body_end()
// | padded to code alignment | // | padded to code alignment |
...@@ -137,7 +137,7 @@ class Code : public HeapObject { ...@@ -137,7 +137,7 @@ class Code : public HeapObject {
inline Address raw_metadata_start() const; inline Address raw_metadata_start() const;
inline Address MetadataStart() const; inline Address MetadataStart() const;
Address OffHeapMetadataStart() const; V8_EXPORT_PRIVATE Address OffHeapMetadataStart() const;
inline Address raw_metadata_end() const; inline Address raw_metadata_end() const;
inline Address MetadataEnd() const; inline Address MetadataEnd() const;
V8_EXPORT_PRIVATE Address OffHeapMetadataEnd() const; V8_EXPORT_PRIVATE Address OffHeapMetadataEnd() const;
...@@ -146,18 +146,18 @@ class Code : public HeapObject { ...@@ -146,18 +146,18 @@ class Code : public HeapObject {
inline int MetadataSize() const; inline int MetadataSize() const;
int OffHeapMetadataSize() const; int OffHeapMetadataSize() const;
// TODO(jgruber,v8:11036): Change all these offsets to be relative to // The metadata section is aligned to this value.
// MetadataStart instead of InstructionStart. static constexpr int kMetadataAlignment = kIntSize;
// [safepoint_table_offset]: If {has_safepoint_info()}, the offset in the // [safepoint_table_offset]: If {has_safepoint_info()}, the offset where the
// instruction stream where the safepoint table starts. // safepoint table starts.
inline int safepoint_table_offset() const; inline int safepoint_table_offset() const { return 0; }
Address SafepointTableAddress() const; Address SafepointTableAddress() const;
int safepoint_table_size() const; int safepoint_table_size() const;
bool has_safepoint_table() const; bool has_safepoint_table() const;
// [handler_table_offset]: The offset in the instruction stream where the // [handler_table_offset]: The offset where the exception handler table
// exception handler table starts. // starts.
inline int handler_table_offset() const; inline int handler_table_offset() const;
inline void set_handler_table_offset(int offset); inline void set_handler_table_offset(int offset);
Address HandlerTableAddress() const; Address HandlerTableAddress() const;
...@@ -263,9 +263,6 @@ class Code : public HeapObject { ...@@ -263,9 +263,6 @@ class Code : public HeapObject {
// reserved in the code prologue. // reserved in the code prologue.
inline int stack_slots() const; inline int stack_slots() const;
// The size of the executable instruction area, without embedded metadata.
int ExecutableInstructionSize() const;
// [marked_for_deoptimization]: If CodeKindCanDeoptimize(kind), tells whether // [marked_for_deoptimization]: If CodeKindCanDeoptimize(kind), tells whether
// the code is going to be deoptimized. // the code is going to be deoptimized.
inline bool marked_for_deoptimization() const; inline bool marked_for_deoptimization() const;
...@@ -405,31 +402,30 @@ class Code : public HeapObject { ...@@ -405,31 +402,30 @@ class Code : public HeapObject {
class OptimizedCodeIterator; class OptimizedCodeIterator;
// Layout description. // Layout description.
#define CODE_FIELDS(V) \ #define CODE_FIELDS(V) \
V(kRelocationInfoOffset, kTaggedSize) \ V(kRelocationInfoOffset, kTaggedSize) \
V(kDeoptimizationDataOffset, kTaggedSize) \ V(kDeoptimizationDataOffset, kTaggedSize) \
V(kSourcePositionTableOffset, kTaggedSize) \ V(kSourcePositionTableOffset, kTaggedSize) \
V(kCodeDataContainerOffset, kTaggedSize) \ V(kCodeDataContainerOffset, kTaggedSize) \
/* Data or code not directly visited by GC directly starts here. */ \ /* Data or code not directly visited by GC directly starts here. */ \
/* The serializer needs to copy bytes starting from here verbatim. */ \ /* The serializer needs to copy bytes starting from here verbatim. */ \
/* Objects embedded into code is visited via reloc info. */ \ /* Objects embedded into code is visited via reloc info. */ \
V(kDataStart, 0) \ V(kDataStart, 0) \
V(kInstructionSizeOffset, kIntSize) \ V(kInstructionSizeOffset, kIntSize) \
V(kMetadataSizeOffset, kIntSize) \ V(kMetadataSizeOffset, kIntSize) \
V(kFlagsOffset, kInt32Size) \ V(kFlagsOffset, kInt32Size) \
V(kBuiltinIndexOffset, kIntSize) \ V(kBuiltinIndexOffset, kIntSize) \
V(kInlinedBytecodeSizeOffset, kIntSize) \ V(kInlinedBytecodeSizeOffset, kIntSize) \
/* Offsets describing inline metadata tables, relative to */ \ /* Offsets describing inline metadata tables, relative to MetadataStart. */ \
/* InstructionStart. */ \ V(kHandlerTableOffsetOffset, kIntSize) \
V(kHandlerTableOffsetOffset, kIntSize) \ V(kConstantPoolOffsetOffset, \
V(kConstantPoolOffsetOffset, \ FLAG_enable_embedded_constant_pool ? kIntSize : 0) \
FLAG_enable_embedded_constant_pool ? kIntSize : 0) \ V(kCodeCommentsOffsetOffset, kIntSize) \
V(kCodeCommentsOffsetOffset, kIntSize) \ V(kUnwindingInfoOffsetOffset, kInt32Size) \
V(kUnwindingInfoOffsetOffset, kInt32Size) \ V(kUnalignedHeaderSize, 0) \
V(kUnalignedHeaderSize, 0) \ /* Add padding to align the instruction start following right after */ \
/* Add padding to align the instruction start following right after */ \ /* the Code object header. */ \
/* the Code object header. */ \ V(kOptionalPaddingOffset, CODE_POINTER_PADDING(kOptionalPaddingOffset)) \
V(kOptionalPaddingOffset, CODE_POINTER_PADDING(kOptionalPaddingOffset)) \
V(kHeaderSize, 0) V(kHeaderSize, 0)
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, CODE_FIELDS) DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, CODE_FIELDS)
......
...@@ -519,9 +519,7 @@ int LiftoffAssembler::GetTotalFrameSlotCountForGC() const { ...@@ -519,9 +519,7 @@ int LiftoffAssembler::GetTotalFrameSlotCountForGC() const {
namespace { namespace {
constexpr AssemblerOptions DefaultLiftoffOptions() { AssemblerOptions DefaultLiftoffOptions() { return AssemblerOptions{}; }
return AssemblerOptions{};
}
} // namespace } // namespace
......
...@@ -901,14 +901,18 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) { ...@@ -901,14 +901,18 @@ WasmCode* NativeModule::AddCodeForTesting(Handle<Code> code) {
static_cast<size_t>(code->BodySize())); static_cast<size_t>(code->BodySize()));
const int stack_slots = code->has_safepoint_info() ? code->stack_slots() : 0; const int stack_slots = code->has_safepoint_info() ? code->stack_slots() : 0;
// Metadata offsets in Code objects are relative to the start of the metadata
// section, whereas WasmCode expects offsets relative to InstructionStart.
const int base_offset = code->InstructionSize();
// TODO(jgruber,v8:8758): Remove this translation. It exists only because // TODO(jgruber,v8:8758): Remove this translation. It exists only because
// Code objects contains real offsets but WasmCode expects an offset of 0 to // Code objects contains real offsets but WasmCode expects an offset of 0 to
// mean 'empty'. // mean 'empty'.
const int safepoint_table_offset = const int safepoint_table_offset =
code->has_safepoint_table() ? code->safepoint_table_offset() : 0; code->has_safepoint_table() ? base_offset + code->safepoint_table_offset()
const int handler_table_offset = code->handler_table_offset(); : 0;
const int constant_pool_offset = code->constant_pool_offset(); const int handler_table_offset = base_offset + code->handler_table_offset();
const int code_comments_offset = code->code_comments_offset(); const int constant_pool_offset = base_offset + code->constant_pool_offset();
const int code_comments_offset = base_offset + code->code_comments_offset();
Vector<uint8_t> dst_code_bytes = Vector<uint8_t> dst_code_bytes =
code_allocator_.AllocateForCode(this, instructions.size()); code_allocator_.AllocateForCode(this, instructions.size());
......
...@@ -14,9 +14,9 @@ TEST(CodeLayoutWithoutUnwindingInfo) { ...@@ -14,9 +14,9 @@ TEST(CodeLayoutWithoutUnwindingInfo) {
CcTest::InitializeVM(); CcTest::InitializeVM();
HandleScope handle_scope(CcTest::i_isolate()); HandleScope handle_scope(CcTest::i_isolate());
// "Hello, World!" in ASCII. // "Hello, World!" in ASCII, padded to kCodeAlignment.
byte buffer_array[13] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, byte buffer_array[16] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x57,
0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21}; 0x6F, 0x72, 0x6C, 0x64, 0x21, 0xcc, 0xcc, 0xcc};
byte* buffer = &buffer_array[0]; byte* buffer = &buffer_array[0];
int buffer_size = sizeof(buffer_array); int buffer_size = sizeof(buffer_array);
...@@ -55,9 +55,9 @@ TEST(CodeLayoutWithUnwindingInfo) { ...@@ -55,9 +55,9 @@ TEST(CodeLayoutWithUnwindingInfo) {
CcTest::InitializeVM(); CcTest::InitializeVM();
HandleScope handle_scope(CcTest::i_isolate()); HandleScope handle_scope(CcTest::i_isolate());
// "Hello, World!" in ASCII. // "Hello, World!" in ASCII, padded to kCodeAlignment.
byte buffer_array[13] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, byte buffer_array[16] = {0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x57,
0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21}; 0x6F, 0x72, 0x6C, 0x64, 0x21, 0xcc, 0xcc, 0xcc};
// "JavaScript" in ASCII. // "JavaScript" in ASCII.
byte unwinding_info_array[10] = {0x4A, 0x61, 0x76, 0x61, 0x53, byte unwinding_info_array[10] = {0x4A, 0x61, 0x76, 0x61, 0x53,
......
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