#include "core_runtime.h"
#include "plugin_manager.h"
#include "path_manager.h"
-#include "log_manager.h"
namespace tizen {
namespace runtime {
static coreclr_shutdown_ptr shutdown = nullptr;
static coreclr_create_delegate_ptr createDelegate = nullptr;
static set_environment_variable_ptr setEnvironmentVariable = nullptr;
+static stop_profile_after_delay_ptr stopProfileAfterDelay = nullptr;
+static set_switch_ptr setSwitch = nullptr;
static void* __coreclrLib = nullptr;
static void* __hostHandle = nullptr;
static unsigned int __domainId = -1;
static bool __isProfileMode = false;
PathManager* CoreRuntime::__pm = nullptr;
+#define MAX_DELAY_SEC 100
+
static std::vector<std::string> __envList;
static void setEnvFromFile()
return -1;
}
- char* pluginPath = pluginGetDllPath();
- if (pluginPath) {
- __pm->addPlatformAssembliesPaths(pluginPath);
+ char* pluginDllPaths = pluginGetDllPath();
+ if (pluginDllPaths && pluginDllPaths[0] != '\0') {
+ __pm->addPlatformAssembliesPaths(pluginDllPaths, true);
}
- if (!pluginHasLogControl()) {
- if (initializeLogManager() < 0) {
- _ERR("Failed to initnialize LogManager");
- return -1;
- }
+ char* pluginNativePaths = pluginGetNativeDllSearchingPath();
+ if (pluginNativePaths && pluginNativePaths[0] != '\0') {
+ __pm->addNativeDllSearchingPaths(pluginNativePaths, true);
}
+ pluginHasLogControl();
+
std::string libCoreclr(concatPath(__pm->getRuntimePath(), "libcoreclr.so"));
__coreclrLib = dlopen(libCoreclr.c_str(), RTLD_NOW | RTLD_LOCAL);
std::string tpa;
char* pluginTPA = pluginGetTPA();
- if (pluginTPA) {
+ if (pluginTPA && pluginTPA[0] != '\0') {
tpa = std::string(pluginTPA);
} else {
addAssembliesFromDirectories(__pm->getPlatformAssembliesPaths(), tpa);
return -1;
}
+ st = createDelegate(__hostHandle, __domainId, "Tizen.Runtime", "Tizen.Runtime.Profiler", "StopProfileAfterDelay", (void**)&stopProfileAfterDelay);
+ if (st < 0 || stopProfileAfterDelay == nullptr) {
+ _ERR("Create delegate for Tizen.Runtime.dll -> Tizen.Runtime.Profiler -> StopProfileAfterDelay failed (0x%08x)", st);
+ return -1;
+ }
+
+ st = createDelegate(__hostHandle, __domainId, "Tizen.Runtime", "Tizen.Runtime.AppSetting", "SetSwitch", (void**)&setSwitch);
+ if (st < 0 || setSwitch == nullptr) {
+ _ERR("Create delegate for Tizen.Runtime.dll -> Tizen.Runtime.AppSetting -> SetSwitch failed (0x%08x)", st);
+ return -1;
+ }
+
if (launchMode == LaunchMode::loader) {
// terminate candidate process if language is changed.
// CurrentCulture created for preloaded dlls should be updated.
_INFO("CoreRuntime finalized");
}
-int CoreRuntime::launch(const char* appId, const char* root, const char* path, int argc, char* argv[])
+int CoreRuntime::launch(const char* appId, const char* root, const char* path, int argc, char* argv[], bool profile)
{
if (!__initialized) {
_ERR("Runtime is not initialized");
return -1;
}
- // launchpad override stdout and stderr to journalctl before launch application.
- // we have to re-override that to input pipe for logging thread.
- // if LogManager is not initialized, below redirectFD will return 0;
- if (redirectFD() < 0) {
- _ERR("Failed to redirect FD");
- return -1;
- }
-
// VD has their own signal handler.
if (!pluginHasLogControl()) {
registerSigHandler();
char* localDataPath = app_get_data_path();
if (localDataPath != nullptr) {
setEnvironmentVariable("XDG_DATA_HOME", localDataPath);
+
+ // set profile.data path and collect/use it if it non-exists/exists.
+ if (profile) {
+ char multiCoreJitProfile[strlen(localDataPath) + strlen(PROFILE_BASENAME) + 1];
+ memcpy(multiCoreJitProfile, localDataPath, strlen(localDataPath) + 1);
+ strncat(multiCoreJitProfile, PROFILE_BASENAME, strlen(PROFILE_BASENAME));
+
+ setEnvironmentVariable("COMPlus_MultiCoreJitProfile", multiCoreJitProfile);
+ setEnvironmentVariable("COMPlus_MultiCoreJitMinNumCpus", "1");
+
+ // stop profiling and write collected data after delay if env value is set.
+ char *env = getenv("CLR_MCJ_PROFILE_WRITE_DELAY");
+ if (env != nullptr) {
+ int delay = std::atoi(env);
+ // To avoid undefined behavior by out-of-range input(atoi), set max delay value to 100.
+ if (delay > 0) {
+ if (delay > MAX_DELAY_SEC) delay = MAX_DELAY_SEC;
+ stopProfileAfterDelay(delay);
+ }
+ }
+
+ if (exist(multiCoreJitProfile)) {
+ setEnvironmentVariable("COMPlus_MultiCoreJitNoProfileGather", "1");
+ }
+ }
free(localDataPath);
}
+ setSwitch("Switch.System.Diagnostics.StackTrace.ShowILOffsets", true);
+
vconf_ignore_key_changed(VCONFKEY_LANGSET, langChangedCB);
pluginBeforeExecute();