Closed Bug 122892 Opened 23 years ago Closed 22 years ago

nsLocalFile::Clone should preserve stat info

Categories

(Core :: XPCOM, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
Future

People

(Reporter: dougt, Assigned: dougt)

References

(Blocks 1 open bug)

Details

Attachments

(4 files, 2 obsolete files)

A C++ copy construction of "this" is all that really is needed. This will avoid extra stat()'s when they are clearly not needed.
Attached patch Fixes up windows and unix (deleted) — Splinter Review
Apparently the mac already does this.
this should avoid a double stat in (at least) xpcom registration.
Keywords: patch
Target Milestone: --- → mozilla0.9.9
The compiler-generated copy constructor looks fine on the Windows impl - everything should just be copied. On Unix, you might save some cycles by assigning the rest of the fields and then doing: if (mHaveCachedStat) mCachedStat = src.mCachedStat; In other words, save an assignment of a sizable struct if it's not valid. Unless struct stat is massive, r=ccarlen
Comment on attachment 67354 [details] [diff] [review] Fixes up windows and unix r=ccarlen - what I suggested would have little to no benefit.
Attachment #67354 - Flags: review+
Comment on attachment 67354 [details] [diff] [review] Fixes up windows and unix sr=dveditz
Attachment #67354 - Flags: review+ → superreview+
Thanks Checking in nsLocalFileUnix.cpp; /cvsroot/mozilla/xpcom/io/nsLocalFileUnix.cpp,v <-- nsLocalFileUnix.cpp new revision: 1.84; previous revision: 1.83 done Checking in nsLocalFileWin.cpp; /cvsroot/mozilla/xpcom/io/nsLocalFileWin.cpp,v <-- nsLocalFileWin.cpp new revision: 1.76; previous revision: 1.75 done
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
backed out. Checking in nsLocalFileUnix.cpp; /cvsroot/mozilla/xpcom/io/nsLocalFileUnix.cpp,v <-- nsLocalFileUnix.cpp new revision: 1.86; previous revision: 1.85 done Checking in nsLocalFileWin.cpp; /cvsroot/mozilla/xpcom/io/nsLocalFileWin.cpp,v <-- nsLocalFileWin.cpp new revision: 1.77; previous revision: 1.76 done
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
You can't use the default copy constructor, becasue that does a bitwise copy. It copies the char* in teh xpidlcstring, not what the char* points to. See bug 113733, though - don't rely (yet) on xpidlcstring's assignment operator, if you do write your own copy constructor.
Depends on: 113733
Actually, I take that back. I think. Its not bitwise, its memberwise copy by default, and nsLocalFileUnix doesn't contain any non-POD types w/o copy constructors.
No longer depends on: 113733
Sorry, to say, but in addition to any compiler issues, there were some serious problems with the functionality of this patch, at least on Linux. The Linux tinderboxes that were able to compile and run tests were showing some very odd numbers (sharp jump in startup time, page laod time, and a sharp drop in window open time). The problem is that this was trashing the profile. See the attached set of listings in a brand new file, after creating, running, quitting, running, quitting, on Linux, without and then with this patch (and darin's bustage tweak). Most notably, with the patch, the Cache folder becomes something called "Cache.Trash" and eventually is deleted, the chrome/ directory gets nuked, XUL.mfasl is always corrupt, and various other files are wrong. Here's the ending state of a profile after running with the patch (this doesn't include damage to mailnews files/dirs that are also not treated well). with the patch (after create/run/quit/run/quit) ... ... and the same, without the patch ??? 4096 00:58 Cache/ 15918 01:03 XUL.mfasl 553519 00:58 XUL.mfasl 5225 01:04 bookmarks.html 5225 00:58 bookmarks.html ??? 4096 00:57 chrome/ 639 01:04 history.dat 639 00:58 history.dat 5666 01:04 localstore.rdf 5666 00:58 localstore.rdf ??? 287 00:57 mimeTypes.rdf 2169 01:03 panels.rdf 2169 00:57 panels.rdf 206 01:04 prefs.js 206 00:58 prefs.js ??? 2335 00:57 search.rdf
> in a brand new file with a brand new profile
Keywords: nsbeta1+
not going to happen yet. so that I don't have to write a copy constructor, I am going to wait until 113733 is fixed.
Depends on: 113733
Target Milestone: mozilla0.9.9 → ---
Gagan, I do not think that this is nsbeta1+.
Target Milestone: --- → mozilla1.1
Whiteboard: [adt2]
I thought you convinced me that this needed a plus! :) alright taking it out...
Keywords: nsbeta1+
Whiteboard: [adt2]
Target Milestone: mozilla1.1alpha → Future
When this is fixed, we can clean up the code & comments at http://lxr.mozilla.org/seamonkey/source/netwerk/base/src/nsStandardURL.cpp#2178.
Actually - we can fix this now (irrelevant of the XPIDLString copy constructor), since darin changed the nsLocalFile* impls to use nsCStrings instead of XPIDLStrings quite a while ago. In addition, I think we _do_ need to write our own copy constructor, rather than letting the compiler synthesize it - we do _not_ want to copy the mRefCnt member. (We could use the synthesized copy ctor and then manually reset mRefCnt to zero, but I think that looks hackish, and the end result (in compiled code) will be worse). (We could also use this for the ::InitWithFile(nsILocalFile*) impl, i.e. have an operator=(const nsLocalFile&), but that would rely on being able to cast an nsILocalFile to an nsLocalFile{Unix,Win,..}. I'm not sure that's a good thing to do, so I'll leave that the way it is for now, but comments are welcome. Note that nsLocalFileMac does this at the moment, using dynamic_cast.) So, with that said... patch coming up to convert all the nsLocalFile*::Clone() methods to use a copy constructor.
Attached patch use copy constructors v1 (deleted) — Splinter Review
and here it is. dougt, mind taking a look if you have some time? thx!
Attachment #127437 - Flags: review?(dougt)
Comment on attachment 127437 [details] [diff] [review] use copy constructors v1 this looks fine, but i remember some problems in using a copy constructor on certian platforms -- that is why these copy constructors are not implemented on all platforms. Before you land this, please verify that everything continues to function as expected. :-)
Attachment #127437 - Flags: review?(dougt) → review+
Thanks - will do. (Your r= is sufficient for xpcom, right? No need to get sr?) darin, dougt: do you have any opinion on comment 16 paragraph 3? If we can make the assumption that an nsILocalFile can be cast to the platform-specific nsLocalFile we're dealing with, then we can optimize that a little bit too. I'd also like to evaluate using nsSharableStrings for the members of nsLocalFile*, instead of plain old CStrings, since ::Clone() is probably a fairly common operation (e.g. when an interface has an nsIFile attribute, with a getter and setter for it). This might save on allocations... (nsFileSpec does this.)
I would not advise assuming nsILocalFile's are implemented by some standard concrete class.
Sounds good to me. :)
Comment on attachment 127437 [details] [diff] [review] use copy constructors v1 >Index: xpcom/io/nsLocalFileMac.cpp > nsLocalFile::Clone(nsIFile **file) > { >+ NS_ENSURE_ARG_POINTER(file); NS_ASSERTION should be sufficient, since it would be really bogus to call this with a null pointer. same goes for other Clone impls. >Index: xpcom/io/nsLocalFileOS2.cpp >+nsLocalFile::nsLocalFile(const nsLocalFile& other) w.r.t. dougt's comment about copy ctor.. may be good to check with mkaply to make sure OS/2 is going to be happy with this. sr=darin fwiw ;)
Attachment #127437 - Flags: superreview+
>I'd also like to evaluate using nsSharableStrings for the members of >nsLocalFile*, instead of plain old CStrings, since ::Clone() is probably a >fairly common operation (e.g. when an interface has an nsIFile attribute, with a >getter and setter for it). This might save on allocations... (nsFileSpec does >this.) i'm not sure that you can do this since a clone of a nsIFile instance might be accessed on a different thread (indeed this does happen in necko). deep copying is probably correct since nsLocalFile implements threadsafe addref/release.
> >+ NS_ENSURE_ARG_POINTER(file); > > NS_ASSERTION should be sufficient, since it would be really bogus > to call this with a null pointer. same goes for other Clone impls. Don't even bother -- a null dereference is as good as an assertbotch (unless you are of the evil school who wants assertions that don't abort, which means you want lots of bogus assertions, which is what you will get in any large project where assertions don't abort). /be
>Don't even bother yes! even better :)
>i'm not sure that you can do this since a clone of a nsIFile instance might be >accessed on a different thread (indeed this does happen in necko). deep copying >is probably correct since nsLocalFile implements threadsafe addref/release. Very good point... I'll leave that part alone, then :) mkaply: per darin's suggestion, could I ask you to take a look at the copy constructor patch and see if that'll break stuff for OS/2? If you can test (or know of someone who could test), that would be really great too...
Attached patch make nsStandardURL use nsIFile::Clone() (obsolete) (deleted) — Splinter Review
this fixes the XXX comment in nsStandardURL.cpp, so we cache the file and clone it. I've tested the copy-constructor patch as well as this; it looks okay to me on linux, no idea about other plats yet. :)
Attachment #127607 - Flags: superreview?(darin)
dan: it might be nice to get some usage stats on how often nsStandardURL::mFile is reused. while you're patch makes it so that reuse is faster, the first call to GetFile is now more expensive. is that worth it?
Sure thing. On browser startup, nsStandardURL::GetFile() is called ~43 times. On a stock trunk, all of these 43 times result in the spec being parsed out from the file (i.e. there are no ::SetFile() calls involved here; that's not a common codepath it seems). With my patch, 26 calls result in parses, and for the remaining 17 we already have the result and clone it. On my P3-550/linux, parsing takes 200-300us and cloning takes <10us. So we'll save around 4-5ms Ts here. (::GetFile and ::SetFile are not called very often on pageload.) That said, there's a problem with my patch... we only clone the first time we parse, and not each time we hand the file out. The old code was inconsistent; it'd hand out a file given to it by ::SetFile() without cloning it, but then it'd be paranoid and not cache a parsed result. Since cloning is cheap, I think we should just clone everything we hand out. Or we could fix the callers that try to modify it. Personally, I think we should not rely on callers being sane, and just clone everything coming in/going out (SetFile/GetFile). Note that the .idl disagrees with me here: http://lxr.mozilla.org/seamonkey/source/netwerk/base/public/nsIFileURL.idl#56
Attachment #127607 - Flags: superreview?(darin)
Attached patch fix nsStandardURL, v2 (obsolete) (deleted) — Splinter Review
now with consistent clonage.
Attachment #127607 - Attachment is obsolete: true
dan: the point of the IDL comment is to try to optimize GetFile since that is the common operation. cloning is not zero cost, so if we can avoid it that'd be a good thing. i can understand changing the implementation to always Clone since that helps you avoid having to fix bugs like bug 161921, but i don't think it means that the interface comments are bad... maybe they're just idealistic. if only we had a way to construct an immutable nsLocalFile ;-) btw: have you checked to see if bug 161921 still exists if you always just hand back mFile? if it does, then i think this patch should include a XXX comment stating that we are still trying to workaround problems in the browser that prevent us from implementing the interface contract.
>dan: the point of the IDL comment is to try to optimize GetFile since that is >the common operation. yeah... it would be best if we could fix 161921 and actually have consumers that obey the idl :) >btw: have you checked to see if bug 161921 still exists if you always just hand >back mFile? sure... it's a little more risky, but i'll go check that out.
Blocks: 212724
Attached patch fix nsStandardURL, v2.01 (deleted) — Splinter Review
so I talked with darin, and he's okay with just putting a comment in there about consumers, and looking at checking them all later... I filed bug 212724 about that, and added a comment about it. (I think it'll take a bit of time to check all the consumers by hand, and it's not just as simple as seeing if bug 161921 still exists if we don't clone, so...)
Attachment #127655 - Attachment is obsolete: true
ergh... and before you nit that patch, just assume I've shifted that |nsresult rv;| inside the |if| block where it's actually used. :)
I tested this patch on windows 2000, and it seems to work fine
OS: Windows 2000 → All
Hardware: PC → All
This isn't working on OS/2. Opening the pref file is failing because mResolvedPath is empty in the call to PR_Open in OpenNSPRFileDesc. mWorkingPath is valid, so the nsLocalFile is not bad.
I was wrong on the OS/2 stuff. I needed to grab some trunk stuff. Better results tomorrow.
Attachment #127782 - Flags: superreview?(darin)
Comment on attachment 127782 [details] [diff] [review] fix nsStandardURL, v2.01 looks good, thanks! sr=darin
Attachment #127782 - Flags: superreview?(darin) → superreview+
Comment on attachment 127782 [details] [diff] [review] fix nsStandardURL, v2.01 Andreas, would you mind taking a look at this patch? thx!
Attachment #127782 - Flags: review?(andreas.otte)
Comment on attachment 127782 [details] [diff] [review] fix nsStandardURL, v2.01 looks good to me too
Attachment #127782 - Flags: review?(andreas.otte) → review+
thanks for the reviews/testing!... marking fixed (both the localfile patch and the standardurl patch have been checked in)
Status: REOPENED → RESOLVED
Closed: 23 years ago22 years ago
Resolution: --- → FIXED
Ts dropped on luna by 6ms with the standardurl patch - a whopping 0.2% ;)
I now believe that this patch was a mistake. See discussion in bug 307815 and bug 307429. Caching stat buffers is a real big hack that results in a variety of workaround hacks. The ability to dump the cache by cloning a nsIFile is nice. The alternative is to create a new nsIFile and initialize it via initWithFile, but that is more work for consumers. It would seem to be exactly what clone was designed to provide, so we should make it work consistently with initWithFile.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: