12const V8SnapshotProfileWriter::ObjectId
15#if defined(DART_PRECOMPILER)
24 intptr_t idx = edge_types_.Add(
"context");
25 ASSERT_EQUAL(idx,
static_cast<intptr_t
>(Edge::Type::kContext));
26 idx = edge_types_.Add(
"element");
27 ASSERT_EQUAL(idx,
static_cast<intptr_t
>(Edge::Type::kElement));
28 idx = edge_types_.Add(
"property");
29 ASSERT_EQUAL(idx,
static_cast<intptr_t
>(Edge::Type::kProperty));
30 idx = edge_types_.Add(
"internal");
31 ASSERT_EQUAL(idx,
static_cast<intptr_t
>(Edge::Type::kInternal));
33 SetObjectTypeAndName(kArtificialRootId,
"ArtificialRoot",
37void V8SnapshotProfileWriter::SetObjectTypeAndName(
const ObjectId& object_id,
41 NodeInfo*
info = EnsureId(object_id);
42 const intptr_t type_index = node_types_.Add(
type);
43 if (
info->type != kInvalidString &&
info->type != type_index) {
44 FATAL(
"Attempting to assign mismatching type %s to node %s",
type,
45 info->ToCString(
this, zone_));
47 info->type = type_index;
49 if (
info->name == kInvalidString) {
54void V8SnapshotProfileWriter::AttributeBytesTo(
const ObjectId& object_id,
56 EnsureId(object_id)->self_size += num_bytes;
59void V8SnapshotProfileWriter::AttributeReferenceTo(
60 const ObjectId& from_object_id,
61 const Reference& reference,
62 const ObjectId& to_object_id) {
63 ASSERT(reference.IsElement() ? reference.offset >= 0
64 : reference.name !=
nullptr);
65 EnsureId(to_object_id);
66 const Edge edge(
this, reference);
67 EnsureId(from_object_id)->AddEdge(edge, to_object_id);
70void V8SnapshotProfileWriter::AttributeDroppedReferenceTo(
71 const ObjectId& from_object_id,
72 const Reference& reference,
73 const ObjectId& to_object_id,
74 const ObjectId& replacement_object_id) {
75 ASSERT(to_object_id.IsArtificial());
76 ASSERT(!replacement_object_id.IsArtificial());
77 ASSERT(reference.IsElement() ? reference.offset >= 0
78 : reference.name !=
nullptr);
81 AttributeReferenceTo(from_object_id, reference, to_object_id);
83 EnsureId(replacement_object_id);
87 Reference replacement_reference =
88 reference.IsElement() ? Reference::Element(-reference.offset)
89 : Reference::Property(OS::SCreate(
90 zone_,
":replacement_%s", reference.
name));
91 const Edge replacement_edge(
this, replacement_reference);
92 EnsureId(from_object_id)->AddEdge(replacement_edge, replacement_object_id);
95bool V8SnapshotProfileWriter::HasId(
const ObjectId& object_id) {
96 return nodes_.HasKey(object_id);
99V8SnapshotProfileWriter::NodeInfo* V8SnapshotProfileWriter::EnsureId(
100 const ObjectId& object_id) {
101 if (!HasId(object_id)) {
102 nodes_.Insert(NodeInfo(
this, object_id));
104 return nodes_.Lookup(object_id);
107const char* V8SnapshotProfileWriter::NodeInfo::ToCString(
108 V8SnapshotProfileWriter* profile_writer,
111 WriteDebug(profile_writer, &writer);
112 return OS::SCreate(zone,
"%s", writer.buffer()->buffer());
115void V8SnapshotProfileWriter::NodeInfo::Write(
116 V8SnapshotProfileWriter* profile_writer,
117 JSONWriter* writer)
const {
119 if (
type == kInvalidString) {
120 FATAL(
"No type given for node %s",
id.ToCString(profile_writer->zone_));
122 writer->PrintValue(
type);
123 if (
name != kInvalidString) {
124 writer->PrintValue(
name);
126 ASSERT(profile_writer !=
nullptr);
129 const intptr_t
name = profile_writer->strings_.AddFormatted(
130 "Unnamed [%s] (nil)", profile_writer->node_types_.At(
type));
131 writer->PrintValue(
name);
134 writer->PrintValue(self_size);
135 writer->PrintValue64(edges->Length());
138void V8SnapshotProfileWriter::NodeInfo::WriteDebug(
139 V8SnapshotProfileWriter* profile_writer,
140 JSONWriter* writer)
const {
141 writer->OpenObject();
142 if (
type != kInvalidString) {
143 writer->PrintProperty(
"type", profile_writer->node_types_.At(
type));
145 if (
name != kInvalidString) {
146 writer->PrintProperty(
"name", profile_writer->strings_.At(
name));
148 id.WriteDebug(writer,
"id");
149 writer->PrintProperty(
"self_size", self_size);
150 edges->WriteDebug(profile_writer, writer,
"edges");
151 writer->CloseObject();
154const char* V8SnapshotProfileWriter::ObjectId::ToCString(Zone* zone)
const {
157 return OS::SCreate(zone,
"%s", writer.buffer()->buffer());
160void V8SnapshotProfileWriter::ObjectId::Write(JSONWriter* writer,
161 const char* property)
const {
162 if (property !=
nullptr) {
163 writer->PrintProperty64(property, encoded_);
165 writer->PrintValue64(encoded_);
169void V8SnapshotProfileWriter::ObjectId::WriteDebug(JSONWriter* writer,
170 const char* property)
const {
171 writer->OpenObject(property);
172 writer->PrintProperty(
"space", IdSpaceToCString(space()));
173 writer->PrintProperty64(
"nonce", nonce());
174 writer->CloseObject();
177const char* V8SnapshotProfileWriter::ObjectId::IdSpaceToCString(
IdSpace space) {
181 case IdSpace::kSnapshot:
183 case IdSpace::kVmText:
185 case IdSpace::kIsolateText:
186 return "IsolateText";
187 case IdSpace::kVmData:
189 case IdSpace::kIsolateData:
190 return "IsolateData";
191 case IdSpace::kArtificial:
198const char* V8SnapshotProfileWriter::EdgeMap::ToCString(
199 V8SnapshotProfileWriter* profile_writer,
202 WriteDebug(profile_writer, &writer);
203 return OS::SCreate(zone,
"%s", writer.buffer()->buffer());
206void V8SnapshotProfileWriter::EdgeMap::WriteDebug(
207 V8SnapshotProfileWriter* profile_writer,
209 const char* property)
const {
210 writer->OpenArray(property);
211 auto edge_it = GetIterator();
212 while (
auto const pair = edge_it.Next()) {
213 pair->edge.WriteDebug(profile_writer, writer, pair->target);
215 writer->CloseArray();
218void V8SnapshotProfileWriter::Edge::Write(
219 V8SnapshotProfileWriter* profile_writer,
221 const ObjectId& target_id)
const {
223 writer->PrintValue64(
static_cast<intptr_t
>(
type));
224 writer->PrintValue64(name_or_offset);
225 auto const target = profile_writer->nodes_.LookupValue(target_id);
226 writer->PrintValue64(
target.offset());
229void V8SnapshotProfileWriter::Edge::WriteDebug(
230 V8SnapshotProfileWriter* profile_writer,
232 const ObjectId& target_id)
const {
233 writer->OpenObject();
234 if (
type != Type::kInvalid) {
235 writer->PrintProperty(
236 "type", profile_writer->edge_types_.At(
static_cast<intptr_t
>(
type)));
238 if (
type == Type::kProperty) {
239 writer->PrintProperty(
"name", profile_writer->strings_.At(name_or_offset));
241 writer->PrintProperty64(
"offset", name_or_offset);
243 auto const target = profile_writer->nodes_.LookupValue(target_id);
244 target.id.WriteDebug(writer,
"target");
245 writer->CloseObject();
248void V8SnapshotProfileWriter::AddRoot(
const ObjectId& object_id,
253 if (roots_.HasKey(object_id))
return;
254 roots_.Insert(object_id);
256 auto const str_index = strings_.Add(
name);
257 auto const root = nodes_.Lookup(kArtificialRootId);
259 root->AddEdge(str_index != kInvalidString
260 ?
Edge(
this, Edge::Type::kProperty, str_index)
261 :
Edge(
this, Edge::Type::kInternal,
root->edges->Length()),
265intptr_t V8SnapshotProfileWriter::StringsTable::Add(
const char* str) {
266 if (str ==
nullptr)
return kInvalidString;
267 if (
auto const kv = index_map_.Lookup(str)) {
270 const char* new_str = OS::SCreate(zone_,
"%s", str);
271 const intptr_t index = strings_.length();
272 strings_.Add(new_str);
273 index_map_.Insert({new_str, index});
277intptr_t V8SnapshotProfileWriter::StringsTable::AddFormatted(
const char*
fmt,
281 const char* str = OS::VSCreate(zone_,
fmt,
args);
283 if (
auto const kv = index_map_.Lookup(str)) {
286 const intptr_t index = strings_.length();
288 index_map_.Insert({str, index});
292const char* V8SnapshotProfileWriter::StringsTable::At(intptr_t index)
const {
293 if (index > strings_.length())
return nullptr;
294 return strings_[index];
297void V8SnapshotProfileWriter::StringsTable::Write(JSONWriter* writer,
298 const char* property)
const {
299 writer->OpenArray(property);
300 for (
auto const str : strings_) {
301 writer->PrintValue(str);
302 writer->PrintNewline();
304 writer->CloseArray();
307void V8SnapshotProfileWriter::Write(JSONWriter* writer) {
308 writer->OpenObject();
310 writer->OpenObject(
"snapshot");
312 writer->OpenObject(
"meta");
315 writer->OpenArray(
"node_fields");
316 writer->PrintValue(
"type");
317 writer->PrintValue(
"name");
318 writer->PrintValue(
"id");
319 writer->PrintValue(
"self_size");
320 writer->PrintValue(
"edge_count");
321 writer->CloseArray();
325 writer->OpenArray(
"node_types");
326 node_types_.Write(writer);
327 writer->CloseArray();
331 writer->OpenArray(
"edge_fields");
332 writer->PrintValue(
"type");
333 writer->PrintValue(
"name_or_index");
334 writer->PrintValue(
"to_node");
335 writer->CloseArray();
339 writer->OpenArray(
"edge_types");
340 edge_types_.Write(writer);
341 writer->CloseArray();
344 writer->CloseObject();
346 writer->PrintProperty64(
"node_count", nodes_.Size());
348 intptr_t edge_count = 0;
349 auto nodes_it = nodes_.GetIterator();
350 while (
auto const info = nodes_it.Next()) {
353 edge_count +=
info->edges->Length();
355 writer->PrintProperty64(
"edge_count", edge_count);
358 writer->CloseObject();
361 writer->OpenArray(
"nodes");
363 auto const root = nodes_.Lookup(kArtificialRootId);
367 root->Write(
this, writer);
369 auto nodes_it = nodes_.GetIterator();
370 for (
auto entry = nodes_it.Next(); entry !=
nullptr;
371 entry = nodes_it.Next()) {
372 if (entry->id == kArtificialRootId)
continue;
373 entry->set_offset(
offset);
374 entry->Write(
this, writer);
377 writer->CloseArray();
381 auto write_edges = [&](
const NodeInfo&
info) {
382 auto edges_it =
info.edges->GetIterator();
383 while (
auto const pair = edges_it.Next()) {
384 pair->edge.Write(
this, writer, pair->target);
387 writer->OpenArray(
"edges");
389 auto const root = nodes_.Lookup(kArtificialRootId);
392 auto nodes_it = nodes_.GetIterator();
393 while (
auto const entry = nodes_it.Next()) {
394 if (entry->id == kArtificialRootId)
continue;
397 writer->CloseArray();
402 strings_.Write(writer,
"strings");
404 writer->CloseObject();
407void V8SnapshotProfileWriter::Write(
const char* filename) {
411 auto file_open = Dart::file_open_callback();
412 auto file_write = Dart::file_write_callback();
413 auto file_close = Dart::file_close_callback();
414 if ((file_open ==
nullptr) || (file_write ==
nullptr) ||
415 (file_close ==
nullptr)) {
416 OS::PrintErr(
"warning: Could not access file callbacks.");
420 auto file = file_open(filename,
true);
421 if (
file ==
nullptr) {
422 OS::PrintErr(
"warning: Failed to write snapshot profile: %s\n", filename);
425 intptr_t output_length = 0;
426 json.Steal(&
output, &output_length);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
GrTriangulator::Edge Edge
#define ASSERT_EQUAL(expected, actual)
static const ObjectId kArtificialRootId
V8SnapshotProfileWriter(Zone *zone)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
DEF_SWITCHES_START aot vmservice shared library name
static SkString fmt(SkColor4f c)