mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-20 07:58:55 +00:00
8086069: Adapt runtime calls to recent intrinsics to pass ints as long
Remove CCallingConventionRequiresIntsAsLongs from shared code and push functionality to native wrapper. Less optimal but more flexible. Reviewed-by: jrose, kvn
This commit is contained in:
parent
7682410613
commit
07c7774cd7
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, 2015, Red Hat Inc. 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
|
||||
@ -28,12 +28,6 @@
|
||||
|
||||
const int StackAlignmentInBytes = 16;
|
||||
|
||||
// Indicates whether the C calling conventions require that
|
||||
// 32-bit integer argument values are properly extended to 64 bits.
|
||||
// If set, SharedRuntime::c_calling_convention() must adapt
|
||||
// signatures accordingly.
|
||||
const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||
|
||||
#define SUPPORTS_NATIVE_CX8
|
||||
|
||||
// The maximum B/BL offset range on AArch64 is 128MB.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2012, 2013 SAP AG. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2012, 2015 SAP AG. 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
|
||||
@ -31,12 +31,6 @@ const int BytesPerInstWord = 4;
|
||||
|
||||
const int StackAlignmentInBytes = 16;
|
||||
|
||||
// Indicates whether the C calling conventions require that
|
||||
// 32-bit integer argument values are properly extended to 64 bits.
|
||||
// If set, SharedRuntime::c_calling_convention() must adapt
|
||||
// signatures accordingly.
|
||||
const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||
|
||||
#define SUPPORTS_NATIVE_CX8
|
||||
|
||||
// The PPC CPUs are NOT multiple-copy-atomic.
|
||||
|
||||
@ -731,23 +731,8 @@ int SharedRuntime::c_calling_convention(const BasicType *sig_bt,
|
||||
case T_SHORT:
|
||||
case T_INT:
|
||||
// We must cast ints to longs and use full 64 bit stack slots
|
||||
// here. We do the cast in GraphKit::gen_stub() and just guard
|
||||
// here against loosing that change.
|
||||
assert(CCallingConventionRequiresIntsAsLongs,
|
||||
"argument of type int should be promoted to type long");
|
||||
guarantee(i > 0 && sig_bt[i-1] == T_LONG,
|
||||
"argument of type (bt) should have been promoted to type (T_LONG,bt) for bt in "
|
||||
"{T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
|
||||
// Do not count halves.
|
||||
regs[i].set_bad();
|
||||
--arg;
|
||||
break;
|
||||
// here. Thus fall through, handle as long.
|
||||
case T_LONG:
|
||||
guarantee(sig_bt[i+1] == T_VOID ||
|
||||
sig_bt[i+1] == T_BOOLEAN || sig_bt[i+1] == T_CHAR ||
|
||||
sig_bt[i+1] == T_BYTE || sig_bt[i+1] == T_SHORT ||
|
||||
sig_bt[i+1] == T_INT,
|
||||
"expecting type (T_LONG,half) or type (T_LONG,bt) with bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
|
||||
case T_OBJECT:
|
||||
case T_ARRAY:
|
||||
case T_ADDRESS:
|
||||
@ -1273,7 +1258,7 @@ static void object_move(MacroAssembler* masm,
|
||||
static void int_move(MacroAssembler*masm,
|
||||
VMRegPair src, VMRegPair dst,
|
||||
Register r_caller_sp, Register r_temp) {
|
||||
assert(src.first()->is_valid() && src.second() == src.first()->next(), "incoming must be long-int");
|
||||
assert(src.first()->is_valid(), "incoming must be int");
|
||||
assert(dst.first()->is_valid() && dst.second() == dst.first()->next(), "outgoing must be long");
|
||||
|
||||
if (src.first()->is_stack()) {
|
||||
@ -1762,13 +1747,6 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
// the jni function will expect them. To figure out where they go
|
||||
// we convert the java signature to a C signature by inserting
|
||||
// the hidden arguments as arg[0] and possibly arg[1] (static method)
|
||||
//
|
||||
// Additionally, on ppc64 we must convert integers to longs in the C
|
||||
// signature. We do this in advance in order to have no trouble with
|
||||
// indexes into the bt-arrays.
|
||||
// So convert the signature and registers now, and adjust the total number
|
||||
// of in-arguments accordingly.
|
||||
int i2l_argcnt = convert_ints_to_longints_argcnt(total_in_args, in_sig_bt); // PPC64: pass ints as longs.
|
||||
|
||||
// Calculate the total number of C arguments and create arrays for the
|
||||
// signature and the outgoing registers.
|
||||
@ -1776,7 +1754,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
// some floating-point arguments must be passed in registers _and_
|
||||
// in stack locations.
|
||||
bool method_is_static = method->is_static();
|
||||
int total_c_args = i2l_argcnt;
|
||||
int total_c_args = total_in_args;
|
||||
|
||||
if (!is_critical_native) {
|
||||
int n_hidden_args = method_is_static ? 2 : 1;
|
||||
@ -1785,7 +1763,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
// No JNIEnv*, no this*, but unpacked arrays (base+length).
|
||||
for (int i = 0; i < total_in_args; i++) {
|
||||
if (in_sig_bt[i] == T_ARRAY) {
|
||||
total_c_args += 2; // PPC64: T_LONG, T_INT, T_ADDRESS (see convert_ints_to_longints and c_calling_convention)
|
||||
total_c_args++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1803,8 +1781,6 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
|
||||
int argc = 0;
|
||||
if (!is_critical_native) {
|
||||
convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
|
||||
|
||||
out_sig_bt[argc++] = T_ADDRESS;
|
||||
if (method->is_static()) {
|
||||
out_sig_bt[argc++] = T_OBJECT;
|
||||
@ -1815,7 +1791,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
}
|
||||
} else {
|
||||
Thread* THREAD = Thread::current();
|
||||
in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
|
||||
in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
|
||||
SignatureStream ss(method->signature());
|
||||
int o = 0;
|
||||
for (int i = 0; i < total_in_args ; i++, o++) {
|
||||
@ -1839,28 +1815,16 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
}
|
||||
} else {
|
||||
in_elem_bt[o] = T_VOID;
|
||||
switch(in_sig_bt[i]) { // PPC64: pass ints as longs.
|
||||
case T_BOOLEAN:
|
||||
case T_CHAR:
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT: in_elem_bt[++o] = T_VOID; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (in_sig_bt[i] != T_VOID) {
|
||||
assert(in_sig_bt[i] == ss.type(), "must match");
|
||||
ss.next();
|
||||
}
|
||||
}
|
||||
assert(i2l_argcnt==o, "must match");
|
||||
|
||||
convert_ints_to_longints(i2l_argcnt, total_in_args, in_sig_bt, in_regs); // PPC64: pass ints as longs.
|
||||
|
||||
for (int i = 0; i < total_in_args ; i++ ) {
|
||||
if (in_sig_bt[i] == T_ARRAY) {
|
||||
// Arrays are passed as int, elem* pair.
|
||||
out_sig_bt[argc++] = T_LONG; // PPC64: pass ints as longs.
|
||||
out_sig_bt[argc++] = T_INT;
|
||||
out_sig_bt[argc++] = T_ADDRESS;
|
||||
} else {
|
||||
@ -1921,7 +1885,8 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_CHAR:
|
||||
case T_INT: /*single_slots++;*/ break; // PPC64: pass ints as longs.
|
||||
case T_INT:
|
||||
// Fall through.
|
||||
case T_ARRAY:
|
||||
case T_LONG: double_slots++; break;
|
||||
default: ShouldNotReachHere();
|
||||
@ -2019,7 +1984,7 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
|
||||
__ save_LR_CR(r_temp_1);
|
||||
__ generate_stack_overflow_check(frame_size_in_bytes); // Check before creating frame.
|
||||
__ mr(r_callers_sp, R1_SP); // Remember frame pointer.
|
||||
__ mr(r_callers_sp, R1_SP); // Remember frame pointer.
|
||||
__ push_frame(frame_size_in_bytes, r_temp_1); // Push the c2n adapter's frame.
|
||||
frame_done_pc = (intptr_t)__ pc();
|
||||
|
||||
@ -2098,24 +2063,16 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT:
|
||||
guarantee(in > 0 && in_sig_bt[in-1] == T_LONG,
|
||||
"expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
|
||||
// Move int and do sign extension.
|
||||
int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
|
||||
break;
|
||||
case T_LONG:
|
||||
if (in_sig_bt[in+1] == T_VOID) {
|
||||
long_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
|
||||
} else {
|
||||
guarantee(in_sig_bt[in+1] == T_BOOLEAN || in_sig_bt[in+1] == T_CHAR ||
|
||||
in_sig_bt[in+1] == T_BYTE || in_sig_bt[in+1] == T_SHORT ||
|
||||
in_sig_bt[in+1] == T_INT,
|
||||
"expecting type (T_LONG,bt) for bt in {T_BOOLEAN, T_CHAR, T_BYTE, T_SHORT, T_INT}");
|
||||
int_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
|
||||
}
|
||||
long_move(masm, in_regs[in], out_regs[out], r_callers_sp, r_temp_1);
|
||||
break;
|
||||
case T_ARRAY:
|
||||
if (is_critical_native) {
|
||||
int body_arg = out;
|
||||
out -= 2; // Point to length arg. PPC64: pass ints as longs.
|
||||
out -= 1; // Point to length arg.
|
||||
unpack_array_argument(masm, in_regs[in], in_elem_bt[in], out_regs[body_arg], out_regs[out],
|
||||
r_callers_sp, r_temp_1, r_temp_2);
|
||||
break;
|
||||
@ -2187,7 +2144,6 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
|
||||
// Make sure that thread is non-volatile; it crosses a bunch of VM calls below.
|
||||
assert(R16_thread->is_nonvolatile(), "thread must be in non-volatile register");
|
||||
|
||||
|
||||
# if 0
|
||||
// DTrace method entry
|
||||
# endif
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, 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
|
||||
@ -30,12 +30,6 @@ const int BytesPerInstWord = 4;
|
||||
|
||||
const int StackAlignmentInBytes = (2*wordSize);
|
||||
|
||||
// Indicates whether the C calling conventions require that
|
||||
// 32-bit integer argument values are properly extended to 64 bits.
|
||||
// If set, SharedRuntime::c_calling_convention() must adapt
|
||||
// signatures accordingly.
|
||||
const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define SUPPORTS_NATIVE_CX8
|
||||
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
|
||||
@ -27,12 +27,6 @@
|
||||
|
||||
const int StackAlignmentInBytes = 16;
|
||||
|
||||
// Indicates whether the C calling conventions require that
|
||||
// 32-bit integer argument values are properly extended to 64 bits.
|
||||
// If set, SharedRuntime::c_calling_convention() must adapt
|
||||
// signatures accordingly.
|
||||
const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#define SUPPORTS_NATIVE_CX8
|
||||
|
||||
// The expected size in bytes of a cache line, used to pad data structures.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2009 Red Hat, Inc.
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2009, 2015, Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -28,10 +28,4 @@
|
||||
|
||||
#include <ffi.h>
|
||||
|
||||
// Indicates whether the C calling conventions require that
|
||||
// 32-bit integer argument values are properly extended to 64 bits.
|
||||
// If set, SharedRuntime::c_calling_convention() must adapt
|
||||
// signatures accordingly.
|
||||
const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||
|
||||
#endif // CPU_ZERO_VM_GLOBALDEFINITIONS_ZERO_HPP
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2015, 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
|
||||
@ -118,19 +118,14 @@ void GraphKit::gen_stub(address C_function,
|
||||
// The C routines gets the base of thread-local storage passed in as an
|
||||
// extra argument. Not all calls need it, but its cheap to add here.
|
||||
for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) {
|
||||
// Convert ints to longs if required.
|
||||
if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(pcnt)->isa_int()) {
|
||||
fields[cnt++] = TypeLong::LONG;
|
||||
fields[cnt] = Type::HALF; // must add an additional half for a long
|
||||
} else {
|
||||
fields[cnt] = jdomain->field_at(pcnt);
|
||||
}
|
||||
fields[cnt] = jdomain->field_at(pcnt);
|
||||
}
|
||||
|
||||
fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
|
||||
// Also pass in the caller's PC, if asked for.
|
||||
if( return_pc )
|
||||
if (return_pc) {
|
||||
fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC
|
||||
}
|
||||
|
||||
const TypeTuple* domain = TypeTuple::make(cnt,fields);
|
||||
// The C routine we are about to call cannot return an oop; it can block on
|
||||
@ -143,21 +138,22 @@ void GraphKit::gen_stub(address C_function,
|
||||
const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms);
|
||||
// Fixup oop returns
|
||||
int retval_ptr = retval->isa_oop_ptr();
|
||||
if( retval_ptr ) {
|
||||
if (retval_ptr) {
|
||||
assert( pass_tls, "Oop must be returned thru TLS" );
|
||||
// Fancy-jumps return address; others return void
|
||||
rfields[TypeFunc::Parms] = is_fancy_jump ? TypeRawPtr::BOTTOM : Type::TOP;
|
||||
|
||||
} else if( retval->isa_int() ) { // Returning any integer subtype?
|
||||
} else if (retval->isa_int()) { // Returning any integer subtype?
|
||||
// "Fatten" byte, char & short return types to 'int' to show that
|
||||
// the native C code can return values with junk high order bits.
|
||||
// We'll sign-extend it below later.
|
||||
rfields[TypeFunc::Parms] = TypeInt::INT; // It's "dirty" and needs sign-ext
|
||||
|
||||
} else if( jrange->cnt() >= TypeFunc::Parms+1 ) { // Else copy other types
|
||||
} else if (jrange->cnt() >= TypeFunc::Parms+1) { // Else copy other types
|
||||
rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms);
|
||||
if( jrange->cnt() == TypeFunc::Parms+2 )
|
||||
if (jrange->cnt() == TypeFunc::Parms+2) {
|
||||
rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1);
|
||||
}
|
||||
}
|
||||
const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields);
|
||||
|
||||
@ -181,14 +177,7 @@ void GraphKit::gen_stub(address C_function,
|
||||
// A little too aggressive on the parm copy; return address is not an input
|
||||
call->set_req(TypeFunc::ReturnAdr, top());
|
||||
for (; i < parm_cnt; i++) { // Regular input arguments
|
||||
// Convert ints to longs if required.
|
||||
if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(i)->isa_int()) {
|
||||
Node* int_as_long = _gvn.transform(new ConvI2LNode(map()->in(i)));
|
||||
call->init_req(cnt++, int_as_long); // long
|
||||
call->init_req(cnt++, top()); // half
|
||||
} else {
|
||||
call->init_req(cnt++, map()->in(i));
|
||||
}
|
||||
call->init_req(cnt++, map()->in(i));
|
||||
}
|
||||
|
||||
call->init_req( cnt++, thread );
|
||||
|
||||
@ -2941,13 +2941,6 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
|
||||
_igvn.register_new_node_with_optimizer(store_value);
|
||||
}
|
||||
|
||||
if (CCallingConventionRequiresIntsAsLongs &&
|
||||
// See StubRoutines::select_fill_function for types. FLOAT has been converted to INT.
|
||||
(t == T_FLOAT || t == T_INT || is_subword_type(t))) {
|
||||
store_value = new ConvI2LNode(store_value);
|
||||
_igvn.register_new_node_with_optimizer(store_value);
|
||||
}
|
||||
|
||||
Node* mem_phi = store->in(MemNode::Memory);
|
||||
Node* result_ctrl;
|
||||
Node* result_mem;
|
||||
@ -2957,9 +2950,6 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
|
||||
uint cnt = 0;
|
||||
call->init_req(TypeFunc::Parms + cnt++, from);
|
||||
call->init_req(TypeFunc::Parms + cnt++, store_value);
|
||||
if (CCallingConventionRequiresIntsAsLongs) {
|
||||
call->init_req(TypeFunc::Parms + cnt++, C->top());
|
||||
}
|
||||
#ifdef _LP64
|
||||
len = new ConvI2LNode(len);
|
||||
_igvn.register_new_node_with_optimizer(len);
|
||||
|
||||
@ -779,18 +779,10 @@ const TypeFunc* OptoRuntime::generic_arraycopy_Type() {
|
||||
const TypeFunc* OptoRuntime::array_fill_Type() {
|
||||
const Type** fields;
|
||||
int argp = TypeFunc::Parms;
|
||||
if (CCallingConventionRequiresIntsAsLongs) {
|
||||
// create input type (domain): pointer, int, size_t
|
||||
fields = TypeTuple::fields(3 LP64_ONLY( + 2));
|
||||
fields[argp++] = TypePtr::NOTNULL;
|
||||
fields[argp++] = TypeLong::LONG;
|
||||
fields[argp++] = Type::HALF;
|
||||
} else {
|
||||
// create input type (domain): pointer, int, size_t
|
||||
fields = TypeTuple::fields(3 LP64_ONLY( + 1));
|
||||
fields[argp++] = TypePtr::NOTNULL;
|
||||
fields[argp++] = TypeInt::INT;
|
||||
}
|
||||
fields = TypeTuple::fields(3 LP64_ONLY( + 1));
|
||||
fields[argp++] = TypePtr::NOTNULL;
|
||||
fields[argp++] = TypeInt::INT;
|
||||
fields[argp++] = TypeX_X; // size in whatevers (size_t)
|
||||
LP64_ONLY(fields[argp++] = Type::HALF); // other half of long length
|
||||
const TypeTuple *domain = TypeTuple::make(argp, fields);
|
||||
|
||||
@ -2616,71 +2616,6 @@ JRT_ENTRY_NO_ASYNC(void, SharedRuntime::block_for_jni_critical(JavaThread* threa
|
||||
GC_locker::unlock_critical(thread);
|
||||
JRT_END
|
||||
|
||||
int SharedRuntime::convert_ints_to_longints_argcnt(int in_args_count, BasicType* in_sig_bt) {
|
||||
int argcnt = in_args_count;
|
||||
if (CCallingConventionRequiresIntsAsLongs) {
|
||||
for (int in = 0; in < in_args_count; in++) {
|
||||
BasicType bt = in_sig_bt[in];
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
case T_CHAR:
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT:
|
||||
argcnt++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert(0, "This should not be needed on this platform");
|
||||
}
|
||||
|
||||
return argcnt;
|
||||
}
|
||||
|
||||
void SharedRuntime::convert_ints_to_longints(int i2l_argcnt, int& in_args_count,
|
||||
BasicType*& in_sig_bt, VMRegPair*& in_regs) {
|
||||
if (CCallingConventionRequiresIntsAsLongs) {
|
||||
VMRegPair *new_in_regs = NEW_RESOURCE_ARRAY(VMRegPair, i2l_argcnt);
|
||||
BasicType *new_in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, i2l_argcnt);
|
||||
|
||||
int argcnt = 0;
|
||||
for (int in = 0; in < in_args_count; in++, argcnt++) {
|
||||
BasicType bt = in_sig_bt[in];
|
||||
VMRegPair reg = in_regs[in];
|
||||
switch (bt) {
|
||||
case T_BOOLEAN:
|
||||
case T_CHAR:
|
||||
case T_BYTE:
|
||||
case T_SHORT:
|
||||
case T_INT:
|
||||
// Convert (bt) to (T_LONG,bt).
|
||||
new_in_sig_bt[argcnt] = T_LONG;
|
||||
new_in_sig_bt[argcnt+1] = bt;
|
||||
assert(reg.first()->is_valid() && !reg.second()->is_valid(), "");
|
||||
new_in_regs[argcnt].set2(reg.first());
|
||||
new_in_regs[argcnt+1].set_bad();
|
||||
argcnt++;
|
||||
break;
|
||||
default:
|
||||
// No conversion needed.
|
||||
new_in_sig_bt[argcnt] = bt;
|
||||
new_in_regs[argcnt] = reg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(argcnt == i2l_argcnt, "must match");
|
||||
|
||||
in_regs = new_in_regs;
|
||||
in_sig_bt = new_in_sig_bt;
|
||||
in_args_count = i2l_argcnt;
|
||||
} else {
|
||||
assert(0, "This should not be needed on this platform");
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Java-Java calling convention
|
||||
// (what you use when Java calls Java)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user