FrameMap::FrameMap(ciMethod* method, int monitors, int reserved_argument_area_size) { assert(_init_done, "should already be completed"); _framesize = -1; _num_spills = -1; assert(monitors >= 0, "not set"); _num_monitors = monitors; assert(reserved_argument_area_size >= 0, "not set"); _reserved_argument_area_size = MAX2(4, reserved_argument_area_size) * BytesPerWord; _argcount = method->arg_size(); _argument_locations = new intArray(_argcount, -1); _incoming_arguments = java_calling_convention(signature_type_array_for(method), false); _oop_map_arg_count = _incoming_arguments->reserved_stack_slots(); int java_index = 0; for (int i = 0; i < _incoming_arguments->length(); i++) { LIR_Opr opr = _incoming_arguments->at(i); if (opr->is_address()) { LIR_Address* address = opr->as_address_ptr(); _argument_locations->at_put(java_index, address->disp() - STACK_BIAS); _incoming_arguments->args()->at_put(i, LIR_OprFact::stack(java_index, as_BasicType(as_ValueType(address->type())))); } java_index += type2size[opr->type()]; } }
VMReg FrameMap::regname(LIR_Opr opr) const { if (opr->is_single_cpu()) { assert(!opr->is_virtual(), "should not see virtual registers here"); return opr->as_register()->as_VMReg(); } else if (opr->is_single_stack()) { return sp_offset2vmreg(sp_offset_for_slot(opr->single_stack_ix())); } else if (opr->is_address()) { LIR_Address* addr = opr->as_address_ptr(); assert(addr->base() == stack_pointer(), "sp based addressing only"); return sp_offset2vmreg(in_ByteSize(addr->index()->as_jint())); } ShouldNotReachHere(); return VMRegImpl::Bad(); }
CallingConvention* FrameMap::c_calling_convention(const BasicTypeArray* signature) { // compute the size of the arguments first. The signature array // that java_calling_convention takes includes a T_VOID after double // work items but our signatures do not. int i; int sizeargs = 0; for (i = 0; i < signature->length(); i++) { sizeargs += type2size[signature->at(i)]; } BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs); VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs); int sig_index = 0; for (i = 0; i < sizeargs; i++, sig_index++) { sig_bt[i] = signature->at(sig_index); if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { sig_bt[i + 1] = T_VOID; i++; } } intptr_t out_preserve = SharedRuntime::c_calling_convention(sig_bt, regs, NULL, sizeargs); LIR_OprList* args = new LIR_OprList(signature->length()); for (i = 0; i < sizeargs;) { BasicType t = sig_bt[i]; assert(t != T_VOID, "should be skipping these"); // C calls are always outgoing bool outgoing = true; LIR_Opr opr = map_to_opr(t, regs + i, outgoing); // they might be of different types if for instance floating point // values are passed in cpu registers, but the sizes must match. assert(type2size[opr->type()] == type2size[t], "type mismatch"); args->append(opr); if (opr->is_address()) { LIR_Address* addr = opr->as_address_ptr(); out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4); } i += type2size[t]; } assert(args->length() == signature->length(), "size mismatch"); out_preserve += SharedRuntime::out_preserve_stack_slots(); update_reserved_argument_area_size(out_preserve * BytesPerWord); return new CallingConvention(args, out_preserve); }
CallingConvention* FrameMap::java_calling_convention(const BasicTypeArray* signature, bool outgoing) { // compute the size of the arguments first. The signature array // that java_calling_convention takes includes a T_VOID after double // work items but our signatures do not. int i; int sizeargs = 0; for (i = 0; i < signature->length(); i++) { sizeargs += type2size[signature->at(i)]; } BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs); VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs); int sig_index = 0; for (i = 0; i < sizeargs; i++, sig_index++) { sig_bt[i] = signature->at(sig_index); if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { sig_bt[i + 1] = T_VOID; i++; } } intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, outgoing); LIR_OprList* args = new LIR_OprList(signature->length()); for (i = 0; i < sizeargs;) { BasicType t = sig_bt[i]; assert(t != T_VOID, "should be skipping these"); LIR_Opr opr = map_to_opr(t, regs + i, outgoing); args->append(opr); if (opr->is_address()) { LIR_Address* addr = opr->as_address_ptr(); assert(addr->disp() == (int)addr->disp(), "out of range value"); out_preserve = MAX2(out_preserve, (intptr_t)(addr->disp() - STACK_BIAS) / 4); } i += type2size[t]; } assert(args->length() == signature->length(), "size mismatch"); out_preserve += SharedRuntime::out_preserve_stack_slots(); if (outgoing) { // update the space reserved for arguments. update_reserved_argument_area_size(out_preserve * BytesPerWord); } return new CallingConvention(args, out_preserve); }