1 /* 2 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2009, 2010 Red Hat, Inc. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "incls/_precompiled.incl" 27 #include "incls/_sharkNativeWrapper.cpp.incl" 28 29 using namespace llvm; 30 31 void SharkNativeWrapper::initialize(const char *name) { 32 // Create the function 33 _function = Function::Create( 34 SharkType::entry_point_type(), 35 GlobalVariable::InternalLinkage, 36 name); 37 38 // Get our arguments 39 Function::arg_iterator ai = function()->arg_begin(); 40 Argument *method = ai++; 41 method->setName("method"); 42 Argument *base_pc = ai++; 43 base_pc->setName("base_pc"); 44 code_buffer()->set_base_pc(base_pc); 45 Argument *thread = ai++; 46 thread->setName("thread"); 47 set_thread(thread); 48 49 // Create and push our stack frame 50 builder()->SetInsertPoint(CreateBlock()); 51 _stack = SharkStack::CreateBuildAndPushFrame(this, method); 52 NOT_PRODUCT(method = NULL); 53 54 // Create the oopmap. We use the one oopmap for every call site in 55 // the wrapper, which results in the odd mild inefficiency but is a 56 // damn sight easier to code. 57 OopMap *oopmap = new OopMap( 58 SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()), 59 SharkStack::oopmap_slot_munge(arg_size())); 60 oopmap->set_oop(SharkStack::slot2reg(stack()->method_slot_offset())); 61 62 // Set up the oop_tmp slot if required: 63 // - For static methods we use it to handlize the class argument 64 // for the call, and to protect the same during slow path locks 65 // (if synchronized). 66 // - For methods returning oops, we use it to protect the return 67 // value across safepoints or slow path unlocking. 68 if (is_static() || is_returning_oop()) { 69 _oop_tmp_slot = stack()->slot_addr( 70 stack()->oop_tmp_slot_offset(), 71 SharkType::oop_type(), 72 "oop_tmp_slot"); 73 74 oopmap->set_oop(SharkStack::slot2reg(stack()->oop_tmp_slot_offset())); 75 } 76 77 // Set up the monitor slot, for synchronized methods 78 if (is_synchronized()) { 79 Unimplemented(); 80 _lock_slot_offset = 23; 81 } 82 83 // Start building the argument list 84 std::vector<const Type*> param_types; 85 std::vector<Value*> param_values; 86 const PointerType *box_type = PointerType::getUnqual(SharkType::oop_type()); 87 88 // First argument is the JNIEnv 89 param_types.push_back(SharkType::jniEnv_type()); 90 param_values.push_back( 91 builder()->CreateAddressOfStructEntry( 92 thread, 93 JavaThread::jni_environment_offset(), 94 SharkType::jniEnv_type(), 95 "jni_environment")); 96 97 // For static methods, the second argument is the class 98 if (is_static()) { 99 builder()->CreateStore( 100 builder()->CreateInlineOop( 101 JNIHandles::make_local( 102 target()->method_holder()->klass_part()->java_mirror())), 103 oop_tmp_slot()); 104 105 param_types.push_back(box_type); 106 param_values.push_back(oop_tmp_slot()); 107 108 _receiver_slot_offset = stack()->oop_tmp_slot_offset(); 109 } 110 else if (is_returning_oop()) { 111 // The oop_tmp slot is registered in the oopmap, 112 // so we need to clear it. This is one of the 113 // mild inefficiencies I mentioned earlier. 114 builder()->CreateStore(LLVMValue::null(), oop_tmp_slot()); 115 } 116 117 // Parse the arguments 118 for (int i = 0; i < arg_size(); i++) { 119 int slot_offset = stack()->locals_slots_offset() + arg_size() - 1 - i; 120 int adjusted_offset = slot_offset; 121 BasicBlock *null, *not_null, *merge; 122 Value *box; 123 PHINode *phi; 124 125 switch (arg_type(i)) { 126 case T_VOID: 127 break; 128 129 case T_OBJECT: 130 case T_ARRAY: 131 null = CreateBlock("null"); 132 not_null = CreateBlock("not_null"); 133 merge = CreateBlock("merge"); 134 135 box = stack()->slot_addr(slot_offset, SharkType::oop_type()); 136 builder()->CreateCondBr( 137 builder()->CreateICmp( 138 ICmpInst::ICMP_EQ, 139 builder()->CreateLoad(box), 140 LLVMValue::null()), 141 null, not_null); 142 143 builder()->SetInsertPoint(null); 144 builder()->CreateBr(merge); 145 146 builder()->SetInsertPoint(not_null); 147 builder()->CreateBr(merge); 148 149 builder()->SetInsertPoint(merge); 150 phi = builder()->CreatePHI(box_type, "boxed_object"); 151 phi->addIncoming(ConstantPointerNull::get(box_type), null); 152 phi->addIncoming(box, not_null); 153 box = phi; 154 155 param_types.push_back(box_type); 156 param_values.push_back(box); 157 158 oopmap->set_oop(SharkStack::slot2reg(slot_offset)); 159 160 if (i == 0 && !is_static()) 161 _receiver_slot_offset = slot_offset; 162 163 break; 164 165 case T_LONG: 166 case T_DOUBLE: 167 adjusted_offset--; 168 // fall through 169 170 default: 171 const Type *param_type = SharkType::to_stackType(arg_type(i)); 172 173 param_types.push_back(param_type); 174 param_values.push_back( 175 builder()->CreateLoad(stack()->slot_addr(adjusted_offset, param_type))); 176 } 177 } 178 179 // The oopmap is now complete, and everything is written 180 // into the frame except the PC. 181 int pc_offset = code_buffer()->create_unique_offset(); 182 183 _oop_maps = new OopMapSet(); 184 oop_maps()->add_gc_map(pc_offset, oopmap); 185 186 builder()->CreateStore( 187 builder()->code_buffer_address(pc_offset), 188 stack()->slot_addr(stack()->pc_slot_offset())); 189 190 // Set up the Java frame anchor 191 stack()->CreateSetLastJavaFrame(); 192 193 // Lock if necessary 194 if (is_synchronized()) 195 Unimplemented(); 196 197 // Change the thread state to _thread_in_native 198 CreateSetThreadState(_thread_in_native); 199 200 // Make the call 201 BasicType result_type = target()->result_type(); 202 const Type* return_type; 203 if (result_type == T_VOID) 204 return_type = SharkType::void_type(); 205 else if (is_returning_oop()) 206 return_type = box_type; 207 else 208 return_type = SharkType::to_arrayType(result_type); 209 Value* native_function = builder()->CreateIntToPtr( 210 LLVMValue::intptr_constant((intptr_t) target()->native_function()), 211 PointerType::getUnqual( 212 FunctionType::get(return_type, param_types, false))); 213 Value *result = builder()->CreateCall( 214 native_function, param_values.begin(), param_values.end()); 215 216 // Start the transition back to _thread_in_Java 217 CreateSetThreadState(_thread_in_native_trans); 218 219 // Make sure new state is visible in the GC thread 220 if (os::is_MP()) { 221 if (UseMembar) 222 builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD); 223 else 224 CreateWriteMemorySerializePage(); 225 } 226 227 // Handle safepoint operations, pending suspend requests, 228 // and pending asynchronous exceptions. 229 BasicBlock *check_thread = CreateBlock("check_thread"); 230 BasicBlock *do_safepoint = CreateBlock("do_safepoint"); 231 BasicBlock *safepointed = CreateBlock("safepointed"); 232 233 Value *global_state = builder()->CreateLoad( 234 builder()->CreateIntToPtr( 235 LLVMValue::intptr_constant( 236 (intptr_t) SafepointSynchronize::address_of_state()), 237 PointerType::getUnqual(SharkType::jint_type())), 238 "global_state"); 239 240 builder()->CreateCondBr( 241 builder()->CreateICmpNE( 242 global_state, 243 LLVMValue::jint_constant(SafepointSynchronize::_not_synchronized)), 244 do_safepoint, check_thread); 245 246 builder()->SetInsertPoint(check_thread); 247 Value *thread_state = builder()->CreateValueOfStructEntry( 248 thread, 249 JavaThread::suspend_flags_offset(), 250 SharkType::jint_type(), 251 "thread_state"); 252 253 builder()->CreateCondBr( 254 builder()->CreateICmpNE( 255 thread_state, 256 LLVMValue::jint_constant(0)), 257 do_safepoint, safepointed); 258 259 builder()->SetInsertPoint(do_safepoint); 260 builder()->CreateCall( 261 builder()->check_special_condition_for_native_trans(), thread); 262 builder()->CreateBr(safepointed); 263 264 // Finally we can change the thread state to _thread_in_Java 265 builder()->SetInsertPoint(safepointed); 266 CreateSetThreadState(_thread_in_Java); 267 268 // Clear the frame anchor 269 stack()->CreateResetLastJavaFrame(); 270 271 // If there is a pending exception then we can just unwind and 272 // return. It seems totally wrong that unlocking is skipped here 273 // but apparently the template interpreter does this so we do too. 274 BasicBlock *exception = CreateBlock("exception"); 275 BasicBlock *no_exception = CreateBlock("no_exception"); 276 277 builder()->CreateCondBr( 278 builder()->CreateICmpEQ( 279 CreateLoadPendingException(), 280 LLVMValue::null()), 281 no_exception, exception); 282 283 builder()->SetInsertPoint(exception); 284 CreateResetHandleBlock(); 285 stack()->CreatePopFrame(0); 286 builder()->CreateRet(LLVMValue::jint_constant(0)); 287 288 builder()->SetInsertPoint(no_exception); 289 290 // If the result was an oop then unbox it before 291 // releasing the handle it might be protected by 292 if (is_returning_oop()) { 293 BasicBlock *null = builder()->GetInsertBlock(); 294 BasicBlock *not_null = CreateBlock("not_null"); 295 BasicBlock *merge = CreateBlock("merge"); 296 297 builder()->CreateCondBr( 298 builder()->CreateICmpNE(result, ConstantPointerNull::get(box_type)), 299 not_null, merge); 300 301 builder()->SetInsertPoint(not_null); 302 Value *unboxed_result = builder()->CreateLoad(result); 303 builder()->CreateBr(merge); 304 305 builder()->SetInsertPoint(merge); 306 PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "result"); 307 phi->addIncoming(LLVMValue::null(), null); 308 phi->addIncoming(unboxed_result, not_null); 309 result = phi; 310 } 311 312 // Reset handle block 313 CreateResetHandleBlock(); 314 315 // Unlock if necessary. 316 if (is_synchronized()) 317 Unimplemented(); 318 319 // Unwind and return 320 Value *result_addr = stack()->CreatePopFrame(type2size[result_type]); 321 if (result_type != T_VOID) { 322 bool needs_cast = false; 323 bool is_signed = false; 324 switch (result_type) { 325 case T_BOOLEAN: 326 result = builder()->CreateICmpNE(result, LLVMValue::jbyte_constant(0)); 327 needs_cast = true; 328 break; 329 330 case T_CHAR: 331 needs_cast = true; 332 break; 333 334 case T_BYTE: 335 case T_SHORT: 336 needs_cast = true; 337 is_signed = true; 338 break; 339 } 340 if (needs_cast) { 341 result = builder()->CreateIntCast( 342 result, SharkType::to_stackType(result_type), is_signed); 343 } 344 345 builder()->CreateStore( 346 result, 347 builder()->CreateIntToPtr( 348 result_addr, 349 PointerType::getUnqual(SharkType::to_stackType(result_type)))); 350 } 351 builder()->CreateRet(LLVMValue::jint_constant(0)); 352 }