Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 57777 invoked from network); 24 Nov 2006 23:35:51 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 24 Nov 2006 23:35:51 -0000 Received: (qmail 23150 invoked by uid 500); 24 Nov 2006 23:36:01 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 23044 invoked by uid 500); 24 Nov 2006 23:36:00 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 23035 invoked by uid 99); 24 Nov 2006 23:36:00 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 24 Nov 2006 15:36:00 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 24 Nov 2006 15:35:30 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id 0FF901A9846; Fri, 24 Nov 2006 15:34:36 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r479048 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier: Graph.cpp Verifier.cpp ver_real.h Date: Fri, 24 Nov 2006 23:34:35 -0000 To: commits@harmony.apache.org From: gshimansky@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20061124233437.0FF901A9846@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org 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 node_num 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 edge_num 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 stderr. * @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