/JIT/ConstantMirror.h

http://unladen-swallow.googlecode.com/ · C Header · 140 lines · 76 code · 23 blank · 41 comment · 1 complexity · fb7b4e4f1a9637973a20ad04238b83cd MD5 · raw file

  1. // -*- C++ -*-
  2. #ifndef UTIL_CONSTANTMIRROR_H
  3. #define UTIL_CONSTANTMIRROR_H
  4. #ifndef __cplusplus
  5. #error This header expects to be included only in C++ source
  6. #endif
  7. #include "Python.h"
  8. #include "JIT/PyTypeBuilder.h"
  9. #include "llvm/ADT/DenseMap.h"
  10. #include "llvm/ADT/StringRef.h"
  11. #include <string>
  12. struct PyGlobalLlvmData;
  13. namespace llvm {
  14. class Constant;
  15. class ExecutionEngine;
  16. class PointerType;
  17. class GlobalValue;
  18. class GlobalVariable;
  19. class LLVMContext;
  20. class StructType;
  21. class TargetData;
  22. class Type;
  23. }
  24. // This class helps mirror constants from the runtime into LLVM
  25. // ConstantStructs and GlobalVariables. For PyObject*s, it uses the
  26. // ExecutionEngine's reverse mapping (getGlobalValueAtAddress()) to
  27. // cache GlobalVariables we've already mirrored and holds a python
  28. // reference to each one so that it doesn't wind up pointing to freed
  29. // memory or holding an out-of-date value. We don't cache
  30. // non-PyObject*s.
  31. class PyConstantMirror {
  32. public:
  33. // Keeps a reference to llvm_data.
  34. // llvm_data->getExecutionEngine() has to be destroyed before this
  35. // object because it causes several CallbackVHs to self-destruct,
  36. // and they access this object.
  37. PyConstantMirror(PyGlobalLlvmData *llvm_data);
  38. // GetConstantFor(x) returns an llvm::Constant representing that
  39. // object. It recursively mirrors objects the value points to
  40. // into GlobalVariables using GetGlobalVariableFor().
  41. llvm::Constant *GetConstantFor(PyObject *obj);
  42. llvm::Constant *GetConstantFor(PyCodeObject *obj);
  43. llvm::Constant *GetConstantFor(PyTypeObject *obj);
  44. llvm::Constant *GetConstantFor(PyTupleObject *obj);
  45. llvm::Constant *GetConstantFor(PyStringObject *obj);
  46. llvm::Constant *GetConstantFor(PyUnicodeObject *obj);
  47. llvm::Constant *GetConstantFor(PyIntObject *obj);
  48. llvm::Constant *GetConstantFor(PyLongObject *obj);
  49. llvm::Constant *GetConstantFor(PyFloatObject *obj);
  50. llvm::Constant *GetConstantFor(PyComplexObject *obj);
  51. llvm::Constant *GetConstantFor(PyNumberMethods *obj);
  52. llvm::Constant *GetConstantFor(PySequenceMethods *obj);
  53. llvm::Constant *GetConstantFor(PyMappingMethods *obj);
  54. llvm::Constant *GetConstantFor(PyBufferProcs *obj);
  55. // GetGlobalVariableFor(obj) returns an llvm::GlobalVariable
  56. // representing that object (or the null constant for obj==NULL),
  57. // tells the ExecutionEngine about the memory that backs it, and
  58. // attaches a Constant initializer to help optimizations. It also
  59. // increfs the object and arranges (with a CallbackVH) to decref
  60. // it when the GlobalVariable is destroyed. We use the
  61. // ExecutionEngine's address->GlobalValue mapping to avoid
  62. // creating two GlobalVariables for the same object.
  63. llvm::Constant *GetGlobalVariableFor(PyObject *obj);
  64. // Create an LLVM global variable that is backed by the given PyCFunction
  65. // function pointer. This currently only works for METH_ARG_RANGE
  66. // functions. Pass the maximum number of arguments the function accepts.
  67. llvm::Constant *GetGlobalForCFunction(PyCFunction cfunc_ptr,
  68. int arity,
  69. const llvm::StringRef &name);
  70. // Create an LLVM global variable that is backed by the given function
  71. // pointer.
  72. template <typename T>
  73. llvm::Constant *GetGlobalForFunctionPointer(void *func_ptr,
  74. const llvm::StringRef &name);
  75. private:
  76. friend struct PyGlobalLlvmData;
  77. // GetGlobalVariableForOwned() increfs 'owner' in order to keep
  78. // 'ptr' alive until the GlobalVariable is destoryed.
  79. template<typename T>
  80. llvm::Constant *GetGlobalVariableForOwned(T *ptr, PyObject *owner);
  81. llvm::Constant *ConstantFromMemory(const llvm::Type *type,
  82. const void *memory) const;
  83. llvm::StructType *ResizeVarObjectType(const llvm::StructType *type,
  84. unsigned dynamic_size) const;
  85. // Create an llvm::Function with the given address, type, and name, or a
  86. // NULL function pointer.
  87. llvm::Constant *CreateFunctionOrNull(void *func_ptr,
  88. const llvm::PointerType *func_ptr_type,
  89. const llvm::StringRef &name) const;
  90. // If LLVM knows a global value at address ptr, return it, otherwise return
  91. // NULL.
  92. llvm::GlobalValue *GetGlobalValueAtAddress(void *ptr) const;
  93. // Attempted shorthand for getting the context.
  94. llvm::LLVMContext &context() const;
  95. class RemovePyObjFromGlobalMappingsVH;
  96. PyGlobalLlvmData &llvm_data_;
  97. llvm::ExecutionEngine &engine_;
  98. const llvm::TargetData &target_data_;
  99. /* When this is true, the RemovePyObjFromGlobalMappingsVH doesn't
  100. decref PyObjects since running their finalizers could run
  101. python code after all modules and the thread state are gone. */
  102. bool python_shutting_down_;
  103. };
  104. // C++ templates require that we keep the templated part in the header.
  105. template<typename T> llvm::Constant *
  106. PyConstantMirror::GetGlobalForFunctionPointer(void *func_ptr,
  107. const llvm::StringRef &name)
  108. {
  109. // Reuse an existing LLVM global if we can.
  110. if (llvm::GlobalValue *found = this->GetGlobalValueAtAddress(func_ptr))
  111. return found;
  112. // Otherwise, create a new LLVM global.
  113. const llvm::PointerType *func_ptr_type =
  114. PyTypeBuilder<T>::get(this->context());
  115. return this->CreateFunctionOrNull(func_ptr, func_ptr_type, name);
  116. }
  117. #endif // UTIL_CONSTANTMIRROR_H