harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From var...@apache.org
Subject svn commit: r540926 [1/5] - in /harmony/enhanced/drlvm/trunk/vm: include/ include/open/ jitrino/src/codegenerator/ia32/ jitrino/src/jet/ jitrino/src/main/ jitrino/src/optimizer/ jitrino/src/shared/ jitrino/src/translator/ jitrino/src/translator/java/ j...
Date Wed, 23 May 2007 11:22:57 GMT
Author: varlax
Date: Wed May 23 04:22:55 2007
New Revision: 540926

URL: http://svn.apache.org/viewvc?view=rev&rev=540926
Log:
Applied HARMONY-3874 [dlrvm][jit] "Lazy resolution" feature implementation in Jitrino compiler

Modified:
    harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h
    harmony/enhanced/drlvm/trunk/vm/include/jit_runtime_support.h
    harmony/enhanced/drlvm/trunk/vm/include/open/vm.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/val.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Inst.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opnd.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/devirtualizer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryoptrep.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifier.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifytaus.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/Type.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/shared/Type.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaLabelPrepass.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaTranslator.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaTranslator.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/VMInterface.h
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlJITInterface.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/Class.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/type.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/C_Interface.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Resolve.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/method.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/init/vm_init.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jit/jit_runtime_support.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/vm_stats.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/jit_intf.h Wed May 23 04:22:55 2007
@@ -219,7 +219,7 @@
 // is replaced with class_property_is_interface2.
 VMEXPORT Boolean class_property_is_interface(Class_Handle ch);
 
-VMEXPORT Boolean        class_get_array_num_dimensions(Class_Handle cl);
+VMEXPORT uint32 class_get_num_array_dimensions(Class_Handle cl, unsigned short cpIndex);
 
 VMEXPORT ClassLoaderHandle class_get_class_loader(Class_Handle c);
 
@@ -233,7 +233,6 @@
 class_load_class_by_name(const char *name,
                          Class_Handle c);
 
-
 VMEXPORT Class_Handle
 class_load_class_by_descriptor(const char *descr,
                                Class_Handle c);
@@ -243,6 +242,9 @@
                                 const char *name,
                                 const char *descr);
 
+/// Returns 'TRUE' if the entry by the given cp_index is resolved.
+VMEXPORT Boolean  class_is_cp_entry_resolved(Compile_Handle ch, Class_Handle clazz, unsigned cp_index);
+
 // This function is for native library support
 // It takes a class name with .s not /s.
 VMEXPORT Class_Handle class_find_loaded(ClassLoaderHandle, const char*);
@@ -255,8 +257,7 @@
 // The following do not cause constant pools to be resolve, if they are not
 // resolved already
 //
-VMEXPORT Class_Handle resolve_class_from_constant_pool(Class_Handle c_handle,
-                                                        unsigned index);
+
 VMEXPORT const char  *const_pool_get_field_name(Class_Handle cl,
                                                  unsigned index);
 VMEXPORT const char  *const_pool_get_field_class_name(Class_Handle cl,

Modified: harmony/enhanced/drlvm/trunk/vm/include/jit_runtime_support.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/jit_runtime_support.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/jit_runtime_support.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/jit_runtime_support.h Wed May 23 04:22:55 2007
@@ -440,53 +440,158 @@
  */
 
  /////
- /// Runtime resolution routine
+ /// Runtime resolution routines
  /////
 
-    VM_RT_RESOLVE = 801,
-  
-/**
- * @param The parameters are the following:
- *        arg\ Class handle
- *        arg\ Constant pool index of an item to be resolved
- *        arg\ A java byte code instruction (<code>JavaByteCodes</code>) 
- *             the resolution is performed for
- *
- * The helper performs resolution of symbolic references during runtime.
- * If resolution failed, the helper throws appropriate <code>LinkageError</code>.
- * Otherwise, the value depends on byte code passed:
- *
- *  === JavaByteCodes ===          === result of call ===
- *
- *  OPCODE_INVOKESTATIC:        resolve_static_method
- *
- *  OPCODE_INVOKEINTERFACE:     resolve_interface_method
- *
- *  OPCODE_INVOKEVIRTUAL,
- *
- *  OPCODE_INVOKESPECIAL:       resolve_virtual_method
- *
- *  OPCODE_INSTANCEOF,
- *
- *  OPCODE_CHECKCAST,
- *
- *  OPCODE_MULTIANEWARRAY       resolve_class
- *
- *  OPCODE_ANEWARRAY:           class_get_array_of_class(resolve_class())
- *
- *  OPCODE_NEW:                 resolve_class_new
- *
- *  OPCODE_GETFIELD,
- *
- *  OPCODE_PUTFIELD:            resolve_nonstatic_field
- *
- *  OPCODE_PUTSTATIC,
- *
- *  OPCODE_GETSTATIC:           resolve_static_field
- *
- * The helper initializes class if the class hasn't been initialized yet
- * for <code>PUTSTATIC</code> and <code>GETSTATIC</code>.
- */
+ 
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *
+    * @return new object
+    *
+    * Creates and returns new object for the given (class, cp_index)
+    * Loads and initialize class if needed
+    */
+    VM_RT_NEWOBJ_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *        arg\ Array size
+    *
+    * @return new array
+    *
+    * Creates and returns new array of the given size
+    * with type referenced by (class, cp_index)
+    * Loads and initialize array class if needed
+    */
+    VM_RT_NEWARRAY_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *
+    * @return field offset
+    *
+    * Returns an offset of the field referenced
+    * by the given (class, cp_index) pair
+    * Field's class must be loaded and  initialized
+    * before this helper call.
+    */
+    VM_RT_GET_NONSTATIC_FIELD_OFFSET_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *
+    * @return field address
+    *
+    * Returns an address of the field referenced
+    * by the given (class, cp_index) pair
+    * Loads and initializes field's class if needed
+    */
+    VM_RT_GET_STATIC_FIELD_ADDR_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *        arg\ Object to check cast
+    *
+    * @return third parameter
+    *
+    * Check if the given object can be casted to 
+    * the type referenced by (class, cp_index) pair
+    * Throws class cast exception if object can't be casted
+    * Returns the object instance (3rd parameter) if cast is allowed
+    * Loads and intialize cast type if needed.
+    */
+    VM_RT_CHECKCAST_WITHRESOLVE,
+    
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *        arg\ Object to check cast
+    *
+    * @return TRUE or FALSE
+    *
+    * Check if the given object is instance of 
+    * the type referenced by (class, cp_index) pair
+    * Return TRUE if object is instance of the given type
+    * or FALSE otherwise
+    * Loads and intialize 'instanceof' type if needed.
+    */
+    VM_RT_INSTANCEOF_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *
+    * @return indirect address of the static method
+    *
+    * Returns the indirect address of the static method referenced
+    * by (class, cp_index) pair
+    * Loads and intialize method's class type if needed.
+    */
+    VM_RT_GET_INVOKESTATIC_ADDR_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *        arg\ Object
+    *
+    * @return indirect address of the interface method
+    *
+    * Returns the indirect address of the interface method referenced
+    * by (class, cp_index) pair for the given object
+    */
+    VM_RT_GET_INVOKEINTERFACE_ADDR_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *        arg\ Object
+    *
+    * @return indirect address of the virtual method
+    *
+    * Returns the indirect address of the virtual method referenced
+    * by (class, cp_index) pair for the given object
+    */
+    VM_RT_GET_INVOKEVIRTUAL_ADDR_WITHRESOLVE,
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *
+    * @return indirect address of the special method
+    *
+    * Returns the indirect address of the special method referenced
+    * by (class, cp_index) pair 
+    */
+    VM_RT_GET_INVOKE_SPECIAL_ADDR_WITHRESOLVE,
+
+    /**
+    * @param The parameters are the following:
+    *        arg\ Class_Handle - enclosing class handle
+    *        arg\ Constant pool index
+    *
+    * @return Class_Handle
+    *
+    * Returns the class handle referenced
+    * by (class, cp_index) pair 
+    * Loads and initialize class if needed
+    */
+    VM_RT_INITIALIZE_CLASS_WITHRESOLVE,
+
 
  /////
  // Non-VM specific helpers for the JIT

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/vm.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/vm.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/vm.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/vm.h Wed May 23 04:22:55 2007
@@ -826,6 +826,14 @@
  */
 VMEXPORT Class_Handle type_info_get_class(Type_Info_Handle tih);
 
+
+/**
+* Gets Type_Info_Handle from the given type name.
+* Does'n resolve type if not resolved
+*/
+
+VMEXPORT Type_Info_Handle type_info_create_from_java_descriptor(ClassLoaderHandle cl, const char* typeName);
+
 /**
  * Get the class if <code>type_info_is_reference</code> or 
  * <code>type_info_is_unboxed</code> returned <code>TRUE</code>. 
@@ -854,6 +862,18 @@
  * of other functions provided in this interface.
  */
 VMEXPORT VM_Data_Type type_info_get_type(Type_Info_Handle tih);
+
+
+/**
+* Checks if a type referenced by the given type info handle is resolved
+*/
+VMEXPORT Boolean type_info_is_resolved(Type_Info_Handle tih);
+
+/**
+* Returns number of array dimension of a type referenced by the 
+* given type info handle.
+*/
+VMEXPORT uint32 type_info_get_num_array_dimensions(Type_Info_Handle tih);
 
 ////
 // end type info-related functions.

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp Wed May 23 04:22:55 2007
@@ -799,6 +799,7 @@
 
         void * handlerAddr=handler->getCodeStartAddr();
         ObjectType * exceptionType = (ObjectType*)((CatchEdge*)edge)->getType();
+        assert(!exceptionType->isUnresolvedType());
         exceptionHandlerInfos.push_back(
             ExceptionHandlerInfo(regionStart, regionEnd, handlerAddr, exceptionType, isExceptObjDead)
             );

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32GCSafePoints.cpp Wed May 23 04:22:55 2007
@@ -421,6 +421,19 @@
     }
 }
 
