14d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner//===-- JIT.cpp - LLVM Just in Time Compiler ------------------------------===// 2f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 9bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// 104d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner// This tool implements a just-in-time compiler for LLVM, allowing direct 11a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif// execution of LLVM bitcode in an efficient manner. 12bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// 13bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===// 14bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 154d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner#include "JIT.h" 1640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin#include "llvm/ADT/SmallPtrSet.h" 17a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#include "llvm/CodeGen/JITCodeEmitter.h" 18b3a847db0b991d3210706a2580428fdc2b6bf037Argyrios Kyrtzidis#include "llvm/CodeGen/MachineCodeInfo.h" 19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Config/config.h" 20df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin#include "llvm/ExecutionEngine/GenericValue.h" 21df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin#include "llvm/ExecutionEngine/JITEventListener.h" 2230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev#include "llvm/ExecutionEngine/JITMemoryManager.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 2944e3dd1672572df28e79649c86f2d44bf3730062Chris Lattner#include "llvm/Support/Dwarf.h" 30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/DynamicLibrary.h" 3131e2466f159a887fed9139067a676f65adf2a8c3Torok Edwin#include "llvm/Support/ErrorHandling.h" 3240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin#include "llvm/Support/ManagedStatic.h" 3344e3dd1672572df28e79649c86f2d44bf3730062Chris Lattner#include "llvm/Support/MutexGuard.h" 34d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetJITInfo.h" 35d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h" 363b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov 37c19aadee66b744311afe6e420847e80822a765f2Chris Lattnerusing namespace llvm; 38abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 394f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach#ifdef __APPLE__ 403b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov// Apple gcc defaults to -fuse-cxa-atexit (i.e. calls __cxa_atexit instead 413b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov// of atexit). It passes the address of linker generated symbol __dso_handle 423b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov// to the function. 433b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov// This configuration change happened at version 5330. 443b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov# include <AvailabilityMacros.h> 453b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov# if defined(MAC_OS_X_VERSION_10_4) && \ 463b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov ((MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4) || \ 473b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov (MAC_OS_X_VERSION_MIN_REQUIRED == MAC_OS_X_VERSION_10_4 && \ 483b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov __APPLE_CC__ >= 5330)) 493b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov# ifndef HAVE___DSO_HANDLE 503b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov# define HAVE___DSO_HANDLE 1 513b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov# endif 523b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov# endif 535f42c550305814f916207b9604b92fbd258e8eafEvan Cheng#endif 543b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov 553b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov#if HAVE___DSO_HANDLE 563b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikovextern void *__dso_handle __attribute__ ((__visibility__ ("hidden"))); 57b76ea74845849e7a499603bb04bfe1614101e910Nate Begeman#endif 585f42c550305814f916207b9604b92fbd258e8eafEvan Cheng 59844731a7f1909f55935e3514c9e713a62d67662eDan Gohmannamespace { 60844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 612fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattnerstatic struct RegisterJIT { 622fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattner RegisterJIT() { JIT::Register(); } 632fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattner} JITRegistrator; 642fe4bb06c6c40d16b7a5ae9cdf6bb6fe94d51be0Chris Lattner 65844731a7f1909f55935e3514c9e713a62d67662eDan Gohman} 66844731a7f1909f55935e3514c9e713a62d67662eDan Gohman 67e46161f10c3e0c640b22e446b873df8b01413f52Bob Wilsonextern "C" void LLVMLinkInJIT() { 682f51914d828b462b054195e73c75448f24e01979Jeff Cohen} 692f51914d828b462b054195e73c75448f24e01979Jeff Cohen 7032c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar// Determine whether we can register EH tables. 7132c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#if (defined(__GNUC__) && !defined(__ARM_EABI__) && \ 7232c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar !defined(__USING_SJLJ_EXCEPTIONS__)) 7332c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#define HAVE_EHTABLE_SUPPORT 1 7432c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#else 7532c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#define HAVE_EHTABLE_SUPPORT 0 7632c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#endif 77d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 7832c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#if HAVE_EHTABLE_SUPPORT 794f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 80d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// libgcc defines the __register_frame function to dynamically register new 81d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// dwarf frames for exception handling. This functionality is not portable 82d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// across compilers and is only provided by GCC. We use the __register_frame 83d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// function here so that code generated by the JIT cooperates with the unwinding 84d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// runtime of libgcc. When JITting with exception handling enable, LLVM 85d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// generates dwarf frames and registers it to libgcc with __register_frame. 86d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// 87d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// The __register_frame function works with Linux. 88d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// 89d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// Unfortunately, this functionality seems to be in libgcc after the unwinding 90d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// library of libgcc for darwin was written. The code for darwin overwrites the 91d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// value updated by __register_frame with a value fetched with "keymgr". 92d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// "keymgr" is an obsolete functionality, which should be rewritten some day. 93d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// In the meantime, since "keymgr" is on all libgccs shipped with apple-gcc, we 94d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// need a workaround in LLVM which uses the "keymgr" to dynamically modify the 95d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// values of an opaque key, used by libgcc to find dwarf tables. 96d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 97299d9d74e9b010c499557380fb6467f5361e141aAnton Korobeynikovextern "C" void __register_frame(void*); 98b35fd448cea32da671ecd3ecaad3cc637598c6e0Duncan Sandsextern "C" void __deregister_frame(void*); 99d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 10000f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050 10100f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng# define USE_KEYMGR 1 10200f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng#else 10300f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng# define USE_KEYMGR 0 10400f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng#endif 10500f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng 10600f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng#if USE_KEYMGR 107d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 108d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffraynamespace { 109d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 110d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// LibgccObject - This is the structure defined in libgcc. There is no #include 111d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// provided for this structure, so we also define it here. libgcc calls it 112d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// "struct object". The structure is undocumented in libgcc. 113d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffraystruct LibgccObject { 114d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray void *unused1; 115d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray void *unused2; 116d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray void *unused3; 1174f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 118d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// frame - Pointer to the exception table. 119d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray void *frame; 1204f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 121d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// encoding - The encoding of the object? 122d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray union { 123d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray struct { 124d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray unsigned long sorted : 1; 125d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray unsigned long from_array : 1; 126d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray unsigned long mixed_encoding : 1; 127d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray unsigned long encoding : 8; 1284f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach unsigned long count : 21; 129d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray } b; 130d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray size_t i; 131d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray } encoding; 1324f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 133d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// fde_end - libgcc defines this field only if some macro is defined. We 134d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// include this field even if it may not there, to make libgcc happy. 135d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray char *fde_end; 1364f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 137d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// next - At least we know it's a chained list! 138d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray struct LibgccObject *next; 139d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray}; 140d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 141d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray// "kemgr" stuff. Apparently, all frame tables are stored there. 142d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffrayextern "C" void _keymgr_set_and_unlock_processwide_ptr(int, void *); 143d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffrayextern "C" void *_keymgr_get_and_lock_processwide_ptr(int); 144d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray#define KEYMGR_GCC3_DW2_OBJ_LIST 302 /* Dwarf2 object list */ 145d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 146d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray/// LibgccObjectInfo - libgcc defines this struct as km_object_info. It 147d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray/// probably contains all dwarf tables that are loaded. 148d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffraystruct LibgccObjectInfo { 149d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 150d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// seenObjects - LibgccObjects already parsed by the unwinding runtime. 151d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// 152d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray struct LibgccObject* seenObjects; 153d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 154d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// unseenObjects - LibgccObjects not parsed yet by the unwinding runtime. 155d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray /// 156d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray struct LibgccObject* unseenObjects; 1574f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 158d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray unsigned unused[2]; 159d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray}; 160d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 161d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray/// darwin_register_frame - Since __register_frame does not work with darwin's 162d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray/// libgcc,we provide our own function, which "tricks" libgcc by modifying the 163d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray/// "Dwarf2 object list" key. 164d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffrayvoid DarwinRegisterFrame(void* FrameBegin) { 165d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // Get the key. 16644e3dd1672572df28e79649c86f2d44bf3730062Chris Lattner LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) 167d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); 16844e3dd1672572df28e79649c86f2d44bf3730062Chris Lattner assert(LOI && "This should be preallocated by the runtime"); 1694f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 170d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // Allocate a new LibgccObject to represent this frame. Deallocation of this 171d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // object may be impossible: since darwin code in libgcc was written after 172d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // the ability to dynamically register frames, things may crash if we 173d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // deallocate it. 174d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray struct LibgccObject* ob = (struct LibgccObject*) 175d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray malloc(sizeof(struct LibgccObject)); 1764f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 177d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // Do like libgcc for the values of the field. 178d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray ob->unused1 = (void *)-1; 179d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray ob->unused2 = 0; 180d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray ob->unused3 = 0; 181d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray ob->frame = FrameBegin; 1824f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach ob->encoding.i = 0; 183d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray ob->encoding.b.encoding = llvm::dwarf::DW_EH_PE_omit; 1844f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 185f451cb870efcf9e0302d25ed05f4cac6bb494e42Dan Gohman // Put the info on both places, as libgcc uses the first or the second 186d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // field. Note that we rely on having two pointers here. If fde_end was a 187d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // char, things would get complicated. 188d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray ob->fde_end = (char*)LOI->unseenObjects; 189d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray ob->next = LOI->unseenObjects; 1904f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 191d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // Update the key's unseenObjects list. 192d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray LOI->unseenObjects = ob; 1934f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 1944f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach // Finally update the "key". Apparently, libgcc requires it. 195d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, 196d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray LOI); 197d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 198d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray} 199d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray 200d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray} 201d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray#endif // __APPLE__ 20232c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#endif // HAVE_EHTABLE_SUPPORT 203299d9d74e9b010c499557380fb6467f5361e141aAnton Korobeynikov 20434c9433004cabd4760987dce4804a91c84908219Chris Lattner/// createJIT - This is the factory method for creating a JIT for the current 20534c9433004cabd4760987dce4804a91c84908219Chris Lattner/// machine, it does not fall back to the interpreter. This takes ownership 206f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin/// of the module. 207f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey YasskinExecutionEngine *JIT::createJIT(Module *M, 2084b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner std::string *ErrorStr, 2094b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner JITMemoryManager *JMM, 21088b5aca20a6dd0a8b15ff620bdee59aae567d245Eric Christopher bool GVsWithCode, 211c5b28580a94e247300e5d3ccf532e153f2ae6f12Dylan Noblesmith TargetMachine *TM) { 21283a82ac0b4dc6ea6b3e56f9e239a113eb5be5f38Nick Lewycky // Try to register the program as a source of symbols to resolve against. 2132ea29ba2a8ddd7ba4b946eb754f1a39304d9fc09Dylan Noblesmith // 2142ea29ba2a8ddd7ba4b946eb754f1a39304d9fc09Dylan Noblesmith // FIXME: Don't do this here. 21583a82ac0b4dc6ea6b3e56f9e239a113eb5be5f38Nick Lewycky sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); 21683a82ac0b4dc6ea6b3e56f9e239a113eb5be5f38Nick Lewycky 2172ea29ba2a8ddd7ba4b946eb754f1a39304d9fc09Dylan Noblesmith // If the target supports JIT code generation, create the JIT. 2184b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner if (TargetJITInfo *TJ = TM->getJITInfo()) { 2199ea47179e647e806a2c67639bfead9d254514e59Dylan Noblesmith return new JIT(M, *TM, *TJ, JMM, GVsWithCode); 2204b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner } else { 2214b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner if (ErrorStr) 2224b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner *ErrorStr = "target does not support JIT code generation"; 2234b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner return 0; 2244b1511b027ce0b648b3379f2891816c25b46f515Reid Kleckner } 22534c9433004cabd4760987dce4804a91c84908219Chris Lattner} 22634c9433004cabd4760987dce4804a91c84908219Chris Lattner 22740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskinnamespace { 22840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin/// This class supports the global getPointerToNamedFunction(), which allows 22940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin/// bugpoint or gdb users to search for a function by name without any context. 23040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskinclass JitPool { 23140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin SmallPtrSet<JIT*, 1> JITs; // Optimize for process containing just 1 JIT. 23240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin mutable sys::Mutex Lock; 23340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskinpublic: 23440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin void Add(JIT *jit) { 23540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard guard(Lock); 23640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JITs.insert(jit); 23740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 23840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin void Remove(JIT *jit) { 23940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard guard(Lock); 24040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JITs.erase(jit); 24140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 24240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin void *getPointerToNamedFunction(const char *Name) const { 24340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard guard(Lock); 24440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin assert(JITs.size() != 0 && "No Jit registered"); 24540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin //search function in every instance of JIT 24640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin for (SmallPtrSet<JIT*, 1>::const_iterator Jit = JITs.begin(), 24740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin end = JITs.end(); 24840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin Jit != end; ++Jit) { 24940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin if (Function *F = (*Jit)->FindFunctionNamed(Name)) 25040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin return (*Jit)->getPointerToFunction(F); 25140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 25240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // The function is not available : fallback on the first created (will 25340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // search in symbol of the current program/library) 25440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin return (*JITs.begin())->getPointerToNamedFunction(Name); 25540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 25640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin}; 25740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey YasskinManagedStatic<JitPool> AllJits; 25840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin} 25940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskinextern "C" { 26040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // getPointerToNamedFunction - This function is used as a global wrapper to 26140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // JIT::getPointerToNamedFunction for the purpose of resolving symbols when 26240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // bugpoint is debugging the JIT. In that scenario, we are loading an .so and 26340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // need to resolve function(s) that are being mis-codegenerated, so we need to 26440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // resolve their addresses at runtime, and this is the way to do it. 26540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin void *getPointerToNamedFunction(const char *Name) { 26640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin return AllJits->getPointerToNamedFunction(Name); 26740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 26840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin} 26940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin 270f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey YasskinJIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji, 27130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev JITMemoryManager *jmm, bool GVsWithCode) 27230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev : ExecutionEngine(M), TM(tm), TJI(tji), 27330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev JMM(jmm ? jmm : JITMemoryManager::CreateDefaultMemManager()), 27430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev AllocateGVsWithCode(GVsWithCode), isAlreadyCodeGenerating(false) { 2753574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow setDataLayout(TM.getDataLayout()); 276abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 277f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin jitstate = new JITState(M); 278f049e07eb8930214941c72f8e4409df394de1567Nate Begeman 279a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes // Initialize JCE 2802763217fbd2f1c54a7a25fd3ae9e997ea6ece0cbReid Kleckner JCE = createEmitter(*this, JMM, TM); 281f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman 28240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // Register in global list of all JITs. 28340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin AllJits->Add(this); 28440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin 28550872d5385463cf1d2e23a758516e7f818e1af24Brian Gaeke // Add target data 286ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer MutexGuard locked(lock); 287f049e07eb8930214941c72f8e4409df394de1567Nate Begeman FunctionPassManager &PM = jitstate->getPM(locked); 2883574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow PM.add(new DataLayout(*TM.getDataLayout())); 28950872d5385463cf1d2e23a758516e7f818e1af24Brian Gaeke 2904d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner // Turn the machine code intermediate representation into bytes in memory that 2914d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner // may be executed. 292d95e67dac029d48984b72889a96a1bb389b8ac71Dylan Noblesmith if (TM.addPassesToEmitMachineCode(PM, *JCE)) { 29375361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Target does not support machine code emission!"); 2944d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner } 2954f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 296a7ec87cd0793c463d792323087b2fb3a4871efe0Nicolas Geoffray // Register routine for informing unwinding runtime about new EH frames 29732c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#if HAVE_EHTABLE_SUPPORT 29800f16283cf12c53c2626d21fb534f9422500f0f1Evan Cheng#if USE_KEYMGR 299d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray struct LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) 300d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); 3014f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 302d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // The key is created on demand, and libgcc creates it the first time an 303d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // exception occurs. Since we need the key to register frames, we create 304d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray // it now. 3053f91bb3ce4c8f6e31c4051cc10799e54c3a26a3aChris Lattner if (!LOI) 3064f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach LOI = (LibgccObjectInfo*)calloc(sizeof(struct LibgccObjectInfo), 1); 3073f91bb3ce4c8f6e31c4051cc10799e54c3a26a3aChris Lattner _keymgr_set_and_unlock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST, LOI); 308d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray InstallExceptionTableRegister(DarwinRegisterFrame); 309b35fd448cea32da671ecd3ecaad3cc637598c6e0Duncan Sands // Not sure about how to deregister on Darwin. 310d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray#else 311a7ec87cd0793c463d792323087b2fb3a4871efe0Nicolas Geoffray InstallExceptionTableRegister(__register_frame); 312b35fd448cea32da671ecd3ecaad3cc637598c6e0Duncan Sands InstallExceptionTableDeregister(__deregister_frame); 313d046fc61ac28f65b209185a12a5e83716941d59bNicolas Geoffray#endif // __APPLE__ 31432c7a5e08cbabb262e3ec080f34652ebf6c39e0fDaniel Dunbar#endif // HAVE_EHTABLE_SUPPORT 3154f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 3161911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner // Initialize passes. 3171911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner PM.doInitialization(); 318bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 319bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 3204d326fa9bea5b80147edf14d1521fc41ce315275Chris LattnerJIT::~JIT() { 321b35fd448cea32da671ecd3ecaad3cc637598c6e0Duncan Sands // Unregister all exception tables registered by this JIT. 322b35fd448cea32da671ecd3ecaad3cc637598c6e0Duncan Sands DeregisterAllTables(); 323b35fd448cea32da671ecd3ecaad3cc637598c6e0Duncan Sands // Cleanup. 32440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin AllJits->Remove(this); 325f049e07eb8930214941c72f8e4409df394de1567Nate Begeman delete jitstate; 326a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes delete JCE; 32730b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev // JMM is a ownership of JCE, so we no need delete JMM here. 3284d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner delete &TM; 3294d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner} 3304d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 331f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin/// addModule - Add a new Module to the JIT. If we previously removed the last 332f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin/// Module, we need re-initialize jitstate with a valid Module. 333f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskinvoid JIT::addModule(Module *M) { 334f049e07eb8930214941c72f8e4409df394de1567Nate Begeman MutexGuard locked(lock); 335f049e07eb8930214941c72f8e4409df394de1567Nate Begeman 336f049e07eb8930214941c72f8e4409df394de1567Nate Begeman if (Modules.empty()) { 337f049e07eb8930214941c72f8e4409df394de1567Nate Begeman assert(!jitstate && "jitstate should be NULL if Modules vector is empty!"); 338f049e07eb8930214941c72f8e4409df394de1567Nate Begeman 339f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin jitstate = new JITState(M); 340f049e07eb8930214941c72f8e4409df394de1567Nate Begeman 341f049e07eb8930214941c72f8e4409df394de1567Nate Begeman FunctionPassManager &PM = jitstate->getPM(locked); 3423574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow PM.add(new DataLayout(*TM.getDataLayout())); 343f049e07eb8930214941c72f8e4409df394de1567Nate Begeman 344f049e07eb8930214941c72f8e4409df394de1567Nate Begeman // Turn the machine code intermediate representation into bytes in memory 345f049e07eb8930214941c72f8e4409df394de1567Nate Begeman // that may be executed. 346d95e67dac029d48984b72889a96a1bb389b8ac71Dylan Noblesmith if (TM.addPassesToEmitMachineCode(PM, *JCE)) { 34775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Target does not support machine code emission!"); 348f049e07eb8930214941c72f8e4409df394de1567Nate Begeman } 3494f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 350f049e07eb8930214941c72f8e4409df394de1567Nate Begeman // Initialize passes. 351f049e07eb8930214941c72f8e4409df394de1567Nate Begeman PM.doInitialization(); 352f049e07eb8930214941c72f8e4409df394de1567Nate Begeman } 3534f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 354f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin ExecutionEngine::addModule(M); 355f049e07eb8930214941c72f8e4409df394de1567Nate Begeman} 356f049e07eb8930214941c72f8e4409df394de1567Nate Begeman 357f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin/// removeModule - If we are removing the last Module, invalidate the jitstate 358f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin/// since the PassManager it contains references a released Module. 359f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskinbool JIT::removeModule(Module *M) { 360f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin bool result = ExecutionEngine::removeModule(M); 3614f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 362f049e07eb8930214941c72f8e4409df394de1567Nate Begeman MutexGuard locked(lock); 3634f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 3649402be960b4895217d009b6204cf08d8e697b8d5Chad Rosier if (jitstate && jitstate->getModule() == M) { 365f049e07eb8930214941c72f8e4409df394de1567Nate Begeman delete jitstate; 366f049e07eb8930214941c72f8e4409df394de1567Nate Begeman jitstate = 0; 367f049e07eb8930214941c72f8e4409df394de1567Nate Begeman } 3684f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 369d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman if (!jitstate && !Modules.empty()) { 370d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman jitstate = new JITState(Modules[0]); 371d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 372d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman FunctionPassManager &PM = jitstate->getPM(locked); 3733574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow PM.add(new DataLayout(*TM.getDataLayout())); 3744f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 375d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // Turn the machine code intermediate representation into bytes in memory 376d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // that may be executed. 377d95e67dac029d48984b72889a96a1bb389b8ac71Dylan Noblesmith if (TM.addPassesToEmitMachineCode(PM, *JCE)) { 37875361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Target does not support machine code emission!"); 379d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman } 3804f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 381d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // Initialize passes. 382d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman PM.doInitialization(); 3834f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach } 384f049e07eb8930214941c72f8e4409df394de1567Nate Begeman return result; 385f049e07eb8930214941c72f8e4409df394de1567Nate Begeman} 386f049e07eb8930214941c72f8e4409df394de1567Nate Begeman 38770975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke/// run - Start execution with the specified function and arguments. 38805a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// 389ff0f1bb32a439cf82cb09ee29544c894a2bfe877Chris LattnerGenericValue JIT::runFunction(Function *F, 390ff0f1bb32a439cf82cb09ee29544c894a2bfe877Chris Lattner const std::vector<GenericValue> &ArgValues) { 391b47130c580385a5a2c922c480a85438b2bb80293Chris Lattner assert(F && "Function *F was null at entry to run()"); 392b47130c580385a5a2c922c480a85438b2bb80293Chris Lattner 393b47130c580385a5a2c922c480a85438b2bb80293Chris Lattner void *FPtr = getPointerToFunction(F); 3947c45d7898bdfdc29a61a58b678e13ed41333ed51Chris Lattner assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); 395db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = F->getFunctionType(); 396db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = FTy->getReturnType(); 397bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 39807ab52b6459f65b3e1c94d52321165688a6096aaDan Gohman assert((FTy->getNumParams() == ArgValues.size() || 39907ab52b6459f65b3e1c94d52321165688a6096aaDan Gohman (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && 40007ab52b6459f65b3e1c94d52321165688a6096aaDan Gohman "Wrong number of arguments passed into function!"); 401e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner assert(FTy->getNumParams() == ArgValues.size() && 402e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner "This doesn't support passing arguments through varargs (yet)!"); 403e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner 404ec8430270a9f1adbf9b790319a1d4781658359fdMisha Brukman // Handle some common cases first. These cases correspond to common `main' 405e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner // prototypes. 406b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { 407f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner switch (ArgValues.size()) { 408f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner case 3: 409b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (FTy->getParamType(0)->isIntegerTy(32) && 4101df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands FTy->getParamType(1)->isPointerTy() && 4111df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands FTy->getParamType(2)->isPointerTy()) { 412f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner int (*PF)(int, char **, const char **) = 413870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner (int(*)(int, char **, const char **))(intptr_t)FPtr; 414ec8430270a9f1adbf9b790319a1d4781658359fdMisha Brukman 415f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner // Call the function. 416e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner GenericValue rv; 4174f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 41838f6a15df69c271c3bebf648642041b31380e31aReid Spencer (char **)GVTOP(ArgValues[1]), 41938f6a15df69c271c3bebf648642041b31380e31aReid Spencer (const char **)GVTOP(ArgValues[2]))); 420f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner return rv; 421f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner } 422f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner break; 423174f2264649d9ae062bdb0a038131c2836596be5Chris Lattner case 2: 424b0bc6c361da9009e8414efde317d9bbff755f6c0Duncan Sands if (FTy->getParamType(0)->isIntegerTy(32) && 4251df9859c40492511b8aa4321eb76496005d3b75bDuncan Sands FTy->getParamType(1)->isPointerTy()) { 426870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr; 427ec8430270a9f1adbf9b790319a1d4781658359fdMisha Brukman 428174f2264649d9ae062bdb0a038131c2836596be5Chris Lattner // Call the function. 429174f2264649d9ae062bdb0a038131c2836596be5Chris Lattner GenericValue rv; 4304f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 43138f6a15df69c271c3bebf648642041b31380e31aReid Spencer (char **)GVTOP(ArgValues[1]))); 432174f2264649d9ae062bdb0a038131c2836596be5Chris Lattner return rv; 433174f2264649d9ae062bdb0a038131c2836596be5Chris Lattner } 434174f2264649d9ae062bdb0a038131c2836596be5Chris Lattner break; 435f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner case 1: 436847a32b78fefb3097b662bcd1156c202d4569d96Nuno Lopes if (FTy->getParamType(0)->isIntegerTy(32)) { 437e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner GenericValue rv; 438870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner int (*PF)(int) = (int(*)(int))(intptr_t)FPtr; 43938f6a15df69c271c3bebf648642041b31380e31aReid Spencer rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); 440f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner return rv; 441f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner } 442847a32b78fefb3097b662bcd1156c202d4569d96Nuno Lopes if (FTy->getParamType(0)->isPointerTy()) { 443847a32b78fefb3097b662bcd1156c202d4569d96Nuno Lopes GenericValue rv; 444847a32b78fefb3097b662bcd1156c202d4569d96Nuno Lopes int (*PF)(char *) = (int(*)(char *))(intptr_t)FPtr; 445847a32b78fefb3097b662bcd1156c202d4569d96Nuno Lopes rv.IntVal = APInt(32, PF((char*)GVTOP(ArgValues[0]))); 446847a32b78fefb3097b662bcd1156c202d4569d96Nuno Lopes return rv; 447847a32b78fefb3097b662bcd1156c202d4569d96Nuno Lopes } 448f7bedf447e080cb57c64d6f0cbf6fbeb9f4c596eChris Lattner break; 449e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner } 450e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner } 451e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner 452e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner // Handle cases where no arguments are passed first. 453e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner if (ArgValues.empty()) { 454e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner GenericValue rv; 455e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner switch (RetTy->getTypeID()) { 456c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown return type for function call!"); 457a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer case Type::IntegerTyID: { 458a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth(); 459a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer if (BitWidth == 1) 46038f6a15df69c271c3bebf648642041b31380e31aReid Spencer rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)()); 461a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer else if (BitWidth <= 8) 46238f6a15df69c271c3bebf648642041b31380e31aReid Spencer rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)()); 463a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer else if (BitWidth <= 16) 46438f6a15df69c271c3bebf648642041b31380e31aReid Spencer rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)()); 465a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer else if (BitWidth <= 32) 46638f6a15df69c271c3bebf648642041b31380e31aReid Spencer rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)()); 467a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer else if (BitWidth <= 64) 46838f6a15df69c271c3bebf648642041b31380e31aReid Spencer rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)()); 4694f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach else 470c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("Integer types > 64 bits not supported"); 471e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner return rv; 472a54b7cbd452b3adb2f51346140d996b29c2cdb30Reid Spencer } 473e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner case Type::VoidTyID: 47438f6a15df69c271c3bebf648642041b31380e31aReid Spencer rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); 475e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner return rv; 476e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner case Type::FloatTyID: 477870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner rv.FloatVal = ((float(*)())(intptr_t)FPtr)(); 478e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner return rv; 479e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner case Type::DoubleTyID: 480870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner rv.DoubleVal = ((double(*)())(intptr_t)FPtr)(); 481d297aea5f24f2ad369162b8c1084cda4dcc839f0Chris Lattner return rv; 4821abac0d725374cb6e527d2a735a5272a4f7913faDale Johannesen case Type::X86_FP80TyID: 4831abac0d725374cb6e527d2a735a5272a4f7913faDale Johannesen case Type::FP128TyID: 4841abac0d725374cb6e527d2a735a5272a4f7913faDale Johannesen case Type::PPC_FP128TyID: 485c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("long double not supported yet"); 486e5eab142a51373dd3bee758ea958575afbfce259Chris Lattner case Type::PointerTyID: 487870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner return PTOGV(((void*(*)())(intptr_t)FPtr)()); 488d297aea5f24f2ad369162b8c1084cda4dcc839f0Chris Lattner } 489ff0f1bb32a439cf82cb09ee29544c894a2bfe877Chris Lattner } 49070975eef572b9e132bbaade16ba9edb76f15f287Brian Gaeke 491cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // Okay, this is not one of our quick and easy cases. Because we don't have a 492cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // full FFI, we have to codegen a nullary stub function that just calls the 493cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // function we are interested in, passing in constants for all of the 494cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // arguments. Make this function and return. 495cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner 496cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // First, create the function. 497debcb01b0f0a15f568ca69e8f288fade4bfc7297Owen Anderson FunctionType *STy=FunctionType::get(RetTy, false); 498051a950000e21935165db56695e35bade668193bGabor Greif Function *Stub = Function::Create(STy, Function::InternalLinkage, "", 499051a950000e21935165db56695e35bade668193bGabor Greif F->getParent()); 500cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner 501cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // Insert a basic block. 5021d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson BasicBlock *StubBB = BasicBlock::Create(F->getContext(), "", Stub); 503cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner 504cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // Convert all of the GenericValue arguments over to constants. Note that we 505cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner // currently don't support varargs. 506990b849abc9481b8c7a482019cd0d95fe2f2a3eaChris Lattner SmallVector<Value*, 8> Args; 507cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner for (unsigned i = 0, e = ArgValues.size(); i != e; ++i) { 508cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner Constant *C = 0; 509db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ArgTy = FTy->getParamType(i); 510cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner const GenericValue &AV = ArgValues[i]; 511cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner switch (ArgTy->getTypeID()) { 512c23197a26f34f559ea9797de51e187087c039c42Torok Edwin default: llvm_unreachable("Unknown argument type for function call!"); 51302a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner case Type::IntegerTyID: 514eed707b1e6097aac2bb6b3d47271f6300ace7f2eOwen Anderson C = ConstantInt::get(F->getContext(), AV.IntVal); 51502a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner break; 51602a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner case Type::FloatTyID: 5176f83c9c6ef0e7f79825a0a8f22941815e4b684c7Owen Anderson C = ConstantFP::get(F->getContext(), APFloat(AV.FloatVal)); 51802a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner break; 51902a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner case Type::DoubleTyID: 5206f83c9c6ef0e7f79825a0a8f22941815e4b684c7Owen Anderson C = ConstantFP::get(F->getContext(), APFloat(AV.DoubleVal)); 52102a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner break; 5221abac0d725374cb6e527d2a735a5272a4f7913faDale Johannesen case Type::PPC_FP128TyID: 5231abac0d725374cb6e527d2a735a5272a4f7913faDale Johannesen case Type::X86_FP80TyID: 52402a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner case Type::FP128TyID: 5250a29cb045444c13160e90fe7942a9d7c720185edTim Northover C = ConstantFP::get(F->getContext(), APFloat(ArgTy->getFltSemantics(), 5260a29cb045444c13160e90fe7942a9d7c720185edTim Northover AV.IntVal)); 52702a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner break; 528cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner case Type::PointerTyID: 529cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner void *ArgPtr = GVTOP(AV); 53002a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner if (sizeof(void*) == 4) 5314f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach C = ConstantInt::get(Type::getInt32Ty(F->getContext()), 5321d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson (int)(intptr_t)ArgPtr); 53302a260aa11a2e1b2c14335274d3c42ca3f3eabc0Chris Lattner else 5341d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson C = ConstantInt::get(Type::getInt64Ty(F->getContext()), 5351d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson (intptr_t)ArgPtr); 5369adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson // Cast the integer to pointer 537baf3c404409d5e47b13984a7f95bfbd6d1f2e79eOwen Anderson C = ConstantExpr::getIntToPtr(C, ArgTy); 538cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner break; 539cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner } 540cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner Args.push_back(C); 541cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner } 542cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner 543a3efbb15ddd5aa9006564cd79086723640084878Jay Foad CallInst *TheCall = CallInst::Create(F, Args, "", StubBB); 544cdfc51ffe3eda17a611fe2aaed1a2e6650d3d203Chris Lattner TheCall->setCallingConv(F->getCallingConv()); 545a471e045b7cef5da428bdada4a362a4be671ef0bChris Lattner TheCall->setTailCall(); 546f012705c7e4ca8cf90b6b734ce1d5355daca5ba5Benjamin Kramer if (!TheCall->getType()->isVoidTy()) 5471d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson // Return result of the call. 5481d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ReturnInst::Create(F->getContext(), TheCall, StubBB); 549cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner else 5501d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson ReturnInst::Create(F->getContext(), StubBB); // Just return void. 551cc22e9f406cf21e3a2036bf6628ee7a5c850d42cChris Lattner 5523174f6703e534366382390b7c7daa913483f4340Jeffrey Yasskin // Finally, call our nullary stub function. 5533174f6703e534366382390b7c7daa913483f4340Jeffrey Yasskin GenericValue Result = runFunction(Stub, std::vector<GenericValue>()); 5543174f6703e534366382390b7c7daa913483f4340Jeffrey Yasskin // Erase it, since no other function can have a reference to it. 5553174f6703e534366382390b7c7daa913483f4340Jeffrey Yasskin Stub->eraseFromParent(); 5563174f6703e534366382390b7c7daa913483f4340Jeffrey Yasskin // And return the result. 5573174f6703e534366382390b7c7daa913483f4340Jeffrey Yasskin return Result; 558bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 5594d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 560df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinvoid JIT::RegisterJITEventListener(JITEventListener *L) { 561df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin if (L == NULL) 562df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin return; 563df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MutexGuard locked(lock); 564df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin EventListeners.push_back(L); 565df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin} 566df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinvoid JIT::UnregisterJITEventListener(JITEventListener *L) { 567df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin if (L == NULL) 568df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin return; 569df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MutexGuard locked(lock); 570df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin std::vector<JITEventListener*>::reverse_iterator I= 571df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin std::find(EventListeners.rbegin(), EventListeners.rend(), L); 572df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin if (I != EventListeners.rend()) { 573df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin std::swap(*I, EventListeners.back()); 574df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin EventListeners.pop_back(); 575df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin } 576df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin} 577df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskinvoid JIT::NotifyFunctionEmitted( 578df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin const Function &F, 579df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin void *Code, size_t Size, 580df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin const JITEvent_EmittedFunctionDetails &Details) { 581df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MutexGuard locked(lock); 582df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 583df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin EventListeners[I]->NotifyFunctionEmitted(F, Code, Size, Details); 584df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin } 585df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin} 586df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin 5877a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskinvoid JIT::NotifyFreeingMachineCode(void *OldPtr) { 588df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MutexGuard locked(lock); 589df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 5907a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin EventListeners[I]->NotifyFreeingMachineCode(OldPtr); 591df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin } 592df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin} 593df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin 5944d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// runJITOnFunction - Run the FunctionPassManager full of 5954d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// just-in-time compilation passes on F, hopefully filling in 5964d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// GlobalAddress[F] with the address of F's machine code. 5974d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// 598b3a847db0b991d3210706a2580428fdc2b6bf037Argyrios Kyrtzidisvoid JIT::runJITOnFunction(Function *F, MachineCodeInfo *MCI) { 599ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer MutexGuard locked(lock); 600b3a847db0b991d3210706a2580428fdc2b6bf037Argyrios Kyrtzidis 601df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin class MCIListener : public JITEventListener { 602df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MachineCodeInfo *const MCI; 603df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin public: 604df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MCIListener(MachineCodeInfo *mci) : MCI(mci) {} 605df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin virtual void NotifyFunctionEmitted(const Function &, 606df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin void *Code, size_t Size, 607df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin const EmittedFunctionDetails &) { 608df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MCI->setAddress(Code); 609df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MCI->setSize(Size); 610df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin } 611df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin }; 612df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin MCIListener MCIL(MCI); 61392fdf4537bd298673552d47adac2ff7bceab9dc9Jeffrey Yasskin if (MCI) 61492fdf4537bd298673552d47adac2ff7bceab9dc9Jeffrey Yasskin RegisterJITEventListener(&MCIL); 615b3a847db0b991d3210706a2580428fdc2b6bf037Argyrios Kyrtzidis 61621afcda54479602c2936946731a3f1ee8e5d2322Dan Gohman runJITOnFunctionUnlocked(F, locked); 617b3a847db0b991d3210706a2580428fdc2b6bf037Argyrios Kyrtzidis 61892fdf4537bd298673552d47adac2ff7bceab9dc9Jeffrey Yasskin if (MCI) 61992fdf4537bd298673552d47adac2ff7bceab9dc9Jeffrey Yasskin UnregisterJITEventListener(&MCIL); 62021afcda54479602c2936946731a3f1ee8e5d2322Dan Gohman} 62121afcda54479602c2936946731a3f1ee8e5d2322Dan Gohman 62221afcda54479602c2936946731a3f1ee8e5d2322Dan Gohmanvoid JIT::runJITOnFunctionUnlocked(Function *F, const MutexGuard &locked) { 62317f218e001862785c5ba5974a6374f2f7bc29ac0Chris Lattner assert(!isAlreadyCodeGenerating && "Error: Recursive compilation detected!"); 6244d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 62568feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner jitTheFunction(F, locked); 626c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner 627d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // If the function referred to another function that had not yet been 628dc85724f703bddf6988b6b3f20203beab775f32bJeffrey Yasskin // read from bitcode, and we are jitting non-lazily, emit it now. 629d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman while (!jitstate->getPendingFunctions(locked).empty()) { 630d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman Function *PF = jitstate->getPendingFunctions(locked).back(); 631d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman jitstate->getPendingFunctions(locked).pop_back(); 632d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 633aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin assert(!PF->hasAvailableExternallyLinkage() && 634aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin "Externally-defined function should not be in pending list."); 635aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin 63668feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner jitTheFunction(PF, locked); 6374f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 638d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // Now that the function has been jitted, ask the JITEmitter to rewrite 639d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // the stub with real address of the function. 640d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman updateFunctionStub(PF); 641c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner } 6424d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner} 6434d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 64468feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattnervoid JIT::jitTheFunction(Function *F, const MutexGuard &locked) { 64568feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner isAlreadyCodeGenerating = true; 64668feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner jitstate->getPM(locked).run(*F); 64768feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner isAlreadyCodeGenerating = false; 64868feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner 64968feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner // clear basic block addresses after this function is done 65068feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner getBasicBlockAddressMap(locked).clear(); 65168feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner} 65268feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner 6534d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// getPointerToFunction - This method is used to get the address of the 6547a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner/// specified function, compiling it if necessary. 6554d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// 6564d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattnervoid *JIT::getPointerToFunction(Function *F) { 657ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer 658c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner if (void *Addr = getPointerToGlobalIfAvailable(F)) 659c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner return Addr; // Check if function already code gen'd 6604d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 661a3ac0c105d26f8535d03031db7e97274b3ff8159Dan Gohman MutexGuard locked(lock); 6621c341c8462a208ccc5ba4b4e030cdc989ce38818Mon P Wang 663aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin // Now that this thread owns the lock, make sure we read in the function if it 664aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin // exists in this Module. 665aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin std::string ErrorMsg; 666f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin if (F->Materialize(&ErrorMsg)) { 66775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Error reading function '" + F->getName()+ 668aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin "' from bitcode file: " + ErrorMsg); 669fd7d99120b394e7aa4cf0b670f7b783a61dec3a1Nicolas Geoffray } 6704d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 671aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin // ... and check if another thread has already code gen'd the function. 672aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin if (void *Addr = getPointerToGlobalIfAvailable(F)) 673aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin return Addr; 674aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin 67546264f020a2f08c605ac69754291a7413d747766Chris Lattner if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { 6766f348e458660063a40052b208bab96895c822877Jeffrey Yasskin bool AbortOnFailure = !F->hasExternalWeakLinkage(); 67769f9378675b23135043d93aa58300fed3ec41cbfDan Gohman void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); 678c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner addGlobalMapping(F, Addr); 679c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner return Addr; 680c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner } 6814d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 68221afcda54479602c2936946731a3f1ee8e5d2322Dan Gohman runJITOnFunctionUnlocked(F, locked); 683c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner 684c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner void *Addr = getPointerToGlobalIfAvailable(F); 6854d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner assert(Addr && "Code generation didn't add function to GlobalAddress table!"); 6864d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner return Addr; 6874d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner} 6884d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 68968feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattnervoid JIT::addPointerToBasicBlock(const BasicBlock *BB, void *Addr) { 69068feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner MutexGuard locked(lock); 6914f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 69268feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner BasicBlockAddressMapTy::iterator I = 69368feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner getBasicBlockAddressMap(locked).find(BB); 69468feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner if (I == getBasicBlockAddressMap(locked).end()) { 69568feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner getBasicBlockAddressMap(locked)[BB] = Addr; 69668feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner } else { 69768feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner // ignore repeats: some BBs can be split into few MBBs? 69868feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner } 69968feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner} 70068feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner 70168feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattnervoid JIT::clearPointerToBasicBlock(const BasicBlock *BB) { 70268feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner MutexGuard locked(lock); 70368feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner getBasicBlockAddressMap(locked).erase(BB); 70468feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner} 70568feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner 70668feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattnervoid *JIT::getPointerToBasicBlock(BasicBlock *BB) { 70768feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner // make sure it's function is compiled by JIT 70868feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner (void)getPointerToFunction(BB->getParent()); 70968feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner 71068feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner // resolve basic block address 71168feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner MutexGuard locked(lock); 7124f9fc854bc8d1482e65cd8fad464644a24fca4bfJim Grosbach 71368feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner BasicBlockAddressMapTy::iterator I = 71468feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner getBasicBlockAddressMap(locked).find(BB); 71568feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner if (I != getBasicBlockAddressMap(locked).end()) { 71668feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner return I->second; 71768feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner } else { 718858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper llvm_unreachable("JIT does not have BB address for address-of-label, was" 719858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper " it eliminated by optimizer?"); 72068feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner } 72168feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner} 72268feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner 72330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshevvoid *JIT::getPointerToNamedFunction(const std::string &Name, 72430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev bool AbortOnFailure){ 72530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (!isSymbolSearchingDisabled()) { 72630b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev void *ptr = JMM->getPointerToNamedFunction(Name, false); 72730b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (ptr) 72830b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return ptr; 72930b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev } 73030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 73130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev /// If a LazyFunctionCreator is installed, use it to get/create the function. 73230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (LazyFunctionCreator) 73330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (void *RP = LazyFunctionCreator(Name)) 73430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return RP; 73530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 73630b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev if (AbortOnFailure) { 73730b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev report_fatal_error("Program used external function '"+Name+ 73830b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev "' which could not be resolved!"); 73930b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev } 74030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev return 0; 74130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev} 74230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 74330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev 744c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner/// getOrEmitGlobalVariable - Return the address of the specified global 745c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner/// variable, possibly emitting it to memory if needed. This is used by the 746c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner/// Emitter. 747c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattnervoid *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) { 748ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer MutexGuard locked(lock); 749ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer 750c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner void *Ptr = getPointerToGlobalIfAvailable(GV); 751c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner if (Ptr) return Ptr; 752c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner 753c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner // If the global is external, just remember the address. 754898e9df8dbc65b9b7b92c35ac6673ac8651ff3e8Jeffrey Yasskin if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) { 7553b30a6e92d1da79674451879d4112a8f83cc12a4Anton Korobeynikov#if HAVE___DSO_HANDLE 7565f42c550305814f916207b9604b92fbd258e8eafEvan Cheng if (GV->getName() == "__dso_handle") 7575f42c550305814f916207b9604b92fbd258e8eafEvan Cheng return (void*)&__dso_handle; 758b82ab94e20bd48ac149746864e0d5b1653bdcf3eEvan Cheng#endif 759fbee579ed46016166d88b4defb81a2e7e253062dDaniel Dunbar Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(GV->getName()); 7606f348e458660063a40052b208bab96895c822877Jeffrey Yasskin if (Ptr == 0) { 76175361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Could not resolve external global address: " 76231e2466f159a887fed9139067a676f65adf2a8c3Torok Edwin +GV->getName()); 763c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner } 76466941988de6a295649b33f4c2b0f36a094b2244dNate Begeman addGlobalMapping(GV, Ptr); 765c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner } else { 766dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // If the global hasn't been emitted to memory yet, allocate space and 767489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // emit it into memory. 768489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin Ptr = getMemoryForGV(GV); 769dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen addGlobalMapping(GV, Ptr); 770489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin EmitGlobalVariable(GV); // Initialize the variable. 771c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner } 772c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner return Ptr; 773c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner} 774c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner 7754d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// recompileAndRelinkFunction - This method is used to force a function 7764d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// which has already been compiled, to be compiled again, possibly 7774d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// after it has been modified. Then the entry to the old copy is overwritten 7784d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// with a branch to the new copy. If there was no old copy, this acts 7794d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// just like JIT::getPointerToFunction(). 7804d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner/// 7814d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattnervoid *JIT::recompileAndRelinkFunction(Function *F) { 782c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner void *OldAddr = getPointerToGlobalIfAvailable(F); 7834d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 784c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner // If it's not already compiled there is no reason to patch it up. 785c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner if (OldAddr == 0) { return getPointerToFunction(F); } 7864d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner 787c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner // Delete the old function mapping. 788c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner addGlobalMapping(F, 0); 789c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner 790c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner // Recodegen the function 7914d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner runJITOnFunction(F); 792c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner 793c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner // Update state, forward the old function to the new function. 794c07ed1387503d25c0b93fcf617f69329d73fc589Chris Lattner void *Addr = getPointerToGlobalIfAvailable(F); 7954d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner assert(Addr && "Code generation didn't add function to GlobalAddress table!"); 7964d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner TJI.replaceMachineCodeForFunction(OldAddr, Addr); 7974d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner return Addr; 7984d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner} 799895eddfad43f848d5accce1789aa80be0db459d3Misha Brukman 80046fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray/// getMemoryForGV - This method abstracts memory allocation of global 80146fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray/// variable so that the JIT can allocate thread local variables depending 80246fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray/// on the target. 80346fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray/// 80446fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffraychar* JIT::getMemoryForGV(const GlobalVariable* GV) { 805489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin char *Ptr; 806489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin 807489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // GlobalVariable's which are not "constant" will cause trouble in a server 808489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // situation. It's returned in the same block of memory as code which may 809489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // not be writable. 810489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin if (isGVCompilationDisabled() && !GV->isConstant()) { 81175361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Compilation of non-internal GlobalValue is disabled!"); 812489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin } 813489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin 814489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // Some applications require globals and code to live together, so they may 815489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // be allocated into the same buffer, but in general globals are allocated 816489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // through the memory manager which puts them near the code but not in the 817489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // same buffer. 818db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *GlobalType = GV->getType()->getElementType(); 8193574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow size_t S = getDataLayout()->getTypeAllocSize(GlobalType); 8203574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow size_t A = getDataLayout()->getPreferredAlignment(GV); 82146fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray if (GV->isThreadLocal()) { 82246fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray MutexGuard locked(lock); 823489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin Ptr = TJI.allocateThreadLocalMemory(S); 824489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin } else if (TJI.allocateSeparateGVMemory()) { 825489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin if (A <= 8) { 826489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin Ptr = (char*)malloc(S); 827489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin } else { 828489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // Allocate S+A bytes of memory, then use an aligned pointer within that 829489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // space. 830489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin Ptr = (char*)malloc(S+A); 831489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin unsigned MisAligned = ((intptr_t)Ptr & (A-1)); 832489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin Ptr = Ptr + (MisAligned ? (A-MisAligned) : 0); 833489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin } 834489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin } else if (AllocateGVsWithCode) { 835489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin Ptr = (char*)JCE->allocateSpace(S, A); 83646fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray } else { 837489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin Ptr = (char*)JCE->allocateGlobal(S, A); 83846fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray } 839489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin return Ptr; 84046fa139e26be6ebc00be2fb45820c2560dd22a32Nicolas Geoffray} 841d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 842d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begemanvoid JIT::addPendingFunction(Function *F) { 843d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman MutexGuard locked(lock); 844d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman jitstate->getPendingFunctions(locked).push_back(F); 845d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman} 846df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin 847df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin 848df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey YasskinJITEventListener::~JITEventListener() {} 849