harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mfur...@apache.org
Subject svn commit: r645073 [2/2] - in /harmony/enhanced/drlvm/trunk/vm/jitrino/src: codegenerator/ codegenerator/ia32/ codegenerator/ipf/ codegenerator/ipf/include/ dynopt/ optimizer/ translator/ translator/java/
Date Sat, 05 Apr 2008 10:58:34 GMT
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.cpp Sat Apr  5 03:58:31 2008
@@ -106,7 +106,6 @@
     { Op_TauVirtualCall,        true,  MB::Call,          MK::Exception,                
            "callvirt",      "callvrt   [%2.%d](%a) ((%0,%1)) -) %l  %b",  },
     { Op_IndirectCall,          true,  MB::Call,          MK::Exception,                
            "calli",         "calli     [%0](%a) ((%1,%2)) -) %l",     },
     { Op_IndirectMemoryCall,    true,  MB::Call,          MK::Exception,                
            "callimem",      "callimem  [%0](%a) ((%1,%2)) -) %l",     },
-    { Op_IntrinsicCall,         true,  MB::Call,          MK::Exception,                
            "callintr",      "callintr  %d(%p) ((%0,%1)) -) %l",       },
     { Op_JitHelperCall,         true,  MB::Call,          MK::Exception,                
            "callhelper",    "callhelper %d(%s) -) %l",       },
     { Op_VMHelperCall,          true,  MB::Call,          MK::Exception,                
            "callvmhelper",  "callvmhelper %d(%s) -) %l  %b",    },
     { Op_Return,                true,  MB::ControlFlow,   MK::None,                     
            "return",        "return    %s",                 },

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/Opcode.h Sat Apr  5 03:58:31 2008
@@ -263,12 +263,6 @@
     NewModifier2_BitsConsumed = 2
 };
 
-enum IntrinsicCallId {
-    CharArrayCopy,
-    ArrayCopyDirect,
-    ArrayCopyReverse
-};
-
 enum JitHelperCallId {
     Prefetch,
     Memset0,
@@ -278,6 +272,8 @@
     ReadThisState, //todo: replace with GetTLS + offset sequence
     LockedCompareAndExchange,
     AddValueProfileValue,
+    ArrayCopyDirect,
+    ArrayCopyReverse,
     StringCompareTo,
     StringRegionMatches,
     StringIndexOf,
@@ -325,7 +321,6 @@
     Op_TauVirtualCall,
     Op_IndirectCall,
     Op_IndirectMemoryCall,
-    Op_IntrinsicCall,
     Op_JitHelperCall,               // call to a jit helper routine
     Op_VMHelperCall,                // call to a vm (runtime) helper routine 
     Op_Return,

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/codelowerer.h Sat Apr  5 03:58:31
2008
@@ -136,8 +136,6 @@
 
     Inst* caseIndirectMemoryCall(CallInst* inst) {return caseDefault(inst);}
 
-    Inst* caseIntrinsicCall(IntrinsicCallInst* inst) {return caseDefault(inst);}
-
     Inst* caseJitHelperCall(JitHelperCallInst* inst) {return caseDefault(inst);}
 
     Inst* caseVMHelperCall(VMHelperCallInst* inst) {return caseDefault(inst);}

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escanalyzer.cpp Sat Apr  5 03:58:31
2008
@@ -419,6 +419,8 @@
                         case ReadThisState:
                         case LockedCompareAndExchange:
                         case AddValueProfileValue:
+                        case ArrayCopyDirect:
+                        case ArrayCopyReverse:
                         case StringCompareTo:
                         case StringIndexOf:
                         case StringRegionMatches:
@@ -520,25 +522,6 @@
                 }
                 break;
 
-            case Op_IntrinsicCall:   // callintr
-                if (!inst->getDst()->isNull()) {
-                    assert(0);
-                }
-                n=inst->getNumSrcOperands();
-                addinst=false;
-                for (uint32 i = 0; i < n; i++) {
-                    Type* tt = inst->getSrc(i)->getType();
-                    if (!tt->isReference()) {
-                        continue;
-                    }
-                    addinst=true;
-                    break;
-                }
-                if (addinst) {
-                    exam2Insts->push_back(inst);
-                }
-                break;
-
             case Op_Catch:           // catch
                 type = inst->getDst()->getType();
                 if (type->isObject()) {
@@ -902,26 +885,6 @@
                 }
                 break;
 
-            case Op_IntrinsicCall:   // callintr
-                n=inst->getNumSrcOperands();
-                switch(inst->asIntrinsicCallInst()->getIntrinsicId()) {
-                    case ArrayCopyDirect:
-                    case ArrayCopyReverse:
-                         cgnode = findCnGNode_op(inst->getSrc(4)->getId());
-                         assert(cgnode!=NULL);
-                         cgn_src = findCnGNode_op(inst->getSrc(2)->getId());
-                         assert(cgn_src!=NULL);
-                         addEdge(cgnode,cgn_src,ET_DEFER,inst);
-                         if (verboseLog) {
-                             Log::out() << "need to add edge from "<< cgnode->cngNodeId
<< " - " << cgnode->opndId << " to "
-                                 << cgn_src->cngNodeId << " - " << cgn_src->opndId
<< std::endl;
-                         }
-                         break;
-                    default:
-                         assert(0);
-                }
-                break;
-
             case Op_StVar:           // stvar
                 type = inst->getDst()->getType();
                 if (type->isObject()) {
@@ -1257,19 +1220,6 @@
                         }
                         return;
                     }
