Commit 1857b217 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

Add Code helper methods for inlined metadata

This adds Code::has_foo() and Code::foo_size() helpers for inlined
metadata sections (currently: the safepoint table, handler table,
constant pool, and code comments). Prior to this, each call site had
to know implementation details of the instruction area layout.

Bug: v8:8758
Change-Id: I9dc391992a4bf709ee403beab8606d85540dc1be
Reviewed-on: https://chromium-review.googlesource.com/c/1451838
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59357}
parent dc15a1ee
......@@ -1113,7 +1113,7 @@ Script JavaScriptFrame::script() const {
int JavaScriptFrame::LookupExceptionHandlerInTable(
int* stack_depth, HandlerTable::CatchPrediction* prediction) {
DCHECK_EQ(0, LookupCode()->handler_table_offset());
DCHECK(!LookupCode()->has_handler_table());
DCHECK(!LookupCode()->is_optimized_code());
return -1;
}
......
......@@ -1683,7 +1683,7 @@ Object Isolate::UnwindAndFindHandler() {
StubFrame* stub_frame = static_cast<StubFrame*>(frame);
Code code = stub_frame->LookupCode();
if (!code->IsCode() || code->kind() != Code::BUILTIN ||
!code->handler_table_offset() || !code->is_turbofanned()) {
!code->has_handler_table() || !code->is_turbofanned()) {
break;
}
......@@ -1874,7 +1874,7 @@ Isolate::CatchType Isolate::PredictExceptionCatcher() {
case StackFrame::STUB: {
Handle<Code> code(frame->LookupCode(), this);
if (!code->IsCode() || code->kind() != Code::BUILTIN ||
!code->handler_table_offset() || !code->is_turbofanned()) {
!code->has_handler_table() || !code->is_turbofanned()) {
break;
}
......@@ -2465,7 +2465,7 @@ Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
} else if (frame->type() == StackFrame::STUB) {
Code code = frame->LookupCode();
if (!code->IsCode() || code->kind() != Code::BUILTIN ||
!code->handler_table_offset() || !code->is_turbofanned()) {
!code->has_handler_table() || !code->is_turbofanned()) {
continue;
}
catch_prediction = code->GetBuiltinCatchPrediction();
......
......@@ -1202,6 +1202,9 @@ void CodeDataContainer::CodeDataContainerVerify(Isolate* isolate) {
}
void Code::CodeVerify(Isolate* isolate) {
// TODO(v8:8758): Should be <= handler_table_offset once we have real offsets.
CHECK_LE(safepoint_table_offset(), constant_pool_offset());
CHECK_LE(handler_table_offset(), constant_pool_offset());
CHECK_LE(constant_pool_offset(), code_comments_offset());
CHECK_LE(code_comments_offset(), InstructionSize());
CHECK(IsAligned(raw_instruction_start(), kCodeAlignment));
......
......@@ -5385,6 +5385,46 @@ void ObjectVisitor::VisitRelocInfo(RelocIterator* it) {
}
}
int Code::safepoint_table_size() const {
if (safepoint_table_offset() == 0) return 0;
const int end_offset = handler_table_offset() != 0 ? handler_table_offset()
: constant_pool_offset();
DCHECK_GE(end_offset - safepoint_table_offset(), 0);
return end_offset - safepoint_table_offset();
}
bool Code::has_safepoint_table() const { return safepoint_table_size() > 0; }
int Code::handler_table_size() const {
if (handler_table_offset() == 0) return 0;
DCHECK_GE(constant_pool_offset() - handler_table_offset(), 0);
return constant_pool_offset() - handler_table_offset();
}
bool Code::has_handler_table() const { return handler_table_size() > 0; }
int Code::constant_pool_size() const {
const int size = code_comments_offset() - constant_pool_offset();
DCHECK_IMPLIES(!FLAG_enable_embedded_constant_pool, size == 0);
return size;
}
bool Code::has_constant_pool() const { return constant_pool_size() > 0; }
int Code::code_comments_size() const {
DCHECK_GE(InstructionSize() - code_comments_offset(), 0);
return InstructionSize() - code_comments_offset();
}
bool Code::has_code_comments() const { return code_comments_size() > 0; }
int Code::ExecutableInstructionSize() const {
return safepoint_table_offset() != 0
? safepoint_table_offset()
: (handler_table_offset() != 0 ? handler_table_offset()
: constant_pool_offset());
}
void Code::ClearEmbeddedObjects(Heap* heap) {
HeapObject undefined = ReadOnlyRoots(heap).undefined_value();
int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
......@@ -5992,16 +6032,8 @@ void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) {
}
{
int size = InstructionSize();
int safepoint_offset =
has_safepoint_info() ? safepoint_table_offset() : size;
int const_pool_offset = constant_pool_offset();
int handler_offset = handler_table_offset() ? handler_table_offset() : size;
int comments_offset = code_comments_offset();
// Stop before reaching any embedded tables
int code_size = std::min(
{handler_offset, safepoint_offset, const_pool_offset, comments_offset});
int code_size = ExecutableInstructionSize();
os << "Instructions (size = " << code_size << ")\n";
DisassembleCodeRange(isolate, os, *this, InstructionStart(), code_size,
current_pc);
......@@ -6010,8 +6042,8 @@ void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) {
DCHECK_EQ(pool_size & kPointerAlignmentMask, 0);
os << "\nConstant Pool (size = " << pool_size << ")\n";
Vector<char> buf = Vector<char>::New(50);
intptr_t* ptr =
reinterpret_cast<intptr_t*>(InstructionStart() + const_pool_offset);
intptr_t* ptr = reinterpret_cast<intptr_t*>(InstructionStart() +
constant_pool_offset());
for (int i = 0; i < pool_size; i += kSystemPointerSize, ptr++) {
SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
os << static_cast<const void*>(ptr) << " " << buf.start() << "\n";
......@@ -6080,7 +6112,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) {
os << "\n";
}
if (handler_table_offset() > 0) {
if (has_handler_table()) {
HandlerTable table(*this);
os << "Handler Table (size = " << table.NumberOfReturnEntries() << ")\n";
if (kind() == OPTIMIZED_FUNCTION) {
......@@ -6104,7 +6136,7 @@ void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) {
os << "\n";
}
if (code_comments_offset() < InstructionSize()) {
if (has_code_comments()) {
PrintCodeCommentsSection(os, code_comments());
}
}
......
......@@ -483,7 +483,6 @@ int Code::stack_slots() const {
}
int Code::safepoint_table_offset() const {
DCHECK(has_safepoint_info());
return READ_INT32_FIELD(this, kSafepointTableOffsetOffset);
}
......@@ -550,18 +549,9 @@ void Code::set_constant_pool_offset(int value) {
WRITE_INT_FIELD(this, kConstantPoolOffset, value);
}
int Code::constant_pool_size() const {
if (!FLAG_enable_embedded_constant_pool) return 0;
return code_comments_offset() - constant_pool_offset();
}
Address Code::constant_pool() const {
if (FLAG_enable_embedded_constant_pool) {
int offset = constant_pool_offset();
if (offset < code_comments_offset()) {
return InstructionStart() + offset;
}
}
return kNullAddress;
if (!has_constant_pool()) return kNullAddress;
return InstructionStart() + constant_pool_offset();
}
int Code::code_comments_offset() const {
......@@ -578,11 +568,8 @@ void Code::set_code_comments_offset(int offset) {
}
Address Code::code_comments() const {
int offset = code_comments_offset();
if (offset < InstructionSize()) {
return InstructionStart() + offset;
}
return kNullAddress;
if (!has_code_comments()) return kNullAddress;
return InstructionStart() + code_comments_offset();
}
Code Code::GetCodeFromTargetAddress(Address address) {
......
......@@ -70,8 +70,8 @@ class Code : public HeapObject {
// Returns the size of the native instructions, including embedded
// data such as the safepoints table. For off-heap code objects
// this may from instruction_size in that this will return the size of the
// off-heap instruction stream rather than the on-heap trampoline located
// this may differ from instruction_size in that this will return the size of
// the off-heap instruction stream rather than the on-heap trampoline located
// at instruction_start.
inline int InstructionSize() const;
int OffHeapInstructionSize() const;
......@@ -98,17 +98,6 @@ class Code : public HeapObject {
inline Object next_code_link() const;
inline void set_next_code_link(Object value);
// [constant_pool offset]: Offset of the constant pool.
// Valid for FLAG_enable_embedded_constant_pool only
inline int constant_pool_offset() const;
inline void set_constant_pool_offset(int offset);
inline int constant_pool_size() const;
// [code_comments_offset]: Offset of the code comment section.
inline int code_comments_offset() const;
inline void set_code_comments_offset(int offset);
inline Address code_comments() const;
// Unchecked accessors to be used during GC.
inline ByteArray unchecked_relocation_info() const;
......@@ -156,11 +145,32 @@ class Code : public HeapObject {
// instruction stream where the safepoint table starts.
inline int safepoint_table_offset() const;
inline void set_safepoint_table_offset(int offset);
int safepoint_table_size() const;
bool has_safepoint_table() const;
// [handler_table_offset]: The offset in the instruction stream where the
// exception handler table starts.
inline int handler_table_offset() const;
inline void set_handler_table_offset(int offset);
int handler_table_size() const;
bool has_handler_table() const;
// [constant_pool offset]: Offset of the constant pool.
// Valid for FLAG_enable_embedded_constant_pool only
inline int constant_pool_offset() const;
inline void set_constant_pool_offset(int offset);
int constant_pool_size() const;
bool has_constant_pool() const;
// [code_comments_offset]: Offset of the code comment section.
inline int code_comments_offset() const;
inline void set_code_comments_offset(int offset);
inline Address code_comments() const;
int code_comments_size() const;
bool has_code_comments() const;
// The size of the executable instruction area, without embedded metadata.
int ExecutableInstructionSize() const;
// [marked_for_deoptimization]: For kind OPTIMIZED_FUNCTION tells whether
// the code is going to be deoptimized.
......@@ -553,8 +563,8 @@ class AbstractCode : public HeapObject {
// Returns the size of the native instructions, including embedded
// data such as the safepoints table. For off-heap code objects
// this may from instruction_size in that this will return the size of the
// off-heap instruction stream rather than the on-heap trampoline located
// this may differ from instruction_size in that this will return the size of
// the off-heap instruction stream rather than the on-heap trampoline located
// at instruction_start.
inline int InstructionSize();
......
......@@ -225,10 +225,10 @@ void PerfJitLogger::LogRecordedBuffer(AbstractCode abstract_code,
const char* code_name = name;
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->is_turbofanned() ? code->safepoint_table_offset()
: code->InstructionSize();
uint32_t code_size = code->ExecutableInstructionSize();
// Unwinding info comes right after debug info.
if (FLAG_perf_prof_unwinding_info) LogWriteUnwindingInfo(code);
......
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