diff --git a/devtools/shared/heapsnapshot/.gitattributes b/devtools/shared/heapsnapshot/.gitattributes new file mode 100644 index 00000000000..44e248a8dd5 --- /dev/null +++ b/devtools/shared/heapsnapshot/.gitattributes @@ -0,0 +1 @@ +CoreDump.pb.* binary diff --git a/devtools/shared/heapsnapshot/AutoMemMap.h b/devtools/shared/heapsnapshot/AutoMemMap.h index a086a4590b0..2b378704eb0 100644 --- a/devtools/shared/heapsnapshot/AutoMemMap.h +++ b/devtools/shared/heapsnapshot/AutoMemMap.h @@ -4,6 +4,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef mozilla_devtools_AutoMemMap_h +#define mozilla_devtools_AutoMemMap_h + #include #include "mozilla/GuardObjects.h" @@ -68,3 +71,5 @@ public: } // namespace devtools } // namespace mozilla + +#endif // mozilla_devtools_AutoMemMap_h diff --git a/devtools/shared/heapsnapshot/CoreDump.pb.cc b/devtools/shared/heapsnapshot/CoreDump.pb.cc index 168feed16c7..5cc020f9965 100644 --- a/devtools/shared/heapsnapshot/CoreDump.pb.cc +++ b/devtools/shared/heapsnapshot/CoreDump.pb.cc @@ -35,12 +35,28 @@ struct StackFrameOneofInstance { const ::google::protobuf::Descriptor* StackFrame_Data_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* StackFrame_Data_reflection_ = NULL; +struct StackFrame_DataOneofInstance { + const ::std::string* source_; + ::google::protobuf::uint64 sourceref_; + const ::std::string* functiondisplayname_; + ::google::protobuf::uint64 functiondisplaynameref_; +}* StackFrame_Data_default_oneof_instance_ = NULL; const ::google::protobuf::Descriptor* Node_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* Node_reflection_ = NULL; +struct NodeOneofInstance { + const ::std::string* typename__; + ::google::protobuf::uint64 typenameref_; + const ::std::string* jsobjectclassname_; + ::google::protobuf::uint64 jsobjectclassnameref_; +}* Node_default_oneof_instance_ = NULL; const ::google::protobuf::Descriptor* Edge_descriptor_ = NULL; const ::google::protobuf::internal::GeneratedMessageReflection* Edge_reflection_ = NULL; +struct EdgeOneofInstance { + const ::std::string* name_; + ::google::protobuf::uint64 nameref_; +}* Edge_default_oneof_instance_ = NULL; } // namespace @@ -86,15 +102,19 @@ void protobuf_AssignDesc_CoreDump_2eproto() { ::google::protobuf::MessageFactory::generated_factory(), sizeof(StackFrame)); StackFrame_Data_descriptor_ = StackFrame_descriptor_->nested_type(0); - static const int StackFrame_Data_offsets_[8] = { + static const int StackFrame_Data_offsets_[12] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, id_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, parent_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, line_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, column_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, source_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, functiondisplayname_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, source_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, sourceref_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, functiondisplayname_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(StackFrame_Data_default_oneof_instance_, functiondisplaynameref_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, issystem_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, isselfhosted_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, SourceOrRef_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, FunctionDisplayNameOrRef_), }; StackFrame_Data_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -104,18 +124,24 @@ void protobuf_AssignDesc_CoreDump_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _has_bits_[0]), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _unknown_fields_), -1, + StackFrame_Data_default_oneof_instance_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StackFrame_Data, _oneof_case_[0]), ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(StackFrame_Data)); Node_descriptor_ = file->message_type(2); - static const int Node_offsets_[7] = { + static const int Node_offsets_[11] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, id_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, typename__), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typename__), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, typenameref_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, size_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, edges_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, allocationstack_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, jsobjectclassname_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassname_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Node_default_oneof_instance_, jsobjectclassnameref_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, coarsetype_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, TypeNameOrRef_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, JSObjectClassNameOrRef_), }; Node_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -125,13 +151,17 @@ void protobuf_AssignDesc_CoreDump_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _has_bits_[0]), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _unknown_fields_), -1, + Node_default_oneof_instance_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Node, _oneof_case_[0]), ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Node)); Edge_descriptor_ = file->message_type(3); - static const int Edge_offsets_[2] = { + static const int Edge_offsets_[4] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, referent_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, name_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Edge_default_oneof_instance_, name_), + PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(Edge_default_oneof_instance_, nameref_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, EdgeNameOrRef_), }; Edge_reflection_ = new ::google::protobuf::internal::GeneratedMessageReflection( @@ -141,6 +171,8 @@ void protobuf_AssignDesc_CoreDump_2eproto() { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _has_bits_[0]), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _unknown_fields_), -1, + Edge_default_oneof_instance_, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Edge, _oneof_case_[0]), ::google::protobuf::DescriptorPool::generated_pool(), ::google::protobuf::MessageFactory::generated_factory(), sizeof(Edge)); @@ -177,10 +209,13 @@ void protobuf_ShutdownFile_CoreDump_2eproto() { delete StackFrame_default_oneof_instance_; delete StackFrame_reflection_; delete StackFrame_Data::default_instance_; + delete StackFrame_Data_default_oneof_instance_; delete StackFrame_Data_reflection_; delete Node::default_instance_; + delete Node_default_oneof_instance_; delete Node_reflection_; delete Edge::default_instance_; + delete Edge_default_oneof_instance_; delete Edge_reflection_; } @@ -192,29 +227,38 @@ void protobuf_AddDesc_CoreDump_2eproto() { ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( "\n\016CoreDump.proto\022\031mozilla.devtools.proto" - "buf\"\035\n\010Metadata\022\021\n\ttimeStamp\030\001 \001(\004\"\250\002\n\nS" + "buf\"\035\n\010Metadata\022\021\n\ttimeStamp\030\001 \001(\004\"\216\003\n\nS" "tackFrame\022:\n\004data\030\001 \001(\0132*.mozilla.devtoo" "ls.protobuf.StackFrame.DataH\000\022\r\n\003ref\030\002 \001" - "(\004H\000\032\274\001\n\004Data\022\n\n\002id\030\001 \001(\004\0225\n\006parent\030\002 \001(" + "(\004H\000\032\242\002\n\004Data\022\n\n\002id\030\001 \001(\004\0225\n\006parent\030\002 \001(" "\0132%.mozilla.devtools.protobuf.StackFrame" - "\022\014\n\004line\030\003 \001(\r\022\016\n\006column\030\004 \001(\r\022\016\n\006source" - "\030\005 \001(\014\022\033\n\023functionDisplayName\030\006 \001(\014\022\020\n\010i" - "sSystem\030\007 \001(\010\022\024\n\014isSelfHosted\030\010 \001(\010B\020\n\016S" - "tackFrameType\"\324\001\n\004Node\022\n\n\002id\030\001 \001(\004\022\020\n\010ty" - "peName\030\002 \001(\014\022\014\n\004size\030\003 \001(\004\022.\n\005edges\030\004 \003(" - "\0132\037.mozilla.devtools.protobuf.Edge\022>\n\017al" - "locationStack\030\005 \001(\0132%.mozilla.devtools.p" - "rotobuf.StackFrame\022\031\n\021jsObjectClassName\030" - "\006 \001(\014\022\025\n\ncoarseType\030\007 \001(\r:\0010\"&\n\004Edge\022\020\n\010" - "referent\030\001 \001(\004\022\014\n\004name\030\002 \001(\014", 628); + "\022\014\n\004line\030\003 \001(\r\022\016\n\006column\030\004 \001(\r\022\020\n\006source" + "\030\005 \001(\014H\000\022\023\n\tsourceRef\030\006 \001(\004H\000\022\035\n\023functio" + "nDisplayName\030\007 \001(\014H\001\022 \n\026functionDisplayN" + "ameRef\030\010 \001(\004H\001\022\020\n\010isSystem\030\t \001(\010\022\024\n\014isSe" + "lfHosted\030\n \001(\010B\r\n\013SourceOrRefB\032\n\030Functio" + "nDisplayNameOrRefB\020\n\016StackFrameType\"\272\002\n\004" + "Node\022\n\n\002id\030\001 \001(\004\022\022\n\010typeName\030\002 \001(\014H\000\022\025\n\013" + "typeNameRef\030\003 \001(\004H\000\022\014\n\004size\030\004 \001(\004\022.\n\005edg" + "es\030\005 \003(\0132\037.mozilla.devtools.protobuf.Edg" + "e\022>\n\017allocationStack\030\006 \001(\0132%.mozilla.dev" + "tools.protobuf.StackFrame\022\033\n\021jsObjectCla" + "ssName\030\007 \001(\014H\001\022\036\n\024jsObjectClassNameRef\030\010" + " \001(\004H\001\022\025\n\ncoarseType\030\t \001(\r:\0010B\017\n\rTypeNam" + "eOrRefB\030\n\026JSObjectClassNameOrRef\"L\n\004Edge" + "\022\020\n\010referent\030\001 \001(\004\022\016\n\004name\030\002 \001(\014H\000\022\021\n\007na" + "meRef\030\003 \001(\004H\000B\017\n\rEdgeNameOrRef", 870); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "CoreDump.proto", &protobuf_RegisterTypes); Metadata::default_instance_ = new Metadata(); StackFrame::default_instance_ = new StackFrame(); StackFrame_default_oneof_instance_ = new StackFrameOneofInstance; StackFrame_Data::default_instance_ = new StackFrame_Data(); + StackFrame_Data_default_oneof_instance_ = new StackFrame_DataOneofInstance; Node::default_instance_ = new Node(); + Node_default_oneof_instance_ = new NodeOneofInstance; Edge::default_instance_ = new Edge(); + Edge_default_oneof_instance_ = new EdgeOneofInstance; Metadata::default_instance_->InitAsDefaultInstance(); StackFrame::default_instance_->InitAsDefaultInstance(); StackFrame_Data::default_instance_->InitAsDefaultInstance(); @@ -460,7 +504,9 @@ const int StackFrame_Data::kParentFieldNumber; const int StackFrame_Data::kLineFieldNumber; const int StackFrame_Data::kColumnFieldNumber; const int StackFrame_Data::kSourceFieldNumber; +const int StackFrame_Data::kSourceRefFieldNumber; const int StackFrame_Data::kFunctionDisplayNameFieldNumber; +const int StackFrame_Data::kFunctionDisplayNameRefFieldNumber; const int StackFrame_Data::kIsSystemFieldNumber; const int StackFrame_Data::kIsSelfHostedFieldNumber; #endif // !_MSC_VER @@ -473,6 +519,10 @@ StackFrame_Data::StackFrame_Data() void StackFrame_Data::InitAsDefaultInstance() { parent_ = const_cast< ::mozilla::devtools::protobuf::StackFrame*>(&::mozilla::devtools::protobuf::StackFrame::default_instance()); + StackFrame_Data_default_oneof_instance_->source_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited(); + StackFrame_Data_default_oneof_instance_->sourceref_ = GOOGLE_ULONGLONG(0); + StackFrame_Data_default_oneof_instance_->functiondisplayname_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited(); + StackFrame_Data_default_oneof_instance_->functiondisplaynameref_ = GOOGLE_ULONGLONG(0); } StackFrame_Data::StackFrame_Data(const StackFrame_Data& from) @@ -489,11 +539,11 @@ void StackFrame_Data::SharedCtor() { parent_ = NULL; line_ = 0u; column_ = 0u; - source_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - functiondisplayname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); issystem_ = false; isselfhosted_ = false; ::memset(_has_bits_, 0, sizeof(_has_bits_)); + clear_has_SourceOrRef(); + clear_has_FunctionDisplayNameOrRef(); } StackFrame_Data::~StackFrame_Data() { @@ -502,11 +552,11 @@ StackFrame_Data::~StackFrame_Data() { } void StackFrame_Data::SharedDtor() { - if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete source_; + if (has_SourceOrRef()) { + clear_SourceOrRef(); } - if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete functiondisplayname_; + if (has_FunctionDisplayNameOrRef()) { + clear_FunctionDisplayNameOrRef(); } if (this != default_instance_) { delete parent_; @@ -534,6 +584,41 @@ StackFrame_Data* StackFrame_Data::New() const { return new StackFrame_Data; } +void StackFrame_Data::clear_SourceOrRef() { + switch(SourceOrRef_case()) { + case kSource: { + delete SourceOrRef_.source_; + break; + } + case kSourceRef: { + // No need to clear + break; + } + case SOURCEORREF_NOT_SET: { + break; + } + } + _oneof_case_[0] = SOURCEORREF_NOT_SET; +} + +void StackFrame_Data::clear_FunctionDisplayNameOrRef() { + switch(FunctionDisplayNameOrRef_case()) { + case kFunctionDisplayName: { + delete FunctionDisplayNameOrRef_.functiondisplayname_; + break; + } + case kFunctionDisplayNameRef: { + // No need to clear + break; + } + case FUNCTIONDISPLAYNAMEORREF_NOT_SET: { + break; + } + } + _oneof_case_[1] = FUNCTIONDISPLAYNAMEORREF_NOT_SET; +} + + void StackFrame_Data::Clear() { #define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ &reinterpret_cast(16)->f) - \ @@ -545,28 +630,20 @@ void StackFrame_Data::Clear() { ::memset(&first, 0, n); \ } while (0) - if (_has_bits_[0 / 32] & 255) { + if (_has_bits_[0 / 32] & 15) { ZR_(line_, column_); - ZR_(issystem_, isselfhosted_); id_ = GOOGLE_ULONGLONG(0); if (has_parent()) { if (parent_ != NULL) parent_->::mozilla::devtools::protobuf::StackFrame::Clear(); } - if (has_source()) { - if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - source_->clear(); - } - } - if (has_functiondisplayname()) { - if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - functiondisplayname_->clear(); - } - } } + ZR_(issystem_, isselfhosted_); #undef OFFSET_OF_FIELD_ #undef ZR_ + clear_SourceOrRef(); + clear_FunctionDisplayNameOrRef(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); } @@ -647,26 +724,58 @@ bool StackFrame_Data::MergePartialFromCodedStream( } else { goto handle_unusual; } - if (input->ExpectTag(50)) goto parse_functionDisplayName; + if (input->ExpectTag(48)) goto parse_sourceRef; break; } - // optional bytes functionDisplayName = 6; + // optional uint64 sourceRef = 6; case 6: { - if (tag == 50) { + if (tag == 48) { + parse_sourceRef: + clear_SourceOrRef(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &SourceOrRef_.sourceref_))); + set_has_sourceref(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(58)) goto parse_functionDisplayName; + break; + } + + // optional bytes functionDisplayName = 7; + case 7: { + if (tag == 58) { parse_functionDisplayName: DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( input, this->mutable_functiondisplayname())); } else { goto handle_unusual; } - if (input->ExpectTag(56)) goto parse_isSystem; + if (input->ExpectTag(64)) goto parse_functionDisplayNameRef; break; } - // optional bool isSystem = 7; - case 7: { - if (tag == 56) { + // optional uint64 functionDisplayNameRef = 8; + case 8: { + if (tag == 64) { + parse_functionDisplayNameRef: + clear_FunctionDisplayNameOrRef(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &FunctionDisplayNameOrRef_.functiondisplaynameref_))); + set_has_functiondisplaynameref(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(72)) goto parse_isSystem; + break; + } + + // optional bool isSystem = 9; + case 9: { + if (tag == 72) { parse_isSystem: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -675,13 +784,13 @@ bool StackFrame_Data::MergePartialFromCodedStream( } else { goto handle_unusual; } - if (input->ExpectTag(64)) goto parse_isSelfHosted; + if (input->ExpectTag(80)) goto parse_isSelfHosted; break; } - // optional bool isSelfHosted = 8; - case 8: { - if (tag == 64) { + // optional bool isSelfHosted = 10; + case 10: { + if (tag == 80) { parse_isSelfHosted: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( @@ -746,20 +855,30 @@ void StackFrame_Data::SerializeWithCachedSizes( 5, this->source(), output); } - // optional bytes functionDisplayName = 6; + // optional uint64 sourceRef = 6; + if (has_sourceref()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(6, this->sourceref(), output); + } + + // optional bytes functionDisplayName = 7; if (has_functiondisplayname()) { ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( - 6, this->functiondisplayname(), output); + 7, this->functiondisplayname(), output); } - // optional bool isSystem = 7; + // optional uint64 functionDisplayNameRef = 8; + if (has_functiondisplaynameref()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->functiondisplaynameref(), output); + } + + // optional bool isSystem = 9; if (has_issystem()) { - ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->issystem(), output); + ::google::protobuf::internal::WireFormatLite::WriteBool(9, this->issystem(), output); } - // optional bool isSelfHosted = 8; + // optional bool isSelfHosted = 10; if (has_isselfhosted()) { - ::google::protobuf::internal::WireFormatLite::WriteBool(8, this->isselfhosted(), output); + ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->isselfhosted(), output); } if (!unknown_fields().empty()) { @@ -801,21 +920,31 @@ void StackFrame_Data::SerializeWithCachedSizes( 5, this->source(), target); } - // optional bytes functionDisplayName = 6; + // optional uint64 sourceRef = 6; + if (has_sourceref()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(6, this->sourceref(), target); + } + + // optional bytes functionDisplayName = 7; if (has_functiondisplayname()) { target = ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( - 6, this->functiondisplayname(), target); + 7, this->functiondisplayname(), target); } - // optional bool isSystem = 7; + // optional uint64 functionDisplayNameRef = 8; + if (has_functiondisplaynameref()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(8, this->functiondisplaynameref(), target); + } + + // optional bool isSystem = 9; if (has_issystem()) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->issystem(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(9, this->issystem(), target); } - // optional bool isSelfHosted = 8; + // optional bool isSelfHosted = 10; if (has_isselfhosted()) { - target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(8, this->isselfhosted(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->isselfhosted(), target); } if (!unknown_fields().empty()) { @@ -858,31 +987,57 @@ int StackFrame_Data::ByteSize() const { this->column()); } - // optional bytes source = 5; - if (has_source()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::BytesSize( - this->source()); - } - - // optional bytes functionDisplayName = 6; - if (has_functiondisplayname()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::BytesSize( - this->functiondisplayname()); - } - - // optional bool isSystem = 7; + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional bool isSystem = 9; if (has_issystem()) { total_size += 1 + 1; } - // optional bool isSelfHosted = 8; + // optional bool isSelfHosted = 10; if (has_isselfhosted()) { total_size += 1 + 1; } } + switch (SourceOrRef_case()) { + // optional bytes source = 5; + case kSource: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->source()); + break; + } + // optional uint64 sourceRef = 6; + case kSourceRef: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->sourceref()); + break; + } + case SOURCEORREF_NOT_SET: { + break; + } + } + switch (FunctionDisplayNameOrRef_case()) { + // optional bytes functionDisplayName = 7; + case kFunctionDisplayName: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->functiondisplayname()); + break; + } + // optional uint64 functionDisplayNameRef = 8; + case kFunctionDisplayNameRef: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->functiondisplaynameref()); + break; + } + case FUNCTIONDISPLAYNAMEORREF_NOT_SET: { + break; + } + } if (!unknown_fields().empty()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( @@ -908,6 +1063,32 @@ void StackFrame_Data::MergeFrom(const ::google::protobuf::Message& from) { void StackFrame_Data::MergeFrom(const StackFrame_Data& from) { GOOGLE_CHECK_NE(&from, this); + switch (from.SourceOrRef_case()) { + case kSource: { + set_source(from.source()); + break; + } + case kSourceRef: { + set_sourceref(from.sourceref()); + break; + } + case SOURCEORREF_NOT_SET: { + break; + } + } + switch (from.FunctionDisplayNameOrRef_case()) { + case kFunctionDisplayName: { + set_functiondisplayname(from.functiondisplayname()); + break; + } + case kFunctionDisplayNameRef: { + set_functiondisplaynameref(from.functiondisplaynameref()); + break; + } + case FUNCTIONDISPLAYNAMEORREF_NOT_SET: { + break; + } + } if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from.has_id()) { set_id(from.id()); @@ -921,12 +1102,8 @@ void StackFrame_Data::MergeFrom(const StackFrame_Data& from) { if (from.has_column()) { set_column(from.column()); } - if (from.has_source()) { - set_source(from.source()); - } - if (from.has_functiondisplayname()) { - set_functiondisplayname(from.functiondisplayname()); - } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { if (from.has_issystem()) { set_issystem(from.issystem()); } @@ -960,10 +1137,12 @@ void StackFrame_Data::Swap(StackFrame_Data* other) { std::swap(parent_, other->parent_); std::swap(line_, other->line_); std::swap(column_, other->column_); - std::swap(source_, other->source_); - std::swap(functiondisplayname_, other->functiondisplayname_); std::swap(issystem_, other->issystem_); std::swap(isselfhosted_, other->isselfhosted_); + std::swap(SourceOrRef_, other->SourceOrRef_); + std::swap(_oneof_case_[0], other->_oneof_case_[0]); + std::swap(FunctionDisplayNameOrRef_, other->FunctionDisplayNameOrRef_); + std::swap(_oneof_case_[1], other->_oneof_case_[1]); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); @@ -1276,10 +1455,12 @@ void StackFrame::Swap(StackFrame* other) { #ifndef _MSC_VER const int Node::kIdFieldNumber; const int Node::kTypeNameFieldNumber; +const int Node::kTypeNameRefFieldNumber; const int Node::kSizeFieldNumber; const int Node::kEdgesFieldNumber; const int Node::kAllocationStackFieldNumber; const int Node::kJsObjectClassNameFieldNumber; +const int Node::kJsObjectClassNameRefFieldNumber; const int Node::kCoarseTypeFieldNumber; #endif // !_MSC_VER @@ -1290,7 +1471,11 @@ Node::Node() } void Node::InitAsDefaultInstance() { + Node_default_oneof_instance_->typename__ = &::google::protobuf::internal::GetEmptyStringAlreadyInited(); + Node_default_oneof_instance_->typenameref_ = GOOGLE_ULONGLONG(0); allocationstack_ = const_cast< ::mozilla::devtools::protobuf::StackFrame*>(&::mozilla::devtools::protobuf::StackFrame::default_instance()); + Node_default_oneof_instance_->jsobjectclassname_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited(); + Node_default_oneof_instance_->jsobjectclassnameref_ = GOOGLE_ULONGLONG(0); } Node::Node(const Node& from) @@ -1304,12 +1489,12 @@ void Node::SharedCtor() { ::google::protobuf::internal::GetEmptyString(); _cached_size_ = 0; id_ = GOOGLE_ULONGLONG(0); - typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); size_ = GOOGLE_ULONGLONG(0); allocationstack_ = NULL; - jsobjectclassname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); coarsetype_ = 0u; ::memset(_has_bits_, 0, sizeof(_has_bits_)); + clear_has_TypeNameOrRef(); + clear_has_JSObjectClassNameOrRef(); } Node::~Node() { @@ -1318,11 +1503,11 @@ Node::~Node() { } void Node::SharedDtor() { - if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete typename__; + if (has_TypeNameOrRef()) { + clear_TypeNameOrRef(); } - if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete jsobjectclassname_; + if (has_JSObjectClassNameOrRef()) { + clear_JSObjectClassNameOrRef(); } if (this != default_instance_) { delete allocationstack_; @@ -1350,26 +1535,66 @@ Node* Node::New() const { return new Node; } -void Node::Clear() { - if (_has_bits_[0 / 32] & 119) { - id_ = GOOGLE_ULONGLONG(0); - if (has_typename_()) { - if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - typename__->clear(); - } +void Node::clear_TypeNameOrRef() { + switch(TypeNameOrRef_case()) { + case kTypeName: { + delete TypeNameOrRef_.typename__; + break; } - size_ = GOOGLE_ULONGLONG(0); + case kTypeNameRef: { + // No need to clear + break; + } + case TYPENAMEORREF_NOT_SET: { + break; + } + } + _oneof_case_[0] = TYPENAMEORREF_NOT_SET; +} + +void Node::clear_JSObjectClassNameOrRef() { + switch(JSObjectClassNameOrRef_case()) { + case kJsObjectClassName: { + delete JSObjectClassNameOrRef_.jsobjectclassname_; + break; + } + case kJsObjectClassNameRef: { + // No need to clear + break; + } + case JSOBJECTCLASSNAMEORREF_NOT_SET: { + break; + } + } + _oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET; +} + + +void Node::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 41) { + ZR_(id_, size_); if (has_allocationstack()) { if (allocationstack_ != NULL) allocationstack_->::mozilla::devtools::protobuf::StackFrame::Clear(); } - if (has_jsobjectclassname()) { - if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - jsobjectclassname_->clear(); - } - } - coarsetype_ = 0u; } + coarsetype_ = 0u; + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + edges_.Clear(); + clear_TypeNameOrRef(); + clear_JSObjectClassNameOrRef(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); } @@ -1407,13 +1632,29 @@ bool Node::MergePartialFromCodedStream( } else { goto handle_unusual; } - if (input->ExpectTag(24)) goto parse_size; + if (input->ExpectTag(24)) goto parse_typeNameRef; break; } - // optional uint64 size = 3; + // optional uint64 typeNameRef = 3; case 3: { if (tag == 24) { + parse_typeNameRef: + clear_TypeNameOrRef(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &TypeNameOrRef_.typenameref_))); + set_has_typenameref(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(32)) goto parse_size; + break; + } + + // optional uint64 size = 4; + case 4: { + if (tag == 32) { parse_size: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( @@ -1422,53 +1663,69 @@ bool Node::MergePartialFromCodedStream( } else { goto handle_unusual; } - if (input->ExpectTag(34)) goto parse_edges; + if (input->ExpectTag(42)) goto parse_edges; break; } - // repeated .mozilla.devtools.protobuf.Edge edges = 4; - case 4: { - if (tag == 34) { + // repeated .mozilla.devtools.protobuf.Edge edges = 5; + case 5: { + if (tag == 42) { parse_edges: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_edges())); } else { goto handle_unusual; } - if (input->ExpectTag(34)) goto parse_edges; - if (input->ExpectTag(42)) goto parse_allocationStack; + if (input->ExpectTag(42)) goto parse_edges; + if (input->ExpectTag(50)) goto parse_allocationStack; break; } - // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5; - case 5: { - if (tag == 42) { + // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6; + case 6: { + if (tag == 50) { parse_allocationStack: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_allocationstack())); } else { goto handle_unusual; } - if (input->ExpectTag(50)) goto parse_jsObjectClassName; + if (input->ExpectTag(58)) goto parse_jsObjectClassName; break; } - // optional bytes jsObjectClassName = 6; - case 6: { - if (tag == 50) { + // optional bytes jsObjectClassName = 7; + case 7: { + if (tag == 58) { parse_jsObjectClassName: DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( input, this->mutable_jsobjectclassname())); } else { goto handle_unusual; } - if (input->ExpectTag(56)) goto parse_coarseType; + if (input->ExpectTag(64)) goto parse_jsObjectClassNameRef; break; } - // optional uint32 coarseType = 7 [default = 0]; - case 7: { - if (tag == 56) { + // optional uint64 jsObjectClassNameRef = 8; + case 8: { + if (tag == 64) { + parse_jsObjectClassNameRef: + clear_JSObjectClassNameOrRef(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &JSObjectClassNameOrRef_.jsobjectclassnameref_))); + set_has_jsobjectclassnameref(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(72)) goto parse_coarseType; + break; + } + + // optional uint32 coarseType = 9 [default = 0]; + case 9: { + if (tag == 72) { parse_coarseType: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( @@ -1517,32 +1774,42 @@ void Node::SerializeWithCachedSizes( 2, this->typename_(), output); } - // optional uint64 size = 3; - if (has_size()) { - ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->size(), output); + // optional uint64 typeNameRef = 3; + if (has_typenameref()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->typenameref(), output); } - // repeated .mozilla.devtools.protobuf.Edge edges = 4; + // optional uint64 size = 4; + if (has_size()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->size(), output); + } + + // repeated .mozilla.devtools.protobuf.Edge edges = 5; for (int i = 0; i < this->edges_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 4, this->edges(i), output); + 5, this->edges(i), output); } - // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5; + // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6; if (has_allocationstack()) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( - 5, this->allocationstack(), output); + 6, this->allocationstack(), output); } - // optional bytes jsObjectClassName = 6; + // optional bytes jsObjectClassName = 7; if (has_jsobjectclassname()) { ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( - 6, this->jsobjectclassname(), output); + 7, this->jsobjectclassname(), output); } - // optional uint32 coarseType = 7 [default = 0]; + // optional uint64 jsObjectClassNameRef = 8; + if (has_jsobjectclassnameref()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->jsobjectclassnameref(), output); + } + + // optional uint32 coarseType = 9 [default = 0]; if (has_coarsetype()) { - ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->coarsetype(), output); + ::google::protobuf::internal::WireFormatLite::WriteUInt32(9, this->coarsetype(), output); } if (!unknown_fields().empty()) { @@ -1567,35 +1834,45 @@ void Node::SerializeWithCachedSizes( 2, this->typename_(), target); } - // optional uint64 size = 3; - if (has_size()) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->size(), target); + // optional uint64 typeNameRef = 3; + if (has_typenameref()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->typenameref(), target); } - // repeated .mozilla.devtools.protobuf.Edge edges = 4; + // optional uint64 size = 4; + if (has_size()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->size(), target); + } + + // repeated .mozilla.devtools.protobuf.Edge edges = 5; for (int i = 0; i < this->edges_size(); i++) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( - 4, this->edges(i), target); + 5, this->edges(i), target); } - // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5; + // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6; if (has_allocationstack()) { target = ::google::protobuf::internal::WireFormatLite:: WriteMessageNoVirtualToArray( - 5, this->allocationstack(), target); + 6, this->allocationstack(), target); } - // optional bytes jsObjectClassName = 6; + // optional bytes jsObjectClassName = 7; if (has_jsobjectclassname()) { target = ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( - 6, this->jsobjectclassname(), target); + 7, this->jsobjectclassname(), target); } - // optional uint32 coarseType = 7 [default = 0]; + // optional uint64 jsObjectClassNameRef = 8; + if (has_jsobjectclassnameref()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(8, this->jsobjectclassnameref(), target); + } + + // optional uint32 coarseType = 9 [default = 0]; if (has_coarsetype()) { - target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(7, this->coarsetype(), target); + target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(9, this->coarsetype(), target); } if (!unknown_fields().empty()) { @@ -1617,35 +1894,23 @@ int Node::ByteSize() const { this->id()); } - // optional bytes typeName = 2; - if (has_typename_()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::BytesSize( - this->typename_()); - } - - // optional uint64 size = 3; + // optional uint64 size = 4; if (has_size()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->size()); } - // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5; + // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6; if (has_allocationstack()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->allocationstack()); } - // optional bytes jsObjectClassName = 6; - if (has_jsobjectclassname()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::BytesSize( - this->jsobjectclassname()); - } - - // optional uint32 coarseType = 7 [default = 0]; + } + if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { + // optional uint32 coarseType = 9 [default = 0]; if (has_coarsetype()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( @@ -1653,7 +1918,7 @@ int Node::ByteSize() const { } } - // repeated .mozilla.devtools.protobuf.Edge edges = 4; + // repeated .mozilla.devtools.protobuf.Edge edges = 5; total_size += 1 * this->edges_size(); for (int i = 0; i < this->edges_size(); i++) { total_size += @@ -1661,6 +1926,44 @@ int Node::ByteSize() const { this->edges(i)); } + switch (TypeNameOrRef_case()) { + // optional bytes typeName = 2; + case kTypeName: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->typename_()); + break; + } + // optional uint64 typeNameRef = 3; + case kTypeNameRef: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->typenameref()); + break; + } + case TYPENAMEORREF_NOT_SET: { + break; + } + } + switch (JSObjectClassNameOrRef_case()) { + // optional bytes jsObjectClassName = 7; + case kJsObjectClassName: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::BytesSize( + this->jsobjectclassname()); + break; + } + // optional uint64 jsObjectClassNameRef = 8; + case kJsObjectClassNameRef: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->jsobjectclassnameref()); + break; + } + case JSOBJECTCLASSNAMEORREF_NOT_SET: { + break; + } + } if (!unknown_fields().empty()) { total_size += ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( @@ -1687,22 +1990,44 @@ void Node::MergeFrom(const ::google::protobuf::Message& from) { void Node::MergeFrom(const Node& from) { GOOGLE_CHECK_NE(&from, this); edges_.MergeFrom(from.edges_); + switch (from.TypeNameOrRef_case()) { + case kTypeName: { + set_typename_(from.typename_()); + break; + } + case kTypeNameRef: { + set_typenameref(from.typenameref()); + break; + } + case TYPENAMEORREF_NOT_SET: { + break; + } + } + switch (from.JSObjectClassNameOrRef_case()) { + case kJsObjectClassName: { + set_jsobjectclassname(from.jsobjectclassname()); + break; + } + case kJsObjectClassNameRef: { + set_jsobjectclassnameref(from.jsobjectclassnameref()); + break; + } + case JSOBJECTCLASSNAMEORREF_NOT_SET: { + break; + } + } if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from.has_id()) { set_id(from.id()); } - if (from.has_typename_()) { - set_typename_(from.typename_()); - } if (from.has_size()) { set_size(from.size()); } if (from.has_allocationstack()) { mutable_allocationstack()->::mozilla::devtools::protobuf::StackFrame::MergeFrom(from.allocationstack()); } - if (from.has_jsobjectclassname()) { - set_jsobjectclassname(from.jsobjectclassname()); - } + } + if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) { if (from.has_coarsetype()) { set_coarsetype(from.coarsetype()); } @@ -1730,12 +2055,14 @@ bool Node::IsInitialized() const { void Node::Swap(Node* other) { if (other != this) { std::swap(id_, other->id_); - std::swap(typename__, other->typename__); std::swap(size_, other->size_); edges_.Swap(&other->edges_); std::swap(allocationstack_, other->allocationstack_); - std::swap(jsobjectclassname_, other->jsobjectclassname_); std::swap(coarsetype_, other->coarsetype_); + std::swap(TypeNameOrRef_, other->TypeNameOrRef_); + std::swap(_oneof_case_[0], other->_oneof_case_[0]); + std::swap(JSObjectClassNameOrRef_, other->JSObjectClassNameOrRef_); + std::swap(_oneof_case_[1], other->_oneof_case_[1]); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); @@ -1756,6 +2083,7 @@ void Node::Swap(Node* other) { #ifndef _MSC_VER const int Edge::kReferentFieldNumber; const int Edge::kNameFieldNumber; +const int Edge::kNameRefFieldNumber; #endif // !_MSC_VER Edge::Edge() @@ -1765,6 +2093,8 @@ Edge::Edge() } void Edge::InitAsDefaultInstance() { + Edge_default_oneof_instance_->name_ = &::google::protobuf::internal::GetEmptyStringAlreadyInited(); + Edge_default_oneof_instance_->nameref_ = GOOGLE_ULONGLONG(0); } Edge::Edge(const Edge& from) @@ -1778,8 +2108,8 @@ void Edge::SharedCtor() { ::google::protobuf::internal::GetEmptyString(); _cached_size_ = 0; referent_ = GOOGLE_ULONGLONG(0); - name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); ::memset(_has_bits_, 0, sizeof(_has_bits_)); + clear_has_EdgeNameOrRef(); } Edge::~Edge() { @@ -1788,8 +2118,8 @@ Edge::~Edge() { } void Edge::SharedDtor() { - if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete name_; + if (has_EdgeNameOrRef()) { + clear_EdgeNameOrRef(); } if (this != default_instance_) { } @@ -1816,15 +2146,27 @@ Edge* Edge::New() const { return new Edge; } -void Edge::Clear() { - if (_has_bits_[0 / 32] & 3) { - referent_ = GOOGLE_ULONGLONG(0); - if (has_name()) { - if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - name_->clear(); - } +void Edge::clear_EdgeNameOrRef() { + switch(EdgeNameOrRef_case()) { + case kName: { + delete EdgeNameOrRef_.name_; + break; + } + case kNameRef: { + // No need to clear + break; + } + case EDGENAMEORREF_NOT_SET: { + break; } } + _oneof_case_[0] = EDGENAMEORREF_NOT_SET; +} + + +void Edge::Clear() { + referent_ = GOOGLE_ULONGLONG(0); + clear_EdgeNameOrRef(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); mutable_unknown_fields()->Clear(); } @@ -1862,6 +2204,22 @@ bool Edge::MergePartialFromCodedStream( } else { goto handle_unusual; } + if (input->ExpectTag(24)) goto parse_nameRef; + break; + } + + // optional uint64 nameRef = 3; + case 3: { + if (tag == 24) { + parse_nameRef: + clear_EdgeNameOrRef(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &EdgeNameOrRef_.nameref_))); + set_has_nameref(); + } else { + goto handle_unusual; + } if (input->ExpectAtEnd()) goto success; break; } @@ -1902,6 +2260,11 @@ void Edge::SerializeWithCachedSizes( 2, this->name(), output); } + // optional uint64 nameRef = 3; + if (has_nameref()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->nameref(), output); + } + if (!unknown_fields().empty()) { ::google::protobuf::internal::WireFormat::SerializeUnknownFields( unknown_fields(), output); @@ -1924,6 +2287,11 @@ void Edge::SerializeWithCachedSizes( 2, this->name(), target); } + // optional uint64 nameRef = 3; + if (has_nameref()) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->nameref(), target); + } + if (!unknown_fields().empty()) { target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( unknown_fields(), target); @@ -1943,13 +2311,25 @@ int Edge::ByteSize() const { this->referent()); } + } + switch (EdgeNameOrRef_case()) { // optional bytes name = 2; - if (has_name()) { + case kName: { total_size += 1 + ::google::protobuf::internal::WireFormatLite::BytesSize( this->name()); + break; + } + // optional uint64 nameRef = 3; + case kNameRef: { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->nameref()); + break; + } + case EDGENAMEORREF_NOT_SET: { + break; } - } if (!unknown_fields().empty()) { total_size += @@ -1976,13 +2356,23 @@ void Edge::MergeFrom(const ::google::protobuf::Message& from) { void Edge::MergeFrom(const Edge& from) { GOOGLE_CHECK_NE(&from, this); + switch (from.EdgeNameOrRef_case()) { + case kName: { + set_name(from.name()); + break; + } + case kNameRef: { + set_nameref(from.nameref()); + break; + } + case EDGENAMEORREF_NOT_SET: { + break; + } + } if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { if (from.has_referent()) { set_referent(from.referent()); } - if (from.has_name()) { - set_name(from.name()); - } } mutable_unknown_fields()->MergeFrom(from.unknown_fields()); } @@ -2007,7 +2397,8 @@ bool Edge::IsInitialized() const { void Edge::Swap(Edge* other) { if (other != this) { std::swap(referent_, other->referent_); - std::swap(name_, other->name_); + std::swap(EdgeNameOrRef_, other->EdgeNameOrRef_); + std::swap(_oneof_case_[0], other->_oneof_case_[0]); std::swap(_has_bits_[0], other->_has_bits_[0]); _unknown_fields_.Swap(&other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); diff --git a/devtools/shared/heapsnapshot/CoreDump.pb.h b/devtools/shared/heapsnapshot/CoreDump.pb.h index d63895100d5..79025dd3ac9 100644 --- a/devtools/shared/heapsnapshot/CoreDump.pb.h +++ b/devtools/shared/heapsnapshot/CoreDump.pb.h @@ -145,6 +145,18 @@ class StackFrame_Data : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const StackFrame_Data& default_instance(); + enum SourceOrRefCase { + kSource = 5, + kSourceRef = 6, + SOURCEORREF_NOT_SET = 0, + }; + + enum FunctionDisplayNameOrRefCase { + kFunctionDisplayName = 7, + kFunctionDisplayNameRef = 8, + FUNCTIONDISPLAYNAMEORREF_NOT_SET = 0, + }; + void Swap(StackFrame_Data* other); // implements Message ---------------------------------------------- @@ -217,10 +229,17 @@ class StackFrame_Data : public ::google::protobuf::Message { inline ::std::string* release_source(); inline void set_allocated_source(::std::string* source); - // optional bytes functionDisplayName = 6; + // optional uint64 sourceRef = 6; + inline bool has_sourceref() const; + inline void clear_sourceref(); + static const int kSourceRefFieldNumber = 6; + inline ::google::protobuf::uint64 sourceref() const; + inline void set_sourceref(::google::protobuf::uint64 value); + + // optional bytes functionDisplayName = 7; inline bool has_functiondisplayname() const; inline void clear_functiondisplayname(); - static const int kFunctionDisplayNameFieldNumber = 6; + static const int kFunctionDisplayNameFieldNumber = 7; inline const ::std::string& functiondisplayname() const; inline void set_functiondisplayname(const ::std::string& value); inline void set_functiondisplayname(const char* value); @@ -229,20 +248,29 @@ class StackFrame_Data : public ::google::protobuf::Message { inline ::std::string* release_functiondisplayname(); inline void set_allocated_functiondisplayname(::std::string* functiondisplayname); - // optional bool isSystem = 7; + // optional uint64 functionDisplayNameRef = 8; + inline bool has_functiondisplaynameref() const; + inline void clear_functiondisplaynameref(); + static const int kFunctionDisplayNameRefFieldNumber = 8; + inline ::google::protobuf::uint64 functiondisplaynameref() const; + inline void set_functiondisplaynameref(::google::protobuf::uint64 value); + + // optional bool isSystem = 9; inline bool has_issystem() const; inline void clear_issystem(); - static const int kIsSystemFieldNumber = 7; + static const int kIsSystemFieldNumber = 9; inline bool issystem() const; inline void set_issystem(bool value); - // optional bool isSelfHosted = 8; + // optional bool isSelfHosted = 10; inline bool has_isselfhosted() const; inline void clear_isselfhosted(); - static const int kIsSelfHostedFieldNumber = 8; + static const int kIsSelfHostedFieldNumber = 10; inline bool isselfhosted() const; inline void set_isselfhosted(bool value); + inline SourceOrRefCase SourceOrRef_case() const; + inline FunctionDisplayNameOrRefCase FunctionDisplayNameOrRef_case() const; // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.StackFrame.Data) private: inline void set_has_id(); @@ -254,14 +282,22 @@ class StackFrame_Data : public ::google::protobuf::Message { inline void set_has_column(); inline void clear_has_column(); inline void set_has_source(); - inline void clear_has_source(); + inline void set_has_sourceref(); inline void set_has_functiondisplayname(); - inline void clear_has_functiondisplayname(); + inline void set_has_functiondisplaynameref(); inline void set_has_issystem(); inline void clear_has_issystem(); inline void set_has_isselfhosted(); inline void clear_has_isselfhosted(); + inline bool has_SourceOrRef(); + void clear_SourceOrRef(); + inline void clear_has_SourceOrRef(); + + inline bool has_FunctionDisplayNameOrRef(); + void clear_FunctionDisplayNameOrRef(); + inline void clear_has_FunctionDisplayNameOrRef(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; ::google::protobuf::uint32 _has_bits_[1]; @@ -270,10 +306,18 @@ class StackFrame_Data : public ::google::protobuf::Message { ::mozilla::devtools::protobuf::StackFrame* parent_; ::google::protobuf::uint32 line_; ::google::protobuf::uint32 column_; - ::std::string* source_; - ::std::string* functiondisplayname_; bool issystem_; bool isselfhosted_; + union SourceOrRefUnion { + ::std::string* source_; + ::google::protobuf::uint64 sourceref_; + } SourceOrRef_; + union FunctionDisplayNameOrRefUnion { + ::std::string* functiondisplayname_; + ::google::protobuf::uint64 functiondisplaynameref_; + } FunctionDisplayNameOrRef_; + ::google::protobuf::uint32 _oneof_case_[2]; + friend void protobuf_AddDesc_CoreDump_2eproto(); friend void protobuf_AssignDesc_CoreDump_2eproto(); friend void protobuf_ShutdownFile_CoreDump_2eproto(); @@ -412,6 +456,18 @@ class Node : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const Node& default_instance(); + enum TypeNameOrRefCase { + kTypeName = 2, + kTypeNameRef = 3, + TYPENAMEORREF_NOT_SET = 0, + }; + + enum JSObjectClassNameOrRefCase { + kJsObjectClassName = 7, + kJsObjectClassNameRef = 8, + JSOBJECTCLASSNAMEORREF_NOT_SET = 0, + }; + void Swap(Node* other); // implements Message ---------------------------------------------- @@ -461,17 +517,24 @@ class Node : public ::google::protobuf::Message { inline ::std::string* release_typename_(); inline void set_allocated_typename_(::std::string* typename_); - // optional uint64 size = 3; + // optional uint64 typeNameRef = 3; + inline bool has_typenameref() const; + inline void clear_typenameref(); + static const int kTypeNameRefFieldNumber = 3; + inline ::google::protobuf::uint64 typenameref() const; + inline void set_typenameref(::google::protobuf::uint64 value); + + // optional uint64 size = 4; inline bool has_size() const; inline void clear_size(); - static const int kSizeFieldNumber = 3; + static const int kSizeFieldNumber = 4; inline ::google::protobuf::uint64 size() const; inline void set_size(::google::protobuf::uint64 value); - // repeated .mozilla.devtools.protobuf.Edge edges = 4; + // repeated .mozilla.devtools.protobuf.Edge edges = 5; inline int edges_size() const; inline void clear_edges(); - static const int kEdgesFieldNumber = 4; + static const int kEdgesFieldNumber = 5; inline const ::mozilla::devtools::protobuf::Edge& edges(int index) const; inline ::mozilla::devtools::protobuf::Edge* mutable_edges(int index); inline ::mozilla::devtools::protobuf::Edge* add_edges(); @@ -480,19 +543,19 @@ class Node : public ::google::protobuf::Message { inline ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge >* mutable_edges(); - // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5; + // optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6; inline bool has_allocationstack() const; inline void clear_allocationstack(); - static const int kAllocationStackFieldNumber = 5; + static const int kAllocationStackFieldNumber = 6; inline const ::mozilla::devtools::protobuf::StackFrame& allocationstack() const; inline ::mozilla::devtools::protobuf::StackFrame* mutable_allocationstack(); inline ::mozilla::devtools::protobuf::StackFrame* release_allocationstack(); inline void set_allocated_allocationstack(::mozilla::devtools::protobuf::StackFrame* allocationstack); - // optional bytes jsObjectClassName = 6; + // optional bytes jsObjectClassName = 7; inline bool has_jsobjectclassname() const; inline void clear_jsobjectclassname(); - static const int kJsObjectClassNameFieldNumber = 6; + static const int kJsObjectClassNameFieldNumber = 7; inline const ::std::string& jsobjectclassname() const; inline void set_jsobjectclassname(const ::std::string& value); inline void set_jsobjectclassname(const char* value); @@ -501,39 +564,64 @@ class Node : public ::google::protobuf::Message { inline ::std::string* release_jsobjectclassname(); inline void set_allocated_jsobjectclassname(::std::string* jsobjectclassname); - // optional uint32 coarseType = 7 [default = 0]; + // optional uint64 jsObjectClassNameRef = 8; + inline bool has_jsobjectclassnameref() const; + inline void clear_jsobjectclassnameref(); + static const int kJsObjectClassNameRefFieldNumber = 8; + inline ::google::protobuf::uint64 jsobjectclassnameref() const; + inline void set_jsobjectclassnameref(::google::protobuf::uint64 value); + + // optional uint32 coarseType = 9 [default = 0]; inline bool has_coarsetype() const; inline void clear_coarsetype(); - static const int kCoarseTypeFieldNumber = 7; + static const int kCoarseTypeFieldNumber = 9; inline ::google::protobuf::uint32 coarsetype() const; inline void set_coarsetype(::google::protobuf::uint32 value); + inline TypeNameOrRefCase TypeNameOrRef_case() const; + inline JSObjectClassNameOrRefCase JSObjectClassNameOrRef_case() const; // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Node) private: inline void set_has_id(); inline void clear_has_id(); inline void set_has_typename_(); - inline void clear_has_typename_(); + inline void set_has_typenameref(); inline void set_has_size(); inline void clear_has_size(); inline void set_has_allocationstack(); inline void clear_has_allocationstack(); inline void set_has_jsobjectclassname(); - inline void clear_has_jsobjectclassname(); + inline void set_has_jsobjectclassnameref(); inline void set_has_coarsetype(); inline void clear_has_coarsetype(); + inline bool has_TypeNameOrRef(); + void clear_TypeNameOrRef(); + inline void clear_has_TypeNameOrRef(); + + inline bool has_JSObjectClassNameOrRef(); + void clear_JSObjectClassNameOrRef(); + inline void clear_has_JSObjectClassNameOrRef(); + ::google::protobuf::UnknownFieldSet _unknown_fields_; ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; ::google::protobuf::uint64 id_; - ::std::string* typename__; ::google::protobuf::uint64 size_; ::google::protobuf::RepeatedPtrField< ::mozilla::devtools::protobuf::Edge > edges_; ::mozilla::devtools::protobuf::StackFrame* allocationstack_; - ::std::string* jsobjectclassname_; ::google::protobuf::uint32 coarsetype_; + union TypeNameOrRefUnion { + ::std::string* typename__; + ::google::protobuf::uint64 typenameref_; + } TypeNameOrRef_; + union JSObjectClassNameOrRefUnion { + ::std::string* jsobjectclassname_; + ::google::protobuf::uint64 jsobjectclassnameref_; + } JSObjectClassNameOrRef_; + ::google::protobuf::uint32 _oneof_case_[2]; + friend void protobuf_AddDesc_CoreDump_2eproto(); friend void protobuf_AssignDesc_CoreDump_2eproto(); friend void protobuf_ShutdownFile_CoreDump_2eproto(); @@ -566,6 +654,12 @@ class Edge : public ::google::protobuf::Message { static const ::google::protobuf::Descriptor* descriptor(); static const Edge& default_instance(); + enum EdgeNameOrRefCase { + kName = 2, + kNameRef = 3, + EDGENAMEORREF_NOT_SET = 0, + }; + void Swap(Edge* other); // implements Message ---------------------------------------------- @@ -615,19 +709,36 @@ class Edge : public ::google::protobuf::Message { inline ::std::string* release_name(); inline void set_allocated_name(::std::string* name); + // optional uint64 nameRef = 3; + inline bool has_nameref() const; + inline void clear_nameref(); + static const int kNameRefFieldNumber = 3; + inline ::google::protobuf::uint64 nameref() const; + inline void set_nameref(::google::protobuf::uint64 value); + + inline EdgeNameOrRefCase EdgeNameOrRef_case() const; // @@protoc_insertion_point(class_scope:mozilla.devtools.protobuf.Edge) private: inline void set_has_referent(); inline void clear_has_referent(); inline void set_has_name(); - inline void clear_has_name(); + inline void set_has_nameref(); + + inline bool has_EdgeNameOrRef(); + void clear_EdgeNameOrRef(); + inline void clear_has_EdgeNameOrRef(); ::google::protobuf::UnknownFieldSet _unknown_fields_; ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; ::google::protobuf::uint64 referent_; - ::std::string* name_; + union EdgeNameOrRefUnion { + ::std::string* name_; + ::google::protobuf::uint64 nameref_; + } EdgeNameOrRef_; + ::google::protobuf::uint32 _oneof_case_[1]; + friend void protobuf_AddDesc_CoreDump_2eproto(); friend void protobuf_AssignDesc_CoreDump_2eproto(); friend void protobuf_ShutdownFile_CoreDump_2eproto(); @@ -785,165 +896,207 @@ inline void StackFrame_Data::set_column(::google::protobuf::uint32 value) { // optional bytes source = 5; inline bool StackFrame_Data::has_source() const { - return (_has_bits_[0] & 0x00000010u) != 0; + return SourceOrRef_case() == kSource; } inline void StackFrame_Data::set_has_source() { - _has_bits_[0] |= 0x00000010u; -} -inline void StackFrame_Data::clear_has_source() { - _has_bits_[0] &= ~0x00000010u; + _oneof_case_[0] = kSource; } inline void StackFrame_Data::clear_source() { - if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - source_->clear(); + if (has_source()) { + delete SourceOrRef_.source_; + clear_has_SourceOrRef(); } - clear_has_source(); } inline const ::std::string& StackFrame_Data::source() const { - // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.source) - return *source_; + if (has_source()) { + return *SourceOrRef_.source_; + } + return ::google::protobuf::internal::GetEmptyStringAlreadyInited(); } inline void StackFrame_Data::set_source(const ::std::string& value) { - set_has_source(); - if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - source_ = new ::std::string; + if (!has_source()) { + clear_SourceOrRef(); + set_has_source(); + SourceOrRef_.source_ = new ::std::string; } - source_->assign(value); - // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.source) + SourceOrRef_.source_->assign(value); } inline void StackFrame_Data::set_source(const char* value) { - set_has_source(); - if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - source_ = new ::std::string; + if (!has_source()) { + clear_SourceOrRef(); + set_has_source(); + SourceOrRef_.source_ = new ::std::string; } - source_->assign(value); - // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.StackFrame.Data.source) + SourceOrRef_.source_->assign(value); } inline void StackFrame_Data::set_source(const void* value, size_t size) { - set_has_source(); - if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - source_ = new ::std::string; + if (!has_source()) { + clear_SourceOrRef(); + set_has_source(); + SourceOrRef_.source_ = new ::std::string; } - source_->assign(reinterpret_cast(value), size); - // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.StackFrame.Data.source) + SourceOrRef_.source_->assign( + reinterpret_cast(value), size); } inline ::std::string* StackFrame_Data::mutable_source() { - set_has_source(); - if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - source_ = new ::std::string; + if (!has_source()) { + clear_SourceOrRef(); + set_has_source(); + SourceOrRef_.source_ = new ::std::string; } - // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.StackFrame.Data.source) - return source_; + return SourceOrRef_.source_; } inline ::std::string* StackFrame_Data::release_source() { - clear_has_source(); - if (source_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - return NULL; - } else { - ::std::string* temp = source_; - source_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (has_source()) { + clear_has_SourceOrRef(); + ::std::string* temp = SourceOrRef_.source_; + SourceOrRef_.source_ = NULL; return temp; + } else { + return NULL; } } inline void StackFrame_Data::set_allocated_source(::std::string* source) { - if (source_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete source_; - } + clear_SourceOrRef(); if (source) { set_has_source(); - source_ = source; - } else { - clear_has_source(); - source_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + SourceOrRef_.source_ = source; } - // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.StackFrame.Data.source) } -// optional bytes functionDisplayName = 6; +// optional uint64 sourceRef = 6; +inline bool StackFrame_Data::has_sourceref() const { + return SourceOrRef_case() == kSourceRef; +} +inline void StackFrame_Data::set_has_sourceref() { + _oneof_case_[0] = kSourceRef; +} +inline void StackFrame_Data::clear_sourceref() { + if (has_sourceref()) { + SourceOrRef_.sourceref_ = GOOGLE_ULONGLONG(0); + clear_has_SourceOrRef(); + } +} +inline ::google::protobuf::uint64 StackFrame_Data::sourceref() const { + if (has_sourceref()) { + return SourceOrRef_.sourceref_; + } + return GOOGLE_ULONGLONG(0); +} +inline void StackFrame_Data::set_sourceref(::google::protobuf::uint64 value) { + if (!has_sourceref()) { + clear_SourceOrRef(); + set_has_sourceref(); + } + SourceOrRef_.sourceref_ = value; +} + +// optional bytes functionDisplayName = 7; inline bool StackFrame_Data::has_functiondisplayname() const { - return (_has_bits_[0] & 0x00000020u) != 0; + return FunctionDisplayNameOrRef_case() == kFunctionDisplayName; } inline void StackFrame_Data::set_has_functiondisplayname() { - _has_bits_[0] |= 0x00000020u; -} -inline void StackFrame_Data::clear_has_functiondisplayname() { - _has_bits_[0] &= ~0x00000020u; + _oneof_case_[1] = kFunctionDisplayName; } inline void StackFrame_Data::clear_functiondisplayname() { - if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - functiondisplayname_->clear(); + if (has_functiondisplayname()) { + delete FunctionDisplayNameOrRef_.functiondisplayname_; + clear_has_FunctionDisplayNameOrRef(); } - clear_has_functiondisplayname(); } inline const ::std::string& StackFrame_Data::functiondisplayname() const { - // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName) - return *functiondisplayname_; + if (has_functiondisplayname()) { + return *FunctionDisplayNameOrRef_.functiondisplayname_; + } + return ::google::protobuf::internal::GetEmptyStringAlreadyInited(); } inline void StackFrame_Data::set_functiondisplayname(const ::std::string& value) { - set_has_functiondisplayname(); - if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - functiondisplayname_ = new ::std::string; + if (!has_functiondisplayname()) { + clear_FunctionDisplayNameOrRef(); + set_has_functiondisplayname(); + FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string; } - functiondisplayname_->assign(value); - // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName) + FunctionDisplayNameOrRef_.functiondisplayname_->assign(value); } inline void StackFrame_Data::set_functiondisplayname(const char* value) { - set_has_functiondisplayname(); - if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - functiondisplayname_ = new ::std::string; + if (!has_functiondisplayname()) { + clear_FunctionDisplayNameOrRef(); + set_has_functiondisplayname(); + FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string; } - functiondisplayname_->assign(value); - // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName) + FunctionDisplayNameOrRef_.functiondisplayname_->assign(value); } inline void StackFrame_Data::set_functiondisplayname(const void* value, size_t size) { - set_has_functiondisplayname(); - if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - functiondisplayname_ = new ::std::string; + if (!has_functiondisplayname()) { + clear_FunctionDisplayNameOrRef(); + set_has_functiondisplayname(); + FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string; } - functiondisplayname_->assign(reinterpret_cast(value), size); - // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName) + FunctionDisplayNameOrRef_.functiondisplayname_->assign( + reinterpret_cast(value), size); } inline ::std::string* StackFrame_Data::mutable_functiondisplayname() { - set_has_functiondisplayname(); - if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - functiondisplayname_ = new ::std::string; + if (!has_functiondisplayname()) { + clear_FunctionDisplayNameOrRef(); + set_has_functiondisplayname(); + FunctionDisplayNameOrRef_.functiondisplayname_ = new ::std::string; } - // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName) - return functiondisplayname_; + return FunctionDisplayNameOrRef_.functiondisplayname_; } inline ::std::string* StackFrame_Data::release_functiondisplayname() { - clear_has_functiondisplayname(); - if (functiondisplayname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - return NULL; - } else { - ::std::string* temp = functiondisplayname_; - functiondisplayname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (has_functiondisplayname()) { + clear_has_FunctionDisplayNameOrRef(); + ::std::string* temp = FunctionDisplayNameOrRef_.functiondisplayname_; + FunctionDisplayNameOrRef_.functiondisplayname_ = NULL; return temp; + } else { + return NULL; } } inline void StackFrame_Data::set_allocated_functiondisplayname(::std::string* functiondisplayname) { - if (functiondisplayname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete functiondisplayname_; - } + clear_FunctionDisplayNameOrRef(); if (functiondisplayname) { set_has_functiondisplayname(); - functiondisplayname_ = functiondisplayname; - } else { - clear_has_functiondisplayname(); - functiondisplayname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + FunctionDisplayNameOrRef_.functiondisplayname_ = functiondisplayname; } - // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.StackFrame.Data.functionDisplayName) } -// optional bool isSystem = 7; +// optional uint64 functionDisplayNameRef = 8; +inline bool StackFrame_Data::has_functiondisplaynameref() const { + return FunctionDisplayNameOrRef_case() == kFunctionDisplayNameRef; +} +inline void StackFrame_Data::set_has_functiondisplaynameref() { + _oneof_case_[1] = kFunctionDisplayNameRef; +} +inline void StackFrame_Data::clear_functiondisplaynameref() { + if (has_functiondisplaynameref()) { + FunctionDisplayNameOrRef_.functiondisplaynameref_ = GOOGLE_ULONGLONG(0); + clear_has_FunctionDisplayNameOrRef(); + } +} +inline ::google::protobuf::uint64 StackFrame_Data::functiondisplaynameref() const { + if (has_functiondisplaynameref()) { + return FunctionDisplayNameOrRef_.functiondisplaynameref_; + } + return GOOGLE_ULONGLONG(0); +} +inline void StackFrame_Data::set_functiondisplaynameref(::google::protobuf::uint64 value) { + if (!has_functiondisplaynameref()) { + clear_FunctionDisplayNameOrRef(); + set_has_functiondisplaynameref(); + } + FunctionDisplayNameOrRef_.functiondisplaynameref_ = value; +} + +// optional bool isSystem = 9; inline bool StackFrame_Data::has_issystem() const { - return (_has_bits_[0] & 0x00000040u) != 0; + return (_has_bits_[0] & 0x00000100u) != 0; } inline void StackFrame_Data::set_has_issystem() { - _has_bits_[0] |= 0x00000040u; + _has_bits_[0] |= 0x00000100u; } inline void StackFrame_Data::clear_has_issystem() { - _has_bits_[0] &= ~0x00000040u; + _has_bits_[0] &= ~0x00000100u; } inline void StackFrame_Data::clear_issystem() { issystem_ = false; @@ -959,15 +1112,15 @@ inline void StackFrame_Data::set_issystem(bool value) { // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.isSystem) } -// optional bool isSelfHosted = 8; +// optional bool isSelfHosted = 10; inline bool StackFrame_Data::has_isselfhosted() const { - return (_has_bits_[0] & 0x00000080u) != 0; + return (_has_bits_[0] & 0x00000200u) != 0; } inline void StackFrame_Data::set_has_isselfhosted() { - _has_bits_[0] |= 0x00000080u; + _has_bits_[0] |= 0x00000200u; } inline void StackFrame_Data::clear_has_isselfhosted() { - _has_bits_[0] &= ~0x00000080u; + _has_bits_[0] &= ~0x00000200u; } inline void StackFrame_Data::clear_isselfhosted() { isselfhosted_ = false; @@ -983,6 +1136,24 @@ inline void StackFrame_Data::set_isselfhosted(bool value) { // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.StackFrame.Data.isSelfHosted) } +inline bool StackFrame_Data::has_SourceOrRef() { + return SourceOrRef_case() != SOURCEORREF_NOT_SET; +} +inline void StackFrame_Data::clear_has_SourceOrRef() { + _oneof_case_[0] = SOURCEORREF_NOT_SET; +} +inline bool StackFrame_Data::has_FunctionDisplayNameOrRef() { + return FunctionDisplayNameOrRef_case() != FUNCTIONDISPLAYNAMEORREF_NOT_SET; +} +inline void StackFrame_Data::clear_has_FunctionDisplayNameOrRef() { + _oneof_case_[1] = FUNCTIONDISPLAYNAMEORREF_NOT_SET; +} +inline StackFrame_Data::SourceOrRefCase StackFrame_Data::SourceOrRef_case() const { + return StackFrame_Data::SourceOrRefCase(_oneof_case_[0]); +} +inline StackFrame_Data::FunctionDisplayNameOrRefCase StackFrame_Data::FunctionDisplayNameOrRef_case() const { + return StackFrame_Data::FunctionDisplayNameOrRefCase(_oneof_case_[1]); +} // ------------------------------------------------------------------- // StackFrame @@ -1096,89 +1267,110 @@ inline void Node::set_id(::google::protobuf::uint64 value) { // optional bytes typeName = 2; inline bool Node::has_typename_() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return TypeNameOrRef_case() == kTypeName; } inline void Node::set_has_typename_() { - _has_bits_[0] |= 0x00000002u; -} -inline void Node::clear_has_typename_() { - _has_bits_[0] &= ~0x00000002u; + _oneof_case_[0] = kTypeName; } inline void Node::clear_typename_() { - if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - typename__->clear(); + if (has_typename_()) { + delete TypeNameOrRef_.typename__; + clear_has_TypeNameOrRef(); } - clear_has_typename_(); } inline const ::std::string& Node::typename_() const { - // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.typeName) - return *typename__; + if (has_typename_()) { + return *TypeNameOrRef_.typename__; + } + return ::google::protobuf::internal::GetEmptyStringAlreadyInited(); } inline void Node::set_typename_(const ::std::string& value) { - set_has_typename_(); - if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - typename__ = new ::std::string; + if (!has_typename_()) { + clear_TypeNameOrRef(); + set_has_typename_(); + TypeNameOrRef_.typename__ = new ::std::string; } - typename__->assign(value); - // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.typeName) + TypeNameOrRef_.typename__->assign(value); } inline void Node::set_typename_(const char* value) { - set_has_typename_(); - if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - typename__ = new ::std::string; + if (!has_typename_()) { + clear_TypeNameOrRef(); + set_has_typename_(); + TypeNameOrRef_.typename__ = new ::std::string; } - typename__->assign(value); - // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Node.typeName) + TypeNameOrRef_.typename__->assign(value); } inline void Node::set_typename_(const void* value, size_t size) { - set_has_typename_(); - if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - typename__ = new ::std::string; + if (!has_typename_()) { + clear_TypeNameOrRef(); + set_has_typename_(); + TypeNameOrRef_.typename__ = new ::std::string; } - typename__->assign(reinterpret_cast(value), size); - // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Node.typeName) + TypeNameOrRef_.typename__->assign( + reinterpret_cast(value), size); } inline ::std::string* Node::mutable_typename_() { - set_has_typename_(); - if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - typename__ = new ::std::string; + if (!has_typename_()) { + clear_TypeNameOrRef(); + set_has_typename_(); + TypeNameOrRef_.typename__ = new ::std::string; } - // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.typeName) - return typename__; + return TypeNameOrRef_.typename__; } inline ::std::string* Node::release_typename_() { - clear_has_typename_(); - if (typename__ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - return NULL; - } else { - ::std::string* temp = typename__; - typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (has_typename_()) { + clear_has_TypeNameOrRef(); + ::std::string* temp = TypeNameOrRef_.typename__; + TypeNameOrRef_.typename__ = NULL; return temp; + } else { + return NULL; } } inline void Node::set_allocated_typename_(::std::string* typename_) { - if (typename__ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete typename__; - } + clear_TypeNameOrRef(); if (typename_) { set_has_typename_(); - typename__ = typename_; - } else { - clear_has_typename_(); - typename__ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + TypeNameOrRef_.typename__ = typename_; } - // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.typeName) } -// optional uint64 size = 3; +// optional uint64 typeNameRef = 3; +inline bool Node::has_typenameref() const { + return TypeNameOrRef_case() == kTypeNameRef; +} +inline void Node::set_has_typenameref() { + _oneof_case_[0] = kTypeNameRef; +} +inline void Node::clear_typenameref() { + if (has_typenameref()) { + TypeNameOrRef_.typenameref_ = GOOGLE_ULONGLONG(0); + clear_has_TypeNameOrRef(); + } +} +inline ::google::protobuf::uint64 Node::typenameref() const { + if (has_typenameref()) { + return TypeNameOrRef_.typenameref_; + } + return GOOGLE_ULONGLONG(0); +} +inline void Node::set_typenameref(::google::protobuf::uint64 value) { + if (!has_typenameref()) { + clear_TypeNameOrRef(); + set_has_typenameref(); + } + TypeNameOrRef_.typenameref_ = value; +} + +// optional uint64 size = 4; inline bool Node::has_size() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000008u) != 0; } inline void Node::set_has_size() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000008u; } inline void Node::clear_has_size() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000008u; } inline void Node::clear_size() { size_ = GOOGLE_ULONGLONG(0); @@ -1194,7 +1386,7 @@ inline void Node::set_size(::google::protobuf::uint64 value) { // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.size) } -// repeated .mozilla.devtools.protobuf.Edge edges = 4; +// repeated .mozilla.devtools.protobuf.Edge edges = 5; inline int Node::edges_size() const { return edges_.size(); } @@ -1224,15 +1416,15 @@ Node::mutable_edges() { return &edges_; } -// optional .mozilla.devtools.protobuf.StackFrame allocationStack = 5; +// optional .mozilla.devtools.protobuf.StackFrame allocationStack = 6; inline bool Node::has_allocationstack() const { - return (_has_bits_[0] & 0x00000010u) != 0; + return (_has_bits_[0] & 0x00000020u) != 0; } inline void Node::set_has_allocationstack() { - _has_bits_[0] |= 0x00000010u; + _has_bits_[0] |= 0x00000020u; } inline void Node::clear_has_allocationstack() { - _has_bits_[0] &= ~0x00000010u; + _has_bits_[0] &= ~0x00000020u; } inline void Node::clear_allocationstack() { if (allocationstack_ != NULL) allocationstack_->::mozilla::devtools::protobuf::StackFrame::Clear(); @@ -1265,91 +1457,112 @@ inline void Node::set_allocated_allocationstack(::mozilla::devtools::protobuf::S // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.allocationStack) } -// optional bytes jsObjectClassName = 6; +// optional bytes jsObjectClassName = 7; inline bool Node::has_jsobjectclassname() const { - return (_has_bits_[0] & 0x00000020u) != 0; + return JSObjectClassNameOrRef_case() == kJsObjectClassName; } inline void Node::set_has_jsobjectclassname() { - _has_bits_[0] |= 0x00000020u; -} -inline void Node::clear_has_jsobjectclassname() { - _has_bits_[0] &= ~0x00000020u; + _oneof_case_[1] = kJsObjectClassName; } inline void Node::clear_jsobjectclassname() { - if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - jsobjectclassname_->clear(); + if (has_jsobjectclassname()) { + delete JSObjectClassNameOrRef_.jsobjectclassname_; + clear_has_JSObjectClassNameOrRef(); } - clear_has_jsobjectclassname(); } inline const ::std::string& Node::jsobjectclassname() const { - // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Node.jsObjectClassName) - return *jsobjectclassname_; + if (has_jsobjectclassname()) { + return *JSObjectClassNameOrRef_.jsobjectclassname_; + } + return ::google::protobuf::internal::GetEmptyStringAlreadyInited(); } inline void Node::set_jsobjectclassname(const ::std::string& value) { - set_has_jsobjectclassname(); - if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - jsobjectclassname_ = new ::std::string; + if (!has_jsobjectclassname()) { + clear_JSObjectClassNameOrRef(); + set_has_jsobjectclassname(); + JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string; } - jsobjectclassname_->assign(value); - // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.jsObjectClassName) + JSObjectClassNameOrRef_.jsobjectclassname_->assign(value); } inline void Node::set_jsobjectclassname(const char* value) { - set_has_jsobjectclassname(); - if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - jsobjectclassname_ = new ::std::string; + if (!has_jsobjectclassname()) { + clear_JSObjectClassNameOrRef(); + set_has_jsobjectclassname(); + JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string; } - jsobjectclassname_->assign(value); - // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Node.jsObjectClassName) + JSObjectClassNameOrRef_.jsobjectclassname_->assign(value); } inline void Node::set_jsobjectclassname(const void* value, size_t size) { - set_has_jsobjectclassname(); - if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - jsobjectclassname_ = new ::std::string; + if (!has_jsobjectclassname()) { + clear_JSObjectClassNameOrRef(); + set_has_jsobjectclassname(); + JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string; } - jsobjectclassname_->assign(reinterpret_cast(value), size); - // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Node.jsObjectClassName) + JSObjectClassNameOrRef_.jsobjectclassname_->assign( + reinterpret_cast(value), size); } inline ::std::string* Node::mutable_jsobjectclassname() { - set_has_jsobjectclassname(); - if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - jsobjectclassname_ = new ::std::string; + if (!has_jsobjectclassname()) { + clear_JSObjectClassNameOrRef(); + set_has_jsobjectclassname(); + JSObjectClassNameOrRef_.jsobjectclassname_ = new ::std::string; } - // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Node.jsObjectClassName) - return jsobjectclassname_; + return JSObjectClassNameOrRef_.jsobjectclassname_; } inline ::std::string* Node::release_jsobjectclassname() { - clear_has_jsobjectclassname(); - if (jsobjectclassname_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - return NULL; - } else { - ::std::string* temp = jsobjectclassname_; - jsobjectclassname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (has_jsobjectclassname()) { + clear_has_JSObjectClassNameOrRef(); + ::std::string* temp = JSObjectClassNameOrRef_.jsobjectclassname_; + JSObjectClassNameOrRef_.jsobjectclassname_ = NULL; return temp; + } else { + return NULL; } } inline void Node::set_allocated_jsobjectclassname(::std::string* jsobjectclassname) { - if (jsobjectclassname_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete jsobjectclassname_; - } + clear_JSObjectClassNameOrRef(); if (jsobjectclassname) { set_has_jsobjectclassname(); - jsobjectclassname_ = jsobjectclassname; - } else { - clear_has_jsobjectclassname(); - jsobjectclassname_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + JSObjectClassNameOrRef_.jsobjectclassname_ = jsobjectclassname; } - // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Node.jsObjectClassName) } -// optional uint32 coarseType = 7 [default = 0]; +// optional uint64 jsObjectClassNameRef = 8; +inline bool Node::has_jsobjectclassnameref() const { + return JSObjectClassNameOrRef_case() == kJsObjectClassNameRef; +} +inline void Node::set_has_jsobjectclassnameref() { + _oneof_case_[1] = kJsObjectClassNameRef; +} +inline void Node::clear_jsobjectclassnameref() { + if (has_jsobjectclassnameref()) { + JSObjectClassNameOrRef_.jsobjectclassnameref_ = GOOGLE_ULONGLONG(0); + clear_has_JSObjectClassNameOrRef(); + } +} +inline ::google::protobuf::uint64 Node::jsobjectclassnameref() const { + if (has_jsobjectclassnameref()) { + return JSObjectClassNameOrRef_.jsobjectclassnameref_; + } + return GOOGLE_ULONGLONG(0); +} +inline void Node::set_jsobjectclassnameref(::google::protobuf::uint64 value) { + if (!has_jsobjectclassnameref()) { + clear_JSObjectClassNameOrRef(); + set_has_jsobjectclassnameref(); + } + JSObjectClassNameOrRef_.jsobjectclassnameref_ = value; +} + +// optional uint32 coarseType = 9 [default = 0]; inline bool Node::has_coarsetype() const { - return (_has_bits_[0] & 0x00000040u) != 0; + return (_has_bits_[0] & 0x00000100u) != 0; } inline void Node::set_has_coarsetype() { - _has_bits_[0] |= 0x00000040u; + _has_bits_[0] |= 0x00000100u; } inline void Node::clear_has_coarsetype() { - _has_bits_[0] &= ~0x00000040u; + _has_bits_[0] &= ~0x00000100u; } inline void Node::clear_coarsetype() { coarsetype_ = 0u; @@ -1365,6 +1578,24 @@ inline void Node::set_coarsetype(::google::protobuf::uint32 value) { // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Node.coarseType) } +inline bool Node::has_TypeNameOrRef() { + return TypeNameOrRef_case() != TYPENAMEORREF_NOT_SET; +} +inline void Node::clear_has_TypeNameOrRef() { + _oneof_case_[0] = TYPENAMEORREF_NOT_SET; +} +inline bool Node::has_JSObjectClassNameOrRef() { + return JSObjectClassNameOrRef_case() != JSOBJECTCLASSNAMEORREF_NOT_SET; +} +inline void Node::clear_has_JSObjectClassNameOrRef() { + _oneof_case_[1] = JSOBJECTCLASSNAMEORREF_NOT_SET; +} +inline Node::TypeNameOrRefCase Node::TypeNameOrRef_case() const { + return Node::TypeNameOrRefCase(_oneof_case_[0]); +} +inline Node::JSObjectClassNameOrRefCase Node::JSObjectClassNameOrRef_case() const { + return Node::JSObjectClassNameOrRefCase(_oneof_case_[1]); +} // ------------------------------------------------------------------- // Edge @@ -1395,80 +1626,110 @@ inline void Edge::set_referent(::google::protobuf::uint64 value) { // optional bytes name = 2; inline bool Edge::has_name() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return EdgeNameOrRef_case() == kName; } inline void Edge::set_has_name() { - _has_bits_[0] |= 0x00000002u; -} -inline void Edge::clear_has_name() { - _has_bits_[0] &= ~0x00000002u; + _oneof_case_[0] = kName; } inline void Edge::clear_name() { - if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - name_->clear(); + if (has_name()) { + delete EdgeNameOrRef_.name_; + clear_has_EdgeNameOrRef(); } - clear_has_name(); } inline const ::std::string& Edge::name() const { - // @@protoc_insertion_point(field_get:mozilla.devtools.protobuf.Edge.name) - return *name_; + if (has_name()) { + return *EdgeNameOrRef_.name_; + } + return ::google::protobuf::internal::GetEmptyStringAlreadyInited(); } inline void Edge::set_name(const ::std::string& value) { - set_has_name(); - if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - name_ = new ::std::string; + if (!has_name()) { + clear_EdgeNameOrRef(); + set_has_name(); + EdgeNameOrRef_.name_ = new ::std::string; } - name_->assign(value); - // @@protoc_insertion_point(field_set:mozilla.devtools.protobuf.Edge.name) + EdgeNameOrRef_.name_->assign(value); } inline void Edge::set_name(const char* value) { - set_has_name(); - if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - name_ = new ::std::string; + if (!has_name()) { + clear_EdgeNameOrRef(); + set_has_name(); + EdgeNameOrRef_.name_ = new ::std::string; } - name_->assign(value); - // @@protoc_insertion_point(field_set_char:mozilla.devtools.protobuf.Edge.name) + EdgeNameOrRef_.name_->assign(value); } inline void Edge::set_name(const void* value, size_t size) { - set_has_name(); - if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - name_ = new ::std::string; + if (!has_name()) { + clear_EdgeNameOrRef(); + set_has_name(); + EdgeNameOrRef_.name_ = new ::std::string; } - name_->assign(reinterpret_cast(value), size); - // @@protoc_insertion_point(field_set_pointer:mozilla.devtools.protobuf.Edge.name) + EdgeNameOrRef_.name_->assign( + reinterpret_cast(value), size); } inline ::std::string* Edge::mutable_name() { - set_has_name(); - if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - name_ = new ::std::string; + if (!has_name()) { + clear_EdgeNameOrRef(); + set_has_name(); + EdgeNameOrRef_.name_ = new ::std::string; } - // @@protoc_insertion_point(field_mutable:mozilla.devtools.protobuf.Edge.name) - return name_; + return EdgeNameOrRef_.name_; } inline ::std::string* Edge::release_name() { - clear_has_name(); - if (name_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - return NULL; - } else { - ::std::string* temp = name_; - name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (has_name()) { + clear_has_EdgeNameOrRef(); + ::std::string* temp = EdgeNameOrRef_.name_; + EdgeNameOrRef_.name_ = NULL; return temp; + } else { + return NULL; } } inline void Edge::set_allocated_name(::std::string* name) { - if (name_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { - delete name_; - } + clear_EdgeNameOrRef(); if (name) { set_has_name(); - name_ = name; - } else { - clear_has_name(); - name_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + EdgeNameOrRef_.name_ = name; } - // @@protoc_insertion_point(field_set_allocated:mozilla.devtools.protobuf.Edge.name) } +// optional uint64 nameRef = 3; +inline bool Edge::has_nameref() const { + return EdgeNameOrRef_case() == kNameRef; +} +inline void Edge::set_has_nameref() { + _oneof_case_[0] = kNameRef; +} +inline void Edge::clear_nameref() { + if (has_nameref()) { + EdgeNameOrRef_.nameref_ = GOOGLE_ULONGLONG(0); + clear_has_EdgeNameOrRef(); + } +} +inline ::google::protobuf::uint64 Edge::nameref() const { + if (has_nameref()) { + return EdgeNameOrRef_.nameref_; + } + return GOOGLE_ULONGLONG(0); +} +inline void Edge::set_nameref(::google::protobuf::uint64 value) { + if (!has_nameref()) { + clear_EdgeNameOrRef(); + set_has_nameref(); + } + EdgeNameOrRef_.nameref_ = value; +} + +inline bool Edge::has_EdgeNameOrRef() { + return EdgeNameOrRef_case() != EDGENAMEORREF_NOT_SET; +} +inline void Edge::clear_has_EdgeNameOrRef() { + _oneof_case_[0] = EDGENAMEORREF_NOT_SET; +} +inline Edge::EdgeNameOrRefCase Edge::EdgeNameOrRef_case() const { + return Edge::EdgeNameOrRefCase(_oneof_case_[0]); +} // @@protoc_insertion_point(namespace_scope) diff --git a/devtools/shared/heapsnapshot/CoreDump.proto b/devtools/shared/heapsnapshot/CoreDump.proto index a97ac364a5a..450833807d3 100644 --- a/devtools/shared/heapsnapshot/CoreDump.proto +++ b/devtools/shared/heapsnapshot/CoreDump.proto @@ -38,11 +38,25 @@ // | . | // +-----------------------------------------------------------------------+ // -// In practice, certain message fields have a lot of duplication (such as type -// or edge name strings). Rather than try and de-duplicate this information at -// the protobuf message and field level, core dumps should be written with -// `google::protobuf::io::GzipOutputStream` and read from +// Core dumps should always be written with a +// `google::protobuf::io::GzipOutputStream` and read from a // `google::protobuf::io::GzipInputStream`. +// +// Note that all strings are de-duplicated. The first time the N^th unique +// string is encountered, the full string is serialized. Subsequent times that +// same string is encountered, it is referenced by N. This de-duplication +// happens across string properties, not on a per-property basis. For example, +// if the same K^th unique string is first used as an Edge::EdgeNameOrRef and +// then as a StackFrame::Data::FunctionDisplayNameOrRef, the first will be the +// actual string as the functionDisplayName oneof property, and the second will +// be a reference to the first as the edgeNameRef oneof property whose value is +// K. +// +// We would ordinarily abstract these de-duplicated strings with messages of +// their own, but unfortunately, the protobuf compiler does not have a way to +// inline a messsage within another message and the child message must be +// referenced by pointer. This leads to extra mallocs that we wish to avoid. + package mozilla.devtools.protobuf; @@ -65,36 +79,59 @@ message StackFrame { } message Data { - optional uint64 id = 1; - optional StackFrame parent = 2; - optional uint32 line = 3; - optional uint32 column = 4; - // char16_t[] - optional bytes source = 5; - // char16_t[] - optional bytes functionDisplayName = 6; - optional bool isSystem = 7; - optional bool isSelfHosted = 8; + optional uint64 id = 1; + optional StackFrame parent = 2; + optional uint32 line = 3; + optional uint32 column = 4; + + // De-duplicated two-byte string. + oneof SourceOrRef { + bytes source = 5; + uint64 sourceRef = 6; + } + + // De-duplicated two-byte string. + oneof FunctionDisplayNameOrRef { + bytes functionDisplayName = 7; + uint64 functionDisplayNameRef = 8; + } + + optional bool isSystem = 9; + optional bool isSelfHosted = 10; } } // A serialized version of `JS::ubi::Node` and its outgoing edges. message Node { - optional uint64 id = 1; - // char16_t[] - optional bytes typeName = 2; - optional uint64 size = 3; - repeated Edge edges = 4; - optional StackFrame allocationStack = 5; - // char[] - optional bytes jsObjectClassName = 6; + optional uint64 id = 1; + + // De-duplicated two-byte string. + oneof TypeNameOrRef { + bytes typeName = 2; + uint64 typeNameRef = 3; + } + + optional uint64 size = 4; + repeated Edge edges = 5; + optional StackFrame allocationStack = 6; + + // De-duplicated one-byte string. + oneof JSObjectClassNameOrRef { + bytes jsObjectClassName = 7; + uint64 jsObjectClassNameRef = 8; + } + // JS::ubi::CoarseType. Defaults to Other. - optional uint32 coarseType = 7 [default = 0]; + optional uint32 coarseType = 9 [default = 0]; } // A serialized edge from the heap graph. message Edge { - optional uint64 referent = 1; - // char16_t[] - optional bytes name = 2; + optional uint64 referent = 1; + + // De-duplicated two-byte string. + oneof EdgeNameOrRef { + bytes name = 2; + uint64 nameRef = 3; + } } diff --git a/devtools/shared/heapsnapshot/DeserializedNode.cpp b/devtools/shared/heapsnapshot/DeserializedNode.cpp index 4b5b118c35b..edf01e7d486 100644 --- a/devtools/shared/heapsnapshot/DeserializedNode.cpp +++ b/devtools/shared/heapsnapshot/DeserializedNode.cpp @@ -10,11 +10,6 @@ namespace mozilla { namespace devtools { -DeserializedEdge::DeserializedEdge() - : referent(0) - , name(nullptr) -{ } - DeserializedEdge::DeserializedEdge(DeserializedEdge&& rhs) { referent = rhs.referent; @@ -29,26 +24,6 @@ DeserializedEdge& DeserializedEdge::operator=(DeserializedEdge&& rhs) return *this; } -bool -DeserializedEdge::init(const protobuf::Edge& edge, HeapSnapshot& owner) -{ - // Although the referent property is optional in the protobuf format for - // future compatibility, we can't semantically have an edge to nowhere and - // require a referent here. - if (!edge.has_referent()) - return false; - referent = edge.referent(); - - if (edge.has_name()) { - const char16_t* duplicateEdgeName = reinterpret_cast(edge.name().c_str()); - name = owner.borrowUniqueString(duplicateEdgeName, edge.name().length() / sizeof(char16_t)); - if (!name) - return false; - } - - return true; -} - JS::ubi::Node DeserializedNode::getEdgeReferent(const DeserializedEdge& edge) { diff --git a/devtools/shared/heapsnapshot/DeserializedNode.h b/devtools/shared/heapsnapshot/DeserializedNode.h index 390d0fd984c..52b9cf287aa 100644 --- a/devtools/shared/heapsnapshot/DeserializedNode.h +++ b/devtools/shared/heapsnapshot/DeserializedNode.h @@ -40,13 +40,13 @@ struct DeserializedEdge { // A borrowed reference to a string owned by this node's owning HeapSnapshot. const char16_t* name; - explicit DeserializedEdge(); + explicit DeserializedEdge(NodeId referent, const char16_t* edgeName = nullptr) + : referent(referent) + , name(edgeName) + { } DeserializedEdge(DeserializedEdge&& rhs); DeserializedEdge& operator=(DeserializedEdge&& rhs); - // Initialize this `DeserializedEdge` from the given `protobuf::Edge` message. - bool init(const protobuf::Edge& edge, HeapSnapshot& owner); - private: DeserializedEdge(const DeserializedEdge&) = delete; DeserializedEdge& operator=(const DeserializedEdge&) = delete; @@ -65,7 +65,8 @@ struct DeserializedNode { uint64_t size; EdgeVector edges; Maybe allocationStack; - UniquePtr jsObjectClassName; + // A borrowed reference to a string owned by this node's owning HeapSnapshot. + const char* jsObjectClassName; // A weak pointer to this node's owning `HeapSnapshot`. Safe without // AddRef'ing because this node's lifetime is equal to that of its owner. HeapSnapshot* owner; @@ -76,7 +77,7 @@ struct DeserializedNode { uint64_t size, EdgeVector&& edges, Maybe allocationStack, - UniquePtr&& className, + const char* className, HeapSnapshot& owner) : id(id) , coarseType(coarseType) @@ -84,7 +85,7 @@ struct DeserializedNode { , size(size) , edges(Move(edges)) , allocationStack(allocationStack) - , jsObjectClassName(Move(className)) + , jsObjectClassName(className) , owner(&owner) { } virtual ~DeserializedNode() { } @@ -96,7 +97,7 @@ struct DeserializedNode { , size(rhs.size) , edges(Move(rhs.edges)) , allocationStack(rhs.allocationStack) - , jsObjectClassName(Move(rhs.jsObjectClassName)) + , jsObjectClassName(rhs.jsObjectClassName) , owner(rhs.owner) { } @@ -258,7 +259,7 @@ public: bool isLive() const override { return false; } const char16_t* typeName() const override; Node::Size size(mozilla::MallocSizeOf mallocSizeof) const override; - const char* jsObjectClassName() const override { return get().jsObjectClassName.get(); } + const char* jsObjectClassName() const override { return get().jsObjectClassName; } bool hasAllocationStack() const override { return get().allocationStack.isSome(); } StackFrame allocationStack() const override; diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.cpp b/devtools/shared/heapsnapshot/HeapSnapshot.cpp index a0ef56ab1ff..3377401d3dd 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.cpp +++ b/devtools/shared/heapsnapshot/HeapSnapshot.cpp @@ -50,6 +50,8 @@ using ::google::protobuf::io::CodedInputStream; using ::google::protobuf::io::GzipInputStream; using ::google::protobuf::io::ZeroCopyInputStream; +using JS::ubi::AtomOrTwoByteChars; + NS_IMPL_CYCLE_COLLECTION_CLASS(HeapSnapshot) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HeapSnapshot) @@ -122,76 +124,159 @@ parseMessage(ZeroCopyInputStream& stream, MessageType& message) return true; } +template +struct GetOrInternStringMatcher +{ + using ReturnType = const CharT*; + + InternedStringSet& internedStrings; + + explicit GetOrInternStringMatcher(InternedStringSet& strings) : internedStrings(strings) { } + + const CharT* match(const std::string* str) { + MOZ_ASSERT(str); + size_t length = str->length() / sizeof(CharT); + auto tempString = reinterpret_cast(str->data()); + + UniquePtr owned(NS_strndup(tempString, length)); + if (!owned || !internedStrings.append(Move(owned))) + return nullptr; + + return internedStrings.back().get(); + } + + const CharT* match(uint64_t ref) { + if (MOZ_LIKELY(ref < internedStrings.length())) { + auto& string = internedStrings[ref]; + MOZ_ASSERT(string); + return string.get(); + } + + return nullptr; + } +}; + +template< + // Either char or char16_t. + typename CharT, + // A reference to either `internedOneByteStrings` or `internedTwoByteStrings` + // if CharT is char or char16_t respectively. + typename InternedStringSet> +const CharT* +HeapSnapshot::getOrInternString(InternedStringSet& internedStrings, + Maybe& maybeStrOrRef) +{ + // Incomplete message: has neither a string nor a reference to an already + // interned string. + if (MOZ_UNLIKELY(maybeStrOrRef.isNothing())) + return nullptr; + + GetOrInternStringMatcher m(internedStrings); + return maybeStrOrRef->match(m); +} + +// Get a de-duplicated string as a Maybe from the given `msg`. +#define GET_STRING_OR_REF_WITH_PROP_NAMES(msg, strPropertyName, refPropertyName) \ + (msg.has_##refPropertyName() \ + ? Some(StringOrRef(msg.refPropertyName())) \ + : msg.has_##strPropertyName() \ + ? Some(StringOrRef(&msg.strPropertyName())) \ + : Nothing()) + +#define GET_STRING_OR_REF(msg, property) \ + (msg.has_##property##ref() \ + ? Some(StringOrRef(msg.property##ref())) \ + : msg.has_##property() \ + ? Some(StringOrRef(&msg.property())) \ + : Nothing()) + bool HeapSnapshot::saveNode(const protobuf::Node& node) { - if (!node.has_id()) + // NB: de-duplicated string properties must be read back and interned in the + // same order here as they are written and serialized in + // `CoreDumpWriter::writeNode` or else indices in references to already + // serialized strings will be off. + + if (NS_WARN_IF(!node.has_id())) return false; NodeId id = node.id(); // Should only deserialize each node once. - if (nodes.has(id)) + if (NS_WARN_IF(nodes.has(id))) return false; - if (!JS::ubi::Uint32IsValidCoarseType(node.coarsetype())) + if (NS_WARN_IF(!JS::ubi::Uint32IsValidCoarseType(node.coarsetype()))) return false; auto coarseType = JS::ubi::Uint32ToCoarseType(node.coarsetype()); - if (!node.has_typename_()) + Maybe typeNameOrRef = GET_STRING_OR_REF_WITH_PROP_NAMES(node, typename_, typenameref); + auto typeName = getOrInternString(internedTwoByteStrings, typeNameOrRef); + if (NS_WARN_IF(!typeName)) return false; - auto duplicatedTypeName = reinterpret_cast( - node.typename_().data()); - auto length = node.typename_().length() / sizeof(char16_t); - auto typeName = borrowUniqueString(duplicatedTypeName, length); - if (!typeName) - return false; - - if (!node.has_size()) + if (NS_WARN_IF(!node.has_size())) return false; uint64_t size = node.size(); auto edgesLength = node.edges_size(); DeserializedNode::EdgeVector edges; - if (!edges.reserve(edgesLength)) + if (NS_WARN_IF(!edges.reserve(edgesLength))) return false; for (decltype(edgesLength) i = 0; i < edgesLength; i++) { - DeserializedEdge edge; - if (!edge.init(node.edges(i), *this)) + auto& protoEdge = node.edges(i); + + if (NS_WARN_IF(!protoEdge.has_referent())) return false; - edges.infallibleAppend(Move(edge)); + NodeId referent = protoEdge.referent(); + + const char16_t* edgeName = nullptr; + if (protoEdge.EdgeNameOrRef_case() != protobuf::Edge::EDGENAMEORREF_NOT_SET) { + Maybe edgeNameOrRef = GET_STRING_OR_REF(protoEdge, name); + edgeName = getOrInternString(internedTwoByteStrings, edgeNameOrRef); + if (NS_WARN_IF(!edgeName)) + return false; + } + + edges.infallibleAppend(DeserializedEdge(referent, edgeName)); } Maybe allocationStack; if (node.has_allocationstack()) { StackFrameId id = 0; - if (!saveStackFrame(node.allocationstack(), id)) + if (NS_WARN_IF(!saveStackFrame(node.allocationstack(), id))) return false; allocationStack.emplace(id); } MOZ_ASSERT(allocationStack.isSome() == node.has_allocationstack()); - UniquePtr jsObjectClassName; - if (node.has_jsobjectclassname()) { - auto length = node.jsobjectclassname().length(); - jsObjectClassName.reset(static_cast(malloc(length + 1))); - if (!jsObjectClassName) + const char* jsObjectClassName = nullptr; + if (node.JSObjectClassNameOrRef_case() != protobuf::Node::JSOBJECTCLASSNAMEORREF_NOT_SET) { + Maybe clsNameOrRef = GET_STRING_OR_REF(node, jsobjectclassname); + jsObjectClassName = getOrInternString(internedOneByteStrings, clsNameOrRef); + if (NS_WARN_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)); + if (NS_WARN_IF(!nodes.putNew(id, DeserializedNode(id, coarseType, typeName, + size, Move(edges), + allocationStack, + jsObjectClassName, *this)))) + { + return false; + }; + + return true; } bool HeapSnapshot::saveStackFrame(const protobuf::StackFrame& frame, StackFrameId& outFrameId) { + // NB: de-duplicated string properties must be read in the same order here as + // they are written in `CoreDumpWriter::getProtobufStackFrame` or else indices + // in references to already serialized strings will be off. + if (frame.has_ref()) { // We should only get a reference to the previous frame if we have already // seen the previous frame. @@ -216,14 +301,6 @@ HeapSnapshot::saveStackFrame(const protobuf::StackFrame& frame, if (frames.has(id)) return false; - Maybe parent; - if (data.has_parent()) { - StackFrameId parentId = 0; - if (!saveStackFrame(data.parent(), parentId)) - return false; - parent = Some(parentId); - } - if (!data.has_line()) return false; uint32_t line = data.line(); @@ -232,25 +309,6 @@ HeapSnapshot::saveStackFrame(const protobuf::StackFrame& frame, return false; uint32_t column = data.column(); - auto duplicatedSource = reinterpret_cast( - data.source().data()); - size_t sourceLength = data.source().length() / sizeof(char16_t); - const char16_t* source = borrowUniqueString(duplicatedSource, sourceLength); - if (!source) - return false; - - const char16_t* functionDisplayName = nullptr; - if (data.has_functiondisplayname() && data.functiondisplayname().length() > 0) { - auto duplicatedName = reinterpret_cast( - data.functiondisplayname().data()); - size_t nameLength = data.functiondisplayname().length() / sizeof(char16_t); - functionDisplayName = borrowUniqueString(duplicatedName, nameLength); - if (!functionDisplayName) - return false; - } - MOZ_ASSERT(!!functionDisplayName == (data.has_functiondisplayname() && - data.functiondisplayname().length() > 0)); - if (!data.has_issystem()) return false; bool isSystem = data.issystem(); @@ -259,6 +317,29 @@ HeapSnapshot::saveStackFrame(const protobuf::StackFrame& frame, return false; bool isSelfHosted = data.isselfhosted(); + Maybe sourceOrRef = GET_STRING_OR_REF(data, source); + auto source = getOrInternString(internedTwoByteStrings, sourceOrRef); + if (!source) + return false; + + const char16_t* functionDisplayName = nullptr; + if (data.FunctionDisplayNameOrRef_case() != + protobuf::StackFrame_Data::FUNCTIONDISPLAYNAMEORREF_NOT_SET) + { + Maybe nameOrRef = GET_STRING_OR_REF(data, functiondisplayname); + functionDisplayName = getOrInternString(internedTwoByteStrings, nameOrRef); + if (!functionDisplayName) + return false; + } + + Maybe parent; + if (data.has_parent()) { + StackFrameId parentId = 0; + if (!saveStackFrame(data.parent(), parentId)) + return false; + parent = Some(parentId); + } + if (!frames.putNew(id, DeserializedStackFrame(id, parent, line, column, source, functionDisplayName, isSystem, isSelfHosted, *this))) @@ -296,7 +377,7 @@ StreamHasData(GzipInputStream& stream) bool HeapSnapshot::init(const uint8_t* buffer, uint32_t size) { - if (!nodes.init() || !frames.init() || !strings.init()) + if (!nodes.init() || !frames.init()) return false; ArrayInputStream stream(buffer, size); @@ -338,22 +419,6 @@ HeapSnapshot::init(const uint8_t* buffer, uint32_t size) return true; } -const char16_t* -HeapSnapshot::borrowUniqueString(const char16_t* duplicateString, size_t length) -{ - MOZ_ASSERT(duplicateString); - UniqueStringHashPolicy::Lookup lookup(duplicateString, length); - auto ptr = strings.lookupForAdd(lookup); - - if (!ptr) { - UniqueString owned(NS_strndup(duplicateString, length)); - if (!owned || !strings.add(ptr, Move(owned))) - return nullptr; - } - - MOZ_ASSERT(ptr->get() != duplicateString); - return ptr->get(); -} /*** Heap Snapshot Analyses ***********************************************************************/ @@ -407,6 +472,10 @@ HeapSnapshot::TakeCensus(JSContext* cx, JS::HandleObject options, } } +#undef GET_STRING_OR_REF_WITH_PROP_NAMES +#undef GET_STRING_OR_REF + + /*** Saving Heap Snapshots ************************************************************************/ // If we are only taking a snapshot of the heap affected by the given set of @@ -549,17 +618,225 @@ EstablishBoundaries(JSContext* cx, } +// A variant covering all the various two-byte strings that we can get from the +// ubi::Node API. +class TwoByteString : public Variant +{ + using Base = Variant; + + struct AsTwoByteStringMatcher + { + using ReturnType = TwoByteString; + + TwoByteString match(JSAtom* atom) { + return TwoByteString(atom); + } + + TwoByteString match(const char16_t* chars) { + return TwoByteString(chars); + } + }; + + struct IsNonNullMatcher + { + using ReturnType = bool; + + template + bool match(const T& t) { return t != nullptr; } + }; + + struct LengthMatcher + { + using ReturnType = size_t; + + size_t match(JSAtom* atom) { + MOZ_ASSERT(atom); + JS::ubi::AtomOrTwoByteChars s(atom); + return s.length(); + } + + size_t match(const char16_t* chars) { + MOZ_ASSERT(chars); + return NS_strlen(chars); + } + + size_t match(const JS::ubi::EdgeName& ptr) { + MOZ_ASSERT(ptr); + return NS_strlen(ptr.get()); + } + }; + + struct CopyToBufferMatcher + { + using ReturnType = size_t; + + RangedPtr destination; + size_t maxLength; + + CopyToBufferMatcher(RangedPtr destination, size_t maxLength) + : destination(destination) + , maxLength(maxLength) + { } + + size_t match(JS::ubi::EdgeName& ptr) { + return ptr ? match(ptr.get()) : 0; + } + + size_t match(JSAtom* atom) { + MOZ_ASSERT(atom); + JS::ubi::AtomOrTwoByteChars s(atom); + return s.copyToBuffer(destination, maxLength); + } + + size_t match(const char16_t* chars) { + MOZ_ASSERT(chars); + JS::ubi::AtomOrTwoByteChars s(chars); + return s.copyToBuffer(destination, maxLength); + } + }; + +public: + template + MOZ_IMPLICIT TwoByteString(T&& rhs) : Base(Forward(rhs)) { } + + template + TwoByteString& operator=(T&& rhs) { + MOZ_ASSERT(this != &rhs, "self-move disallowed"); + this->~TwoByteString(); + new (this) TwoByteString(Forward(rhs)); + return *this; + } + + TwoByteString(const TwoByteString&) = delete; + TwoByteString& operator=(const TwoByteString&) = delete; + + // Rewrap the inner value of a JS::ubi::AtomOrTwoByteChars as a TwoByteString. + static TwoByteString from(JS::ubi::AtomOrTwoByteChars&& s) { + AsTwoByteStringMatcher m; + return s.match(m); + } + + // Returns true if the given TwoByteString is non-null, false otherwise. + bool isNonNull() const { + IsNonNullMatcher m; + return match(m); + } + + // Return the length of the string, 0 if it is null. + size_t length() const { + LengthMatcher m; + return match(m); + } + + // Copy the contents of a TwoByteString into the provided buffer. The buffer + // is NOT null terminated. The number of characters written is returned. + size_t copyToBuffer(RangedPtr destination, size_t maxLength) { + CopyToBufferMatcher m(destination, maxLength); + return match(m); + } + + struct HashPolicy; +}; + +// A hashing policy for TwoByteString. +// +// Atoms are pointer hashed and use pointer equality, which means that we +// tolerate some duplication across atoms and the other two types of two-byte +// strings. In practice, we expect the amount of this duplication to be very low +// because each type is generally a different semantic thing in addition to +// having a slightly different representation. For example, the set of edge +// names and the set stack frames' source names naturally tend not to overlap +// very much if at all. +struct TwoByteString::HashPolicy { + using Lookup = TwoByteString; + + struct HashingMatcher { + using ReturnType = js::HashNumber; + + js::HashNumber match(const JSAtom* atom) { + return js::DefaultHasher::hash(atom); + } + + js::HashNumber match(const char16_t* chars) { + MOZ_ASSERT(chars); + auto length = NS_strlen(chars); + return HashString(chars, length); + } + + js::HashNumber match(const JS::ubi::EdgeName& ptr) { + MOZ_ASSERT(ptr); + return match(ptr.get()); + } + }; + + static js::HashNumber hash(const Lookup& l) { + HashingMatcher hasher; + return l.match(hasher); + } + + struct EqualityMatcher { + using ReturnType = bool; + const TwoByteString& rhs; + explicit EqualityMatcher(const TwoByteString& rhs) : rhs(rhs) { } + + bool match(const JSAtom* atom) { + return rhs.is() && rhs.as() == atom; + } + + bool match(const char16_t* chars) { + MOZ_ASSERT(chars); + + const char16_t* rhsChars = nullptr; + if (rhs.is()) + rhsChars = rhs.as(); + else if (rhs.is()) + rhsChars = rhs.as().get(); + else + return false; + MOZ_ASSERT(rhsChars); + + auto length = NS_strlen(chars); + if (NS_strlen(rhsChars) != length) + return false; + + return memcmp(chars, rhsChars, length * sizeof(char16_t)) == 0; + } + + bool match(const JS::ubi::EdgeName& ptr) { + MOZ_ASSERT(ptr); + return match(ptr.get()); + } + }; + + static bool match(const TwoByteString& k, const Lookup& l) { + EqualityMatcher eq(l); + return k.match(eq); + } + + static void rekey(TwoByteString& k, TwoByteString&& newKey) { + k = Move(newKey); + } +}; + // A `CoreDumpWriter` that serializes nodes to protobufs and writes them to the // given `ZeroCopyOutputStream`. class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter { - using Set = js::HashSet; + using FrameSet = js::HashSet; + using TwoByteStringMap = js::HashMap; + using OneByteStringMap = js::HashMap; - JSContext* cx; - bool wantNames; + JSContext* cx; + bool wantNames; // The set of |JS::ubi::StackFrame::identifier()|s that have already been // serialized and written to the core dump. - Set framesAlreadySerialized; + FrameSet framesAlreadySerialized; + // The set of two-byte strings that have already been serialized and written + // to the core dump. + TwoByteStringMap twoByteStringsAlreadySerialized; + // The set of one-byte strings that have already been serialized and written + // to the core dump. + OneByteStringMap oneByteStringsAlreadySerialized; ::google::protobuf::io::ZeroCopyOutputStream& stream; @@ -573,7 +850,64 @@ class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter return !codedStream.HadError(); } + // Attach the full two-byte string or a reference to a two-byte string that + // has already been serialized to a protobuf message. + template + bool attachTwoByteString(TwoByteString& string, SetStringFunction setString, + SetRefFunction setRef) { + auto ptr = twoByteStringsAlreadySerialized.lookupForAdd(string); + if (ptr) { + setRef(ptr->value()); + return true; + } + + auto length = string.length(); + auto stringData = MakeUnique(length * sizeof(char16_t), '\0'); + if (!stringData) + return false; + + auto buf = const_cast(reinterpret_cast(stringData->data())); + string.copyToBuffer(RangedPtr(buf, length), length); + + uint64_t ref = twoByteStringsAlreadySerialized.count(); + if (!twoByteStringsAlreadySerialized.add(ptr, Move(string), ref)) + return false; + + setString(stringData.release()); + return true; + } + + // Attach the full one-byte string or a reference to a one-byte string that + // has already been serialized to a protobuf message. + template + bool attachOneByteString(const char* string, SetStringFunction setString, + SetRefFunction setRef) { + auto ptr = oneByteStringsAlreadySerialized.lookupForAdd(string); + if (ptr) { + setRef(ptr->value()); + return true; + } + + auto length = strlen(string); + auto stringData = MakeUnique(string, length); + if (!stringData) + return false; + + uint64_t ref = oneByteStringsAlreadySerialized.count(); + if (!oneByteStringsAlreadySerialized.add(ptr, string, ref)) + return false; + + setString(stringData.release()); + return true; + } + protobuf::StackFrame* getProtobufStackFrame(JS::ubi::StackFrame& frame) { + // NB: de-duplicated string properties must be written in the same order + // here as they are read in `HeapSnapshot::saveStackFrame` or else indices + // in references to already serialized strings will be off. + MOZ_ASSERT(frame, "null frames should be represented as the lack of a serialized " "stack frame"); @@ -598,24 +932,22 @@ class MOZ_STACK_CLASS StreamWriter : public CoreDumpWriter data->set_issystem(frame.isSystem()); data->set_isselfhosted(frame.isSelfHosted()); - auto source = MakeUnique(frame.sourceLength() * sizeof(char16_t), - '\0'); - if (!source) + auto dupeSource = TwoByteString::from(frame.source()); + if (!attachTwoByteString(dupeSource, + [&] (std::string* source) { data->set_allocated_source(source); }, + [&] (uint64_t ref) { data->set_sourceref(ref); })) + { return nullptr; - auto buf = const_cast(reinterpret_cast(source->data())); - frame.source(RangedPtr(buf, frame.sourceLength()), - frame.sourceLength()); - data->set_allocated_source(source.release()); + } - auto nameLength = frame.functionDisplayNameLength(); - if (nameLength > 0) { - auto functionDisplayName = MakeUnique(nameLength * sizeof(char16_t), - '\0'); - if (!functionDisplayName) + auto dupeName = TwoByteString::from(frame.functionDisplayName()); + if (dupeName.isNonNull()) { + if (!attachTwoByteString(dupeName, + [&] (std::string* name) { data->set_allocated_functiondisplayname(name); }, + [&] (uint64_t ref) { data->set_functiondisplaynameref(ref); })) + { return nullptr; - auto buf = const_cast(reinterpret_cast(functionDisplayName->data())); - frame.functionDisplayName(RangedPtr(buf, nameLength), nameLength); - data->set_allocated_functiondisplayname(functionDisplayName.release()); + } } auto parent = frame.parent(); @@ -641,14 +973,20 @@ public: : cx(cx) , wantNames(wantNames) , framesAlreadySerialized(cx) + , twoByteStringsAlreadySerialized(cx) + , oneByteStringsAlreadySerialized(cx) , stream(stream) { } - bool init() { return framesAlreadySerialized.init(); } + bool init() { + return framesAlreadySerialized.init() && + twoByteStringsAlreadySerialized.init() && + oneByteStringsAlreadySerialized.init(); + } ~StreamWriter() override { } - virtual bool writeMetadata(uint64_t timestamp) override { + virtual bool writeMetadata(uint64_t timestamp) final { protobuf::Metadata metadata; metadata.set_timestamp(timestamp); return writeMessage(metadata); @@ -656,20 +994,55 @@ public: virtual bool writeNode(const JS::ubi::Node& ubiNode, EdgePolicy includeEdges) final { + // NB: de-duplicated string properties must be written in the same order + // here as they are read in `HeapSnapshot::saveNode` or else indices in + // references to already serialized strings will be off. + protobuf::Node protobufNode; protobufNode.set_id(ubiNode.identifier()); protobufNode.set_coarsetype(JS::ubi::CoarseTypeToUint32(ubiNode.coarseType())); - const char16_t* typeName = ubiNode.typeName(); - size_t length = NS_strlen(typeName) * sizeof(char16_t); - protobufNode.set_typename_(typeName, length); + auto typeName = TwoByteString(ubiNode.typeName()); + if (NS_WARN_IF(!attachTwoByteString(typeName, + [&] (std::string* name) { protobufNode.set_allocated_typename_(name); }, + [&] (uint64_t ref) { protobufNode.set_typenameref(ref); }))) + { + return false; + } JSRuntime* rt = JS_GetRuntime(cx); mozilla::MallocSizeOf mallocSizeOf = dbg::GetDebuggerMallocSizeOf(rt); MOZ_ASSERT(mallocSizeOf); protobufNode.set_size(ubiNode.size(mallocSizeOf)); + if (includeEdges) { + auto edges = ubiNode.edges(JS_GetRuntime(cx), wantNames); + if (NS_WARN_IF(!edges)) + return false; + + for ( ; !edges->empty(); edges->popFront()) { + ubi::Edge& ubiEdge = edges->front(); + + protobuf::Edge* protobufEdge = protobufNode.add_edges(); + if (NS_WARN_IF(!protobufEdge)) { + return false; + } + + protobufEdge->set_referent(ubiEdge.referent.identifier()); + + if (wantNames && ubiEdge.name) { + TwoByteString edgeName(Move(ubiEdge.name)); + if (NS_WARN_IF(!attachTwoByteString(edgeName, + [&] (std::string* name) { protobufEdge->set_allocated_name(name); }, + [&] (uint64_t ref) { protobufEdge->set_nameref(ref); }))) + { + return false; + } + } + } + } + if (ubiNode.hasAllocationStack()) { auto ubiStackFrame = ubiNode.allocationStack(); auto protoStackFrame = getProtobufStackFrame(ubiStackFrame); @@ -679,29 +1052,11 @@ public: } if (auto className = ubiNode.jsObjectClassName()) { - size_t length = strlen(className); - protobufNode.set_jsobjectclassname(className, length); - } - - if (includeEdges) { - auto edges = ubiNode.edges(JS_GetRuntime(cx), wantNames); - if (NS_WARN_IF(!edges)) + if (NS_WARN_IF(!attachOneByteString(className, + [&] (std::string* name) { protobufNode.set_allocated_jsobjectclassname(name); }, + [&] (uint64_t ref) { protobufNode.set_jsobjectclassnameref(ref); }))) + { return false; - - for ( ; !edges->empty(); edges->popFront()) { - const ubi::Edge& ubiEdge = edges->front(); - - protobuf::Edge* protobufEdge = protobufNode.add_edges(); - if (NS_WARN_IF(!protobufEdge)) { - return false; - } - - protobufEdge->set_referent(ubiEdge.referent.identifier()); - - if (wantNames && ubiEdge.name) { - size_t length = NS_strlen(ubiEdge.name) * sizeof(char16_t); - protobufEdge->set_name(ubiEdge.name, length); - } } } diff --git a/devtools/shared/heapsnapshot/HeapSnapshot.h b/devtools/shared/heapsnapshot/HeapSnapshot.h index 8c4de6fb2a2..b4c9593cd71 100644 --- a/devtools/shared/heapsnapshot/HeapSnapshot.h +++ b/devtools/shared/heapsnapshot/HeapSnapshot.h @@ -34,36 +34,14 @@ struct NSFreePolicy { } }; -using UniqueString = UniquePtr; - -struct UniqueStringHashPolicy { - struct Lookup { - const char16_t* str; - size_t length; - - Lookup(const char16_t* str, size_t length) - : str(str) - , length(length) - { } - }; - - static js::HashNumber hash(const Lookup& lookup) { - MOZ_ASSERT(lookup.str); - return HashString(lookup.str, lookup.length); - } - - static bool match(const UniqueString& existing, const Lookup& lookup) { - MOZ_ASSERT(lookup.str); - if (NS_strlen(existing.get()) != lookup.length) - return false; - return memcmp(existing.get(), lookup.str, lookup.length * sizeof(char16_t)) == 0; - } -}; +using UniqueTwoByteString = UniquePtr; +using UniqueOneByteString = UniquePtr; class HeapSnapshot final : public nsISupports , public nsWrapperCache { friend struct DeserializedNode; + friend struct DeserializedEdge; friend struct DeserializedStackFrame; friend struct JS::ubi::Concrete; @@ -72,7 +50,6 @@ class HeapSnapshot final : public nsISupports , rootId(0) , nodes(cx) , frames(cx) - , strings(cx) , mParent(aParent) { MOZ_ASSERT(aParent); @@ -108,14 +85,15 @@ class HeapSnapshot final : public nsISupports DeserializedStackFrame::HashPolicy>; FrameSet frames; - // Core dump files have many duplicate strings: type names are repeated for - // each node, and although in theory edge names are highly customizable for - // specific edges, in practice they are also highly duplicated. Rather than - // make each Deserialized{Node,Edge} malloc their own copy of their edge and - // type names, we de-duplicate the strings here and Deserialized{Node,Edge} - // get borrowed pointers into this set. - using UniqueStringSet = js::HashSet; - UniqueStringSet strings; + Vector internedTwoByteStrings; + Vector internedOneByteStrings; + + using StringOrRef = Variant; + + template + const CharT* getOrInternString(InternedStringSet& internedStrings, + Maybe& maybeStrOrRef); protected: nsCOMPtr mParent; diff --git a/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp b/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp index c098287cf16..f984f0e8927 100644 --- a/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp +++ b/devtools/shared/heapsnapshot/tests/gtest/DeserializedNodeUbiNodes.cpp @@ -43,9 +43,8 @@ DEF_TEST(DeserializedNodeUbiNodes, { NodeId id = uint64_t(1) << 33; uint64_t size = uint64_t(1) << 60; MockDeserializedNode mocked(id, typeName, size); - mocked.jsObjectClassName = mozilla::UniquePtr(strdup(className)); - ASSERT_TRUE(!!mocked.jsObjectClassName); mocked.coarseType = JS::ubi::CoarseType::Script; + mocked.jsObjectClassName = className; DeserializedNode& deserialized = mocked; JS::ubi::Node ubi(&deserialized); @@ -57,15 +56,14 @@ DEF_TEST(DeserializedNodeUbiNodes, { EXPECT_EQ(JS::ubi::CoarseType::Script, ubi.coarseType()); EXPECT_EQ(id, ubi.identifier()); EXPECT_FALSE(ubi.isLive()); - EXPECT_EQ(strcmp(ubi.jsObjectClassName(), className), 0); + EXPECT_EQ(ubi.jsObjectClassName(), className); // Test the ubi::Node's edges. UniquePtr referent1(new MockDeserializedNode(1, nullptr, 10)); - DeserializedEdge edge1; - edge1.referent = referent1->id; + DeserializedEdge edge1(referent1->id); mocked.addEdge(Move(edge1)); EXPECT_CALL(mocked, getEdgeReferent(Field(&DeserializedEdge::referent, @@ -76,8 +74,7 @@ DEF_TEST(DeserializedNodeUbiNodes, { UniquePtr referent2(new MockDeserializedNode(2, nullptr, 20)); - DeserializedEdge edge2; - edge2.referent = referent2->id; + DeserializedEdge edge2(referent2->id); mocked.addEdge(Move(edge2)); EXPECT_CALL(mocked, getEdgeReferent(Field(&DeserializedEdge::referent, @@ -88,8 +85,7 @@ DEF_TEST(DeserializedNodeUbiNodes, { UniquePtr referent3(new MockDeserializedNode(3, nullptr, 30)); - DeserializedEdge edge3; - edge3.referent = referent3->id; + DeserializedEdge edge3(referent3->id); mocked.addEdge(Move(edge3)); EXPECT_CALL(mocked, getEdgeReferent(Field(&DeserializedEdge::referent, @@ -97,5 +93,5 @@ DEF_TEST(DeserializedNodeUbiNodes, { .Times(1) .WillOnce(Return(JS::ubi::Node(referent3.get()))); - ubi.edges(JS_GetRuntime(cx)); + ubi.edges(rt); }); diff --git a/devtools/shared/heapsnapshot/tests/gtest/DevTools.h b/devtools/shared/heapsnapshot/tests/gtest/DevTools.h index 20b272064e6..1146833f7c9 100644 --- a/devtools/shared/heapsnapshot/tests/gtest/DevTools.h +++ b/devtools/shared/heapsnapshot/tests/gtest/DevTools.h @@ -182,7 +182,7 @@ class Concrete : public Base return concreteTypeName; } - UniquePtr edges(JSRuntime* rt, bool wantNames) const override { + UniquePtr edges(JSRuntime*, bool) const override { return UniquePtr(js_new(get().edges)); } @@ -270,6 +270,14 @@ MATCHER_P(UTF16StrEq, str, "") { return NS_strcmp(arg, str) == 0; } +MATCHER_P(UniqueUTF16StrEq, str, "") { + return NS_strcmp(arg.get(), str) == 0; +} + +MATCHER(UniqueIsNull, "") { + return arg.get() == nullptr; +} + } // namespace testing diff --git a/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp b/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp index 234463618a5..5b22342447c 100644 --- a/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp +++ b/devtools/shared/heapsnapshot/tests/gtest/SerializesEdgeNames.cpp @@ -30,11 +30,11 @@ DEF_TEST(SerializesEdgeNames, { writer, writeNode(AllOf(EdgesLength(rt, 3), Edge(rt, 0, Field(&JS::ubi::Edge::name, - UTF16StrEq(edgeName))), + UniqueUTF16StrEq(edgeName))), Edge(rt, 1, Field(&JS::ubi::Edge::name, - UTF16StrEq(emptyStr))), + UniqueUTF16StrEq(emptyStr))), Edge(rt, 2, Field(&JS::ubi::Edge::name, - IsNull()))), + UniqueIsNull()))), _) ) .Times(1) diff --git a/devtools/shared/heapsnapshot/tests/gtest/UniqueStringHashPolicy.cpp b/devtools/shared/heapsnapshot/tests/gtest/UniqueStringHashPolicy.cpp deleted file mode 100644 index 3c210d5e82f..00000000000 --- a/devtools/shared/heapsnapshot/tests/gtest/UniqueStringHashPolicy.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Bug 1171226 - Test UniqueStringHashPolicy::match - -#include "DevTools.h" -#include "mozilla/devtools/HeapSnapshot.h" - -using mozilla::devtools::UniqueString; -using mozilla::devtools::UniqueStringHashPolicy; - -DEF_TEST(UniqueStringHashPolicy_match, { - // 1 - // 01234567890123456 - UniqueString str1(NS_strdup(MOZ_UTF16("some long string and a tail"))); - ASSERT_TRUE(!!str1); - - UniqueStringHashPolicy::Lookup lookup(MOZ_UTF16("some long string with same prefix"), 16); - - // str1 is longer than Lookup.length, so they shouldn't match, even though - // the first 16 chars are equal! - ASSERT_FALSE(UniqueStringHashPolicy::match(str1, lookup)); - }); diff --git a/devtools/shared/heapsnapshot/tests/gtest/moz.build b/devtools/shared/heapsnapshot/tests/gtest/moz.build index 14f7fa6b104..fb10b1419ec 100644 --- a/devtools/shared/heapsnapshot/tests/gtest/moz.build +++ b/devtools/shared/heapsnapshot/tests/gtest/moz.build @@ -18,7 +18,6 @@ UNIFIED_SOURCES = [ 'SerializesEdgeNames.cpp', 'SerializesEverythingInHeapGraphOnce.cpp', 'SerializesTypeNames.cpp', - 'UniqueStringHashPolicy.cpp', ] # THE MOCK_METHOD2 macro from gtest triggers this clang warning and it's hard diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h index 74a0bfb46c7..9822ac5f98a 100644 --- a/js/public/UbiNode.h +++ b/js/public/UbiNode.h @@ -25,6 +25,7 @@ #include "js/RootingAPI.h" #include "js/TracingAPI.h" #include "js/TypeDecls.h" +#include "js/Value.h" #include "js/Vector.h" // JS::ubi::Node @@ -186,6 +187,7 @@ class DefaultDelete : public JS::DeletePolicy; +class AtomOrTwoByteChars : public Variant { + using Base = Variant; + + public: + template + MOZ_IMPLICIT AtomOrTwoByteChars(T&& rhs) : Base(Forward(rhs)) { } + + template + AtomOrTwoByteChars& operator=(T&& rhs) { + MOZ_ASSERT(this != &rhs, "self-move disallowed"); + this->~AtomOrTwoByteChars(); + new (this) AtomOrTwoByteChars(Forward(rhs)); + return *this; + } + + // Return the length of the given AtomOrTwoByteChars string. + size_t length(); + + // Copy the given AtomOrTwoByteChars string into the destination buffer, + // inflating if necessary. Does NOT null terminate. Returns the number of + // characters written to destination. + size_t copyToBuffer(RangedPtr destination, size_t length); +}; // The base class implemented by each ConcreteStackFrame type. Subclasses // must not add data members to this class. @@ -786,23 +810,25 @@ class Node { /*** Edge and EdgeRange ***************************************************************************/ +using EdgeName = UniquePtr; + // An outgoing edge to a referent node. class Edge { public: Edge() : name(nullptr), referent() { } // Construct an initialized Edge, taking ownership of |name|. - Edge(char16_t* name, const Node& referent) { - this->name = name; - this->referent = referent; - } + Edge(char16_t* name, const Node& referent) + : name(name) + , referent(referent) + { } // Move construction and assignment. - Edge(Edge&& rhs) { - name = rhs.name; - referent = rhs.referent; - rhs.name = nullptr; - } + Edge(Edge&& rhs) + : name(mozilla::Move(rhs.name)) + , referent(rhs.referent) + { } + Edge& operator=(Edge&& rhs) { MOZ_ASSERT(&rhs != this); this->~Edge(); @@ -810,10 +836,6 @@ class Edge { return *this; } - ~Edge() { - js_free(const_cast(name)); - } - Edge(const Edge&) = delete; Edge& operator=(const Edge&) = delete; @@ -826,7 +848,7 @@ class Edge { // (In real life we'll want a better representation for names, to avoid // creating tons of strings when the names follow a pattern; and we'll need // to think about lifetimes carefully to ensure traversal stays cheap.) - const char16_t* name; + EdgeName name; // This edge's referent. Node referent; diff --git a/js/public/Utility.h b/js/public/Utility.h index 5aaafca6382..3279b0c23f4 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -128,7 +128,7 @@ extern JS_PUBLIC_DATA(uint32_t) targetThread; static inline bool OOMThreadCheck() { - return (!js::oom::targetThread + return (!js::oom::targetThread || js::oom::targetThread == js::oom::GetThreadType()); } @@ -435,15 +435,15 @@ namespace JS { template struct DeletePolicy { - void operator()(T* ptr) { - js_delete(ptr); + void operator()(const T* ptr) { + js_delete(const_cast(ptr)); } }; struct FreePolicy { - void operator()(void* ptr) { - js_free(ptr); + void operator()(const void* ptr) { + js_free(const_cast(ptr)); } }; diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 6281d620ae5..7312fe332c5 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -2141,7 +2141,7 @@ struct FindPathHandler { // Record how we reached this node. This is the last edge on a // shortest path to this node. - EdgeName edgeName = DuplicateString(cx, edge.name); + EdgeName edgeName = DuplicateString(cx, edge.name.get()); if (!edgeName) return false; *backEdge = mozilla::Move(BackEdge(origin, Move(edgeName))); diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp index f1badf95771..3e682a7a33d 100644 --- a/js/src/vm/UbiNode.cpp +++ b/js/src/vm/UbiNode.cpp @@ -52,16 +52,6 @@ using JS::ubi::StackFrame; using JS::ubi::TracerConcrete; using JS::ubi::TracerConcreteWithCompartment; -template -static size_t -copyToBuffer(const CharT* src, RangedPtr dest, size_t length) -{ - size_t i = 0; - for ( ; i < length; i++) - dest[i] = src[i]; - return i; -} - struct CopyToBufferMatcher { using ReturnType = size_t; @@ -74,6 +64,16 @@ struct CopyToBufferMatcher , maxLength(maxLength) { } + template + static size_t + copyToBufferHelper(const CharT* src, RangedPtr dest, size_t length) + { + size_t i = 0; + for ( ; i < length; i++) + dest[i] = src[i]; + return i; + } + size_t match(JSAtom* atom) { @@ -83,8 +83,8 @@ struct CopyToBufferMatcher size_t length = std::min(atom->length(), maxLength); JS::AutoCheckCannotGC noGC; return atom->hasTwoByteChars() - ? copyToBuffer(atom->twoByteChars(noGC), destination, length) - : copyToBuffer(atom->latin1Chars(noGC), destination, length); + ? copyToBufferHelper(atom->twoByteChars(noGC), destination, length) + : copyToBufferHelper(atom->latin1Chars(noGC), destination, length); } size_t @@ -94,22 +94,15 @@ struct CopyToBufferMatcher return 0; size_t length = std::min(js_strlen(chars), maxLength); - return copyToBuffer(chars, destination, length); + return copyToBufferHelper(chars, destination, length); } }; size_t -StackFrame::source(RangedPtr destination, size_t length) const +JS::ubi::AtomOrTwoByteChars::copyToBuffer(RangedPtr destination, size_t length) { CopyToBufferMatcher m(destination, length); - return source().match(m); -} - -size_t -StackFrame::functionDisplayName(RangedPtr destination, size_t length) const -{ - CopyToBufferMatcher m(destination, length); - return functionDisplayName().match(m); + return match(m); } struct LengthMatcher @@ -130,17 +123,36 @@ struct LengthMatcher }; size_t -StackFrame::sourceLength() +JS::ubi::AtomOrTwoByteChars::length() { LengthMatcher m; - return source().match(m); + return match(m); +} + +size_t +StackFrame::source(RangedPtr destination, size_t length) const +{ + auto s = source(); + return s.copyToBuffer(destination, length); +} + +size_t +StackFrame::functionDisplayName(RangedPtr destination, size_t length) const +{ + auto name = functionDisplayName(); + return name.copyToBuffer(destination, length); +} + +size_t +StackFrame::sourceLength() +{ + return source().length(); } size_t StackFrame::functionDisplayNameLength() { - LengthMatcher m; - return functionDisplayName().match(m); + return functionDisplayName().length(); } // All operations on null ubi::Nodes crash. diff --git a/xpcom/glue/nsCRTGlue.cpp b/xpcom/glue/nsCRTGlue.cpp index 1bc4377a3f1..a050e15ea75 100644 --- a/xpcom/glue/nsCRTGlue.cpp +++ b/xpcom/glue/nsCRTGlue.cpp @@ -128,17 +128,21 @@ NS_strdup(const char16_t* aString) return NS_strndup(aString, len); } -char16_t* -NS_strndup(const char16_t* aString, uint32_t aLen) +template +CharT* +NS_strndup(const CharT* aString, uint32_t aLen) { - char16_t* newBuf = (char16_t*)NS_Alloc((aLen + 1) * sizeof(char16_t)); + auto newBuf = (CharT*)NS_Alloc((aLen + 1) * sizeof(CharT)); if (newBuf) { - memcpy(newBuf, aString, aLen * sizeof(char16_t)); + memcpy(newBuf, aString, aLen * sizeof(CharT)); newBuf[aLen] = '\0'; } return newBuf; } +template char16_t* NS_strndup(const char16_t* aString, uint32_t aLen); +template char* NS_strndup(const char* aString, uint32_t aLen); + char* NS_strdup(const char* aString) { diff --git a/xpcom/glue/nsCRTGlue.h b/xpcom/glue/nsCRTGlue.h index 4e59c137c45..8caa1ae2727 100644 --- a/xpcom/glue/nsCRTGlue.h +++ b/xpcom/glue/nsCRTGlue.h @@ -63,10 +63,14 @@ char16_t* NS_strdup(const char16_t* aString); char* NS_strdup(const char* aString); /** - * strndup for char16_t strings... this function will ensure that the - * new string is null-terminated. Uses the NS_Alloc allocator. + * strndup for char16_t or char strings (normal strndup is not available on + * windows). This function will ensure that the new string is + * null-terminated. Uses the NS_Alloc allocator. + * + * CharT may be either char16_t or char. */ -char16_t* NS_strndup(const char16_t* aString, uint32_t aLen); +template +CharT* NS_strndup(const CharT* aString, uint32_t aLen); // The following case-conversion methods only deal in the ascii repertoire // A-Z and a-z