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