You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2006/11/25 00:34:35 UTC

svn commit: r479048 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier: Graph.cpp Verifier.cpp ver_real.h

Author: gshimansky
Date: Fri Nov 24 15:34:29 2006
New Revision: 479048

URL: http://svn.apache.org/viewvc?view=rev&rev=479048
Log:
Applied HARMONY-1943 [drlvm][verifier] Parser jsr and ret instruction for verifier

Test passed on windowsXP, Ubuntu, Gentoo, SuSE 10 x86_64


Modified:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Verifier.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp?view=diff&rev=479048&r1=479047&r2=479048
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Graph.cpp Fri Nov 24 15:34:29 2006
@@ -66,17 +66,12 @@
  */
 vf_Graph::vf_Graph( unsigned node,      // number of nodes
                     unsigned edge)      // number of edges
+                    : m_nodes(NULL), m_edges(NULL), m_enum(NULL), m_nodenum(0),
+                    m_edgenum(1), m_enummax(0), m_enumcount(0), m_free(true)
 {
-    m_local = 0;
-    m_free = true;
     m_pool = vf_create_pool();
-    m_node = (vf_Node_t*)vf_alloc_pool_memory( m_pool, node * sizeof(vf_Node_t) );
-    m_nodenum = node;
-    m_edge = (vf_Edge_t*)vf_alloc_pool_memory( m_pool, edge * sizeof(vf_Edge_t) );
-    m_edgenum = 0;
-    m_edgemem = edge;
-    m_enum = (unsigned*)vf_alloc_pool_memory( m_pool, m_nodenum * sizeof(unsigned) );
-    m_enumcount = 0;
+    CreateNodes( node );
+    CreateEdges( edge );
     return;
 } // vf_Graph::vf_Graph
 
@@ -86,17 +81,12 @@
 vf_Graph::vf_Graph( unsigned node,          // number of nodes
                     unsigned edge,          // number of edges
                     vf_VerifyPool_t *pool)  // external pool
+                    : m_nodes(NULL), m_edges(NULL), m_pool(pool), m_enum(NULL),
+                    m_nodenum(0), m_edgenum(1), m_enummax(0), m_enumcount(0),
+                    m_free(false)
 {
-    m_local = 0;
-    m_free = false;
-    m_pool = pool;
-    m_node = (vf_Node_t*)vf_alloc_pool_memory( m_pool, node * sizeof(vf_Node_t) );
-    m_nodenum = node;
-    m_edge = (vf_Edge_t*)vf_alloc_pool_memory( m_pool, edge * sizeof(vf_Edge_t) );
-    m_edgenum = 0;
-    m_edgemem = edge;
-    m_enum = (unsigned*)vf_alloc_pool_memory( m_pool, m_nodenum * sizeof(unsigned) );
-    m_enumcount = 0;
+    CreateNodes( node );
+    CreateEdges( edge );
     return;
 } // vf_Graph::vf_Graph
 
@@ -117,12 +107,75 @@
 void
 vf_Graph::CreateNodes( unsigned number )    // number of nodes
 {
-    m_node = (vf_Node_t*)vf_alloc_pool_memory( m_pool, number * sizeof(vf_Node_t) );
-    m_nodenum = number;
+    assert(number > 0);
+    vf_NodeContainer_t* nodes;
+    nodes = (vf_NodeContainer_t*)AllocMemory( sizeof(vf_NodeContainer_t)
+            + (number - 1) * sizeof(vf_Node_t) );
+    nodes->m_max = number;
+    if( m_nodes == NULL ) {
+        m_nodes = nodes;
+    } else {
+        vf_NodeContainer_t *index = m_nodes->m_next;
+        while( index->m_next ) {
+            index = index->m_next;
+        }
+        index->m_next = nodes;
+    }
     return;
 } // vf_Graph::CreateNodes
 
 /**
+ * Gets graph node.
+ */
+vf_Node_t*
+vf_Graph::GetNode( unsigned node_num )  // graph node number
+{
+    // get node
+    assert( m_nodes );
+    assert( node_num < m_nodenum );
+    unsigned count = node_num;
+    vf_NodeContainer_t* nodes = m_nodes;
+    while( count > nodes->m_max ) {
+        count -= nodes->m_max;
+        nodes = nodes->m_next;
+        assert(nodes);
+    }
+    return &nodes->m_node[count];
+} // vf_Graph::GetNode
+
+/**
+ * Creates a new node and sets data to it.
+ */
+void
+vf_Graph::NewNode( unsigned begin,      // begin code instruction of node
+                   unsigned end,        // end code instruction of node
+                   unsigned len)        // bytecode length of node
+{
+    // get node
+    assert( m_nodes );
+    unsigned count = m_nodenum;
+    vf_NodeContainer_t* nodes = m_nodes;
+    while( count > nodes->m_max ) {
+        count -= nodes->m_max;
+        nodes = nodes->m_next;
+        assert(nodes);
+    }
+
+    // set node
+    vf_Node_t* node = &nodes->m_node[count];
+    node->m_start = begin;
+    node->m_end = end;
+    node->m_len = len;
+
+    // increment nodes count
+    m_nodenum++;
+    nodes->m_used++;
+    assert( nodes->m_used <= nodes->m_max );
+
+    return;
+} // vf_Graph::NewNode
+
+/**
  * Function set data to graph node.
  */
 void
@@ -131,38 +184,76 @@
                    unsigned end,        // end code instruction of node
                    unsigned len)        // bytecode length of node
 {
-    // check node number is in range.
-    assert( num < m_nodenum );
-    m_node[num].m_start = begin;
-    m_node[num].m_end = end;
-    m_node[num].m_len = len;
+    vf_Node_t* node = GetNode( num );
+    node->m_start = begin;
+    node->m_end = end;
+    node->m_len = len;
     return;
 } // vf_Graph::SetNode
 
 /**
- * Function set new edge for graph nodes.
+ * Gets graph edge.
+ */
+vf_Edge_t*
+vf_Graph::GetEdge( unsigned edge_num )  // graph edge number
+{
+    // get edge
+    assert( m_edges );
+    assert( edge_num < m_edgenum );
+    assert( edge_num );             // zero edge is reserved
+    unsigned count = edge_num;
+    vf_EdgeContainer_t* edges = m_edges;
+    while( count > edges->m_max ) {
+        count -= edges->m_max;
+        edges = edges->m_next;
+        assert(edges);
+    }
+    return &edges->m_edge[count];
+} // vf_Graph::GetEdge
+
+/**
+ * Creates a new edge for graph nodes.
  */
 void
