annotate src/share/vm/opto/generateOptoStub.cpp @ 17716:cdb71841f4bc

6498581: ThreadInterruptTest3 produces wrong output on Windows Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set. Reviewed-by: acorn, kvn Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author minqi
date Wed, 26 Feb 2014 15:20:41 -0800
parents 55fb97c4c58d
children abec000618bf
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
17467
55fb97c4c58d 8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents: 12158
diff changeset
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #include "opto/addnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27 #include "opto/callnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "opto/cfgnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "opto/compile.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "opto/connode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "opto/locknode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "opto/memnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33 #include "opto/mulnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
34 #include "opto/node.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
35 #include "opto/parse.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
36 #include "opto/phaseX.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
37 #include "opto/rootnode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
38 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
39 #include "opto/type.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 //--------------------gen_stub-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
42 void GraphKit::gen_stub(address C_function,
a61af66fc99e Initial load
duke
parents:
diff changeset
43 const char *name,
a61af66fc99e Initial load
duke
parents:
diff changeset
44 int is_fancy_jump,
a61af66fc99e Initial load
duke
parents:
diff changeset
45 bool pass_tls,
a61af66fc99e Initial load
duke
parents:
diff changeset
46 bool return_pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 const TypeTuple *jdomain = C->tf()->domain();
a61af66fc99e Initial load
duke
parents:
diff changeset
50 const TypeTuple *jrange = C->tf()->range();
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 // The procedure start
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
53 StartNode* start = new (C) StartNode(root(), jdomain);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
54 _gvn.set_type_bottom(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // Make a map, with JVM state
a61af66fc99e Initial load
duke
parents:
diff changeset
57 uint parm_cnt = jdomain->cnt();
a61af66fc99e Initial load
duke
parents:
diff changeset
58 uint max_map = MAX2(2*parm_cnt+1, jrange->cnt());
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // %%% SynchronizationEntryBCI is redundant; use InvocationEntryBci in interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
60 assert(SynchronizationEntryBCI == InvocationEntryBci, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
61 JVMState* jvms = new (C) JVMState(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
62 jvms->set_bci(InvocationEntryBci);
a61af66fc99e Initial load
duke
parents:
diff changeset
63 jvms->set_monoff(max_map);
12158
766fac3395d6 8012972: Incremental Inlining should support scalar replaced object in debug info
kvn
parents: 7994
diff changeset
64 jvms->set_scloff(max_map);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
65 jvms->set_endoff(max_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
67 SafePointNode *map = new (C) SafePointNode( max_map, jvms );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
68 jvms->set_map(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
69 set_jvms(jvms);
a61af66fc99e Initial load
duke
parents:
diff changeset
70 assert(map == this->map(), "kit.map is set");
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // Make up the parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
74 uint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 for( i = 0; i < parm_cnt; i++ )
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
76 map()->init_req(i, _gvn.transform(new (C) ParmNode(start, i)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
77 for( ; i<map()->req(); i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
78 map()->init_req(i, top()); // For nicer debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 // GraphKit requires memory to be a MergeMemNode:
a61af66fc99e Initial load
duke
parents:
diff changeset
81 set_all_memory(map()->memory());
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // Get base of thread-local storage area
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
84 Node* thread = _gvn.transform( new (C) ThreadLocalNode() );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 const int NoAlias = Compile::AliasIdxBot;
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 Node* adr_last_Java_pc = basic_plus_adr(top(),
a61af66fc99e Initial load
duke
parents:
diff changeset
89 thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
90 in_bytes(JavaThread::frame_anchor_offset()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
91 in_bytes(JavaFrameAnchor::last_Java_pc_offset()));
7994
9fae07c31641 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 6842
diff changeset
92 #if defined(SPARC)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
93 Node* adr_flags = basic_plus_adr(top(),
a61af66fc99e Initial load
duke
parents:
diff changeset
94 thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
95 in_bytes(JavaThread::frame_anchor_offset()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
96 in_bytes(JavaFrameAnchor::flags_offset()));
7994
9fae07c31641 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 6842
diff changeset
97 #endif /* defined(SPARC) */
0
a61af66fc99e Initial load
duke
parents:
diff changeset
98
a61af66fc99e Initial load
duke
parents:
diff changeset
99
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // Drop in the last_Java_sp. last_Java_fp is not touched.
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // Always do this after the other "last_Java_frame" fields are set since
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // as soon as last_Java_sp != NULL the has_last_Java_frame is true and
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // users will look at the other fields.
a61af66fc99e Initial load
duke
parents:
diff changeset
104 //
a61af66fc99e Initial load
duke
parents:
diff changeset
105 Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
106 Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
a61af66fc99e Initial load
duke
parents:
diff changeset
107 store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias);
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 // Set _thread_in_native
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // The order of stores into TLS is critical! Setting _thread_in_native MUST
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // be last, because a GC is allowed at any time after setting it and the GC
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // will require last_Java_pc and last_Java_sp.
a61af66fc99e Initial load
duke
parents:
diff changeset
113 Node* adr_state = basic_plus_adr(top(), thread, in_bytes(JavaThread::thread_state_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 //-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Compute signature for C call. Varies from the Java signature!
a61af66fc99e Initial load
duke
parents:
diff changeset
117 const Type **fields = TypeTuple::fields(2*parm_cnt+2);
a61af66fc99e Initial load
duke
parents:
diff changeset
118 uint cnt = TypeFunc::Parms;
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // The C routines gets the base of thread-local storage passed in as an
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // extra argument. Not all calls need it, but its cheap to add here.
a61af66fc99e Initial load
duke
parents:
diff changeset
121 for( ; cnt<parm_cnt; cnt++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
122 fields[cnt] = jdomain->field_at(cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
123 fields[cnt++] = TypeRawPtr::BOTTOM; // Thread-local storage
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // Also pass in the caller's PC, if asked for.
a61af66fc99e Initial load
duke
parents:
diff changeset
125 if( return_pc )
a61af66fc99e Initial load
duke
parents:
diff changeset
126 fields[cnt++] = TypeRawPtr::BOTTOM; // Return PC
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 const TypeTuple* domain = TypeTuple::make(cnt,fields);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // The C routine we are about to call cannot return an oop; it can block on
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // exit and a GC will trash the oop while it sits in C-land. Instead, we
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // return the oop through TLS for runtime calls.
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // Also, C routines returning integer subword values leave the high
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // order bits dirty; these must be cleaned up by explicit sign extension.
a61af66fc99e Initial load
duke
parents:
diff changeset
134 const Type* retval = (jrange->cnt() == TypeFunc::Parms) ? Type::TOP : jrange->field_at(TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // Make a private copy of jrange->fields();
a61af66fc99e Initial load
duke
parents:
diff changeset
136 const Type **rfields = TypeTuple::fields(jrange->cnt() - TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // Fixup oop returns
a61af66fc99e Initial load
duke
parents:
diff changeset
138 int retval_ptr = retval->isa_oop_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
139 if( retval_ptr ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 assert( pass_tls, "Oop must be returned thru TLS" );
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Fancy-jumps return address; others return void
a61af66fc99e Initial load
duke
parents:
diff changeset
142 rfields[TypeFunc::Parms] = is_fancy_jump ? TypeRawPtr::BOTTOM : Type::TOP;
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 } else if( retval->isa_int() ) { // Returning any integer subtype?
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // "Fatten" byte, char & short return types to 'int' to show that
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // the native C code can return values with junk high order bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // We'll sign-extend it below later.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 rfields[TypeFunc::Parms] = TypeInt::INT; // It's "dirty" and needs sign-ext
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 } else if( jrange->cnt() >= TypeFunc::Parms+1 ) { // Else copy other types
a61af66fc99e Initial load
duke
parents:
diff changeset
151 rfields[TypeFunc::Parms] = jrange->field_at(TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 if( jrange->cnt() == TypeFunc::Parms+2 )
a61af66fc99e Initial load
duke
parents:
diff changeset
153 rfields[TypeFunc::Parms+1] = jrange->field_at(TypeFunc::Parms+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 const TypeTuple* range = TypeTuple::make(jrange->cnt(),rfields);
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // Final C signature
a61af66fc99e Initial load
duke
parents:
diff changeset
158 const TypeFunc *c_sig = TypeFunc::make(domain,range);
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 //-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
161 // Make the call node
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
162 CallRuntimeNode *call = new (C)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
163 CallRuntimeNode(c_sig, C_function, name, TypePtr::BOTTOM);
a61af66fc99e Initial load
duke
parents:
diff changeset
164 //-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 // Fix-up the debug info for the call
a61af66fc99e Initial load
duke
parents:
diff changeset
167 call->set_jvms( new (C) JVMState(0) );
a61af66fc99e Initial load
duke
parents:
diff changeset
168 call->jvms()->set_bci(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
169 call->jvms()->set_offsets(cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Set fixed predefined input arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
172 cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 for( i=0; i<TypeFunc::Parms; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
174 call->init_req( cnt++, map()->in(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
175 // A little too aggressive on the parm copy; return address is not an input
a61af66fc99e Initial load
duke
parents:
diff changeset
176 call->set_req(TypeFunc::ReturnAdr, top());
a61af66fc99e Initial load
duke
parents:
diff changeset
177 for( ; i<parm_cnt; i++ ) // Regular input arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
178 call->init_req( cnt++, map()->in(i) );
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 call->init_req( cnt++, thread );
a61af66fc99e Initial load
duke
parents:
diff changeset
181 if( return_pc ) // Return PC, if asked for
a61af66fc99e Initial load
duke
parents:
diff changeset
182 call->init_req( cnt++, returnadr() );
a61af66fc99e Initial load
duke
parents:
diff changeset
183 _gvn.transform_no_reclaim(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 //-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // Now set up the return results
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
188 set_control( _gvn.transform( new (C) ProjNode(call,TypeFunc::Control)) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
189 set_i_o( _gvn.transform( new (C) ProjNode(call,TypeFunc::I_O )) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
190 set_all_memory_call(call);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 if (range->cnt() > TypeFunc::Parms) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
192 Node* retnode = _gvn.transform( new (C) ProjNode(call,TypeFunc::Parms) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
193 // C-land is allowed to return sub-word values. Convert to integer type.
a61af66fc99e Initial load
duke
parents:
diff changeset
194 assert( retval != Type::TOP, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
195 if (retval == TypeInt::BOOL) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
196 retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFF)) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
197 } else if (retval == TypeInt::CHAR) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
198 retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 } else if (retval == TypeInt::BYTE) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
200 retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
201 retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
202 } else if (retval == TypeInt::SHORT) {
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
203 retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
204 retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206 map()->set_req( TypeFunc::Parms, retnode );
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 //-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 // Clear last_Java_sp
a61af66fc99e Initial load
duke
parents:
diff changeset
212 store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // Clear last_Java_pc and (optionally)_flags
a61af66fc99e Initial load
duke
parents:
diff changeset
214 store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias);
7994
9fae07c31641 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 6842
diff changeset
215 #if defined(SPARC)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
216 store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias);
7994
9fae07c31641 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 6842
diff changeset
217 #endif /* defined(SPARC) */
0
a61af66fc99e Initial load
duke
parents:
diff changeset
218 #ifdef IA64
a61af66fc99e Initial load
duke
parents:
diff changeset
219 Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
220 if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
a61af66fc99e Initial load
duke
parents:
diff changeset
221 store_to_memory(NULL, adr_last_Java_fp, null(), T_ADDRESS, NoAlias);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 // For is-fancy-jump, the C-return value is also the branch target
a61af66fc99e Initial load
duke
parents:
diff changeset
225 Node* target = map()->in(TypeFunc::Parms);
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Runtime call returning oop in TLS? Fetch it out
a61af66fc99e Initial load
duke
parents:
diff changeset
227 if( pass_tls ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 Node* adr = basic_plus_adr(top(), thread, in_bytes(JavaThread::vm_result_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
229 Node* vm_result = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 map()->set_req(TypeFunc::Parms, vm_result); // vm_result passed as result
a61af66fc99e Initial load
duke
parents:
diff changeset
231 // clear thread-local-storage(tls)
a61af66fc99e Initial load
duke
parents:
diff changeset
232 store_to_memory(NULL, adr, null(), T_ADDRESS, NoAlias);
a61af66fc99e Initial load
duke
parents:
diff changeset
233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 //-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // check exception
a61af66fc99e Initial load
duke
parents:
diff changeset
237 Node* adr = basic_plus_adr(top(), thread, in_bytes(Thread::pending_exception_offset()));
a61af66fc99e Initial load
duke
parents:
diff changeset
238 Node* pending = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 Node* exit_memory = reset_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
241
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
242 Node* cmp = _gvn.transform( new (C) CmpPNode(pending, null()) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
243 Node* bo = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
244 IfNode *iff = create_and_map_if(control(), bo, PROB_MIN, COUNT_UNKNOWN);
a61af66fc99e Initial load
duke
parents:
diff changeset
245
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
246 Node* if_null = _gvn.transform( new (C) IfFalseNode(iff) );
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
247 Node* if_not_null = _gvn.transform( new (C) IfTrueNode(iff) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
a61af66fc99e Initial load
duke
parents:
diff changeset
250 Node *exc_target = makecon(TypeRawPtr::make( StubRoutines::forward_exception_entry() ));
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
251 Node *to_exc = new (C) TailCallNode(if_not_null,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
252 i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
253 exit_memory,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
254 frameptr(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
255 returnadr(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
256 exc_target, null());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
257 root()->add_req(_gvn.transform(to_exc)); // bind to root to keep live
a61af66fc99e Initial load
duke
parents:
diff changeset
258 C->init_start(start);
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 //-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // If this is a normal subroutine return, issue the return and be done.
a61af66fc99e Initial load
duke
parents:
diff changeset
262 Node *ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 switch( is_fancy_jump ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 case 0: // Make a return instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
265 // Return to caller, free any space for return address
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
266 ret = new (C) ReturnNode(TypeFunc::Parms, if_null,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
267 i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
268 exit_memory,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
269 frameptr(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
270 returnadr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (C->tf()->range()->cnt() > TypeFunc::Parms)
a61af66fc99e Initial load
duke
parents:
diff changeset
272 ret->add_req( map()->in(TypeFunc::Parms) );
a61af66fc99e Initial load
duke
parents:
diff changeset
273 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 case 1: // This is a fancy tail-call jump. Jump to computed address.
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // Jump to new callee; leave old return address alone.
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
276 ret = new (C) TailCallNode(if_null,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
277 i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
278 exit_memory,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
279 frameptr(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
280 returnadr(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
281 target, map()->in(TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
282 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 case 2: // Pop return address & jump
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // Throw away old return address; jump to new computed address
a61af66fc99e Initial load
duke
parents:
diff changeset
285 //assert(C_function == CAST_FROM_FN_PTR(address, OptoRuntime::rethrow_C), "fancy_jump==2 only for rethrow");
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
286 ret = new (C) TailJumpNode(if_null,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
287 i_o(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
288 exit_memory,
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
289 frameptr(),
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 1972
diff changeset
290 target, map()->in(TypeFunc::Parms));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
291 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
293 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 root()->add_req(_gvn.transform(ret));
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }