< prev index next >

src/share/vm/opto/generateOptoStub.cpp

Print this page
rev 8611 : 8086069: Adapt runtime calls to recent intrinsics to pass ints as long
Summary: Remove CCallingConventionRequiresIntsAsLongs from shared code and push functionality to native wrapper. Less optimal but more flexible.

*** 1,7 **** /* ! * Copyright (c) 1999, 2013, 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. --- 1,7 ---- /* ! * 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 116,138 **** const Type **fields = TypeTuple::fields(2*parm_cnt+2); uint cnt = TypeFunc::Parms; // 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++] = TypeRawPtr::BOTTOM; // Thread-local storage // Also pass in the caller's PC, if asked for. ! 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 // exit and a GC will trash the oop while it sits in C-land. Instead, we // return the oop through TLS for runtime calls. --- 116,133 ---- const Type **fields = TypeTuple::fields(2*parm_cnt+2); uint cnt = TypeFunc::Parms; // 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++) { 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) { 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 // exit and a GC will trash the oop while it sits in C-land. Instead, we // return the oop through TLS for runtime calls.
*** 141,166 **** const Type* retval = (jrange->cnt() == TypeFunc::Parms) ? Type::TOP : jrange->field_at(TypeFunc::Parms); // Make a private copy of jrange->fields(); const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms); // Fixup oop returns int retval_ptr = retval->isa_oop_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? // "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 rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms); ! if( jrange->cnt() == TypeFunc::Parms+2 ) rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1); } const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields); // Final C signature const TypeFunc *c_sig = TypeFunc::make(domain,range); --- 136,162 ---- const Type* retval = (jrange->cnt() == TypeFunc::Parms) ? Type::TOP : jrange->field_at(TypeFunc::Parms); // Make a private copy of jrange->fields(); const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms); // Fixup oop returns int retval_ptr = retval->isa_oop_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? // "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 rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms); ! if (jrange->cnt() == TypeFunc::Parms+2) { rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1); } + } const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields); // Final C signature const TypeFunc *c_sig = TypeFunc::make(domain,range);
*** 179,197 **** for (i = 0; i < TypeFunc::Parms; i++) call->init_req(cnt++, map()->in(i)); // 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++, thread ); if( return_pc ) // Return PC, if asked for call->init_req( cnt++, returnadr() ); _gvn.transform_no_reclaim(call); --- 175,186 ----
< prev index next >