-vf_Graph::SetNewEdge( unsigned start,   // start graph node of edge
-                      unsigned end)     // end graph node of edge
+vf_Graph::NewEdge( unsigned start,   // start graph node of edge
+                   unsigned end)     // end graph node of edge
 {
-    // check edges pool
-    assert( m_edgenum < m_edgemem );
-    // check node numbers are in range.
+    // check node numbers are in range
     assert( start < m_nodenum );
     assert( end < m_nodenum );
-    // set new edge
-    vf_Edge_t *edge = &m_edge[m_edgenum++];     // zero edge is reserved
+
+    // get edge
+    assert( m_edges );
+    unsigned count = m_edgenum;
+    vf_EdgeContainer_t* edges = m_edges;
+    while( count > edges->m_max ) {
+        count -= edges->m_max;
+        edges = edges->m_next;
+        assert(edges);
+    }
+
+    // get a new edge and edge's nodes
+    vf_Edge_t *edge = &edges->m_edge[count];
+    vf_Node_t *node_start = GetNode( start );
+    vf_Node_t *node_end = GetNode( end );
+
+    // set a new edge
     edge->m_start = start;
     edge->m_end = end;
-    edge->m_outnext = m_node[start].m_outedge;
-    m_node[start].m_outedge = m_edgenum;        // zero edge is reserved
-    m_node[start].m_outnum++;
-    edge->m_innext = m_node[end].m_inedge;
-    m_node[end].m_inedge = m_edgenum;           // zero edge is reserved
-    m_node[end].m_innum++;
+    edge->m_outnext = node_start->m_outedge;
+    node_start->m_outedge = m_edgenum;
+    node_start->m_outnum++;
+    edge->m_innext = node_end->m_inedge;
+    node_end->m_inedge = m_edgenum;
+    node_end->m_innum++;
+
+    // increment edge count
+    m_edgenum++;
+    edges->m_used++;
+    assert( edges->m_used <= edges->m_max );
+
     return;
-} // vf_Graph::SetNewEdge
+} // vf_Graph::NewEdge
 
 /**
  * Function receive first code instruction of graph node.
@@ -172,7 +263,7 @@
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    return m_node[num].m_start;
+    return GetNode( num )->m_start;
 } // vf_Graph::GetNodeFirstInstr
 
 /**
@@ -183,18 +274,18 @@
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    return m_node[num].m_end;
+    return GetNode( num )->m_end;
 } // vf_Graph::GetNodeLastInstr
 
 /**
  * Function receive bytecode length of graph node instructions.
  */
-unsigned
+inline unsigned
 vf_Graph::GetNodeByteCodeLen( unsigned num )    // graph node number
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    return m_node[num].m_len;
+    return GetNode( num )->m_len;
 } // vf_Graph::GetNodeByteCodeLen
 
 /**
@@ -205,19 +296,19 @@
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    return m_node[num].m_stack;
+    return GetNode( num )->m_stack;
 } // vf_Graph::GetNodeStackModifier
 
 /**
  * Function sets graph node stack modifier.
  */
-void
+inline void
 vf_Graph::SetNodeStackModifier( unsigned num,   // graph node number
                                 int stack)      // stack deep modifier
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    m_node[num].m_stack = stack;
+    GetNode( num )->m_stack = stack;
     return;
 } // vf_Graph::SetNodeStackModifier
 
@@ -239,7 +330,7 @@
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    m_node[num].m_mark = mark;
+    GetNode( num )->m_mark = mark;
     return;
 } // vf_Graph::SetNodeMark
 
@@ -251,18 +342,18 @@
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    return m_node[num].m_mark;
+    return GetNode( num )->m_mark;
 } // vf_Graph::GetNodeMark
 
 /**
  * Function checks if node is marked.
  */
-bool
+inline bool
 vf_Graph::IsNodeMarked( unsigned num )  // graph node number
 {
     // check node number is in range.
     assert( num < m_nodenum );
-    return (m_node[num].m_mark != 0);
+    return (GetNode( num )->m_mark != 0);
 } // vf_Graph::IsNodeMarked
 
 /**
@@ -272,13 +363,39 @@
 vf_Graph::CleanNodesMark()
 {
     // clean node's mark
-    for( unsigned index = 0; index < m_nodenum; index++ ) {
-        m_node[index].m_mark = 0;
+    assert( m_nodes );
+    vf_NodeContainer_t* nodes = m_nodes;
+    while( nodes != NULL ) {
+        for( unsigned index = 0; index < nodes->m_used; index++ ) {
+            nodes->m_node[index].m_mark = 0;
+        }
+        nodes = nodes->m_next;
     }
     return;
 } // vf_Graph::CleanNodesMark
 
 /**
+ * Function receives IN data flow vector of node.
+ */
+vf_MapVector_t *
+vf_Graph::GetNodeInVector( unsigned node_num )      // graph node number
+{
+    assert( node_num < m_nodenum );
+    return &(GetNode( node_num )->m_invector);
+} // vf_Graph::GetNodeInVector
+
+/**
+ * Function receives OUT data flow vector of node.
+ */
+vf_MapVector_t *
+vf_Graph::GetNodeOutVector( unsigned node_num )     // graph node number
+{
+    assert( node_num <= m_nodenum );
+    return &(GetNode( node_num )->m_outvector);
+} // vf_Graph::GetNodeOutVector
+
+
+/**
  * Function creates IN data flow vector of node.
  */
 void
