harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mloe...@apache.org
Subject svn commit: r584170 [6/7] - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363: base/ java5/ java6/
Date Fri, 12 Oct 2007 14:42:23 GMT
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.h?rev=584170&r1=584169&r2=584170&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.h Fri Oct 12 07:42:03 2007
@@ -1,327 +1,327 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Mikhail Loenko, Vladimir Molotkov
- */  
-
-#ifndef __CONTEXT5_H__
-#define __CONTEXT5_H__
-
-#include <assert.h>
-#include <string.h>
-#include "../base/context_x.h"
-#include "stackmap_5.h"
-#include "instr_props_5.h"
-
-using namespace CPVerifier;
-
-
-namespace CPVerifier_5 {
-
-    //
-    // Context - main class of Type Checker
-    //
-
-    class vf_Context_5 : public vf_Context_x<vf_Context_5, WorkmapElement, _WorkmapElement, StackmapElement> {
-    public:
-        vf_Context_5(SharedClasswideData &classwide) :
-          vf_Context_x<vf_Context_5, WorkmapElement, _WorkmapElement, StackmapElement>(classwide) {}
-
-          vf_Result verify_method(method_handler method);
-    protected:
-        // various flags for all the method's bytecode instructions
-        InstrProps props;
-
-        // stack to push instructions like branch targets, etc to go thru the method. the stack is method-wide.
-        MarkableStack stack;
-
-        FastStack dead_code_stack;
-        bool      dead_code_parsing;
-
-        //we would like to flush StackMapTable attribute from this method
-        bool      stackmapattr_calculation;
-
-        static const short MARK_SUBROUTINE_DONE = -1;
-
-        //init method-wide data
-        void init(method_handler _m_method, bool _stackmapattr_calculation = 0) {
-            vf_Context_x<vf_Context_5, WorkmapElement, _WorkmapElement, StackmapElement>::init(_m_method);
-            stack.init();
-            dead_code_stack.init();
-
-            props.init(mem, m_code_length);
-
-            //we would like to flush StackMapTable attribute from this method
-            stackmapattr_calculation = _stackmapattr_calculation;
-        }
-
-        // load derived types previously stored for the given instruction
-        void fill_workmap(Address instr) {
-            PropsHead *head = (PropsHead*)props.getInstrProps(instr);
-            if( head->is_workmap() ) {
-                tc_memcpy(workmap, head->getWorkmap(), sizeof(WorkmapHead) + sizeof(WorkmapElement) * (m_stack_start + head->workmap.depth));
-            } else {
-                StackmapHead *stackmap = head->getStackmap();
-
-                workmap->depth = stackmap->depth;
-
-                for( unsigned i = 0; i < m_stack_start + stackmap->depth; i++) {
-                    workmap->elements[i] = _WorkmapElement(&stackmap->elements[i]);
-                    assert( workmap->elements[i].getAnyPossibleValue() != SM_NONE );
-                }
-            }
-            no_locals_info = 1;
-        }
-
-        //store a copy of the current workmap for another instruction (such as a branch target)
-        void storeWorkmapCopy(Address target) {
-            int sz = m_stack_start + workmap->depth;
-            PropsHead* copy = newWorkmapProps(sz);
-            tc_memcpy(copy->getWorkmap(), workmap, sizeof(WorkmapHead) + sizeof(WorkmapElement) * sz);
-
-            props.setInstrProps(target, copy);
-        }
-
-        //create a stackmap vector of the given size sz (max_locals <= sz <= max_locals+max_stack)
-        PropsHead* newStackmap(int sz) {
-            return (PropsHead*)mem.calloc(sizeof(PropsHead) + sizeof(StackmapElement) * sz);
-        }
-
-        //create a vector that will be used for JSR procesing. 
-        //It contains ether stackmap or workmap vector, SubrouitineData, and flags vector indicating 
-        //changed locals
-        PropsHead *newRetData() {
-            assert( sizeof(StackmapElement) >= sizeof(WorkmapElement) );
-
-            int sz = sizeof(PropsHead) + sizeof(StackmapElement) * (m_max_stack + m_stack_start) + //stackmap
-                ((sizeof(SubroutineData)+ m_stack_start) & (~3)) + 4; // fixed data and changed locals vector
-
-            PropsHead * ret = (PropsHead *) mem.calloc(sz);
-            ret->set_as_workmap();
-            return ret;
-        }
-
-        //creates a temporary variable for converting 
-        StackmapElement *new_variable() {
-            return (StackmapElement*) mem.calloc(sizeof(StackmapElement));
-        }
-
-        /////////////////////////////////////////////////////////////////////////////////////////////////////
-
-        //First verification pass thru the method. checks that no jump outside the method or to the middle of instruction
-        //checks that opcodes are valid
-        vf_Result parse(Address instr);
-
-        //Second pass: dataflow of a piece of the method starting from the beginning or a branch target and finishing
-        //on return, athrow or hitting previously passed instruction. 
-        //This function initializes workmap and calls DataflowLoop
-        vf_Result StartLinearDataflow(Address start);
-
-        //Second pass: Finilize subroutie processing -- once we are here, then all the RETs from achievable for
-        //the given subroutine are passed, so we can resume passing for JSRs to the given address
-        //This function initializes workmap properly and calls DataflowLoop
-        vf_Result SubroutineDone(Address start);
-
-        //Second pass: dataflow of a piece of the method starting from the beginning or a branch target and finishing
-        //on return, athrow or hitting previously passed instruction
-        vf_Result DataflowLoop(Address start, int workmap_is_a_copy_of_stackmap);
-
-        //constraint propagation
-        vf_Result propagate(StackmapElement *changed, SmConstant new_value);
-
-        //update current derived types according to what was changed in subroutine
-        void restore_workmap_after_jsr(Address jsr_target);
-
-        //create vector constraints for each target of a switch
-        vf_Result processSwitchTarget(Address target) {
-            vf_Result tcr;
-            if( props.isMultiway(target) ) {
-                if( (tcr=new_generic_vector_constraint(target)) != VF_OK ) {
-                    return tcr;
-                }
-
-                if( !props.isDataflowPassed(target) ) {
-                    stack.xPush(target);
-                }
-            } else {
-                assert( !props.isDataflowPassed(target) );
-                storeWorkmapCopy(target);
-
-                stack.xPush(target);
-            }
-            return VF_OK;
-        }
-
-
-        ///////////////////////////////////  "VIRTUAL" METHODS /////////////////////////////////////////////
-    public:
-        //create constraint vector in case of a branch 
-        //simple conatraints are created for pairs of both locals and stack (current must be assignable to target)
-        vf_Result new_generic_vector_constraint(Address target_instr) {
-            return new_generic_vector_constraint_impl(getStackmap(target_instr, workmap->depth));
-        }
-
-        //when we hit RET instruction we update the data for the given subroutine with current derived types
-        vf_Result new_ret_vector_constraint(Address target_instr);
-
-        // push catch-block to the stack of branches to pass
-        void push_handler(Address handler_pc) {
-            if( !props.isDataflowPassed(handler_pc) ) {
-                stack.xPush(handler_pc);
-            }
-        }
-
-        //create simple single constraint: "'from' is assingable to 'to'"
-        vf_Result new_scalar_constraint(WorkmapElement *from, StackmapElement *to);
-
-        //add one more possible value (type) that can come to the given point (local or stack)
-        vf_Result add_incoming_value(SmConstant new_value, StackmapElement *destination);
-
-        //create stackmap for exception handler start
-        void createHandlerStackmap(Address handler_pc, SmConstant type) {
-            StackmapHead *map = getStackmap(handler_pc, 1);
-            //handler stackmaps are created before any dataflow analysis is done
-            assert(map->depth == 0 || map->depth == 1);
-            map->depth = 1;
-
-            vf_Result tcr = add_incoming_value(type, &map->elements[m_stack_start]);
-
-            // it is initialization stage
-            assert(tcr == VF_OK);
-        }
-
-
-        //create a workmap vector for the given size sz (max_locals <= sz <= max_locals+max_stack)
-        PropsHead *newWorkmapProps(int sz) {
-            PropsHead * ret = (PropsHead*)mem.malloc(sizeof(PropsHead) + sizeof(WorkmapElement) * sz);
-            ret->set_as_workmap();
-            return ret;
-        }
-
-        //returns stackmap for the 'instr' instruction
-        //if it does not exists yet -- create it. When created use 'depth' as stack depth
-        StackmapHead *getStackmap(Address instr, int depth) {
-            PropsHead *pro = (PropsHead*) props.getInstrProps(instr);
-            if( !pro ) {
-                pro = newStackmap(m_stack_start + depth);
-                props.setInstrProps(instr, pro);
-                pro->getStackmap()->depth = depth;
-            }
-            return pro->getStackmap();
-        }
-
-        //returns stackmap for the 'instr' instruction. it must exist
-        StackmapHead *getStackmap(Address instr) {
-            PropsHead *pro = (PropsHead*)props.getInstrProps(instr);
-            assert(pro);
-            return pro->getStackmap();
-        }
-
-        /////////////// expect some type //////////////
-
-        //expect exactly this type
-        int workmap_expect_strict( WorkmapElement &el, SmConstant type ) {
-            assert(type != SM_BOGUS);
-
-            if( !el.isVariable() ) {
-                return type == el.getConst();
-            }
-
-            IncomingType *in = el.getVariable()->firstIncoming();
-            while( in ) {
-                if( type != in->value ) {
-                    return false;
-                }
-                in = in->next();
-            }
-
-            ExpectedType *exp = el.getVariable()->firstExpected();
-            while( exp ) {
-                if( type == exp->value ) {
-                    return true;
-                }
-                exp = exp->next();
-            }
-
-            el.getVariable()->newExpectedType(&mem, type);
-
-            return true;
-        }
-
-        int workmap_expect( WorkmapElement &el, SmConstant type ) {
-            if( !el.isVariable() ) {
-                return tpool.mustbe_assignable(el.getConst(), type);
-            } else {
-                ExpectedType* exp = el.getVariable()->firstExpected();
-                while( exp ) {
-                    if( type == exp->value ) {
-                        return true;
-                    }
-                    exp = exp->next();
-                }
-
-                IncomingType *in = el.getVariable()->firstIncoming();
-                //check that all existing incoming type are assignable to the new expected type
-                while( in ) {
-                    if( !tpool.mustbe_assignable(in->value, type) ) {
-                        return false;
-                    }
-                    in = in->next();
-                }
-                //add the new expected type
-                el.getVariable()->newExpectedType(&mem, type);
-            }
-            return true;
-        }
-
-        //create special type of conatraint: "'from' is an array and it's element is assignable to 'to'"
-        vf_Result new_scalar_array2ref_constraint(WorkmapElement *from, WorkmapElement *to) {
-            if( !from->isVariable() ) {
-                //although new_scalar_conatraint() whould process from constants correctly 
-                // we just do not need new variable if it is really a constant
-                *to = _WorkmapElement( tpool.get_ref_from_array(from->getConst()) );
-                return VF_OK;
-            }
-            assert( from->isVariable() );
-
-            ArrayCnstr* arr = from->getVariable()->firstArrayCnstr();
-            //at most one array conversion constraint per variable is possible
-            if( arr ) {
-                *to = _WorkmapElement(arr->variable);
-                return VF_OK;
-            }
-
-            *to = _WorkmapElement( new_variable() );
-
-            IncomingType *inc = from->getVariable()->firstIncoming();
-            from->getVariable()->newArrayConversionConstraint(&mem, to->getVariable());
-
-            while( inc ) {
-                SmConstant inc_val = tpool.get_ref_from_array(inc->value);
-                vf_Result vcr = add_incoming_value( inc_val, to->getVariable() );
-                if( vcr != VF_OK ) {
-                    return vcr;
-                }
-                inc = inc->next();
-            }
-            return VF_OK;
-        }
-    };
-
-} // namespace CPVerifier
-
-#endif
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Mikhail Loenko, Vladimir Molotkov
+ */  
+
+#ifndef __CONTEXT5_H__
+#define __CONTEXT5_H__
+
+#include <assert.h>
+#include <string.h>
+#include "../base/context_x.h"
+#include "stackmap_5.h"
+#include "instr_props_5.h"
+
+using namespace CPVerifier;
+
+
+namespace CPVerifier_5 {
+
+    //
+    // Context - main class of Type Checker
+    //
+
+    class vf_Context_5 : public vf_Context_x<vf_Context_5, WorkmapElement, _WorkmapElement, StackmapElement> {
+    public:
+        vf_Context_5(SharedClasswideData &classwide) :
+          vf_Context_x<vf_Context_5, WorkmapElement, _WorkmapElement, StackmapElement>(classwide) {}
+
+          vf_Result verify_method(method_handler method);
+    protected:
+        // various flags for all the method's bytecode instructions
+        InstrProps props;
+
+        // stack to push instructions like branch targets, etc to go thru the method. the stack is method-wide.
+        MarkableStack stack;
+
+        FastStack dead_code_stack;
+        bool      dead_code_parsing;
+
+        //we would like to flush StackMapTable attribute from this method
+        bool      stackmapattr_calculation;
+
+        static const short MARK_SUBROUTINE_DONE = -1;
+
+        //init method-wide data
+        void init(method_handler _m_method, bool _stackmapattr_calculation = 0) {
+            vf_Context_x<vf_Context_5, WorkmapElement, _WorkmapElement, StackmapElement>::init(_m_method);
+            stack.init();
+            dead_code_stack.init();
+
+            props.init(mem, m_code_length);
+
+            //we would like to flush StackMapTable attribute from this method
+            stackmapattr_calculation = _stackmapattr_calculation;
+        }
+
+        // load derived types previously stored for the given instruction
+        void fill_workmap(Address instr) {
+            PropsHead *head = (PropsHead*)props.getInstrProps(instr);
+            if( head->is_workmap() ) {
+                tc_memcpy(workmap, head->getWorkmap(), sizeof(WorkmapHead) + sizeof(WorkmapElement) * (m_stack_start + head->workmap.depth));
+            } else {
+                StackmapHead *stackmap = head->getStackmap();
+
+                workmap->depth = stackmap->depth;
+
+                for( unsigned i = 0; i < m_stack_start + stackmap->depth; i++) {
+                    workmap->elements[i] = _WorkmapElement(&stackmap->elements[i]);
+                    assert( workmap->elements[i].getAnyPossibleValue() != SM_NONE );
+                }
+            }
+            no_locals_info = 1;
+        }
+
+        //store a copy of the current workmap for another instruction (such as a branch target)
+        void storeWorkmapCopy(Address target) {
+            int sz = m_stack_start + workmap->depth;
+            PropsHead* copy = newWorkmapProps(sz);
+            tc_memcpy(copy->getWorkmap(), workmap, sizeof(WorkmapHead) + sizeof(WorkmapElement) * sz);
+
+            props.setInstrProps(target, copy);
+        }
+
+        //create a stackmap vector of the given size sz (max_locals <= sz <= max_locals+max_stack)
+        PropsHead* newStackmap(int sz) {
+            return (PropsHead*)mem.calloc(sizeof(PropsHead) + sizeof(StackmapElement) * sz);
+        }
+
+        //create a vector that will be used for JSR procesing. 
+        //It contains ether stackmap or workmap vector, SubrouitineData, and flags vector indicating 
+        //changed locals
+        PropsHead *newRetData() {
+            assert( sizeof(StackmapElement) >= sizeof(WorkmapElement) );
+
+            int sz = sizeof(PropsHead) + sizeof(StackmapElement) * (m_max_stack + m_stack_start) + //stackmap
+                ((sizeof(SubroutineData)+ m_stack_start) & (~3)) + 4; // fixed data and changed locals vector
+
+            PropsHead * ret = (PropsHead *) mem.calloc(sz);
+            ret->set_as_workmap();
+            return ret;
+        }
+
+        //creates a temporary variable for converting 
+        StackmapElement *new_variable() {
+            return (StackmapElement*) mem.calloc(sizeof(StackmapElement));
+        }
+
+        /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+        //First verification pass thru the method. checks that no jump outside the method or to the middle of instruction
+        //checks that opcodes are valid
+        vf_Result parse(Address instr);
+
+        //Second pass: dataflow of a piece of the method starting from the beginning or a branch target and finishing
+        //on return, athrow or hitting previously passed instruction. 
+        //This function initializes workmap and calls DataflowLoop
+        vf_Result StartLinearDataflow(Address start);
+
+        //Second pass: Finilize subroutie processing -- once we are here, then all the RETs from achievable for
+        //the given subroutine are passed, so we can resume passing for JSRs to the given address
+        //This function initializes workmap properly and calls DataflowLoop
+        vf_Result SubroutineDone(Address start);
+
+        //Second pass: dataflow of a piece of the method starting from the beginning or a branch target and finishing
+        //on return, athrow or hitting previously passed instruction
+        vf_Result DataflowLoop(Address start, int workmap_is_a_copy_of_stackmap);
+
+        //constraint propagation
+        vf_Result propagate(StackmapElement *changed, SmConstant new_value);
+
+        //update current derived types according to what was changed in subroutine
+        void restore_workmap_after_jsr(Address jsr_target);
+
+        //create vector constraints for each target of a switch
+        vf_Result processSwitchTarget(Address target) {
+            vf_Result tcr;
+            if( props.isMultiway(target) ) {
+                if( (tcr=new_generic_vector_constraint(target)) != VF_OK ) {
+                    return tcr;
+                }
+
+                if( !props.isDataflowPassed(target) ) {
+                    stack.xPush(target);
+                }
+            } else {
+                assert( !props.isDataflowPassed(target) );
+                storeWorkmapCopy(target);
+
+                stack.xPush(target);
+            }
+            return VF_OK;
+        }
+
+
+        ///////////////////////////////////  "VIRTUAL" METHODS /////////////////////////////////////////////
+    public:
+        //create constraint vector in case of a branch 
+        //simple conatraints are created for pairs of both locals and stack (current must be assignable to target)
+        vf_Result new_generic_vector_constraint(Address target_instr) {
+            return new_generic_vector_constraint_impl(getStackmap(target_instr, workmap->depth));
+        }
+
+        //when we hit RET instruction we update the data for the given subroutine with current derived types
+        vf_Result new_ret_vector_constraint(Address target_instr);
+
+        // push catch-block to the stack of branches to pass
+        void push_handler(Address handler_pc) {
+            if( !props.isDataflowPassed(handler_pc) ) {
+                stack.xPush(handler_pc);
+            }
+        }
+
+        //create simple single constraint: "'from' is assingable to 'to'"
+        vf_Result new_scalar_constraint(WorkmapElement *from, StackmapElement *to);
+
+        //add one more possible value (type) that can come to the given point (local or stack)
+        vf_Result add_incoming_value(SmConstant new_value, StackmapElement *destination);
+
+        //create stackmap for exception handler start
+        void createHandlerStackmap(Address handler_pc, SmConstant type) {
+            StackmapHead *map = getStackmap(handler_pc, 1);
+            //handler stackmaps are created before any dataflow analysis is done
+            assert(map->depth == 0 || map->depth == 1);
+            map->depth = 1;
+
+            vf_Result tcr = add_incoming_value(type, &map->elements[m_stack_start]);
+
+            // it is initialization stage
+            assert(tcr == VF_OK);
+        }
+
+
+        //create a workmap vector for the given size sz (max_locals <= sz <= max_locals+max_stack)
+        PropsHead *newWorkmapProps(int sz) {
+            PropsHead * ret = (PropsHead*)mem.malloc(sizeof(PropsHead) + sizeof(WorkmapElement) * sz);
+            ret->set_as_workmap();
+            return ret;
+        }
+
+        //returns stackmap for the 'instr' instruction
+        //if it does not exists yet -- create it. When created use 'depth' as stack depth
+        StackmapHead *getStackmap(Address instr, int depth) {
+            PropsHead *pro = (PropsHead*) props.getInstrProps(instr);
+            if( !pro ) {
+                pro = newStackmap(m_stack_start + depth);
+                props.setInstrProps(instr, pro);
+                pro->getStackmap()->depth = depth;
+            }
+            return pro->getStackmap();
+        }
+
+        //returns stackmap for the 'instr' instruction. it must exist
+        StackmapHead *getStackmap(Address instr) {
+            PropsHead *pro = (PropsHead*)props.getInstrProps(instr);
+            assert(pro);
+            return pro->getStackmap();
+        }
+
+        /////////////// expect some type //////////////
+
+        //expect exactly this type
+        int workmap_expect_strict( WorkmapElement &el, SmConstant type ) {
+            assert(type != SM_BOGUS);
+
+            if( !el.isVariable() ) {
+                return type == el.getConst();
+            }
+
+            IncomingType *in = el.getVariable()->firstIncoming();
+            while( in ) {
+                if( type != in->value ) {
+                    return false;
+                }
+                in = in->next();
+            }
+
+            ExpectedType *exp = el.getVariable()->firstExpected();
+            while( exp ) {
+                if( type == exp->value ) {
+                    return true;
+                }
+                exp = exp->next();
+            }
+
+            el.getVariable()->newExpectedType(&mem, type);
+
+            return true;
+        }
+
+        int workmap_expect( WorkmapElement &el, SmConstant type ) {
+            if( !el.isVariable() ) {
+                return tpool.mustbe_assignable(el.getConst(), type);
+            } else {
+                ExpectedType* exp = el.getVariable()->firstExpected();
+                while( exp ) {
+                    if( type == exp->value ) {
+                        return true;
+                    }
+                    exp = exp->next();
+                }
+
+                IncomingType *in = el.getVariable()->firstIncoming();
+                //check that all existing incoming type are assignable to the new expected type
+                while( in ) {
+                    if( !tpool.mustbe_assignable(in->value, type) ) {
+                        return false;
+                    }
+                    in = in->next();
+                }
+                //add the new expected type
+                el.getVariable()->newExpectedType(&mem, type);
+            }
+            return true;
+        }
+
+        //create special type of conatraint: "'from' is an array and it's element is assignable to 'to'"
+        vf_Result new_scalar_array2ref_constraint(WorkmapElement *from, WorkmapElement *to) {
+            if( !from->isVariable() ) {
+                //although new_scalar_conatraint() whould process from constants correctly 
+                // we just do not need new variable if it is really a constant
+                *to = _WorkmapElement( tpool.get_ref_from_array(from->getConst()) );
+                return VF_OK;
+            }
+            assert( from->isVariable() );
+
+            ArrayCnstr* arr = from->getVariable()->firstArrayCnstr();
+            //at most one array conversion constraint per variable is possible
+            if( arr ) {
+                *to = _WorkmapElement(arr->variable);
+                return VF_OK;
+            }
+
+            *to = _WorkmapElement( new_variable() );
+
+            IncomingType *inc = from->getVariable()->firstIncoming();
+            from->getVariable()->newArrayConversionConstraint(&mem, to->getVariable());
+
+            while( inc ) {
+                SmConstant inc_val = tpool.get_ref_from_array(inc->value);
+                vf_Result vcr = add_incoming_value( inc_val, to->getVariable() );
+                if( vcr != VF_OK ) {
+                    return vcr;
+                }
+                inc = inc->next();
+            }
+            return VF_OK;
+        }
+    };
+
+} // namespace CPVerifier
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.h
            ('svn:executable' removed)

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/instr_props_5.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/instr_props_5.h?rev=584170&r1=584169&r2=584170&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/instr_props_5.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/instr_props_5.h Fri Oct 12 07:42:03 2007
@@ -1,129 +1,129 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Mikhail Loenko, Vladimir Molotkov
- */  
-
-#ifndef __INSTR_PROPS5_H_
-#define __INSTR_PROPS5_H_
-
-#include <assert.h>
-#include "../base/stackmap.h"
-
-using namespace CPVerifier;
-
-namespace CPVerifier_5 {
-
-    //store flags and properties (stackmaps, workmaps, etc) for each instruction
-    class InstrProps : public InstrPropsBase {
-    private:
-        //array of bit flags
-        uint8* packed_flags;
-
-        //returns flags for the instruction 'instr'. other bits are not necessary 0s
-        int get_dirty_mask(Address instr) {
-            int b = packed_flags[instr/4];
-            b = b >> ((instr % 4) * 2);
-            return b;
-        }
-
-        //bit OR flags for the instruction 'instr' with 'mask'
-        void fill_mask(Address instr, int mask) {
-            assert((mask & ~3) == 0);
-            mask = mask << ((instr % 4) * 2);
-
-            packed_flags[instr/4] |= mask;
-        }
-
-        //clears bits the are set in the 'mask' (& ~mask) for the instruction 'instr'
-        void clear_mask(Address instr, int mask) {
-            assert((mask & ~3) == 0);
-            mask = mask << (instr % 4) * 2;
-
-            packed_flags[instr/4] &= ~mask;
-        }
-
-    public:
-        //initializes the class. this function is invoked once per method - removes old data in initializes storages.
-        void init(Memory &mem, int code_len) {
-            InstrPropsBase::init(mem, code_len);
-            packed_flags = (uint8*)mem.calloc( ((code_len/4) & ~3) + 4);
-        }
-
-        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
-        //returns 1 if mask is 01 (parsed) or 11 ('special' parsed  special == has stackmap)
-        int isParsePassed(Address instr) {
-            return get_dirty_mask(instr) & 1;
-        }
-
-        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
-        //returns 1 if mask is 10 (middle of instruction)
-        int isOperand(Address instr) {
-            return (get_dirty_mask(instr) & 3) == 2;
-        }
-
-        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
-        //setls low mask bit to 1
-        void setParsePassed(Address instr) {
-            fill_mask(instr, 1);
-        }
-
-        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
-        //sets mask to 10
-        int setOperand(Address instr) {
-            int idx = instr/4;
-            int shift = ((instr % 4) * 2);
-
-            int mask01 = 1 << shift;
-            int mask10 = 2 << shift;
-
-            //is an instruction
-            if( packed_flags[idx] & mask01 ) return 0;
-
-            //mark as a middle
-            packed_flags[idx] |= mask10;
-            return 1;
-        }
-
-        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
-        //set mask to 11
-        void setMultiway(Address instr) {
-            fill_mask(instr, 3);
-        }
-
-        //pass2: 01 - new, 11 - special, 00 - passed (or unused), 10 - special passed (or unused)
-        //for all instructions (except unuzed) returns 1 if it's 'passed' or 'special passed'
-        //return 0 otherwise
-        int isDataflowPassed(Address instr) {
-            return !(get_dirty_mask(instr) & 1);
-        }
-
-        //return 1 for special and special passed instructions (instructions that are achievable by multiple passes)
-        int isMultiway(Address instr) { //II_MULTIWAY
-            return get_dirty_mask(instr) & 2;
-        }
-
-        //mark instruction as passed
-        void setDataflowPassed(Address instr) {
-            clear_mask(instr, 1);
-        }
-
-    };
-} // namespace CPVerifier
-
-
-#endif
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Mikhail Loenko, Vladimir Molotkov
+ */  
+
+#ifndef __INSTR_PROPS5_H_
+#define __INSTR_PROPS5_H_
+
+#include <assert.h>
+#include "../base/stackmap.h"
+
+using namespace CPVerifier;
+
+namespace CPVerifier_5 {
+
+    //store flags and properties (stackmaps, workmaps, etc) for each instruction
+    class InstrProps : public InstrPropsBase {
+    private:
+        //array of bit flags
+        uint8* packed_flags;
+
+        //returns flags for the instruction 'instr'. other bits are not necessary 0s
+        int get_dirty_mask(Address instr) {
+            int b = packed_flags[instr/4];
+            b = b >> ((instr % 4) * 2);
+            return b;
+        }
+
+        //bit OR flags for the instruction 'instr' with 'mask'
+        void fill_mask(Address instr, int mask) {
+            assert((mask & ~3) == 0);
+            mask = mask << ((instr % 4) * 2);
+
+            packed_flags[instr/4] |= mask;
+        }
+
+        //clears bits the are set in the 'mask' (& ~mask) for the instruction 'instr'
+        void clear_mask(Address instr, int mask) {
+            assert((mask & ~3) == 0);
+            mask = mask << (instr % 4) * 2;
+
+            packed_flags[instr/4] &= ~mask;
+        }
+
+    public:
+        //initializes the class. this function is invoked once per method - removes old data in initializes storages.
+        void init(Memory &mem, int code_len) {
+            InstrPropsBase::init(mem, code_len);
+            packed_flags = (uint8*)mem.calloc( ((code_len/4) & ~3) + 4);
+        }
+
+        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
+        //returns 1 if mask is 01 (parsed) or 11 ('special' parsed  special == has stackmap)
+        int isParsePassed(Address instr) {
+            return get_dirty_mask(instr) & 1;
+        }
+
+        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
+        //returns 1 if mask is 10 (middle of instruction)
+        int isOperand(Address instr) {
+            return (get_dirty_mask(instr) & 3) == 2;
+        }
+
+        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
+        //setls low mask bit to 1
+        void setParsePassed(Address instr) {
+            fill_mask(instr, 1);
+        }
+
+        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
+        //sets mask to 10
+        int setOperand(Address instr) {
+            int idx = instr/4;
+            int shift = ((instr % 4) * 2);
+
+            int mask01 = 1 << shift;
+            int mask10 = 2 << shift;
+
+            //is an instruction
+            if( packed_flags[idx] & mask01 ) return 0;
+
+            //mark as a middle
+            packed_flags[idx] |= mask10;
+            return 1;
+        }
+
+        //pass1: 00 - new (or dead code), 01 - parsed, 10 - middle of instruction, 11 - 'special' parsed (special == has stackmap)
+        //set mask to 11
+        void setMultiway(Address instr) {
+            fill_mask(instr, 3);
+        }
+
+        //pass2: 01 - new, 11 - special, 00 - passed (or unused), 10 - special passed (or unused)
+        //for all instructions (except unuzed) returns 1 if it's 'passed' or 'special passed'
+        //return 0 otherwise
+        int isDataflowPassed(Address instr) {
+            return !(get_dirty_mask(instr) & 1);
+        }
+
+        //return 1 for special and special passed instructions (instructions that are achievable by multiple passes)
+        int isMultiway(Address instr) { //II_MULTIWAY
+            return get_dirty_mask(instr) & 2;
+        }
+
+        //mark instruction as passed
+        void setDataflowPassed(Address instr) {
+            clear_mask(instr, 1);
+        }
+
+    };
+} // namespace CPVerifier
+
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/instr_props_5.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/instr_props_5.h
            ('svn:executable' removed)

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/stackmap_5.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/stackmap_5.h?rev=584170&r1=584169&r2=584170&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/stackmap_5.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/stackmap_5.h Fri Oct 12 07:42:03 2007
@@ -1,372 +1,372 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-/** 
- * @author Mikhail Loenko, Vladimir Molotkov
- */  
-
-#ifndef __STACKMAP5_H__
-#define __STACKMAP5_H__
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include "../base/stackmap_x.h"
-
-#ifdef WIN32
-#define intptr int64
-#else
-#define intptr long
-#endif
-
-using namespace CPVerifier;
-
-namespace CPVerifier_5 {
-
-    struct StackmapElement;
-    struct WorkmapElement;
-
-    //possible relations between verificaton types
-    enum ConstraintType {
-        CT_GENERIC = 0,         // sub-defined type A is assignable to sub-defined type B
-        CT_ARRAY2REF = 1,       // A is a known-type array. element of A is assignable to sub-defined type B
-        CT_EXPECTED_TYPE = 2,   // sub-defined type A is assignable to known-type B
-        CT_INCOMING_VALUE = 3   // known-type A is assignable to sub-defined type B
-    };
-
-    //structure for maintaining subroutine-specific data
-    //until subroutine is passed with the second (dataflow) pass we record to the wait list all JSR instructions
-    //calling this subroutine. Once the subroutine is over we continue 2nd pass for each wait-listed instruction
-    //see vf_Context_Base::SubroutineDone
-    struct SubroutineData {
-        Address caller;         //first JSR instruction that called this subroutine
-        short retCount;         //number of ret instructions for this subroutine
-        uint8  subrDataflowed;   // =1 if dataflow pass for the subroutine is over
-    };
-
-    //list constant verification type (i.e. known-type) that are assignable to some sub-definite type (i.e. StackMapElement)
-    //see StackmapElement
-    struct IncomingType {
-        //next in the list
-        IncomingType *nxt;
-
-        //value of the verification type recorded as int
-        //TODO: don't remember why it's 'int' rather than 'SmConstant'
-        int value;
-
-        //simple next in the list
-        IncomingType *next() {
-            return nxt;
-        }
-    };
-
-    //list of constraints for some sub-definite verification type (i.e. StackMapElement)
-    //see StackmapElement
-
-    struct Constraint {
-        //next in the list
-        Constraint *nxt;
-
-        //either
-        union {
-            StackmapElement *variable; // sub-definite verificarion type
-            int value;                 // or constant (known) verification type rcorded as int
-        };
-
-        //consatrint type
-        ConstraintType type;
-
-        //next constrait of type 't'
-        static Constraint *next(Constraint *cur, int t) {
-            while( cur && cur->type != t ) {
-                cur = (Constraint*)cur->next();
-            }
-            return cur;
-        }
-
-        //simple next in the list
-        Constraint *next() {
-            return nxt;
-        }
-    };
-
-    //constraint of the CT_EXPECTED_TYPE type: sub-defined type A is assignable to known-type B
-    struct ExpectedType : Constraint {
-        ExpectedType *next() {
-            return (ExpectedType *) Constraint::next(Constraint::next(), CT_EXPECTED_TYPE);
-        }
-    };
-
-    //constraint of the CT_GENERIC type: sub-defined type A is assignable to sub-defined type B
-    struct GenericCnstr : Constraint {
-        GenericCnstr *next() {
-            return (GenericCnstr *) Constraint::next(Constraint::next(), CT_GENERIC);
-        }
-    };
-
-    //constraint of the CT_ARRAY2REF type: A is a known-type array. element of A is assignable to sub-defined type B
-    struct ArrayCnstr : Constraint {
-        //there can be only one CT_ARRAY2REF per StackMap Element
-        ArrayCnstr *next() {
-            assert(0);
-            return 0;
-        }
-    };
-
-
-    //StackMapElement structure represens sub-definite verification type: we don't know what type is it, but
-    //we know about instructions that expect ExpectedTypes here and we know that IncomingValues can be here
-    //we also know that this type must be assignable to other sub-defenite types as indicated by CT_GENERIC
-    //constrains and there can be special limitations represented by CT_ARRAY2REF constraints
-    struct StackmapElement { //TODO: should be rewritten to save footprint
-        //list of IncomingType constraint
-        IncomingType *incoming;
-
-        //list of all the conatraints of other types
-        Constraint *others;
-
-        //return value from any IncomingType constraint
-        //when we need to compae to some unmergable type we don;t need to interate thru the list
-        //also used to assert that an IncomingValue constraint exists
-        SmConstant getAnyIncomingValue() {
-            assert(firstIncoming());
-            return firstIncoming()->value;
-        }
-
-        //return first IncomingType constraint
-        IncomingType *firstIncoming() {
-            //TODO: I have to store somewhere the "modified" bit. Sorry.
-            return (IncomingType*)( (intptr)incoming & ~3 );
-        }
-
-        //return first conatrint of any type except IncomingType
-        Constraint *firstOthers() {
-            return others;
-        }
-
-        //return first CT_EXPECTED_TYPE constraint
-        ExpectedType *firstExpected() {
-            return (ExpectedType*)Constraint::next(others, CT_EXPECTED_TYPE);
-        }
-
-        //return first CT_GENERIC constraint
-        GenericCnstr *firstGenericCnstr() {
-            return (GenericCnstr*)Constraint::next(others, CT_GENERIC);
-        }
-
-        //return first (and the only) CT_ARRAY2REF constraint
-        ArrayCnstr *firstArrayCnstr() {
-            return (ArrayCnstr*)Constraint::next(others, CT_ARRAY2REF);
-        }
-
-        //clean-up
-        void init() {
-            incoming = 0;
-            others = 0;
-        }
-
-        //add incoming type with the 'value' value
-        void newIncomingType(Memory *mem, SmConstant value) {
-            IncomingType *in = (IncomingType *)mem->malloc(sizeof(IncomingType));
-
-            intptr mask = (intptr)incoming & 3;
-            incoming = (IncomingType *) ((intptr)incoming & ~3);
-
-            in->nxt = value == SM_BOGUS ? 0 : incoming;
-            //in->type = CT_INCOMING_VALUE;
-            in->value = value.c;
-
-            incoming = in;
-
-            incoming = (IncomingType *) ((intptr)incoming | mask);
-        }
-
-        //add expected type with the 'value' value
-        void newExpectedType(Memory *mem, SmConstant value) {
-            newConstraint(mem, CT_EXPECTED_TYPE)->value = value.c;
-        }
-
-        Constraint *newConstraint(Memory *mem, int type) {
-            Constraint *o = (Constraint *)mem->malloc(sizeof(Constraint));
-
-            o->nxt = others;
-            o->type = (ConstraintType)type;
-
-            others = o;
-            return o;
-        }
-
-        //add generic constraint ('this' is assignable to 'to')
-        void newGenericConstraint(Memory *mem, StackmapElement *to) {
-            newConstraint(mem, CT_GENERIC)->variable = to;
-        }
-
-        //add generic constraint ('this' is an array, which element is assignable to 'to')
-        void newArrayConversionConstraint(Memory *mem, StackmapElement *to) {
-            assert(!firstArrayCnstr());
-            newConstraint(mem, CT_ARRAY2REF)->variable = to;
-        }
-
-        // return 'modified' flag for the stackmap. the flag is stored in the first bit of the 'incoming' pointer
-        // "modified" is about subroutines: you have to track which locals were changed
-        int isJsrModified() {
-            return (int)(intptr)incoming & 1;
-        }
-
-        //set 'modified' flag for the stackmap. the flag is stored in the first bit of the 'incoming' pointer
-        // "modified" is about subroutines: you have to track which locals were changed
-        void setJsrModified() {
-            incoming = (IncomingType *) ((intptr)incoming | 1);
-        }
-
-        //clear 'modified' flag for the stackmap. the flag is stored in the first bit of the 'incoming' pointer
-        // "modified" is about subroutines: you have to track which locals were changed
-        void clearJsrModified() {
-            incoming = (IncomingType *) ((intptr)incoming & ~1);
-        }
-    };
-
-    //WorkMapElement structure represent an element of the workmap vector -- vector of the derived types
-    //a type might be either constant (or known) (e.g. if some previous instruction has put something on stack or locals)
-    //or sub-definite (e.g. if we've recently passed a branch target and don't know which types were on stack or locals)
-    struct WorkmapElement {
-        //value. two low bits a used to store flags
-        union {
-            _SmConstant const_val;      //either a constant (known-type)
-            StackmapElement *var_ptr;   //or a variable (sub-definite type)
-        };
-
-        //is it a sub-definite (not constant) type?
-        int isVariable() {
-            assert(const_val != SM_NONE);
-            return !((intptr)var_ptr & 1);
-        }
-
-        //get value for the constant (known) verification type
-        SmConstant getConst() {
-            return const_val;
-        }
-
-        //get variable representing sub-definite verification type
-        StackmapElement *getVariable() {
-            return (StackmapElement *) ((intptr)var_ptr & ~3);
-        }
-
-        //when we need to compae to some unmergable type we don;t need to interate thru the list
-        //also used to assert that an IncomingValue constraint exists
-        SmConstant getAnyPossibleValue() {
-            SmConstant ret = isVariable() ? getVariable()->getAnyIncomingValue() : const_val;
-            assert(ret != SM_NONE);
-            return ret;
-        }
-
-        // return 'modified' flag for the workmap element. the flag is stored in the second bit of the union
-        //"modified" is about subroutines: you have to track which locals were changed
-        //it's easier to think of all the constants as "modified"
-        int isJsrModified() {
-            return (int)(intptr)var_ptr & 3;
-        }
-
-        // set 'modified' flag for the workmap element. the flag is stored in the second bit of the union
-        void setJsrModified() {
-            if( isVariable() ) {
-                var_ptr = (StackmapElement*)((intptr)var_ptr | 2);
-            }
-        }
-    };
-
-    //WorkmapElement type with some constructors
-    struct _WorkmapElement : WorkmapElement {
-        _WorkmapElement(WorkmapElement other) {
-            const_val = other.const_val;
-        }
-
-        _WorkmapElement(StackmapElement *s) {
-            var_ptr = s;
-            if( s->isJsrModified() ) {
-                setJsrModified();
-            }
-        }
-
-        _WorkmapElement(SmConstant c) {
-            const_val = c;
-        }
-    };
-
-    //Store various data for the given instruction. Possible data are: StackMap vector, WorkMap vector,
-    //Subroutine-specific data
-    //for a single instruction it might be either
-    // 1) no data
-    // 2) workmap only
-    // 3) stackmap only
-    // 4) stackmap and subroutine data. in this case two PropsHead structures are created the first one for the StackMap,
-    //    it's 'next' points to the second PropsHead containing Subroutine info. In this case second PropsHead keeps 0xFFFF
-    //    instead of 'instr'
-    // the list is used to organize storing Props as a HashTable
-    struct PropsHead : public PropsHeadBase {
-        typedef MapHead<WorkmapElement> WorkmapHead;
-        typedef MapHead<StackmapElement> StackmapHead;
-
-        // really one bit is used: FF_ISWORKMAP. TODO: merge with (Stack|Work)map->flags
-        unsigned short instr_flags; 
-
-        //possible flag value
-        static const short FF_ISWORKMAP = 1;
-
-        //actual properties
-        union {
-            WorkmapHead workmap;
-            StackmapHead stackmap;
-        };
-
-        //get workmap stored here
-        WorkmapHead *getWorkmap() {
-            assert(is_workmap());
-            return &workmap;
-        }
-
-        //get stackmap stored here
-        StackmapHead *getStackmap() {
-            assert(!is_workmap());
-            return &stackmap;
-        }
-
-        //get subroutine data stored here
-        SubroutineData *getSubrData(int el_cnt) {
-            assert(instr == 0xFFFF);
-            return (SubroutineData *) &stackmap.elements[el_cnt];
-        }
-
-        //is it a workmap?
-        int is_workmap() {
-            return instr_flags & FF_ISWORKMAP;
-        }
-
-        //set 'is workmap' flag
-        void set_as_workmap() {
-            instr_flags |= FF_ISWORKMAP;
-        }
-
-        //clear flag
-        void clearInstrFlag(short flag) {
-            instr_flags &= ~flag;
-        }
-    };
-
-
-} // namespace CPVerifier_5
-
-#endif
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Mikhail Loenko, Vladimir Molotkov
+ */  
+
+#ifndef __STACKMAP5_H__
+#define __STACKMAP5_H__
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "../base/stackmap_x.h"
+
+#ifdef WIN32
+#define intptr int64
+#else
+#define intptr long
+#endif
+
+using namespace CPVerifier;
+
+namespace CPVerifier_5 {
+
+    struct StackmapElement;
+    struct WorkmapElement;
+
+    //possible relations between verificaton types
+    enum ConstraintType {
+        CT_GENERIC = 0,         // sub-defined type A is assignable to sub-defined type B
+        CT_ARRAY2REF = 1,       // A is a known-type array. element of A is assignable to sub-defined type B
+        CT_EXPECTED_TYPE = 2,   // sub-defined type A is assignable to known-type B
+        CT_INCOMING_VALUE = 3   // known-type A is assignable to sub-defined type B
+    };
+
+    //structure for maintaining subroutine-specific data
+    //until subroutine is passed with the second (dataflow) pass we record to the wait list all JSR instructions
+    //calling this subroutine. Once the subroutine is over we continue 2nd pass for each wait-listed instruction
+    //see vf_Context_Base::SubroutineDone
+    struct SubroutineData {
+        Address caller;         //first JSR instruction that called this subroutine
+        short retCount;         //number of ret instructions for this subroutine
+        uint8  subrDataflowed;   // =1 if dataflow pass for the subroutine is over
+    };
+
+    //list constant verification type (i.e. known-type) that are assignable to some sub-definite type (i.e. StackMapElement)
+    //see StackmapElement
+    struct IncomingType {
+        //next in the list
+        IncomingType *nxt;
+
+        //value of the verification type recorded as int
+        //TODO: don't remember why it's 'int' rather than 'SmConstant'
+        int value;
+
+        //simple next in the list
+        IncomingType *next() {
+            return nxt;
+        }
+    };
+
+    //list of constraints for some sub-definite verification type (i.e. StackMapElement)
+    //see StackmapElement
+
+    struct Constraint {
+        //next in the list
+        Constraint *nxt;
+
+        //either
+        union {
+            StackmapElement *variable; // sub-definite verificarion type
+            int value;                 // or constant (known) verification type rcorded as int
+        };
+
+        //consatrint type
+        ConstraintType type;
+
+        //next constrait of type 't'
+        static Constraint *next(Constraint *cur, int t) {
+            while( cur && cur->type != t ) {
+                cur = (Constraint*)cur->next();
+            }
+            return cur;
+        }
+
+        //simple next in the list
+        Constraint *next() {
+            return nxt;
+        }
+    };
+
+    //constraint of the CT_EXPECTED_TYPE type: sub-defined type A is assignable to known-type B
+    struct ExpectedType : Constraint {
+        ExpectedType *next() {
+            return (ExpectedType *) Constraint::next(Constraint::next(), CT_EXPECTED_TYPE);
+        }
+    };
+
+    //constraint of the CT_GENERIC type: sub-defined type A is assignable to sub-defined type B
+    struct GenericCnstr : Constraint {
+        GenericCnstr *next() {
+            return (GenericCnstr *) Constraint::next(Constraint::next(), CT_GENERIC);
+        }
+    };
+
+    //constraint of the CT_ARRAY2REF type: A is a known-type array. element of A is assignable to sub-defined type B
+    struct ArrayCnstr : Constraint {
+        //there can be only one CT_ARRAY2REF per StackMap Element
+        ArrayCnstr *next() {
+            assert(0);
+            return 0;
+        }
+    };
+
+
+    //StackMapElement structure represens sub-definite verification type: we don't know what type is it, but
+    //we know about instructions that expect ExpectedTypes here and we know that IncomingValues can be here
+    //we also know that this type must be assignable to other sub-defenite types as indicated by CT_GENERIC
+    //constrains and there can be special limitations represented by CT_ARRAY2REF constraints
+    struct StackmapElement { //TODO: should be rewritten to save footprint
+        //list of IncomingType constraint
+        IncomingType *incoming;
+
+        //list of all the conatraints of other types
+        Constraint *others;
+
+        //return value from any IncomingType constraint
+        //when we need to compae to some unmergable type we don;t need to interate thru the list
+        //also used to assert that an IncomingValue constraint exists
+        SmConstant getAnyIncomingValue() {
+            assert(firstIncoming());
+            return firstIncoming()->value;
+        }
+
+        //return first IncomingType constraint
+        IncomingType *firstIncoming() {
+            //TODO: I have to store somewhere the "modified" bit. Sorry.
+            return (IncomingType*)( (intptr)incoming & ~3 );
+        }
+
+        //return first conatrint of any type except IncomingType
+        Constraint *firstOthers() {
+            return others;
+        }
+
+        //return first CT_EXPECTED_TYPE constraint
+        ExpectedType *firstExpected() {
+            return (ExpectedType*)Constraint::next(others, CT_EXPECTED_TYPE);
+        }
+
+        //return first CT_GENERIC constraint
+        GenericCnstr *firstGenericCnstr() {
+            return (GenericCnstr*)Constraint::next(others, CT_GENERIC);
+        }
+
+        //return first (and the only) CT_ARRAY2REF constraint
+        ArrayCnstr *firstArrayCnstr() {
+            return (ArrayCnstr*)Constraint::next(others, CT_ARRAY2REF);
+        }
+
+        //clean-up
+        void init() {
+            incoming = 0;
+            others = 0;
+        }
+
+        //add incoming type with the 'value' value
+        void newIncomingType(Memory *mem, SmConstant value) {
+            IncomingType *in = (IncomingType *)mem->malloc(sizeof(IncomingType));
+
+            intptr mask = (intptr)incoming & 3;
+            incoming = (IncomingType *) ((intptr)incoming & ~3);
+
+            in->nxt = value == SM_BOGUS ? 0 : incoming;
+            //in->type = CT_INCOMING_VALUE;
+            in->value = value.c;
+
+            incoming = in;
+
+            incoming = (IncomingType *) ((intptr)incoming | mask);
+        }
+
+        //add expected type with the 'value' value
+        void newExpectedType(Memory *mem, SmConstant value) {
+            newConstraint(mem, CT_EXPECTED_TYPE)->value = value.c;
+        }
+
+        Constraint *newConstraint(Memory *mem, int type) {
+            Constraint *o = (Constraint *)mem->malloc(sizeof(Constraint));
+
+            o->nxt = others;
+            o->type = (ConstraintType)type;
+
+            others = o;
+            return o;
+        }
+
+        //add generic constraint ('this' is assignable to 'to')
+        void newGenericConstraint(Memory *mem, StackmapElement *to) {
+            newConstraint(mem, CT_GENERIC)->variable = to;
+        }
+
+        //add generic constraint ('this' is an array, which element is assignable to 'to')
+        void newArrayConversionConstraint(Memory *mem, StackmapElement *to) {
+            assert(!firstArrayCnstr());
+            newConstraint(mem, CT_ARRAY2REF)->variable = to;
+        }
+
+        // return 'modified' flag for the stackmap. the flag is stored in the first bit of the 'incoming' pointer
+        // "modified" is about subroutines: you have to track which locals were changed
+        int isJsrModified() {
+            return (int)(intptr)incoming & 1;
+        }
+
+        //set 'modified' flag for the stackmap. the flag is stored in the first bit of the 'incoming' pointer
+        // "modified" is about subroutines: you have to track which locals were changed
+        void setJsrModified() {
+            incoming = (IncomingType *) ((intptr)incoming | 1);
+        }
+
+        //clear 'modified' flag for the stackmap. the flag is stored in the first bit of the 'incoming' pointer
+        // "modified" is about subroutines: you have to track which locals were changed
+        void clearJsrModified() {
+            incoming = (IncomingType *) ((intptr)incoming & ~1);
+        }
+    };
+
+    //WorkMapElement structure represent an element of the workmap vector -- vector of the derived types
+    //a type might be either constant (or known) (e.g. if some previous instruction has put something on stack or locals)
+    //or sub-definite (e.g. if we've recently passed a branch target and don't know which types were on stack or locals)
+    struct WorkmapElement {
+        //value. two low bits a used to store flags
+        union {
+            _SmConstant const_val;      //either a constant (known-type)
+            StackmapElement *var_ptr;   //or a variable (sub-definite type)
+        };
+
+        //is it a sub-definite (not constant) type?
+        int isVariable() {
+            assert(const_val != SM_NONE);
+            return !((intptr)var_ptr & 1);
+        }
+
+        //get value for the constant (known) verification type
+        SmConstant getConst() {
+            return const_val;
+        }
+
+        //get variable representing sub-definite verification type
+        StackmapElement *getVariable() {
+            return (StackmapElement *) ((intptr)var_ptr & ~3);
+        }
+
+        //when we need to compae to some unmergable type we don;t need to interate thru the list
+        //also used to assert that an IncomingValue constraint exists
+        SmConstant getAnyPossibleValue() {
+            SmConstant ret = isVariable() ? getVariable()->getAnyIncomingValue() : const_val;
+            assert(ret != SM_NONE);
+            return ret;
+        }
+
+        // return 'modified' flag for the workmap element. the flag is stored in the second bit of the union
+        //"modified" is about subroutines: you have to track which locals were changed
+        //it's easier to think of all the constants as "modified"
+        int isJsrModified() {
+            return (int)(intptr)var_ptr & 3;
+        }
+
+        // set 'modified' flag for the workmap element. the flag is stored in the second bit of the union
+        void setJsrModified() {
+            if( isVariable() ) {
+                var_ptr = (StackmapElement*)((intptr)var_ptr | 2);
+            }
+        }
+    };
+
+    //WorkmapElement type with some constructors
+    struct _WorkmapElement : WorkmapElement {
+        _WorkmapElement(WorkmapElement other) {
+            const_val = other.const_val;
+        }
+
+        _WorkmapElement(StackmapElement *s) {
+            var_ptr = s;
+            if( s->isJsrModified() ) {
+                setJsrModified();
+            }
+        }
+
+        _WorkmapElement(SmConstant c) {
+            const_val = c;
+        }
+    };
+
+    //Store various data for the given instruction. Possible data are: StackMap vector, WorkMap vector,
+    //Subroutine-specific data
+    //for a single instruction it might be either
+    // 1) no data
+    // 2) workmap only
+    // 3) stackmap only
+    // 4) stackmap and subroutine data. in this case two PropsHead structures are created the first one for the StackMap,
+    //    it's 'next' points to the second PropsHead containing Subroutine info. In this case second PropsHead keeps 0xFFFF
+    //    instead of 'instr'
+    // the list is used to organize storing Props as a HashTable
+    struct PropsHead : public PropsHeadBase {
+        typedef MapHead<WorkmapElement> WorkmapHead;
+        typedef MapHead<StackmapElement> StackmapHead;
+
+        // really one bit is used: FF_ISWORKMAP. TODO: merge with (Stack|Work)map->flags
+        unsigned short instr_flags; 
+
+        //possible flag value
+        static const short FF_ISWORKMAP = 1;
+
+        //actual properties
+        union {
+            WorkmapHead workmap;
+            StackmapHead stackmap;
+        };
+
+        //get workmap stored here
+        WorkmapHead *getWorkmap() {
+            assert(is_workmap());
+            return &workmap;
+        }
+
+        //get stackmap stored here
+        StackmapHead *getStackmap() {
+            assert(!is_workmap());
+            return &stackmap;
+        }
+
+        //get subroutine data stored here
+        SubroutineData *getSubrData(int el_cnt) {
+            assert(instr == 0xFFFF);
+            return (SubroutineData *) &stackmap.elements[el_cnt];
+        }
+
+        //is it a workmap?
+        int is_workmap() {
+            return instr_flags & FF_ISWORKMAP;
+        }
+
+        //set 'is workmap' flag
+        void set_as_workmap() {
+            instr_flags |= FF_ISWORKMAP;
+        }
+
+        //clear flag
+        void clearInstrFlag(short flag) {
+            instr_flags &= ~flag;
+        }
+    };
+
+
+} // namespace CPVerifier_5
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/stackmap_5.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/stackmap_5.h
            ('svn:executable' removed)



Mime
View raw message