blob: b0271a00fb4da601ae726ba59df5ec733e847069 [file] [log] [blame]
// 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/codegen/assembler-inl.h"
#include "src/codegen/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,
uint32_t code_comments_size)
: code_comments_start_(code_comments_start),
code_comments_size_(code_comments_size),
current_entry_(code_comments_start + kOffsetToFirstCommentEntry) {
DCHECK_NE(kNullAddress, code_comments_start);
DCHECK_IMPLIES(code_comments_size,
code_comments_size ==
base::ReadUnalignedValue<uint32_t>(code_comments_start_));
}
uint32_t CodeCommentsIterator::size() const { return code_comments_size_; }
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 ReadUnalignedValue<uint32_t>(current_entry_ + kOffsetToCommentSize);
}
uint32_t CodeCommentsIterator::GetPCOffset() const {
return ReadUnalignedValue<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,
uint32_t code_comments_size) {
CodeCommentsIterator it(code_comments_start, code_comments_size);
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