bool HeapSnapshot::saveNode(const protobuf::Node& node) { if (!node.has_id()) return false; NodeId id = node.id(); if (!node.has_typename_()) return false; const auto* duplicatedTypeName = reinterpret_cast<const char16_t*>( node.typename_().c_str()); const char16_t* typeName = borrowUniqueString( duplicatedTypeName, node.typename_().length() / sizeof(char16_t)); if (!typeName) return false; if (!node.has_size()) return false; uint64_t size = node.size(); auto edgesLength = node.edges_size(); DeserializedNode::EdgeVector edges; if (!edges.reserve(edgesLength)) return false; for (decltype(edgesLength) i = 0; i < edgesLength; i++) { DeserializedEdge edge; if (!edge.init(node.edges(i), *this)) return false; edges.infallibleAppend(Move(edge)); } DeserializedNode dn(id, typeName, size, Move(edges), *this); return nodes.putNew(id, Move(dn)); }
bool HeapSnapshot::saveNode(const protobuf::Node& node) { if (!node.has_id()) return false; NodeId id = node.id(); // Should only deserialize each node once. if (nodes.has(id)) return false; if (!JS::ubi::Uint32IsValidCoarseType(node.coarsetype())) return false; auto coarseType = JS::ubi::Uint32ToCoarseType(node.coarsetype()); if (!node.has_typename_()) return false; auto duplicatedTypeName = reinterpret_cast<const char16_t*>( node.typename_().data()); auto length = node.typename_().length() / sizeof(char16_t); auto typeName = borrowUniqueString(duplicatedTypeName, length); if (!typeName) return false; if (!node.has_size()) return false; uint64_t size = node.size(); auto edgesLength = node.edges_size(); DeserializedNode::EdgeVector edges; if (!edges.reserve(edgesLength)) return false; for (decltype(edgesLength) i = 0; i < edgesLength; i++) { DeserializedEdge edge; if (!edge.init(node.edges(i), *this)) return false; edges.infallibleAppend(Move(edge)); } Maybe<StackFrameId> allocationStack; if (node.has_allocationstack()) { StackFrameId id = 0; if (!saveStackFrame(node.allocationstack(), id)) return false; allocationStack.emplace(id); } MOZ_ASSERT(allocationStack.isSome() == node.has_allocationstack()); UniquePtr<char[]> jsObjectClassName; if (node.has_jsobjectclassname()) { auto length = node.jsobjectclassname().length(); jsObjectClassName.reset(static_cast<char*>(malloc(length + 1))); if (!jsObjectClassName) return false; strncpy(jsObjectClassName.get(), node.jsobjectclassname().data(), length); jsObjectClassName.get()[length] = '\0'; } return nodes.putNew(id, DeserializedNode(id, coarseType, typeName, size, Move(edges), allocationStack, Move(jsObjectClassName), *this)); }