Commit c1af2821 authored by mythria's avatar mythria Committed by Commit bot

Adds support for collecting statistics about code and its metadata.

Adds an API to request the total size of code/bytecode and their associated
metadata in the heap. When requested, the code_space, old_space and
large_object_space  is scanned to find any code/bytecode array objects.
This could be slow and hence it should be used with caution.

BUG=v8:5019
LOG=N

Review-Url: https://codereview.chromium.org/1997363002
Cr-Commit-Position: refs/heads/master@{#36534}
parent 49411f5f
...@@ -5274,6 +5274,18 @@ class V8_EXPORT HeapObjectStatistics { ...@@ -5274,6 +5274,18 @@ class V8_EXPORT HeapObjectStatistics {
friend class Isolate; friend class Isolate;
}; };
class V8_EXPORT HeapCodeStatistics {
public:
HeapCodeStatistics();
size_t code_and_metadata_size() { return code_and_metadata_size_; }
size_t bytecode_and_metadata_size() { return bytecode_and_metadata_size_; }
private:
size_t code_and_metadata_size_;
size_t bytecode_and_metadata_size_;
friend class Isolate;
};
class RetainedObjectInfo; class RetainedObjectInfo;
...@@ -5805,6 +5817,15 @@ class V8_EXPORT Isolate { ...@@ -5805,6 +5817,15 @@ class V8_EXPORT Isolate {
bool GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics* object_statistics, bool GetHeapObjectStatisticsAtLastGC(HeapObjectStatistics* object_statistics,
size_t type_index); size_t type_index);
/**
* Get statistics about code and its metadata in the heap.
*
* \param object_statistics The HeapCodeStatistics object to fill in
* statistics of code, bytecode and their metadata.
* \returns true on success.
*/
bool GetHeapCodeAndMetadataStatistics(HeapCodeStatistics* object_statistics);
/** /**
* Get a call stack sample from the isolate. * Get a call stack sample from the isolate.
* \param state Execution state. * \param state Execution state.
......
...@@ -5511,6 +5511,8 @@ HeapObjectStatistics::HeapObjectStatistics() ...@@ -5511,6 +5511,8 @@ HeapObjectStatistics::HeapObjectStatistics()
object_count_(0), object_count_(0),
object_size_(0) {} object_size_(0) {}
HeapCodeStatistics::HeapCodeStatistics()
: code_and_metadata_size_(0), bytecode_and_metadata_size_(0) {}
bool v8::V8::InitializeICU(const char* icu_data_file) { bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file); return i::InitializeICU(icu_data_file);
...@@ -7465,6 +7467,18 @@ bool Isolate::GetHeapObjectStatisticsAtLastGC( ...@@ -7465,6 +7467,18 @@ bool Isolate::GetHeapObjectStatisticsAtLastGC(
return true; return true;
} }
bool Isolate::GetHeapCodeAndMetadataStatistics(
HeapCodeStatistics* code_statistics) {
if (!code_statistics) return false;
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->heap()->CollectCodeStatistics();
code_statistics->code_and_metadata_size_ = isolate->code_and_metadata_size();
code_statistics->bytecode_and_metadata_size_ =
isolate->bytecode_and_metadata_size();
return true;
}
void Isolate::GetStackSample(const RegisterState& state, void** frames, void Isolate::GetStackSample(const RegisterState& state, void** frames,
size_t frames_limit, SampleInfo* sample_info) { size_t frames_limit, SampleInfo* sample_info) {
......
...@@ -450,21 +450,10 @@ bool UseIgnition(CompilationInfo* info) { ...@@ -450,21 +450,10 @@ bool UseIgnition(CompilationInfo* info) {
} }
int CodeAndMetadataSize(CompilationInfo* info) { int CodeAndMetadataSize(CompilationInfo* info) {
int size = 0;
if (info->has_bytecode_array()) { if (info->has_bytecode_array()) {
Handle<BytecodeArray> bytecode_array = info->bytecode_array(); return info->bytecode_array()->SizeIncludingMetadata();
size += bytecode_array->BytecodeArraySize();
size += bytecode_array->constant_pool()->Size();
size += bytecode_array->handler_table()->Size();
size += bytecode_array->source_position_table()->Size();
} else {
Handle<Code> code = info->code();
size += code->CodeSize();
size += code->relocation_info()->Size();
size += code->deoptimization_data()->Size();
size += code->handler_table()->Size();
} }
return size; return info->code()->SizeIncludingMetadata();
} }
bool GenerateUnoptimizedCode(CompilationInfo* info) { bool GenerateUnoptimizedCode(CompilationInfo* info) {
......
...@@ -4459,6 +4459,15 @@ void Heap::MemoryPressureNotification(MemoryPressureLevel level, ...@@ -4459,6 +4459,15 @@ void Heap::MemoryPressureNotification(MemoryPressureLevel level,
} }
} }
void Heap::CollectCodeStatistics() {
PagedSpace::ResetCodeAndMetadataStatistics(isolate());
// We do not look for code in new space, or map space. If code
// somehow ends up in those spaces, we would miss it here.
code_space_->CollectCodeStatistics();
old_space_->CollectCodeStatistics();
lo_space_->CollectCodeStatistics();
}
#ifdef DEBUG #ifdef DEBUG
void Heap::Print() { void Heap::Print() {
...@@ -4473,11 +4482,7 @@ void Heap::Print() { ...@@ -4473,11 +4482,7 @@ void Heap::Print() {
void Heap::ReportCodeStatistics(const char* title) { void Heap::ReportCodeStatistics(const char* title) {
PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title); PrintF(">>>>>> Code Stats (%s) >>>>>>\n", title);
PagedSpace::ResetCodeStatistics(isolate()); CollectCodeStatistics();
// We do not look for code in new space, map space, or old space. If code
// somehow ends up in those spaces, we would miss it here.
code_space_->CollectCodeStatistics();
lo_space_->CollectCodeStatistics();
PagedSpace::ReportCodeStatistics(isolate()); PagedSpace::ReportCodeStatistics(isolate());
} }
......
...@@ -1170,6 +1170,13 @@ class Heap { ...@@ -1170,6 +1170,13 @@ class Heap {
bool GetObjectTypeName(size_t index, const char** object_type, bool GetObjectTypeName(size_t index, const char** object_type,
const char** object_sub_type); const char** object_sub_type);
// ===========================================================================
// Code statistics. ==========================================================
// ===========================================================================
// Collect code (Code and BytecodeArray objects) statistics.
void CollectCodeStatistics();
// =========================================================================== // ===========================================================================
// GC statistics. ============================================================ // GC statistics. ============================================================
// =========================================================================== // ===========================================================================
......
...@@ -2025,7 +2025,6 @@ void SemiSpaceIterator::Initialize(Address start, Address end) { ...@@ -2025,7 +2025,6 @@ void SemiSpaceIterator::Initialize(Address start, Address end) {
limit_ = end; limit_ = end;
} }
#ifdef DEBUG #ifdef DEBUG
// heap_histograms is shared, always clear it before using it. // heap_histograms is shared, always clear it before using it.
static void ClearHistograms(Isolate* isolate) { static void ClearHistograms(Isolate* isolate) {
...@@ -2043,25 +2042,22 @@ static void ClearHistograms(Isolate* isolate) { ...@@ -2043,25 +2042,22 @@ static void ClearHistograms(Isolate* isolate) {
static void ClearCodeKindStatistics(int* code_kind_statistics) { static void ClearCodeKindStatistics(int* code_kind_statistics) {
for (int i = 0; i < Code::NUMBER_OF_KINDS; i++) { for (int i = 0; i < AbstractCode::NUMBER_OF_KINDS; i++) {
code_kind_statistics[i] = 0; code_kind_statistics[i] = 0;
} }
} }
static void ReportCodeKindStatistics(int* code_kind_statistics) { static void ReportCodeKindStatistics(int* code_kind_statistics) {
PrintF("\n Code kind histograms: \n"); PrintF("\n Code kind histograms: \n");
for (int i = 0; i < Code::NUMBER_OF_KINDS; i++) { for (int i = 0; i < AbstractCode::NUMBER_OF_KINDS; i++) {
if (code_kind_statistics[i] > 0) { if (code_kind_statistics[i] > 0) {
PrintF(" %-20s: %10d bytes\n", PrintF(" %-20s: %10d bytes\n",
Code::Kind2String(static_cast<Code::Kind>(i)), AbstractCode::Kind2String(static_cast<AbstractCode::Kind>(i)),
code_kind_statistics[i]); code_kind_statistics[i]);
} }
} }
PrintF("\n"); PrintF("\n");
} }
static int CollectHistogramInfo(HeapObject* obj) { static int CollectHistogramInfo(HeapObject* obj) {
Isolate* isolate = obj->GetIsolate(); Isolate* isolate = obj->GetIsolate();
InstanceType type = obj->map()->instance_type(); InstanceType type = obj->map()->instance_type();
...@@ -2758,12 +2754,15 @@ HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) { ...@@ -2758,12 +2754,15 @@ HeapObject* PagedSpace::SlowAllocateRaw(int size_in_bytes) {
return SweepAndRetryAllocation(size_in_bytes); return SweepAndRetryAllocation(size_in_bytes);
} }
#ifdef DEBUG #ifdef DEBUG
void PagedSpace::ReportCodeStatistics(Isolate* isolate) { void PagedSpace::ReportCodeStatistics(Isolate* isolate) {
CommentStatistic* comments_statistics = CommentStatistic* comments_statistics =
isolate->paged_space_comments_statistics(); isolate->paged_space_comments_statistics();
ReportCodeKindStatistics(isolate->code_kind_statistics()); ReportCodeKindStatistics(isolate->code_kind_statistics());
PrintF("Code size including metadata : %10d bytes\n",
isolate->code_and_metadata_size());
PrintF("Bytecode size including metadata: %10d bytes\n",
isolate->bytecode_and_metadata_size());
PrintF( PrintF(
"Code comment statistics (\" [ comment-txt : size/ " "Code comment statistics (\" [ comment-txt : size/ "
"count (average)\"):\n"); "count (average)\"):\n");
...@@ -2777,7 +2776,6 @@ void PagedSpace::ReportCodeStatistics(Isolate* isolate) { ...@@ -2777,7 +2776,6 @@ void PagedSpace::ReportCodeStatistics(Isolate* isolate) {
PrintF("\n"); PrintF("\n");
} }
void PagedSpace::ResetCodeStatistics(Isolate* isolate) { void PagedSpace::ResetCodeStatistics(Isolate* isolate) {
CommentStatistic* comments_statistics = CommentStatistic* comments_statistics =
isolate->paged_space_comments_statistics(); isolate->paged_space_comments_statistics();
...@@ -2853,40 +2851,28 @@ static void CollectCommentStatistics(Isolate* isolate, RelocIterator* it) { ...@@ -2853,40 +2851,28 @@ static void CollectCommentStatistics(Isolate* isolate, RelocIterator* it) {
EnterComment(isolate, comment_txt, flat_delta); EnterComment(isolate, comment_txt, flat_delta);
} }
// Collects code comment statistics
// Collects code size statistics: static void CollectCodeCommentStatistics(HeapObject* obj, Isolate* isolate) {
// - by code kind if (!obj->IsCode()) {
// - by code comment return;
void PagedSpace::CollectCodeStatistics() { }
Isolate* isolate = heap()->isolate(); Code* code = Code::cast(obj);
HeapObjectIterator obj_it(this); RelocIterator it(code);
for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) { int delta = 0;
if (obj->IsAbstractCode()) { const byte* prev_pc = code->instruction_start();
AbstractCode* code = AbstractCode::cast(obj); while (!it.done()) {
isolate->code_kind_statistics()[code->kind()] += code->Size(); if (it.rinfo()->rmode() == RelocInfo::COMMENT) {
} delta += static_cast<int>(it.rinfo()->pc() - prev_pc);
if (obj->IsCode()) { CollectCommentStatistics(isolate, &it);
// TODO(mythria): Also enable this for BytecodeArray when it supports prev_pc = it.rinfo()->pc();
// RelocInformation.
Code* code = Code::cast(obj);
RelocIterator it(code);
int delta = 0;
const byte* prev_pc = code->instruction_start();
while (!it.done()) {
if (it.rinfo()->rmode() == RelocInfo::COMMENT) {
delta += static_cast<int>(it.rinfo()->pc() - prev_pc);
CollectCommentStatistics(isolate, &it);
prev_pc = it.rinfo()->pc();
}
it.next();
}
DCHECK(code->instruction_start() <= prev_pc &&
prev_pc <= code->instruction_end());
delta += static_cast<int>(code->instruction_end() - prev_pc);
EnterComment(isolate, "NoComment", delta);
} }
it.next();
} }
DCHECK(code->instruction_start() <= prev_pc &&
prev_pc <= code->instruction_end());
delta += static_cast<int>(code->instruction_end() - prev_pc);
EnterComment(isolate, "NoComment", delta);
} }
...@@ -2907,6 +2893,44 @@ void PagedSpace::ReportStatistics() { ...@@ -2907,6 +2893,44 @@ void PagedSpace::ReportStatistics() {
} }
#endif #endif
static void RecordCodeSizeIncludingMetadata(AbstractCode* abstract_code,
Isolate* isolate) {
int size = abstract_code->SizeIncludingMetadata();
if (abstract_code->IsCode()) {
size += isolate->code_and_metadata_size();
isolate->set_code_and_metadata_size(size);
} else {
size += isolate->bytecode_and_metadata_size();
isolate->set_bytecode_and_metadata_size(size);
}
}
// Collects code size statistics:
// - code and metadata size
// - by code kind (only in debug mode)
// - by code comment (only in debug mode)
void PagedSpace::CollectCodeStatistics() {
Isolate* isolate = heap()->isolate();
HeapObjectIterator obj_it(this);
for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) {
if (obj->IsAbstractCode()) {
AbstractCode* code = AbstractCode::cast(obj);
RecordCodeSizeIncludingMetadata(code, isolate);
#ifdef DEBUG
isolate->code_kind_statistics()[code->kind()] += code->Size();
CollectCodeCommentStatistics(obj, isolate);
#endif
}
}
}
void PagedSpace::ResetCodeAndMetadataStatistics(Isolate* isolate) {
isolate->set_code_and_metadata_size(0);
isolate->set_bytecode_and_metadata_size(0);
#ifdef DEBUG
ResetCodeStatistics(isolate);
#endif
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// MapSpace implementation // MapSpace implementation
...@@ -3177,6 +3201,20 @@ void LargeObjectSpace::Verify() { ...@@ -3177,6 +3201,20 @@ void LargeObjectSpace::Verify() {
} }
#endif #endif
void LargeObjectSpace::CollectCodeStatistics() {
Isolate* isolate = heap()->isolate();
LargeObjectIterator obj_it(this);
for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) {
if (obj->IsAbstractCode()) {
AbstractCode* code = AbstractCode::cast(obj);
RecordCodeSizeIncludingMetadata(code, isolate);
#ifdef DEBUG
isolate->code_kind_statistics()[code->kind()] += code->Size();
CollectCodeCommentStatistics(obj, isolate);
#endif
}
}
}
#ifdef DEBUG #ifdef DEBUG
void LargeObjectSpace::Print() { void LargeObjectSpace::Print() {
...@@ -3206,18 +3244,6 @@ void LargeObjectSpace::ReportStatistics() { ...@@ -3206,18 +3244,6 @@ void LargeObjectSpace::ReportStatistics() {
} }
void LargeObjectSpace::CollectCodeStatistics() {
Isolate* isolate = heap()->isolate();
LargeObjectIterator obj_it(this);
for (HeapObject* obj = obj_it.Next(); obj != NULL; obj = obj_it.Next()) {
if (obj->IsAbstractCode()) {
AbstractCode* code = AbstractCode::cast(obj);
isolate->code_kind_statistics()[code->kind()] += code->Size();
}
}
}
void Page::Print() { void Page::Print() {
// Make a best-effort to print the objects in the page. // Make a best-effort to print the objects in the page.
PrintF("Page@%p in %s\n", static_cast<void*>(this->address()), PrintF("Page@%p in %s\n", static_cast<void*>(this->address()),
......
...@@ -2243,6 +2243,12 @@ class PagedSpace : public Space { ...@@ -2243,6 +2243,12 @@ class PagedSpace : public Space {
// The dummy page that anchors the linked list of pages. // The dummy page that anchors the linked list of pages.
Page* anchor() { return &anchor_; } Page* anchor() { return &anchor_; }
// Collect code size related statistics
void CollectCodeStatistics();
// Reset code size related statistics
static void ResetCodeAndMetadataStatistics(Isolate* isolate);
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
// Verify integrity of this space. // Verify integrity of this space.
virtual void Verify(ObjectVisitor* visitor); virtual void Verify(ObjectVisitor* visitor);
...@@ -2260,7 +2266,6 @@ class PagedSpace : public Space { ...@@ -2260,7 +2266,6 @@ class PagedSpace : public Space {
void ReportStatistics(); void ReportStatistics();
// Report code object related statistics // Report code object related statistics
void CollectCodeStatistics();
static void ReportCodeStatistics(Isolate* isolate); static void ReportCodeStatistics(Isolate* isolate);
static void ResetCodeStatistics(Isolate* isolate); static void ResetCodeStatistics(Isolate* isolate);
#endif #endif
...@@ -3068,6 +3073,9 @@ class LargeObjectSpace : public Space { ...@@ -3068,6 +3073,9 @@ class LargeObjectSpace : public Space {
LargePage* first_page() { return first_page_; } LargePage* first_page() { return first_page_; }
// Collect code statistics.
void CollectCodeStatistics();
#ifdef VERIFY_HEAP #ifdef VERIFY_HEAP
virtual void Verify(); virtual void Verify();
#endif #endif
...@@ -3075,7 +3083,6 @@ class LargeObjectSpace : public Space { ...@@ -3075,7 +3083,6 @@ class LargeObjectSpace : public Space {
#ifdef DEBUG #ifdef DEBUG
void Print() override; void Print() override;
void ReportStatistics(); void ReportStatistics();
void CollectCodeStatistics();
#endif #endif
private: private:
......
...@@ -372,10 +372,10 @@ class ThreadLocalTop BASE_EMBEDDED { ...@@ -372,10 +372,10 @@ class ThreadLocalTop BASE_EMBEDDED {
#ifdef DEBUG #ifdef DEBUG
#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V) \ #define ISOLATE_INIT_DEBUG_ARRAY_LIST(V) \
V(CommentStatistic, paged_space_comments_statistics, \ V(CommentStatistic, paged_space_comments_statistics, \
CommentStatistic::kMaxComments + 1) \ CommentStatistic::kMaxComments + 1) \
V(int, code_kind_statistics, Code::NUMBER_OF_KINDS) V(int, code_kind_statistics, AbstractCode::NUMBER_OF_KINDS)
#else #else
#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V) #define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
...@@ -418,6 +418,8 @@ typedef List<HeapObject*> DebugObjectCache; ...@@ -418,6 +418,8 @@ typedef List<HeapObject*> DebugObjectCache;
V(uint32_t, per_isolate_assert_data, 0xFFFFFFFFu) \ V(uint32_t, per_isolate_assert_data, 0xFFFFFFFFu) \
V(PromiseRejectCallback, promise_reject_callback, NULL) \ V(PromiseRejectCallback, promise_reject_callback, NULL) \
V(const v8::StartupData*, snapshot_blob, NULL) \ V(const v8::StartupData*, snapshot_blob, NULL) \
V(int, code_and_metadata_size, 0) \
V(int, bytecode_and_metadata_size, 0) \
ISOLATE_INIT_SIMULATOR_LIST(V) ISOLATE_INIT_SIMULATOR_LIST(V)
#define THREAD_LOCAL_TOP_ACCESSOR(type, name) \ #define THREAD_LOCAL_TOP_ACCESSOR(type, name) \
......
...@@ -1608,6 +1608,8 @@ void Logger::LogCodeObject(Object* object) { ...@@ -1608,6 +1608,8 @@ void Logger::LogCodeObject(Object* object) {
description = "A Wasm to JavaScript adapter"; description = "A Wasm to JavaScript adapter";
tag = Logger::STUB_TAG; tag = Logger::STUB_TAG;
break; break;
case AbstractCode::NUMBER_OF_KINDS:
UNIMPLEMENTED();
} }
PROFILE(isolate_, CodeCreateEvent(tag, code_object, description)); PROFILE(isolate_, CodeCreateEvent(tag, code_object, description));
} }
......
...@@ -4027,6 +4027,13 @@ Address BytecodeArray::GetFirstBytecodeAddress() { ...@@ -4027,6 +4027,13 @@ Address BytecodeArray::GetFirstBytecodeAddress() {
int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); } int BytecodeArray::BytecodeArraySize() { return SizeFor(this->length()); }
int BytecodeArray::SizeIncludingMetadata() {
int size = BytecodeArraySize();
size += constant_pool()->Size();
size += handler_table()->Size();
size += source_position_table()->Size();
return size;
}
ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset) ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
...@@ -5191,6 +5198,13 @@ int AbstractCode::instruction_size() { ...@@ -5191,6 +5198,13 @@ int AbstractCode::instruction_size() {
} }
} }
int AbstractCode::SizeIncludingMetadata() {
if (IsCode()) {
return GetCode()->SizeIncludingMetadata();
} else {
return GetBytecodeArray()->SizeIncludingMetadata();
}
}
int AbstractCode::ExecutableSize() { int AbstractCode::ExecutableSize() {
if (IsCode()) { if (IsCode()) {
return GetCode()->ExecutableSize(); return GetCode()->ExecutableSize();
...@@ -6415,6 +6429,13 @@ int Code::body_size() { ...@@ -6415,6 +6429,13 @@ int Code::body_size() {
return RoundUp(instruction_size(), kObjectAlignment); return RoundUp(instruction_size(), kObjectAlignment);
} }
int Code::SizeIncludingMetadata() {
int size = CodeSize();
size += relocation_info()->Size();
size += deoptimization_data()->Size();
size += handler_table()->Size();
return size;
}
ByteArray* Code::unchecked_relocation_info() { ByteArray* Code::unchecked_relocation_info() {
return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset)); return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
......
...@@ -13539,6 +13539,14 @@ const char* Code::Kind2String(Kind kind) { ...@@ -13539,6 +13539,14 @@ const char* Code::Kind2String(Kind kind) {
return NULL; return NULL;
} }
// Identify kind of code.
const char* AbstractCode::Kind2String(Kind kind) {
if (kind < AbstractCode::INTERPRETED_FUNCTION)
return Code::Kind2String((Code::Kind)kind);
if (kind == AbstractCode::INTERPRETED_FUNCTION) return "INTERPRETED_FUNCTION";
UNREACHABLE();
return NULL;
}
Handle<WeakCell> Code::WeakCellFor(Handle<Code> code) { Handle<WeakCell> Code::WeakCellFor(Handle<Code> code) {
DCHECK(code->kind() == OPTIMIZED_FUNCTION); DCHECK(code->kind() == OPTIMIZED_FUNCTION);
......
...@@ -4445,6 +4445,10 @@ class BytecodeArray : public FixedArrayBase { ...@@ -4445,6 +4445,10 @@ class BytecodeArray : public FixedArrayBase {
inline int instruction_size(); inline int instruction_size();
// Returns the size of bytecode and its metadata. This includes the size of
// bytecode, constant pool, source position table, and handler table.
inline int SizeIncludingMetadata();
int SourcePosition(int offset); int SourcePosition(int offset);
int SourceStatementPosition(int offset); int SourceStatementPosition(int offset);
...@@ -5120,6 +5124,10 @@ class Code: public HeapObject { ...@@ -5120,6 +5124,10 @@ class Code: public HeapObject {
// Returns the size of the instructions, padding, and relocation information. // Returns the size of the instructions, padding, and relocation information.
inline int body_size(); inline int body_size();
// Returns the size of code and its metadata. This includes the size of code
// relocation information, deoptimization data and handler table.
inline int SizeIncludingMetadata();
// Returns the address of the first relocation info (read backwards!). // Returns the address of the first relocation info (read backwards!).
inline byte* relocation_start(); inline byte* relocation_start();
...@@ -5351,8 +5359,11 @@ class AbstractCode : public HeapObject { ...@@ -5351,8 +5359,11 @@ class AbstractCode : public HeapObject {
CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM) CODE_KIND_LIST(DEFINE_CODE_KIND_ENUM)
#undef DEFINE_CODE_KIND_ENUM #undef DEFINE_CODE_KIND_ENUM
INTERPRETED_FUNCTION, INTERPRETED_FUNCTION,
NUMBER_OF_KINDS
}; };
static const char* Kind2String(Kind kind);
int SourcePosition(int offset); int SourcePosition(int offset);
int SourceStatementPosition(int offset); int SourceStatementPosition(int offset);
...@@ -5362,9 +5373,12 @@ class AbstractCode : public HeapObject { ...@@ -5362,9 +5373,12 @@ class AbstractCode : public HeapObject {
// Returns the address right after the last instruction. // Returns the address right after the last instruction.
inline Address instruction_end(); inline Address instruction_end();
// Returns the of the code instructions. // Returns the size of the code instructions.
inline int instruction_size(); inline int instruction_size();
// Returns the size of instructions and the metadata.
inline int SizeIncludingMetadata();
// Returns true if pc is inside this object's instructions. // Returns true if pc is inside this object's instructions.
inline bool contains(byte* pc); inline bool contains(byte* pc);
......
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