1 /*
   2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright 2008, 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 "ci/ciEnv.hpp"
  28 #include "ci/ciMethod.hpp"
  29 #include "code/debugInfoRec.hpp"
  30 #include "code/dependencies.hpp"
  31 #include "code/exceptionHandlerTable.hpp"
  32 #include "code/oopRecorder.hpp"
  33 #include "compiler/abstractCompiler.hpp"
  34 #include "compiler/oopMap.hpp"
  35 #include "shark/llvmHeaders.hpp"
  36 #include "shark/sharkBuilder.hpp"
  37 #include "shark/sharkCodeBuffer.hpp"
  38 #include "shark/sharkCompiler.hpp"
  39 #include "shark/sharkContext.hpp"
  40 #include "shark/sharkEntry.hpp"
  41 #include "shark/sharkFunction.hpp"
  42 #include "shark/sharkMemoryManager.hpp"
  43 #include "shark/sharkNativeWrapper.hpp"
  44 #include "shark/shark_globals.hpp"
  45 #include "utilities/debug.hpp"
  46 
  47 #include <fnmatch.h>
  48 
  49 using namespace llvm;
  50 
  51 #if SHARK_LLVM_VERSION >= 27
  52 namespace {
  53   cl::opt<std::string>
  54   MCPU("mcpu");
  55 
  56   cl::list<std::string>
  57   MAttrs("mattr",
  58          cl::CommaSeparated);
  59 }
  60 #endif
  61 
  62 SharkCompiler::SharkCompiler()
  63   : AbstractCompiler() {
  64   // Create the lock to protect the memory manager and execution engine
  65   _execution_engine_lock = new Monitor(Mutex::leaf, "SharkExecutionEngineLock");
  66   MutexLocker locker(execution_engine_lock());
  67 
  68   // Make LLVM safe for multithreading
  69   if (!llvm_start_multithreaded())
  70     fatal("llvm_start_multithreaded() failed");
  71 
  72   // Initialize the native target
  73   InitializeNativeTarget();
  74 
  75   // Create the two contexts which we'll use
  76   _normal_context = new SharkContext("normal");
  77   _native_context = new SharkContext("native");
  78 
  79   // Create the memory manager
  80   _memory_manager = new SharkMemoryManager();
  81 
  82 #if SHARK_LLVM_VERSION >= 27
  83   // Finetune LLVM for the current host CPU.
  84   StringMap<bool> Features;
  85   bool gotCpuFeatures = llvm::sys::getHostCPUFeatures(Features);
  86   std::string cpu("-mcpu=" + llvm::sys::getHostCPUName());
  87 
  88   std::vector<const char*> args;
  89   args.push_back(""); // program name
  90   args.push_back(cpu.c_str());
  91 
  92   std::string mattr("-mattr=");
  93   if(gotCpuFeatures){
  94     for(StringMap<bool>::iterator I = Features.begin(),
  95       E = Features.end(); I != E; ++I){
  96       if(I->second){
  97         std::string attr(I->first());
  98         mattr+="+"+attr+",";
  99       }
 100     }
 101     args.push_back(mattr.c_str());
 102   }
 103 
 104   args.push_back(0);  // terminator
 105   cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]);
 106 
 107   // Create the JIT
 108   std::string ErrorMsg;
 109 
 110   EngineBuilder builder(_normal_context->module());
 111   builder.setMCPU(MCPU);
 112   builder.setMAttrs(MAttrs);
 113   builder.setJITMemoryManager(memory_manager());
 114   builder.setEngineKind(EngineKind::JIT);
 115   builder.setErrorStr(&ErrorMsg);
 116   _execution_engine = builder.create();
 117 
 118   if (!execution_engine()) {
 119     if (!ErrorMsg.empty())
 120       printf("Error while creating Shark JIT: %s\n",ErrorMsg.c_str());
 121     else
 122       printf("Unknown error while creating Shark JIT\n");
 123     exit(1);
 124   }
 125 
 126   execution_engine()->addModule(
 127     _native_context->module());
 128 #else
 129   _execution_engine = ExecutionEngine::createJIT(
 130     _normal_context->module_provider(),
 131     NULL, memory_manager(), CodeGenOpt::Default);
 132   execution_engine()->addModuleProvider(
 133     _native_context->module_provider());
 134 #endif
 135 
 136   // All done
 137   mark_initialized();
 138 }
 139 
 140 void SharkCompiler::initialize() {
 141   ShouldNotCallThis();
 142 }
 143 
 144 void SharkCompiler::compile_method(ciEnv*    env,
 145                                    ciMethod* target,
 146                                    int       entry_bci) {
 147   assert(is_initialized(), "should be");
 148   ResourceMark rm;
 149   const char *name = methodname(
 150     target->holder()->name()->as_utf8(), target->name()->as_utf8());
 151 
 152   // Do the typeflow analysis
 153   ciTypeFlow *flow;
 154   if (entry_bci == InvocationEntryBci)
 155     flow = target->get_flow_analysis();
 156   else
 157     flow = target->get_osr_flow_analysis(entry_bci);
 158   if (flow->failing())
 159     return;
 160   if (SharkPrintTypeflowOf != NULL) {
 161     if (!fnmatch(SharkPrintTypeflowOf, name, 0))
 162       flow->print_on(tty);
 163   }
 164 
 165   // Create the recorders
 166   Arena arena;
 167   env->set_oop_recorder(new OopRecorder(&arena));
 168   OopMapSet oopmaps;
 169   env->set_debug_info(new DebugInformationRecorder(env->oop_recorder()));
 170   env->debug_info()->set_oopmaps(&oopmaps);
 171   env->set_dependencies(new Dependencies(env));
 172 
 173   // Create the code buffer and builder
 174   CodeBuffer hscb("Shark", 256 * K, 64 * K);
 175   hscb.initialize_oop_recorder(env->oop_recorder());
 176   MacroAssembler *masm = new MacroAssembler(&hscb);
 177   SharkCodeBuffer cb(masm);
 178   SharkBuilder builder(&cb);
 179 
 180   // Emit the entry point
 181   SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
 182 
 183   // Build the LLVM IR for the method
 184   Function *function = SharkFunction::build(env, &builder, flow, name);
 185 
 186   // Generate native code.  It's unpleasant that we have to drop into
 187   // the VM to do this -- it blocks safepoints -- but I can't see any
 188   // other way to handle the locking.
 189   {
 190     ThreadInVMfromNative tiv(JavaThread::current());
 191     generate_native_code(entry, function, name);
 192   }
 193 
 194   // Install the method into the VM
 195   CodeOffsets offsets;
 196   offsets.set_value(CodeOffsets::Deopt, 0);
 197   offsets.set_value(CodeOffsets::Exceptions, 0);
 198   offsets.set_value(CodeOffsets::Verified_Entry,
 199                     target->is_static() ? 0 : wordSize);
 200 
 201   ExceptionHandlerTable handler_table;
 202   ImplicitExceptionTable inc_table;
 203 
 204   env->register_method(target,
 205                        entry_bci,
 206                        &offsets,
 207                        0,
 208                        &hscb,
 209                        0,
 210                        &oopmaps,
 211                        &handler_table,
 212                        &inc_table,
 213                        this,
 214                        env->comp_level(),
 215                        false,
 216                        false);
 217 }
 218 
 219 nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm,
 220                                                 methodHandle    target,
 221                                                 BasicType*      arg_types,
 222                                                 BasicType       return_type) {
 223   assert(is_initialized(), "should be");
 224   ResourceMark rm;
 225   const char *name = methodname(
 226     target->klass_name()->as_utf8(), target->name()->as_utf8());
 227 
 228   // Create the code buffer and builder
 229   SharkCodeBuffer cb(masm);
 230   SharkBuilder builder(&cb);
 231 
 232   // Emit the entry point
 233   SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
 234 
 235   // Build the LLVM IR for the method
 236   SharkNativeWrapper *wrapper = SharkNativeWrapper::build(
 237     &builder, target, name, arg_types, return_type);
 238 
 239   // Generate native code
 240   generate_native_code(entry, wrapper->function(), name);
 241 
 242   // Return the nmethod for installation in the VM
 243   return nmethod::new_native_nmethod(target,
 244                                      masm->code(),
 245                                      0,
 246                                      0,
 247                                      wrapper->frame_size(),
 248                                      wrapper->receiver_offset(),
 249                                      wrapper->lock_offset(),
 250                                      wrapper->oop_maps());
 251 }
 252 
 253 void SharkCompiler::generate_native_code(SharkEntry* entry,
 254                                          Function*   function,
 255                                          const char* name) {
 256   // Print the LLVM bitcode, if requested
 257   if (SharkPrintBitcodeOf != NULL) {
 258     if (!fnmatch(SharkPrintBitcodeOf, name, 0))
 259       function->dump();
 260   }
 261 
 262   // Compile to native code
 263   address code = NULL;
 264   context()->add_function(function);
 265   {
 266     MutexLocker locker(execution_engine_lock());
 267     free_queued_methods();
 268 
 269     if (SharkPrintAsmOf != NULL) {
 270 #if SHARK_LLVM_VERSION >= 27
 271 #ifndef NDEBUG
 272       if (!fnmatch(SharkPrintAsmOf, name, 0)) {
 273         llvm::SetCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit"));
 274         llvm::DebugFlag = true;
 275       }
 276       else {
 277         llvm::SetCurrentDebugType("");
 278         llvm::DebugFlag = false;
 279       }
 280 #endif // !NDEBUG
 281 #else
 282       // NB you need to patch LLVM with http://tinyurl.com/yf3baln for this
 283       std::vector<const char*> args;
 284       args.push_back(""); // program name
 285       if (!fnmatch(SharkPrintAsmOf, name, 0))
 286         args.push_back("-debug-only=x86-emitter");
 287       else
 288         args.push_back("-debug-only=none");
 289       args.push_back(0);  // terminator
 290       cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]);
 291 #endif // SHARK_LLVM_VERSION
 292     }
 293     memory_manager()->set_entry_for_function(function, entry);
 294     code = (address) execution_engine()->getPointerToFunction(function);
 295   }
 296   entry->set_entry_point(code);
 297   entry->set_function(function);
 298   entry->set_context(context());
 299   address code_start = entry->code_start();
 300   address code_limit = entry->code_limit();
 301 
 302   // Register generated code for profiling, etc
 303   if (JvmtiExport::should_post_dynamic_code_generated())
 304     JvmtiExport::post_dynamic_code_generated(name, code_start, code_limit);
 305 
 306   // Print debug information, if requested
 307   if (SharkTraceInstalls) {
 308     tty->print_cr(
 309       " [%p-%p): %s (%d bytes code)",
 310       code_start, code_limit, name, code_limit - code_start);
 311   }
 312 }
 313 
 314 void SharkCompiler::free_compiled_method(address code) {
 315   // This method may only be called when the VM is at a safepoint.
 316   // All _thread_in_vm threads will be waiting for the safepoint to
 317   // finish with the exception of the VM thread, so we can consider
 318   // ourself the owner of the execution engine lock even though we
 319   // can't actually acquire it at this time.
 320   assert(Thread::current()->is_VM_thread(), "must be called by VM thread");
 321   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 322 
 323   SharkEntry *entry = (SharkEntry *) code;
 324   entry->context()->push_to_free_queue(entry->function());
 325 }
 326 
 327 void SharkCompiler::free_queued_methods() {
 328   // The free queue is protected by the execution engine lock
 329   assert(execution_engine_lock()->owned_by_self(), "should be");
 330 
 331   while (true) {
 332     Function *function = context()->pop_from_free_queue();
 333     if (function == NULL)
 334       break;
 335 
 336     execution_engine()->freeMachineCodeForFunction(function);
 337     function->eraseFromParent();
 338   }
 339 }
 340 
 341 const char* SharkCompiler::methodname(const char* klass, const char* method) {
 342   char *buf = NEW_RESOURCE_ARRAY(char, strlen(klass) + 2 + strlen(method) + 1);
 343 
 344   char *dst = buf;
 345   for (const char *c = klass; *c; c++) {
 346     if (*c == '/')
 347       *(dst++) = '.';
 348     else
 349       *(dst++) = *c;
 350   }
 351   *(dst++) = ':';
 352   *(dst++) = ':';
 353   for (const char *c = method; *c; c++) {
 354     *(dst++) = *c;
 355   }
 356   *(dst++) = '\0';
 357   return buf;
 358 }