-                    if (inst->getOpcode() == Op_IntrinsicCall) { //callintr
-                        uint32 iid = inst->asIntrinsicCallInst()->getIntrinsicId();
-                        switch(iid) {
-                            case ArrayCopyDirect:
-                            case ArrayCopyReverse:
-                                if (verboseLog) {
-                                    Log::out() << "++++ addEdge: callintr" <<
 std::endl;
-                                }
-                                return;
-                            default:
-                               assert(0);
-                        }
-                    }
                     if (inst->getOpcode() == Op_LdFieldAddr) {
                         FieldDesc* fd=inst->asFieldAccessInst()->getFieldDesc();
                         if (fd->getParentType()->isSystemString()&&strcmp(fd->getName(),"value")==0)
{
@@ -2711,8 +2661,6 @@
         fd->printFullName(os);
         os << std::endl;
     }
-    if (inst->asIntrinsicCallInst())
-        os << "        IntrinsicCallInst" << std::endl;
     if (inst->asMethodCallInst())
         os << "        MethodCallInst" << std::endl;
     if (inst->asMultiSrcInst())
@@ -3557,7 +3505,7 @@
     Opnd** args = NULL;
     InstFactory& instfactory = irManager.getInstFactory();
     Inst* jhcinst = instfactory.makeJitHelperCall(
-            stThis, ReadThisState, 0, args);
+            stThis, ReadThisState, NULL, NULL, 0, args);
     jhcinst->insertAfter(inst_after);
     newBlock = fg.splitNodeAtInstruction(jhcinst,true, false,instfactory.makeLabel());
     fg.addEdge(oldBlock,fg.getUnwindNode());
@@ -3668,7 +3616,7 @@
     Opnd* args[1] = {stVal};
     InstFactory& instfactory = irManager.getInstFactory();
     Inst* jhcinst = instfactory.makeJitHelperCall(
-            OpndManager::getNullOpnd(), SaveThisState, 1, args);
+            OpndManager::getNullOpnd(), SaveThisState, NULL, NULL, 1, args);
        // insert jit helper
     if (inst_before->getNode()->getFirstInst() == inst_before) {
         jhcinst->insertAfter(inst_before);
@@ -5840,7 +5788,10 @@
     return callInst->getVMHelperId() == id;
 }
 
-} //namespace Jitrino 
+} //namespace Jitrino
+
+
+
 
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escapeanalyzer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escapeanalyzer.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escapeanalyzer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/escapeanalyzer.cpp Sat Apr  5 03:58:31
2008
@@ -71,7 +71,6 @@
     switch (inst->getOpcode()) {
     case Op_DirectCall:     case Op_TauVirtualCall:
     case Op_IndirectCall:   case Op_IndirectMemoryCall: 
-    case Op_IntrinsicCall:
     case Op_Return:         case Op_Throw:
     case Op_TauStInd:       case Op_TauStRef:  
     case Op_TauStField:     case Op_TauStElem:     case Op_TauStStatic:
@@ -107,7 +106,7 @@
         if (srcIndex == 0)
             return false;
         break;
-    case Op_DirectCall:    case Op_TauVirtualCall:   case Op_IntrinsicCall:
+    case Op_DirectCall:    case Op_TauVirtualCall:
         break;
         //
         // return & throw
@@ -182,7 +181,7 @@
         //
         // calls should already be marked as escaping
         //
-    case Op_DirectCall:     case Op_TauVirtualCall:        case Op_IntrinsicCall:
+    case Op_DirectCall:     case Op_TauVirtualCall:
     case Op_IndirectCall:   case Op_IndirectMemoryCall: 
         break;
         //
@@ -339,7 +338,6 @@
             break;
         case Op_DirectCall:   
         case Op_TauVirtualCall:
-        case Op_IntrinsicCall:
             {
                 if (isRefOrPtrType(inst->getDst())) {
                     // this instruction creates a free ptr/ref

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/hashvaluenumberer.cpp Sat Apr  5
03:58:31 2008
@@ -208,8 +208,6 @@
     
     Inst* caseIndirectMemoryCall(CallInst* inst) { return caseDefault(inst); }
     
-    Inst* caseIntrinsicCall(IntrinsicCallInst* inst) { return caseDefault(inst); }
-
     Inst* caseJitHelperCall(JitHelperCallInst* inst) {return caseDefault(inst);}
 
     Inst* caseVMHelperCall(VMHelperCallInst* inst) {return caseDefault(inst);}
@@ -2322,7 +2320,7 @@
     case Op_TauCheckDivOpnds:
         break;
     case Op_DirectCall: case Op_TauVirtualCall: case Op_IndirectCall:
-    case Op_IndirectMemoryCall: case Op_IntrinsicCall:   case Op_InitType:
+    case Op_IndirectMemoryCall: case Op_JitHelperCall:   case Op_InitType:
         break;
     case Op_TauMonitorExit:
         break;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/inliner.cpp Sat Apr  5 03:58:31
2008
@@ -136,6 +136,9 @@
             _inlineSkipMethodTable->add_method_record("java/lang/Long", "numberOfTrailingZeros",
"(J)I", des, false);
 
 #endif
+            if(argSource->getBoolArg("System_arraycopy_as_magic",true)) {
+                _inlineSkipMethodTable->add_method_record("java/lang/System", "arraycopy",
"(Ljava/lang/Object;ILjava/lang/Object;II)V", des, false);
+            }
             if(argSource->getBoolArg("String_compareTo_as_magic",true)) {
                 _inlineSkipMethodTable->add_method_record("java/lang/String", "compareTo",
"(Ljava/lang/String;)I", des, false);
             }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/lazyexceptionopt.cpp Sat Apr  5
03:58:31 2008
@@ -892,7 +892,6 @@
             }
 #endif
             return methodCallHasSideEffect(inst);  
-        case Op_IntrinsicCall:
         case Op_JitHelperCall:
         case Op_VMHelperCall:
             return true;
@@ -1103,6 +1102,10 @@
     }
 }
 