+static bool isStaticFieldPtrDefWithCall(Inst* inst) {
+    if (inst->hasKind(Inst::Kind_CallInst)) {
+        CallInst* callInst = (CallInst*)inst;
+        Opnd::RuntimeInfo * rt = callInst->getRuntimeInfo();
+        if (rt && rt->getKind() == Opnd::RuntimeInfo::Kind_HelperAddress
+            && ((CompilationInterface::RuntimeHelperId)(POINTER_SIZE_INT)rt->getValue(0)
+                    == CompilationInterface::Helper_GetStaticFieldAddrWithResolve))
+        {
+            return true;
+        }
+    }
+    return false;
+}
 
 void GCSafePointsInfo::updatePairsOnInst(Inst* inst, GCSafePointPairs& res) {
     runLivenessFilter(inst, res);//filter pairs with dead mptrs from list
@@ -438,6 +451,11 @@
     Opnd* opnd = inst->getOpnd(defIndex);
     Type* opndType = opnd->getType();
     if (!opndType->isObject() && !opndType->isManagedPtr()) {
+        return;
+    }
+    if (isStaticFieldPtrDefWithCall(inst)) {
+        removePairByMPtrOpnd(res, opnd);
+        staticMptrs.insert(opnd);
         return;
     }
     if (mode == MODE_1_FIX_BASES) { //3 addr form

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp Wed May 23 04:22:55 2007
@@ -1734,8 +1734,18 @@
 CG_OpndHandle * InstCodeSelector::addOffset(Type *pointerType, CG_OpndHandle* refHandle,
                                CG_OpndHandle* offsetHandle)
 { 
-    ICS_ASSERT(0);
-    return 0;
+    Opnd* base = (Opnd*)refHandle;
+    Opnd* offsetOpnd = (Opnd*)offsetHandle;
+    Type* fieldRefType = pointerType;
+    assert(base->getType()->isObject());
+    assert(offsetOpnd->getType()->isInteger());
+    assert(fieldRefType->isManagedPtr());
+
+#ifdef _EM64T_
+    return simpleOp_I8(Mnemonic_ADD, fieldRefType, (Opnd*)base, offsetOpnd);
+#else
+    return simpleOp_I4(Mnemonic_ADD, fieldRefType, (Opnd*)base, offsetOpnd);
+#endif
 }
 
 //_______________________________________________________________________________________________________________
@@ -2780,6 +2790,7 @@
         dstOpnd  = tlsBase;
         break;
     }
+    //vmhelper slow paths
     case CompilationInterface::Helper_NewObj_UsingVtable:
     case CompilationInterface::Helper_NewVector_UsingVtable:
     case CompilationInterface::Helper_ObjMonitorEnter:
@@ -2788,7 +2799,21 @@
     case CompilationInterface::Helper_LdInterface:
     case CompilationInterface::Helper_Cast:
     case CompilationInterface::Helper_IsInstanceOf:
-    {
+    
+    //helpers used by JIT in lazy resolution mode
+    case CompilationInterface::Helper_NewObjWithResolve:
+    case CompilationInterface::Helper_NewArrayWithResolve:
+    case CompilationInterface::Helper_GetNonStaticFieldOffsetWithResolve:
+    case CompilationInterface::Helper_GetStaticFieldAddrWithResolve:
+    case CompilationInterface::Helper_CheckCastWithResolve:
+    case CompilationInterface::Helper_InstanceOfWithResolve:
+    case CompilationInterface::Helper_GetInvokeStaticAddrWithResolve:
+    case CompilationInterface::Helper_GetInvokeInterfaceAddrWithResolve:
+    case CompilationInterface::Helper_GetInvokeVirtualAddrWithResolve:
+    case CompilationInterface::Helper_GetInvokeSpecialAddrWithResolve:
+    case CompilationInterface::Helper_InitializeClassWithResolve:
+    case CompilationInterface::Helper_NewMultiArray:
+{
         dstOpnd = retType==NULL ? NULL: irManager.newOpnd(retType);
         CallInst * callInst=irManager.newRuntimeHelperCallInst(callId, numArgs, (Opnd**)args, dstOpnd);
         appendInsts(callInst);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/bcproc.cpp Wed May 23 04:22:55 2007
@@ -386,7 +386,14 @@
         get_args_info(is_static, jinst.op0, args, &retType);
         
         Method_Handle meth = NULL;
-
+        unsigned short cpIndex = (unsigned short)jinst.op0;
+        bool lazy = m_lazy_resolution;
+        bool resolve = !lazy || class_is_cp_entry_resolved(m_compileHandle, m_klass, cpIndex);
+        if (!resolve) {
+            assert(lazy);
+            gen_invoke(opkod, NULL, cpIndex, args, retType);
+            return;
+        }
         if (opkod == OPCODE_INVOKESTATIC) {
             meth = resolve_static_method(m_compileHandle, m_klass,
                                             jinst.op0);
@@ -422,7 +429,7 @@
         else {
             meth = resolve_virtual_method(m_compileHandle, m_klass, jinst.op0);
         }
-        gen_invoke(opkod, meth, args, retType);
+        gen_invoke(opkod, meth, 0, args, retType);
         return;
     }
     switch(jinst.opcode) {
@@ -483,64 +490,19 @@
 
     switch(jinst.opcode) {
     case OPCODE_NEW:
-        {
-        Class_Handle klass;
-        klass = vm_resolve_class_new(m_compileHandle, m_klass, jinst.op0);
-        gen_new(klass);
-        }
+        gen_new(m_klass, (unsigned short)jinst.op0);
         break;
     case OPCODE_PUTSTATIC:
     case OPCODE_GETSTATIC:
-        {
-        jtype jt = to_jtype(class_get_cp_field_type(
-                                    m_klass, (unsigned short)jinst.op0));
-        const bool is_put = jinst.opcode == OPCODE_PUTSTATIC;
-        Field_Handle fld;
-        fld = resolve_static_field(m_compileHandle, m_klass, 
-                                    jinst.op0, is_put);
-        if (fld && !field_is_static(fld)) {
-            fld = NULL;
-        }
-        if (fld != NULL) {
-            Class_Handle klass = field_get_class(fld);
-            assert(klass);
-            if (klass != m_klass && class_needs_initialization(klass)) {
-                gen_call_vm(ci_helper_o, rt_helper_init_class, 0, klass);
-            }
-        }
-        gen_static_op(jinst.opcode, jt, fld);
-        }
-        break;
     case OPCODE_PUTFIELD:
     case OPCODE_GETFIELD:
-        // stack: [objref, value] ; op0 -
-        {
-        jtype jt = to_jtype(class_get_cp_field_type(
-                                    m_klass, (unsigned short)jinst.op0));
-        bool is_put = jinst.opcode == OPCODE_PUTFIELD;
-        
-        Field_Handle fld = NULL;
-        fld = resolve_nonstatic_field(m_compileHandle, m_klass, 
-                                    jinst.op0, is_put);
-        gen_field_op(jinst.opcode, jt, fld);
-        }
+        gen_field_op(jinst.opcode, m_klass, (unsigned short)jinst.op0);
         break;
     case OPCODE_ARRAYLENGTH:
         gen_array_length();
         break;
     case OPCODE_ANEWARRAY:
-        {
-        Allocation_Handle ah = 0;
-        Class_Handle klass = resolve_class(m_compileHandle, m_klass, 
-                                           jinst.op0);
-        if (klass != NULL) {
-            klass = class_get_array_of_class(klass);
-        }
-        if (klass != NULL) {
-            ah = class_get_allocation_handle(klass);
-        }
-        gen_new_array(ah);
-        }
+        gen_new_array(m_klass, (unsigned short)jinst.op0);
         break;
     case OPCODE_NEWARRAY:
         {
@@ -563,11 +525,7 @@
         }
         break;
     case OPCODE_MULTIANEWARRAY:
-        {
-        Class_Handle klass = NULL;
-        klass = resolve_class(m_compileHandle, m_klass, jinst.op0);
-        gen_multianewarray(klass, jinst.op1);
-        }
+        gen_multianewarray(m_klass, (unsigned short)jinst.op0, jinst.op1);
         break;
     case OPCODE_MONITORENTER:
     case OPCODE_MONITOREXIT:
@@ -575,12 +533,7 @@
         break;
     case OPCODE_CHECKCAST:
     case OPCODE_INSTANCEOF:
-        {
-        const bool chk = jinst.opcode == OPCODE_CHECKCAST;
-        Class_Handle klazz = NULL;
-        klazz = resolve_class(m_compileHandle, m_klass, jinst.op0);
-        gen_instanceof_cast(chk, klazz);
-        }
+        gen_instanceof_cast(jinst.opcode, m_klass, (unsigned short)jinst.op0);
         break;
     default: assert(false); break;
     }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg.h Wed May 23 04:22:55 2007
@@ -102,6 +102,23 @@
     return slots;
 }
 
+/** the class is used by codegen internally to keep field information */
+class FieldOpInfo {
+public:
+    FieldOpInfo(Field_Handle f, Class_Handle h, unsigned short i, JavaByteCodes oc) 
+        : fld(f), enclClass(h), cpIndex(i), opcode(oc){}
+
+    bool isGet() const {return opcode == OPCODE_GETFIELD || opcode == OPCODE_GETSTATIC;}
+    bool isPut() const {return !isGet();}
+    bool isStatic() const {return opcode == OPCODE_GETSTATIC || opcode == OPCODE_PUTSTATIC;}
+
+
+    Field_Handle    fld;
+    Class_Handle    enclClass;
+    unsigned short  cpIndex;
+    JavaByteCodes   opcode;
+};
+
 /**
  * Code generation routines for most of byte code instructions.
  *
@@ -116,6 +133,8 @@
     {
         m_pmfPipeline = NULL;
         m_pmf = NULL;
+        m_lazy_resolution = false;
+        m_compileHandle = NULL;
     }
 
     /**
@@ -163,24 +182,12 @@
      */
     void gen_ldc(void);
     /**
-     * @brief Generates PUTFIELD and GETFIELD operations.
-     *
-     * Simply invokes do_field_op().
-     */
-    void gen_field_op(JavaByteCodes op, jtype jt, Field_Handle fld);
-    /**
-     * @brief Generates PUTSTATIC and GETSTATIC operations.
+     * @brief Generates PUTFIELD/GETFIELD/PUTSTATIC/GETSTATIC operations.
      *
-     * Simply invokes do_field_op().
      */
-    void gen_static_op(JavaByteCodes op, jtype jt, Field_Handle fld);
-    /**
-     * @brief Do all the job for gen_static_op() and gen_field_op().
-     *
-     * Invokes gen_check_null() for GETFIELD and PUTFIELD.
-     */
-    void do_field_op(JavaByteCodes op, jtype jt, Field_Handle fld);
-
+    void gen_field_op(JavaByteCodes opcode,  Class_Handle enclClass, unsigned short cpIndex);
+    
+    
     /**
     * @brief Generates modification watchpoints if VM need it.
     *
@@ -213,7 +220,7 @@
     /**
      * @brief Generates code for INVOKE instructions.
      */
-    void gen_invoke(JavaByteCodes opcod, Method_Handle meth, 
+    void gen_invoke(JavaByteCodes opcod, Method_Handle meth, unsigned short cpIndex,
                     const ::std::vector<jtype>& args, jtype retType);
 
     /**
@@ -265,21 +272,22 @@
     /**
      * @brief Generates code for NEW instruction.
      */
-    void gen_new(Class_Handle klass);
+    void gen_new(Class_Handle enclClass, unsigned short cpIndex);
     /**
      * @brief Generates ANEWARRAY, NEWARRAY.
      */
     void gen_new_array(Allocation_Handle ah);
+    void gen_new_array(Class_Handle enclClass, unsigned cpIndex);
     /**
      * @brief Generates MULTIANEWARRAY.
      */
-    void gen_multianewarray(Class_Handle klass, unsigned num_dims);
+    void gen_multianewarray(Class_Handle enclClass, unsigned short cpIndex, unsigned num_dims);
     /**
      * @brief Generates code for INSTANCEOF or CHECKCAST operations.
      * @param chk - if \b true, generates CHECKCAST, INSTANCEOF otherwise.
      * @param klass - Class_Handle of the class to cast to.
      */
-    void gen_instanceof_cast(bool chk, Class_Handle klass);
+    void gen_instanceof_cast(JavaByteCodes opcode, Class_Handle enclClass, unsigned short cpIndex);
     /**
      * @brief Generates code for MONITOREXTERN and MONITOREXIT.
      */
@@ -463,8 +471,9 @@
      * The opcode may be one of AASTORE, PUTFIELD or PUTSTATIC.
      *
      * For AASTORE \c fieldHandle must be \b NULL.
+     * For AASTORE \c fieldSlotAddress is not used
      */
-    void gen_write_barrier(JavaByteCodes opcode, Field_Handle fieldHandle);
+    void gen_write_barrier(JavaByteCodes opcode, Field_Handle fieldHandle, Opnd fieldSlotAddress);
 
 
     /**
@@ -1016,6 +1025,13 @@
             m_bbstate->m_last_gr = ar;
         }
     }
+
+    /**
+    * @brief Checks if the class name is vmmagic class
+    * @return  - true if the class name is vmmagic class
+    */
+    static bool is_magic_class(const char* kname);
+
 protected:
     /**
      * @brief Tests whether the specified flag is set in method's compilation
@@ -1082,6 +1098,15 @@
         }
         return to_bool(val);
     }
+
+
+    /**
+    * @brief Do all the job for gen_field_op()
+    *
+    * Invokes gen_check_null() for GETFIELD and PUTFIELD.
+    */
+    void do_field_op(const FieldOpInfo& fieldOp);
+
     /**
      * PMF instance to get arguments from.
      */
@@ -1251,7 +1276,17 @@
      * as some methods may be rejected (seen, but not compiled).
      */
     unsigned     m_methID;
-    
+
+    /**
+    * @brief If 'TRUE' JIT will not ask VM to resolve any unresolved types during compilation
+    */    
+    bool m_lazy_resolution;
+
+    /**
+    * @brief Compilation handle.
+    */    
+    Compile_Handle  m_compileHandle;
+
 };
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_fld_arr.cpp Wed May 23 04:22:55 2007
@@ -129,7 +129,7 @@
     vunref(jt);
     // stack: [.., aref, idx, val]
     if (jt == jobj && helperOk) {
-        gen_write_barrier(m_curr_inst->opcode, NULL);
+        gen_write_barrier(m_curr_inst->opcode, NULL, Opnd(0));
         static const CallSig cs_aastore(CCONV_HELPERS, jobj, i32, jobj);
         unsigned stackFix = gen_stack_to_args(true, cs_aastore, 0);
 #ifdef _EM64T_
@@ -201,82 +201,105 @@
     vpop();
 }
 
-void CodeGen::gen_static_op(JavaByteCodes op, jtype jt, Field_Handle fld) {
-    do_field_op(op, jt, fld);
-}
 
-void CodeGen::gen_field_op(JavaByteCodes op, jtype jt, Field_Handle fld)
-{
-    do_field_op(op, jt, fld);
+void CodeGen::gen_field_op(JavaByteCodes opcode,  Class_Handle enclClass, unsigned short cpIndex) {
+    FieldOpInfo fieldOp(NULL, enclClass, cpIndex, opcode); 
+
+    bool needJVMTI = compilation_params.exe_notify_field_modification 
+                    || compilation_params.exe_notify_field_access;
+    bool lazy = m_lazy_resolution && !needJVMTI; // JVMTI field access helpers are not ready for lazy resolution mode
+    bool resolve = !lazy || class_is_cp_entry_resolved(m_compileHandle, enclClass, cpIndex);
+    if (resolve) {
+        if (!fieldOp.isStatic()) {
+            fieldOp.fld = resolve_nonstatic_field(m_compileHandle, enclClass, cpIndex, fieldOp.isPut());
+        } else {
+            Field_Handle fld = resolve_static_field(m_compileHandle, enclClass,  cpIndex, fieldOp.isPut());
+            if (fld && !field_is_static(fld)) {
+                fld = NULL;
+            }
+            if (fld != NULL) {
+                Class_Handle klass = field_get_class(fld);
+                assert(klass);
+                if (klass != m_klass && class_needs_initialization(klass)) {
+                    gen_call_vm(ci_helper_o, rt_helper_init_class, 0, klass);
+                }
+                fieldOp.fld = fld;
+            }
+        }
+        if(fieldOp.fld == NULL) { 
+            //TODO: we can avoid this check and use lazy resolution code path in this case!
+            assert(!lazy);
+            gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0, enclClass, cpIndex, opcode);
+        }
+    }
+    do_field_op(fieldOp);
 }
 
-void CodeGen::do_field_op(JavaByteCodes opcode, jtype jt, Field_Handle fld)
+
+void CodeGen::do_field_op(const FieldOpInfo& fieldOp)
 {
-    bool field_op = false, get = false; // PUTSTATIC is default
-    unsigned ref_depth = 0;
-    if (opcode == OPCODE_PUTFIELD) {
-        field_op = true;
-        ref_depth = is_wide(jt) ? 2 : 1;
-    }
-    else if (opcode == OPCODE_GETFIELD) {
-        field_op = true;
-        get = true;
-    }
-    else if (opcode == OPCODE_GETSTATIC) {
-        get = true;
-    }
-    else {
-        assert(opcode == OPCODE_PUTSTATIC);
-    }
-    
-    if(fld == NULL) {
-        const JInst& jinst = *m_curr_inst;
-        gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0,
-                       m_klass, jinst.op0, jinst.opcode);
-    }
+    // Presumption: we dont have compressed refs on IA32 and all other 
+    // (64bits) platforms have compressed refs. 
+    // is_ia32() check added below so on IA32 it becomes 'false' during the 
+    // compilation, without access to g_refs_squeeze in runtime.
+    assert(is_ia32() || g_refs_squeeze);
+
+
+    jtype jt = to_jtype(class_get_cp_field_type(fieldOp.enclClass, fieldOp.cpIndex));
     
-    bool fieldIsMagic = fld && field_is_magic(fld);
+    const char* fieldClassName = const_pool_get_field_class_name(fieldOp.enclClass, fieldOp.cpIndex);
+    bool fieldIsMagic = is_magic_class(fieldClassName);
     if (fieldIsMagic) {
         jt = iplatf;
     }
 
-    if (!get && compilation_params.exe_notify_field_modification && !fieldIsMagic)  {
-        gen_modification_watchpoint(opcode, jt, fld);
-    }
-
-    if (!get && ! fieldIsMagic) {
-        gen_write_barrier(opcode, fld);
-    }
-
-    
     Opnd where;
-    if (field_op) {
+    if (!fieldOp.isStatic()) { //generate check null
+        unsigned ref_depth = fieldOp.isPut() ? (is_wide(jt) ? 2 : 1) : 0;
         Val& ref = vstack(ref_depth, true);
         gen_check_null(ref_depth);
-        unsigned fld_offset = fld ? field_get_offset(fld) : 0;
-        where = Opnd(jt, ref.reg(), fld_offset);
-    }
-    else {
-        // static s
-        char * fld_addr = fld ? (char*)field_get_address(fld) : NULL;
-        where = vaddr(jt, fld_addr);
+        if (fieldOp.fld) { //field is resolved -> offset is available
+            unsigned fld_offset = field_get_offset(fieldOp.fld);
+            where = Opnd(jt, ref.reg(), fld_offset);
+        }  else { //field is not resolved -> generate code to request offset
+            static const CallSig cs_get_offset(CCONV_STDCALL, iplatf, i32, i32);
+            gen_call_vm(cs_get_offset, rt_helper_field_get_offset_withresolve, 0, fieldOp.enclClass, fieldOp.cpIndex, fieldOp.isPut());
+            runlock(cs_get_offset);
+            alu(alu_add, gr_ret, ref.as_opnd());
+            where = Opnd(jt, gr_ret, 0);
+        }
+    } else {
+        if (fieldOp.fld) { //field is resolved -> address is available
+            char * fld_addr = (char*)field_get_address(fieldOp.fld);
+            where = vaddr(jt, fld_addr);
+        }  else { //field is not resolved -> generate code to request address
+            static const CallSig cs_get_addr(CCONV_STDCALL, iplatf, i32, i32);
+            gen_call_vm(cs_get_addr, rt_helper_field_get_address_withresolve, 0, fieldOp.enclClass, fieldOp.cpIndex, fieldOp.isPut());
+            runlock(cs_get_addr);
+            where = Opnd(jt, gr_ret, 0);
+        }
     }
     rlock(where);
-    
-    // Presumption: we dont have compressed refs on IA32 and all other 
-    // (64bits) platforms have compressed refs. 
-    // is_ia32() check added below so on IA32 it becomes 'false' during the 
-    // compilation, without access to g_refs_squeeze in runtime.
-    assert(is_ia32() || g_refs_squeeze);
-    
 
-    if (get && compilation_params.exe_notify_field_access && !fieldIsMagic) {
-        gen_access_watchpoint(opcode, jt, fld);
+    // notify all listeners
+
+    if (fieldOp.isPut() && compilation_params.exe_notify_field_modification && !fieldIsMagic)  {
+        gen_modification_watchpoint(fieldOp.opcode, jt, fieldOp.fld);
     }
+    if (fieldOp.isGet() && compilation_params.exe_notify_field_access && !fieldIsMagic) {
+        gen_access_watchpoint(fieldOp.opcode, jt, fieldOp.fld);
+    }
+    if (fieldOp.isPut() && ! fieldIsMagic) {
+        gen_write_barrier(fieldOp.opcode, fieldOp.fld, where);
+    }
+
     
-    if (get) {
 
-        if (field_op) {
+    //generate get/put op
+
+    if (fieldOp.isGet()) {
+
+        if (!fieldOp.isStatic()) {
             // pop out ref
             vpop();
         }
@@ -382,7 +405,7 @@
 
     
     vpop(); // pop out value
-    if (field_op) {
+    if (!fieldOp.isStatic()) {
         vpop(); // pop out ref
     }
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_instr.cpp Wed May 23 04:22:55 2007
@@ -299,7 +299,7 @@
 //
 }
 
-void CodeGen::gen_write_barrier(JavaByteCodes opcode, Field_Handle fieldHandle)
+void CodeGen::gen_write_barrier(JavaByteCodes opcode, Field_Handle fieldHandle, Opnd fieldSlotAddress)
 {
     //
     // TODO: the WB implementation is expected to perform the write
@@ -328,12 +328,7 @@
     if (!doGenWB4J && !doGenWB4C) {
         return;
     }
-    if ((opcode == OPCODE_PUTFIELD || opcode == OPCODE_PUTSTATIC) && 
-         fieldHandle == NULL) {
-        // Resolution error ? - nothing to report
-        return;
-    }
-
+    
     const bool wb4c_skip_statics = get_bool_arg("wb4c.skip_statics", true);
     if (doGenWB4C && (opcode == OPCODE_PUTSTATIC) && wb4c_skip_statics) {
         // Currently, in DRLVM, statics are allocated outside of GC heap, 
@@ -428,22 +423,19 @@
         //
         mode = 0;
         //
-        unsigned f_offset = field_get_offset(fieldHandle);
+        assert(fieldSlotAddress.is_reg());
         baseObject = vstack(1, true);
         rlock(baseObject);
-        slotAddress = Val(jobj, valloc(jobj));
-        Opnd address(jobj, baseObject.reg(), f_offset);
-        lea(slotAddress.as_opnd(), address);
+        slotAddress = fieldSlotAddress;
         rlock(slotAddress);
     }
     else if (opcode == OPCODE_PUTSTATIC) {
         //
         mode = 1;
         //
+        assert(fieldSlotAddress.is_reg());
         baseObject = Val(jobj, NULL_REF);
-        rlock(baseObject);
-        void* fieldAddress = field_get_address(fieldHandle);
-        slotAddress = Opnd(jobj, (int_ptr)fieldAddress);
+        slotAddress = fieldSlotAddress;
         rlock(slotAddress);
     }
     else if (opcode == OPCODE_AASTORE) {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_meth.cpp Wed May 23 04:22:55 2007
@@ -694,8 +694,7 @@
     }
 }
 
-
-void CodeGen::gen_invoke(JavaByteCodes opcod, Method_Handle meth,
+void CodeGen::gen_invoke(JavaByteCodes opcod, Method_Handle meth, unsigned short cpIndex,
                          const ::std::vector<jtype> &args, jtype retType)
 {
     const unsigned slots = count_slots(args);
@@ -716,7 +715,7 @@
     
     const bool is_static = opcod == OPCODE_INVOKESTATIC;
     Val thiz = is_static ? Val() : vstack(thiz_depth, true);
-    if (meth == NULL) {
+    if (meth == NULL && !m_lazy_resolution) {
         runlock(cs); // was just locked above - unlock
         gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0,
                        m_klass, jinst.op0, jinst.opcode);
@@ -736,31 +735,64 @@
         rlock(thiz);
     }
     
-    // INVOKEINTERFACE must have VM helper call first, so will place 
+    // INVOKEINTERFACE and lazy resolution must have VM helper call first, so will place 
     // its args later, after the call, to avoid destruction of args 
     // on registers.
-    if (opcod != OPCODE_INVOKEINTERFACE) {
+    if (opcod != OPCODE_INVOKEINTERFACE && meth != NULL) {
         stackFix = gen_stack_to_args(true, cs, 0);
         gen_gc_stack(-1, true);
         vpark();
     }
     //
-        // Check for null here - we just spilled all the args and 
-        // parked all the registers, so we have a chance to use HW NPE 
+    // Check for null here - we just spilled all the args and 
+    // parked all the registers, so we have a chance to use HW NPE 
     // For INVOKEINTERFACE we did not spill args, but we'll call VM first,
     // which is pretty expensive by itself, so the HW check does not give 
     // much.
     //
-        if (!is_static) {
-            // For invokeSPECIAL, we're using indirect address provided by 
-            // the VM. This means we do not read vtable, which means no 
-            // memory access, so we can't use HW checks - have to use 
+    if (!is_static) {
+        // For invokeSPECIAL, we're using indirect address provided by 
+        // the VM. This means we do not read vtable, which means no 
+        // memory access, so we can't use HW checks - have to use 
         // explicit one. Not a big loss, as the INVOKESPECIAL mostly
-            // comes right after NEW which guarantees non-null.
-            gen_check_null(thiz, opcod != OPCODE_INVOKESPECIAL);
-        }
-    
-    if (opcod == OPCODE_INVOKEINTERFACE) {
+        // comes right after NEW which guarantees non-null.
+        gen_check_null(thiz, opcod != OPCODE_INVOKESPECIAL);
+    }
+    if (meth == NULL) {
+        //lazy resolution mode: get method addr and call it.
+        assert(m_lazy_resolution);
+        //1. get method address
+        if (opcod == OPCODE_INVOKESTATIC || opcod == OPCODE_INVOKESPECIAL) {
+            static const CallSig cs_get_is_addr(CCONV_STDCALL, iplatf, i32);
+            char* helper = opcod == OPCODE_INVOKESTATIC ?  rt_helper_get_invokestatic_addr_withresolve :
+                                                           rt_helper_get_invokespecial_addr_withresolve;
+            gen_call_vm(cs_get_is_addr, helper, 0, m_klass, cpIndex);
+            runlock(cs_get_is_addr);
+        } else {
+            assert(opcod == OPCODE_INVOKEVIRTUAL || opcod == OPCODE_INVOKEINTERFACE);
+            static const CallSig cs_get_iv_addr(CCONV_STDCALL, iplatf, i32, jobj);
+            char * helper = opcod == OPCODE_INVOKEVIRTUAL ? rt_helper_get_invokevirtual_addr_withresolve : 
+                                                            rt_helper_get_invokeinterface_addr_withresolve;
+            // setup constant parameters first,
+            Val vclass(iplatf, m_klass);
+            Val vcpIdx(cpIndex);
+            gen_args(cs_get_iv_addr, 0, &vclass, &vcpIdx, &thiz);
+            gen_call_vm(cs_get_iv_addr, helper, 3);
+            runlock(cs_get_iv_addr);
+        } 
+        rlock(gr_ret); //WARN: call addr is in gr_ret -> lock it
+
+        //2.  call java method
+        stackFix = gen_stack_to_args(true, cs, 0);
+        gen_gc_stack(-1, true);
+        vpark();
+        
+        AR gr = valloc(iplatf);
+        ld(jobj, gr, gr_ret); //load indirect addr
+        call(gr, cs, is_set(DBG_CHECK_STACK));
+        runlock(gr_ret);
+    } 
+    else if (opcod == OPCODE_INVOKEINTERFACE) {
         // if it's INVOKEINTERFACE, then first resolve it
         Class_Handle klass = method_get_class(meth);
         const CallSig cs_vtbl(CCONV_STDCALL, jobj, jobj);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/cg_obj.cpp Wed May 23 04:22:55 2007
@@ -36,14 +36,45 @@
 namespace Jitrino {
 namespace Jet {
 
-void CodeGen::gen_new_array(Allocation_Handle ah)
+void CodeGen::gen_new_array(Class_Handle enclClass, unsigned cpIndex) 
 {
-    const JInst& jinst = *m_curr_inst;
-    assert(jinst.opcode == OPCODE_NEWARRAY 
-        ||  jinst.opcode == OPCODE_ANEWARRAY 
-        || jinst.opcode == OPCODE_INVOKESTATIC); //OPCODE_INVOKESTATIC is used to generate magic
+    bool lazy = m_lazy_resolution;
+    bool resolve = !lazy || class_is_cp_entry_resolved(m_compileHandle, enclClass, cpIndex);
+    if (resolve) {
+        Allocation_Handle ah = 0;
+        Class_Handle klass = resolve_class(m_compileHandle, enclClass,  cpIndex);
+        if (klass != NULL) {
+            klass = class_get_array_of_class(klass);
+        }
+        if (klass != NULL) {
+            ah = class_get_allocation_handle(klass);
+        }
+        gen_new_array(ah);
+        return;
+    } 
+    assert(lazy);
+    static const CallSig cs_newarray_withresolve(CCONV_STDCALL, iplatf, i32, i32);
+    Val sizeVal = vstack(0);
+    // setup constant parameters first,
+    Val vclass(iplatf, enclClass);
+    Val vcpIdx((int)cpIndex);
+    gen_args(cs_newarray_withresolve, 0, &vclass, &vcpIdx, &sizeVal);
+    gen_call_vm(cs_newarray_withresolve, rt_helper_new_array_withresolve, 3);
+    vpop();// pop array size
+    gen_save_ret(jobj);
+
+    // the returned can not be null, marking as such.
+    vstack(0).set(VA_NZ);
+    // allocation assumes GC invocation
+    m_bbstate->seen_gcpt = true;
+}
 
+void CodeGen::gen_new_array(Allocation_Handle ah) {
+    const JInst& jinst = *m_curr_inst;
+    assert(jinst.opcode == OPCODE_NEWARRAY ||  jinst.opcode == OPCODE_ANEWARRAY);
+        
     if (ah == 0) {
+        assert(!m_lazy_resolution);
         // it's unexpected that that something failed for a primitive type
         assert(jinst.opcode != OPCODE_NEWARRAY);
         gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0,
@@ -75,15 +106,13 @@
     m_bbstate->seen_gcpt = true;
 }
 
-void CodeGen::gen_multianewarray(Class_Handle klass, unsigned num_dims)
+void CodeGen::gen_multianewarray(Class_Handle enclClass, unsigned short cpIndex, unsigned num_dims)
 {
     // stack: [..., count1, [...count N] ]
     // args: (klassHandle, num_dims, count_n, ... count_1)
     // native stack to be established (ia32):  
     //          .., count_1, .. count_n, num_dims, klassHandle
     
-    const JInst& jinst = *m_curr_inst;
-
     vector<jtype> args;
     for (unsigned i = 0; i<num_dims; i++) {
         args.push_back(i32);
@@ -91,16 +120,37 @@
     args.push_back(i32);
     args.push_back(jobj);
         
+    Class_Handle klass = NULL;
+    Val klassVal;
+
+    bool lazy = m_lazy_resolution;
+    bool resolve = !lazy || class_is_cp_entry_resolved(m_compileHandle, enclClass, cpIndex);
+    if(!resolve) {
+        assert(lazy);
+        static CallSig ci_get_class_withresolve(CCONV_STDCALL, iplatf, i32);
+        gen_call_vm(ci_get_class_withresolve, rt_helper_get_class_withresolve, 0, enclClass, cpIndex);
+        runlock(ci_get_class_withresolve);
+        klassVal = Val(jobj, gr_ret);
+    }  else {
+        klass = resolve_class(m_compileHandle, enclClass, cpIndex);
+        klassVal = Val(jobj, klass);
+    }
+    rlock(klassVal); // to protect gr_ret while setting up helper args
+
     // note: need to restore the stack - the cdecl-like function
     CallSig ci(CCONV_CDECL_IA32|CCONV_MEM|CCONV_L2R|CCONV_CALLER_POPS, args);
     unsigned stackFix = gen_stack_to_args(true, ci, 0, num_dims);
-    
-    if (klass == NULL) {
+
+    runlock(klassVal);
+
+    if (klass == NULL && !lazy) {
         gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0,
-                       m_klass, jinst.op0, jinst.opcode);
+                       m_klass, cpIndex, OPCODE_MULTIANEWARRAY);
     }
-    
-    gen_call_vm(ci, rt_helper_multinewarray, num_dims, num_dims, klass);
+    Val vnum_dims = Opnd(num_dims);
+    gen_args(ci, num_dims, &vnum_dims, &klassVal);
+
+    gen_call_vm(ci, rt_helper_multinewarray, 2+num_dims);
     runlock(ci);
     if (stackFix != 0) {
         alu(alu_sub, sp, stackFix);
@@ -113,42 +163,67 @@
 }
 
 
-void CodeGen::gen_new(Class_Handle klass)
+void CodeGen::gen_new(Class_Handle enclClass, unsigned short cpIndex)
 {
-    const JInst& jinst = *m_curr_inst;
-    if (klass == NULL) {
-        gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0,
-                       m_klass, jinst.op0, jinst.opcode);
-    }
-    else {
-        unsigned size = class_get_boxed_data_size(klass);
-        Allocation_Handle ah = class_get_allocation_handle(klass);
-        static CallSig ci_new(CCONV_STDCALL, i32, jobj);
-        gen_call_vm(ci_new, rt_helper_new, 0, size, ah);
+    bool lazy = m_lazy_resolution;
+    bool resolve = !lazy || class_is_cp_entry_resolved(m_compileHandle, enclClass, cpIndex);
+    if (resolve) {
+        Class_Handle klass = resolve_class_new(m_compileHandle, enclClass, cpIndex);
+        if (klass == NULL) {
+            gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0, enclClass, cpIndex, OPCODE_NEW);
+        } else {
+            unsigned size = class_get_boxed_data_size(klass);
+            Allocation_Handle ah = class_get_allocation_handle(klass);
+            static CallSig ci_new(CCONV_STDCALL, i32, jobj);
+            gen_call_vm(ci_new, rt_helper_new, 0, size, ah);
+        }
+    } else {
+        assert(lazy);
+        static CallSig ci_new_with_resolve(CCONV_STDCALL, iplatf, i32);
+        gen_call_vm(ci_new_with_resolve, rt_helper_new_withresolve, 0, enclClass, cpIndex);
     }
     gen_save_ret(jobj);
     // the returned can not be null, marking as such.
     vstack(0).set(VA_NZ);
     // allocation assumes GC invocation
+    
     m_bbstate->seen_gcpt = true;
 }
 
-void CodeGen::gen_instanceof_cast(bool checkcast, Class_Handle klass)
+void CodeGen::gen_instanceof_cast(JavaByteCodes opcode, Class_Handle enclClass, unsigned short cpIdx)
 {
-    const JInst& jinst = *m_curr_inst;
-    if (klass == NULL) {
-        gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0,
-                       m_klass, jinst.op0, jinst.opcode);
-    }
-    static const CallSig cs(CCONV_STDCALL, jobj, jobj);
-    unsigned stackFix = gen_stack_to_args(true, cs, 0, 1);
-    char * helper = checkcast ? rt_helper_checkcast : rt_helper_instanceof;
-    gen_call_vm(cs, helper, 1, klass);
-    if (stackFix != 0) {
-        alu(alu_sub, sp, stackFix);
+    assert (opcode == OPCODE_INSTANCEOF || opcode == OPCODE_CHECKCAST);
+    bool lazy = m_lazy_resolution;
+    bool resolve  = !lazy || class_is_cp_entry_resolved(m_compileHandle, enclClass, cpIdx);
+    if (resolve) {
+        Class_Handle klass = resolve_class(m_compileHandle, enclClass, cpIdx);
+        if (klass == NULL) {
+            assert(!lazy);
+            gen_call_throw(ci_helper_linkerr, rt_helper_throw_linking_exc, 0, enclClass, cpIdx, opcode);
+        }
+        static const CallSig cs(CCONV_STDCALL, jobj, jobj);
+        unsigned stackFix = gen_stack_to_args(true, cs, 0, 1);
+        char * helper = opcode == OPCODE_CHECKCAST ? rt_helper_checkcast : rt_helper_instanceof;
+        gen_call_vm(cs, helper, 1, klass);
+        if (stackFix != 0) {
+            alu(alu_sub, sp, stackFix);
+        }
+        runlock(cs);
+        gen_save_ret(opcode == OPCODE_CHECKCAST ? jobj : i32);
+    } else {
+        assert(lazy);
+        static const CallSig cs_with_resolve(CCONV_STDCALL, iplatf, i32, jobj);
+        char * helper = opcode == OPCODE_CHECKCAST ? rt_helper_checkcast_withresolve : rt_helper_instanceof_withresolve;
+        Val tos = vstack(0);
+        // setup constant parameters first,
+        Val vclass(iplatf, enclClass);
+        Val vcpIdx(cpIdx);
+        gen_args(cs_with_resolve, 0, &vclass, &vcpIdx, &tos);
+        gen_call_vm(cs_with_resolve, helper, 3);
+        runlock(cs_with_resolve);
+        vpop();//pop obj
+        gen_save_ret(opcode == OPCODE_CHECKCAST ? jobj : i32);
     }
-    runlock(cs);
-    gen_save_ret(checkcast ? jobj : i32);
 }
 
 void CodeGen::gen_monitor_ee(void)

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp Wed May 23 04:22:55 2007
@@ -140,6 +140,16 @@
     if (!get_bool_arg("bbp", true)) {
         compile_flags &= JMF_BBPOLLING;
     }
+    
+    m_lazy_resolution  = get_bool_arg("lazyResolution", false);
+#ifdef _DEBUG
+    bool assertOnRecursion = get_bool_arg("assertOnRecursion", false);
+    if (assertOnRecursion) {
+        assert(Jitrino::getCompilationRecursionLevel() == 1);
+    }
+#endif
+
+
     //
     // Debugging support
     //
@@ -1446,6 +1456,30 @@
                 (char*)vm_get_rt_support_addr(VM_RT_GC_SAFE_POINT);
     rt_helper_get_tls_base_ptr= 
                 (char*)vm_get_rt_support_addr(VM_RT_GC_GET_TLS_BASE);
+
+    rt_helper_new_withresolve =
+                    (char*)vm_get_rt_support_addr(VM_RT_NEWOBJ_WITHRESOLVE);
+    rt_helper_new_array_withresolve =
+        (char*)vm_get_rt_support_addr(VM_RT_NEWARRAY_WITHRESOLVE);
+    rt_helper_get_class_withresolve =
+        (char*)vm_get_rt_support_addr(VM_RT_INITIALIZE_CLASS_WITHRESOLVE);
+    rt_helper_checkcast_withresolve =
+                    (char*)vm_get_rt_support_addr(VM_RT_CHECKCAST_WITHRESOLVE);
+    rt_helper_instanceof_withresolve =
+                    (char*)vm_get_rt_support_addr(VM_RT_INSTANCEOF_WITHRESOLVE);
+    rt_helper_field_get_offset_withresolve =
+                    (char*)vm_get_rt_support_addr(VM_RT_GET_NONSTATIC_FIELD_OFFSET_WITHRESOLVE);
+    rt_helper_field_get_address_withresolve = 
+                    (char*)vm_get_rt_support_addr(VM_RT_GET_STATIC_FIELD_ADDR_WITHRESOLVE);
+    rt_helper_get_invokevirtual_addr_withresolve = 
+                (char*)vm_get_rt_support_addr(VM_RT_GET_INVOKEVIRTUAL_ADDR_WITHRESOLVE);
+    rt_helper_get_invokespecial_addr_withresolve = 
+                    (char*)vm_get_rt_support_addr(VM_RT_GET_INVOKE_SPECIAL_ADDR_WITHRESOLVE);
+    rt_helper_get_invokestatic_addr_withresolve = 
+                    (char*)vm_get_rt_support_addr(VM_RT_GET_INVOKESTATIC_ADDR_WITHRESOLVE);
+    rt_helper_get_invokeinterface_addr_withresolve = 
+                    (char*)vm_get_rt_support_addr(VM_RT_GET_INVOKEINTERFACE_ADDR_WITHRESOLVE);
+
     //
     rt_helper_ti_method_enter = 
             (char*)vm_get_rt_support_addr(VM_RT_JVMTI_METHOD_ENTER_CALLBACK);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.h Wed May 23 04:22:55 2007
@@ -355,6 +355,7 @@
      * @return  - true if current inst is magic call, false otherwise.
      */
     bool gen_magic(void);
+
     
     //
     // Method being compiled info
@@ -410,11 +411,6 @@
      * @brief Code buffer allocated by VM.
      */
     char *  m_vmCode;
-    
-    /**
-     * @brief Compilation handle.
-     */    
-    Compile_Handle  m_compileHandle;
     
     /**
      * @brief Parses method's signature at the given constant pool entry.

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/magics.cpp Wed May 23 04:22:55 2007
@@ -37,23 +37,15 @@
 namespace Jitrino {
 namespace Jet {
 
-bool is_magic(Class_Handle k)
+bool CodeGen::is_magic_class(const char* kname)
 {
     static const char unboxedName[] = "org/vmmagic/unboxed/";
     static const unsigned nameLen = sizeof(unboxedName)-1;
 
-    assert(k!=NULL);
-    const char * kname = class_get_name(k);
+    assert(kname!=NULL);
     return !strncmp(kname, unboxedName, nameLen);
 }
 
-bool is_magic(Method_Handle m)
-{
-    assert(m != NULL);
-    Class_Handle klass = method_get_class(m);
-    return is_magic(klass);
-}
-
 static size_t sizeof_jt(jtype jt) {
     static size_t sizes[] =  { 
         1, //i8,
@@ -110,27 +102,15 @@
         return false;
     }
     
-    vector<jtype> args;
-    jtype retType;
-    bool is_static = opkod == OPCODE_INVOKESTATIC;
-    get_args_info(is_static, jinst.op0, args, &retType);
+    const char* kname = const_pool_get_method_class_name(m_klass, (unsigned short)jinst.op0);
 
-    Method_Handle meth = NULL;
-    if (opkod == OPCODE_INVOKESTATIC) {
-        meth = resolve_static_method(m_compileHandle, m_klass, jinst.op0);
-    } else if (opkod == OPCODE_INVOKEVIRTUAL) {
-        meth = resolve_virtual_method(m_compileHandle, m_klass, jinst.op0);
-    } else {
-        assert(opkod == OPCODE_INVOKESPECIAL);
-        meth = resolve_special_method(m_compileHandle, m_klass, jinst.op0);
-    }
-    if (meth == NULL || !is_magic(meth)) {
+    if (!is_magic_class(kname)) {
         return false;
     }
-
     // This is a magic -> transform it
 
-    const char* mname = method_get_name(meth);
+    const char* mname = const_pool_get_method_name(m_klass, (unsigned short)jinst.op0);
+
     jtype magicType = iplatf;
 
     if (!strcmp(mname, "fromLong")) {
@@ -149,6 +129,11 @@
         it keeps all magic classes as objects and magics becomes a part of GC enumeration
         This code must be refactored or removed
 
+
+    vector<jtype> args;
+    jtype retType;
+    bool is_static = opkod == OPCODE_INVOKESTATIC;
+    get_args_info(is_static, jinst.op0, args, &retType);
 
     // ADD, SUB, DIFF, etc - 2 args arithmetics
     ALU oper = alu_count;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.cpp Wed May 23 04:22:55 2007
@@ -62,6 +62,20 @@
 char *  StaticConsts::rt_helper_gc_safepoint = NULL;
 char *  StaticConsts::rt_helper_get_tls_base_ptr= NULL;
 
+char*   StaticConsts::rt_helper_new_withresolve= NULL;
+char*   StaticConsts::rt_helper_new_array_withresolve= NULL;
+char*   StaticConsts::rt_helper_get_class_withresolve= NULL;
+char*   StaticConsts::rt_helper_checkcast_withresolve= NULL;
+char*   StaticConsts::rt_helper_instanceof_withresolve= NULL;
+char*   StaticConsts::rt_helper_field_get_offset_withresolve = NULL;
+char*   StaticConsts::rt_helper_field_get_address_withresolve = NULL;
+char*   StaticConsts::rt_helper_get_invokevirtual_addr_withresolve = NULL;
+char*   StaticConsts::rt_helper_get_invokespecial_addr_withresolve = NULL;
+char*   StaticConsts::rt_helper_get_invokestatic_addr_withresolve = NULL;
+char*   StaticConsts::rt_helper_get_invokeinterface_addr_withresolve = NULL;
+
+
+
 unsigned StaticConsts::rt_array_length_offset = NOTHING;
 unsigned StaticConsts::rt_suspend_req_flag_offset = NOTHING;
 int StaticConsts::rt_vtable_offset = 0;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/sconsts.h Wed May 23 04:22:55 2007
@@ -76,6 +76,19 @@
     static char*        rt_helper_ti_field_modification;
 
     static char*        rt_helper_gc_safepoint;
+
+    static char*        rt_helper_new_withresolve;
+    static char*        rt_helper_new_array_withresolve;
+    static char*        rt_helper_get_class_withresolve;
+    static char*        rt_helper_checkcast_withresolve;
+    static char*        rt_helper_instanceof_withresolve;
+    static char*        rt_helper_field_get_offset_withresolve;
+    static char*        rt_helper_field_get_address_withresolve;
+    static char*        rt_helper_get_invokevirtual_addr_withresolve;
+    static char*        rt_helper_get_invokespecial_addr_withresolve;
+    static char*        rt_helper_get_invokestatic_addr_withresolve;
+    static char*        rt_helper_get_invokeinterface_addr_withresolve;
+
     /**
      * @brief An offset of 'thread suspend requiest' flag in TIB.
      * @see rt_helper_get_tls_base_ptr

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/val.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/val.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/val.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/val.h Wed May 23 04:22:55 2007
@@ -116,7 +116,7 @@
     Val(jtype jt, const void* p)
     {
         clear();
-        m_kind = opnd_imm; assert(jt==jobj); m_jt = jt; m_pval = p;
+        m_kind = opnd_imm; assert(jt==jobj || jt==iplatf); m_jt = jt; m_pval = p;
     }
     Val(AR base, int disp, AR index = ar_x, unsigned scale=0)
     {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.cpp Wed May 23 04:22:55 2007
@@ -68,6 +68,7 @@
 
 struct Jitrino::Flags Jitrino::flags;
 
+static TlsKey recursionKey = 0;
 
 
 // some demo parameters
@@ -144,6 +145,8 @@
         jitInstances = new (*global_mm) JITInstances(*global_mm);
 
         flags.time=false;
+
+        recursionKey = Tls::allocKey();
     }
 
     jitInstance = new (*global_mm) JITInstanceContext(*global_mm, jh, name);
@@ -383,6 +386,21 @@
     }
 }
 
+
+
+int Jitrino::getCompilationRecursionLevel() {
+    return (int)(POINTER_SIZE_INT)Tls::get(recursionKey);
+}
+
+void Jitrino::incCompilationRecursionLevel() {
+    int recursion = (int)(POINTER_SIZE_INT)Tls::get(recursionKey);
+    Tls::put(recursionKey, (void*)(POINTER_SIZE_INT)(recursion+1));
+}
+
+void Jitrino::decCompilationRecursionLevel() {
+    int recursion = (int)(POINTER_SIZE_INT)Tls::get(recursionKey);
+    Tls::put(recursionKey, (void*)(POINTER_SIZE_INT)(recursion-1));
+}
 
 
 } //namespace Jitrino 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.h?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/main/Jitrino.h Wed May 23 04:22:55 2007
@@ -80,6 +80,10 @@
     static struct Flags flags;
     static JITInstanceContext* getJITInstanceContext(JIT_Handle jitHandle);
     static void killJITInstanceContext(JITInstanceContext* jit);
+    
+    static int  getCompilationRecursionLevel();
+    static void incCompilationRecursionLevel();
+    static void decCompilationRecursionLevel();
 
 private:
     static MemoryManager *global_mm; 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp?view=diff&rev=540926&r1=540925&r2=540926
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/IRBuilder.cpp Wed May 23 04:22:55 2007
@@ -31,9 +31,6 @@
 
 namespace Jitrino {
 
-static void UNIMPLEMENTED(char* fun) {
-    Log::out() << "   !!!!  IRBuilder: unimplemented: " << fun << "   !!!\n";
-}
 
 #if defined(_MSC_VER) && !defined (__ICL) && !defined (__GNUC__)
 #pragma warning(disable : 4355)
@@ -1320,7 +1317,69 @@
     return dst;
 }
 
+Opnd* IRBuilder::createTypeOpnd(ObjectType* type) {
+    Opnd* res = NULL;
+    POINTER_SIZE_SINT val = (POINTER_SIZE_SINT)type->getRuntimeIdentifier();
+    res = genLdConstant(val);
+    return res;
+}
 // Calls
+
+Opnd* IRBuilder::genIndirectCallWithResolve(Type* returnType,
+                                Opnd* tauNullCheckedFirstArg,
+                                Opnd* tauTypesChecked,
+                                uint32 numArgs,
+                                Opnd* args[],
+                                ObjectType* ch,
+                                JavaByteCodes bc,
+                                uint32 cpIndex
+                                )
+{
+    assert(!returnType->isNullObject());
+    Opnd* callAddrOpnd = lookupHash(Op_VMHelperCall, bc, cpIndex, numArgs>0?args[0]->getId() : 0);
+    if (tauTypesChecked == NULL) {
+        tauTypesChecked = genTauUnsafe(); 
+    }
+
+    if (callAddrOpnd == NULL) {
+        CompilationInterface::RuntimeHelperId vmHelperId = CompilationInterface::Helper_Null;
+        MemoryManager& mm = irManager->getMemoryManager();
+        Opnd* clsOpnd = createTypeOpnd(ch);
+        Opnd* idxOpnd = genLdConstant((int)cpIndex);
+        uint32 numHelperArgs = 0;
+        Opnd** helperArgs = helperArgs = new(mm)Opnd*[3];
+        helperArgs[0] = clsOpnd;
+        helperArgs[1] = idxOpnd;
+        helperArgs[2] = NULL;
+        switch(bc) {
+        case OPCODE_INVOKESTATIC:
+            vmHelperId = CompilationInterface::Helper_GetInvokeStaticAddrWithResolve;
+            numHelperArgs = 2;
+            break;
+        case OPCODE_INVOKEVIRTUAL:
+            vmHelperId = CompilationInterface::Helper_GetInvokeVirtualAddrWithResolve;
+            helperArgs[2] = args[0];
+            numHelperArgs = 3;
+            break;
+        case OPCODE_INVOKESPECIAL:
+            vmHelperId = CompilationInterface::Helper_GetInvokeSpecialAddrWithResolve;
+            numHelperArgs = 2;
+            break;
+        case OPCODE_INVOKEINTERFACE:
+            vmHelperId = CompilationInterface::Helper_GetInvokeInterfaceAddrWithResolve;
+            helperArgs[2] = args[0];
+            numHelperArgs = 3;
+            break;
+        default: assert(0);
+        }
+        callAddrOpnd = genVMHelperCall(vmHelperId, typeManager->getUnresolvedMethodPtrType(ch, cpIndex), numHelperArgs, helperArgs);
+        insertHash(Op_VMHelperCall, bc, cpIndex, numArgs>0?args[0]->getId() : 0, callAddrOpnd->getInst());
+    }
+
+    return genIndirectMemoryCall(returnType, callAddrOpnd,  tauNullCheckedFirstArg, tauTypesChecked, numArgs, args, NULL); 
+}
+
+
 Opnd*
 IRBuilder::genDirectCall(MethodDesc* methodDesc,
                          Type* returnType,
@@ -1387,10 +1446,9 @@
     } else {
         tauNullCheckedFirstArg = propagateCopy(tauNullCheckedFirstArg);
     }
-    if (!tauTypesChecked || 
-        (tauTypesChecked->getInst()->getOpcode() == Op_TauUnsafe)) {
+    if (!tauTypesChecked || (tauTypesChecked->getInst()->getOpcode() == Op_TauUnsafe)) {
         // if no type check available yet
-        tauTypesChecked = genTauHasType(args[0], methodDesc->getParentType());
+        tauTypesChecked = genTauHasTypeWithConv(&args[0], methodDesc->getParentType());
     } else {
         tauTypesChecked = propagateCopy(tauTypesChecked);
     }
@@ -1566,8 +1624,12 @@
 IRBuilder::genReturn(Opnd* src, Type* retType) {
     src = propagateCopy(src);
     if(Log::isEnabled()) {
-        if (retType != src->getType()) {
-            UNIMPLEMENTED("ret type check");
+        Type* srcType = src->getType();
+        bool convOk = retType == srcType;
+        convOk = convOk || (retType->isObject() && srcType->isObject());
+        if (!convOk){
+            assert(!typeManager->isLazyResolutionMode());
+            Log::out() << "ERROR   !!!!  IRBuilder: unimplemented: ret typecheck !!!\n";
         }
     }
     appendInst(instFactory->makeReturn(src));
@@ -1848,8 +1910,7 @@
 
 Opnd*
 IRBuilder::genLdField(Type* type, Opnd* base, FieldDesc* fieldDesc) {
-    if (fieldDesc->isStatic())
-        return genLdStatic(type, fieldDesc);
+    assert(!fieldDesc->isStatic());
     base = propagateCopy(base);
     Opnd *tauNullCheck = genTauCheckNull(base);
     Opnd *tauAddressInRange = 
@@ -1863,7 +1924,7 @@
     Modifier mod = uncompress ? AutoCompress_Yes : AutoCompress_No;
     if (irBuilderFlags.expandMemAddrs) {
         return genTauLdInd(mod, type, type->tag, 
-                           genLdFieldAddrNoChecks(type, base, fieldDesc), 
+                           genLdFieldAddr(type, base, fieldDesc), 
                            tauNullCheck, tauAddressInRange);
     }
 
@@ -1874,6 +1935,24 @@
     return dst;
 }
 
+Opnd*
+IRBuilder::genLdFieldWithResolve(Type* type, Opnd* base, ObjectType* enclClass, uint32 cpIndex) {
+    base = propagateCopy(base);
+    Opnd *tauNullCheck = genTauCheckNull(base);
+    Opnd *tauAddressInRange = genTauSafe();
+
+    bool uncompress = false;
+    if (irBuilderFlags.compressedReferences && type->isObject()) {
+        assert(!type->isCompressedReference());
+        uncompress = true;
+    }
+    Modifier mod = uncompress ? AutoCompress_Yes : AutoCompress_No;
+    assert(irBuilderFlags.expandMemAddrs);
+
+    Opnd* addr = genLdFieldAddrWithResolve(type, base, enclClass, cpIndex, false);
+    return genTauLdInd(mod, type, type->tag, addr,  tauNullCheck, tauAddressInRange);
+}
+
 void
 IRBuilder::genInitType(NamedType* type) {
     if (!type->needsInitialization())
@@ -1886,6 +1965,20 @@
 }
 
 Opnd*
+IRBuilder::genLdStaticWithResolve(Type* type, ObjectType* enclClass, uint32 cpIdx) {
+    bool uncompress = false;
+    if (irBuilderFlags.compressedReferences && type->isObject()) {
+        assert(!type->isCompressedReference());
+        uncompress = true;
+    }
+    Modifier mod = uncompress ? AutoCompress_Yes : AutoCompress_No;
+
+    Opnd *tauOk = genTauSafe(); // static field, always safe
+    Opnd* addrOpnd = genLdStaticAddrWithResolve(type, enclClass, cpIdx, false);
+    return genTauLdInd(mod, type, type->tag, addrOpnd, tauOk, tauOk);
+}
+
+Opnd*
 IRBuilder::genLdStatic(Type* type, FieldDesc* fieldDesc) {
     bool uncompress = false;
     if (irBuilderFlags.compressedReferences && type->isObject()) {
@@ -1948,21 +2041,13 @@
     return genLdElem(type,array,index,tauNullChecked,tauAddressInRange);
 }
 
-// this is now used just for CLI; the tauNonNull operand is ignored, but the
-// check should remain even after optimization. 
 Opnd*
 IRBuilder::genLdFieldAddr(Type* type, Opnd* base, FieldDesc* fieldDesc) {
-    if (fieldDesc->isStatic()) {
-        assert(0);
-        return genLdStaticAddr(type, fieldDesc);
-    }
+    assert(!fieldDesc->isStatic());
 
     base = propagateCopy(base);
 
-    // generate a null check if the field is not static
-        ((base->getType()->isObject())
-         ? genTauCheckNull(base)
-         : genTauUnsafe());
+    genTauCheckNull(base);
     
     Opnd* dst = lookupHash(Op_LdFieldAddr, base->getId(), fieldDesc->getId());
     if (dst) return dst;
@@ -1981,28 +2066,21 @@
         dst = createOpnd(typeManager->getManagedPtrType(type));
     }
     appendInst(instFactory->makeLdFieldAddr(dst, base, fieldDesc));
-    insertHash(Op_LdFieldAddr, base->getId(), fieldDesc->getId(), 
-               dst->getInst());
+    insertHash(Op_LdFieldAddr, base->getId(), fieldDesc->getId(), dst->getInst());
     return dst;
 }
 
-// null check isn't needed for this address calculation
 Opnd*
-IRBuilder::genLdFieldAddrNoChecks(Type* type, Opnd* base, FieldDesc* fieldDesc) {
-    if (fieldDesc->isStatic()) {
-        assert(0);
-        return genLdStaticAddrNoChecks(type, fieldDesc);
-    }
-
+IRBuilder::genLdFieldAddrWithResolve(Type* type, Opnd* base, ObjectType* enclClass, uint32 cpIndex, bool putfield) {
     base = propagateCopy(base);
+    genTauCheckNull(base);
 
-    Opnd* dst = lookupHash(Op_LdFieldAddr, base->getId(), fieldDesc->getId());
+    //1. loading field offset
+    JavaByteCodes opcode = putfield? OPCODE_PUTFIELD : OPCODE_GETFIELD;
+    Opnd* dst = lookupHash(Op_VMHelperCall, opcode, base->getId(), cpIndex);
     if (dst) return dst;
 
-    if (base->getType()->isIntPtr()) {
-        // unmanaged pointer
-        dst = createOpnd(typeManager->getIntPtrType());
-    } else if (irBuilderFlags.compressedReferences && type->isObject()) {
+    if (irBuilderFlags.compressedReferences && type->isObject()) {
         // until VM type system is upgraded,
         // fieldDesc type will have uncompressed ref type;
         // compress it
@@ -2012,21 +2090,23 @@
     } else {
         dst = createOpnd(typeManager->getManagedPtrType(type));
     }
-    appendInst(instFactory->makeLdFieldAddr(dst, base, fieldDesc));
-    insertHash(Op_LdFieldAddr, base->getId(), fieldDesc->getId(), 
-               dst->getInst());
+    Opnd** args = new (irManager->getMemoryManager()) Opnd*[3];
+    args[0] = createTypeOpnd(enclClass);
+    args[1] = genLdConstant((int)cpIndex);
+    args[2] = genLdConstant((int)putfield?1:0);
+    Opnd* offsetOpnd = genVMHelperCall(CompilationInterface::Helper_GetNonStaticFieldOffsetWithResolve, 
+                                    typeManager->getInt32Type(), 3, args);
+    insertHash(Op_VMHelperCall, opcode, base->getId(), cpIndex, dst->getInst());
+
+    //2. adding the offset to object opnd -> getting the address of the field
+    appendInst(instFactory->makeAddOffset(dst, base, offsetOpnd));
     return dst;
 }
 
-
 Opnd*
 IRBuilder::genLdStaticAddr(Type* type, FieldDesc* fieldDesc) {
     genInitType(fieldDesc->getParentType());
-    return genLdStaticAddrNoChecks(type, fieldDesc);
-}
 
-Opnd*
-IRBuilder::genLdStaticAddrNoChecks(Type* type, FieldDesc* fieldDesc) {
     Opnd* dst = lookupHash(Op_LdStaticAddr, fieldDesc->getId());
     if (dst) return dst;
 
@@ -2046,6 +2126,31 @@
 }
 
 Opnd*
+IRBuilder::genLdStaticAddrWithResolve(Type* type, ObjectType* enclClass, uint32 cpIndex, bool putfield) {
+    JavaByteCodes opcode = putfield ? OPCODE_PUTSTATIC : OPCODE_GETSTATIC;
+    Opnd* dst = lookupHash(Op_VMHelperCall, opcode, cpIndex);
+    if (dst) return dst;
+
+    if (irBuilderFlags.compressedReferences && type->isObject()) {
+        // until VM type system is upgraded,
+        // fieldDesc type will have uncompressed ref type;
+        // compress it
+        assert(!type->isCompressedReference());
+        Type *compressedType = typeManager->compressType(type);
+        dst = createOpnd(typeManager->getManagedPtrType(compressedType));
+    } else {
+        dst = createOpnd(typeManager->getManagedPtrType(type));
+    }
+    Opnd** args = new (irManager->getMemoryManager()) Opnd*[3];
+    args[0] = createTypeOpnd(enclClass);
+    args[1] = genLdConstant((int)cpIndex);
+    args[2] = genLdConstant((int)putfield?1:0);
+    appendInst(instFactory->makeVMHelperCall(dst, CompilationInterface::Helper_GetStaticFieldAddrWithResolve, 3, args));
+    insertHash(Op_VMHelperCall, OPCODE_GETSTATIC, cpIndex, dst->getInst());
+    return dst;
+}
+
+Opnd*
 IRBuilder::genLdElemAddr(Type* elemType, Opnd* array, Opnd* index) {
     // null and bounds checks
     index = propagateCopy(index);
@@ -2580,15 +2685,9 @@
 }
 
 void
-IRBuilder::genStField(Type* type,
-                      Opnd* base,
-                      FieldDesc* fieldDesc,
-                      Opnd* src) {
-    if (fieldDesc->isStatic()) {
-        assert(0); 
-        genStStatic(type, fieldDesc, src);
-        return;
-    }
+IRBuilder::genStField(Type* type, Opnd* base, FieldDesc* fieldDesc,Opnd* src) {
+    assert (!fieldDesc->isStatic());
+
     base = propagateCopy(base);
     src = propagateCopy(src);
     Opnd *tauBaseNonNull = genTauCheckNull(base);
@@ -2632,6 +2731,41 @@
     }
 }
 
+
+void       
+IRBuilder::genStFieldWithResolve(Type* type, Opnd* base, ObjectType* enclClass, uint32 cpIdx, Opnd* src) {
+    base = propagateCopy(base);
+    src = propagateCopy(src);
+    Opnd *tauBaseNonNull = genTauCheckNull(base);
+    Opnd *tauBaseTypeIsOk = genTauSafe();
+    Opnd *tauStoredTypeIsOk = (type->isObject() ? genTauHasType(src, type) : genTauSafe()); 
+    assert(irBuilderFlags.expandMemAddrs);
+    Opnd *ptr = genLdFieldAddrWithResolve(type, base, enclClass, cpIdx, true);
+    if (irBuilderFlags.insertWriteBarriers && src->getType()->isObject()) {
+        genTauStRef(type, base, ptr, src, 
+            tauBaseNonNull, 
+            tauBaseTypeIsOk,
+            tauStoredTypeIsOk); 
+    } else {
+        genTauStInd(type, ptr, src, 
+            tauBaseNonNull, 
+            tauBaseTypeIsOk,
+            tauStoredTypeIsOk);
+    }
+}
+
+
+void       
+IRBuilder::genStStaticWithResolve(Type* type, ObjectType* enclClass, uint32 cpIdx, Opnd* src) {
+    src = propagateCopy(src);
+    Opnd *tauOk = genTauSafe(); // address is always ok
+    Opnd *tauTypeIsOk = type->isObject() ? genTauHasType(src, type) : genTauSafe();
+    assert(irBuilderFlags.expandMemAddrs);
+    Opnd* addr = genLdStaticAddrWithResolve(type, enclClass, cpIdx, true);
+    genTauStInd(type, addr, src, tauOk,  tauOk, tauTypeIsOk);
+    return;
+}
+
 void
 IRBuilder::genStStatic(Type* type, FieldDesc* fieldDesc, Opnd* src) {
     src = propagateCopy(src);
@@ -2739,6 +2873,7 @@
     genStElem(elemType,array,index,src,tauNullChecked,tauBaseTypeChecked,tauAddressInRange);
 }
 
+
 Opnd*
 IRBuilder::genNewObj(Type* type) {
     Opnd* dst = createOpnd(type);
@@ -2747,6 +2882,31 @@
 }
 
 Opnd*
+IRBuilder::genNewObjWithResolve(ObjectType* enclClass, uint32 cpIndex) {
+    Opnd* clsOpnd = createTypeOpnd(enclClass);
+    Opnd* idxOpnd = genLdConstant((int)cpIndex);
+    Opnd** args = new (irManager->getMemoryManager()) Opnd*[2];
+    args[0]=clsOpnd;
+    args[1]=idxOpnd;
+    Opnd* res = genVMHelperCall(CompilationInterface::Helper_NewObjWithResolve, typeManager->getUnresolvedObjectType(), 2, args);
+    return res;
+}
+
+Opnd*
+IRBuilder::genNewArrayWithResolve(NamedType* elemType, Opnd* numElems, ObjectType* enclClass, uint32 cpIndex) {
+    numElems = propagateCopy(numElems);
+    Opnd* clsOpnd = createTypeOpnd(enclClass);
+    Opnd* idxOpnd = genLdConstant((int)cpIndex);
+    Opnd** args = new (irManager->getMemoryManager()) Opnd*[3];
+    args[0]=clsOpnd;
+    args[1]=idxOpnd;
+    args[2]=numElems;
+    Type* resType = typeManager->getArrayType(elemType);
+    Opnd* res = genVMHelperCall(CompilationInterface::Helper_NewArrayWithResolve, resType, 3, args);
+    return res;
+}
+
+Opnd*
 IRBuilder::genNewArray(NamedType* elemType, Opnd* numElems) {
     numElems = propagateCopy(numElems);
     Opnd* dst = createOpnd(typeManager->getArrayType(elemType));
@@ -2768,6 +2928,35 @@
     return dst;
 }
 
+Opnd*
+IRBuilder::genMultianewarrayWithResolve(NamedType* arrayType,
+                                        ObjectType* enclClass, 
+                                        uint32 cpIndex,
+                                        uint32 dimensions,
+                                        Opnd** numElems) 
+{
+    Opnd* enclClsOpnd = createTypeOpnd(enclClass);
+    Opnd* idxOpnd = genLdConstant((int)cpIndex);
+    Opnd** args = new (irManager->getMemoryManager()) Opnd*[2];
+    args[0] = enclClsOpnd;
+    args[1] = idxOpnd;
+    Opnd* clsOpnd = genVMHelperCall(CompilationInterface::Helper_InitializeClassWithResolve, 
+                                    typeManager->getUnmanagedPtrType(typeManager->getInt8Type()),
+                                    2, args);
+    
+    size_t nArgs2 = 2+dimensions;
+    Opnd** args2  = new (irManager->getMemoryManager()) Opnd*[nArgs2];
+    args2[0]=clsOpnd;
+    args2[1]=genLdConstant((int)dimensions);
+    // create an array of arrays type
+    for (uint32 i=0; i<dimensions; i++) {
+        args2[i+2]=numElems[dimensions-1-i];
+    }
+    Opnd* dst = genVMHelperCall(CompilationInterface::Helper_NewMultiArray, arrayType, (uint32)nArgs2, args2);
+    return dst;
+}
+
+
 void
 IRBuilder::genMonitorEnter(Opnd* src) {
     src = propagateCopy(src);
@@ -2890,6 +3079,24 @@
     return dst;
 }
 
+// type checking
+// CastException (succeeds if argument is null, returns casted object)
+Opnd*
+IRBuilder::genCastWithResolve(Opnd* src, Type* type, ObjectType* enclClass, uint32 cpIndex) {
+    src = propagateCopy(src);
+    Opnd* dst = lookupHash(Op_VMHelperCall, OPCODE_CHECKCAST, src->getId(), cpIndex);
+    if (dst) return dst;
+
+    Opnd** args = new (irManager->getMemoryManager()) Opnd*[3];
+    args[0] = createTypeOpnd(enclClass);
+    args[1] = genLdConstant((int)cpIndex);
+    args[2] = src;
+    dst = genVMHelperCall(CompilationInterface::Helper_CheckCastWithResolve, type, 3, args);
+    insertHash(Op_VMHelperCall, OPCODE_CHECKCAST, src->getId(), cpIndex, dst->getInst());
+    return dst;
+}
+
+
 Opnd*
 IRBuilder::genTauCheckCast(Opnd* src, Opnd *tauNullChecked, Type* castType) {
     src = propagateCopy(src);
@@ -2957,6 +3164,25 @@
 }
 
 Opnd*
+IRBuilder::genInstanceOfWithResolve(Opnd* src, ObjectType* enclClass, uint32 cpIndex) {
+    src = propagateCopy(src);
+
+    Opnd* dst = lookupHash(Op_VMHelperCall, OPCODE_INSTANCEOF, src->getId(), cpIndex);
+    if (dst) {
+        return dst;
+    }
+
+    Opnd** args = new (irManager->getMemoryManager()) Opnd*[3];
+    args[0] = createTypeOpnd(enclClass);
+    args[1] = genLdConstant((int)cpIndex);
+    args[2] = src;
+    dst = genVMHelperCall(CompilationInterface::Helper_InstanceOfWithResolve, typeManager->getInt32Type(), 3, args);
+    insertHash(Op_VMHelperCall, OPCODE_INSTANCEOF, src->getId(), cpIndex,  dst->getInst());
+    return dst;
+}
+
+
+Opnd*
 IRBuilder::genSizeOf(Type* type) {
     Opnd* dst = createOpnd(typeManager->getUInt32Type());
     appendInst(instFactory->makeSizeof(dst, type));
@@ -3371,6 +3597,19 @@
     
     insertHash(hashcode, src->getId(), castType->getId(), dst->getInst());
     return dst;
+}
+
+Opnd* IRBuilder::genTauHasTypeWithConv(Opnd **srcPtr, Type *hasType) {
+    Opnd* src = srcPtr[0];
+    Opnd* res = genTauHasType(src, hasType);
+    Type* srcType = src->getType();
+    if (srcType->isUnresolvedType()) {
+        //change opnd type in case if unresolved
+        Modifier mod = Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No);
+        Opnd* newSrc = genConv(hasType, hasType->tag, mod,  src);
+        srcPtr[0] = newSrc;
+    }
+    return res;
 }
 
 Opnd*



Mime
View raw message