1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_RENDERSCRIPT_EXECUTABLE_H 18 #define ANDROID_RENDERSCRIPT_EXECUTABLE_H 19 20 21 #include "rsCpuScript.h" 22 23 #include <stdlib.h> 24 #include <string> 25 26 namespace android { 27 namespace renderscript { 28 29 class Context; 30 31 class SharedLibraryUtils { 32 public: 33 #ifndef RS_COMPATIBILITY_LIB 34 // Creates a shared library in cacheDir for the bitcode named resName. 35 // If reuse is false and SOPath is not nullptr, saves the filename 36 // used for the shared library in SOPath. 37 static bool createSharedLibrary(const char* driverName, 38 const char* cacheDir, 39 const char* resName, 40 const bool reuse = true, 41 std::string *SOPath = nullptr); 42 #endif 43 44 // Load the shared library referred to by cacheDir and resName. If we have 45 // already loaded this library, we instead create a new copy (in the 46 // cache dir) and then load that. We then immediately destroy the copy. 47 // This is required behavior to implement script instancing for the support 48 // library, since shared objects are loaded and de-duped by name only. 49 50 // For 64bit RS Support Lib, the shared lib path cannot be constructed from 51 // cacheDir, so nativeLibDir is needed to load shared libs. 52 static void* loadSharedLibrary(const char *cacheDir, const char *resName, 53 const char *nativeLibDir = nullptr, 54 bool *alreadyLoaded = nullptr); 55 56 // Load the shared library referred to by fullPath, and delete it right 57 // after loading it. Files loaded by this function are only used once, e.g., 58 // shared libraries generated for scripts in a debug context. Deleting them 59 // is OK in this case since the shared libraries have already been dlopened. 60 // Deletion is also required because such files are not intended for reuse. 61 static void* loadAndDeleteSharedLibrary(const char *fullPath); 62 63 // Create a len length string containing random characters from [A-Za-z0-9]. 64 static std::string getRandomString(size_t len); 65 66 private: 67 // Attempt to load the shared library from origName, but then fall back to 68 // creating a copy of the shared library if necessary (to ensure instancing). 69 // This function returns the dlopen()-ed handle if successful. 70 static void *loadSOHelper(const char *origName, const char *cacheDir, 71 const char *resName, bool* alreadyLoaded = nullptr); 72 73 static const char* LD_EXE_PATH; 74 static const char* RS_CACHE_DIR; 75 }; 76 77 class ScriptExecutable { 78 public: ScriptExecutable(void ** fieldAddress,bool * fieldIsObject,const char * const * fieldName,size_t varCount,InvokeFunc_t * invokeFunctions,size_t funcCount,ForEachFunc_t * forEachFunctions,uint32_t * forEachSignatures,size_t forEachCount,ReduceDescription * reduceDescriptions,size_t reduceCount,const char ** pragmaKeys,const char ** pragmaValues,size_t pragmaCount,const char ** globalNames,const void ** globalAddresses,const size_t * globalSizes,const uint32_t * globalProperties,size_t globalEntries,bool isThreadable,uint32_t buildChecksum)79 ScriptExecutable(void** fieldAddress, bool* fieldIsObject, 80 const char* const * fieldName, size_t varCount, 81 InvokeFunc_t* invokeFunctions, size_t funcCount, 82 ForEachFunc_t* forEachFunctions, uint32_t* forEachSignatures, 83 size_t forEachCount, 84 ReduceDescription *reduceDescriptions, size_t reduceCount, 85 const char** pragmaKeys, const char** pragmaValues, 86 size_t pragmaCount, 87 const char **globalNames, const void **globalAddresses, 88 const size_t *globalSizes, 89 const uint32_t *globalProperties, size_t globalEntries, 90 bool isThreadable, uint32_t buildChecksum) : 91 mFieldAddress(fieldAddress), mFieldIsObject(fieldIsObject), 92 mFieldName(fieldName), mExportedVarCount(varCount), 93 mInvokeFunctions(invokeFunctions), mFuncCount(funcCount), 94 mForEachFunctions(forEachFunctions), mForEachSignatures(forEachSignatures), 95 mForEachCount(forEachCount), 96 mReduceDescriptions(reduceDescriptions), mReduceCount(reduceCount), 97 mPragmaKeys(pragmaKeys), mPragmaValues(pragmaValues), 98 mPragmaCount(pragmaCount), mGlobalNames(globalNames), 99 mGlobalAddresses(globalAddresses), mGlobalSizes(globalSizes), 100 mGlobalProperties(globalProperties), mGlobalEntries(globalEntries), 101 mIsThreadable(isThreadable), mBuildChecksum(buildChecksum) { 102 } 103 ~ScriptExecutable()104 ~ScriptExecutable() { 105 for (size_t i = 0; i < mExportedVarCount; ++i) { 106 if (mFieldIsObject[i]) { 107 if (mFieldAddress[i] != nullptr) { 108 rs_object_base *obj_addr = 109 reinterpret_cast<rs_object_base *>(mFieldAddress[i]); 110 rsrClearObject(obj_addr); 111 } 112 } 113 } 114 115 for (size_t i = 0; i < mPragmaCount; ++i) { 116 delete [] mPragmaKeys[i]; 117 delete [] mPragmaValues[i]; 118 } 119 delete[] mPragmaValues; 120 delete[] mPragmaKeys; 121 122 delete[] mReduceDescriptions; 123 124 delete[] mForEachSignatures; 125 delete[] mForEachFunctions; 126 127 delete[] mInvokeFunctions; 128 129 for (size_t i = 0; i < mExportedVarCount; i++) { 130 delete[] mFieldName[i]; 131 } 132 delete[] mFieldName; 133 delete[] mFieldIsObject; 134 delete[] mFieldAddress; 135 } 136 137 // Create an ScriptExecutable object from a shared object. 138 // If expectedChecksum is not zero, it will be compared to the checksum 139 // embedded in the shared object. A mismatch will cause a failure. 140 // If succeeded, returns the new object. Otherwise, returns nullptr. 141 static ScriptExecutable* 142 createFromSharedObject(void* sharedObj, 143 uint32_t expectedChecksum = 0); 144 getExportedVariableCount()145 size_t getExportedVariableCount() const { return mExportedVarCount; } getExportedFunctionCount()146 size_t getExportedFunctionCount() const { return mFuncCount; } getExportedForEachCount()147 size_t getExportedForEachCount() const { return mForEachCount; } getExportedReduceCount()148 size_t getExportedReduceCount() const { return mReduceCount; } getPragmaCount()149 size_t getPragmaCount() const { return mPragmaCount; } 150 getFieldAddress(int slot)151 void* getFieldAddress(int slot) const { return mFieldAddress[slot]; } 152 void* getFieldAddress(const char* name) const; getFieldIsObject(int slot)153 bool getFieldIsObject(int slot) const { return mFieldIsObject[slot]; } getFieldName(int slot)154 const char* getFieldName(int slot) const { return mFieldName[slot]; } 155 getInvokeFunction(int slot)156 InvokeFunc_t getInvokeFunction(int slot) const { return mInvokeFunctions[slot]; } 157 getForEachFunction(int slot)158 ForEachFunc_t getForEachFunction(int slot) const { return mForEachFunctions[slot]; } getForEachSignature(int slot)159 uint32_t getForEachSignature(int slot) const { return mForEachSignatures[slot]; } 160 getReduceDescription(int slot)161 const ReduceDescription* getReduceDescription(int slot) const { 162 return &mReduceDescriptions[slot]; 163 } 164 getPragmaKeys()165 const char ** getPragmaKeys() const { return mPragmaKeys; } getPragmaValues()166 const char ** getPragmaValues() const { return mPragmaValues; } 167 getGlobalName(int i)168 const char* getGlobalName(int i) const { 169 if (i < mGlobalEntries) { 170 return mGlobalNames[i]; 171 } else { 172 return nullptr; 173 } 174 } getGlobalAddress(int i)175 const void* getGlobalAddress(int i) const { 176 if (i < mGlobalEntries) { 177 return mGlobalAddresses[i]; 178 } else { 179 return nullptr; 180 } 181 } getGlobalSize(int i)182 size_t getGlobalSize(int i) const { 183 if (i < mGlobalEntries) { 184 return mGlobalSizes[i]; 185 } else { 186 return 0; 187 } 188 } getGlobalProperties(int i)189 uint32_t getGlobalProperties(int i) const { 190 if (i < mGlobalEntries) { 191 return mGlobalProperties[i]; 192 } else { 193 return 0; 194 } 195 } getGlobalEntries()196 int getGlobalEntries() const { return mGlobalEntries; } 197 getThreadable()198 bool getThreadable() const { return mIsThreadable; } 199 getBuildChecksum()200 uint32_t getBuildChecksum() const { return mBuildChecksum; } 201 202 bool dumpGlobalInfo() const; 203 204 private: 205 void** mFieldAddress; 206 bool* mFieldIsObject; 207 const char* const * mFieldName; 208 size_t mExportedVarCount; 209 210 InvokeFunc_t* mInvokeFunctions; 211 size_t mFuncCount; 212 213 ForEachFunc_t* mForEachFunctions; 214 uint32_t* mForEachSignatures; 215 size_t mForEachCount; 216 217 ReduceDescription* mReduceDescriptions; 218 size_t mReduceCount; 219 220 const char ** mPragmaKeys; 221 const char ** mPragmaValues; 222 size_t mPragmaCount; 223 224 const char ** mGlobalNames; 225 const void ** mGlobalAddresses; 226 const size_t * mGlobalSizes; 227 const uint32_t * mGlobalProperties; 228 int mGlobalEntries; 229 230 bool mIsThreadable; 231 uint32_t mBuildChecksum; 232 }; 233 234 } // namespace renderscript 235 } // namespace android 236 237 #endif // ANDROID_RENDERSCRIPT_EXECUTABLE_H 238