From ad44c62065f5128476fee83472753534252219e7 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Tue, 19 Apr 2011 13:46:19 +0000
Subject: [PATCH] [pykd] updated : improve performance of typedVar function

git-svn-id: https://pykd.svn.codeplex.com/svn@64221 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgtype.cpp | 137 +++++++++++++----------------------------------
 pykd/dbgtype.h   |  17 +++---
 2 files changed, 44 insertions(+), 110 deletions(-)

diff --git a/pykd/dbgtype.cpp b/pykd/dbgtype.cpp
index 49dc43c..be6fd76 100644
--- a/pykd/dbgtype.cpp
+++ b/pykd/dbgtype.cpp
@@ -177,11 +177,11 @@ isBaseType( const std::string  &typeName );
 
 template< typename valType>
 boost::python::object
-valueLoader( ULONG64 address, ULONG size );
+valueLoader( PVOID address, ULONG size );
 
 template<>
 boost::python::object
-valueLoader<void*>( ULONG64 address, ULONG size )
+valueLoader<void*>( PVOID address, ULONG size )
 {
     if ( is64bitSystem() )
         return valueLoader<__int64>( address, size );
@@ -190,7 +190,7 @@ valueLoader<void*>( ULONG64 address, ULONG size )
 }
 
 boost::python::object