@@ -288,18 +405,18 @@
 {
     assert( example );
     assert( node_num < m_nodenum );
-    vf_MapVector_t *vector = &m_node[node_num].m_invector;
+    vf_MapVector_t *vector = GetNodeInVector( node_num );
     // create and set local vector
     if( example->m_maxlocal ) {
-        vector->m_local = (vf_MapEntry_t*)vf_alloc_pool_memory( m_pool, 
-                 example->m_maxlocal * sizeof(vf_MapEntry_t) );
+        vector->m_local = (vf_MapEntry_t*)AllocMemory(example->m_maxlocal
+                                * sizeof(vf_MapEntry_t) );
         vector->m_number = example->m_number;
         vector->m_maxlocal = example->m_maxlocal;
     }
     // create and set stack vector
     if( example->m_maxstack ) {
-        vector->m_stack = (vf_MapEntry_t*)vf_alloc_pool_memory( m_pool, 
-                 example->m_maxstack * sizeof(vf_MapEntry_t) );
+        vector->m_stack = (vf_MapEntry_t*)AllocMemory( example->m_maxstack
+                                * sizeof(vf_MapEntry_t) );
         vector->m_deep = example->m_deep;
         vector->m_maxstack = example->m_maxstack;
     }
@@ -325,18 +442,18 @@
 {
     assert( example );
     assert( node_num < m_nodenum );
-    vf_MapVector_t *vector = &m_node[node_num].m_outvector;
+    vf_MapVector_t *vector = GetNodeOutVector( node_num );
     // create and set local vector
     if( example->m_maxlocal ) {
-        vector->m_local = (vf_MapEntry_t*)vf_alloc_pool_memory( m_pool, 
-                 example->m_maxlocal * sizeof(vf_MapEntry_t) );
+        vector->m_local = (vf_MapEntry_t*)AllocMemory( example->m_maxlocal
+                                    * sizeof(vf_MapEntry_t) );
         vector->m_number = example->m_number;
         vector->m_maxlocal = example->m_maxlocal;
     }
     // create and set stack vector
     if( example->m_maxstack ) {
-        vector->m_stack = (vf_MapEntry_t*)vf_alloc_pool_memory( m_pool, 
-                 example->m_maxstack * sizeof(vf_MapEntry_t) );
+        vector->m_stack = (vf_MapEntry_t*)AllocMemory( example->m_maxstack
+                                    * sizeof(vf_MapEntry_t) );
         vector->m_deep = example->m_deep;
         vector->m_maxstack = example->m_maxstack;
     }
@@ -353,33 +470,25 @@
 } // vf_Graph::SetNodeOutVector
 
 /**
- * Function receives IN data flow vector of node.
- */
-vf_MapVector_t *
-vf_Graph::GetNodeInVector( unsigned node_num )      // graph node number
-{
-    assert( node_num < m_nodenum );
-    return &m_node[node_num].m_invector;
-} // vf_Graph::GetNodeInVector
-
-/**
- * Function receives OUT data flow vector of node.
- */
-vf_MapVector_t *
-vf_Graph::GetNodeOutVector( unsigned node_num )     // graph node number
-{
-    assert( node_num <= m_nodenum );
-    return &m_node[node_num].m_outvector;
-} // vf_Graph::GetNodeOutVector
-
-/**
  * Function creates graph edges.
  */
 void
 vf_Graph::CreateEdges( unsigned number )        // number of edges
 {
-    m_edge = (vf_Edge_t*)vf_alloc_pool_memory( m_pool, number * sizeof(vf_Edge_t) );
-    m_edgemem = number;
+    assert(number > 0);
+    vf_EdgeContainer_t* edges;
+    edges = (vf_EdgeContainer_t*)AllocMemory( sizeof(vf_EdgeContainer_t)
+                    + number * sizeof(vf_Edge_t) );
+    edges->m_max = number + 1;  // zero edge is reserved
+    if( m_edges == NULL ) {
+        m_edges = edges;
+    } else {
+        vf_EdgeContainer_t *index = m_edges->m_next;
+        while( index->m_next ) {
+            index = index->m_next;
+        }
+        index->m_next = edges;
+    }
     return;
 } // vf_Graph::CreateEdges
 
@@ -390,8 +499,8 @@
 vf_Graph::GetEdgeNextInEdge( unsigned num )     // graph node number
 {
     // zero edge is reserved
-    assert( num && num <= m_edgenum );
-    return m_edge[num - 1].m_innext;
+    assert( num && num < m_edgenum );
+    return GetEdge( num )->m_innext;
 } // vf_Graph::GetEdgeNextInEdge
 
 /**
@@ -401,8 +510,8 @@
 vf_Graph::GetEdgeNextOutEdge( unsigned num )    // graph node number
 {
     // zero edge is reserved
-    assert( num && num <= m_edgenum );
-    return m_edge[num - 1].m_outnext;
+    assert( num && num < m_edgenum );
+    return GetEdge( num )->m_outnext;
 } // vf_Graph::GetEdgeNextOutEdge
 
 /**
@@ -412,8 +521,8 @@
 vf_Graph::GetEdgeStartNode( unsigned num )      // graph node number
 {
     // zero edge is reserved
-    assert( num && num <= m_edgenum );
-    return m_edge[num - 1].m_start;
+    assert( num && num < m_edgenum );
+    return GetEdge( num )->m_start;
 } // vf_Graph::GetEdgeStartNode
 
 /**
@@ -423,8 +532,8 @@
 vf_Graph::GetEdgeEndNode( unsigned num )        // graph node number
 {
     // zero edge is reserved
-    assert( num && num <= m_edgenum );
-    return m_edge[num - 1].m_end;
+    assert( num && num < m_edgenum );
+    return GetEdge( num )->m_end;
 } // vf_Graph::GetEdgeStartNode
 
 /**
@@ -434,7 +543,7 @@
 vf_Graph::GetNodeInEdgeNumber( unsigned num )   // graph node number
 {
     assert( num < m_nodenum );
-    return m_node[num].m_innum;
+    return GetNode( num )->m_innum;
 } // vf_Graph::GetNodeInEdgeNumber
 
 /**
@@ -444,7 +553,7 @@
 vf_Graph::GetNodeOutEdgeNumber( unsigned num )  // graph node number
 {
     assert( num < m_nodenum );
-    return m_node[num].m_outnum;
+    return GetNode( num )->m_outnum;
 } // vf_Graph::GetNodeOutEdgeNumber
 
 /**
@@ -454,7 +563,7 @@
 vf_Graph::GetNodeFirstInEdge( unsigned num )    // graph node number
 {
     assert( num < m_nodenum );
-    return m_node[num].m_inedge;
+    return GetNode( num )->m_inedge;
 } // vf_Graph::GetNodeFirstInEdge
 
 /**
@@ -464,7 +573,7 @@
 vf_Graph::GetNodeFirstOutEdge( unsigned num )   // graph node number
 {
     assert( num < m_nodenum );
-    return m_node[num].m_outedge;
+    return GetNode( num )->m_outedge;
 } // vf_Graph::GetNodeFirstOutEdge
 
 /**
@@ -485,21 +594,33 @@
 void
 vf_Graph::SetStartCountNode( unsigned node_num )     // graph node number
 {
-    // check node number is in range.
+    // check node number is in range
+    assert( m_nodes );
     assert( node_num < m_nodenum );
- 
+
+    // create memory
+    if( m_enummax < m_nodenum ) {
+        m_enum = (unsigned*)AllocMemory( sizeof(unsigned) * m_nodenum );
+    }
+
     // clean node enumeration
-    for( unsigned index = 0; index < m_nodenum; index++ ) {
-        m_node[index].m_nodecount = ~0U;
-        m_enum[index] = ~0U;
+    vf_NodeContainer_t* nodes = m_nodes;
+    unsigned count = 0;
+    while( nodes != NULL ) {
+        for( unsigned index = 0; index < nodes->m_used; index++, count++ ) {
+            nodes->m_node[index].m_nodecount = ~0U;
+            m_enum[count] = ~0U;
+        }
+        nodes = nodes->m_next;
     }
+    assert( count == m_nodenum );
 
     // set enumeration first element;
     m_enum[0] = node_num;
     m_enumcount = 1;
 
     // set node enumeration number
-    m_node[node_num].m_nodecount = 0;
+    GetNode( node_num )->m_nodecount = 0;
     return;
 } // vf_Graph::SetStartCountNode
 
@@ -526,7 +647,7 @@
     m_enum[m_enumcount] = node_num;
 
     // set node enumeration number and increase number of enumerated nodes
-    m_node[node_num].m_nodecount = m_enumcount++;
+    GetNode( node_num )->m_nodecount = m_enumcount++;
     return;
 } // vf_Graph::SetNextCountNode
 
@@ -559,7 +680,7 @@
 {
     // check node number is in range.
     assert( node_num < m_nodenum );
-    return m_node[node_num].m_nodecount;
+    return GetNode( node_num )->m_nodecount;
 } // vf_Graph::GetNodeCountElement
 
 /************************************************************
@@ -596,24 +717,24 @@
     vf_Edge_t *edge;
 
     // print node incoming edges
-    for( index = 0, edge = &m_edge[m_node[num].m_inedge - 1];
-        index < m_node[num].m_innum;
-        index++, edge = &m_edge[edge->m_innext - 1] )
+    for( index = 0, edge = GetEdge( GetNode( num )->m_inedge );
+        index < GetNode( num )->m_innum;
+        index++, edge = GetEdge( edge->m_innext ) )
     {
         VERIFY_DEBUG( " [" << edge->m_start << "] -->" );
     }
 
     // print node
-    if( vf_is_instruction_has_flags( &ctex->m_code[m_node[num].m_start],
+    if( vf_is_instruction_has_flags( &ctex->m_code[GetNode( num )->m_start],
                                      VF_FLAG_START_ENTRY ) )
     { // start node
-        VERIFY_DEBUG( "node[" << num << "]: " << m_node[num].m_start << "[-] start" );
-    } else if( vf_is_instruction_has_flags( &ctex->m_code[m_node[num].m_start],
+        VERIFY_DEBUG( "node[" << num << "]: " << GetNode( num )->m_start << "[-] start" );
+    } else if( vf_is_instruction_has_flags( &ctex->m_code[GetNode( num )->m_start],
                                             VF_FLAG_END_ENTRY ) )
     { // end node
-        VERIFY_DEBUG( "node[" << num << "]: " << m_node[num].m_start << "[-] end" );
+        VERIFY_DEBUG( "node[" << num << "]: " << GetNode( num )->m_start << "[-] end" );
         VERIFY_DEBUG( "-- end --" );
-    } else if( vf_is_instruction_has_flags( &ctex->m_code[m_node[num].m_start],
+    } else if( vf_is_instruction_has_flags( &ctex->m_code[GetNode( num )->m_start],
                                             VF_FLAG_HANDLER ) )
     { // handler node
         VERIFY_DEBUG( "node[" << num << "]: " << num << "handler entry" );
@@ -622,9 +743,9 @@
     }
 
     // print node outcoming edges
-    for( index = 0, edge = &m_edge[m_node[num].m_outedge - 1];
-        index < m_node[num].m_outnum;
-        index++, edge = &m_edge[edge->m_outnext - 1] )
+    for( index = 0, edge = GetEdge( GetNode( num )->m_outedge );
+        index < GetNode( num )->m_outnum;
+        index++, edge = GetEdge( edge->m_outnext ) )
     {
         VERIFY_DEBUG( " --> [" << edge->m_end << "]" );
     }
@@ -643,11 +764,11 @@
 #if _VERIFY_DEBUG
     // print node header
     VERIFY_DEBUG( "Node #" << num );
-    VERIFY_DEBUG( "Stack mod: " << m_node[num].m_stack );
+    VERIFY_DEBUG( "Stack mod: " << GetNode( num )->m_stack );
 
     // get code instructions
-    unsigned count = m_node[num].m_end - m_node[num].m_start + 1;
-    vf_Code_t *instr = &( ctex->m_code[ m_node[num].m_start ] );
+    unsigned count = GetNode( num )->m_end - GetNode( num )->m_start + 1;
+    vf_Code_t *instr = &( ctex->m_code[ GetNode( num )->m_start ] );
 
     // print node instructions
     for( unsigned index = 0; index < count; index++, instr++ ) {
@@ -667,21 +788,18 @@
 {
 #if _VERIFY_DEBUG
     unsigned index;
-    char *pointer,
-         fname[1024];
 
     // get class and method name
     const char *class_name = class_get_name( ctex->m_class );
     const char *method_name = method_get_name( ctex->m_method );
+    const char *method_desc = method_get_descriptor( ctex->m_method );
 
     // create file name
-    if( !class_name || !method_name
-       || (strlen(class_name) + strlen(method_name) + 10 > 1024 ) )
-    {
-        return;
-    }
-    sprintf( fname, "%s_%s.dot", class_name, method_name );
-    pointer = fname;
+    unsigned len = strlen(class_name) + strlen(method_name)
+                        + strlen(method_desc) + 6;
+    char *fname = (char*)STD_ALLOCA(len);
+    sprintf( fname, "%s_%s%s.dot", class_name, method_name, method_desc );
+    char* pointer = fname;
     while( pointer != NULL ) {
         switch(*pointer)
         {
@@ -711,7 +829,7 @@
         vf_error();
     }
     // create name of graph
-    sprintf( fname, "%s::%s", class_name, method_name );
+    sprintf( fname, "%s::%s%s", class_name, method_name, method_desc );
 
     // print graph to file
     DumpDotHeader( fname, fout );
@@ -742,7 +860,6 @@
         << "nodesep=\".20\";" << endl
         << "page=\"8.5,11\";" << endl
         << "ratio=auto;" << endl
-        << "fontpath=\"c:\\winnt\\fonts\";" << endl
         << "node [color=lightblue2, style=filled, shape=record, "
                   << "fontname=\"Courier\", fontsize=9];" << endl
         << "label=\"" << graph_name << "\";" << endl;
@@ -763,19 +880,19 @@
     vf_Edge_t *edge;
 
     // print node to dot file
-    if( vf_is_instruction_has_flags( &ctex->m_code[m_node[num].m_start],
+    if( vf_is_instruction_has_flags( &ctex->m_code[GetNode( num )->m_start],
                                      VF_FLAG_START_ENTRY ) )
     { // start node
         out << "node" << num << " [label=\"START\", color=limegreen]" << endl;
-    } else if( vf_is_instruction_has_flags( &ctex->m_code[m_node[num].m_start],
+    } else if( vf_is_instruction_has_flags( &ctex->m_code[GetNode( num )->m_start],
                                             VF_FLAG_END_ENTRY ) )
     { // end node
         out << "node" << num << " [label=\"END\", color=orangered]" << endl;
-    } else if( vf_is_instruction_has_flags( &ctex->m_code[m_node[num].m_start],
+    } else if( vf_is_instruction_has_flags( &ctex->m_code[GetNode( num )->m_start],
                                             VF_FLAG_HANDLER ) )
     { // handler node
         out << "node" << num << " [label=\"Handler #"
-            << num << "\\n---------\\n" << "Type: #" << m_node[num].m_len
+            << num << "\\n---------\\n" << "Type: #" << GetNode( num )->m_len
             << "\", shape=ellipse, color=aquamarine]" << endl;
     } else { // another nodes
         out << "node" << num 
@@ -785,15 +902,20 @@
     }
 
     // print node outcoming edges to dot file
-    for( index = 0, edge = &m_edge[m_node[num].m_outedge - 1];
-            index < m_node[num].m_outnum;
-            index++, edge = &m_edge[edge->m_outnext - 1] )
+    for( index = 0, edge = GetEdge( GetNode( num )->m_outedge );
+            index < GetNode( num )->m_outnum;
+            index++, edge = GetEdge( edge->m_outnext ) )
     {
         out << "node" << num << " -> " << "node" << edge->m_end;
-        if( vf_is_instruction_has_flags( &ctex->m_code[m_node[edge->m_end].m_start],
+        if( vf_is_instruction_has_flags( &ctex->m_code[GetNode( edge->m_end )->m_start],
                                          VF_FLAG_HANDLER ) )
         {
             out << "[color=red]" << endl;
+        } else if( num + 1 != edge->m_end     // it's a subroutine call branch
+            && vf_is_instruction_has_flags( &ctex->m_code[GetNode( num )->m_end],
+                        VF_FLAG_SUBROUTINE ) )
+        {
+            out << "[color=blue]" << endl;
         }
         out << ";" << endl;
     }
@@ -814,11 +936,11 @@
 #if _VERIFY_DEBUG
     // print node header
     out << "Node " << num << next_node
-        << "Stack mod: " << m_node[num].m_stack << next_node;
+        << "Stack mod: " << GetNode( num )->m_stack << next_node;
 
     // get code instructions
-    unsigned count = m_node[num].m_end - m_node[num].m_start + 1;
-    vf_Code_t *instr = &( ctex->m_code[ m_node[num].m_start ] );
+    unsigned count = GetNode( num )->m_end - GetNode( num )->m_start + 1;
+    vf_Code_t *instr = &( ctex->m_code[ GetNode( num )->m_start ] );
 
     // print node instructions
     for( unsigned index = 0; index < count; index++, instr++ ) {
@@ -887,17 +1009,18 @@
     code2node = (unsigned*)vf_alloc_pool_memory( ctex->m_pool, 
                             codeNum * sizeof(unsigned) );
     /** 
-     * Skip start-entry node and create handler nodes
+     * Create start-entry and handler nodes
      */
+    vGraph->NewNode( 0, 0, 0 );
     for( index = 1; index < handlcount + 1; index++ ) {
-        vGraph->SetNode( index, index, index, 0 );
+        vGraph->NewNode( index, index, 0 );
         vGraph->SetNodeStackModifier( index, 1 ); 
     }
 
     /**
-     * Fill nodes
-     * Node count consists of start-entry node and handler nodes
-     * Skip first instruction, because we create first node 
+     * Create nodes
+     * Node count begins from the first basic block after the last handler node.
+     * Skip the first instruction, because we create the first node
      * at his end instruction.
      */
     for( last = nodeCount = 1 + handlcount, index = last + 1;
@@ -907,7 +1030,7 @@
         if( vf_is_begin_basic_block( &code[index] ) ) {
             // set graph nodes
             len = code[index].m_addr - code[last].m_addr;
-            vGraph->SetNode( nodeCount, last, index - 1, len );
+            vGraph->NewNode( last, index - 1, len );
             vGraph->SetNodeStackModifier( nodeCount, 
                         vf_get_node_stack_deep( &code[last], &code[index - 1] ) );
             code2node[last] = nodeCount++;
@@ -916,12 +1039,12 @@
     }
     // set last node with code segment
     len = code_end - code[last].m_addr;
-    vGraph->SetNode( nodeCount, last, index - 1, len );
+    vGraph->NewNode( last, index - 1, len );
     vGraph->SetNodeStackModifier( nodeCount, 
         vf_get_node_stack_deep( &code[last], &code[index - 1] ) );
     code2node[last] = nodeCount++;
     // set exit node
-    vGraph->SetNode( nodeCount, codeNum - 1, 0, 0 );
+    vGraph->NewNode( codeNum - 1, 0, 0 );
     code2node[codeNum - 1] = nodeCount++;
     assert( ctex->m_nodeNum == nodeCount );
 
@@ -929,7 +1052,7 @@
      * Create edges
      * First edge from start-entry node to first code node
      */
-    vGraph->SetNewEdge( 0, handlcount + 1 );
+    vGraph->NewEdge( 0, handlcount + 1 );
     for( index = 1; index < nodeCount - 1; index++ ) {
         codeInstr = &code[ vGraph->GetNodeLastInstr( index ) ];
         // check correct branching
@@ -952,7 +1075,7 @@
                 }
 #endif // _VERIFY_DEBUG
                 node = code2node[ codeInstr->m_off[count] ];
-                vGraph->SetNewEdge( index, node );
+                vGraph->NewEdge( index, node );
             }
         } else {
             if( index + 1 == nodeCount - 1 ) {
@@ -964,14 +1087,14 @@
                 result = VER_ErrorBranch;
                 goto labelEnd_createGraph; 
             }
-            vGraph->SetNewEdge( index, index + 1 );
+            vGraph->NewEdge( index, index + 1 );
         }
         // set exception handler edges
         if( codeInstr->m_handler != NULL ) {
             for( count = 0; count < handlcount; count++ ) {
                 if( codeInstr->m_handler[count] ) {
                     // set edge to exception handler entry
-                    vGraph->SetNewEdge( index, count + 1 );
+                    vGraph->NewEdge( index, count + 1 );
                 }
             }
         }

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Verifier.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Verifier.cpp?view=diff&rev=479048&r1=479047&r2=479048
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Verifier.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/Verifier.cpp Fri Nov 24 15:34:29 2006
@@ -127,6 +127,9 @@
     result = vf_parse_bytecode( ctex );
     if( result != VER_OK ) {
         goto labelEnd_verifyClassBytecode;
+    } else if( ctex->m_dump.m_with_subroutine ) {
+        result = VER_NoSupportJSR;
+        goto labelEnd_verifyClassBytecode;
     }
     
     /**
@@ -400,11 +403,11 @@
  * Function returns recieved offset.
  */
 static inline int
