v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bytecode-array.cc
Go to the documentation of this file.
1// Copyright 2023 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
7#include <iomanip>
8
11#include "src/common/globals.h"
15#include "src/utils/memcopy.h"
16
17namespace v8 {
18namespace internal {
19
21 int position = 0;
22 if (!HasSourcePositionTable()) return position;
24 source_position_table(kAcquireLoad),
27 !it.done() && it.code_offset() <= offset; it.Advance()) {
28 position = it.source_position().ScriptOffset();
29 }
30 return position;
31}
32
34 int position = 0;
35 if (!HasSourcePositionTable()) return position;
36 for (SourcePositionTableIterator it(source_position_table(kAcquireLoad));
37 !it.done() && it.code_offset() <= offset; it.Advance()) {
38 if (it.is_statement()) {
39 position = it.source_position().ScriptOffset();
40 }
41 }
42 return position;
43}
44
45void BytecodeArray::PrintJson(std::ostream& os) {
47
48 Address base_address = GetFirstBytecodeAddress();
49 BytecodeArray handle_storage = *this;
50 Handle<BytecodeArray> handle(reinterpret_cast<Address*>(&handle_storage));
52 bool first_data = true;
53
54 os << "{\"data\": [";
55
56 while (!iterator.done()) {
57 if (!first_data) os << ", ";
58 Address current_address = base_address + iterator.current_offset();
59 first_data = false;
60
61 os << "{\"offset\":" << iterator.current_offset() << ", \"disassembly\":\"";
63 os, reinterpret_cast<uint8_t*>(current_address), false);
64
66 os << " (" << iterator.GetJumpTargetOffset() << ")";
67 }
68
70 os << " {";
71 bool first_entry = true;
73 iterator.GetJumpTableTargetOffsets()) {
74 if (!first_entry) os << ", ";
75 first_entry = false;
76 os << entry.target_offset;
77 }
78 os << "}";
79 }
80
81 os << "\"}";
82 iterator.Advance();
83 }
84
85 os << "]";
86
87 int constant_pool_length = constant_pool()->length();
88 if (constant_pool_length > 0) {
89 os << ", \"constantPool\": [";
90 for (int i = 0; i < constant_pool_length; i++) {
91 Tagged<Object> object = constant_pool()->get(i);
92 if (i > 0) os << ", ";
93 os << "\"" << object << "\"";
94 }
95 os << "]";
96 }
97
98 os << "}";
99}
100
101void BytecodeArray::Disassemble(std::ostream& os) {
103 // Storage for backing the handle passed to the iterator. This handle won't be
104 // updated by the gc, but that's ok because we've disallowed GCs anyway.
105 BytecodeArray handle_storage = *this;
106 Handle<BytecodeArray> handle(reinterpret_cast<Address*>(&handle_storage));
107 Disassemble(handle, os);
108}
109
110// static
112 std::ostream& os) {
114
115 os << "Parameter count " << handle->parameter_count() << "\n";
116 os << "Register count " << handle->register_count() << "\n";
117 os << "Frame size " << handle->frame_size() << "\n";
118
119 Address base_address = handle->GetFirstBytecodeAddress();
121
123 while (!iterator.done()) {
124 if (!source_positions.done() &&
125 iterator.current_offset() == source_positions.code_offset()) {
126 os << std::setw(5) << source_positions.source_position().ScriptOffset();
127 os << (source_positions.is_statement() ? " S> " : " E> ");
128 source_positions.Advance();
129 } else {
130 os << " ";
131 }
132 Address current_address = base_address + iterator.current_offset();
133 os << reinterpret_cast<const void*>(current_address) << " @ "
134 << std::setw(4) << iterator.current_offset() << " : ";
136 os, reinterpret_cast<uint8_t*>(current_address));
138 Address jump_target = base_address + iterator.GetJumpTargetOffset();
139 os << " (" << reinterpret_cast<void*>(jump_target) << " @ "
140 << iterator.GetJumpTargetOffset() << ")";
141 }
143 os << " {";
144 bool first_entry = true;
146 iterator.GetJumpTableTargetOffsets()) {
147 if (first_entry) {
148 first_entry = false;
149 } else {
150 os << ",";
151 }
152 os << " " << entry.case_value << ": @" << entry.target_offset;
153 }
154 os << " }";
155 }
156 os << std::endl;
157 iterator.Advance();
158 }
159
160 os << "Constant pool (size = " << handle->constant_pool()->length() << ")\n";
161#ifdef OBJECT_PRINT
162 if (handle->constant_pool()->length() > 0) {
163 Print(handle->constant_pool(), os);
164 }
165#endif
166
167 os << "Handler Table (size = " << handle->handler_table()->length() << ")\n";
168#ifdef ENABLE_DISASSEMBLER
169 if (handle->handler_table()->length() > 0) {
170 HandlerTable table(*handle);
171 table.HandlerTableRangePrint(os);
172 }
173#endif
174
175 Tagged<TrustedByteArray> source_position_table =
176 handle->SourcePositionTable();
177 os << "Source Position Table (size = " << source_position_table->length()
178 << ")\n";
179#ifdef OBJECT_PRINT
180 if (source_position_table->length() > 0) {
181 os << Brief(source_position_table) << std::endl;
182 }
183#endif
184}
185
187 BytecodeArray from = *this;
188 DCHECK_EQ(from->length(), to->length());
189 CopyBytes(reinterpret_cast<uint8_t*>(to->GetFirstBytecodeAddress()),
190 reinterpret_cast<uint8_t*>(from->GetFirstBytecodeAddress()),
191 from->length());
192}
193
194} // namespace internal
195} // namespace v8
int SourceStatementPosition(int offset) const
int SourcePosition(int offset) const
void CopyBytecodesTo(Tagged< BytecodeArray > to)
V8_EXPORT_PRIVATE void Disassemble(std::ostream &os)
V8_EXPORT_PRIVATE void PrintJson(std::ostream &os)
static std::ostream & Decode(std::ostream &os, const uint8_t *bytecode_start, bool with_hex=true)
static constexpr bool IsSwitch(Bytecode bytecode)
Definition bytecodes.h:819
static constexpr bool IsJump(Bytecode bytecode)
Definition bytecodes.h:798
SourcePositionTable * source_positions
int32_t offset
int position
Definition liveedit.cc:290
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
void CopyBytes(T *dst, const T *src, size_t num_bytes)
Definition memcopy.h:261
static constexpr AcquireLoadTag kAcquireLoad
Definition globals.h:2908
#define DCHECK_EQ(v1, v2)
Definition logging.h:485