-voidLoader( ULONG64 address, ULONG size ) {
+voidLoader( PVOID address, ULONG size ) {
     return boost::python::object();
 }
 
@@ -214,7 +214,7 @@ basicTypeNames[] = {
 
 typedef
 boost::python::object
-(*basicTypeLoader)( ULONG64 address, ULONG size );
+(*basicTypeLoader)( PVOID address, ULONG size );
     
 basicTypeLoader     basicTypeLoaders[] = {
     valueLoader<unsigned char>,
@@ -452,84 +452,6 @@ TypeInfo::setupBaseType()
 
 /////////////////////////////////////////////////////////////////////////////////
 
-/*
-TypeInfo::TypeInfo( const std::string  &moduleName, const std::string  &typeName )
-{
-
-}
-*/
-
-/////////////////////////////////////////////////////////////////////////////////
-
-/*
-TypeInfo::TypeInfo( const std::string  &moduleName, ULONG typeId )
-{
-    HRESULT      hres;
-
-    m_size = 0;
-    m_baseType = false;
-    m_pointer = false;
-    
-    try {
-
-        ULONG64     moduleBase = 0;
-        hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );
-        if ( FAILED( hres ) )
-            throw  DbgException( "IDebugSymbol::GetModuleByModuleName  failed" ); 
-
-        hres = dbgExt->symbols->GetTypeSize( moduleBase, typeId, &m_size );
-        if ( FAILED( hres ) )
-            throw DbgException( "IDebugSymbol::GetTypeSize failed" );
-            
-        for ( ULONG   i = 0; ; ++i )
-        {
-            char   fieldName[100];
-            hres = dbgExt->symbols2->GetFieldName( moduleBase, typeId, i, fieldName, sizeof(fieldName), NULL );
-            
-            if ( FAILED( hres ) )
-                break;  
-            
-            ULONG   fieldTypeId;
-            ULONG   fieldOffset;
-            hres = dbgExt->symbols3->GetFieldTypeAndOffset( moduleBase, typeId, fieldName, &fieldTypeId, &fieldOffset );
-
-            if ( FAILED( hres ) )
-                throw  DbgException( "IDebugSymbol3::GetFieldTypeAndOffset  failed" ); 
-
-            ULONG   fieldSize;                
-            hres = dbgExt->symbols->GetTypeSize( moduleBase, fieldTypeId, &fieldSize );
-            if ( FAILED( hres ) )
-                throw DbgException( "IDebugSymbol::GetTypeSize failed" );
-
-            char    fieldTypeName[100];
-            hres = dbgExt->symbols->GetTypeName( moduleBase, fieldTypeId, fieldTypeName, sizeof(fieldTypeName), NULL );
-
-            std::string     fieldTypeNameStr( fieldTypeName );
-            if ( fieldTypeNameStr == "__unnamed" 
-             ||  fieldTypeNameStr.find("<unnamed-tag>") < fieldTypeNameStr.size() )
-            {
-                m_fields.push_back( TypeField( fieldName, TypeInfo( moduleName, fieldTypeId ), fieldSize, fieldOffset ) );
-            }
-            else
-            {
-                m_fields.push_back( TypeField( fieldName, get(moduleName, fieldTypeName), fieldSize, fieldOffset ) );
-            }                
-       }
-    }
-    catch( std::exception  &e )
-    {
-        dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
-    }
-    catch(...)
-    {
-        dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
-    }
-}
-
-*/
-
-/////////////////////////////////////////////////////////////////////////////////
-
 boost::python::object
 TypeInfo::build( ULONG offset /* = 0 */ ) const
 {
@@ -566,18 +488,29 @@ TypeInfo::build( ULONG offset /* = 0 */ ) const
 /////////////////////////////////////////////////////////////////////////////////
 
 boost::python::object
-TypeInfo::load( ULONG64 addr, ULONG offset /* = 0 */ ) const
+TypeInfo::load( ULONG64 targetAddr, PVOID cacheBuffer , ULONG offset /* = 0 */ ) const
 {
-    if ( !isOffsetValid( addr) )
+    if ( !isOffsetValid( targetAddr) )
         return boost::python::object();
-
+        
+    boost::scoped_array<char>       rawBuffer;    
+        
+    if ( cacheBuffer == NULL )
+    {
+        rawBuffer.reset( new char[ m_size ] );
+        cacheBuffer = rawBuffer.get();
+        
+        if ( !loadMemory( targetAddr, cacheBuffer, m_size ) )
+            return boost::python::object();
+    }           
+    
     if ( m_pointer )
-        return ptrLoader( addr );
-
+        return ptrLoader( (PVOID)( (ULONG_PTR)cacheBuffer + offset ) );
+        
     if ( m_baseType )
-        return loadBaseType( addr );
+        return loadBaseType( (PVOID)( (ULONG_PTR)cacheBuffer + offset ) );   
 
-    boost::shared_ptr<typedVarClass>    ptr( new typedVarClass( *this, offset, addr ) );
+    boost::shared_ptr<typedVarClass>    ptr( new typedVarClass( *this, offset, targetAddr ) );
     boost::python::object               var( ptr );
     ptr->setPyObj( var );
 
@@ -588,7 +521,7 @@ TypeInfo::load( ULONG64 addr, ULONG offset /* = 0 */ ) const
         if ( field->size == field->type.size() )
         {
             var.attr( field->name.c_str() ) = 
-                field->type.load( addr + field->offset, offset + field->offset );
+                field->type.load( targetAddr + field->offset, cacheBuffer, offset + field->offset );
         }
         else
         {
@@ -597,7 +530,7 @@ TypeInfo::load( ULONG64 addr, ULONG offset /* = 0 */ ) const
             for ( unsigned int i = 0; i < field->size / field->type.size(); ++i )
             {
                 const ULONG locOffset = field->offset + i * (ULONG)field->type.size();
-                arr.append( field->type.load( addr + locOffset, offset + locOffset ) );
+                arr.append( field->type.load( targetAddr + locOffset, cacheBuffer, offset + locOffset ) );
             }
 
             var.attr( field->name.c_str() ) = arr;
@@ -633,7 +566,7 @@ isBaseType( const std::string  &typeName )
 /////////////////////////////////////////////////////////////////////////////////
 
 boost::python::object
-TypeInfo::loadBaseType( ULONG64 address ) const
+TypeInfo::loadBaseType( PVOID address ) const
 {
    for ( int i = 0; i < sizeof( basicTypeNames ) / sizeof( char* ); ++i )
    {
@@ -657,15 +590,18 @@ TypeInfo::loadBaseType( ULONG64 address ) const
 
 template< typename valType>
 boost::python::object
-valueLoader( ULONG64 address, ULONG size )
+valueLoader( PVOID address, ULONG size )
 {
     if ( size == sizeof(valType) )
     {
-        valType     v = 0;          
-        if ( loadMemory( address, &v, sizeof(v) ) )
-        {
-            return boost::python::long_( (unsigned __int64)v );
-        }            
+        valType     v = *(valType*)address;
+        return boost::python::long_( (unsigned __int64)v );
+        
+        
+        //if ( loadMemory( address, &v, sizeof(v) ) )
+        //{
+        //    return boost::python::long_( (unsigned __int64)v );
+        //}            
     }
     else
     {    
@@ -673,9 +609,8 @@ valueLoader( ULONG64 address, ULONG size )
 
         for ( unsigned int i = 0; i < size / sizeof(valType); ++i )
         {
-            valType  v = 0;
-            if ( !loadMemory( address + i * sizeof(valType), &v, sizeof(v) ) )
-                    return boost::python::object();
+            valType  v = *( (valType*)address + i );
+            //if ( !loadMemory( address + i * sizeof(valType), &v, sizeof(v) ) )
 
             arr[i] = boost::python::long_( (unsigned __int64)v );    
         }
diff --git a/pykd/dbgtype.h b/pykd/dbgtype.h
index 62328c7..26e424d 100644
--- a/pykd/dbgtype.h
+++ b/pykd/dbgtype.h
@@ -5,6 +5,7 @@
 #include <list>
 
 #include "dbgmem.h"
+#include "dbgsystem.h"
 
 /////////////////////////////////////////////////////////////////////////////////
 
@@ -92,13 +93,8 @@ public:
         m_typeName( typeName )
         {}  
             
-
-/*    TypeInfo( const std::string  &moduleName, const std::string  &typeName );
-    
-    TypeInfo( const std::string  &moduleName, ULONG typeId );   */ 
-
     boost::python::object
-    load( ULONG64 addr, ULONG offset = 0 ) const;
+    load( ULONG64 targetAddr, PVOID cacheBuffer = NULL, ULONG offset = 0 ) const;
 
     boost::python::object
     build( ULONG offset = 0 ) const;
@@ -138,11 +134,14 @@ private:
     static TypeInfoMap                          g_typeInfoCache; 
 
     boost::python::object
-    loadBaseType( ULONG64 addr ) const;
+    loadBaseType( PVOID addr ) const;
 
     boost::python::object
-    ptrLoader( ULONG64 addr ) const  {
-        return boost::python::object( loadPtrByPtr( addr ) );
+    ptrLoader( PVOID addr ) const  {
+        if ( is64bitSystem() )
+            return boost::python::object( *(PULONG64)addr );
+        else
+            return boost::python::object( addr64( *(PULONG)addr ) );
     }
 
     void