-vf_get_double_branch_offset( vf_Instr_t *code,          // instruction
-                             unsigned code_pc,          // instruction offset in bytcode array
-                             unsigned char *bytecode,   // bytecode array
-                             unsigned *index_p,         // offset index in bytecode array
-                             vf_VerifyPool_t *pool)     // memory pool
+vf_get_double_hword_branch_offset( vf_Instr_t *code,          // instruction
+                                   unsigned code_pc,          // instruction offset in bytcode array
+                                   unsigned char *bytecode,   // bytecode array
+                                   unsigned *index_p,         // offset index in bytecode array
+                                   vf_VerifyPool_t *pool)     // memory pool
 {
     // get first branch offset
     int offset = vf_get_hword_offset( code_pc, bytecode, index_p );
@@ -415,7 +418,30 @@
     // set second edge branch for instruction
     vf_set_instruction_offset( code, 1, (*index_p) );
     return offset;
-} // vf_get_double_branch_offset
+} // vf_get_double_hword_branch_offset
+
+/**
+ * Function receives word (4 bytes) branch offset from bytecode array and
+ * sets reseived offset and next instruction offset into instruction.
+ * Function returns recieved offset.
+ */
+static inline int
+vf_get_double_word_branch_offset( vf_Instr_t *code,          // instruction
+                                  unsigned code_pc,          // instruction offset in bytcode array
+                                  unsigned char *bytecode,   // bytecode array
+                                  unsigned *index_p,         // offset index in bytecode array
+                                  vf_VerifyPool_t *pool)     // memory pool
+{
+    // get first branch offset
+    int offset = vf_get_word_offset( code_pc, bytecode, index_p );
+    // create and set edge branchs for instruction
+    vf_create_instruction_offset( code, 2, pool );
+    // set first edge branch for instruction
+    vf_set_instruction_offset( code, 0, offset );
+    // set second edge branch for instruction
+    vf_set_instruction_offset( code, 1, (*index_p) );
+    return offset;
+} // vf_get_double_word_branch_offset
 
 /**
  * Function receives tableswitch branch from bytecode array and
@@ -652,6 +678,19 @@
 } // vf_set_vector_stack_entry_ref
 
 /**
+ * Function sets return address data type for given stack map vector entry.
+ */
+static inline void
+vf_set_vector_stack_entry_addr( vf_MapEntry_t *vector,   // stack map vector
+                                unsigned num,            // vector entry number
+                                unsigned count)          // program count
+{
+    // set stack map vector entry by return address
+    vector[num].m_type = SM_RETURN_ADDR;
+    vector[num].m_pc = count;
+} // vf_set_vector_stack_entry_addr
+
+/**
  * Function sets signle word data type for given stack map vector entry.
  */
 static inline void
