[code-comments] Put code comments into the code object
Code comments in the snapshot can now be enabled with gn arg 'v8_enable_snapshot_code_comments' Bug: v8:7989 Change-Id: I8bd00cafa63132d00d849394c311ba15e6b6daf3 Reviewed-on: https://chromium-review.googlesource.com/c/1329173 Commit-Queue: Sigurd Schneider <sigurds@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Michael Stanton <mvstanton@chromium.org> Cr-Commit-Position: refs/heads/master@{#58020}
This commit is contained in:
parent
23b7d95665
commit
e774cffe2b
10
BUILD.gn
10
BUILD.gn
@ -88,6 +88,9 @@ declare_args() {
|
|||||||
# Enable embedded builtins.
|
# Enable embedded builtins.
|
||||||
v8_enable_embedded_builtins = true
|
v8_enable_embedded_builtins = true
|
||||||
|
|
||||||
|
# Enable code comments for builtins in the snapshot (impacts performance).
|
||||||
|
v8_enable_snapshot_code_comments = false
|
||||||
|
|
||||||
# Build-time flag for enabling nojit mode.
|
# Build-time flag for enabling nojit mode.
|
||||||
# TODO(v8:7777): Remove the build-time flag once the --jitless runtime flag
|
# TODO(v8:7777): Remove the build-time flag once the --jitless runtime flag
|
||||||
# does everything we need.
|
# does everything we need.
|
||||||
@ -1149,6 +1152,10 @@ template("run_mksnapshot") {
|
|||||||
args += [ rebase_path(v8_embed_script, root_build_dir) ]
|
args += [ rebase_path(v8_embed_script, root_build_dir) ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (v8_enable_snapshot_code_comments) {
|
||||||
|
args += [ "--code-comments" ]
|
||||||
|
}
|
||||||
|
|
||||||
if (v8_enable_fast_mksnapshot) {
|
if (v8_enable_fast_mksnapshot) {
|
||||||
args += [
|
args += [
|
||||||
"--no-turbo-rewrite-far-jumps",
|
"--no-turbo-rewrite-far-jumps",
|
||||||
@ -1734,6 +1741,8 @@ v8_source_set("v8_base") {
|
|||||||
"src/char-predicates.cc",
|
"src/char-predicates.cc",
|
||||||
"src/char-predicates.h",
|
"src/char-predicates.h",
|
||||||
"src/checks.h",
|
"src/checks.h",
|
||||||
|
"src/code-comments.cc",
|
||||||
|
"src/code-comments.h",
|
||||||
"src/code-events.h",
|
"src/code-events.h",
|
||||||
"src/code-factory.cc",
|
"src/code-factory.cc",
|
||||||
"src/code-factory.h",
|
"src/code-factory.h",
|
||||||
@ -2242,7 +2251,6 @@ v8_source_set("v8_base") {
|
|||||||
"src/lookup-inl.h",
|
"src/lookup-inl.h",
|
||||||
"src/lookup.cc",
|
"src/lookup.cc",
|
||||||
"src/lookup.h",
|
"src/lookup.h",
|
||||||
"src/lsan.h",
|
|
||||||
"src/machine-type.cc",
|
"src/machine-type.cc",
|
||||||
"src/machine-type.h",
|
"src/machine-type.h",
|
||||||
"src/macro-assembler-inl.h",
|
"src/macro-assembler-inl.h",
|
||||||
|
@ -573,10 +573,11 @@ Assembler::~Assembler() {
|
|||||||
|
|
||||||
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
||||||
// Emit constant pool if necessary.
|
// Emit constant pool if necessary.
|
||||||
int constant_pool_offset = 0;
|
|
||||||
CheckConstPool(true, false);
|
CheckConstPool(true, false);
|
||||||
DCHECK(pending_32_bit_constants_.empty());
|
DCHECK(pending_32_bit_constants_.empty());
|
||||||
|
|
||||||
|
int code_comments_size = WriteCodeComments();
|
||||||
|
|
||||||
AllocateAndInstallRequestedHeapObjects(isolate);
|
AllocateAndInstallRequestedHeapObjects(isolate);
|
||||||
|
|
||||||
// Set up code descriptor.
|
// Set up code descriptor.
|
||||||
@ -584,11 +585,11 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->buffer_size = buffer_size_;
|
desc->buffer_size = buffer_size_;
|
||||||
desc->instr_size = pc_offset();
|
desc->instr_size = pc_offset();
|
||||||
desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
|
desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
|
||||||
desc->constant_pool_size =
|
desc->constant_pool_size = 0;
|
||||||
(constant_pool_offset ? desc->instr_size - constant_pool_offset : 0);
|
|
||||||
desc->origin = this;
|
desc->origin = this;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5114,7 +5115,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
|
|||||||
|
|
||||||
void Assembler::ConstantPoolAddEntry(int position, RelocInfo::Mode rmode,
|
void Assembler::ConstantPoolAddEntry(int position, RelocInfo::Mode rmode,
|
||||||
intptr_t value) {
|
intptr_t value) {
|
||||||
DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::CONST_POOL);
|
DCHECK(rmode != RelocInfo::CONST_POOL);
|
||||||
// We can share CODE_TARGETs because we don't patch the code objects anymore,
|
// We can share CODE_TARGETs because we don't patch the code objects anymore,
|
||||||
// and we make sure we emit only one reloc info for them (thus delta patching)
|
// and we make sure we emit only one reloc info for them (thus delta patching)
|
||||||
// will apply the delta only once. At the moment, we do not dedup code targets
|
// will apply the delta only once. At the moment, we do not dedup code targets
|
||||||
|
@ -1415,10 +1415,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstPoolScope);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Record a comment relocation entry that can be used by a disassembler.
|
|
||||||
// Use --code-comments to enable.
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -1679,6 +1675,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
intptr_t value);
|
intptr_t value);
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class RelocInfo;
|
friend class RelocInfo;
|
||||||
friend class BlockConstPoolScope;
|
friend class BlockConstPoolScope;
|
||||||
friend class EnsureSpace;
|
friend class EnsureSpace;
|
||||||
|
@ -332,8 +332,7 @@ bool ConstPool::AddSharedEntry(SharedEntryMap& entry_map, uint64_t data,
|
|||||||
|
|
||||||
// Constant Pool.
|
// Constant Pool.
|
||||||
bool ConstPool::RecordEntry(intptr_t data, RelocInfo::Mode mode) {
|
bool ConstPool::RecordEntry(intptr_t data, RelocInfo::Mode mode) {
|
||||||
DCHECK(mode != RelocInfo::COMMENT && mode != RelocInfo::CONST_POOL &&
|
DCHECK(mode != RelocInfo::CONST_POOL && mode != RelocInfo::VENEER_POOL &&
|
||||||
mode != RelocInfo::VENEER_POOL &&
|
|
||||||
mode != RelocInfo::DEOPT_SCRIPT_OFFSET &&
|
mode != RelocInfo::DEOPT_SCRIPT_OFFSET &&
|
||||||
mode != RelocInfo::DEOPT_INLINING_ID &&
|
mode != RelocInfo::DEOPT_INLINING_ID &&
|
||||||
mode != RelocInfo::DEOPT_REASON && mode != RelocInfo::DEOPT_ID);
|
mode != RelocInfo::DEOPT_REASON && mode != RelocInfo::DEOPT_ID);
|
||||||
@ -617,6 +616,8 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
CheckConstPool(true, false);
|
CheckConstPool(true, false);
|
||||||
DCHECK(constpool_.IsEmpty());
|
DCHECK(constpool_.IsEmpty());
|
||||||
|
|
||||||
|
int code_comments_size = WriteCodeComments();
|
||||||
|
|
||||||
AllocateAndInstallRequestedHeapObjects(isolate);
|
AllocateAndInstallRequestedHeapObjects(isolate);
|
||||||
|
|
||||||
// Set up code descriptor.
|
// Set up code descriptor.
|
||||||
@ -631,6 +632,7 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->constant_pool_size = 0;
|
desc->constant_pool_size = 0;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4765,15 +4767,14 @@ void Assembler::GrowBuffer() {
|
|||||||
|
|
||||||
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
|
void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data,
|
||||||
ConstantPoolMode constant_pool_mode) {
|
ConstantPoolMode constant_pool_mode) {
|
||||||
if ((rmode == RelocInfo::COMMENT) ||
|
if ((rmode == RelocInfo::INTERNAL_REFERENCE) ||
|
||||||
(rmode == RelocInfo::INTERNAL_REFERENCE) ||
|
|
||||||
(rmode == RelocInfo::CONST_POOL) || (rmode == RelocInfo::VENEER_POOL) ||
|
(rmode == RelocInfo::CONST_POOL) || (rmode == RelocInfo::VENEER_POOL) ||
|
||||||
(rmode == RelocInfo::DEOPT_SCRIPT_OFFSET) ||
|
(rmode == RelocInfo::DEOPT_SCRIPT_OFFSET) ||
|
||||||
(rmode == RelocInfo::DEOPT_INLINING_ID) ||
|
(rmode == RelocInfo::DEOPT_INLINING_ID) ||
|
||||||
(rmode == RelocInfo::DEOPT_REASON) || (rmode == RelocInfo::DEOPT_ID)) {
|
(rmode == RelocInfo::DEOPT_REASON) || (rmode == RelocInfo::DEOPT_ID)) {
|
||||||
// Adjust code for new modes.
|
// Adjust code for new modes.
|
||||||
DCHECK(RelocInfo::IsComment(rmode) || RelocInfo::IsDeoptReason(rmode) ||
|
DCHECK(RelocInfo::IsDeoptReason(rmode) || RelocInfo::IsDeoptId(rmode) ||
|
||||||
RelocInfo::IsDeoptId(rmode) || RelocInfo::IsDeoptPosition(rmode) ||
|
RelocInfo::IsDeoptPosition(rmode) ||
|
||||||
RelocInfo::IsInternalReference(rmode) ||
|
RelocInfo::IsInternalReference(rmode) ||
|
||||||
RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode));
|
RelocInfo::IsConstPool(rmode) || RelocInfo::IsVeneerPool(rmode));
|
||||||
// These modes do not need an entry in the constant pool.
|
// These modes do not need an entry in the constant pool.
|
||||||
|
@ -1086,9 +1086,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
EndBlockVeneerPool();
|
EndBlockVeneerPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debugging ----------------------------------------------------------------
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -3588,6 +3585,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
|
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class EnsureSpace;
|
friend class EnsureSpace;
|
||||||
friend class ConstPool;
|
friend class ConstPool;
|
||||||
};
|
};
|
||||||
|
@ -197,16 +197,10 @@ void Assembler::RecordDeoptReason(DeoptimizeReason reason,
|
|||||||
RecordRelocInfo(RelocInfo::DEOPT_ID, id);
|
RecordRelocInfo(RelocInfo::DEOPT_ID, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::RecordComment(const char* msg) {
|
|
||||||
if (FLAG_code_comments) {
|
|
||||||
EnsureSpace ensure_space(this);
|
|
||||||
RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assembler::DataAlign(int m) {
|
void Assembler::DataAlign(int m) {
|
||||||
DCHECK(m >= 2 && base::bits::IsPowerOfTwo(m));
|
DCHECK(m >= 2 && base::bits::IsPowerOfTwo(m));
|
||||||
while ((pc_offset() & (m - 1)) != 0) {
|
while ((pc_offset() & (m - 1)) != 0) {
|
||||||
|
EnsureSpace ensure_space(this);
|
||||||
db(0);
|
db(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,5 +243,15 @@ void AssemblerBase::ReserveCodeTargetSpace(size_t num_of_code_targets) {
|
|||||||
code_targets_.reserve(num_of_code_targets);
|
code_targets_.reserve(num_of_code_targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Assembler::WriteCodeComments() {
|
||||||
|
if (!FLAG_code_comments || code_comments_writer_.entry_count() == 0) return 0;
|
||||||
|
DataAlign(Code::kCodeCommentsOffsetFactor);
|
||||||
|
int offset = pc_offset();
|
||||||
|
code_comments_writer_.Emit(this);
|
||||||
|
int size = pc_offset() - offset;
|
||||||
|
DCHECK_EQ(size, code_comments_writer_.section_size());
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include <forward_list>
|
#include <forward_list>
|
||||||
|
|
||||||
|
#include "src/code-comments.h"
|
||||||
#include "src/deoptimize-reason.h"
|
#include "src/deoptimize-reason.h"
|
||||||
#include "src/external-reference.h"
|
#include "src/external-reference.h"
|
||||||
#include "src/flags.h"
|
#include "src/flags.h"
|
||||||
@ -244,6 +245,14 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced {
|
|||||||
// Used to print the name of some special registers.
|
// Used to print the name of some special registers.
|
||||||
static const char* GetSpecialRegisterName(int code) { return "UNKNOWN"; }
|
static const char* GetSpecialRegisterName(int code) { return "UNKNOWN"; }
|
||||||
|
|
||||||
|
// Record an inline code comment that can be used by a disassembler.
|
||||||
|
// Use --code-comments to enable.
|
||||||
|
void RecordComment(const char* msg) {
|
||||||
|
if (FLAG_code_comments) {
|
||||||
|
code_comments_writer_.Add(pc_offset(), std::string(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Add 'target' to the {code_targets_} vector, if necessary, and return the
|
// Add 'target' to the {code_targets_} vector, if necessary, and return the
|
||||||
// offset at which it is stored.
|
// offset at which it is stored.
|
||||||
@ -290,6 +299,8 @@ class V8_EXPORT_PRIVATE AssemblerBase : public Malloced {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodeCommentsWriter code_comments_writer_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Before we copy code into the code space, we sometimes cannot encode
|
// Before we copy code into the code space, we sometimes cannot encode
|
||||||
// call/jump code targets as we normally would, as the difference between the
|
// call/jump code targets as we normally would, as the difference between the
|
||||||
|
@ -214,7 +214,7 @@ void HandlerBuiltinsAssembler::Generate_ElementsTransitionAndStore(
|
|||||||
Node* vector = Parameter(Descriptor::kVector);
|
Node* vector = Parameter(Descriptor::kVector);
|
||||||
Node* context = Parameter(Descriptor::kContext);
|
Node* context = Parameter(Descriptor::kContext);
|
||||||
|
|
||||||
Comment("ElementsTransitionAndStore: store_mode=%d", store_mode);
|
Comment("ElementsTransitionAndStore: store_mode=", store_mode);
|
||||||
|
|
||||||
Label miss(this);
|
Label miss(this);
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ void HandlerBuiltinsAssembler::Generate_StoreFastElementIC(
|
|||||||
Node* vector = Parameter(Descriptor::kVector);
|
Node* vector = Parameter(Descriptor::kVector);
|
||||||
Node* context = Parameter(Descriptor::kContext);
|
Node* context = Parameter(Descriptor::kContext);
|
||||||
|
|
||||||
Comment("StoreFastElementStub: store_mode=%d", store_mode);
|
Comment("StoreFastElementStub: store_mode=", store_mode);
|
||||||
|
|
||||||
Label miss(this);
|
Label miss(this);
|
||||||
|
|
||||||
|
102
src/code-comments.cc
Normal file
102
src/code-comments.cc
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
#include "src/assembler-inl.h"
|
||||||
|
#include "src/code-comments.h"
|
||||||
|
|
||||||
|
namespace v8 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static constexpr uint8_t kOffsetToFirstCommentEntry = kUInt32Size;
|
||||||
|
static constexpr uint8_t kOffsetToPCOffset = 0;
|
||||||
|
static constexpr uint8_t kOffsetToCommentSize = kOffsetToPCOffset + kUInt32Size;
|
||||||
|
static constexpr uint8_t kOffsetToCommentString =
|
||||||
|
kOffsetToCommentSize + kUInt32Size;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
uint32_t CodeCommentEntry::comment_length() const {
|
||||||
|
return static_cast<uint32_t>(comment.size() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CodeCommentEntry::size() const {
|
||||||
|
return kOffsetToCommentString + comment_length();
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeCommentsIterator::CodeCommentsIterator(Address code_comments_start)
|
||||||
|
: code_comments_start_(code_comments_start),
|
||||||
|
current_entry_(code_comments_start + kOffsetToFirstCommentEntry) {}
|
||||||
|
|
||||||
|
uint32_t CodeCommentsIterator::size() const {
|
||||||
|
return code_comments_start_ != kNullAddress
|
||||||
|
? *reinterpret_cast<uint32_t*>(code_comments_start_)
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* CodeCommentsIterator::GetComment() const {
|
||||||
|
const char* comment_string =
|
||||||
|
reinterpret_cast<const char*>(current_entry_ + kOffsetToCommentString);
|
||||||
|
CHECK_EQ(GetCommentSize(), strlen(comment_string) + 1);
|
||||||
|
return comment_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CodeCommentsIterator::GetCommentSize() const {
|
||||||
|
return *reinterpret_cast<uint32_t*>(current_entry_ + kOffsetToCommentSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CodeCommentsIterator::GetPCOffset() const {
|
||||||
|
return *reinterpret_cast<uint32_t*>(current_entry_ + kOffsetToPCOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeCommentsIterator::Next() {
|
||||||
|
current_entry_ += kOffsetToCommentString + GetCommentSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CodeCommentsIterator::HasCurrent() const {
|
||||||
|
return current_entry_ < code_comments_start_ + size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeCommentsWriter::Emit(Assembler* assm) {
|
||||||
|
assm->dd(section_size());
|
||||||
|
for (auto i = comments_.begin(); i != comments_.end(); ++i) {
|
||||||
|
assm->dd(i->pc_offset);
|
||||||
|
assm->dd(i->comment_length());
|
||||||
|
for (char c : i->comment) {
|
||||||
|
EnsureSpace ensure_space(assm);
|
||||||
|
assm->db(c);
|
||||||
|
}
|
||||||
|
assm->db('\0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CodeCommentsWriter::Add(uint32_t pc_offset, std::string comment) {
|
||||||
|
CodeCommentEntry entry = {pc_offset, std::move(comment)};
|
||||||
|
byte_count_ += entry.size();
|
||||||
|
comments_.push_back(std::move(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t CodeCommentsWriter::entry_count() const { return comments_.size(); }
|
||||||
|
uint32_t CodeCommentsWriter::section_size() const {
|
||||||
|
return kOffsetToFirstCommentEntry + static_cast<uint32_t>(byte_count_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintCodeCommentsSection(std::ostream& out, Address code_comments_start) {
|
||||||
|
CodeCommentsIterator it(code_comments_start);
|
||||||
|
out << "CodeComments (size = " << it.size() << ")\n";
|
||||||
|
if (it.HasCurrent()) {
|
||||||
|
out << std::setw(6) << "pc" << std::setw(6) << "len"
|
||||||
|
<< " comment\n";
|
||||||
|
}
|
||||||
|
for (; it.HasCurrent(); it.Next()) {
|
||||||
|
out << std::hex << std::setw(6) << it.GetPCOffset() << std::dec
|
||||||
|
<< std::setw(6) << it.GetCommentSize() << " (" << it.GetComment()
|
||||||
|
<< ")\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace v8
|
68
src/code-comments.h
Normal file
68
src/code-comments.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef V8_CODE_COMMENTS_H_
|
||||||
|
#define V8_CODE_COMMENTS_H_
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "include/v8-internal.h"
|
||||||
|
|
||||||
|
namespace v8 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class Assembler;
|
||||||
|
|
||||||
|
// Code comments section layout:
|
||||||
|
// byte count content
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// 4 size as uint32_t
|
||||||
|
// [Inline array of CodeCommentEntry in increasing pc_offset order]
|
||||||
|
// ┌ 4 pc_offset of entry as uint32_t
|
||||||
|
// ├ 4 length of the comment including terminating '\0'
|
||||||
|
// └ <variable length> characters of the comment including terminating '\0'
|
||||||
|
|
||||||
|
struct CodeCommentEntry {
|
||||||
|
uint32_t pc_offset;
|
||||||
|
std::string comment;
|
||||||
|
uint32_t comment_length() const;
|
||||||
|
uint32_t size() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CodeCommentsWriter {
|
||||||
|
public:
|
||||||
|
void Add(uint32_t pc_offset, std::string comment);
|
||||||
|
void Emit(Assembler* assm);
|
||||||
|
size_t entry_count() const;
|
||||||
|
uint32_t section_size() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t byte_count_ = 0;
|
||||||
|
std::vector<CodeCommentEntry> comments_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CodeCommentsIterator {
|
||||||
|
public:
|
||||||
|
// Address can be kNullAddress. In this case HasCurrent() will return false.
|
||||||
|
explicit CodeCommentsIterator(Address code_comments_start);
|
||||||
|
uint32_t size() const;
|
||||||
|
const char* GetComment() const;
|
||||||
|
uint32_t GetCommentSize() const;
|
||||||
|
uint32_t GetPCOffset() const;
|
||||||
|
void Next();
|
||||||
|
bool HasCurrent() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Address code_comments_start_;
|
||||||
|
Address current_entry_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void PrintCodeCommentsSection(std::ostream& out, Address code_comments_start);
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace v8
|
||||||
|
|
||||||
|
#endif // V8_CODE_COMMENTS_H_
|
@ -49,5 +49,9 @@ int CodeReference::relocation_size() const {
|
|||||||
: wasm_code_->reloc_info().length();
|
: wasm_code_->reloc_info().length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Address CodeReference::code_comments() const {
|
||||||
|
return kind_ == JS ? js_code_->code_comments() : wasm_code_->code_comments();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -31,6 +31,7 @@ class CodeReference {
|
|||||||
const byte* relocation_start() const;
|
const byte* relocation_start() const;
|
||||||
const byte* relocation_end() const;
|
const byte* relocation_end() const;
|
||||||
int relocation_size() const;
|
int relocation_size() const;
|
||||||
|
Address code_comments() const;
|
||||||
bool is_null() const {
|
bool is_null() const {
|
||||||
return kind_ == JS ? js_code_.is_null() : wasm_code_ == nullptr;
|
return kind_ == JS ? js_code_.is_null() : wasm_code_ == nullptr;
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ void CodeStubAssembler::Check(const BranchGenerator& branch,
|
|||||||
Label ok(this);
|
Label ok(this);
|
||||||
Label not_ok(this, Label::kDeferred);
|
Label not_ok(this, Label::kDeferred);
|
||||||
if (message != nullptr && FLAG_code_comments) {
|
if (message != nullptr && FLAG_code_comments) {
|
||||||
Comment("[ Assert: %s", message);
|
Comment("[ Assert: ", message);
|
||||||
} else {
|
} else {
|
||||||
Comment("[ Assert");
|
Comment("[ Assert");
|
||||||
}
|
}
|
||||||
@ -2885,7 +2885,7 @@ TNode<Smi> CodeStubAssembler::BuildAppendJSArray(ElementsKind kind,
|
|||||||
TVariable<IntPtrT>* arg_index,
|
TVariable<IntPtrT>* arg_index,
|
||||||
Label* bailout) {
|
Label* bailout) {
|
||||||
CSA_SLOW_ASSERT(this, IsJSArray(array));
|
CSA_SLOW_ASSERT(this, IsJSArray(array));
|
||||||
Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
|
Comment("BuildAppendJSArray: ", ElementsKindToString(kind));
|
||||||
Label pre_bailout(this);
|
Label pre_bailout(this);
|
||||||
Label success(this);
|
Label success(this);
|
||||||
TVARIABLE(Smi, var_tagged_length);
|
TVARIABLE(Smi, var_tagged_length);
|
||||||
@ -2952,7 +2952,7 @@ void CodeStubAssembler::TryStoreArrayElement(ElementsKind kind,
|
|||||||
void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
|
void CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* array,
|
||||||
Node* value, Label* bailout) {
|
Node* value, Label* bailout) {
|
||||||
CSA_SLOW_ASSERT(this, IsJSArray(array));
|
CSA_SLOW_ASSERT(this, IsJSArray(array));
|
||||||
Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
|
Comment("BuildAppendJSArray: ", ElementsKindToString(kind));
|
||||||
ParameterMode mode = OptimalParameterMode();
|
ParameterMode mode = OptimalParameterMode();
|
||||||
VARIABLE(var_length, OptimalParameterRepresentation(),
|
VARIABLE(var_length, OptimalParameterRepresentation(),
|
||||||
TaggedToParameter(LoadFastJSArrayLength(array), mode));
|
TaggedToParameter(LoadFastJSArrayLength(array), mode));
|
||||||
@ -5059,8 +5059,8 @@ void CodeStubAssembler::CopyStringCharacters(Node* from_string, Node* to_string,
|
|||||||
bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING;
|
bool from_one_byte = from_encoding == String::ONE_BYTE_ENCODING;
|
||||||
bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING;
|
bool to_one_byte = to_encoding == String::ONE_BYTE_ENCODING;
|
||||||
DCHECK_IMPLIES(to_one_byte, from_one_byte);
|
DCHECK_IMPLIES(to_one_byte, from_one_byte);
|
||||||
Comment("CopyStringCharacters %s -> %s",
|
Comment("CopyStringCharacters ",
|
||||||
from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING",
|
from_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING", " -> ",
|
||||||
to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING");
|
to_one_byte ? "ONE_BYTE_ENCODING" : "TWO_BYTE_ENCODING");
|
||||||
|
|
||||||
ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS;
|
ElementsKind from_kind = from_one_byte ? UINT8_ELEMENTS : UINT16_ELEMENTS;
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
#include "src/counters.h"
|
#include "src/counters.h"
|
||||||
#include "src/eh-frame.h"
|
#include "src/eh-frame.h"
|
||||||
#include "src/frames.h"
|
#include "src/frames.h"
|
||||||
#include "src/lsan.h"
|
|
||||||
#include "src/macro-assembler-inl.h"
|
#include "src/macro-assembler-inl.h"
|
||||||
#include "src/objects/smi.h"
|
#include "src/objects/smi.h"
|
||||||
#include "src/optimized-compilation-info.h"
|
#include "src/optimized-compilation-info.h"
|
||||||
@ -65,10 +64,7 @@ CodeGenerator::CodeGenerator(
|
|||||||
deoptimization_exits_(zone()),
|
deoptimization_exits_(zone()),
|
||||||
deoptimization_states_(zone()),
|
deoptimization_states_(zone()),
|
||||||
deoptimization_literals_(zone()),
|
deoptimization_literals_(zone()),
|
||||||
inlined_function_count_(0),
|
|
||||||
translations_(zone()),
|
translations_(zone()),
|
||||||
handler_table_offset_(0),
|
|
||||||
last_lazy_deopt_pc_(0),
|
|
||||||
caller_registers_saved_(false),
|
caller_registers_saved_(false),
|
||||||
jump_tables_(nullptr),
|
jump_tables_(nullptr),
|
||||||
ools_(nullptr),
|
ools_(nullptr),
|
||||||
@ -202,29 +198,21 @@ void CodeGenerator::AssembleCode() {
|
|||||||
current_block_ = block->rpo_number();
|
current_block_ = block->rpo_number();
|
||||||
unwinding_info_writer_.BeginInstructionBlock(tasm()->pc_offset(), block);
|
unwinding_info_writer_.BeginInstructionBlock(tasm()->pc_offset(), block);
|
||||||
if (FLAG_code_comments) {
|
if (FLAG_code_comments) {
|
||||||
Vector<char> buffer = Vector<char>::New(200);
|
std::ostringstream buffer;
|
||||||
char* buffer_start = buffer.start();
|
buffer << "-- B" << block->rpo_number().ToInt() << " start";
|
||||||
LSAN_IGNORE_OBJECT(buffer_start);
|
if (block->IsDeferred()) buffer << " (deferred)";
|
||||||
|
if (!block->needs_frame()) buffer << " (no frame)";
|
||||||
int next = SNPrintF(
|
if (block->must_construct_frame()) buffer << " (construct frame)";
|
||||||
buffer, "-- B%d start%s%s%s%s", block->rpo_number().ToInt(),
|
if (block->must_deconstruct_frame()) buffer << " (deconstruct frame)";
|
||||||
block->IsDeferred() ? " (deferred)" : "",
|
|
||||||
block->needs_frame() ? "" : " (no frame)",
|
|
||||||
block->must_construct_frame() ? " (construct frame)" : "",
|
|
||||||
block->must_deconstruct_frame() ? " (deconstruct frame)" : "");
|
|
||||||
|
|
||||||
buffer = buffer.SubVector(next, buffer.length());
|
|
||||||
|
|
||||||
if (block->IsLoopHeader()) {
|
if (block->IsLoopHeader()) {
|
||||||
next = SNPrintF(buffer, " (loop up to %d)", block->loop_end().ToInt());
|
buffer << " (loop up to " << block->loop_end().ToInt() << ")";
|
||||||
buffer = buffer.SubVector(next, buffer.length());
|
|
||||||
}
|
}
|
||||||
if (block->loop_header().IsValid()) {
|
if (block->loop_header().IsValid()) {
|
||||||
next = SNPrintF(buffer, " (in loop %d)", block->loop_header().ToInt());
|
buffer << " (in loop " << block->loop_header().ToInt() << ")";
|
||||||
buffer = buffer.SubVector(next, buffer.length());
|
|
||||||
}
|
}
|
||||||
SNPrintF(buffer, " --");
|
buffer << " --";
|
||||||
tasm()->RecordComment(buffer_start);
|
tasm()->RecordComment(buffer.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_access_state()->MarkHasFrame(block->needs_frame());
|
frame_access_state()->MarkHasFrame(block->needs_frame());
|
||||||
@ -408,6 +396,7 @@ MaybeHandle<Code> CodeGenerator::FinalizeCode() {
|
|||||||
tasm()->AbortedCodeGeneration();
|
tasm()->AbortedCodeGeneration();
|
||||||
return MaybeHandle<Code>();
|
return MaybeHandle<Code>();
|
||||||
}
|
}
|
||||||
|
|
||||||
isolate()->counters()->total_compiled_code_size()->Increment(
|
isolate()->counters()->total_compiled_code_size()->Increment(
|
||||||
code->raw_instruction_size());
|
code->raw_instruction_size());
|
||||||
|
|
||||||
@ -734,9 +723,7 @@ void CodeGenerator::AssembleSourcePosition(SourcePosition source_position) {
|
|||||||
buffer << source_position.InliningStack(info);
|
buffer << source_position.InliningStack(info);
|
||||||
}
|
}
|
||||||
buffer << " --";
|
buffer << " --";
|
||||||
char* str = StrDup(buffer.str().c_str());
|
tasm()->RecordComment(buffer.str().c_str());
|
||||||
LSAN_IGNORE_OBJECT(str);
|
|
||||||
tasm()->RecordComment(str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,10 +415,10 @@ class CodeGenerator final : public GapResolver::Assembler {
|
|||||||
ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
|
ZoneDeque<DeoptimizationExit*> deoptimization_exits_;
|
||||||
ZoneDeque<DeoptimizationState*> deoptimization_states_;
|
ZoneDeque<DeoptimizationState*> deoptimization_states_;
|
||||||
ZoneDeque<DeoptimizationLiteral> deoptimization_literals_;
|
ZoneDeque<DeoptimizationLiteral> deoptimization_literals_;
|
||||||
size_t inlined_function_count_;
|
size_t inlined_function_count_ = 0;
|
||||||
TranslationBuffer translations_;
|
TranslationBuffer translations_;
|
||||||
int handler_table_offset_;
|
int handler_table_offset_ = 0;
|
||||||
int last_lazy_deopt_pc_;
|
int last_lazy_deopt_pc_ = 0;
|
||||||
|
|
||||||
// kArchCallCFunction could be reached either:
|
// kArchCallCFunction could be reached either:
|
||||||
// kArchCallCFunction;
|
// kArchCallCFunction;
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "src/frames.h"
|
#include "src/frames.h"
|
||||||
#include "src/interface-descriptors.h"
|
#include "src/interface-descriptors.h"
|
||||||
#include "src/interpreter/bytecodes.h"
|
#include "src/interpreter/bytecodes.h"
|
||||||
#include "src/lsan.h"
|
|
||||||
#include "src/machine-type.h"
|
#include "src/machine-type.h"
|
||||||
#include "src/macro-assembler.h"
|
#include "src/macro-assembler.h"
|
||||||
#include "src/memcopy.h"
|
#include "src/memcopy.h"
|
||||||
@ -451,25 +450,9 @@ void CodeAssembler::Unreachable() {
|
|||||||
raw_assembler()->Unreachable();
|
raw_assembler()->Unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeAssembler::Comment(const char* format, ...) {
|
void CodeAssembler::Comment(std::string str) {
|
||||||
if (!FLAG_code_comments) return;
|
if (!FLAG_code_comments) return;
|
||||||
char buffer[4 * KB];
|
raw_assembler()->Comment(str);
|
||||||
StringBuilder builder(buffer, arraysize(buffer));
|
|
||||||
va_list arguments;
|
|
||||||
va_start(arguments, format);
|
|
||||||
builder.AddFormattedList(format, arguments);
|
|
||||||
va_end(arguments);
|
|
||||||
|
|
||||||
// Copy the string before recording it in the assembler to avoid
|
|
||||||
// issues when the stack allocated buffer goes out of scope.
|
|
||||||
const int prefix_len = 2;
|
|
||||||
int length = builder.position() + 1;
|
|
||||||
char* copy = reinterpret_cast<char*>(malloc(length + prefix_len));
|
|
||||||
LSAN_IGNORE_OBJECT(copy);
|
|
||||||
MemCopy(copy + prefix_len, builder.Finalize(), length);
|
|
||||||
copy[0] = ';';
|
|
||||||
copy[1] = ' ';
|
|
||||||
raw_assembler()->Comment(copy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeAssembler::Bind(Label* label) { return label->Bind(); }
|
void CodeAssembler::Bind(Label* label) { return label->Bind(); }
|
||||||
|
@ -846,7 +846,18 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
|||||||
void DebugAbort(Node* message);
|
void DebugAbort(Node* message);
|
||||||
void DebugBreak();
|
void DebugBreak();
|
||||||
void Unreachable();
|
void Unreachable();
|
||||||
void Comment(const char* format, ...);
|
void Comment(const char* msg) {
|
||||||
|
if (!FLAG_code_comments) return;
|
||||||
|
Comment(std::string(msg));
|
||||||
|
}
|
||||||
|
void Comment(std::string msg);
|
||||||
|
template <class... Args>
|
||||||
|
void Comment(Args&&... args) {
|
||||||
|
if (!FLAG_code_comments) return;
|
||||||
|
std::ostringstream s;
|
||||||
|
USE((s << std::forward<Args>(args))...);
|
||||||
|
Comment(s.str());
|
||||||
|
}
|
||||||
|
|
||||||
void Bind(Label* label);
|
void Bind(Label* label);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -547,8 +547,11 @@ void RawMachineAssembler::Unreachable() {
|
|||||||
current_block_ = nullptr;
|
current_block_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RawMachineAssembler::Comment(const char* msg) {
|
void RawMachineAssembler::Comment(std::string msg) {
|
||||||
AddNode(machine()->Comment(msg));
|
size_t length = msg.length() + 1;
|
||||||
|
char* zone_buffer = zone()->NewArray<char>(length);
|
||||||
|
MemCopy(zone_buffer, msg.c_str(), length);
|
||||||
|
AddNode(machine()->Comment(zone_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* RawMachineAssembler::CallN(CallDescriptor* call_descriptor,
|
Node* RawMachineAssembler::CallN(CallDescriptor* call_descriptor,
|
||||||
|
@ -933,7 +933,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
|
|||||||
void DebugAbort(Node* message);
|
void DebugAbort(Node* message);
|
||||||
void DebugBreak();
|
void DebugBreak();
|
||||||
void Unreachable();
|
void Unreachable();
|
||||||
void Comment(const char* msg);
|
void Comment(std::string msg);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
void Bind(RawMachineLabel* label, AssemblerDebugInfo info);
|
void Bind(RawMachineLabel* label, AssemblerDebugInfo info);
|
||||||
|
@ -177,7 +177,7 @@ void ConstantPoolBuilder::EmitGroup(Assembler* assm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit and return position of pool. Zero implies no constant pool.
|
// Emit and return size of pool.
|
||||||
int ConstantPoolBuilder::Emit(Assembler* assm) {
|
int ConstantPoolBuilder::Emit(Assembler* assm) {
|
||||||
bool emitted = emitted_label_.is_bound();
|
bool emitted = emitted_label_.is_bound();
|
||||||
bool empty = IsEmpty();
|
bool empty = IsEmpty();
|
||||||
@ -203,7 +203,7 @@ int ConstantPoolBuilder::Emit(Assembler* assm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !empty ? emitted_label_.pos() : 0;
|
return !empty ? (assm->pc_offset() - emitted_label_.pos()) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // defined(V8_TARGET_ARCH_PPC)
|
#endif // defined(V8_TARGET_ARCH_PPC)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "src/assembler-inl.h"
|
#include "src/assembler-inl.h"
|
||||||
|
#include "src/code-comments.h"
|
||||||
#include "src/code-reference.h"
|
#include "src/code-reference.h"
|
||||||
#include "src/code-stubs.h"
|
#include "src/code-stubs.h"
|
||||||
#include "src/debug/debug.h"
|
#include "src/debug/debug.h"
|
||||||
@ -274,6 +275,7 @@ static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
|
|||||||
std::ostream* os, CodeReference code,
|
std::ostream* os, CodeReference code,
|
||||||
const V8NameConverter& converter, byte* begin, byte* end,
|
const V8NameConverter& converter, byte* begin, byte* end,
|
||||||
Address current_pc) {
|
Address current_pc) {
|
||||||
|
CHECK(!code.is_null());
|
||||||
v8::internal::EmbeddedVector<char, 128> decode_buffer;
|
v8::internal::EmbeddedVector<char, 128> decode_buffer;
|
||||||
v8::internal::EmbeddedVector<char, kOutBufferSize> out_buffer;
|
v8::internal::EmbeddedVector<char, kOutBufferSize> out_buffer;
|
||||||
StringBuilder out(out_buffer.start(), out_buffer.length());
|
StringBuilder out(out_buffer.start(), out_buffer.length());
|
||||||
@ -281,7 +283,11 @@ static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
|
|||||||
disasm::Disassembler d(converter,
|
disasm::Disassembler d(converter,
|
||||||
disasm::Disassembler::kContinueOnUnimplementedOpcode);
|
disasm::Disassembler::kContinueOnUnimplementedOpcode);
|
||||||
RelocIterator* it = nullptr;
|
RelocIterator* it = nullptr;
|
||||||
if (!code.is_null()) {
|
CodeCommentsIterator cit(code.code_comments());
|
||||||
|
// Relocation exists if we either have no isolate (wasm code),
|
||||||
|
// or we have an isolate and it is not an off-heap instruction stream.
|
||||||
|
if (!isolate ||
|
||||||
|
!InstructionStream::PcIsOffHeap(isolate, bit_cast<Address>(begin))) {
|
||||||
it = new RelocIterator(code);
|
it = new RelocIterator(code);
|
||||||
} else {
|
} else {
|
||||||
// No relocation information when printing code stubs.
|
// No relocation information when printing code stubs.
|
||||||
@ -327,19 +333,18 @@ static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
|
|||||||
std::vector<intptr_t> datas;
|
std::vector<intptr_t> datas;
|
||||||
if (it != nullptr) {
|
if (it != nullptr) {
|
||||||
while (!it->done() && it->rinfo()->pc() < reinterpret_cast<Address>(pc)) {
|
while (!it->done() && it->rinfo()->pc() < reinterpret_cast<Address>(pc)) {
|
||||||
if (RelocInfo::IsComment(it->rinfo()->rmode())) {
|
// Collect all data.
|
||||||
// For comments just collect the text.
|
pcs.push_back(it->rinfo()->pc());
|
||||||
comments.push_back(
|
rmodes.push_back(it->rinfo()->rmode());
|
||||||
reinterpret_cast<const char*>(it->rinfo()->data()));
|
datas.push_back(it->rinfo()->data());
|
||||||
} else {
|
|
||||||
// For other reloc info collect all data.
|
|
||||||
pcs.push_back(it->rinfo()->pc());
|
|
||||||
rmodes.push_back(it->rinfo()->rmode());
|
|
||||||
datas.push_back(it->rinfo()->data());
|
|
||||||
}
|
|
||||||
it->next();
|
it->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (cit.HasCurrent() &&
|
||||||
|
cit.GetPCOffset() < static_cast<Address>(pc - begin)) {
|
||||||
|
comments.push_back(cit.GetComment());
|
||||||
|
cit.Next();
|
||||||
|
}
|
||||||
|
|
||||||
// Comments.
|
// Comments.
|
||||||
for (size_t i = 0; i < comments.size(); i++) {
|
for (size_t i = 0; i < comments.size(); i++) {
|
||||||
@ -402,14 +407,11 @@ static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Emit comments following the last instruction (if any).
|
// Emit comments following the last instruction (if any).
|
||||||
if (it != nullptr) {
|
while (cit.HasCurrent() &&
|
||||||
for ( ; !it->done(); it->next()) {
|
cit.GetPCOffset() < static_cast<Address>(pc - begin)) {
|
||||||
if (RelocInfo::IsComment(it->rinfo()->rmode())) {
|
out.AddFormatted(" %s", cit.GetComment());
|
||||||
out.AddFormatted(" %s",
|
DumpBuffer(os, &out);
|
||||||
reinterpret_cast<const char*>(it->rinfo()->data()));
|
cit.Next();
|
||||||
DumpBuffer(os, &out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete it;
|
delete it;
|
||||||
@ -419,19 +421,16 @@ static int DecodeIt(Isolate* isolate, ExternalReferenceEncoder* ref_encoder,
|
|||||||
int Disassembler::Decode(Isolate* isolate, std::ostream* os, byte* begin,
|
int Disassembler::Decode(Isolate* isolate, std::ostream* os, byte* begin,
|
||||||
byte* end, CodeReference code, Address current_pc) {
|
byte* end, CodeReference code, Address current_pc) {
|
||||||
V8NameConverter v8NameConverter(isolate, code);
|
V8NameConverter v8NameConverter(isolate, code);
|
||||||
bool decode_off_heap = isolate && InstructionStream::PcIsOffHeap(
|
|
||||||
isolate, bit_cast<Address>(begin));
|
|
||||||
CodeReference code_ref = decode_off_heap ? CodeReference() : code;
|
|
||||||
if (isolate) {
|
if (isolate) {
|
||||||
// We have an isolate, so support external reference names.
|
// We have an isolate, so support external reference names.
|
||||||
SealHandleScope shs(isolate);
|
SealHandleScope shs(isolate);
|
||||||
DisallowHeapAllocation no_alloc;
|
DisallowHeapAllocation no_alloc;
|
||||||
ExternalReferenceEncoder ref_encoder(isolate);
|
ExternalReferenceEncoder ref_encoder(isolate);
|
||||||
return DecodeIt(isolate, &ref_encoder, os, code_ref, v8NameConverter, begin,
|
return DecodeIt(isolate, &ref_encoder, os, code, v8NameConverter, begin,
|
||||||
end, current_pc);
|
end, current_pc);
|
||||||
} else {
|
} else {
|
||||||
// No isolate => isolate-independent code. No external reference names.
|
// No isolate => isolate-independent code. No external reference names.
|
||||||
return DecodeIt(nullptr, nullptr, os, code_ref, v8NameConverter, begin, end,
|
return DecodeIt(nullptr, nullptr, os, code, v8NameConverter, begin, end,
|
||||||
current_pc);
|
current_pc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -707,17 +707,16 @@ enum ParseRestriction {
|
|||||||
// A CodeDesc describes a buffer holding instructions and relocation
|
// A CodeDesc describes a buffer holding instructions and relocation
|
||||||
// information. The instructions start at the beginning of the buffer
|
// information. The instructions start at the beginning of the buffer
|
||||||
// and grow forward, the relocation information starts at the end of
|
// and grow forward, the relocation information starts at the end of
|
||||||
// the buffer and grows backward. A constant pool may exist at the
|
// the buffer and grows backward. A constant pool and a code comments
|
||||||
// end of the instructions.
|
// section may exist at the in this order at the end of the instructions.
|
||||||
//
|
//
|
||||||
// |<--------------- buffer_size ----------------------------------->|
|
// │<--------------- buffer_size ----------------------------------->│
|
||||||
// |<------------- instr_size ---------->| |<-- reloc_size -->|
|
// │<---------------- instr_size ------------->│ │<-reloc_size->│
|
||||||
// | |<- const_pool_size ->| |
|
// │ │<-const pool->│ │ │ │
|
||||||
// +=====================================+========+==================+
|
// │ │<- comments->│ │ │
|
||||||
// | instructions | data | free | reloc info |
|
// ├───────────────────────────────────────────┼──────┼──────────────┤
|
||||||
// +=====================================+========+==================+
|
// │ instructions │ data │ free │ reloc info │
|
||||||
// ^
|
// ├───────────────────────────────────────────┴──────┴──────────────┘
|
||||||
// |
|
|
||||||
// buffer
|
// buffer
|
||||||
|
|
||||||
struct CodeDesc {
|
struct CodeDesc {
|
||||||
@ -726,9 +725,18 @@ struct CodeDesc {
|
|||||||
int instr_size;
|
int instr_size;
|
||||||
int reloc_size;
|
int reloc_size;
|
||||||
int constant_pool_size;
|
int constant_pool_size;
|
||||||
|
int code_comments_size;
|
||||||
byte* unwinding_info;
|
byte* unwinding_info;
|
||||||
int unwinding_info_size;
|
int unwinding_info_size;
|
||||||
Assembler* origin;
|
Assembler* origin;
|
||||||
|
int constant_pool_offset() const {
|
||||||
|
return constant_pool_size
|
||||||
|
? instr_size - code_comments_size - constant_pool_size
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
int code_comments_offset() const {
|
||||||
|
return code_comments_size ? (instr_size - code_comments_size) : 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// State for inline cache call sites. Aliased as IC::State.
|
// State for inline cache call sites. Aliased as IC::State.
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "src/heap/code-stats.h"
|
#include "src/heap/code-stats.h"
|
||||||
|
|
||||||
|
#include "src/code-comments.h"
|
||||||
#include "src/objects-inl.h"
|
#include "src/objects-inl.h"
|
||||||
#include "src/reloc-info.h"
|
#include "src/reloc-info.h"
|
||||||
|
|
||||||
@ -164,36 +165,28 @@ void CodeStatistics::EnterComment(Isolate* isolate, const char* comment,
|
|||||||
// Call for each nested comment start (start marked with '[ xxx', end marked
|
// Call for each nested comment start (start marked with '[ xxx', end marked
|
||||||
// with ']'. RelocIterator 'it' must point to a comment reloc info.
|
// with ']'. RelocIterator 'it' must point to a comment reloc info.
|
||||||
void CodeStatistics::CollectCommentStatistics(Isolate* isolate,
|
void CodeStatistics::CollectCommentStatistics(Isolate* isolate,
|
||||||
RelocIterator* it) {
|
CodeCommentsIterator* cit) {
|
||||||
DCHECK(!it->done());
|
DCHECK(cit->HasCurrent());
|
||||||
DCHECK(it->rinfo()->rmode() == RelocInfo::COMMENT);
|
const char* comment_txt = cit->GetComment();
|
||||||
const char* tmp = reinterpret_cast<const char*>(it->rinfo()->data());
|
if (comment_txt[0] != '[') {
|
||||||
if (tmp[0] != '[') {
|
|
||||||
// Not a nested comment; skip
|
// Not a nested comment; skip
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for end of nested comment or a new nested comment
|
// Search for end of nested comment or a new nested comment
|
||||||
const char* const comment_txt =
|
int prev_pc_offset = cit->GetPCOffset();
|
||||||
reinterpret_cast<const char*>(it->rinfo()->data());
|
|
||||||
Address prev_pc = it->rinfo()->pc();
|
|
||||||
int flat_delta = 0;
|
int flat_delta = 0;
|
||||||
it->next();
|
cit->Next();
|
||||||
while (true) {
|
for (; cit->HasCurrent(); cit->Next()) {
|
||||||
// All nested comments must be terminated properly, and therefore exit
|
// All nested comments must be terminated properly, and therefore exit
|
||||||
// from loop.
|
// from loop.
|
||||||
DCHECK(!it->done());
|
const char* const txt = cit->GetComment();
|
||||||
if (it->rinfo()->rmode() == RelocInfo::COMMENT) {
|
flat_delta += cit->GetPCOffset() - prev_pc_offset;
|
||||||
const char* const txt =
|
if (txt[0] == ']') break; // End of nested comment
|
||||||
reinterpret_cast<const char*>(it->rinfo()->data());
|
// A new comment
|
||||||
flat_delta += static_cast<int>(it->rinfo()->pc() - prev_pc);
|
CollectCommentStatistics(isolate, cit);
|
||||||
if (txt[0] == ']') break; // End of nested comment
|
// Skip code that was covered with previous comment
|
||||||
// A new comment
|
prev_pc_offset = cit->GetPCOffset();
|
||||||
CollectCommentStatistics(isolate, it);
|
|
||||||
// Skip code that was covered with previous comment
|
|
||||||
prev_pc = it->rinfo()->pc();
|
|
||||||
}
|
|
||||||
it->next();
|
|
||||||
}
|
}
|
||||||
EnterComment(isolate, comment_txt, flat_delta);
|
EnterComment(isolate, comment_txt, flat_delta);
|
||||||
}
|
}
|
||||||
@ -208,21 +201,18 @@ void CodeStatistics::CollectCodeCommentStatistics(HeapObject* obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Code code = Code::cast(obj);
|
Code code = Code::cast(obj);
|
||||||
RelocIterator it(code);
|
CodeCommentsIterator cit(code->code_comments());
|
||||||
int delta = 0;
|
int delta = 0;
|
||||||
Address prev_pc = code->raw_instruction_start();
|
int prev_pc_offset = 0;
|
||||||
while (!it.done()) {
|
while (cit.HasCurrent()) {
|
||||||
if (it.rinfo()->rmode() == RelocInfo::COMMENT) {
|
delta += static_cast<int>(cit.GetPCOffset() - prev_pc_offset);
|
||||||
delta += static_cast<int>(it.rinfo()->pc() - prev_pc);
|
CollectCommentStatistics(isolate, &cit);
|
||||||
CollectCommentStatistics(isolate, &it);
|
prev_pc_offset = cit.GetPCOffset();
|
||||||
prev_pc = it.rinfo()->pc();
|
cit.Next();
|
||||||
}
|
|
||||||
it.next();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DCHECK(code->raw_instruction_start() <= prev_pc &&
|
DCHECK(0 <= prev_pc_offset && prev_pc_offset <= code->raw_instruction_size());
|
||||||
prev_pc <= code->raw_instruction_end());
|
delta += static_cast<int>(code->raw_instruction_size() - prev_pc_offset);
|
||||||
delta += static_cast<int>(code->raw_instruction_end() - prev_pc);
|
|
||||||
EnterComment(isolate, "NoComment", delta);
|
EnterComment(isolate, "NoComment", delta);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
class Isolate;
|
class CodeCommentsIterator;
|
||||||
class HeapObject;
|
class HeapObject;
|
||||||
|
class Isolate;
|
||||||
class LargeObjectSpace;
|
class LargeObjectSpace;
|
||||||
class PagedSpace;
|
class PagedSpace;
|
||||||
class RelocIterator;
|
|
||||||
|
|
||||||
class CodeStatistics {
|
class CodeStatistics {
|
||||||
public:
|
public:
|
||||||
@ -35,7 +35,8 @@ class CodeStatistics {
|
|||||||
Isolate* isolate);
|
Isolate* isolate);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void CollectCommentStatistics(Isolate* isolate, RelocIterator* it);
|
static void CollectCommentStatistics(Isolate* isolate,
|
||||||
|
CodeCommentsIterator* it);
|
||||||
static void CollectCodeCommentStatistics(HeapObject* obj, Isolate* isolate);
|
static void CollectCodeCommentStatistics(HeapObject* obj, Isolate* isolate);
|
||||||
static void EnterComment(Isolate* isolate, const char* comment, int delta);
|
static void EnterComment(Isolate* isolate, const char* comment, int delta);
|
||||||
static void ResetCodeStatistics(Isolate* isolate);
|
static void ResetCodeStatistics(Isolate* isolate);
|
||||||
|
@ -87,7 +87,8 @@ void InitializeCode(Heap* heap, Handle<Code> code, int object_size,
|
|||||||
code->set_deoptimization_data(*deopt_data);
|
code->set_deoptimization_data(*deopt_data);
|
||||||
code->set_stub_key(stub_key);
|
code->set_stub_key(stub_key);
|
||||||
code->set_source_position_table(*source_position_table);
|
code->set_source_position_table(*source_position_table);
|
||||||
code->set_constant_pool_offset(desc.instr_size - desc.constant_pool_size);
|
code->set_constant_pool_offset(desc.constant_pool_offset());
|
||||||
|
code->set_code_comments_offset(desc.code_comments_offset());
|
||||||
code->set_builtin_index(builtin_index);
|
code->set_builtin_index(builtin_index);
|
||||||
|
|
||||||
// Allow self references to created code object by patching the handle to
|
// Allow self references to created code object by patching the handle to
|
||||||
@ -2826,6 +2827,7 @@ Handle<Code> Factory::NewOffHeapTrampolineFor(Handle<Code> code,
|
|||||||
if (code->has_safepoint_info()) {
|
if (code->has_safepoint_info()) {
|
||||||
result->set_safepoint_table_offset(code->safepoint_table_offset());
|
result->set_safepoint_table_offset(code->safepoint_table_offset());
|
||||||
}
|
}
|
||||||
|
result->set_code_comments_offset(code->code_comments_offset());
|
||||||
|
|
||||||
// Replace the newly generated trampoline's RelocInfo ByteArray with the
|
// Replace the newly generated trampoline's RelocInfo ByteArray with the
|
||||||
// canonical one stored in the roots to avoid duplicating it for every
|
// canonical one stored in the roots to avoid duplicating it for every
|
||||||
|
@ -340,6 +340,7 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
||||||
|
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
|
||||||
// that we are still not overlapping instructions and relocation info).
|
// that we are still not overlapping instructions and relocation info).
|
||||||
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
||||||
@ -355,6 +356,7 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->constant_pool_size = 0;
|
desc->constant_pool_size = 0;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
|
|
||||||
// Collection stage
|
// Collection stage
|
||||||
auto jump_opt = jump_optimization_info();
|
auto jump_opt = jump_optimization_info();
|
||||||
@ -400,7 +402,6 @@ bool Assembler::IsNop(Address addr) {
|
|||||||
|
|
||||||
void Assembler::Nop(int bytes) {
|
void Assembler::Nop(int bytes) {
|
||||||
EnsureSpace ensure_space(this);
|
EnsureSpace ensure_space(this);
|
||||||
|
|
||||||
// Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
|
// Multi byte nops from http://support.amd.com/us/Processor_TechDocs/40546.pdf
|
||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
switch (bytes) {
|
switch (bytes) {
|
||||||
|
@ -1722,9 +1722,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
return pc_offset() - label->pos();
|
return pc_offset() - label->pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use --code-comments to enable.
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -1849,6 +1846,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
|
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class EnsureSpace;
|
friend class EnsureSpace;
|
||||||
|
|
||||||
// Internal reference positions, required for (potential) patching in
|
// Internal reference positions, required for (potential) patching in
|
||||||
|
31
src/lsan.h
31
src/lsan.h
@ -1,31 +0,0 @@
|
|||||||
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// LeakSanitizer support.
|
|
||||||
|
|
||||||
#ifndef V8_LSAN_H_
|
|
||||||
#define V8_LSAN_H_
|
|
||||||
|
|
||||||
#include "src/base/macros.h"
|
|
||||||
#include "src/globals.h"
|
|
||||||
|
|
||||||
// There is no compile time flag for LSan, to enable this whenever ASan is
|
|
||||||
// enabled. Note that LSan can be used as part of ASan with 'detect_leaks=1'.
|
|
||||||
// On windows, LSan is not implemented yet, so disable it there.
|
|
||||||
#if defined(V8_USE_ADDRESS_SANITIZER) && !defined(V8_OS_WIN)
|
|
||||||
|
|
||||||
#include <sanitizer/lsan_interface.h>
|
|
||||||
|
|
||||||
#define LSAN_IGNORE_OBJECT(ptr) __lsan_ignore_object(ptr)
|
|
||||||
|
|
||||||
#else // defined(V8_USE_ADDRESS_SANITIZER) && !defined(V8_OS_WIN)
|
|
||||||
|
|
||||||
#define LSAN_IGNORE_OBJECT(ptr) \
|
|
||||||
static_assert(std::is_pointer<decltype(ptr)>::value || \
|
|
||||||
std::is_same<v8::internal::Address, decltype(ptr)>::value, \
|
|
||||||
"static type violation")
|
|
||||||
|
|
||||||
#endif // defined(V8_USE_ADDRESS_SANITIZER) && !defined(V8_OS_WIN)
|
|
||||||
|
|
||||||
#endif // V8_LSAN_H_
|
|
@ -339,6 +339,9 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
|
|||||||
|
|
||||||
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
||||||
EmitForbiddenSlotInstruction();
|
EmitForbiddenSlotInstruction();
|
||||||
|
|
||||||
|
int code_comments_size = WriteCodeComments();
|
||||||
|
|
||||||
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
||||||
|
|
||||||
AllocateAndInstallRequestedHeapObjects(isolate);
|
AllocateAndInstallRequestedHeapObjects(isolate);
|
||||||
@ -352,6 +355,7 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->constant_pool_size = 0;
|
desc->constant_pool_size = 0;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1728,10 +1728,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Record a comment relocation entry that can be used by a disassembler.
|
|
||||||
// Use --code-comments to enable.
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -2233,6 +2229,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
private:
|
private:
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class RegExpMacroAssemblerMIPS;
|
friend class RegExpMacroAssemblerMIPS;
|
||||||
friend class RelocInfo;
|
friend class RelocInfo;
|
||||||
friend class BlockTrampolinePoolScope;
|
friend class BlockTrampolinePoolScope;
|
||||||
|
@ -316,6 +316,9 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
|
|||||||
|
|
||||||
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
||||||
EmitForbiddenSlotInstruction();
|
EmitForbiddenSlotInstruction();
|
||||||
|
|
||||||
|
int code_comments_size = WriteCodeComments();
|
||||||
|
|
||||||
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
||||||
|
|
||||||
AllocateAndInstallRequestedHeapObjects(isolate);
|
AllocateAndInstallRequestedHeapObjects(isolate);
|
||||||
@ -330,6 +333,7 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->constant_pool_size = 0;
|
desc->constant_pool_size = 0;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1796,10 +1796,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockGrowBufferScope);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Record a comment relocation entry that can be used by a disassembler.
|
|
||||||
// Use --code-comments to enable.
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -2268,6 +2264,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
private:
|
private:
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class RegExpMacroAssemblerMIPS;
|
friend class RegExpMacroAssemblerMIPS;
|
||||||
friend class RelocInfo;
|
friend class RelocInfo;
|
||||||
friend class BlockTrampolinePoolScope;
|
friend class BlockTrampolinePoolScope;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "src/objects.h"
|
#include "src/objects.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -14752,13 +14753,10 @@ bool Code::IsIsolateIndependent(Isolate* isolate) {
|
|||||||
constexpr int all_real_modes_mask =
|
constexpr int all_real_modes_mask =
|
||||||
(1 << (RelocInfo::LAST_REAL_RELOC_MODE + 1)) - 1;
|
(1 << (RelocInfo::LAST_REAL_RELOC_MODE + 1)) - 1;
|
||||||
constexpr int mode_mask = all_real_modes_mask &
|
constexpr int mode_mask = all_real_modes_mask &
|
||||||
~RelocInfo::ModeMask(RelocInfo::COMMENT) &
|
|
||||||
~RelocInfo::ModeMask(RelocInfo::CONST_POOL) &
|
~RelocInfo::ModeMask(RelocInfo::CONST_POOL) &
|
||||||
~RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) &
|
~RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) &
|
||||||
~RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
|
~RelocInfo::ModeMask(RelocInfo::VENEER_POOL);
|
||||||
STATIC_ASSERT(RelocInfo::LAST_REAL_RELOC_MODE == RelocInfo::VENEER_POOL);
|
STATIC_ASSERT(RelocInfo::LAST_REAL_RELOC_MODE == RelocInfo::VENEER_POOL);
|
||||||
STATIC_ASSERT(RelocInfo::ModeMask(RelocInfo::COMMENT) ==
|
|
||||||
(1 << RelocInfo::COMMENT));
|
|
||||||
STATIC_ASSERT(mode_mask ==
|
STATIC_ASSERT(mode_mask ==
|
||||||
(RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
|
(RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
|
||||||
RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
|
RelocInfo::ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
|
||||||
@ -15141,23 +15139,26 @@ void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) {
|
|||||||
int size = InstructionSize();
|
int size = InstructionSize();
|
||||||
int safepoint_offset =
|
int safepoint_offset =
|
||||||
has_safepoint_info() ? safepoint_table_offset() : size;
|
has_safepoint_info() ? safepoint_table_offset() : size;
|
||||||
int constant_pool_offset = this->constant_pool_offset();
|
int const_pool_offset =
|
||||||
|
constant_pool_offset() ? constant_pool_offset() : size;
|
||||||
int handler_offset = handler_table_offset() ? handler_table_offset() : size;
|
int handler_offset = handler_table_offset() ? handler_table_offset() : size;
|
||||||
|
int comments_offset =
|
||||||
|
code_comments_offset() ? code_comments_offset() : size;
|
||||||
|
|
||||||
// Stop before reaching any embedded tables
|
// Stop before reaching any embedded tables
|
||||||
int code_size =
|
int code_size = std::min(
|
||||||
Min(handler_offset, Min(safepoint_offset, constant_pool_offset));
|
{handler_offset, safepoint_offset, const_pool_offset, comments_offset});
|
||||||
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);
|
||||||
|
|
||||||
if (constant_pool_offset < size) {
|
if (const_pool_offset != size) {
|
||||||
int constant_pool_size = safepoint_offset - constant_pool_offset;
|
int constant_pool_size = comments_offset - const_pool_offset;
|
||||||
DCHECK_EQ(constant_pool_size & kPointerAlignmentMask, 0);
|
DCHECK_EQ(constant_pool_size & kPointerAlignmentMask, 0);
|
||||||
os << "\nConstant Pool (size = " << constant_pool_size << ")\n";
|
os << "\nConstant Pool (size = " << constant_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*>(InstructionStart() + const_pool_offset);
|
||||||
for (int i = 0; i < constant_pool_size; i += kPointerSize, ptr++) {
|
for (int i = 0; i < constant_pool_size; i += kPointerSize, ptr++) {
|
||||||
SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
|
SNPrintF(buf, "%4d %08" V8PRIxPTR, i, *ptr);
|
||||||
os << static_cast<const void*>(ptr) << " " << buf.start() << "\n";
|
os << static_cast<const void*>(ptr) << " " << buf.start() << "\n";
|
||||||
@ -15234,6 +15235,10 @@ void Code::Disassemble(const char* name, std::ostream& os, Address current_pc) {
|
|||||||
eh_frame_disassembler.DisassembleToStream(os);
|
eh_frame_disassembler.DisassembleToStream(os);
|
||||||
os << "\n";
|
os << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (code_comments_offset() > 0) {
|
||||||
|
PrintCodeCommentsSection(os, code_comments());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // ENABLE_DISASSEMBLER
|
#endif // ENABLE_DISASSEMBLER
|
||||||
|
|
||||||
|
@ -483,14 +483,21 @@ inline HandlerTable::CatchPrediction Code::GetBuiltinCatchPrediction() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Code::builtin_index() const {
|
int Code::builtin_index() const {
|
||||||
int index = READ_INT_FIELD(this, kBuiltinIndexOffset);
|
int data = READ_UINT32_FIELD(this, kBuiltinIndexAndCodeCommentsOffset);
|
||||||
|
int index = BuiltinIndexField::decode(data);
|
||||||
|
if (index == BuiltinIndexField::kMax) index = -1;
|
||||||
DCHECK(index == -1 || Builtins::IsBuiltinId(index));
|
DCHECK(index == -1 || Builtins::IsBuiltinId(index));
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Code::set_builtin_index(int index) {
|
void Code::set_builtin_index(int index) {
|
||||||
DCHECK(index == -1 || Builtins::IsBuiltinId(index));
|
DCHECK(index == -1 || Builtins::IsBuiltinId(index));
|
||||||
WRITE_INT_FIELD(this, kBuiltinIndexOffset, index);
|
static_assert(Builtins::builtin_count <= BuiltinIndexField::kMax,
|
||||||
|
"BuiltinIndexField too small");
|
||||||
|
int data = READ_UINT32_FIELD(this, kBuiltinIndexAndCodeCommentsOffset);
|
||||||
|
if (index == -1) index = BuiltinIndexField::kMax;
|
||||||
|
data = BuiltinIndexField::update(data, index);
|
||||||
|
WRITE_INT_FIELD(this, kBuiltinIndexAndCodeCommentsOffset, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Code::is_builtin() const { return builtin_index() != -1; }
|
bool Code::is_builtin() const { return builtin_index() != -1; }
|
||||||
@ -563,25 +570,48 @@ bool Code::is_optimized_code() const { return kind() == OPTIMIZED_FUNCTION; }
|
|||||||
bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
|
bool Code::is_wasm_code() const { return kind() == WASM_FUNCTION; }
|
||||||
|
|
||||||
int Code::constant_pool_offset() const {
|
int Code::constant_pool_offset() const {
|
||||||
if (!FLAG_enable_embedded_constant_pool) return InstructionSize();
|
if (!FLAG_enable_embedded_constant_pool) return 0;
|
||||||
return READ_INT_FIELD(this, kConstantPoolOffset);
|
return READ_INT_FIELD(this, kConstantPoolOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
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_LT(value, InstructionSize());
|
||||||
WRITE_INT_FIELD(this, kConstantPoolOffset, value);
|
WRITE_INT_FIELD(this, kConstantPoolOffset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Address Code::constant_pool() const {
|
Address Code::constant_pool() const {
|
||||||
if (FLAG_enable_embedded_constant_pool) {
|
if (FLAG_enable_embedded_constant_pool) {
|
||||||
int offset = constant_pool_offset();
|
int offset = constant_pool_offset();
|
||||||
if (offset < InstructionSize()) {
|
DCHECK(offset < InstructionSize());
|
||||||
|
if (offset != 0) {
|
||||||
return InstructionStart() + offset;
|
return InstructionStart() + offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return kNullAddress;
|
return kNullAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Code::code_comments_offset() const {
|
||||||
|
int data = READ_UINT32_FIELD(this, kBuiltinIndexAndCodeCommentsOffset);
|
||||||
|
int offset = CodeCommentsOffsetField::decode(data);
|
||||||
|
return offset * kCodeCommentsOffsetFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Code::set_code_comments_offset(int offset) {
|
||||||
|
DCHECK_EQ(offset % kCodeCommentsOffsetFactor, 0);
|
||||||
|
offset /= kCodeCommentsOffsetFactor;
|
||||||
|
int data = READ_UINT32_FIELD(this, kBuiltinIndexAndCodeCommentsOffset);
|
||||||
|
DCHECK_LE(offset, CodeCommentsOffsetField::kMax);
|
||||||
|
data = CodeCommentsOffsetField::update(data, offset);
|
||||||
|
WRITE_INT_FIELD(this, kBuiltinIndexAndCodeCommentsOffset, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Address Code::code_comments() const {
|
||||||
|
int offset = code_comments_offset();
|
||||||
|
CHECK(offset < InstructionSize());
|
||||||
|
return offset == 0 ? kNullAddress : InstructionStart() + offset;
|
||||||
|
}
|
||||||
|
|
||||||
Code Code::GetCodeFromTargetAddress(Address address) {
|
Code Code::GetCodeFromTargetAddress(Address address) {
|
||||||
{
|
{
|
||||||
// TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
|
// TODO(jgruber,v8:6666): Support embedded builtins here. We'd need to pass
|
||||||
|
@ -105,6 +105,11 @@ class Code : public HeapObjectPtr {
|
|||||||
inline int constant_pool_offset() const;
|
inline int constant_pool_offset() const;
|
||||||
inline void set_constant_pool_offset(int offset);
|
inline void set_constant_pool_offset(int offset);
|
||||||
|
|
||||||
|
// [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.
|
// Unchecked accessors to be used during GC.
|
||||||
inline ByteArray unchecked_relocation_info() const;
|
inline ByteArray unchecked_relocation_info() const;
|
||||||
|
|
||||||
@ -387,7 +392,7 @@ class Code : public HeapObjectPtr {
|
|||||||
V(kHandlerTableOffsetOffset, kIntSize) \
|
V(kHandlerTableOffsetOffset, kIntSize) \
|
||||||
V(kStubKeyOffset, kIntSize) \
|
V(kStubKeyOffset, kIntSize) \
|
||||||
V(kConstantPoolOffset, FLAG_enable_embedded_constant_pool ? kIntSize : 0) \
|
V(kConstantPoolOffset, FLAG_enable_embedded_constant_pool ? kIntSize : 0) \
|
||||||
V(kBuiltinIndexOffset, kIntSize) \
|
V(kBuiltinIndexAndCodeCommentsOffset, kIntSize) \
|
||||||
/* 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(kHeaderPaddingStart, CODE_POINTER_PADDING(kHeaderPaddingStart)) \
|
V(kHeaderPaddingStart, CODE_POINTER_PADDING(kHeaderPaddingStart)) \
|
||||||
@ -426,6 +431,18 @@ class Code : public HeapObjectPtr {
|
|||||||
#undef CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS
|
#undef CODE_KIND_SPECIFIC_FLAGS_BIT_FIELDS
|
||||||
static_assert(IsExceptionCaughtField::kNext <= 32, "KindSpecificFlags full");
|
static_assert(IsExceptionCaughtField::kNext <= 32, "KindSpecificFlags full");
|
||||||
|
|
||||||
|
// BuiltinIndexAndCodeComments field
|
||||||
|
#define BUILTIN_INDEX_AND_CODE_COMMENTS_BIT_FIELDS(V, _) \
|
||||||
|
V(BuiltinIndexField, int, 11, _) \
|
||||||
|
V(CodeCommentsOffsetField, int, 21, _)
|
||||||
|
DEFINE_BIT_FIELDS(BUILTIN_INDEX_AND_CODE_COMMENTS_BIT_FIELDS)
|
||||||
|
#undef BUILTIN_INDEX_AND_CODE_COMMENTS_BIT_FIELDS
|
||||||
|
static_assert(CodeCommentsOffsetField::kNext <= 32,
|
||||||
|
"BuiltinIndexAndCodeCommentsFlags full");
|
||||||
|
|
||||||
|
// Code comment offset must be a multiple of {kCodeCommentsOffsetFactor}.
|
||||||
|
static constexpr uint8_t kCodeCommentsOffsetFactor = 128;
|
||||||
|
|
||||||
// The {marked_for_deoptimization} field is accessed from generated code.
|
// The {marked_for_deoptimization} field is accessed from generated code.
|
||||||
static const int kMarkedForDeoptimizationBit =
|
static const int kMarkedForDeoptimizationBit =
|
||||||
MarkedForDeoptimizationField::kShift;
|
MarkedForDeoptimizationField::kShift;
|
||||||
|
@ -265,9 +265,12 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
|
|||||||
|
|
||||||
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
||||||
// Emit constant pool if necessary.
|
// Emit constant pool if necessary.
|
||||||
int constant_pool_offset = EmitConstantPool();
|
int constant_pool_size = EmitConstantPool();
|
||||||
|
|
||||||
EmitRelocations();
|
EmitRelocations();
|
||||||
|
|
||||||
|
int code_comments_size = WriteCodeComments();
|
||||||
|
|
||||||
AllocateAndInstallRequestedHeapObjects(isolate);
|
AllocateAndInstallRequestedHeapObjects(isolate);
|
||||||
|
|
||||||
// Set up code descriptor.
|
// Set up code descriptor.
|
||||||
@ -275,11 +278,11 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->buffer_size = buffer_size_;
|
desc->buffer_size = buffer_size_;
|
||||||
desc->instr_size = pc_offset();
|
desc->instr_size = pc_offset();
|
||||||
desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
|
desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
|
||||||
desc->constant_pool_size =
|
desc->constant_pool_size = constant_pool_size;
|
||||||
(constant_pool_offset ? desc->instr_size - constant_pool_offset : 0);
|
|
||||||
desc->origin = this;
|
desc->origin = this;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1335,10 +1335,6 @@ class Assembler : public AssemblerBase {
|
|||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstantPoolEntrySharingScope);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(BlockConstantPoolEntrySharingScope);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Record a comment relocation entry that can be used by a disassembler.
|
|
||||||
// Use --code-comments to enable.
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -1622,6 +1618,8 @@ class Assembler : public AssemblerBase {
|
|||||||
|
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class RegExpMacroAssemblerPPC;
|
friend class RegExpMacroAssemblerPPC;
|
||||||
friend class RelocInfo;
|
friend class RelocInfo;
|
||||||
friend class BlockTrampolinePoolScope;
|
friend class BlockTrampolinePoolScope;
|
||||||
|
@ -159,9 +159,7 @@ void RelocInfoWriter::Write(const RelocInfo* rinfo) {
|
|||||||
WriteShortTaggedPC(pc_delta, kWasmStubCallTag);
|
WriteShortTaggedPC(pc_delta, kWasmStubCallTag);
|
||||||
} else {
|
} else {
|
||||||
WriteModeAndPC(pc_delta, rmode);
|
WriteModeAndPC(pc_delta, rmode);
|
||||||
if (RelocInfo::IsComment(rmode)) {
|
if (RelocInfo::IsDeoptReason(rmode)) {
|
||||||
WriteData(rinfo->data());
|
|
||||||
} else if (RelocInfo::IsDeoptReason(rmode)) {
|
|
||||||
DCHECK_LT(rinfo->data(), 1 << kBitsPerByte);
|
DCHECK_LT(rinfo->data(), 1 << kBitsPerByte);
|
||||||
WriteShortData(rinfo->data());
|
WriteShortData(rinfo->data());
|
||||||
} else if (RelocInfo::IsConstPool(rmode) ||
|
} else if (RelocInfo::IsConstPool(rmode) ||
|
||||||
@ -250,13 +248,7 @@ void RelocIterator::next() {
|
|||||||
AdvanceReadLongPCJump();
|
AdvanceReadLongPCJump();
|
||||||
} else {
|
} else {
|
||||||
AdvanceReadPC();
|
AdvanceReadPC();
|
||||||
if (RelocInfo::IsComment(rmode)) {
|
if (RelocInfo::IsDeoptReason(rmode)) {
|
||||||
if (SetMode(rmode)) {
|
|
||||||
AdvanceReadData();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Advance(kIntptrSize);
|
|
||||||
} else if (RelocInfo::IsDeoptReason(rmode)) {
|
|
||||||
Advance();
|
Advance();
|
||||||
if (SetMode(rmode)) {
|
if (SetMode(rmode)) {
|
||||||
ReadShortData();
|
ReadShortData();
|
||||||
@ -404,8 +396,6 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
|
|||||||
return "relative code target";
|
return "relative code target";
|
||||||
case RUNTIME_ENTRY:
|
case RUNTIME_ENTRY:
|
||||||
return "runtime entry";
|
return "runtime entry";
|
||||||
case COMMENT:
|
|
||||||
return "comment";
|
|
||||||
case EXTERNAL_REFERENCE:
|
case EXTERNAL_REFERENCE:
|
||||||
return "external reference";
|
return "external reference";
|
||||||
case INTERNAL_REFERENCE:
|
case INTERNAL_REFERENCE:
|
||||||
@ -439,9 +429,7 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
|
|||||||
|
|
||||||
void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT
|
void RelocInfo::Print(Isolate* isolate, std::ostream& os) { // NOLINT
|
||||||
os << reinterpret_cast<const void*>(pc_) << " " << RelocModeName(rmode_);
|
os << reinterpret_cast<const void*>(pc_) << " " << RelocModeName(rmode_);
|
||||||
if (IsComment(rmode_)) {
|
if (rmode_ == DEOPT_SCRIPT_OFFSET || rmode_ == DEOPT_INLINING_ID) {
|
||||||
os << " (" << reinterpret_cast<char*>(data_) << ")";
|
|
||||||
} else if (rmode_ == DEOPT_SCRIPT_OFFSET || rmode_ == DEOPT_INLINING_ID) {
|
|
||||||
os << " (" << data() << ")";
|
os << " (" << data() << ")";
|
||||||
} else if (rmode_ == DEOPT_REASON) {
|
} else if (rmode_ == DEOPT_REASON) {
|
||||||
os << " ("
|
os << " ("
|
||||||
@ -518,7 +506,6 @@ void RelocInfo::Verify(Isolate* isolate) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RUNTIME_ENTRY:
|
case RUNTIME_ENTRY:
|
||||||
case COMMENT:
|
|
||||||
case EXTERNAL_REFERENCE:
|
case EXTERNAL_REFERENCE:
|
||||||
case DEOPT_SCRIPT_OFFSET:
|
case DEOPT_SCRIPT_OFFSET:
|
||||||
case DEOPT_INLINING_ID:
|
case DEOPT_INLINING_ID:
|
||||||
|
@ -62,7 +62,6 @@ class RelocInfo {
|
|||||||
WASM_STUB_CALL,
|
WASM_STUB_CALL,
|
||||||
|
|
||||||
RUNTIME_ENTRY,
|
RUNTIME_ENTRY,
|
||||||
COMMENT,
|
|
||||||
|
|
||||||
EXTERNAL_REFERENCE, // The address of an external C++ function.
|
EXTERNAL_REFERENCE, // The address of an external C++ function.
|
||||||
INTERNAL_REFERENCE, // An address inside the same function.
|
INTERNAL_REFERENCE, // An address inside the same function.
|
||||||
@ -141,7 +140,6 @@ class RelocInfo {
|
|||||||
static constexpr bool IsWasmStubCall(Mode mode) {
|
static constexpr bool IsWasmStubCall(Mode mode) {
|
||||||
return mode == WASM_STUB_CALL;
|
return mode == WASM_STUB_CALL;
|
||||||
}
|
}
|
||||||
static constexpr bool IsComment(Mode mode) { return mode == COMMENT; }
|
|
||||||
static constexpr bool IsConstPool(Mode mode) { return mode == CONST_POOL; }
|
static constexpr bool IsConstPool(Mode mode) { return mode == CONST_POOL; }
|
||||||
static constexpr bool IsVeneerPool(Mode mode) { return mode == VENEER_POOL; }
|
static constexpr bool IsVeneerPool(Mode mode) { return mode == VENEER_POOL; }
|
||||||
static constexpr bool IsDeoptPosition(Mode mode) {
|
static constexpr bool IsDeoptPosition(Mode mode) {
|
||||||
|
@ -366,6 +366,8 @@ Assembler::Assembler(const AssemblerOptions& options, void* buffer,
|
|||||||
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
||||||
EmitRelocations();
|
EmitRelocations();
|
||||||
|
|
||||||
|
int code_comments_size = WriteCodeComments();
|
||||||
|
|
||||||
AllocateAndInstallRequestedHeapObjects(isolate);
|
AllocateAndInstallRequestedHeapObjects(isolate);
|
||||||
|
|
||||||
// Set up code descriptor.
|
// Set up code descriptor.
|
||||||
@ -377,6 +379,7 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->origin = this;
|
desc->origin = this;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Assembler::Align(int m) {
|
void Assembler::Align(int m) {
|
||||||
|
@ -1491,10 +1491,6 @@ inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) {
|
|||||||
return pc_offset() - label->pos();
|
return pc_offset() - label->pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record a comment relocation entry that can be used by a disassembler.
|
|
||||||
// Use --code-comments to enable.
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -1655,6 +1651,8 @@ inline void ss_a_format(Opcode op, int f1, int f2, int f3, int f4, int f5) {
|
|||||||
|
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class RegExpMacroAssemblerS390;
|
friend class RegExpMacroAssemblerS390;
|
||||||
friend class RelocInfo;
|
friend class RelocInfo;
|
||||||
friend class EnsureSpace;
|
friend class EnsureSpace;
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include "src/builtins/constants-table-builder.h"
|
#include "src/builtins/constants-table-builder.h"
|
||||||
#include "src/isolate-data.h"
|
#include "src/isolate-data.h"
|
||||||
#include "src/isolate-inl.h"
|
#include "src/isolate-inl.h"
|
||||||
#include "src/lsan.h"
|
|
||||||
#include "src/snapshot/serializer-common.h"
|
#include "src/snapshot/serializer-common.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
@ -118,14 +117,9 @@ bool TurboAssemblerBase::IsAddressableThroughRootRegister(
|
|||||||
|
|
||||||
void TurboAssemblerBase::RecordCommentForOffHeapTrampoline(int builtin_index) {
|
void TurboAssemblerBase::RecordCommentForOffHeapTrampoline(int builtin_index) {
|
||||||
if (!FLAG_code_comments) return;
|
if (!FLAG_code_comments) return;
|
||||||
size_t len = strlen("-- Inlined Trampoline to --") +
|
std::ostringstream str;
|
||||||
strlen(Builtins::name(builtin_index)) + 1;
|
str << "-- Inlined Trampoline to " << Builtins::name(builtin_index) << " --";
|
||||||
Vector<char> buffer = Vector<char>::New(static_cast<int>(len));
|
RecordComment(str.str().c_str());
|
||||||
char* buffer_start = buffer.start();
|
|
||||||
LSAN_IGNORE_OBJECT(buffer_start);
|
|
||||||
SNPrintF(buffer, "-- Inlined Trampoline to %s --",
|
|
||||||
Builtins::name(builtin_index));
|
|
||||||
RecordComment(buffer_start);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
@ -112,6 +112,11 @@ Address WasmCode::constant_pool() const {
|
|||||||
return kNullAddress;
|
return kNullAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Address WasmCode::code_comments() const {
|
||||||
|
if (code_comments_offset() <= 0) return kNullAddress;
|
||||||
|
return instruction_start() + code_comments_offset_;
|
||||||
|
}
|
||||||
|
|
||||||
size_t WasmCode::trap_handler_index() const {
|
size_t WasmCode::trap_handler_index() const {
|
||||||
CHECK(HasTrapHandlerIndex());
|
CHECK(HasTrapHandlerIndex());
|
||||||
return static_cast<size_t>(trap_handler_index_);
|
return static_cast<size_t>(trap_handler_index_);
|
||||||
@ -227,7 +232,6 @@ void WasmCode::Validate() const {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RelocInfo::EXTERNAL_REFERENCE:
|
case RelocInfo::EXTERNAL_REFERENCE:
|
||||||
case RelocInfo::COMMENT:
|
|
||||||
case RelocInfo::CONST_POOL:
|
case RelocInfo::CONST_POOL:
|
||||||
case RelocInfo::VENEER_POOL:
|
case RelocInfo::VENEER_POOL:
|
||||||
// These are OK to appear.
|
// These are OK to appear.
|
||||||
@ -257,6 +261,9 @@ void WasmCode::Disassemble(const char* name, std::ostream& os,
|
|||||||
|
|
||||||
#ifdef ENABLE_DISASSEMBLER
|
#ifdef ENABLE_DISASSEMBLER
|
||||||
size_t instruction_size = body_size;
|
size_t instruction_size = body_size;
|
||||||
|
if (code_comments_offset_ && code_comments_offset_ < instruction_size) {
|
||||||
|
instruction_size = code_comments_offset_;
|
||||||
|
}
|
||||||
if (constant_pool_offset_ && constant_pool_offset_ < instruction_size) {
|
if (constant_pool_offset_ && constant_pool_offset_ < instruction_size) {
|
||||||
instruction_size = constant_pool_offset_;
|
instruction_size = constant_pool_offset_;
|
||||||
}
|
}
|
||||||
@ -307,6 +314,12 @@ void WasmCode::Disassemble(const char* name, std::ostream& os,
|
|||||||
it.rinfo()->Print(nullptr, os);
|
it.rinfo()->Print(nullptr, os);
|
||||||
}
|
}
|
||||||
os << "\n";
|
os << "\n";
|
||||||
|
|
||||||
|
if (code_comments_offset() > 0) {
|
||||||
|
Address code_comments = reinterpret_cast<Address>(instructions().start() +
|
||||||
|
code_comments_offset());
|
||||||
|
PrintCodeCommentsSection(os, code_comments);
|
||||||
|
}
|
||||||
#endif // ENABLE_DISASSEMBLER
|
#endif // ENABLE_DISASSEMBLER
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +405,7 @@ CompilationEnv NativeModule::CreateCompilationEnv() const {
|
|||||||
WasmCode* NativeModule::AddOwnedCode(
|
WasmCode* NativeModule::AddOwnedCode(
|
||||||
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
|
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
|
||||||
size_t safepoint_table_offset, size_t handler_table_offset,
|
size_t safepoint_table_offset, size_t handler_table_offset,
|
||||||
size_t constant_pool_offset,
|
size_t constant_pool_offset, size_t code_comments_offset,
|
||||||
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
|
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
|
||||||
OwnedVector<const byte> reloc_info,
|
OwnedVector<const byte> reloc_info,
|
||||||
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
|
OwnedVector<const byte> source_position_table, WasmCode::Kind kind,
|
||||||
@ -404,11 +417,11 @@ WasmCode* NativeModule::AddOwnedCode(
|
|||||||
base::MutexGuard lock(&allocation_mutex_);
|
base::MutexGuard lock(&allocation_mutex_);
|
||||||
Vector<byte> executable_buffer = AllocateForCode(instructions.size());
|
Vector<byte> executable_buffer = AllocateForCode(instructions.size());
|
||||||
// Ownership will be transferred to {owned_code_} below.
|
// Ownership will be transferred to {owned_code_} below.
|
||||||
code = new WasmCode(this, index, executable_buffer, stack_slots,
|
code = new WasmCode(
|
||||||
safepoint_table_offset, handler_table_offset,
|
this, index, executable_buffer, stack_slots, safepoint_table_offset,
|
||||||
constant_pool_offset, std::move(protected_instructions),
|
handler_table_offset, constant_pool_offset, code_comments_offset,
|
||||||
std::move(reloc_info), std::move(source_position_table),
|
std::move(protected_instructions), std::move(reloc_info),
|
||||||
kind, tier);
|
std::move(source_position_table), kind, tier);
|
||||||
|
|
||||||
if (owned_code_.empty() ||
|
if (owned_code_.empty() ||
|
||||||
code->instruction_start() > owned_code_.back()->instruction_start()) {
|
code->instruction_start() > owned_code_.back()->instruction_start()) {
|
||||||
@ -492,6 +505,7 @@ WasmCode* NativeModule::AddAnonymousCode(Handle<Code> code, WasmCode::Kind kind,
|
|||||||
safepoint_table_offset, // safepoint_table_offset
|
safepoint_table_offset, // safepoint_table_offset
|
||||||
code->handler_table_offset(), // handler_table_offset
|
code->handler_table_offset(), // handler_table_offset
|
||||||
code->constant_pool_offset(), // constant_pool_offset
|
code->constant_pool_offset(), // constant_pool_offset
|
||||||
|
code->code_comments_offset(), // code_comments_offset
|
||||||
{}, // protected_instructions
|
{}, // protected_instructions
|
||||||
std::move(reloc_info), // reloc_info
|
std::move(reloc_info), // reloc_info
|
||||||
std::move(source_pos), // source positions
|
std::move(source_pos), // source positions
|
||||||
@ -537,12 +551,12 @@ WasmCode* NativeModule::AddCode(
|
|||||||
OwnedVector<byte> reloc_info = OwnedVector<byte>::New(desc.reloc_size);
|
OwnedVector<byte> reloc_info = OwnedVector<byte>::New(desc.reloc_size);
|
||||||
memcpy(reloc_info.start(), desc.buffer + desc.buffer_size - desc.reloc_size,
|
memcpy(reloc_info.start(), desc.buffer + desc.buffer_size - desc.reloc_size,
|
||||||
desc.reloc_size);
|
desc.reloc_size);
|
||||||
WasmCode* ret =
|
|
||||||
AddOwnedCode(index, {desc.buffer, static_cast<size_t>(desc.instr_size)},
|
WasmCode* ret = AddOwnedCode(
|
||||||
stack_slots, safepoint_table_offset, handler_table_offset,
|
index, {desc.buffer, static_cast<size_t>(desc.instr_size)}, stack_slots,
|
||||||
desc.instr_size - desc.constant_pool_size,
|
safepoint_table_offset, handler_table_offset, desc.constant_pool_offset(),
|
||||||
std::move(protected_instructions), std::move(reloc_info),
|
desc.code_comments_offset(), std::move(protected_instructions),
|
||||||
std::move(source_pos_table), kind, tier);
|
std::move(reloc_info), std::move(source_pos_table), kind, tier);
|
||||||
|
|
||||||
// Apply the relocation delta by iterating over the RelocInfo.
|
// Apply the relocation delta by iterating over the RelocInfo.
|
||||||
intptr_t delta = ret->instructions().start() - desc.buffer;
|
intptr_t delta = ret->instructions().start() - desc.buffer;
|
||||||
@ -581,15 +595,15 @@ WasmCode* NativeModule::AddCode(
|
|||||||
WasmCode* NativeModule::AddDeserializedCode(
|
WasmCode* NativeModule::AddDeserializedCode(
|
||||||
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
|
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
|
||||||
size_t safepoint_table_offset, size_t handler_table_offset,
|
size_t safepoint_table_offset, size_t handler_table_offset,
|
||||||
size_t constant_pool_offset,
|
size_t constant_pool_offset, size_t code_comments_offset,
|
||||||
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
|
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions,
|
||||||
OwnedVector<const byte> reloc_info,
|
OwnedVector<const byte> reloc_info,
|
||||||
OwnedVector<const byte> source_position_table, WasmCode::Tier tier) {
|
OwnedVector<const byte> source_position_table, WasmCode::Tier tier) {
|
||||||
WasmCode* code =
|
WasmCode* code = AddOwnedCode(
|
||||||
AddOwnedCode(index, instructions, stack_slots, safepoint_table_offset,
|
index, instructions, stack_slots, safepoint_table_offset,
|
||||||
handler_table_offset, constant_pool_offset,
|
handler_table_offset, constant_pool_offset, code_comments_offset,
|
||||||
std::move(protected_instructions), std::move(reloc_info),
|
std::move(protected_instructions), std::move(reloc_info),
|
||||||
std::move(source_position_table), WasmCode::kFunction, tier);
|
std::move(source_position_table), WasmCode::kFunction, tier);
|
||||||
|
|
||||||
if (!code->protected_instructions_.is_empty()) {
|
if (!code->protected_instructions_.is_empty()) {
|
||||||
code->RegisterTrapHandlerData();
|
code->RegisterTrapHandlerData();
|
||||||
@ -641,6 +655,7 @@ WasmCode* NativeModule::CreateEmptyJumpTable(uint32_t num_wasm_functions) {
|
|||||||
0, // safepoint_table_offset
|
0, // safepoint_table_offset
|
||||||
0, // handler_table_offset
|
0, // handler_table_offset
|
||||||
0, // constant_pool_offset
|
0, // constant_pool_offset
|
||||||
|
0, // code_comments_offset
|
||||||
{}, // protected_instructions
|
{}, // protected_instructions
|
||||||
{}, // reloc_info
|
{}, // reloc_info
|
||||||
{}, // source_pos
|
{}, // source_pos
|
||||||
|
@ -113,9 +113,11 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
|||||||
NativeModule* native_module() const { return native_module_; }
|
NativeModule* native_module() const { return native_module_; }
|
||||||
Tier tier() const { return tier_; }
|
Tier tier() const { return tier_; }
|
||||||
Address constant_pool() const;
|
Address constant_pool() const;
|
||||||
|
Address code_comments() const;
|
||||||
size_t constant_pool_offset() const { return constant_pool_offset_; }
|
size_t constant_pool_offset() const { return constant_pool_offset_; }
|
||||||
size_t safepoint_table_offset() const { return safepoint_table_offset_; }
|
size_t safepoint_table_offset() const { return safepoint_table_offset_; }
|
||||||
size_t handler_table_offset() const { return handler_table_offset_; }
|
size_t handler_table_offset() const { return handler_table_offset_; }
|
||||||
|
size_t code_comments_offset() const { return code_comments_offset_; }
|
||||||
uint32_t stack_slots() const { return stack_slots_; }
|
uint32_t stack_slots() const { return stack_slots_; }
|
||||||
bool is_liftoff() const { return tier_ == kLiftoff; }
|
bool is_liftoff() const { return tier_ == kLiftoff; }
|
||||||
bool contains(Address pc) const {
|
bool contains(Address pc) const {
|
||||||
@ -151,7 +153,7 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
|||||||
WasmCode(NativeModule* native_module, uint32_t index,
|
WasmCode(NativeModule* native_module, uint32_t index,
|
||||||
Vector<byte> instructions, uint32_t stack_slots,
|
Vector<byte> instructions, uint32_t stack_slots,
|
||||||
size_t safepoint_table_offset, size_t handler_table_offset,
|
size_t safepoint_table_offset, size_t handler_table_offset,
|
||||||
size_t constant_pool_offset,
|
size_t constant_pool_offset, size_t code_comments_offset,
|
||||||
OwnedVector<trap_handler::ProtectedInstructionData>
|
OwnedVector<trap_handler::ProtectedInstructionData>
|
||||||
protected_instructions,
|
protected_instructions,
|
||||||
OwnedVector<const byte> reloc_info,
|
OwnedVector<const byte> reloc_info,
|
||||||
@ -166,10 +168,12 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
|||||||
stack_slots_(stack_slots),
|
stack_slots_(stack_slots),
|
||||||
safepoint_table_offset_(safepoint_table_offset),
|
safepoint_table_offset_(safepoint_table_offset),
|
||||||
handler_table_offset_(handler_table_offset),
|
handler_table_offset_(handler_table_offset),
|
||||||
|
code_comments_offset_(code_comments_offset),
|
||||||
protected_instructions_(std::move(protected_instructions)),
|
protected_instructions_(std::move(protected_instructions)),
|
||||||
tier_(tier) {
|
tier_(tier) {
|
||||||
DCHECK_LE(safepoint_table_offset, instructions.size());
|
DCHECK_LE(safepoint_table_offset, instructions.size());
|
||||||
DCHECK_LE(constant_pool_offset, instructions.size());
|
DCHECK_LT(constant_pool_offset, instructions.size());
|
||||||
|
DCHECK_LT(code_comments_offset, instructions.size());
|
||||||
DCHECK_LE(handler_table_offset, instructions.size());
|
DCHECK_LE(handler_table_offset, instructions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,6 +200,7 @@ class V8_EXPORT_PRIVATE WasmCode final {
|
|||||||
// conversions.
|
// conversions.
|
||||||
size_t safepoint_table_offset_ = 0;
|
size_t safepoint_table_offset_ = 0;
|
||||||
size_t handler_table_offset_ = 0;
|
size_t handler_table_offset_ = 0;
|
||||||
|
size_t code_comments_offset_ = 0;
|
||||||
intptr_t trap_handler_index_ = -1;
|
intptr_t trap_handler_index_ = -1;
|
||||||
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions_;
|
OwnedVector<trap_handler::ProtectedInstructionData> protected_instructions_;
|
||||||
Tier tier_;
|
Tier tier_;
|
||||||
@ -226,7 +231,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
|||||||
WasmCode* AddDeserializedCode(
|
WasmCode* AddDeserializedCode(
|
||||||
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
|
uint32_t index, Vector<const byte> instructions, uint32_t stack_slots,
|
||||||
size_t safepoint_table_offset, size_t handler_table_offset,
|
size_t safepoint_table_offset, size_t handler_table_offset,
|
||||||
size_t constant_pool_offset,
|
size_t constant_pool_offset, size_t code_comments_offset,
|
||||||
OwnedVector<trap_handler::ProtectedInstructionData>
|
OwnedVector<trap_handler::ProtectedInstructionData>
|
||||||
protected_instructions,
|
protected_instructions,
|
||||||
OwnedVector<const byte> reloc_info,
|
OwnedVector<const byte> reloc_info,
|
||||||
@ -366,6 +371,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
|
|||||||
uint32_t stack_slots, size_t safepoint_table_offset,
|
uint32_t stack_slots, size_t safepoint_table_offset,
|
||||||
size_t handler_table_offset,
|
size_t handler_table_offset,
|
||||||
size_t constant_pool_offset,
|
size_t constant_pool_offset,
|
||||||
|
size_t code_comments_offset,
|
||||||
OwnedVector<trap_handler::ProtectedInstructionData>,
|
OwnedVector<trap_handler::ProtectedInstructionData>,
|
||||||
OwnedVector<const byte> reloc_info,
|
OwnedVector<const byte> reloc_info,
|
||||||
OwnedVector<const byte> source_position_table,
|
OwnedVector<const byte> source_position_table,
|
||||||
|
@ -191,6 +191,7 @@ constexpr size_t kCodeHeaderSize =
|
|||||||
sizeof(size_t) + // offset of constant pool
|
sizeof(size_t) + // offset of constant pool
|
||||||
sizeof(size_t) + // offset of safepoint table
|
sizeof(size_t) + // offset of safepoint table
|
||||||
sizeof(size_t) + // offset of handler table
|
sizeof(size_t) + // offset of handler table
|
||||||
|
sizeof(size_t) + // offset of code comments
|
||||||
sizeof(uint32_t) + // stack slots
|
sizeof(uint32_t) + // stack slots
|
||||||
sizeof(size_t) + // code size
|
sizeof(size_t) + // code size
|
||||||
sizeof(size_t) + // reloc size
|
sizeof(size_t) + // reloc size
|
||||||
@ -286,6 +287,7 @@ void NativeModuleSerializer::WriteCode(const WasmCode* code, Writer* writer) {
|
|||||||
writer->Write(code->constant_pool_offset());
|
writer->Write(code->constant_pool_offset());
|
||||||
writer->Write(code->safepoint_table_offset());
|
writer->Write(code->safepoint_table_offset());
|
||||||
writer->Write(code->handler_table_offset());
|
writer->Write(code->handler_table_offset());
|
||||||
|
writer->Write(code->code_comments_offset());
|
||||||
writer->Write(code->stack_slots());
|
writer->Write(code->stack_slots());
|
||||||
writer->Write(code->instructions().size());
|
writer->Write(code->instructions().size());
|
||||||
writer->Write(code->reloc_info().size());
|
writer->Write(code->reloc_info().size());
|
||||||
@ -450,6 +452,7 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
|
|||||||
size_t constant_pool_offset = reader->Read<size_t>();
|
size_t constant_pool_offset = reader->Read<size_t>();
|
||||||
size_t safepoint_table_offset = reader->Read<size_t>();
|
size_t safepoint_table_offset = reader->Read<size_t>();
|
||||||
size_t handler_table_offset = reader->Read<size_t>();
|
size_t handler_table_offset = reader->Read<size_t>();
|
||||||
|
size_t code_comment_offset = reader->Read<size_t>();
|
||||||
uint32_t stack_slot_count = reader->Read<uint32_t>();
|
uint32_t stack_slot_count = reader->Read<uint32_t>();
|
||||||
size_t code_size = reader->Read<size_t>();
|
size_t code_size = reader->Read<size_t>();
|
||||||
size_t reloc_size = reader->Read<size_t>();
|
size_t reloc_size = reader->Read<size_t>();
|
||||||
@ -471,7 +474,7 @@ bool NativeModuleDeserializer::ReadCode(uint32_t fn_index, Reader* reader) {
|
|||||||
|
|
||||||
WasmCode* code = native_module_->AddDeserializedCode(
|
WasmCode* code = native_module_->AddDeserializedCode(
|
||||||
fn_index, code_buffer, stack_slot_count, safepoint_table_offset,
|
fn_index, code_buffer, stack_slot_count, safepoint_table_offset,
|
||||||
handler_table_offset, constant_pool_offset,
|
handler_table_offset, constant_pool_offset, code_comment_offset,
|
||||||
std::move(protected_instructions), std::move(reloc_info),
|
std::move(protected_instructions), std::move(reloc_info),
|
||||||
std::move(source_pos), tier);
|
std::move(source_pos), tier);
|
||||||
|
|
||||||
|
@ -456,6 +456,8 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
PatchConstPool();
|
PatchConstPool();
|
||||||
DCHECK(constpool_.IsEmpty());
|
DCHECK(constpool_.IsEmpty());
|
||||||
|
|
||||||
|
int code_comments_size = WriteCodeComments();
|
||||||
|
|
||||||
// At this point overflow() may be true, but the gap ensures
|
// At this point overflow() may be true, but the gap ensures
|
||||||
// that we are still not overlapping instructions and relocation info.
|
// that we are still not overlapping instructions and relocation info.
|
||||||
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
|
||||||
@ -473,6 +475,7 @@ void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
|
|||||||
desc->constant_pool_size = 0;
|
desc->constant_pool_size = 0;
|
||||||
desc->unwinding_info_size = 0;
|
desc->unwinding_info_size = 0;
|
||||||
desc->unwinding_info = nullptr;
|
desc->unwinding_info = nullptr;
|
||||||
|
desc->code_comments_size = code_comments_size;
|
||||||
|
|
||||||
// Collection stage
|
// Collection stage
|
||||||
auto jump_opt = jump_optimization_info();
|
auto jump_opt = jump_optimization_info();
|
||||||
|
@ -1914,10 +1914,6 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
return pc_offset() - label->pos();
|
return pc_offset() - label->pos();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record a comment relocation entry that can be used by a disassembler.
|
|
||||||
// Use --code-comments to enable.
|
|
||||||
void RecordComment(const char* msg);
|
|
||||||
|
|
||||||
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
// Record a deoptimization reason that can be used by a log or cpu profiler.
|
||||||
// Use --trace-deopt to enable.
|
// Use --trace-deopt to enable.
|
||||||
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
|
||||||
@ -2404,6 +2400,8 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
|
|||||||
|
|
||||||
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
|
||||||
|
|
||||||
|
int WriteCodeComments();
|
||||||
|
|
||||||
friend class EnsureSpace;
|
friend class EnsureSpace;
|
||||||
friend class RegExpMacroAssemblerX64;
|
friend class RegExpMacroAssemblerX64;
|
||||||
|
|
||||||
|
@ -582,6 +582,38 @@ TEST(ExceptionHandler) {
|
|||||||
CHECK_EQ(2, ft.CallChecked<Smi>()->value());
|
CHECK_EQ(2, ft.CallChecked<Smi>()->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestCodeAssemblerCodeComment) {
|
||||||
|
i::FLAG_code_comments = true;
|
||||||
|
Isolate* isolate(CcTest::InitIsolateOnce());
|
||||||
|
const int kNumParams = 0;
|
||||||
|
CodeAssemblerTester asm_tester(isolate, kNumParams);
|
||||||
|
CodeAssembler m(asm_tester.state());
|
||||||
|
|
||||||
|
CodeAssembler::TVariable<Object> var(m.SmiConstant(0), &m);
|
||||||
|
Label exception(&m, {&var}, Label::kDeferred);
|
||||||
|
{
|
||||||
|
CodeAssemblerScopedExceptionHandler handler(&m, &exception, &var);
|
||||||
|
Node* context = m.HeapConstant(Handle<Context>(isolate->native_context()));
|
||||||
|
m.CallRuntime(Runtime::kThrow, context, m.SmiConstant(2));
|
||||||
|
}
|
||||||
|
m.Comment("Comment1");
|
||||||
|
m.Return(m.SmiConstant(1));
|
||||||
|
|
||||||
|
m.Bind(&exception);
|
||||||
|
m.Return(var.value());
|
||||||
|
|
||||||
|
Handle<Code> code = asm_tester.GenerateCode();
|
||||||
|
CHECK_NE(code->code_comments(), kNullAddress);
|
||||||
|
CodeCommentsIterator it(code->code_comments());
|
||||||
|
CHECK(it.HasCurrent());
|
||||||
|
bool found_comment = false;
|
||||||
|
while (it.HasCurrent()) {
|
||||||
|
if (strcmp(it.GetComment(), "Comment1") == 0) found_comment = true;
|
||||||
|
it.Next();
|
||||||
|
}
|
||||||
|
CHECK(found_comment);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -30,6 +30,7 @@ TEST(CodeLayoutWithoutUnwindingInfo) {
|
|||||||
code_desc.origin = nullptr;
|
code_desc.origin = nullptr;
|
||||||
code_desc.unwinding_info = nullptr;
|
code_desc.unwinding_info = nullptr;
|
||||||
code_desc.unwinding_info_size = 0;
|
code_desc.unwinding_info_size = 0;
|
||||||
|
code_desc.code_comments_size = 0;
|
||||||
|
|
||||||
Handle<Code> code = CcTest::i_isolate()->factory()->NewCode(
|
Handle<Code> code = CcTest::i_isolate()->factory()->NewCode(
|
||||||
code_desc, Code::STUB, Handle<Object>::null());
|
code_desc, Code::STUB, Handle<Object>::null());
|
||||||
@ -68,6 +69,7 @@ TEST(CodeLayoutWithUnwindingInfo) {
|
|||||||
code_desc.origin = nullptr;
|
code_desc.origin = nullptr;
|
||||||
code_desc.unwinding_info = unwinding_info;
|
code_desc.unwinding_info = unwinding_info;
|
||||||
code_desc.unwinding_info_size = unwinding_info_size;
|
code_desc.unwinding_info_size = unwinding_info_size;
|
||||||
|
code_desc.code_comments_size = 0;
|
||||||
|
|
||||||
Handle<Code> code = CcTest::i_isolate()->factory()->NewCode(
|
Handle<Code> code = CcTest::i_isolate()->factory()->NewCode(
|
||||||
code_desc, Code::STUB, Handle<Object>::null());
|
code_desc, Code::STUB, Handle<Object>::null());
|
||||||
|
Loading…
Reference in New Issue
Block a user