| // 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 |