@@ -760,6 +799,22 @@
 } // vf_set_vector_local_var_ref
 
 /**
+ * Function sets return address data type for given local variable vector entry.
+ */
+static inline void
+vf_set_vector_local_var_addr( vf_MapEntry_t *vector,   // stack map vector
+                              unsigned num,            // vector entry number
+                              unsigned count,          // program count
+                              unsigned local)          // number of local variable
+{
+    // set local variable vector entry to return address
+    vector[num].m_type = SM_RETURN_ADDR;
+    vector[num].m_pc = count;
+    vector[num].m_is_local = true;
+    vector[num].m_local = (unsigned short)local;
+} // vf_set_vector_local_var_addr
+
+/**
  * Function sets a given data type for a given local variable vector entry.
  */
 static inline void
@@ -982,6 +1037,19 @@
 } // vf_set_in_vector_local_var_ref 
 
 /**
+ * Function sets return address data type for code instruction IN local variable vector entry.
+ */
+static inline void
+vf_set_in_vector_local_var_addr( vf_Code_t *code,                // code instruction
+                                 unsigned num,                   // IN vector entry number
+                                 unsigned count,                 // program count
+                                 unsigned local)                 // local variable number
+{
+    vf_set_vector_local_var_addr( code->m_invector, num, count, local );
+    return;
+} // vf_set_in_vector_local_var_addr
+
+/**
  * Function sets a given data type for code instruction IN local variable vector entry.
  */
 static inline void UNUSED
