コード例 #1
0
// inputs should be preserved outside if required since we do a call
// num_std_need_to_save registers will be preserved
char * m2n_gen_push_m2n(char * buf, Method_Handle method, 
                        frame_type current_frame_type, 
                        bool handles,
                        unsigned num_callee_saves,
                        unsigned num_std_need_to_save,
                        I_32 bytes_to_m2n_top) {
    // skip callee-saves registers
    bytes_to_m2n_top -= num_callee_saves * LcgEM64TContext::GR_SIZE;
    // TODO: check if it makes sense to save all callee-saves registers here
    //store rest of callee-saves registers
    for (unsigned i = num_callee_saves; i < LcgEM64TContext::MAX_GR_LOCALS; i++) {
        bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
        buf = mov(buf,
            M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
            LcgEM64TContext::get_reg_from_map(LcgEM64TContext::GR_LOCALS_OFFSET + i),
            size_64);        
    }
    // init pop_regs to null
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
        Imm_Opnd(size_32, 0), size_64);
    // store current_frame_type
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    assert(fit32(current_frame_type));
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
        Imm_Opnd(size_32, current_frame_type), size_64);
    // store a method associated with the current m2n frame
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    if (fit32((int64)method)) {
        buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
            Imm_Opnd(size_32, (int64)method), size_64);
    } else {
        buf = mov(buf, rax_opnd, Imm_Opnd(size_64, (int64)method), size_64);
        buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top), rax_opnd);
    }
    // store local object handles
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top),
        Imm_Opnd(size_64, (int64)0), size_64);

    // move pointer to the current VM_Thread structure to rax
    buf = m2n_gen_ts_to_register(buf, &rax_opnd,
        num_callee_saves, LcgEM64TContext::MAX_GR_LOCALS,
        num_std_need_to_save, 0);
    
    // shift to the last_m2n_frame field
    I_32 last_m2n_frame_offset = (I_32)(int64)&((VM_thread*)0)->last_m2n_frame;
    buf = alu(buf, add_opc,  rax_opnd,  Imm_Opnd(size_32, last_m2n_frame_offset), size_64);
    // store pointer to pointer to last m2n frame
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top), rax_opnd, size_64);
    // save pointer to the previous m2n frame
    bytes_to_m2n_top -= LcgEM64TContext::GR_SIZE;
    buf = mov(buf, r9_opnd, M_Base_Opnd(rax_reg, 0));
    buf = mov(buf, M_Base_Opnd(rsp_reg, bytes_to_m2n_top), r9_opnd, size_64);
    // update last m2n frame of the current thread
    buf = lea(buf, r9_opnd, M_Base_Opnd(rsp_reg, bytes_to_m2n_top));
    buf = mov(buf,  M_Base_Opnd(rax_reg, 0), r9_opnd, size_64);
    return buf;
}
コード例 #2
0
bool RuntimeInterface::isSOEArea(MethodDesc* methodDesc, const ::JitFrameContext* context, bool isFirst) {
#ifdef _EM64T_
    POINTER_SIZE_INT eip = *context->p_rip;
#else
    POINTER_SIZE_INT eip = *context->p_eip;
#endif
    StackInfo stackInfo;
    stackInfo.read(methodDesc, eip, isFirst);
    assert(eip >= (POINTER_SIZE_INT)methodDesc->getCodeBlockAddress(0));
    POINTER_SIZE_INT eipOffset = eip - (POINTER_SIZE_INT)methodDesc->getCodeBlockAddress(0);
    assert(fit32(eipOffset));
    return eipOffset<=stackInfo.getSOECheckAreaOffset();
}
コード例 #3
0
void StackInfo::read(MethodDesc* pMethodDesc, POINTER_SIZE_INT eip, bool isFirst) {
    U_8* data = pMethodDesc->getInfoBlock();
    byteSize = ((StackInfo *)data)->byteSize;
    hashTableSize = ((StackInfo *)data)->hashTableSize;
    frameSize = ((StackInfo *)data)->frameSize;
    icalleeOffset = ((StackInfo *)data)->icalleeOffset;
    icalleeMask = ((StackInfo *)data)->icalleeMask;
    localOffset = ((StackInfo *)data)->localOffset;
    offsetOfThis = ((StackInfo *)data)->offsetOfThis;
    itraceMethodExitString = ((StackInfo *)data)->itraceMethodExitString;
    soeCheckAreaOffset = ((StackInfo *)data)->soeCheckAreaOffset;
    
    if (!isFirst){
        DepthEntry * entry = getHashEntry(data, eip, hashTableSize);
        assert(entry);
        if (!entry){
            if (Log::cat_rt()->isEnabled())
                Log::cat_rt()->out()<<"eip=0x"<<(void*)eip<<" not found during stack unwinding!"<<::std::endl;
            ::std::cerr<<"eip=0x"<<(void*)eip<<" not found during stack unwinding!"<<::std::endl;
        }
        calleeSaveRegsMask = entry->info.calleeSaveRegs;
        stackDepth = entry->info.stackDepth;
    }else{
        assert(eip >= (POINTER_SIZE_INT)pMethodDesc->getCodeBlockAddress(0));
        POINTER_SIZE_INT eipOffset = eip - (POINTER_SIZE_INT)pMethodDesc->getCodeBlockAddress(0);
        assert(fit32(eipOffset));
        if (eipOffset <= soeCheckAreaOffset) {
            stackDepth = 0; //0 depth -> stack overflow error
        } else {
            DepthEntry * entry = NULL;
            U_32 i = CALL_MIN_SIZE;
            for (; i<= CALL_MAX_SIZE; i++) {
                entry = getHashEntry(data, eip + i, hashTableSize);
                if(entry)
                    break;
            }
            if (entry && (entry->info.callSize == i)) {
                stackDepth = entry->info.stackDepth; //call site's depth
            } else {
                stackDepth = frameSize; //hardware NPE's depth
            }
        }

        if (Log::cat_rt()->isEnabled())
            Log::cat_rt()->out()<<"Hardware exception from eip=0x"<<(void*)eip<<::std::endl;
    }
}