Gecko and C++ Onboarding
5 June 2017
Nathan Froyd @froydnj
Improvements by Waldo, mstange, mccr8
Today’s suggested topics
Release the Gecko firehose
Today’s goal
Familiarization, not expertise
Please ask questions!
#engineering-onboarding for backchannel
Overview
Gecko architecture: history
Gecko architecture: XPCOM
Gecko architecture: XPCOM basics
Gecko architecture: XPCOM contract IDs
Gecko architecture: XPCOM services
Gecko architecture: portability
Gecko architecture: evolving
Overview
C++ dialect: style
C++ dialect: infallible allocation
C++ dialect: static analysis
C++ dialect: language features
Brief note on portability
C++ dialect: std:: classes
Progress bullets
XPCOM / MFBT data structures
Growable vectors
MFBT linked lists
XPCOM hashtables
XPCOM hashtables, cont’d
XPCOM hashtables, cont’d
XPCOM strings
XPCOM strings, cont’d
XPCOM string classes
XPCOM string classes, cont’d
XPCOM strings, cont’d
XPCOM string helpers
XPCOM string helpers: example
nsString x; …
NS_ConvertUTF16ToUTF8 utf8(x);
// use utf8 as a normal nsCString
// pass conversion to a const char *
f(..., NS_ConvertUTF16ToUTF8(x).get());
XPCOM strings, documentation
Owned pointers
Owned pointers: the old way
Reference counting
One day a student came to Moon and said: "I understand how to make a better garbage collector. We must keep a reference count of the pointers to each [object]."
Moon patiently told the student the following story:
"One day a student came to Moon and said: ‘I understand how to make a better garbage collector…”
—AI Koan from The New Hacker’s Dictionary
Reference counting: basic interface
Reference counting: thread safety
Reference counting: smart pointers
Refcounting: cycles
Refcounting: cycle collector
Refcounting: declaration
Refcounting: definition
// in nsThing.cpp
// concrete class name followed by
// variadic list of interfaces implemented
NS_IMPL_ISUPPORTS(nsThing, nsIThing);
// works the same for threadsafe ones, too
NS_IMPL_ISUPPORTS(nsThreadsafeThing, nsIThing);
Refcounting: declarations, cont’d
Refcounting: implementation
Refcounting: already_AddRefed
Leak checking
Leak checking: macros
Leak checking: macro considerations
Leak checking: more information
Logging
Logging modules
Dynamic logging
Progress bullets
Code generation
XPIDL files
XPIDL files: generated code
XPIDL files: generated code
XPIDL files: generated code
IDL text | C++ translation / prototypes |
const unsigned long NORMAL_FILE_TYPE = 0; | enum { NORMAL_FILE_TYPE = 0 }; |
void append(in AString node); | NS_IMETHOD Append(const nsAString&); |
bool exists(); | NS_IMETHOD Exists(bool*); |
readonly attribute long long fileSize; | NS_IMETHOD GetFileSize(int64_t*); |
attribute AString leafName; | NS_IMETHOD GetLeafName(nsAString&); NS_IMETHOD SetLeafName(const nsAString&); |
XPIDL files: generated code
XPIDL files: generated code
IPDL files
IPDL codegen
IPDL links
WebIDL files
WebIDL bindings: why?
WebIDL bindings: links
Progress bullets
Code search
Profiling
Debugging
Debugging: rr
Last words
Feedback!
Refcounting: ownership transfers
Klass* Klass::Create(...)
{
RefPtr<Klass> k = new Klass(...);
// Other stuff
return /* ??? */
}
Ownership transfer strategies
Ownership transfers
| Pointer outparam | already_AddRefed<T> | Smart pointer |
Identifying feature | T** argument, usually last | return type | return type |
Passing ownership | p.forget(outparam); | return p.forget(); | return p; |
Caller | RefPtr<T> p; o->Method(getter_AddRefs(p)); | RefPtr<T> p; p = o->Method(); | RefPtr<T> p; p = o->Method(); |
Use cases | XPIDL-style interfaces | static Create() methods | many |
QueryInterface: XPCOM’s dynamic_cast
QueryInterface example
nsCOMPtr<nsIFoo> foo = …;
nsCOMPtr<nsIBar> bar =
do_QueryInterface(foo);
// bar is now non-null if foo was non-null
// and supports the nsIBar interface
nsCOMPtr helpers: do_CreateInstance
do_CreateInstance example
nsCOMPtr<nsIFoo> f =
do_CreateInstance(“@mozilla.org/foo;1”);
nsresult rv = f->Init();
// Roughly equivalent JS
let f = Cc[“@mozilla.org/foo;1”]
.createInstance(Ci.nsIFoo);
f.init();
nsCOMPtr helpers: do_GetService
do_GetService example
nsCOMPtr<nsICatchyService> service =
do_GetService(“@mozilla.org/catchy;1”);
// Alternative, preferred if available
service = services::GetCatchyService();
nsCOMPtr helpers: do_GetInterface
do_GetInterface example
nsCOMPtr<nsIFoo> foo = …
nsCOMPtr<nsIInterfaceRequestor> iir =
do_QueryInterface(foo);
nsCOMPtr<nsIBar> bar =
do_GetInterface(iir);
// bar now non-null if
// - foo supported nsIInterfaceRequestor
// - foo knew how to provide nsIBar things
Progress bullets
Debugging
Debugging: rr
Progress bullets
What happens when I click a link?
Gecko overview: docshell
Gecko overview: networking
Gecko overview: parsing
Gecko overview: DOM
Gecko overview: layout
Gecko overview: graphics
What does all that other code do?
We didn’t cover all the toplevel directories.
What are the other big pieces?
Gecko overview: storage
Gecko overview: images
Gecko overview: media
Gecko overview: widget
Gecko overview: IPC
Gecko overview: JavaScript
Gecko overview: XPConnect
Gecko overview: MFBT
Gecko overview: XPCOM
Gecko overview: NSPR
Progress bullets
Nuts and bolts: C++ visibility