@@ -1130,6 +1198,18 @@
 } // vf_set_out_vector_stack_entry_ref
 
 /**
+ * Function sets return adress data type for code instruction OUT stack map vector entry.
+ */
+static inline void
+vf_set_out_vector_stack_entry_addr( vf_Code_t *code,          // code instruction
+                                    unsigned num,             // OUT vector entry number
+                                    unsigned count)           // program coint
+{
+    vf_set_vector_stack_entry_addr( code->m_outvector, num, count );
+    return;
+} // vf_set_out_vector_stack_entry_addr
+
+/**
  * Function sets int data type for code instruction OUT local variable vector entry.
  */
 static inline void
@@ -4087,21 +4167,36 @@
 } // vf_opcode_ifxnull
 
 /**
- * Function sets code instruction structure for opcode goto.
+ * Function sets code instruction structure for opcodes jsr and jsr_w.
  */
-static inline void UNUSED
-vf_opcode_goto( vf_Code_t *code,            // code instruction
-                vf_VerifyPool_t * pool)     // memory pool
+static inline void
+vf_opcode_jsr( vf_Code_t *code,            // code instruction
+               unsigned code_num,          // program count of instruction
+               vf_VerifyPool_t *pool)      // memory pool
 {
+    // set instruction flag
+    vf_set_instruction_flag( code, VF_FLAG_SUBROUTINE );
     // set stack modifier for instruction
-    vf_set_stack_modifier( code, -1 );
-    // set minimal stack for instruction
-    vf_set_min_stack( code, 1 );
+    vf_set_stack_modifier( code, 1 );
+    // create out vector
+    vf_new_out_vector( code, 1, pool );
+    vf_set_out_vector_stack_entry_addr( code, 0, code_num );
+    return;
+} // vf_opcode_jsr
+
+/**
+ * Function sets code instruction structure for opcode ret.
+ */
+static inline void
+vf_opcode_ret( vf_Code_t *code,              // code instruction
+               unsigned local,               // local variable number
+               vf_VerifyPool_t * pool)       // memory pool
+{
     // create in vector
     vf_new_in_vector( code, 1, pool );
-    vf_set_in_vector_stack_entry_int( code, 0 );
+    vf_set_in_vector_local_var_addr( code, 0, 0, local );
     return;
-} // vf_opcode_goto
+} // vf_opcode_ret
 
 /**
  * Function sets code instruction structure for end-entry.
@@ -4654,7 +4749,7 @@
         case OPCODE_IFGE:           /* 0x9c + s2 */
         case OPCODE_IFGT:           /* 0x9d + s2 */
         case OPCODE_IFLE:           /* 0x9e + s2 */
