michael@0: // Test01.cpp michael@0: michael@0: #include "nsIDOMNode.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsString.h" michael@0: michael@0: NS_DEF_PTR(nsIDOMNode); michael@0: michael@0: /* michael@0: This test file compares the generated code size of similar functions between raw michael@0: COM interface pointers (|AddRef|ing and |Release|ing by hand) and |nsCOMPtr|s. michael@0: michael@0: Function size results were determined by examining dissassembly of the generated code. michael@0: mXXX is the size of the generated code on the Macintosh. wXXX is the size on Windows. michael@0: For these tests, all reasonable optimizations were enabled and exceptions were michael@0: disabled (just as we build for release). michael@0: michael@0: The tests in this file explore only the simplest functionality: assigning a pointer michael@0: to be reference counted into a [raw, nsCOMPtr] object; ensuring that it is michael@0: |AddRef|ed and |Release|d appropriately; calling through the pointer to a function michael@0: supplied by the underlying COM interface. michael@0: michael@0: Windows: michael@0: raw_optimized 31 bytes michael@0: raw, nsCOMPtr* 34 michael@0: nsCOMPtr_optimized* 38 michael@0: nsCOMPtr_optimized 42 michael@0: nsCOMPtr 46 michael@0: michael@0: Macintosh: michael@0: raw_optimized, nsCOMPtr_optimized 112 bytes (1.0000) michael@0: nsCOMPtr 120 (1.0714) i.e., 7.14% bigger than raw_optimized et al michael@0: raw 140 (1.2500) michael@0: michael@0: The overall difference in size between Windows and Macintosh is caused by the michael@0: the PowerPC RISC architecture where every instruction is 4 bytes. michael@0: michael@0: On Macintosh, nsCOMPtr generates out-of-line destructors which are michael@0: not referenced, and which can be stripped by the linker. michael@0: */ michael@0: michael@0: void michael@0: Test01_raw( nsIDOMNode* aDOMNode, nsString* aResult ) michael@0: // m140, w34 michael@0: { michael@0: /* michael@0: This test is designed to be more like a typical large function where, michael@0: because you are working with several resources, you don't just return when michael@0: one of them is |nullptr|. Similarly: |Test01_nsCOMPtr00|, and |Test01_nsIPtr00|. michael@0: */ michael@0: michael@0: nsIDOMNode* node = aDOMNode; michael@0: NS_IF_ADDREF(node); michael@0: michael@0: if ( node ) michael@0: node->GetNodeName(*aResult); michael@0: michael@0: NS_IF_RELEASE(node); michael@0: } michael@0: michael@0: void michael@0: Test01_raw_optimized( nsIDOMNode* aDOMNode, nsString* aResult ) michael@0: // m112, w31 michael@0: { michael@0: /* michael@0: This test simulates smaller functions where you _do_ just return michael@0: |nullptr| at the first sign of trouble. Similarly: |Test01_nsCOMPtr01|, michael@0: and |Test01_nsIPtr01|. michael@0: */ michael@0: michael@0: /* michael@0: This test produces smaller code that |Test01_raw| because it avoids michael@0: the three tests: |NS_IF_...|, and |if ( node )|. michael@0: */ michael@0: michael@0: // -- the following code is assumed, but is commented out so we compare only michael@0: // the relevent generated code michael@0: michael@0: // if ( !aDOMNode ) michael@0: // return; michael@0: michael@0: nsIDOMNode* node = aDOMNode; michael@0: NS_ADDREF(node); michael@0: node->GetNodeName(*aResult); michael@0: NS_RELEASE(node); michael@0: } michael@0: michael@0: void michael@0: Test01_nsCOMPtr( nsIDOMNode* aDOMNode, nsString* aResult ) michael@0: // m120, w46/34 michael@0: { michael@0: nsCOMPtr node = aDOMNode; michael@0: michael@0: if ( node ) michael@0: node->GetNodeName(*aResult); michael@0: } michael@0: michael@0: void michael@0: Test01_nsCOMPtr_optimized( nsIDOMNode* aDOMNode, nsString* aResult ) michael@0: // m112, w42/38 michael@0: { michael@0: // if ( !aDOMNode ) michael@0: // return; michael@0: michael@0: nsCOMPtr node = aDOMNode; michael@0: node->GetNodeName(*aResult); michael@0: }