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