-} //namespace Jitrino 
+} //namespace Jitrino
+
+
+
+
 
 

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/memoryopt.cpp Sat Apr  5 03:58:31
2008
@@ -618,42 +618,6 @@
             thePass->effectAnyGlobal(n, i);
         }
         break;
-    case Op_IntrinsicCall:
-        {
-            IntrinsicCallInst *calli = i->asIntrinsicCallInst();
-            IntrinsicCallId callId = calli->getIntrinsicId();
-            switch (callId) {
-            case CharArrayCopy:
-            case ArrayCopyDirect:
-            case ArrayCopyReverse:
-                {
-                    assert(calli->getNumSrcOperands() == 7);
-#ifndef NDEBUG
-                    Opnd *tauNullChecked = calli->getSrc(0);
-                    assert(tauNullChecked->getType()->tag == Type::Tau);
-                    Opnd *tauTypesChecked = calli->getSrc(1);
-                    assert(tauTypesChecked->getType()->tag == Type::Tau);
-#endif
-                    Opnd *srcarray = calli->getSrc(2);
-                    Opnd *srcoffset = calli->getSrc(3);
-                    Opnd *dstarray = calli->getSrc(4);
-                    Opnd *dstoffset = calli->getSrc(5);
-                    Opnd *length = calli->getSrc(6);
-
-                    // effectXXXArrayElements actually does not depends on offset parameter
-                    // so we do not need any special managing for the case of reverse copying
-                    thePass->effectReadArrayLength(n, i, srcarray);
-                    thePass->effectReadArrayElements(n, i, srcarray, srcoffset, length);
-                    thePass->effectReadArrayLength(n, i, dstarray);
-                    thePass->effectWriteArrayElements(n, i, dstarray, dstoffset, length);
-                }
-                break;
-            default:
-                assert(0);
-                break;
-            }
-        }
-        break;
     case Op_VMHelperCall:
         break;
     case Op_JitHelperCall:
@@ -668,8 +632,10 @@
             case ReadThisState:
             case LockedCompareAndExchange:
             case AddValueProfileValue:
+            case ArrayCopyDirect:
+            case ArrayCopyReverse:
             case StringCompareTo:
-	    case StringIndexOf:
+            case StringIndexOf:
             case StringRegionMatches:
             case FillArrayWithConst: 
             case ClassIsArray:

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifier.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifier.h?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifier.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifier.h Sat Apr  5 03:58:31
2008
@@ -491,8 +491,6 @@
 
     Inst* caseIndirectMemoryCall(CallInst* inst);
 
-    Inst* caseIntrinsicCall(IntrinsicCallInst* inst) {return caseDefault(inst);}
-
     Inst* caseJitHelperCall(JitHelperCallInst* inst) {return simplifyJitHelperCall(inst->asJitHelperCallInst());}
 
     Inst* caseVMHelperCall(VMHelperCallInst* inst) {return caseDefault(inst);}
@@ -539,9 +537,9 @@
                                inst->getDst()->getType(),
                                inst->getToken(),
                                inst->getEnclosingMethod());
-	if (opnd != NULL)
-	    return opnd->getInst();
-	return inst;
+        if (opnd != NULL)
+            return opnd->getInst();
+        return inst;
     }
 
     Inst* caseLdVar(Inst* inst) {return caseDefault(inst);}

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifytaus.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifytaus.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifytaus.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/optimizer/simplifytaus.cpp Sat Apr  5 03:58:31
2008
@@ -477,7 +477,6 @@
     case Op_TauVirtualCall:
     case Op_IndirectCall:
     case Op_IndirectMemoryCall:
-    case Op_IntrinsicCall:
         if (handleCalls) {
             return genTauSafe();
         } else {

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.cpp Sat Apr  5
03:58:31 2008
@@ -92,8 +92,6 @@
 
 static const char* help = \
     "  propValues[={ON|off}]    -  propagate values during translation\n"\
-    "  genArrayCopy[={ON|off}] - inline java/lang/System::arraycopy call as a copying loop\n"\
-    "  genArrayCopyRepMove[={ON|off}] - inline java/lang/System::arraycopy call as 'rep move'
instruction\n"\
     "  balancedSync[={on|OFF}] - treat all synchronization as balanced\n"\
     "  ignoreSync[={on|OFF}]   - do not generate synchronization\n"\
     "  syncAsEnterFence[={on|OFF}] - implement synchronization as monitor enter fence\n"\
@@ -119,8 +117,6 @@
 #else
     flags.optArrayInit = getBoolArg("optArrayInit", true);
 #endif
-    flags.genArrayCopy = getBoolArg("genArrayCopy", false); 
-    flags.genArrayCopyRepMove = getBoolArg("genArrayCopyRepMove", true);
     flags.onlyBalancedSync = getBoolArg("balancedSync", false);
 
     flags.ignoreSync       = getBoolArg("ignoreSync",false);

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/TranslatorIntfc.h Sat Apr  5 03:58:31
2008
@@ -50,8 +50,6 @@
     // to select which byte code translator optimizations are done
 struct TranslatorFlags {
     bool propValues         : 1;    // do value propagation
-    bool genArrayCopy       : 1;    // inline java/lang/System::arraycopy call as a copying
loop
-    bool genArrayCopyRepMove: 1;    // inline java/lang/System::arraycopy call as 'rep move'
instruction
     bool onlyBalancedSync   : 1;    // treat all method synchronization as balanced
     bool ignoreSync         : 1;    // do not generate monitor enter/exit instructions
     bool syncAsEnterFence   : 1;    // implement monitor enter as enter fence and

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
(original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp
Sat Apr  5 03:58:31 2008
@@ -1645,21 +1645,13 @@
         returnType = typeManager.getNullObjectType();
     }
     //
-    //  Try some optimizations for System::arraycopy(...), Min, Max, Abs...
+    //  Try some optimizations for Min, Max, Abs...
     //
-
-    if (translationFlags.genArrayCopyRepMove == true 
-        && genArrayCopyRepMove(methodDesc,numArgs,srcOpnds)) {
-        return;
-    } else if (translationFlags.genArrayCopy == true &&
-        genArrayCopy(methodDesc,numArgs,srcOpnds)) {
-        return;
-    } else if (translationFlags.genMinMaxAbs == true &&
+    if (translationFlags.genMinMaxAbs == true &&
         genMinMax(methodDesc,numArgs,srcOpnds,returnType)) {
         return;
-    } else {
+    } else
         genInvokeStatic(methodDesc,numArgs,srcOpnds,returnType);
-    }
 }
 
 void 
@@ -2352,502 +2344,6 @@
 }
 
 bool