-            offset = vf_get_double_branch_offset( &codeInstr[instr], 
+            offset = vf_get_double_hword_branch_offset( &codeInstr[instr],
                             instr, bytecode, &index, pool );
             result = vf_check_branch_offset( offset, len, ctex );
             if( result != VER_OK ) {
@@ -4673,7 +4768,7 @@
         case OPCODE_IF_ICMPGE:      /* 0xa2 + s2 */
         case OPCODE_IF_ICMPGT:      /* 0xa3 + s2 */
         case OPCODE_IF_ICMPLE:      /* 0xa4 + s2 */
-            offset = vf_get_double_branch_offset( &codeInstr[instr], 
+            offset = vf_get_double_hword_branch_offset( &codeInstr[instr],
                             instr, bytecode, &index, pool );
             result = vf_check_branch_offset( offset, len, ctex );
             if( result != VER_OK ) {
@@ -4688,7 +4783,7 @@
             break;
         case OPCODE_IF_ACMPEQ:      /* 0xa5 + s2 */
         case OPCODE_IF_ACMPNE:      /* 0xa6 + s2 */
-            offset = vf_get_double_branch_offset( &codeInstr[instr], 
+            offset = vf_get_double_hword_branch_offset( &codeInstr[instr],
                             instr, bytecode, &index, pool );
             result = vf_check_branch_offset( offset, len, ctex );
             if( result != VER_OK ) {
@@ -4714,15 +4809,34 @@
             }
             break;
         case OPCODE_JSR:            /* 0xa8 + s2 */
-            // FIXME - JSR instruction doesn't support in current version
-            result = VER_NoSupportJSR;
-            goto labelEnd_vf_parse_bytecode;
-            //break; // remark #111: statement is unreachable
+            offset = vf_get_double_hword_branch_offset( &codeInstr[instr],
+                            instr, bytecode, &index, pool );
+            result = vf_check_branch_offset( offset, len, ctex );
+            if( result != VER_OK ) {
+                goto labelEnd_vf_parse_bytecode;
+            }
+            result = vf_check_branch_offset( index, len, ctex );
+            if( result != VER_OK ) {
+                goto labelEnd_vf_parse_bytecode;
+            }
+            vf_opcode_jsr( code, codeNum, pool );
+            ctex->m_dump.m_with_subroutine = 1;
+            vf_set_basic_block_flag( &codeInstr[offset] );
+            vf_set_basic_block_flag( &codeInstr[index] );
+            break;
         case OPCODE_RET:            /* 0xa9 + u1|u2  */
-            // FIXME - RET instruction doesn't support in current version
-            result = VER_NoSupportJSR;
-            goto labelEnd_vf_parse_bytecode;
-            // break; // remark #111: statement is unreachable
+            local = (unsigned short)vf_get_local_var_number( code, bytecode, &index );
+            result = vf_check_local_var_number( local, locals, ctex );
+            if( result != VER_OK ) {
+                goto labelEnd_vf_parse_bytecode;
+            }
+            vf_opcode_ret( code, local, pool );
+            // create and set edge branch to exit
+            vf_set_single_instruction_offset( &codeInstr[instr], ~0U, pool );
+            if( index < len ) {
+                vf_set_basic_block_flag( &codeInstr[index] );
+            }
+            break;
         case OPCODE_TABLESWITCH:    /* 0xaa + pad + s4 * (3 + N) */
             vf_opcode_switch( code, pool );
             branches = vf_set_tableswitch_offsets( &codeInstr[instr],
@@ -4985,7 +5099,7 @@
             break;
         case OPCODE_IFNULL:         /* 0xc6 + s2 */
         case OPCODE_IFNONNULL:      /* 0xc7 + s2 */
-            offset = vf_get_double_branch_offset( &codeInstr[instr], 
+            offset = vf_get_double_hword_branch_offset( &codeInstr[instr],
                             instr, bytecode, &index, pool );
             result = vf_check_branch_offset( offset, len, ctex );
             if( result != VER_OK ) {
@@ -5011,10 +5125,21 @@
             }
             break;
         case OPCODE_JSR_W:          /* 0xc9 + s4 */
-            // FIXME - JSR_W instruction doesn't support in current version
-            result = VER_NoSupportJSR;
-            goto labelEnd_vf_parse_bytecode;
-            //break; // remark #111: statement is unreachable
+            offset = vf_get_double_word_branch_offset( &codeInstr[instr],
+                            instr, bytecode, &index, pool );
+            result = vf_check_branch_offset( offset, len, ctex );
+            if( result != VER_OK ) {
+                goto labelEnd_vf_parse_bytecode;
+            }
+            result = vf_check_branch_offset( index, len, ctex );
+            if( result != VER_OK ) {
+                goto labelEnd_vf_parse_bytecode;
+            }
+            vf_opcode_jsr( code, codeNum, pool );
+            ctex->m_dump.m_with_subroutine = 1;
+            vf_set_basic_block_flag( &codeInstr[offset] );
+            vf_set_basic_block_flag( &codeInstr[index] );
+            break;
         case _OPCODE_UNDEFINED:     /* 0xba */
         default:
             VERIFY_REPORT( ctex, "(class: " << class_get_name( ctex->m_class ) 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h?view=diff&rev=479048&r1=479047&r2=479048
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier/ver_real.h Fri Nov 24 15:34:29 2006
@@ -255,6 +255,7 @@
     SM_DOUBLE_LO,
     SM_LONG_HI,
     SM_DOUBLE_HI,
+    SM_RETURN_ADDR,
     // additional types
     SM_COPY_0,
     SM_COPY_1,
@@ -279,7 +280,8 @@
     VF_FLAG_END_ENTRY = 4,
     VF_FLAG_HANDLER = 8,
     VF_FLAG_RETURN = 16,
-    VF_FLAG_THROW = 32
+    VF_FLAG_THROW = 32,
+    VF_FLAG_SUBROUTINE = 64
 } vf_InstructionFlag_t;
 
 /**
@@ -293,6 +295,10 @@
 typedef struct vf_Context vf_Context_t;
 /// Verifier code instruction structure.
 typedef struct vf_Code_s vf_Code_t;
+/// Graph node container structure
+typedef struct vf_NodeContainer_s vf_NodeContainer_t;
+/// Graph edge container structure
+typedef struct vf_EdgeContainer_s vf_EdgeContainer_t;
 /// Verifier graph structure.
 typedef struct vf_Graph vf_Graph_t;
 /// Verifier graph node structure.
@@ -337,7 +343,10 @@
  */
 typedef struct {
     vf_ValidType_t *m_vtype;        ///< valid type for reference
-    unsigned m_new;                 ///< number of opcode new (for uninitialized)
+    union {
+        unsigned m_new;             ///< program count of opcode new for uninitialized
+        unsigned m_pc;              ///< program count of return address for subroutine
+    };
     union {
         unsigned short m_local;     ///< number of local variable
         unsigned short m_index;     ///< constant pool index for access check
@@ -429,6 +438,28 @@
 };
 
 /**
+ * Graph node container structure.
+ */
+struct vf_NodeContainer_s
+{
+    vf_NodeContainer_t* m_next;     ///< next container
+    unsigned m_max;                 ///< max number of nodes in container
+    unsigned m_used;                ///< number of nodes in container
+    vf_Node_t m_node[1];            ///< array of container nodes
+};
+
+/**
+ * Graph edge container structure.
+ */
+struct vf_EdgeContainer_s
+{
+    vf_EdgeContainer_t* m_next;     ///< next container
+    unsigned m_max;                 ///< max number of edges in container
+    unsigned m_used;                ///< number of edges in container
+    vf_Edge_t m_edge[1];            ///< array of container edges
+};
+
+/**
  * Verifier control flow graph structure.
  */
 struct vf_Graph
@@ -466,6 +497,28 @@
     void CreateNodes( unsigned count );
 
     /**
+     * Gets graph node.
+     * Parameter <i>node_num</i> must be in range.
+     *
+     * @param[in] node_num  - node number
+     *
+     * @return The pointer to node structure.
+     */
+    vf_Node_t* GetNode( unsigned node_num );
+
+    /**
+     * Creates a new node and sets data to it.
+     * Node array must have enough free space for a new element.
+     *
+     * @param[in] begin_instr   - begin code instruction of node
+     * @param[in] end_instr     - end code instruction of code
+     * @param[in] bytecode_len  - bytecode length of node instructions
+     */
+    void NewNode( unsigned begin_instr,
+                  unsigned end_instr,
+                  unsigned bytecode_len);
+
+    /**
      * Function set data to graph node.
      * @param node_num      - number of graph node
      * @param begin_instr   - begin code instruction of node
@@ -479,13 +532,24 @@
                   unsigned bytecode_len );
 
     /**
-     * Function set new edge for graph nodes.
+     * Gets graph edge.
+     * Parameter <i>edge_num</i> must be in range.
+     *
+     * @param[in] edge_num  - edge number
+     *
+     * @return The pointer to edge structure.
+     */
+    vf_Edge_t* GetEdge( unsigned edge_num );
+
+    /**
+     * Creates a new edge for graph nodes.
+     *
      * @param start_node    - start edge node
      * @param end_node      - end edge node
      * @note Edge is set as out edge for start_node and as in edge for end_node.
      */
-    void SetNewEdge( unsigned start_node,
-                     unsigned end_node);
+    void NewEdge( unsigned start_node,
+                  unsigned end_node);
 
     /**
      * Function receive first code instruction of graph node.
@@ -740,6 +804,26 @@
     void DumpGraph( vf_Context_t *context );
 
     /**
+     * Function dumps verifier graph in file in DOT format.
+     * @param context - current verifier context
+     * @note Function is valid in debug mode.
+     * @note File name is created from class and method names with .dot extension.
+     * @see vf_Context_t
+     */
+    void DumpDotGraph( vf_Context_t *context );
+
+private:
+    vf_NodeContainer_t *m_nodes;        ///< array of nodes
+    vf_EdgeContainer_t *m_edges;        ///< array of edges
+    vf_VerifyPool_t *m_pool;            ///< graph memory pool
+    unsigned *m_enum;                   ///< graph node enumeration structure
+    unsigned m_nodenum;                 ///< number of nodes
+    unsigned m_edgenum;                 ///< number of edges
+    unsigned m_enummax;                 ///< max number of enumerated elements
+    unsigned m_enumcount;               ///< number of enumerated elements
+    bool m_free;                        ///< need to free pool
+
+    /**
      * Function prints graph node in <code>stderr</code>.
      * @param node_num  - number of graph node
      * @param context      - current verifier context
@@ -760,14 +844,6 @@
     void DumpNodeInternal( unsigned node_num,
                            vf_Context_t *context);
 
-    /**
-     * Function dumps verifier graph in file in DOT format.
-     * @param context - current verifier context
-     * @note Function is valid in debug mode.
-     * @note File name is created from class and method names with .dot extension.
-     * @see vf_Context_t
-     */
-    void DumpDotGraph( vf_Context_t *context );
 
     /**
      * Function dumps graph header in file in DOT format.
@@ -813,17 +889,6 @@
      */
     void DumpDotEnd( ofstream &fout );
 
-private:
-    vf_Node_t *m_node;          ///< array of nodes
-    vf_Edge_t *m_edge;          ///< array of edges
-    vf_VerifyPool_t *m_pool;    ///< graph memory pool
-    unsigned *m_enum;           ///< graph node enumeration structure
-    unsigned m_nodenum;         ///< number of nodes
-    unsigned m_edgenum;         ///< number of edges
-    unsigned m_edgemem;         ///< number of allocted edges
-    unsigned m_local;           ///< number of locals
-    unsigned m_enumcount;       ///< number of enumerated elements
-    bool m_free;                ///< need to free pool
 }; // struct vf_Graph
 
 /**
@@ -1079,8 +1144,11 @@
         m_method(NULL), m_graph(NULL), m_pool(NULL), m_code(NULL), 
         m_codeNum(0), m_nodeNum(0), m_edgeNum(0)
         {
-            vf_ContextDump zero1 = {0}; m_dump = zero1;
-            vf_ContextVType zero2 = {0}; m_vtype = zero2;
+            vf_ContextDump zero1 = {0};
+            vf_ContextVType zero2 = {0};
+
+            m_dump = zero1;
+            m_vtype = zero2;
         }
 
     /**
@@ -1122,6 +1190,7 @@
      */
     struct vf_ContextDump {
         unsigned m_verify : 1;          ///< verify all flag
+        unsigned m_with_subroutine : 1; ///< verified method has subrotine
         unsigned m_constraint : 1;      ///< dump type constraints for class
         unsigned m_code : 1;            ///< print code array in stream
         unsigned m_graph : 1;           ///< print original control flow graph