mirror of
				https://github.com/yuzu-emu/breakpad.git
				synced 2025-11-04 16:04:58 +00:00 
			
		
		
		
	output function names for PGO-optimized cold function blocks. r=mark at http://breakpad.appspot.com/40007
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@430 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
		
							parent
							
								
									2712a8c712
								
							
						
					
					
						commit
						927cc8fa2a
					
				| 
						 | 
				
			
			@ -136,17 +136,18 @@ bool PDBSourceLineWriter::PrintLines(IDiaEnumLineNumbers *lines) {
 | 
			
		|||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool PDBSourceLineWriter::PrintFunction(IDiaSymbol *function) {
 | 
			
		||||
bool PDBSourceLineWriter::PrintFunction(IDiaSymbol *function,
 | 
			
		||||
                                        IDiaSymbol *block) {
 | 
			
		||||
  // The function format is:
 | 
			
		||||
  // FUNC <address> <length> <param_stack_size> <function>
 | 
			
		||||
  DWORD rva;
 | 
			
		||||
  if (FAILED(function->get_relativeVirtualAddress(&rva))) {
 | 
			
		||||
  if (FAILED(block->get_relativeVirtualAddress(&rva))) {
 | 
			
		||||
    fprintf(stderr, "couldn't get rva\n");
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ULONGLONG length;
 | 
			
		||||
  if (FAILED(function->get_length(&length))) {
 | 
			
		||||
  if (FAILED(block->get_length(&length))) {
 | 
			
		||||
    fprintf(stderr, "failed to get function length\n");
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -255,7 +256,7 @@ bool PDBSourceLineWriter::PrintFunctions() {
 | 
			
		|||
    // that PDBSourceLineWriter will output either a FUNC or PUBLIC line,
 | 
			
		||||
    // but not both.
 | 
			
		||||
    if (tag == SymTagFunction) {
 | 
			
		||||
      if (!PrintFunction(symbol)) {
 | 
			
		||||
      if (!PrintFunction(symbol, symbol)) {
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    } else if (tag == SymTagPublicSymbol) {
 | 
			
		||||
| 
						 | 
				
			
			@ -266,6 +267,64 @@ bool PDBSourceLineWriter::PrintFunctions() {
 | 
			
		|||
    symbol.Release();
 | 
			
		||||
  } while (SUCCEEDED(symbols->Next(1, &symbol, &count)) && count == 1);
 | 
			
		||||
 | 
			
		||||
  // When building with PGO, the compiler can split functions into
 | 
			
		||||
  // "hot" and "cold" blocks, and move the "cold" blocks out to separate
 | 
			
		||||
  // pages, so the function can be noncontiguous. To find these blocks,
 | 
			
		||||
  // we have to iterate over all the compilands, and then find blocks
 | 
			
		||||
  // that are children of them. We can then find the lexical parents
 | 
			
		||||
  // of those blocks and print out an extra FUNC line for blocks
 | 
			
		||||
  // that are not contained in their parent functions.
 | 
			
		||||
  CComPtr<IDiaSymbol> global;
 | 
			
		||||
  if (FAILED(session_->get_globalScope(&global))) {
 | 
			
		||||
    fprintf(stderr, "get_globalScope failed\n");
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CComPtr<IDiaEnumSymbols> compilands;
 | 
			
		||||
  if (FAILED(global->findChildren(SymTagCompiland, NULL,
 | 
			
		||||
                                  nsNone, &compilands))) {
 | 
			
		||||
    fprintf(stderr, "findChildren failed on the global\n");
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CComPtr<IDiaSymbol> compiland;
 | 
			
		||||
  while (SUCCEEDED(compilands->Next(1, &compiland, &count)) && count == 1) {
 | 
			
		||||
    CComPtr<IDiaEnumSymbols> blocks;
 | 
			
		||||
    if (FAILED(compiland->findChildren(SymTagBlock, NULL,
 | 
			
		||||
                                       nsNone, &blocks))) {
 | 
			
		||||
      fprintf(stderr, "findChildren failed on a compiland\n");
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CComPtr<IDiaSymbol> block;
 | 
			
		||||
    while (SUCCEEDED(blocks->Next(1, &block, &count)) && count == 1) {
 | 
			
		||||
      // find this block's lexical parent function
 | 
			
		||||
      CComPtr<IDiaSymbol> parent;
 | 
			
		||||
      DWORD tag;
 | 
			
		||||
      if (SUCCEEDED(block->get_lexicalParent(&parent)) &&
 | 
			
		||||
          SUCCEEDED(parent->get_symTag(&tag)) &&
 | 
			
		||||
          tag == SymTagFunction) {
 | 
			
		||||
        // now get the block's offset and the function's offset and size,
 | 
			
		||||
        // and determine if the block is outside of the function
 | 
			
		||||
        DWORD func_rva, block_rva;
 | 
			
		||||
        ULONGLONG func_length;
 | 
			
		||||
        if (SUCCEEDED(block->get_relativeVirtualAddress(&block_rva)) &&
 | 
			
		||||
            SUCCEEDED(parent->get_relativeVirtualAddress(&func_rva)) &&
 | 
			
		||||
            SUCCEEDED(parent->get_length(&func_length))) {
 | 
			
		||||
          if (block_rva < func_rva || block_rva > (func_rva + func_length)) {
 | 
			
		||||
            if (!PrintFunction(parent, block)) {
 | 
			
		||||
              return false;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      parent.Release();
 | 
			
		||||
      block.Release();
 | 
			
		||||
    }
 | 
			
		||||
    blocks.Release();
 | 
			
		||||
    compiland.Release();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,8 +111,11 @@ class PDBSourceLineWriter {
 | 
			
		|||
  bool PrintLines(IDiaEnumLineNumbers *lines);
 | 
			
		||||
 | 
			
		||||
  // Outputs a function address and name, followed by its source line list.
 | 
			
		||||
  // block can be the same object as function, or it can be a reference
 | 
			
		||||
  // to a code block that is lexically part of this function, but
 | 
			
		||||
  // resides at a separate address.
 | 
			
		||||
  // Returns true on success.
 | 
			
		||||
  bool PrintFunction(IDiaSymbol *function);
 | 
			
		||||
  bool PrintFunction(IDiaSymbol *function, IDiaSymbol *block);
 | 
			
		||||
 | 
			
		||||
  // Outputs all functions as described above.  Returns true on success.
 | 
			
		||||
  bool PrintFunctions();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue