57 // the wrapper, which results in the odd mild inefficiency but is a |
57 // the wrapper, which results in the odd mild inefficiency but is a |
58 // damn sight easier to code. |
58 // damn sight easier to code. |
59 OopMap *oopmap = new OopMap( |
59 OopMap *oopmap = new OopMap( |
60 SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()), |
60 SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()), |
61 SharkStack::oopmap_slot_munge(arg_size())); |
61 SharkStack::oopmap_slot_munge(arg_size())); |
62 oopmap->set_oop(SharkStack::slot2reg(stack()->method_slot_offset())); |
|
63 |
62 |
64 // Set up the oop_tmp slot if required: |
63 // Set up the oop_tmp slot if required: |
65 // - For static methods we use it to handlize the class argument |
64 // - For static methods we use it to handlize the class argument |
66 // for the call, and to protect the same during slow path locks |
65 // for the call, and to protect the same during slow path locks |
67 // (if synchronized). |
66 // (if synchronized). |
81 Unimplemented(); |
80 Unimplemented(); |
82 _lock_slot_offset = 23; |
81 _lock_slot_offset = 23; |
83 } |
82 } |
84 |
83 |
85 // Start building the argument list |
84 // Start building the argument list |
86 std::vector<const Type*> param_types; |
85 std::vector<Type*> param_types; |
87 std::vector<Value*> param_values; |
86 std::vector<Value*> param_values; |
88 const PointerType *box_type = PointerType::getUnqual(SharkType::oop_type()); |
87 PointerType *box_type = PointerType::getUnqual(SharkType::oop_type()); |
89 |
88 |
90 // First argument is the JNIEnv |
89 // First argument is the JNIEnv |
91 param_types.push_back(SharkType::jniEnv_type()); |
90 param_types.push_back(SharkType::jniEnv_type()); |
92 param_values.push_back( |
91 param_values.push_back( |
93 builder()->CreateAddressOfStructEntry( |
92 builder()->CreateAddressOfStructEntry( |
147 |
146 |
148 builder()->SetInsertPoint(not_null); |
147 builder()->SetInsertPoint(not_null); |
149 builder()->CreateBr(merge); |
148 builder()->CreateBr(merge); |
150 |
149 |
151 builder()->SetInsertPoint(merge); |
150 builder()->SetInsertPoint(merge); |
152 phi = builder()->CreatePHI(box_type, "boxed_object"); |
151 phi = builder()->CreatePHI(box_type, 0, "boxed_object"); |
153 phi->addIncoming(ConstantPointerNull::get(box_type), null); |
152 phi->addIncoming(ConstantPointerNull::get(box_type), null); |
154 phi->addIncoming(box, not_null); |
153 phi->addIncoming(box, not_null); |
155 box = phi; |
154 box = phi; |
156 |
155 |
157 param_types.push_back(box_type); |
156 param_types.push_back(box_type); |
199 // Change the thread state to _thread_in_native |
198 // Change the thread state to _thread_in_native |
200 CreateSetThreadState(_thread_in_native); |
199 CreateSetThreadState(_thread_in_native); |
201 |
200 |
202 // Make the call |
201 // Make the call |
203 BasicType result_type = target()->result_type(); |
202 BasicType result_type = target()->result_type(); |
204 const Type* return_type; |
203 Type* return_type; |
205 if (result_type == T_VOID) |
204 if (result_type == T_VOID) |
206 return_type = SharkType::void_type(); |
205 return_type = SharkType::void_type(); |
207 else if (is_returning_oop()) |
206 else if (is_returning_oop()) |
208 return_type = box_type; |
207 return_type = box_type; |
209 else |
208 else |
211 Value* native_function = builder()->CreateIntToPtr( |
210 Value* native_function = builder()->CreateIntToPtr( |
212 LLVMValue::intptr_constant((intptr_t) target()->native_function()), |
211 LLVMValue::intptr_constant((intptr_t) target()->native_function()), |
213 PointerType::getUnqual( |
212 PointerType::getUnqual( |
214 FunctionType::get(return_type, param_types, false))); |
213 FunctionType::get(return_type, param_types, false))); |
215 Value *result = builder()->CreateCall( |
214 Value *result = builder()->CreateCall( |
216 native_function, param_values.begin(), param_values.end()); |
215 native_function, llvm::makeArrayRef(param_values)); |
217 |
216 |
218 // Start the transition back to _thread_in_Java |
217 // Start the transition back to _thread_in_Java |
219 CreateSetThreadState(_thread_in_native_trans); |
218 CreateSetThreadState(_thread_in_native_trans); |
220 |
219 |
221 // Make sure new state is visible in the GC thread |
220 // Make sure new state is visible in the GC thread |
222 if (os::is_MP()) { |
221 if (os::is_MP()) { |
223 if (UseMembar) |
222 if (UseMembar) |
224 builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD); |
223 builder()->CreateFence(llvm::SequentiallyConsistent, llvm::CrossThread); |
225 else |
224 else |
226 CreateWriteMemorySerializePage(); |
225 CreateWriteMemorySerializePage(); |
227 } |
226 } |
228 |
227 |
229 // Handle safepoint operations, pending suspend requests, |
228 // Handle safepoint operations, pending suspend requests, |
303 builder()->SetInsertPoint(not_null); |
302 builder()->SetInsertPoint(not_null); |
304 Value *unboxed_result = builder()->CreateLoad(result); |
303 Value *unboxed_result = builder()->CreateLoad(result); |
305 builder()->CreateBr(merge); |
304 builder()->CreateBr(merge); |
306 |
305 |
307 builder()->SetInsertPoint(merge); |
306 builder()->SetInsertPoint(merge); |
308 PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "result"); |
307 PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "result"); |
309 phi->addIncoming(LLVMValue::null(), null); |
308 phi->addIncoming(LLVMValue::null(), null); |
310 phi->addIncoming(unboxed_result, not_null); |
309 phi->addIncoming(unboxed_result, not_null); |
311 result = phi; |
310 result = phi; |
312 } |
311 } |
313 |
312 |