/* * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// Convert method signature into an array of BasicTypes for the arguments
BasicTypeArray* FrameMap::signature_type_array_for(const ciMethod* method) {
ciSignature* sig = method->signature();
BasicTypeList* sta = new BasicTypeList(method->arg_size()); // add receiver, if any if (!method->is_static()) sta->append(T_OBJECT); // add remaining arguments for (int i = 0; i < sig->count(); i++) {
ciType* type = sig->type_at(i);
BasicType t = type->basic_type(); if (t == T_ARRAY) {
t = T_OBJECT;
}
sta->append(t);
} // done return sta;
}
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);
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() / 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);
} returnnew CallingConvention(args, out_preserve);
}
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() / 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); returnnew CallingConvention(args, out_preserve);
}
// For OopMaps, map a local variable or spill index to an VMReg. // This is the offset from sp() in the frame of the slot for the index, // skewed by SharedInfo::stack0 to indicate a stack location (vs.a register.) // // C ABI size + // framesize + framesize + // stack0 stack0 stack0 0 <- VMReg->value() // | | | <registers> | // ..........|..............|..............|.............| // 0 1 2 3 | <C ABI area> | 4 5 6 ...... | <- local indices // ^ ^ sp() // | | // arguments non-argument locals
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.