diff --git a/mobile/app/Makefile.in b/mobile/app/Makefile.in index f5cff054b1b3..9f842f653b82 100644 --- a/mobile/app/Makefile.in +++ b/mobile/app/Makefile.in @@ -54,25 +54,18 @@ CPPSRCS = nsBrowserApp.cpp LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base +LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/build + +DEFINES += -DXPCOM_GLUE +STL_FLAGS= LIBS += $(JEMALLOC_LIBS) -ifeq (Linux_1, $(OS_ARCH)_$(GNU_LD)) -OS_LDFLAGS += -Wl,-rpath='$$ORIGIN' -NSDISTMODE = copy -endif - LIBS += \ - $(XPCOM_GLUE_LDOPTS) \ - $(NSPR_LIBS) \ + $(EXTRA_DSO_LIBS) \ + $(XPCOM_STANDALONE_GLUE_LDOPTS) \ $(NULL) -ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) -LIBS += $(DIST)/bin/XUL -else -EXTRA_DSO_LIBS += xul -LIBS += $(EXTRA_DSO_LIBS) -endif ifeq ($(OS_ARCH),WINNT) OS_LIBS += $(call EXPAND_LIBNAME,version) endif @@ -84,6 +77,10 @@ WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup endif endif #LIBXUL_SDK +# This switches $(INSTALL) to copy mode, like $(SYSINSTALL), so things that +# shouldn't get 755 perms need $(IFLAGS1) for either way of calling nsinstall. +NSDISTMODE = copy + include $(topsrcdir)/config/rules.mk GRE_MILESTONE = $(shell $(PYTHON) $(topsrcdir)/config/printconfigsetting.py $(LIBXUL_DIST)/bin/platform.ini Build Milestone) diff --git a/mobile/app/nsBrowserApp.cpp b/mobile/app/nsBrowserApp.cpp index 85c033a07cef..19da11f98482 100644 --- a/mobile/app/nsBrowserApp.cpp +++ b/mobile/app/nsBrowserApp.cpp @@ -36,14 +36,19 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsXPCOMGlue.h" #include "nsXULAppAPI.h" -#ifdef XP_WIN +#if defined(XP_WIN) #include #include +#elif defined(XP_UNIX) +#include +#include #endif #include #include +#include #include "plstr.h" #include "prprf.h" @@ -54,11 +59,16 @@ #include "nsStringGlue.h" #ifdef XP_WIN -// we want to use the DLL blocklist if possible -#define XRE_WANT_DLL_BLOCKLIST // we want a wmain entry point #include "nsWindowsWMain.cpp" +#define snprintf _snprintf +#define strcasecmp _stricmp #endif +#include "BinaryPath.h" + +#include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL + +#include "mozilla/Telemetry.h" static void Output(const char *fmt, ... ) { @@ -85,17 +95,20 @@ static PRBool IsArg(const char* arg, const char* s) { if (*++arg == '-') ++arg; - return !PL_strcasecmp(arg, s); + return !strcasecmp(arg, s); } #if defined(XP_WIN) || defined(XP_OS2) if (*arg == '/') - return !PL_strcasecmp(++arg, s); + return !strcasecmp(++arg, s); #endif return PR_FALSE; } +/** + * A helper class which calls NS_LogInit/NS_LogTerm in its scope. + */ class ScopedLogging { public: @@ -103,22 +116,48 @@ public: ~ScopedLogging() { NS_LogTerm(); } }; -int main(int argc, char* argv[]) -{ - ScopedLogging log; +XRE_GetFileFromPathType XRE_GetFileFromPath; +XRE_CreateAppDataType XRE_CreateAppData; +XRE_FreeAppDataType XRE_FreeAppData; +#ifdef XRE_HAS_DLL_BLOCKLIST +XRE_SetupDllBlocklistType XRE_SetupDllBlocklist; +#endif +XRE_TelemetryAccumulateType XRE_TelemetryAccumulate; +XRE_mainType XRE_main; +static const nsDynamicFunctionLoad kXULFuncs[] = { + { "XRE_GetFileFromPath", (NSFuncPtr*) &XRE_GetFileFromPath }, + { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData }, + { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData }, +#ifdef XRE_HAS_DLL_BLOCKLIST + { "XRE_SetupDllBlocklist", (NSFuncPtr*) &XRE_SetupDllBlocklist }, +#endif + { "XRE_TelemetryAccumulate", (NSFuncPtr*) &XRE_TelemetryAccumulate }, + { "XRE_main", (NSFuncPtr*) &XRE_main }, + { nsnull, nsnull } +}; + +static int do_main(const char *exePath, int argc, char* argv[]) +{ nsCOMPtr appini; - nsresult rv = XRE_GetBinaryPath(argv[0], getter_AddRefs(appini)); +#ifdef XP_WIN + // exePath comes from mozilla::BinaryPath::Get, which returns a UTF-8 + // encoded path, so it is safe to convert it + nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(exePath), PR_FALSE, + getter_AddRefs(appini)); +#else + nsresult rv = NS_NewNativeLocalFile(nsDependentCString(exePath), PR_FALSE, + getter_AddRefs(appini)); +#endif if (NS_FAILED(rv)) { - Output("Couldn't calculate the application directory."); return 255; } + appini->SetNativeLeafName(NS_LITERAL_CSTRING("application.ini")); // Allow firefox.exe to launch XULRunner apps via -app // Note that -app must be the *first* argument. - char *appEnv = nsnull; - const char *appDataFile = PR_GetEnv("XUL_APP_FILE"); + const char *appDataFile = getenv("XUL_APP_FILE"); if (appDataFile && *appDataFile) { rv = XRE_GetFileFromPath(appDataFile, getter_AddRefs(appini)); if (NS_FAILED(rv)) { @@ -138,8 +177,12 @@ int main(int argc, char* argv[]) return 255; } - appEnv = PR_smprintf("XUL_APP_FILE=%s", argv[2]); - PR_SetEnv(appEnv); + char appEnv[MAXPATHLEN]; + snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]); + if (putenv(appEnv)) { + Output("Couldn't set %s.\n", appEnv); + return 255; + } argv[2] = argv[0]; argv += 2; argc -= 2; @@ -154,7 +197,90 @@ int main(int argc, char* argv[]) int result = XRE_main(argc, argv, appData); XRE_FreeAppData(appData); - if (appEnv) - PR_smprintf_free(appEnv); + return result; +} + +int main(int argc, char* argv[]) +{ + char exePath[MAXPATHLEN]; + + nsresult rv = mozilla::BinaryPath::Get(argv[0], exePath); + if (NS_FAILED(rv)) { + Output("Couldn't calculate the application directory.\n"); + return 255; + } + + char *lastSlash = strrchr(exePath, XPCOM_FILE_PATH_SEPARATOR[0]); + if (!lastSlash || (lastSlash - exePath > MAXPATHLEN - sizeof(XPCOM_DLL) - 1)) + return 255; + + strcpy(++lastSlash, XPCOM_DLL); + + int gotCounters; +#if defined(XP_UNIX) + struct rusage initialRUsage; + gotCounters = !getrusage(RUSAGE_SELF, &initialRUsage); +#elif defined(XP_WIN) + // GetProcessIoCounters().ReadOperationCount seems to have little to + // do with actual read operations. It reports 0 or 1 at this stage + // in the program. Luckily 1 coincides with when prefetch is + // enabled. If Windows prefetch didn't happen we can do our own + // faster dll preloading. + IO_COUNTERS ioCounters; + gotCounters = GetProcessIoCounters(GetCurrentProcess(), &ioCounters); + if (gotCounters && !ioCounters.ReadOperationCount) +#endif + { + XPCOMGlueEnablePreload(); + } + + + rv = XPCOMGlueStartup(exePath); + if (NS_FAILED(rv)) { + Output("Couldn't load XPCOM.\n"); + return 255; + } + + rv = XPCOMGlueLoadXULFunctions(kXULFuncs); + if (NS_FAILED(rv)) { + Output("Couldn't load XRE functions.\n"); + return 255; + } + +#ifdef XRE_HAS_DLL_BLOCKLIST + XRE_SetupDllBlocklist(); +#endif + + if (gotCounters) { +#if defined(XP_WIN) + XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_OPS, + int(ioCounters.ReadOperationCount)); + XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_READ_TRANSFER, + int(ioCounters.ReadTransferCount / 1024)); + IO_COUNTERS newIoCounters; + if (GetProcessIoCounters(GetCurrentProcess(), &newIoCounters)) { + XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_OPS, + int(newIoCounters.ReadOperationCount - ioCounters.ReadOperationCount)); + XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_READ_TRANSFER, + int((newIoCounters.ReadTransferCount - ioCounters.ReadTransferCount) / 1024)); + } +#elif defined(XP_UNIX) + XRE_TelemetryAccumulate(mozilla::Telemetry::EARLY_GLUESTARTUP_HARD_FAULTS, + int(initialRUsage.ru_majflt)); + struct rusage newRUsage; + if (!getrusage(RUSAGE_SELF, &newRUsage)) { + XRE_TelemetryAccumulate(mozilla::Telemetry::GLUESTARTUP_HARD_FAULTS, + int(newRUsage.ru_majflt - initialRUsage.ru_majflt)); + } +#endif + } + + int result; + { + ScopedLogging log; + result = do_main(exePath, argc, argv); + } + + XPCOMGlueShutdown(); return result; }