-JavaByteCodeTranslator::methodIsArraycopy(MethodDesc * methodDesc) {
-
-    return (strcmp(methodDesc->getName(),"arraycopy") == 0 &&
-            strcmp(methodDesc->getParentType()->getName(),"java/lang/System") ==0);
-}
-
-bool
-JavaByteCodeTranslator::arraycopyOptimizable(MethodDesc * methodDesc, 
-                                             uint32       numArgs,
-                                             Opnd **      srcOpnds,
-                                             bool         usingWriteBarriers) {
-
-    //
-    //  an ArrayStoreException is thrown and the destination is not modified: 
-    //  
-    //  - The src argument refers to an object that is not an array. 
-    //  - The dest argument refers to an object that is not an array. 
-    //  - The src argument and dest argument refer to arrays whose component types are different
primitive types. 
-    //  - The src argument refers to an array with a primitive component type and the dest
argument
-    //    refers to an array with a reference component type. 
-    //  - The src argument refers to an array with a reference component type and the dest
argument
-    //    refers to an array with a primitive component type. 
-    //
-    assert(numArgs == 5);
-    Opnd * src = srcOpnds[0];
-    Type * srcType = src->getType();
-    Opnd * dst = srcOpnds[2];
-    Type * dstType = dst->getType();
-    assert(srcType->isObject() &&
-           srcOpnds[1]->getType()->isInt4() && // 1 - srcPos
-           dstType->isObject() &&
-           srcOpnds[3]->getType()->isInt4() && // 3 - dstPos
-           srcOpnds[4]->getType()->isInt4());  // 4 - length
-
-    bool srcIsArray = srcType->isArray() && !srcType->isUnresolvedType();
-    bool dstIsArray = dstType->isArray() && !dstType->isUnresolvedType();
-
-    bool isOptimizable = true;
-
-    if ( srcIsArray && dstIsArray )  {
-        // these are arrays        
-
-        ArrayType* srcAsArrayType = srcType->asArrayType();
-        ArrayType* dstAsArrayType = dstType->asArrayType();
-        bool srcIsArrOfPrimitive = srcIsArray && VMInterface::isArrayOfPrimitiveElements(srcAsArrayType->getVMTypeHandle());
-        bool dstIsArrOfPrimitive = dstIsArray && VMInterface::isArrayOfPrimitiveElements(dstAsArrayType->getVMTypeHandle());
-
-        // are these primitive or reference arrays?
-        if ( srcIsArrOfPrimitive && dstIsArrOfPrimitive ) {
-            // both arrays are primitive
-
-            // if we are dealing with different primitive type arrays, reject optimization
-            // TODO: is that really necessary?
-            isOptimizable = (srcType == dstType); 
-
-        } else if ( srcIsArrOfPrimitive ^ dstIsArrOfPrimitive ) {
-            // arrays are mixed primitive and reference types
-            // reject optimization
-            isOptimizable = false;
-
-        } else {
-            // both arrays are reference
-
-            // if write barriers are enabled, reject optimization
-            // if not, check the types
-            if ( usingWriteBarriers && compilationInterface.needWriteBarriers() )
{ 
-                isOptimizable = false;
-            } else {
-                // Here is some inaccuracy. If src is a subclass of dst there is no ASE for
sure.
-                // If it is not, we should check the assignability of each element being
copied.
-                // To avoid this we just reject the inlining of System::arraycopy call in
this case.
-                NamedType* srcElemType = srcAsArrayType->getElementType();
-                NamedType* dstElemType = dstAsArrayType->getElementType();
-                isOptimizable = (srcElemType->getVMTypeHandle() == dstElemType->getVMTypeHandle());
-            }
-
-        }
-
-    } else {
-        // source or destination are not arrays
-        isOptimizable = false;
-    }
-
-    return isOptimizable;
-}
-
-bool
-JavaByteCodeTranslator::genArrayCopyRepMove(MethodDesc * methodDesc, 
-                                            uint32       numArgs,
-                                            Opnd **      srcOpnds) {
-
-    if( !methodIsArraycopy(methodDesc) ||
-        !arraycopyOptimizable(methodDesc,numArgs,srcOpnds,true) )
-    {
-        // reject the inlining of System::arraycopy call
-        return false;
-    }
-
-    if (Log::isEnabled()) {
-        Log::out() << "XXX array copy into 'rep move': ";
-        methodDesc->printFullName(Log::out());
-        Log::out() << ::std::endl;
-    }
-
-    assert(numArgs == 5);
-    Opnd * src = srcOpnds[0];
-    Opnd * srcPos = srcOpnds[1];
-    Type * srcPosType = srcPos->getType();
-    Opnd * dst = srcOpnds[2];
-    Opnd * dstPos = srcOpnds[3];
-    Type * dstPosType = dstPos->getType();
-    Opnd * len = srcOpnds[4];
-
-    //
-    //  Generate exception condition checks:
-    //      chknull src
-    //      chknull dst
-    //      cmpbr srcPos < 0, boundsException
-    //      cmpbr dstPos < 0, boundsException
-    //      cmpbr len < 0, boundsException
-    //      srcEnd = add srcPos, len
-    //      srcLen = src.length
-    //      cmpbr srcEnd > srcLen, boundsException
-    //      dstEnd = add dstPos, len
-    //      dstLen = dst.length
-    //      cmpbr dstEnd > dstLen, boundsException
-    //  Skip trivial:
-    //      cmpbr (src == dst) && (dstPos == srcPos), Exit
-    //  Choose a direction:
-    //      cmpbr (dstPos > srcPos) && (src == dst), Reverse
-    //
-    //  Intrinsic calls will be codeselected into rep move instruction.
-    //  Direct:
-    //      IntrinsicCall id=ArrayCopyDirect
-    //      goto Exit
-    //  Reverse:
-    //      srcPos = srcPos + len - 1
-    //      dstPos = dstPos + len - 1
-    //      IntrinsicCall id=ArrayCopyReverse
-    //      goto Exit
-    //
-    //  boundsException:
-    //      chkbounds -1, src
-    //  Exit:
-    //
-    Opnd *tauSrcNullChecked = irBuilder.genTauCheckNull(src);
-    Opnd *tauDstNullChecked = irBuilder.genTauCheckNull(dst);
-    Opnd *tauNullCheckedRefArgs = irBuilder.genTauAnd(tauSrcNullChecked,tauDstNullChecked);
-    
-    LabelInst * reverseCopying = irBuilder.createLabel();
-    LabelInst * boundsException = irBuilder.createLabel();
-    LabelInst * Exit = irBuilder.createLabel();
-
-    Type * intType = typeManager.getInt32Type();
-    Type::Tag intTag = intType->tag;
-    Type * voidType = typeManager.getVoidType();
-
-    newFallthroughBlock();
-    Opnd * zero = irBuilder.genLdConstant((int32)0);
-    Opnd * minusone = irBuilder.genLdConstant((int32)-1);
-
-    irBuilder.genBranch(intTag,Cmp_GT,boundsException,zero,srcPos);        
-
-    newFallthroughBlock();
-    irBuilder.genBranch(intTag,Cmp_GT,boundsException,zero,dstPos);
-
-    newFallthroughBlock();
-    irBuilder.genBranch(intTag,Cmp_GT,boundsException,zero,len);
-
-    Modifier mod = Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No);
-
-    newFallthroughBlock();   
-    Opnd * srcLen = irBuilder.genArrayLen(intType,intTag,src);
-    Opnd * srcEnd = irBuilder.genAdd(intType,mod,srcPos,len);
-    irBuilder.genBranch(intTag,Cmp_GT,boundsException,srcEnd,srcLen);
-    
-    newFallthroughBlock();
-    Opnd * dstEnd = irBuilder.genAdd(intType,mod,dstPos,len);
-    Opnd * dstLen = irBuilder.genArrayLen(intType,intTag,dst);
-    irBuilder.genBranch(intTag,Cmp_GT,boundsException,dstEnd,dstLen);
-
-    newFallthroughBlock();
-
-    // The case of same arrays and same positions
-    Opnd * diff = irBuilder.genCmp3(intType,intTag,Cmp_GT,dstPos,srcPos);
-    Opnd * sameArrays = irBuilder.genCmp(intType,Type::IntPtr,Cmp_EQ,src,dst);
-    Opnd * zeroDiff = irBuilder.genCmp(intType,intTag,Cmp_EQ,diff,zero);
-    Opnd * nothingToCopy = irBuilder.genAnd(intType,sameArrays,zeroDiff);
-    irBuilder.genBranch(intTag,Cmp_GT,Exit,nothingToCopy,zero);
-
-    newFallthroughBlock();
-
-    Opnd* tauTypesChecked = irBuilder.genTauSafe();
-
-    // Choosing direction
-    Opnd * dstIsGreater = irBuilder.genCmp(intType,intTag,Cmp_GT,diff,zero);
-    Opnd * reverseCopy = irBuilder.genAnd(intType,sameArrays,dstIsGreater);
-    irBuilder.genBranch(intTag,Cmp_GT,reverseCopying,reverseCopy,zero);
-
-    newFallthroughBlock();
-
-    {   // Direct Copying
-    irBuilder.genIntrinsicCall(ArrayCopyDirect,voidType,
-                               tauNullCheckedRefArgs,
-                               tauTypesChecked,
-                               numArgs,srcOpnds);
-    irBuilder.genJump(Exit);
-    }   // End of Direct Copying
-
-    irBuilder.genLabel(reverseCopying);
-    cfgBuilder.genBlockAfterCurrent(reverseCopying);
-    {   // Reverse Copying
-
-    Opnd* lastSrcIdx = irBuilder.genAdd(srcPosType,mod,srcEnd,minusone);
-    Opnd* lastDstIdx = irBuilder.genAdd(dstPosType,mod,dstEnd,minusone);
-
-    Opnd** reverseArgs = new (memManager) Opnd*[numArgs];
-    reverseArgs[0] = srcOpnds[0]; // src
-    reverseArgs[1] = lastSrcIdx;  // srcPos+len-1
-    reverseArgs[2] = srcOpnds[2]; // dst
-    reverseArgs[3] = lastDstIdx;  // dstPos+len-1
-    reverseArgs[4] = srcOpnds[4]; // len
-    // copy
-    irBuilder.genIntrinsicCall(ArrayCopyReverse,voidType,
-                               tauNullCheckedRefArgs,
-                               tauTypesChecked,
-                               numArgs,reverseArgs);
-    irBuilder.genJump(Exit);
-    }   // End of Reverse Copying
-
-    irBuilder.genLabel(boundsException);
-    cfgBuilder.genBlockAfterCurrent(boundsException);
-    irBuilder.genTauCheckBounds(src,minusone,tauSrcNullChecked);
-
-    irBuilder.genLabel(Exit);
-    cfgBuilder.genBlockAfterCurrent(Exit);
-
-    return true;
-}
-
-bool
-JavaByteCodeTranslator::genArrayCopy(MethodDesc * methodDesc, 
-                                     uint32       numArgs,
-                                     Opnd **      srcOpnds) {
-
-    if( !methodIsArraycopy(methodDesc) ||
-        !arraycopyOptimizable(methodDesc,numArgs,srcOpnds,false) )
-    {
-        // reject the inlining of System::arraycopy call
-        return false;
-    }
-
-    if (Log::isEnabled()) {
-        Log::out() << "XXX array copy: "; methodDesc->printFullName(Log::out());
Log::out() << ::std::endl;
-    }
-
-    assert(numArgs == 5);
-    Opnd * src = srcOpnds[0];
-    Type * srcType = src->getType();
-    Opnd * srcPos = srcOpnds[1];
-    Type * srcPosType = srcPos->getType();
-    Opnd * dst = srcOpnds[2];
-    Type * dstType = dst->getType();
-    Opnd * dstPos = srcOpnds[3];
-    Type * dstPosType = dstPos->getType();
-    Opnd * len = srcOpnds[4];
-
-    //
-    //  Generate exception condition checks:
-    //      chknull src
-    //      chknull dst
-    //      cmpbr srcPos < 0, boundsException
-    //      cmpbr dstPos < 0, boundsException
-    //      cmpbr len < 0, boundsException
-    //      srcEnd = add srcPos, len
-    //      srcLen = src.length
-    //      cmpbr srcEnd > srcLen, boundsException
-    //      dstEnd = add dstPos, len
-    //      dstLen = dst.length
-    //      cmpbr dstEnd > dstLen, boundsException
-    //
-    //      diff = Cmp3(dstPos,srcPos)
-    //          //  1 if dstPos > srcPos
-    //          //  0 if dstPos == srcPos
-    //          // -1 if dstPos < srcPos
-    //      if (src == dst && diff == 0)  // nothing to do
-    //          goto L1:
-    //
-    //      if (diff > 0)
-    //          goto reverseCopying:
-    //
-    //      indexSrc = srcPos
-    //      indexDst = dstPos
-    //      increment = 1
-    //  copyDirectLoopHeader:
-    //      if (indexSrc == srcEnd)
-    //          goto L1:
-    //      dst[indexDst] = src[indexSrc]
-    //      indexSrc += increment
-    //      indexDst += increment
-    //      goto copyDirectLoopHeader:
-    //
-    //  reverseCopying:
-    //      indexSrc = srcPos + len - 1
-    //      indexDst = dstPos + len - 1
-    //      decrement = 1
-    //  copyReverseLoopHeader:
-    //      if (indexSrc < srcPos)
-    //          goto L1:
-    //      dst[indexDst] = src[indexSrc]
-    //      indexSrc -= decrement
-    //      indexDst -= decrement
-    //      goto copyReverseLoopHeader:
-    //
-    //  boundsException:
-    //      chkbounds -1, src
-    //  L1:
-    //
-    Opnd *tauSrcNullChecked = irBuilder.genTauCheckNull(src);
-    Opnd *tauDstNullChecked = irBuilder.genTauCheckNull(dst);
-    
-    LabelInst * reverseCopying = irBuilder.createLabel();
-    LabelInst * boundsException = irBuilder.createLabel();
-    LabelInst * L1 = irBuilder.createLabel();
-    Type * intType = typeManager.getInt32Type();
-
-    newFallthroughBlock();
-    Opnd * zero = irBuilder.genLdConstant((int32)0);
-    Opnd * one  = irBuilder.genLdConstant((int32)1);
-    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,zero,srcPos);        
-
-    newFallthroughBlock();
-    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,zero,dstPos);
-
-    newFallthroughBlock();
-    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,zero,len);
-
-    Modifier mod = Modifier(Overflow_None)|Modifier(Exception_Never)|Modifier(Strict_No);
-
-    newFallthroughBlock();   
-    Opnd * srcLen = irBuilder.genArrayLen(intType,Type::Int32,src);
-    Opnd * srcEnd = irBuilder.genAdd(intType,mod,srcPos,len);
-    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,srcEnd,srcLen);
-    
-    newFallthroughBlock();
-    Opnd * dstEnd = irBuilder.genAdd(intType,mod,dstPos,len);
-    Opnd * dstLen = irBuilder.genArrayLen(intType,Type::Int32,dst);
-    irBuilder.genBranch(Type::Int32,Cmp_GT,boundsException,dstEnd,dstLen);
-
-    newFallthroughBlock();
-
-    // The case of same arrays and same positions
-    Opnd * diff = irBuilder.genCmp3(intType,Type::Int32,Cmp_GT,dstPos,srcPos);
-    Opnd * sameArrays = irBuilder.genCmp(intType,Type::IntPtr,Cmp_EQ,src,dst);
-    Opnd * zeroDiff = irBuilder.genCmp(intType,Type::Int32,Cmp_EQ,diff,zero);
-    Opnd * nothingToCopy = irBuilder.genAnd(intType,sameArrays,zeroDiff);
-    irBuilder.genBranch(Type::Int32,Cmp_GT,L1,nothingToCopy,zero);
-
-    newFallthroughBlock();
-
-    // Choosing direction
-
-    irBuilder.genBranch(Type::Int32,Cmp_GT,reverseCopying,diff,zero);
-
-    newFallthroughBlock();
-
-    {   //Direct Copying
-
-    // indexes for using inside the loop
-    VarOpnd* srcPosVar = irBuilder.genVarDef(srcPosType, false);
-    VarOpnd* dstPosVar = irBuilder.genVarDef(dstPosType, false);
-
-    irBuilder.genStVar(srcPosVar, srcPos);
-    irBuilder.genStVar(dstPosVar, dstPos);
-
-    Opnd* srcPosOpnd = NULL;
-    Opnd* dstPosOpnd = NULL;
-
-    // Loop Header
-    LabelInst * loopHead = irBuilder.createLabel();
-    irBuilder.genLabel(loopHead);
-    cfgBuilder.genBlockAfterCurrent(loopHead);
-
-    // loop exit condition (srcIndex = srcStartIndex + len)
-    srcPosOpnd = irBuilder.genLdVar(srcPosType,srcPosVar);
-    irBuilder.genBranch(Type::Int32,Cmp_EQ,L1,srcPosOpnd,srcEnd);
-
-    newFallthroughBlock();
-    // array bounds have been checked directly 
-    // the types have been checked above so tauAddressInRange is tauSafe
-    Opnd *tauSrcAddressInRange = irBuilder.genTauSafe();
-    Opnd *tauDstAddressInRange = irBuilder.genTauSafe();
-    Opnd *tauDstBaseTypeChecked = irBuilder.genTauSafe();
-
-    // load indexes
-    srcPosOpnd = irBuilder.genLdVar(srcPosType,srcPosVar);
-    dstPosOpnd = irBuilder.genLdVar(dstPosType,dstPosVar);
-
-    Type* srcElemType = srcType->asArrayType()->getElementType();
-    Type* dstElemType = dstType->asArrayType()->getElementType();
-
-    // copy element
-    // (Checks are performed before the loop)
-    Opnd* elem = irBuilder.genLdElem(srcElemType,src,srcPosOpnd,
-                                     tauSrcNullChecked, tauSrcAddressInRange);
-    irBuilder.genStElem(dstElemType,dst,dstPosOpnd,elem,
-                        tauDstNullChecked, tauDstBaseTypeChecked, tauDstAddressInRange);
-
-    // increment indexes
-    srcPosOpnd = irBuilder.genAdd(srcPosType,mod,srcPosOpnd,one);
-    dstPosOpnd = irBuilder.genAdd(dstPosType,mod,dstPosOpnd,one);
-
-    // store indexes
-    irBuilder.genStVar(srcPosVar, srcPosOpnd);
-    irBuilder.genStVar(dstPosVar, dstPosOpnd);
-
-    // back edge
-    irBuilder.genPseudoThrow();
-    irBuilder.genJump(loopHead);
-    
-    }   // End of Direct Copying
-
-    {   //Reverse Copying
-    irBuilder.genLabel(reverseCopying);
-    cfgBuilder.genBlockAfterCurrent(reverseCopying);
-
-    // indexes for using inside the loop
-    VarOpnd* srcPosVar = irBuilder.genVarDef(srcPosType, false);
-    VarOpnd* dstPosVar = irBuilder.genVarDef(dstPosType, false);
-
-    Opnd* lastSrcIdx = irBuilder.genSub(srcPosType,mod,srcEnd,one);
-    Opnd* lastDstIdx = irBuilder.genSub(dstPosType,mod,dstEnd,one);
-
-    irBuilder.genStVar(srcPosVar, lastSrcIdx);
-    irBuilder.genStVar(dstPosVar, lastDstIdx);
-
-    Opnd* srcPosOpnd = NULL;
-    Opnd* dstPosOpnd = NULL;
-
-    // Loop Header
-    LabelInst * loopHead = irBuilder.createLabel();
-    irBuilder.genLabel(loopHead);
-    cfgBuilder.genBlockAfterCurrent(loopHead);
-
-    // loop exit condition (srcIndex < srcPos)
-    srcPosOpnd = irBuilder.genLdVar(srcPosType,srcPosVar);
-    irBuilder.genBranch(Type::Int32,Cmp_GT,L1,srcPos,srcPosOpnd);
-
-    newFallthroughBlock();
-    // array bounds have been checked directly 
-    // the types have been checked above so tauAddressInRange is tauSafe
-    Opnd *tauSrcAddressInRange = irBuilder.genTauSafe();
-    Opnd *tauDstAddressInRange = irBuilder.genTauSafe();
-    Opnd *tauDstBaseTypeChecked = irBuilder.genTauSafe();
-
-    // load indexes
-    srcPosOpnd = irBuilder.genLdVar(srcPosType,srcPosVar);
-    dstPosOpnd = irBuilder.genLdVar(dstPosType,dstPosVar);
-
-    Type* srcElemType = srcType->asArrayType()->getElementType();
-    Type* dstElemType = dstType->asArrayType()->getElementType();
-
-    // copy element
-    // (Checks are performed before the loop)
-    Opnd* elem = irBuilder.genLdElem(srcElemType,src,srcPosOpnd,
-                                     tauSrcNullChecked, tauSrcAddressInRange);
-    irBuilder.genStElem(dstElemType,dst,dstPosOpnd,elem,
-                        tauDstNullChecked, tauDstBaseTypeChecked, tauDstAddressInRange);
-
-    // decrement indexes
-    srcPosOpnd = irBuilder.genSub(srcPosType,mod,srcPosOpnd,one);
-    dstPosOpnd = irBuilder.genSub(dstPosType,mod,dstPosOpnd,one);
-
-    // store indexes
-    irBuilder.genStVar(srcPosVar, srcPosOpnd);
-    irBuilder.genStVar(dstPosVar, dstPosOpnd);
-
-    // back edge
-    irBuilder.genPseudoThrow();
-    irBuilder.genJump(loopHead);
-
-    }   // End of Reverse Copying
-
-
-    irBuilder.genLabel(boundsException);
-    cfgBuilder.genBlockAfterCurrent(boundsException);
-    Opnd * minusOne = irBuilder.genLdConstant((int32)-1);
-    irBuilder.genTauCheckBounds(src,minusOne,tauSrcNullChecked);
-
-    irBuilder.genLabel(L1);
-    cfgBuilder.genBlockAfterCurrent(L1);
-
-    return true;
-}
-
-bool
 JavaByteCodeTranslator::genMinMax(MethodDesc * methodDesc, 
                                   uint32       numArgs,
                                   Opnd **      srcOpnds,
@@ -3250,12 +2746,12 @@
     if (loadConst) {
         ConstInst::ConstValue v;
 #ifdef _EM64T_
-	v.i8 = theConst;
+        v.i8 = theConst;
 #else
-	v.i4 = theConst;	
+        v.i4 = theConst;        
 #endif
         Opnd* res = irBuilder.genLdConstant(typeManager.getUIntPtrType(), v);
-	
+
         if (resType->isPtr()) {
             res = irBuilder.genConv(resType, resType->tag, mod, res);
         }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h?rev=645073&r1=645072&r2=645073&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/translator/java/JavaByteCodeTranslator.h Sat
Apr  5 03:58:31 2008
@@ -273,11 +273,6 @@
     bool    genVMMagic(const char* mname, uint32 numArgs,Opnd ** srcOpnds,Type * returnType);
     bool    genVMHelper(const char* mname, uint32 numArgs,Opnd ** srcOpnds,Type * returnType);
     
-    bool    methodIsArraycopy(MethodDesc * methodDesc);
-    bool    arraycopyOptimizable(MethodDesc * methodDesc, uint32 numArgs, Opnd ** srcOpnds,
bool usingWriteBarriers);
-
-    bool    genArrayCopyRepMove(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds);
-    bool    genArrayCopy(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds);
     bool    genMinMax(MethodDesc * methodDesc,uint32 numArgs,Opnd ** srcOpnds, Type * returnType);
     void    newFallthroughBlock();
 



Mime
View raw message