void APIMagicsHandlerSession::runImpl()

in vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp [113:238]


void APIMagicsHandlerSession::runImpl() {
    CompilationContext* cc = getCompilationContext();
    MemoryManager tmpMM("Inline API methods");
#ifndef _EM64T_
    bool mathAsMagic = getBoolArg("magic_math", true);
#endif
    //finding all api magic calls
    IRManager* irm = cc->getLIRManager();
    ControlFlowGraph* fg = irm->getFlowGraph();
    StlVector<APIMagicHandler*> handlers(tmpMM);
    const Nodes& nodes = fg->getNodesPostOrder();//process checking only reachable nodes.
    for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
        Node* node = *it;
        if (node->isBlockNode()) {
            for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) {
                if (!inst->hasKind(Inst::Kind_CallInst)) {
                    continue;
                }
                if ( ((CallInst*)inst)->isDirect() ) {
                    CallInst* callInst = (CallInst*)inst;
                    Opnd * targetOpnd=callInst->getOpnd(callInst->getTargetOpndIndex());
                    assert(targetOpnd->isPlacedIn(OpndKind_Imm));
                    Opnd::RuntimeInfo * ri=targetOpnd->getRuntimeInfo();
                    if( !ri ) { 
                        continue; 
                    };
                    if( ri->getKind() == Opnd::RuntimeInfo::Kind_MethodDirectAddr ){
#ifndef _EM64T_
                        MethodDesc * md = (MethodDesc*)ri->getValue(0);
                        const char* className = md->getParentType()->getName();
                        const char* methodName = md->getName();
                        const char* signature = md->getSignatureString();
                        if (!strcmp(className, "java/lang/Integer")) {
                            if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(I)I")) {
                                handlers.push_back(new (tmpMM) Integer_numberOfLeadingZeros_Handler_x_I_x_I(irm, callInst, md));
                            } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(I)I")) {
                                handlers.push_back(new (tmpMM) Integer_numberOfTrailingZeros_Handler_x_I_x_I(irm, callInst, md));
                            }
                        } else if (!strcmp(className, "java/lang/Long")) {
                            if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(J)I")) {
                                handlers.push_back(new (tmpMM) Long_numberOfLeadingZeros_Handler_x_J_x_I(irm, callInst, md));
                            } else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(J)I")) {
                                handlers.push_back(new (tmpMM) Long_numberOfTrailingZeros_Handler_x_J_x_I(irm, callInst, md));
                            }
                        } else if (!strcmp(className, "java/lang/Float")) {
                            if (!strcmp(methodName, "floatToRawIntBits") && !strcmp(signature, "(F)I")) {
                                handlers.push_back(new (tmpMM) Float_floatToRawIntBits_x_F_x_I(irm, callInst, md));
                            } else if (!strcmp(methodName, "intBitsToFloat") && !strcmp(signature, "(I)F")) {
                                handlers.push_back(new (tmpMM) Float_intBitsToFloat_x_I_x_F(irm, callInst, md));
                            }
                        } else if (mathAsMagic && !strcmp(className, "java/lang/Math")) {
                            if (!strcmp(signature, "(D)D")) { 
                                if (!strcmp(methodName, "sqrt")) {                                   
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, SQRT, Mnemonic_FSQRT)); 
                                } 
                                if (!strcmp(methodName, "sin")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, SIN, Mnemonic_FSIN)); 
                                }      
                                if (!strcmp(methodName, "cos")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, COS, Mnemonic_FCOS)); 
                                } 
                                if (!strcmp(methodName, "abs")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ABS, Mnemonic_FABS)); 
                                }
                                if (!strcmp(methodName, "tan")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, TAN, Mnemonic_FPTAN)); 
                                } 
                                if (!strcmp(methodName, "log")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, LOG, Mnemonic_FLDLN2)); 
                                }       
                                if (!strcmp(methodName, "log10")) {                                   
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, LOG10, Mnemonic_FLDLG2)); 
                                }
                                if (!strcmp(methodName, "log1p")) {                                   
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, LOG1P, Mnemonic_FLDLN2)); 
                                }       
                                if (!strcmp(methodName, "atan")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ATAN)); 
                                }
                                if (!strcmp(methodName, "asin")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ASIN)); 
                                }
                                if (!strcmp(methodName, "acos")) {                                    
                                       handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ACOS)); 
                                }
                            } else if (!strcmp(signature, "(F)F") && !strcmp(methodName, "abs")) {
                                handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ABS, Mnemonic_FABS));
                            } else if (!strcmp(signature, "(DD)D") && !strcmp(methodName, "atan2")) {
                                handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ATAN2)); 
                            }
                        }
#endif
                    } else if( ri->getKind() == Opnd::RuntimeInfo::Kind_InternalHelperAddress ) {
                        if( strcmp((char*)ri->getValue(0),"memory_copy_direct")==0 ) {
                            if(getBoolArg("System_arraycopy_as_magic", true)) {
                                handlers.push_back(new (tmpMM) System_arraycopyDirect_Handler(irm, callInst, NULL));
                            } else { assert(0); }
                        } else if( strcmp((char*)ri->getValue(0),"memory_copy_reverse")==0 ) {
                            if(getBoolArg("System_arraycopy_as_magic", true)) {
                                handlers.push_back(new (tmpMM) System_arraycopyReverse_Handler(irm, callInst, NULL));
                            } else { assert(0); }
                        } else if( strcmp((char*)ri->getValue(0),"String_compareTo")==0 ) {
                            if(getBoolArg("String_compareTo_as_magic", true))
                                handlers.push_back(new (tmpMM) String_compareTo_Handler_x_String_x_I(irm, callInst, NULL));
                        } else if( strcmp((char*)ri->getValue(0),"String_regionMatches")==0 ) {
                            if(getBoolArg("String_regionMatches_as_magic", true))
                                handlers.push_back(new (tmpMM) String_regionMatches_Handler_x_I_x_String_x_I_x_I_x_Z(irm, callInst, NULL));
                        } else if( strcmp((char*)ri->getValue(0),"String_indexOf")==0 ) {
                            if(getBoolArg("String_indexOf_as_magic", true))
                                handlers.push_back(new (tmpMM) String_indexOf_Handler_x_String_x_I_x_I(irm, callInst, NULL));
                        }
                    }
                }
            }
        }
    }

    //running all handlers
    for (StlVector<APIMagicHandler*>::const_iterator it = handlers.begin(), end = handlers.end(); it!=end; ++it) {
        APIMagicHandler* handler = *it;
        handler->run();
    }
    if (handlers.size() > 0) {
        irm->invalidateLivenessInfo();
    }
}