1 /*
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
101 // Always do this after the other "last_Java_frame" fields are set since
102 // as soon as last_Java_sp != NULL the has_last_Java_frame is true and
103 // users will look at the other fields.
104 //
105 Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
106 Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
107 store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias, MemNode::unordered);
108
109 // Set _thread_in_native
110 // The order of stores into TLS is critical! Setting _thread_in_native MUST
111 // be last, because a GC is allowed at any time after setting it and the GC
112 // will require last_Java_pc and last_Java_sp.
113
114 //-----------------------------
115 // Compute signature for C call. Varies from the Java signature!
116 const Type **fields = TypeTuple::fields(2*parm_cnt+2);
117 uint cnt = TypeFunc::Parms;
118 // The C routines gets the base of thread-local storage passed in as an
119 // extra argument. Not all calls need it, but its cheap to add here.
120 for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) {
121 // Convert ints to longs if required.
122 if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(pcnt)->isa_int()) {
123 fields[cnt++] = TypeLong::LONG;
124 fields[cnt] = Type::HALF; // must add an additional half for a long
125 } else {
126 fields[cnt] = jdomain->field_at(pcnt);
127 }
128 }
129
130 fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
131 // Also pass in the caller's PC, if asked for.
132 if( return_pc )
133 fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC
134
135 const TypeTuple* domain = TypeTuple::make(cnt,fields);
136 // The C routine we are about to call cannot return an oop; it can block on
137 // exit and a GC will trash the oop while it sits in C-land. Instead, we
138 // return the oop through TLS for runtime calls.
139 // Also, C routines returning integer subword values leave the high
140 // order bits dirty; these must be cleaned up by explicit sign extension.
141 const Type* retval = (jrange->cnt() == TypeFunc::Parms) ? Type::TOP : jrange->field_at(TypeFunc::Parms);
142 // Make a private copy of jrange->fields();
143 const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms);
144 // Fixup oop returns
145 int retval_ptr = retval->isa_oop_ptr();
146 if( retval_ptr ) {
147 assert( pass_tls, "Oop must be returned thru TLS" );
148 // Fancy-jumps return address; others return void
149 rfields[TypeFunc::Parms] = is_fancy_jump ? TypeRawPtr::BOTTOM : Type::TOP;
150
151 } else if( retval->isa_int() ) { // Returning any integer subtype?
152 // "Fatten" byte, char & short return types to 'int' to show that
153 // the native C code can return values with junk high order bits.
154 // We'll sign-extend it below later.
155 rfields[TypeFunc::Parms] = TypeInt::INT; // It's "dirty" and needs sign-ext
156
157 } else if( jrange->cnt() >= TypeFunc::Parms+1 ) { // Else copy other types
158 rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms);
159 if( jrange->cnt() == TypeFunc::Parms+2 )
160 rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1);
161 }
162 const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields);
163
164 // Final C signature
165 const TypeFunc *c_sig = TypeFunc::make(domain,range);
166
167 //-----------------------------
168 // Make the call node
169 CallRuntimeNode *call = new CallRuntimeNode(c_sig, C_function, name, TypePtr::BOTTOM);
170 //-----------------------------
171
172 // Fix-up the debug info for the call
173 call->set_jvms( new (C) JVMState(0) );
174 call->jvms()->set_bci(0);
175 call->jvms()->set_offsets(cnt);
176
177 // Set fixed predefined input arguments
178 cnt = 0;
179 for (i = 0; i < TypeFunc::Parms; i++)
180 call->init_req(cnt++, map()->in(i));
181 // A little too aggressive on the parm copy; return address is not an input
182 call->set_req(TypeFunc::ReturnAdr, top());
183 for (; i < parm_cnt; i++) { // Regular input arguments
184 // Convert ints to longs if required.
185 if (CCallingConventionRequiresIntsAsLongs && jdomain->field_at(i)->isa_int()) {
186 Node* int_as_long = _gvn.transform(new ConvI2LNode(map()->in(i)));
187 call->init_req(cnt++, int_as_long); // long
188 call->init_req(cnt++, top()); // half
189 } else {
190 call->init_req(cnt++, map()->in(i));
191 }
192 }
193
194 call->init_req( cnt++, thread );
195 if( return_pc ) // Return PC, if asked for
196 call->init_req( cnt++, returnadr() );
197 _gvn.transform_no_reclaim(call);
198
199
200 //-----------------------------
201 // Now set up the return results
202 set_control( _gvn.transform( new ProjNode(call,TypeFunc::Control)) );
203 set_i_o( _gvn.transform( new ProjNode(call,TypeFunc::I_O )) );
204 set_all_memory_call(call);
205 if (range->cnt() > TypeFunc::Parms) {
206 Node* retnode = _gvn.transform( new ProjNode(call,TypeFunc::Parms) );
207 // C-land is allowed to return sub-word values. Convert to integer type.
208 assert( retval != Type::TOP, "" );
209 if (retval == TypeInt::BOOL) {
210 retnode = _gvn.transform( new AndINode(retnode, intcon(0xFF)) );
211 } else if (retval == TypeInt::CHAR) {
212 retnode = _gvn.transform( new AndINode(retnode, intcon(0xFFFF)) );
|
1 /*
2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
101 // Always do this after the other "last_Java_frame" fields are set since
102 // as soon as last_Java_sp != NULL the has_last_Java_frame is true and
103 // users will look at the other fields.
104 //
105 Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
106 Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
107 store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias, MemNode::unordered);
108
109 // Set _thread_in_native
110 // The order of stores into TLS is critical! Setting _thread_in_native MUST
111 // be last, because a GC is allowed at any time after setting it and the GC
112 // will require last_Java_pc and last_Java_sp.
113
114 //-----------------------------
115 // Compute signature for C call. Varies from the Java signature!
116 const Type **fields = TypeTuple::fields(2*parm_cnt+2);
117 uint cnt = TypeFunc::Parms;
118 // The C routines gets the base of thread-local storage passed in as an
119 // extra argument. Not all calls need it, but its cheap to add here.
120 for (uint pcnt = cnt; pcnt < parm_cnt; pcnt++, cnt++) {
121 fields[cnt] = jdomain->field_at(pcnt);
122 }
123
124 fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
125 // Also pass in the caller's PC, if asked for.
126 if (return_pc) {
127 fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC
128 }
129
130 const TypeTuple* domain = TypeTuple::make(cnt,fields);
131 // The C routine we are about to call cannot return an oop; it can block on
132 // exit and a GC will trash the oop while it sits in C-land. Instead, we
133 // return the oop through TLS for runtime calls.
134 // Also, C routines returning integer subword values leave the high
135 // order bits dirty; these must be cleaned up by explicit sign extension.
136 const Type* retval = (jrange->cnt() == TypeFunc::Parms) ? Type::TOP : jrange->field_at(TypeFunc::Parms);
137 // Make a private copy of jrange->fields();
138 const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms);
139 // Fixup oop returns
140 int retval_ptr = retval->isa_oop_ptr();
141 if (retval_ptr) {
142 assert( pass_tls, "Oop must be returned thru TLS" );
143 // Fancy-jumps return address; others return void
144 rfields[TypeFunc::Parms] = is_fancy_jump ? TypeRawPtr::BOTTOM : Type::TOP;
145
146 } else if (retval->isa_int()) { // Returning any integer subtype?
147 // "Fatten" byte, char & short return types to 'int' to show that
148 // the native C code can return values with junk high order bits.
149 // We'll sign-extend it below later.
150 rfields[TypeFunc::Parms] = TypeInt::INT; // It's "dirty" and needs sign-ext
151
152 } else if (jrange->cnt() >= TypeFunc::Parms+1) { // Else copy other types
153 rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms);
154 if (jrange->cnt() == TypeFunc::Parms+2) {
155 rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1);
156 }
157 }
158 const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields);
159
160 // Final C signature
161 const TypeFunc *c_sig = TypeFunc::make(domain,range);
162
163 //-----------------------------
164 // Make the call node
165 CallRuntimeNode *call = new CallRuntimeNode(c_sig, C_function, name, TypePtr::BOTTOM);
166 //-----------------------------
167
168 // Fix-up the debug info for the call
169 call->set_jvms( new (C) JVMState(0) );
170 call->jvms()->set_bci(0);
171 call->jvms()->set_offsets(cnt);
172
173 // Set fixed predefined input arguments
174 cnt = 0;
175 for (i = 0; i < TypeFunc::Parms; i++)
176 call->init_req(cnt++, map()->in(i));
177 // A little too aggressive on the parm copy; return address is not an input
178 call->set_req(TypeFunc::ReturnAdr, top());
179 for (; i < parm_cnt; i++) { // Regular input arguments
180 call->init_req(cnt++, map()->in(i));
181 }
182
183 call->init_req( cnt++, thread );
184 if( return_pc ) // Return PC, if asked for
185 call->init_req( cnt++, returnadr() );
186 _gvn.transform_no_reclaim(call);
187
188
189 //-----------------------------
190 // Now set up the return results
191 set_control( _gvn.transform( new ProjNode(call,TypeFunc::Control)) );
192 set_i_o( _gvn.transform( new ProjNode(call,TypeFunc::I_O )) );
193 set_all_memory_call(call);
194 if (range->cnt() > TypeFunc::Parms) {
195 Node* retnode = _gvn.transform( new ProjNode(call,TypeFunc::Parms) );
196 // C-land is allowed to return sub-word values. Convert to integer type.
197 assert( retval != Type::TOP, "" );
198 if (retval == TypeInt::BOOL) {
199 retnode = _gvn.transform( new AndINode(retnode, intcon(0xFF)) );
200 } else if (retval == TypeInt::CHAR) {
201 retnode = _gvn.transform( new AndINode(retnode, intcon(0xFFFF)) );
|