Closed
Bug 104962
Opened 23 years ago
Closed 23 years ago
3 calls to GetWndowsFolder costs 3% of startup
Categories
(Core :: XPCOM, defect)
Tracking
()
RESOLVED
FIXED
mozilla0.9.6
People
(Reporter: dp, Assigned: dougt)
References
Details
(Keywords: perf)
Attachments
(3 files)
1.83 KB,
patch
|
dveditz
:
review+
|
Details | Diff | Splinter Review |
2.36 KB,
patch
|
Details | Diff | Splinter Review | |
3.11 KB,
patch
|
dveditz
:
review+
jband_mozilla
:
superreview+
|
Details | Diff | Splinter Review |
We call GetWindowsFolder() 3 times and this costs 3.3% of startup. Wonder what
they are for and if there are better ways of doing this.
Reporter | ||
Updated•23 years ago
|
Assignee | ||
Comment 1•23 years ago
|
||
wow. 3%?
Do you know what the parameter of these three calls is? Are there more than 3
calls to GetWindowsFolder but only 3 of them take the percentage that you cite?
GetWindowsFolder is a windows system call wrapper that returns well known places
on the users machine. IIRC, we cache the result, so no two requests should ever
be the same. Briefly looking at this code, I quickly get sick. . Reassign and
I will try to fix it up for 9.6.
Reporter | ||
Comment 2•23 years ago
|
||
Thanks dan. Reassigning.
I see only three calls on startup. The calls are:
Application Dir [1]
IE Favouries [2]
- bookmarks code
- file system data source
Assignee: dp → dveditz
Target Milestone: mozilla0.9.7 → ---
Assignee | ||
Comment 3•23 years ago
|
||
(did you see how I offered to help fix this up, but totally avoided the real
work while having it assigned to my coworker. mind control. $9.95 a month.
contact me directly :-) )
Seriously, did you mean to reassign it to me or dan?
Reporter | ||
Comment 4•23 years ago
|
||
To you Mr. Dougt. And now to bed right away before I screwup more.
Assignee: dveditz → dougt
Assignee | ||
Comment 5•23 years ago
|
||
Comment 6•23 years ago
|
||
Comment on attachment 53780 [details] [diff] [review]
proposed patch v.1
>Index: nsSpecialSystemDirectory.cpp
>===================================================================
>+ int len = PL_strlen(path);
>+ if (len>1 && path[len-1] != '\\')
>+ {
>+ path[len] = '\\';
>+ path[len + 1] = '\0';
>+ }
What if Windows filled up the buffer? unlikely, but you could
go over with your slash if it does.
Throw in a "&& len < sizeof path" and r=dveditz
Do we know what locations we're asking for? perhaps part of the
delay is simply firing up the shell32.dll the first time (although
by avoiding it here we might simply be moving the delay elsewhere).
If it's just the windows directory or system directory then special
casing to use GetWindowsDirectory() and GetSystemDirectory()
(which are in the kernel) might speed things up.
Attachment #53780 -
Flags: review+
Assignee | ||
Comment 7•23 years ago
|
||
your right. the string should be allocated MAX_LEN+1
Reporter | ||
Comment 8•23 years ago
|
||
Tested patch and it eliminated the 3% and improved startup by that amount.
Very cool dougt.
Comment 9•23 years ago
|
||
Comment on attachment 53780 [details] [diff] [review]
proposed patch v.1
sr=darin (nice find)
Assignee | ||
Comment 10•23 years ago
|
||
Checking in nsSpecialSystemDirectory.cpp;
/cvsroot/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp,v <--
nsSpecialSystemDirectory.cpp
new revision: 1.46; previous revision: 1.45
done
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Comment 11•23 years ago
|
||
No! SHGetSpecialFolderPath is not present in all target versions of Win32.
See the docs on the function on the MS site.
On NT4 I get a modal dialog from the system telling me that that entry point is
not found in shell32.dll
BACK IT OUT!
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Updated•23 years ago
|
Severity: normal → blocker
Assignee | ||
Comment 12•23 years ago
|
||
crap. you need IE4 to use this SYSTEM api. Ill back it out.
Assignee | ||
Comment 13•23 years ago
|
||
I will dymanically look up this symbol in the next patch.
Assignee | ||
Comment 14•23 years ago
|
||
Backed out:
Checking in nsSpecialSystemDirectory.cpp;
/cvsroot/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp,v <--
nsSpecialSystemDirectory.cpp
new revision: 1.47; previous revision: 1.46
done
Comment 16•23 years ago
|
||
IE4 is not needed but shfolder.dll *is*
a search through MSDN got me here:
"
A-2. Use SHGetFolderPath To Determine Special Folder Paths
Whenever you access any of the special folders in the following list, your
application should use the Win32 APIs to dynamically obtain the proper
language-specific folder names. The preferred way to do this is using the
SHGetFolderPath API with the appropriate CSIDL constant. This function behaves
consistently across Windows 95, Windows 98, Windows NT 4.0, and Windows 2000.
This API is redistributable via the SHFOLDER.DLL. Software vendors are
encouraged to redistribute this component as much as possible to enable this
support on Windows operating systems prior to Windows 2000. Windows 2000
includes this DLL as a protected system file and, as such, this DLL cannot be
replaced on Windows 2000 or greater.
Note To ensure your application can run on Windows 9x, Windows NT 4.0 and
Windows 2000, always link to the SHGetFolderPath implementation in SHFOLDER.DLL.
Windows 2000 natively implements SHGetFolderPath in SHELL32.DLL, but other
versions of Windows do not include SHGetFolderPath in SHELL32.DLL.
"
from:
Specifications,
Application Specification for Microsoft Windows 2000 Server,
Appendix A : Best Practices
"I will dymanically look up this symbol in the next patch"
The symbol should be looked up in shfolder.dll, not shell32.dll
So that this could work on Windows 9x and NT4 if someone decides to redistribute
shfolder.dll
just a minor comment on the source:
version 1.47:
// Get the shell's allocator.
if (!SUCCEEDED(SHGetMalloc(&pMalloc)))
return;
// Allocate a buffer
if ((pBuffer = (LPSTR) pMalloc->Alloc(MAX_PATH + 2)) == NULL)
// XXXXXXXXXX pMalloc should be released here with pMalloc->Release();
return;
Assignee | ||
Comment 18•23 years ago
|
||
Comment 19•23 years ago
|
||
+#if defined (XP_WIN)
+BOOL (WINAPI * getSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath, int
nFolder, BOOL fCreate) = NULL;
+static HINSTANCE gShell32DLLInst = NULL;
+#endif
+NS_COM void StartupSpecialSystemDirectory()
+{
+#if defined (XP_WIN)
+ gShell32DLLInst = LoadLibrary("Shell32.dll");
+ if(gShell32DLLInst)
+ {
+ getSpecialPathProc = (BOOL (WINAPI *) (HWND hwndOwner,
+ LPSTR lpszPath,
+ int nFolder,
+ BOOL fCreate))
+ GetProcAddress(gShell32DLLInst,
"SHGetSpecialFolderPath");
+ }
+#endif
+}
You need a typedef. Even if you were using this type in only one place a typedef
is prettier. But since you use it in two places, it is mandatory in my book. The
param names are not required.
It would be good to add a comment about why this is needed; i.e. that
GetSpecialPath is faster but not available without IE4 (or whatever). I'd
also add a comment after the 'if' block at the end saying that it is falling
back to do the same thing but by different means.
Assignee | ||
Comment 20•23 years ago
|
||
there are no typedefs for similar constructs:
/xpcom/io/nsFileSpecOS2.cpp, line 819
/xpcom/io/nsLocalFileOS2.cpp, line 1694
/xpcom/io/nsFileSpecWin.cpp, line 690
/xpcom/io/nsLocalFileWin.cpp, line 1497
Comment 21•23 years ago
|
||
Personally I'd go with balleysson's suggestion and link with shfolder.dll
instead, and redistribute that .dll in the installer if it's not already present.
Then if you had to you could #if _MSC_VER < 1200 the old slow code to keep old
folks building. Other parts of the build already requires SP3 for VC6 people so
they should be OK.
Comment 22•23 years ago
|
||
dougt: five wrongs don't make a right. You *know* this is lame.
dveditz: I'm OK with linking to a new dll if it is freely redistributable and
easily available. If we go that route then an announcement (with a link to the
dll and how to install it) needs to be posted for developers. And, the
installers need to be updated to do the deed before this change hits the tree
again.
Assignee | ||
Comment 23•23 years ago
|
||
jband: okay. you got me. I am a slacker. I will fix it up. In the meantime,
can you tell me if this work for you?
dveditz: You really want every mozilla windows distribution to have to ship this
library?
Comment 24•23 years ago
|
||
Sure, why not? It's only 20K (compresses to < 8K for distribution), and it's the
right way to do it according to MS. We could make it an optional install like
msvcrt.dll -- if you don't put it in the package the install won't fail, but if
you install on a platform without it then the browser will fail. Distributors
choice. If people can build the damn thing (currently requires MSVC) then they
can redistribute shfolder.dll.
but I don't care much either way. If you prefer doing the GetProcAddress that's
fine, will save 8K on the package size at the cost of some speed for the lookup
and some code bloat for the backup method.
Assignee | ||
Comment 25•23 years ago
|
||
I do not want to have to redistribute libraries.
Comment 26•23 years ago
|
||
You don't have to redistribute libraries (or it should be another bug).
Once this bug is fixed, every mozilla distribution can choose to distribute or
not to distribute shfolder.dll.
But, for this to be possible, please look up the symbol in shfolder.dll, not in
shell32.dll (this is *now* the right thing to do with windows 2000 and XP, and
ther is no need to redistribute anything).
If you want to target other OS like NT4 + IE4 (ie with newer version of
shell32.dll ) then you can look up in shell32.dll when the look up in
shfolder.dll has failed.
this should look like:
NS_COM void StartupSpecialSystemDirectory()
{
#if defined (XP_WIN)
gShell32DLLInst = LoadLibrary("shfolder.dll");
if(gShell32DLLInst)
{
getSpecialPathProc = (BOOL (WINAPI *) (HWND hwndOwner,
LPSTR lpszPath,
int nFolder,
BOOL fCreate))
GetProcAddress(gShell32DLLInst,
"SHGetSpecialFolderPath");
}
if (!getSpecialPathProc)
{
if (gShell32DLLInst)
FreeLibrary(gShell32DLLInst);
gShell32DLLInst = LoadLibrary("shell32.dll");
if(gShell32DLLInst)
{
getSpecialPathProc = (BOOL (WINAPI *) (HWND hwndOwner,
LPSTR lpszPath,
int nFolder,
BOOL fCreate))
GetProcAddress(gShell32DLLInst,
"SHGetSpecialFolderPath");
}
}
#endif
}
you could define the function (SHGetFolderPath) prototype with a typedef
and the code would be clearer
Comment 27•23 years ago
|
||
dougt: FWIW, I no longer have the machine on which this was a problem for me.
So, I can't test for you. But others *do* still care about that platform. Like I
said before... I don't care if there is a new dll requirement as long as the
installers have a handle on the problem and people who build or run
non-installer builds are warned and given clear instructions on where to get the
new dll and how to install it.
Assignee | ||
Comment 28•23 years ago
|
||
(I actually though that you were the last person to have NT without ie4. :-)
Bernard, I will incorporate your suggestion.
Assignee | ||
Comment 29•23 years ago
|
||
Assignee | ||
Updated•23 years ago
|
Target Milestone: --- → mozilla0.9.6
Comment 30•23 years ago
|
||
Comment on attachment 55613 [details] [diff] [review]
another round. v.3
sr=jband
Looks good to me.
I trust that the entry point really can be in one or
the other dll.
I'd probably do a silly loop thing for the two lookups to
avoid repeating code. But this is fine.
comment nit: 'writing' has only one 't'.
Attachment #55613 -
Flags: superreview+
Comment 31•23 years ago
|
||
Comment on attachment 55613 [details] [diff] [review]
another round. v.3
r=dveditz
Attachment #55613 -
Flags: review+
Assignee | ||
Comment 32•23 years ago
|
||
Fix checked in:
Checking in nsSpecialSystemDirectory.cpp;
/cvsroot/mozilla/xpcom/io/nsSpecialSystemDirectory.cpp,v <--
nsSpecialSystemDirectory.cpp
new revision: 1.52; previous revision: 1.51
done
Status: REOPENED → RESOLVED
Closed: 23 years ago → 23 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•