From 9a5a4709e2e52984faccc01f32b0e9df9b409e94 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 28 Sep 2011 09:25:52 +0100 Subject: [PATCH 01/65] Bug 689037 - Remove unused layout/tools/layout-debug/makefiles.sh; r=khuey --- layout/tools/layout-debug/makefiles.sh | 43 -------------------------- 1 file changed, 43 deletions(-) delete mode 100755 layout/tools/layout-debug/makefiles.sh diff --git a/layout/tools/layout-debug/makefiles.sh b/layout/tools/layout-debug/makefiles.sh deleted file mode 100755 index 3e0318ad1298..000000000000 --- a/layout/tools/layout-debug/makefiles.sh +++ /dev/null @@ -1,43 +0,0 @@ -#! /bin/sh -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is Mozilla Build System -# -# The Initial Developer of the Original Code is -# Ben Turner -# -# Portions created by the Initial Developer are Copyright (C) 2007 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -add_makefiles " - layout/tools/layout-debug/Makefile - layout/tools/layout-debug/src/Makefile - layout/tools/layout-debug/ui/Makefile -" From 64618cc93b45ca16d409783e9991ef8be62425ba Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 28 Sep 2011 09:26:05 +0100 Subject: [PATCH 02/65] Bug 689043 - Add missing makefiles to xulrunner/makefiles.sh; r=khuey --- xulrunner/makefiles.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/xulrunner/makefiles.sh b/xulrunner/makefiles.sh index f2faaec8f743..65b522b3b496 100644 --- a/xulrunner/makefiles.sh +++ b/xulrunner/makefiles.sh @@ -42,6 +42,30 @@ xulrunner/app/Makefile xulrunner/app/profile/Makefile xulrunner/app/profile/chrome/Makefile xulrunner/app/profile/extensions/Makefile +xulrunner/examples/Makefile +xulrunner/examples/simple/Makefile +xulrunner/examples/simple/components/Makefile +xulrunner/examples/simple/components/public/Makefile +xulrunner/examples/simple/components/src/Makefile +xulrunner/setup/Makefile +xulrunner/stub/Makefile xulrunner/installer/Makefile -xulrunner/installer/mac/Makefile " + +if [ "$OS_ARCH" = "WINNT" -a "$MOZ_INSTALLER" ]; then + add_makefiles " + xulrunner/installer/windows/Makefile + " +fi + +if [ "$OS_ARCH" = "Darwin" ]; then + add_makefiles " + xulrunner/installer/mac/Makefile + " +fi + +if [ "$OS_ARCH" = "WINNT" ]; then + add_makefiles " + xulrunner/tools/redit/Makefile + " +fi From 203a48e7acca3bb6360579d5ca220f6931d0a6ac Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 28 Sep 2011 09:26:24 +0100 Subject: [PATCH 03/65] Bug 689040 - Add missing makefiles to services/makefiles.sh & move tests inside ENABLE_TESTS conditional; r=khuey --- services/makefiles.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/makefiles.sh b/services/makefiles.sh index 7eceecaf0db5..be73919ced11 100644 --- a/services/makefiles.sh +++ b/services/makefiles.sh @@ -42,9 +42,13 @@ MAKEFILES_crypto=" MAKEFILES_sync=" services/sync/Makefile services/sync/locales/Makefile - services/sync/tests/Makefile " +if [ "$ENABLE_TESTS" ]; then + MAKEFILES_crypto="$MAKEFILES_crypto services/crypto/tests/Makefile" + MAKEFILES_sync="$MAKEFILES_sync services/sync/tests/Makefile" +fi + add_makefiles " services/Makefile $MAKEFILES_crypto From 3b7f457af881ede26d3bdcbae91fd062511ef0b0 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Wed, 28 Sep 2011 09:26:46 +0100 Subject: [PATCH 04/65] Bug 689036 - Collapse redundant Makefiles in extensions/pref/ & fix missing in makefiles.sh; r=khuey --- extensions/pref/Makefile.in | 2 +- extensions/pref/makefiles.sh | 8 +++- extensions/pref/system-pref/Makefile.in | 47 --------------------- extensions/pref/system-pref/src/Makefile.in | 5 --- 4 files changed, 8 insertions(+), 54 deletions(-) delete mode 100644 extensions/pref/system-pref/Makefile.in diff --git a/extensions/pref/Makefile.in b/extensions/pref/Makefile.in index 6a23c7590457..d83319ed3e56 100644 --- a/extensions/pref/Makefile.in +++ b/extensions/pref/Makefile.in @@ -46,7 +46,7 @@ include $(DEPTH)/config/autoconf.mk DIRS = autoconfig ifdef MOZ_ENABLE_GTK2 -DIRS += system-pref +DIRS += system-pref/src endif include $(topsrcdir)/config/rules.mk diff --git a/extensions/pref/makefiles.sh b/extensions/pref/makefiles.sh index dfbd120af76b..7e8679b0cc14 100755 --- a/extensions/pref/makefiles.sh +++ b/extensions/pref/makefiles.sh @@ -41,5 +41,11 @@ add_makefiles " extensions/pref/autoconfig/Makefile extensions/pref/autoconfig/public/Makefile extensions/pref/autoconfig/src/Makefile - extensions/pref/autoconfig/resources/Makefile " + +if [ "$MOZ_ENABLE_GTK2" ]; then + add_makefiles " + extensions/pref/system-pref/src/Makefile + extensions/pref/system-pref/src/gconf/Makefile + " +fi diff --git a/extensions/pref/system-pref/Makefile.in b/extensions/pref/system-pref/Makefile.in deleted file mode 100644 index 77ed7ba2cded..000000000000 --- a/extensions/pref/system-pref/Makefile.in +++ /dev/null @@ -1,47 +0,0 @@ -# ***** BEGIN LICENSE BLOCK ***** -# Version: MPL 1.1/GPL 2.0/LGPL 2.1 -# -# The contents of this file are subject to the Mozilla Public License Version -# 1.1 (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# http://www.mozilla.org/MPL/ -# -# Software distributed under the License is distributed on an "AS IS" basis, -# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License -# for the specific language governing rights and limitations under the -# License. -# -# The Original Code is mozilla.org code. -# -# The Initial Developer of the Original Code is -# Sun Microsystems, Inc. -# Portions created by the Initial Developer are Copyright (C) 2003 -# the Initial Developer. All Rights Reserved. -# -# Contributor(s): -# Bolian Yin -# -# Alternatively, the contents of this file may be used under the terms of -# either the GNU General Public License Version 2 or later (the "GPL"), or -# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), -# in which case the provisions of the GPL or the LGPL are applicable instead -# of those above. If you wish to allow use of your version of this file only -# under the terms of either the GPL or the LGPL, and not to allow others to -# use your version of this file under the terms of the MPL, indicate your -# decision by deleting the provisions above and replace them with the notice -# and other provisions required by the GPL or the LGPL. If you do not delete -# the provisions above, a recipient may use your version of this file under -# the terms of any one of the MPL, the GPL or the LGPL. -# -# ***** END LICENSE BLOCK ***** - -DEPTH = ../../.. -topsrcdir = @top_srcdir@ -srcdir = @srcdir@ -VPATH = @srcdir@ - -include $(DEPTH)/config/autoconf.mk - -DIRS = src - -include $(topsrcdir)/config/rules.mk diff --git a/extensions/pref/system-pref/src/Makefile.in b/extensions/pref/system-pref/src/Makefile.in index 75053dc36def..499d65f2ae36 100644 --- a/extensions/pref/system-pref/src/Makefile.in +++ b/extensions/pref/system-pref/src/Makefile.in @@ -50,10 +50,7 @@ SHORT_LIBNAME = syspref FORCE_STATIC_LIB = 1 LIBXUL_LIBRARY = 1 - -ifdef MOZ_ENABLE_GTK2 DIRS = gconf -endif CPPSRCS = \ nsSystemPref.cpp \ @@ -65,8 +62,6 @@ EXPORTS = \ include $(topsrcdir)/config/rules.mk -ifdef MOZ_ENABLE_GTK2 INCLUDES += \ -I$(srcdir)/gconf \ $(NULL) -endif From c8c23518fe85fcb208635f7c1c01e4cd290ea0d6 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Wed, 28 Sep 2011 10:31:01 +0200 Subject: [PATCH 05/65] Bug 688044 - ASSERTION: Why is the root in mDirtyRoots already? r=bzbarsky --- layout/base/nsPresShell.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index e0bab0f40343..e13fbd347d48 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1962,18 +1962,19 @@ PresShell::InitialReflow(nscoord aWidth, nscoord aHeight) NS_ASSERTION(rootFrame, "How did that happen?"); - // Note: Because the frame just got created, it has the NS_FRAME_IS_DIRTY - // bit set. Unset it so that FrameNeedsReflow() will work right. - NS_ASSERTION(!mDirtyRoots.Contains(rootFrame), - "Why is the root in mDirtyRoots already?"); - - rootFrame->RemoveStateBits(NS_FRAME_IS_DIRTY | - NS_FRAME_HAS_DIRTY_CHILDREN); - FrameNeedsReflow(rootFrame, eResize, NS_FRAME_IS_DIRTY); - - NS_ASSERTION(mDirtyRoots.Contains(rootFrame), - "Should be in mDirtyRoots now"); - NS_ASSERTION(mReflowScheduled, "Why no reflow scheduled?"); + // Note: when the frame was created above it had the NS_FRAME_IS_DIRTY bit + // set, but XBL processing could have caused a reflow which clears it. + if (NS_LIKELY(rootFrame->GetStateBits() & NS_FRAME_IS_DIRTY)) { + // Unset the DIRTY bits so that FrameNeedsReflow() will work right. + rootFrame->RemoveStateBits(NS_FRAME_IS_DIRTY | + NS_FRAME_HAS_DIRTY_CHILDREN); + NS_ASSERTION(!mDirtyRoots.Contains(rootFrame), + "Why is the root in mDirtyRoots already?"); + FrameNeedsReflow(rootFrame, eResize, NS_FRAME_IS_DIRTY); + NS_ASSERTION(mDirtyRoots.Contains(rootFrame), + "Should be in mDirtyRoots now"); + NS_ASSERTION(mReflowScheduled, "Why no reflow scheduled?"); + } // Restore our root scroll position now if we're getting here after EndLoad // got called, since this is our one chance to do it. Note that we need not From f3238fadd707585906e978b8105b422ab4ca14e9 Mon Sep 17 00:00:00 2001 From: Chris Leary Date: Thu, 22 Sep 2011 15:13:36 -0700 Subject: [PATCH 06/65] Bug 684039: Don't use JSArenaPool in nsJSEnvironment. (r=mrbkap) --HG-- extra : rebase_source : 63c16359271389509b7fc118a3d55c965eb8a931 --- dom/base/nsJSEnvironment.cpp | 64 ++++++++++++++++++++---------------- dom/base/nsJSEnvironment.h | 5 ++- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 0649a7b41bc7..cef6c4a0e44c 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -199,6 +199,33 @@ nsMemoryPressureObserver::Observe(nsISupports* aSubject, const char* aTopic, return NS_OK; } +class nsRootedJSValueArray { +public: + explicit nsRootedJSValueArray(JSContext *cx) : avr(cx, vals.Length(), vals.Elements()) {} + + PRBool SetCapacity(JSContext *cx, size_t capacity) { + PRBool ok = vals.SetCapacity(capacity); + if (!ok) + return PR_FALSE; + // Values must be safe for the GC to inspect (they must not contain garbage). + memset(vals.Elements(), 0, vals.Capacity() * sizeof(jsval)); + resetRooter(cx); + return PR_TRUE; + } + + jsval *Elements() { + return vals.Elements(); + } + +private: + void resetRooter(JSContext *cx) { + avr.changeArray(vals.Elements(), vals.Length()); + } + + nsAutoTArray vals; + js::AutoArrayRooter avr; +}; + /**************************************************************** ************************** AutoFree **************************** ****************************************************************/ @@ -218,15 +245,6 @@ private: void *mPtr; }; -class nsAutoPoolRelease { -public: - nsAutoPoolRelease(JSArenaPool *p, void *m) : mPool(p), mMark(m) {} - ~nsAutoPoolRelease() { JS_ARENA_RELEASE(mPool, mMark); } -private: - JSArenaPool *mPool; - void *mMark; -}; - // A utility function for script languages to call. Although it looks small, // the use of nsIDocShell and nsPresContext triggers a huge number of // dependencies that most languages would not otherwise need. @@ -1912,16 +1930,14 @@ nsJSContext::CallEventHandler(nsISupports* aTarget, void *aScope, void *aHandler return NS_ERROR_FAILURE; } - Maybe poolRelease; - Maybe tvr; + Maybe tempStorage; // Use |target| as the scope for wrapping the arguments, since aScope is // the safe scope in many cases, which isn't very useful. Wrapping aTarget // was OK because those typically have PreCreate methods that give them the // right scope anyway, and we want to make sure that the arguments end up // in the same scope as aTarget. - rv = ConvertSupportsTojsvals(aargv, target, &argc, - &argv, poolRelease, tvr); + rv = ConvertSupportsTojsvals(aargv, target, &argc, &argv, tempStorage); NS_ENSURE_SUCCESS(rv, rv); ++mExecuteDepth; @@ -2343,12 +2359,10 @@ nsJSContext::SetProperty(void *aTarget, const char *aPropName, nsISupports *aArg JSAutoRequest ar(mContext); - Maybe poolRelease; - Maybe tvr; + Maybe tempStorage; nsresult rv; - rv = ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc, - &argv, poolRelease, tvr); + rv = ConvertSupportsTojsvals(aArgs, GetNativeGlobal(), &argc, &argv, tempStorage); NS_ENSURE_SUCCESS(rv, rv); jsval vargs; @@ -2384,8 +2398,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs, void *aScope, PRUint32 *aArgc, jsval **aArgv, - Maybe &aPoolRelease, - Maybe &aRooter) + Maybe &aTempStorage) { nsresult rv = NS_OK; @@ -2420,16 +2433,11 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs, argCount = 1; // the nsISupports which is not an array } - void *mark = JS_ARENA_MARK(&mContext->tempPool); - jsval *argv; - size_t nbytes = argCount * sizeof(jsval); - JS_ARENA_ALLOCATE_CAST(argv, jsval *, &mContext->tempPool, nbytes); - NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY); - memset(argv, 0, nbytes); /* initialize so GC-able */ - // Use the caller's auto guards to release and unroot. - aPoolRelease.construct(&mContext->tempPool, mark); - aRooter.construct(mContext, argCount, argv); + aTempStorage.construct(mContext); + PRBool ok = aTempStorage.ref().SetCapacity(mContext, argCount); + NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY); + jsval *argv = aTempStorage.ref().Elements(); if (argsArray) { for (argCtr = 0; argCtr < argCount && NS_SUCCEEDED(rv); argCtr++) { diff --git a/dom/base/nsJSEnvironment.h b/dom/base/nsJSEnvironment.h index 54434ee0dfed..7ce9a377d085 100644 --- a/dom/base/nsJSEnvironment.h +++ b/dom/base/nsJSEnvironment.h @@ -48,7 +48,7 @@ #include "nsScriptNameSpaceManager.h" class nsIXPConnectJSObjectHolder; -class nsAutoPoolRelease; +class nsRootedJSValueArray; namespace js { class AutoArrayRooter; } @@ -204,8 +204,7 @@ protected: void *aScope, PRUint32 *aArgc, jsval **aArgv, - mozilla::Maybe &aPoolRelease, - mozilla::Maybe &aRooter); + mozilla::Maybe &aPoolRelease); nsresult AddSupportsPrimitiveTojsvals(nsISupports *aArg, jsval *aArgv); From 3b3f1cf4c7329a01c0e824ab7778af34dcc69d51 Mon Sep 17 00:00:00 2001 From: Chris Leary Date: Thu, 22 Sep 2011 13:22:30 -0700 Subject: [PATCH 07/65] Bug 684039: rewrite JS LIFO allocator, avoids thrashing. (r=luke) --HG-- rename : js/src/jsarena.h => js/src/ds/LifoAlloc.h extra : rebase_source : 098bf9561114f82363ebd0862213acf952709257 --- caps/src/nsScriptSecurityManager.cpp | 1 - js/src/Makefile.in | 9 +- js/src/ds/LifoAlloc.cpp | 149 ++++++++++++ js/src/ds/LifoAlloc.h | 335 +++++++++++++++++++++++++++ js/src/frontend/ParseMaps.cpp | 6 +- js/src/jsanalyze.cpp | 60 +++-- js/src/jsanalyze.h | 21 +- js/src/jsapi.cpp | 10 +- js/src/jsarena.h | 317 ------------------------- js/src/jscntxt.cpp | 27 +-- js/src/jscntxt.h | 38 +-- js/src/jscntxtinlines.h | 6 + js/src/jscompartment.cpp | 13 +- js/src/jscompartment.h | 3 +- js/src/jsdbgapi.cpp | 11 +- js/src/jsemit.cpp | 13 +- js/src/jsemit.h | 8 +- js/src/jsfun.cpp | 4 +- js/src/jsinfer.cpp | 101 ++++---- js/src/jsinfer.h | 15 +- js/src/jsinferinlines.h | 6 +- js/src/jsinterp.cpp | 1 - js/src/jsiter.cpp | 1 - js/src/jsobj.cpp | 1 - js/src/json.cpp | 1 - js/src/jsopcode.cpp | 98 +++----- js/src/jsopcode.h | 3 +- js/src/jsparse.cpp | 16 +- js/src/jsprvtd.h | 24 ++ js/src/jsregexpinlines.h | 29 +-- js/src/jsscan.cpp | 1 - js/src/jsscope.cpp | 1 - js/src/jsscript.cpp | 13 +- js/src/jsscript.h | 2 - js/src/jstl.h | 3 +- js/src/jstracer.cpp | 10 +- js/src/jsutil.h | 2 + js/src/methodjit/Compiler.cpp | 7 +- js/src/methodjit/FrameState.cpp | 4 +- js/src/methodjit/LoopState.cpp | 2 +- js/src/shell/js.cpp | 36 ++- mfbt/Util.h | 3 + 42 files changed, 724 insertions(+), 687 deletions(-) create mode 100644 js/src/ds/LifoAlloc.cpp create mode 100644 js/src/ds/LifoAlloc.h delete mode 100644 js/src/jsarena.h diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index 461545a8b206..70121998a0ce 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -59,7 +59,6 @@ #include "nsDOMError.h" #include "nsDOMCID.h" #include "jsdbgapi.h" -#include "jsarena.h" #include "jsfun.h" #include "jsobj.h" #include "nsIXPConnect.h" diff --git a/js/src/Makefile.in b/js/src/Makefile.in index b0fd3b5dfdc5..c595fa336073 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -101,7 +101,6 @@ CPPSRCS = \ jsalloc.cpp \ jsanalyze.cpp \ jsapi.cpp \ - jsarena.cpp \ jsarray.cpp \ jsatom.cpp \ jsbool.cpp \ @@ -161,6 +160,7 @@ CPPSRCS = \ Stack.cpp \ String.cpp \ ParseMaps.cpp \ + LifoAlloc.cpp \ Unicode.cpp \ $(NULL) @@ -174,7 +174,6 @@ INSTALLED_HEADERS = \ js.msg \ jsalloc.h \ jsapi.h \ - jsarena.h \ jsatom.h \ jsbit.h \ jsclass.h \ @@ -241,9 +240,10 @@ INSTALLED_HEADERS = \ VPATH += \ $(srcdir)/vm \ $(srcdir)/frontend \ + $(srcdir)/ds \ $(NULL) -EXPORTS_NAMESPACES = vm +EXPORTS_NAMESPACES = vm ds EXPORTS_vm = \ ArgumentsObject.h \ @@ -255,6 +255,9 @@ EXPORTS_vm = \ Unicode.h \ $(NULL) +EXPORTS_ds = \ + LifoAlloc.h + ############################################### # BEGIN include sources for low-level code shared with Gecko # diff --git a/js/src/ds/LifoAlloc.cpp b/js/src/ds/LifoAlloc.cpp new file mode 100644 index 000000000000..94b8442d20db --- /dev/null +++ b/js/src/ds/LifoAlloc.cpp @@ -0,0 +1,149 @@ +#include "LifoAlloc.h" + +#include + +using namespace js; + +namespace js { +namespace detail { + +BumpChunk * +BumpChunk::new_(size_t chunkSize) +{ + JS_ASSERT(RoundUpPow2(chunkSize) == chunkSize); + void *mem = js_malloc(chunkSize); + if (!mem) + return NULL; + BumpChunk *result = new (mem) BumpChunk(chunkSize - sizeof(BumpChunk)); + + /* + * We assume that the alignment of sAlign is less than that of + * the underlying memory allocator -- creating a new BumpChunk should + * always satisfy the sAlign alignment constraint. + */ + JS_ASSERT(AlignPtr(result->bump) == result->bump); + return result; +} + +void * +BumpChunk::tryAllocUnaligned(size_t n) +{ + char *oldBump = bump; + char *newBump = bump + n; + if (newBump > limit) + return NULL; + + setBump(newBump); + return oldBump; +} + +} /* namespace detail */ +} /* namespace js */ + +void +LifoAlloc::freeAll() +{ + while (first) { + BumpChunk *victim = first; + first = first->next(); + BumpChunk::delete_(victim); + } + first = latest = NULL; +} + +void +LifoAlloc::freeUnused() +{ + /* Don't free anything if we have outstanding marks. */ + if (markCount || !first) + return; + + JS_ASSERT(first && latest); + + /* Rewind through any unused chunks. */ + if (!latest->used()) { + BumpChunk *lastUsed = NULL; + for (BumpChunk *it = first; it != latest; it = it->next()) { + if (it->used()) + lastUsed = it; + } + if (!lastUsed) { + freeAll(); + return; + } + latest = lastUsed; + } + + /* Free all chunks after |latest|. */ + size_t freed = 0; + for (BumpChunk *victim = latest->next(); victim; victim = victim->next()) { + BumpChunk::delete_(victim); + freed++; + } +} + +LifoAlloc::BumpChunk * +LifoAlloc::getOrCreateChunk(size_t n) +{ + if (first) { + /* Look for existing, unused BumpChunks to satisfy the request. */ + while (latest->next()) { + latest = latest->next(); + latest->resetBump(); /* This was an unused BumpChunk on the chain. */ + if (latest->canAlloc(n)) + return latest; + } + } + + size_t defaultChunkFreeSpace = defaultChunkSize_ - sizeof(BumpChunk); + size_t chunkSize = n > defaultChunkFreeSpace + ? RoundUpPow2(n + sizeof(BumpChunk)) + : defaultChunkSize_; + + /* If we get here, we couldn't find an existing BumpChunk to fill the request. */ + BumpChunk *newChunk = BumpChunk::new_(chunkSize); + if (!newChunk) + return NULL; + if (!first) { + latest = first = newChunk; + } else { + JS_ASSERT(latest && !latest->next()); + latest->setNext(newChunk); + latest = newChunk; + } + return newChunk; +} + +void * +LifoAlloc::allocUnaligned(size_t n) +{ + void *result; + if (latest && (result = latest->tryAllocUnaligned(n))) + return result; + + return alloc(n); +} + +void * +LifoAlloc::reallocUnaligned(void *origPtr, size_t origSize, size_t incr) +{ + JS_ASSERT(first && latest); + + /* + * Maybe we can grow the latest allocation in a BumpChunk. + * + * Note: we could also realloc the whole BumpChunk in the !canAlloc + * case, but this should not be a frequently hit case. + */ + if (latest + && origPtr == (char *) latest->mark() - origSize + && latest->canAllocUnaligned(incr)) { + JS_ALWAYS_TRUE(allocUnaligned(incr)); + return origPtr; + } + + /* Otherwise, memcpy. */ + size_t newSize = origSize + incr; + void *newPtr = allocUnaligned(newSize); + return newPtr ? memcpy(newPtr, origPtr, origSize) : NULL; +} diff --git a/js/src/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h new file mode 100644 index 000000000000..feed4526ea10 --- /dev/null +++ b/js/src/ds/LifoAlloc.h @@ -0,0 +1,335 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sw=4 et tw=99 ft=cpp: + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released + * June 12, 2009. + * + * The Initial Developer of the Original Code is + * the Mozilla Corporation. + * + * Contributor(s): + * Chris Leary + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef LifoAlloc_h__ +#define LifoAlloc_h__ + +/* + * This data structure supports stacky LIFO allocation (mark/release and + * LifoAllocScope). It does not maintain one contiguous segment; instead, it + * maintains a bunch of linked memory segments. In order to prevent malloc/free + * thrashing, unused segments are deallocated when garbage collection occurs. + */ + +#include "jsutil.h" +#include "jstl.h" + +namespace js { + +namespace detail { + +static const size_t LIFO_ALLOC_ALIGN = 8; + +JS_ALWAYS_INLINE +char * +AlignPtr(void *orig) +{ + typedef tl::StaticAssert< + tl::FloorLog2::result == tl::CeilingLog2::result + >::result _; + + char *result = (char *) ((uintptr_t(orig) + (LIFO_ALLOC_ALIGN - 1)) & -LIFO_ALLOC_ALIGN); + JS_ASSERT(uintptr_t(result) % LIFO_ALLOC_ALIGN == 0); + return result; +} + +/* Header for a chunk of memory wrangled by the LifoAlloc. */ +class BumpChunk +{ + char *bump; + char *limit; + BumpChunk *next_; + size_t bumpSpaceSize; + + char *base() const { return limit - bumpSpaceSize; } + + explicit BumpChunk(size_t bumpSpaceSize) + : bump(reinterpret_cast(this) + sizeof(BumpChunk)), limit(bump + bumpSpaceSize), + next_(NULL), bumpSpaceSize(bumpSpaceSize) { + JS_ASSERT(bump == AlignPtr(bump)); + } + + void clobberUnused() { +#ifdef DEBUG + memset(bump, 0xcd, limit - bump); +#endif + } + + void setBump(void *ptr) { + JS_ASSERT(base() <= ptr); + JS_ASSERT(ptr <= limit); + DebugOnly prevBump = bump; + bump = static_cast(ptr); + if (prevBump < bump) + clobberUnused(); + } + + public: + BumpChunk *next() const { return next_; } + void setNext(BumpChunk *succ) { next_ = succ; } + + size_t used() const { return bump - base(); } + + void resetBump() { + setBump(reinterpret_cast(this) + sizeof(BumpChunk)); + } + + void *mark() const { return bump; } + + void release(void *mark) { + JS_ASSERT(contains(mark)); + JS_ASSERT(mark <= bump); + setBump(mark); + } + + bool contains(void *mark) const { + return base() <= mark && mark <= limit; + } + + bool canAlloc(size_t n) { + return AlignPtr(bump) + n <= limit; + } + + bool canAllocUnaligned(size_t n) { + return bump + n <= limit; + } + + /* Try to perform an allocation of size |n|, return null if not possible. */ + JS_ALWAYS_INLINE + void *tryAlloc(size_t n) { + char *aligned = AlignPtr(bump); + char *newBump = aligned + n; + if (newBump > limit) + return NULL; + + setBump(newBump); + return aligned; + } + + void *tryAllocUnaligned(size_t n); + + void *allocInfallible(size_t n) { + void *result = tryAlloc(n); + JS_ASSERT(result); + return result; + } + + static BumpChunk *new_(size_t chunkSize); + + static void delete_(BumpChunk *chunk) { +#ifdef DEBUG + memset(chunk, 0xcd, sizeof(*chunk) + chunk->bumpSpaceSize); +#endif + js_free(chunk); + } +}; + +} /* namespace detail */ + +/* + * LIFO bump allocator: used for phase-oriented and fast LIFO allocations. + * + * Note: |latest| is not necessary "last". We leave BumpChunks latent in the + * chain after they've been released to avoid thrashing before a GC. + */ +class LifoAlloc +{ + typedef detail::BumpChunk BumpChunk; + + BumpChunk *first; + BumpChunk *latest; + size_t markCount; + size_t defaultChunkSize_; + + void operator=(const LifoAlloc &); + LifoAlloc(const LifoAlloc &); + + /* + * Return a BumpChunk that can perform an allocation of at least size |n| + * and add it to the chain appropriately. + * + * Side effect: if retval is non-null, |first| and |latest| are initialized + * appropriately. + */ + BumpChunk *getOrCreateChunk(size_t n); + + void reset(size_t defaultChunkSize) { + JS_ASSERT(RoundUpPow2(defaultChunkSize) == defaultChunkSize); + first = latest = NULL; + defaultChunkSize_ = defaultChunkSize; + markCount = 0; + } + + public: + explicit LifoAlloc(size_t defaultChunkSize) { reset(defaultChunkSize); } + + /* Steal allocated chunks from |other|. */ + void steal(LifoAlloc *other) { + JS_ASSERT(!other->markCount); + PodCopy((char *) this, (char *) other, sizeof(*this)); + other->reset(defaultChunkSize_); + } + + ~LifoAlloc() { freeAll(); } + + size_t defaultChunkSize() const { return defaultChunkSize_; } + + /* Frees all held memory. */ + void freeAll(); + + /* Should be called on GC in order to release any held chunks. */ + void freeUnused(); + + JS_ALWAYS_INLINE + void *alloc(size_t n) { + void *result; + if (latest && (result = latest->tryAlloc(n))) + return result; + + if (!getOrCreateChunk(n)) + return NULL; + + return latest->allocInfallible(n); + } + + template + T *newArray(size_t count) { + void *mem = alloc(sizeof(T) * count); + if (!mem) + return NULL; + JS_STATIC_ASSERT(tl::IsPodType::result); + return (T *) mem; + } + + /* + * Create an array with uninitialized elements of type |T|. + * The caller is responsible for initialization. + */ + template + T *newArrayUninitialized(size_t count) { + return static_cast(alloc(sizeof(T) * count)); + } + + void *mark() { + markCount++; + + return latest ? latest->mark() : NULL; + } + + void release(void *mark) { + markCount--; + + if (!mark) { + latest = first; + if (latest) + latest->resetBump(); + return; + } + + /* + * Find the chunk that contains |mark|, and make sure we don't pass + * |latest| along the way -- we should be making the chain of active + * chunks shorter, not longer! + */ + BumpChunk *container = first; + while (true) { + if (container->contains(mark)) + break; + JS_ASSERT(container != latest); + container = container->next(); + } + latest = container; + latest->release(mark); + } + + /* Get the total "used" (occupied bytes) count for the arena chunks. */ + size_t used() const { + size_t accum = 0; + BumpChunk *it = first; + while (it) { + accum += it->used(); + it = it->next(); + } + return accum; + } + + /* Doesn't perform construction; useful for lazily-initialized POD types. */ + template + JS_ALWAYS_INLINE + T *newPod() { + return static_cast(alloc(sizeof(T))); + } + + JS_DECLARE_NEW_METHODS(alloc, JS_ALWAYS_INLINE) + + /* Some legacy clients (ab)use LifoAlloc to act like a vector, see bug 688891. */ + + void *allocUnaligned(size_t n); + void *reallocUnaligned(void *origPtr, size_t origSize, size_t incr); +}; + +class LifoAllocScope { + LifoAlloc *lifoAlloc; + void *mark; + bool shouldRelease; + JS_DECL_USE_GUARD_OBJECT_NOTIFIER + + public: + explicit LifoAllocScope(LifoAlloc *lifoAlloc + JS_GUARD_OBJECT_NOTIFIER_PARAM) + : lifoAlloc(lifoAlloc), shouldRelease(true) { + JS_GUARD_OBJECT_NOTIFIER_INIT; + mark = lifoAlloc->mark(); + } + + ~LifoAllocScope() { + if (shouldRelease) + lifoAlloc->release(mark); + } + + void releaseEarly() { + JS_ASSERT(shouldRelease); + lifoAlloc->release(mark); + shouldRelease = false; + } +}; + +} /* namespace js */ + +#endif diff --git a/js/src/frontend/ParseMaps.cpp b/js/src/frontend/ParseMaps.cpp index ab2d563afdaa..edc5623715a4 100644 --- a/js/src/frontend/ParseMaps.cpp +++ b/js/src/frontend/ParseMaps.cpp @@ -39,6 +39,7 @@ * ***** END LICENSE BLOCK ***** */ #include "ParseMaps-inl.h" +#include "jscompartment.h" using namespace js; @@ -125,13 +126,12 @@ DumpAtomDefnMap(const AtomDefnMapPtr &map) AtomDeclNode * AtomDecls::allocNode(JSDefinition *defn) { - AtomDeclNode *p; - JS_ARENA_ALLOCATE_TYPE(p, AtomDeclNode, &cx->tempPool); + AtomDeclNode *p = cx->tempLifoAlloc().new_(defn); if (!p) { js_ReportOutOfMemory(cx); return NULL; } - return new (p) AtomDeclNode(defn); + return p; } bool diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index 09e7a838b3e3..8da77037679e 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -109,8 +109,7 @@ Bytecode::mergeDefines(JSContext *cx, ScriptAnalysis *script, bool initial, * with progressively smaller sets of defined variables. */ if (!owned) { - uint32 *reallocArray = - ArenaArray(cx->compartment->pool, defineCount); + uint32 *reallocArray = cx->typeLifoAlloc().newArray(defineCount); if (!reallocArray) { script->setOOM(cx); return false; @@ -134,12 +133,11 @@ void PrintBytecode(JSContext *cx, JSScript *script, jsbytecode *pc) { printf("#%u:", script->id()); - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAlloc lifoAlloc(1024); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &lifoAlloc, 0); js_Disassemble1(cx, script, pc, pc - script->code, true, &sprinter); fprintf(stdout, "%s", sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); } #endif @@ -157,7 +155,7 @@ ScriptAnalysis::addJump(JSContext *cx, unsigned offset, Bytecode *&code = codeArray[offset]; bool initial = (code == NULL); if (initial) { - code = ArenaNew(cx->compartment->pool); + code = cx->typeLifoAlloc().new_(); if (!code) { setOOM(cx); return false; @@ -278,16 +276,16 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) { JS_ASSERT(cx->compartment->activeAnalysis); JS_ASSERT(!ranBytecode()); - JSArenaPool &pool = cx->compartment->pool; + LifoAlloc &tla = cx->typeLifoAlloc(); unsigned length = script->length; unsigned nargs = script->hasFunction ? script->function()->nargs : 0; numSlots = TotalSlots(script); - codeArray = ArenaArray(pool, length); - definedLocals = ArenaArray(pool, script->nfixed); - escapedSlots = ArenaArray(pool, numSlots); + codeArray = tla.newArray(length); + definedLocals = tla.newArray(script->nfixed); + escapedSlots = tla.newArray(numSlots); if (!codeArray || !definedLocals || !escapedSlots) { setOOM(cx); @@ -371,7 +369,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) unsigned forwardCatch = 0; /* Fill in stack depth and definitions at initial bytecode. */ - Bytecode *startcode = ArenaNew(pool); + Bytecode *startcode = tla.new_(); if (!startcode) { setOOM(cx); return; @@ -703,7 +701,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) if (definedLocals[local] == LOCAL_CONDITIONALLY_DEFINED) { if (forwardJump) { /* Add this local to the variables defined after this bytecode. */ - uint32 *newArray = ArenaArray(pool, defineCount + 1); + uint32 *newArray = tla.newArray(defineCount + 1); if (!newArray) { setOOM(cx); return; @@ -795,7 +793,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) bool initial = (nextcode == NULL); if (initial) { - nextcode = ArenaNew(pool); + nextcode = tla.new_(); if (!nextcode) { setOOM(cx); return; @@ -839,9 +837,9 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx) return; } - JSArenaPool &pool = cx->compartment->pool; + LifoAlloc &tla = cx->typeLifoAlloc(); - lifetimes = ArenaArray(pool, numSlots); + lifetimes = tla.newArray(numSlots); if (!lifetimes) { setOOM(cx); return; @@ -969,7 +967,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx) /* Restore all saved variables. :FIXME: maybe do this precisely. */ for (unsigned i = 0; i < savedCount; i++) { LifetimeVariable &var = *saved[i]; - var.lifetime = ArenaNew(pool, offset, var.savedEnd, var.saved); + var.lifetime = tla.new_(offset, var.savedEnd, var.saved); if (!var.lifetime) { cx->free_(saved); setOOM(cx); @@ -1036,7 +1034,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx) if (loop && loop->entry > loop->lastBlock) loop->lastBlock = loop->entry; - LoopAnalysis *nloop = ArenaNew(pool); + LoopAnalysis *nloop = tla.new_(); if (!nloop) { cx->free_(saved); setOOM(cx); @@ -1085,7 +1083,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx) * Jumping to a place where this variable is live. Make a new * lifetime segment for the variable. */ - var.lifetime = ArenaNew(pool, offset, var.savedEnd, var.saved); + var.lifetime = tla.new_(offset, var.savedEnd, var.saved); if (!var.lifetime) { cx->free_(saved); setOOM(cx); @@ -1149,7 +1147,7 @@ ScriptAnalysis::addVariable(JSContext *cx, LifetimeVariable &var, unsigned offse } } } - var.lifetime = ArenaNew(cx->compartment->pool, offset, var.savedEnd, var.saved); + var.lifetime = cx->typeLifoAlloc().new_(offset, var.savedEnd, var.saved); if (!var.lifetime) { setOOM(cx); return; @@ -1166,7 +1164,7 @@ ScriptAnalysis::killVariable(JSContext *cx, LifetimeVariable &var, unsigned offs /* Make a point lifetime indicating the write. */ if (!var.saved) saved[savedCount++] = &var; - var.saved = ArenaNew(cx->compartment->pool, offset, var.savedEnd, var.saved); + var.saved = cx->typeLifoAlloc().new_(offset, var.savedEnd, var.saved); if (!var.saved) { setOOM(cx); return; @@ -1252,7 +1250,7 @@ ScriptAnalysis::extendVariable(JSContext *cx, LifetimeVariable &var, } JS_ASSERT(savedEnd <= end); if (savedEnd > segment->end) { - Lifetime *tail = ArenaNew(cx->compartment->pool, savedEnd, 0, segment->next); + Lifetime *tail = cx->typeLifoAlloc().new_(savedEnd, 0, segment->next); if (!tail) { setOOM(cx); return; @@ -1329,7 +1327,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx) return; } - JSArenaPool &pool = cx->compartment->pool; + LifoAlloc &tla = cx->typeLifoAlloc(); unsigned maxDepth = script->nslots - script->nfixed; /* @@ -1490,7 +1488,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx) unsigned xuses = ExtendedUse(pc) ? nuses + 1 : nuses; if (xuses) { - code->poppedValues = (SSAValue *)ArenaArray(pool, xuses); + code->poppedValues = tla.newArray(xuses); if (!code->poppedValues) { setOOM(cx); return; @@ -1513,7 +1511,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx) } if (xuses) { - SSAUseChain *useChains = ArenaArray(cx->compartment->pool, xuses); + SSAUseChain *useChains = tla.newArray(xuses); if (!useChains) { setOOM(cx); return; @@ -1540,7 +1538,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx) unsigned xdefs = ExtendedDef(pc) ? ndefs + 1 : ndefs; if (xdefs) { - code->pushedUses = ArenaArray(cx->compartment->pool, xdefs); + code->pushedUses = tla.newArray(xdefs); if (!code->pushedUses) { setOOM(cx); return; @@ -1731,8 +1729,8 @@ PhiNodeCapacity(unsigned length) bool ScriptAnalysis::makePhi(JSContext *cx, uint32 slot, uint32 offset, SSAValue *pv) { - SSAPhiNode *node = ArenaNew(cx->compartment->pool); - SSAValue *options = ArenaArray(cx->compartment->pool, PhiNodeCapacity(0)); + SSAPhiNode *node = cx->typeLifoAlloc().new_(); + SSAValue *options = cx->typeLifoAlloc().newArray(PhiNodeCapacity(0)); if (!node || !options) { setOOM(cx); return false; @@ -1764,7 +1762,7 @@ ScriptAnalysis::insertPhi(JSContext *cx, SSAValue &phi, const SSAValue &v) if (trackUseChain(v)) { SSAUseChain *&uses = useChain(v); - SSAUseChain *use = ArenaNew(cx->compartment->pool); + SSAUseChain *use = cx->typeLifoAlloc().new_(); if (!use) { setOOM(cx); return; @@ -1782,8 +1780,8 @@ ScriptAnalysis::insertPhi(JSContext *cx, SSAValue &phi, const SSAValue &v) return; } - SSAValue *newOptions = ArenaArray(cx->compartment->pool, - PhiNodeCapacity(node->length + 1)); + SSAValue *newOptions = + cx->typeLifoAlloc().newArray(PhiNodeCapacity(node->length + 1)); if (!newOptions) { setOOM(cx); return; @@ -1922,7 +1920,7 @@ ScriptAnalysis::freezeNewValues(JSContext *cx, uint32 offset) return; } - code.newValues = ArenaArray(cx->compartment->pool, count + 1); + code.newValues = cx->typeLifoAlloc().newArray(count + 1); if (!code.newValues) { setOOM(cx); return; diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index 9bbcb09ca906..371bf0c44713 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -41,11 +41,13 @@ #ifndef jsanalyze_h___ #define jsanalyze_h___ -#include "jsarena.h" #include "jscompartment.h" #include "jscntxt.h" #include "jsinfer.h" #include "jsscript.h" +#include "jstl.h" + +#include "ds/LifoAlloc.h" struct JSScript; @@ -83,11 +85,6 @@ namespace analyze { * analyses are independent from type inference. */ -class SSAValue; -struct SSAUseChain; -struct LoopAnalysis; -struct SlotValue; - /* Information about a bytecode instruction. */ class Bytecode { @@ -1372,4 +1369,16 @@ void PrintBytecode(JSContext *cx, JSScript *script, jsbytecode *pc); } /* namespace analyze */ } /* namespace js */ +namespace js { +namespace tl { + +template <> struct IsPodType { static const bool result = true; }; +template <> struct IsPodType { static const bool result = true; }; +template <> struct IsPodType { static const bool result = true; }; +template <> struct IsPodType { static const bool result = true; }; +template <> struct IsPodType { static const bool result = true; }; + +} /* namespace tl */ +} /* namespace js */ + #endif // jsanalyze_h___ diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index e76b399d3ce7..9aa634390b1f 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -48,7 +48,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsutil.h" #include "jsclist.h" #include "jsdhash.h" @@ -100,6 +99,7 @@ #include "vm/Stack-inl.h" #include "vm/String-inl.h" +#include "ds/LifoAlloc.h" #if ENABLE_YARR_JIT #include "assembler/jit/ExecutableAllocator.h" @@ -2608,10 +2608,6 @@ JS_CompartmentGC(JSContext *cx, JSCompartment *comp) LeaveTrace(cx); - /* Don't nuke active arenas if executing or compiling. */ - if (cx->tempPool.current == &cx->tempPool.first) - JS_FinishArenaPool(&cx->tempPool); - GCREASON(PUBLIC_API); js_GC(cx, comp, GC_NORMAL); } @@ -2628,10 +2624,6 @@ JS_MaybeGC(JSContext *cx) { LeaveTrace(cx); - /* Don't nuke active arenas if executing or compiling. */ - if (cx->tempPool.current == &cx->tempPool.first) - JS_FinishArenaPool(&cx->tempPool); - MaybeGC(cx); } diff --git a/js/src/jsarena.h b/js/src/jsarena.h deleted file mode 100644 index e45e8e44b03a..000000000000 --- a/js/src/jsarena.h +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#ifndef jsarena_h___ -#define jsarena_h___ -/* - * Lifetime-based fast allocation, inspired by much prior art, including - * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" - * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). - * - * Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE). - */ -#include -#include "jstypes.h" -#include "jscompat.h" -#include "jsstaticcheck.h" - -JS_BEGIN_EXTERN_C - -typedef struct JSArena JSArena; -typedef struct JSArenaPool JSArenaPool; - -struct JSArena { - JSArena *next; /* next arena for this lifetime */ - jsuword base; /* aligned base address, follows this header */ - jsuword limit; /* one beyond last byte in arena */ - jsuword avail; /* points to next available byte */ -}; - -struct JSArenaPool { - JSArena first; /* first arena in pool list */ - JSArena *current; /* arena from which to allocate space */ - size_t arenasize; /* net exact size of a new arena */ - jsuword mask; /* alignment mask (power-of-2 - 1) */ -}; - -#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask) - -#define JS_ARENA_ALLOCATE(p, pool, nb) \ - JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb) - -#define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \ - JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0) - -#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \ - JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit) - -/* - * NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb - * from a->limit rather than adding _nb to _p, to avoid overflow (possible when - * running a 32-bit program on a 64-bit system where the kernel maps the heap - * up against the top of the 32-bit address space, see bug 279273). Note that - * this necessitates a comparison between nb and a->limit that looks like a - * (conceptual) type error but isn't. - */ -#define JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, guard) \ - JS_BEGIN_MACRO \ - JSArena *_a = (pool)->current; \ - size_t _nb = JS_ARENA_ALIGN(pool, nb); \ - jsuword _p = _a->avail; \ - if ((guard) || _p > _a->limit - _nb) \ - _p = (jsuword)JS_ArenaAllocate(pool, _nb); \ - else \ - _a->avail = _p + _nb; \ - p = (type) _p; \ - STATIC_ASSUME(!p || ubound((char *)p) >= nb); \ - JS_END_MACRO - -#define JS_ARENA_GROW(p, pool, size, incr) \ - JS_ARENA_GROW_CAST(p, void *, pool, size, incr) - -#define JS_ARENA_GROW_CAST(p, type, pool, size, incr) \ - JS_BEGIN_MACRO \ - JSArena *_a = (pool)->current; \ - if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) { \ - /* p was the last thing allocated in the current arena... */ \ - size_t _nb = (size) + (incr); \ - _nb = JS_ARENA_ALIGN(pool, _nb); \ - if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) { \ - /* ... and we have space, so just extend p in-place */ \ - _a->avail = (jsuword)(p) + _nb; \ - } else if ((jsuword)(p) == _a->base) { \ - /* ... p is also the 1st thing in this arena */ \ - p = (type) JS_ArenaRealloc(pool, p, size, incr); \ - } else { \ - /* hard case */ \ - p = (type) JS_ArenaGrow(pool, p, size, incr); \ - } \ - } else { \ - /* hard case */ \ - p = (type) JS_ArenaGrow(pool, p, size, incr); \ - } \ - STATIC_ASSUME(!p || ubound((char *)p) >= size + incr); \ - JS_END_MACRO - -#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail) -#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q)) - -/* - * Check if the mark is inside arena's allocated area. - */ -#define JS_IS_IN_ARENA(a, mark) \ - (JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base)) - -#ifdef DEBUG -#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \ - memset((void*)(a)->avail, JS_FREE_PATTERN, \ - (a)->limit - (a)->avail)) -#define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \ - (a)->limit - (jsuword)(a)) -#else -#define JS_CLEAR_UNUSED(a) /* nothing */ -#define JS_CLEAR_ARENA(a) /* nothing */ -#endif - -#define JS_ARENA_RELEASE(pool, mark) \ - JS_BEGIN_MACRO \ - char *_m = (char *)(mark); \ - JSArena *_a = (pool)->current; \ - if (_a != &(pool)->first && JS_IS_IN_ARENA(_a, _m)) { \ - _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \ - JS_ASSERT(_a->avail <= _a->limit); \ - JS_CLEAR_UNUSED(_a); \ - } else { \ - JS_ArenaRelease(pool, _m); \ - } \ - JS_END_MACRO - -#define JS_ARENA_DESTROY(pool, a, pnext) \ - JS_BEGIN_MACRO \ - JS_COUNT_ARENA(pool,--); \ - if ((pool)->current == (a)) (pool)->current = &(pool)->first; \ - *(pnext) = (a)->next; \ - JS_CLEAR_ARENA(a); \ - js::UnwantedForeground::free_(a); \ - (a) = NULL; \ - JS_END_MACRO - -/* - * Initialize an arena pool with a minimum size per arena of |size| bytes. - * |align| must be 1, 2, 4 or 8. - */ -extern JS_PUBLIC_API(void) -JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, - size_t align); - -/* - * Free the arenas in pool. The user may continue to allocate from pool - * after calling this function. There is no need to call JS_InitArenaPool() - * again unless JS_FinishArenaPool(pool) has been called. - */ -extern JS_PUBLIC_API(void) -JS_FreeArenaPool(JSArenaPool *pool); - -/* - * Free the arenas in pool and finish using it altogether. - */ -extern JS_PUBLIC_API(void) -JS_FinishArenaPool(JSArenaPool *pool); - -/* - * Deprecated do-nothing function. - */ -extern JS_PUBLIC_API(void) -JS_ArenaFinish(void); - -/* - * Deprecated do-nothing function. - */ -extern JS_PUBLIC_API(void) -JS_ArenaShutDown(void); - -/* - * Friend functions used by the JS_ARENA_*() macros. - */ -extern JS_PUBLIC_API(void *) -JS_ArenaAllocate(JSArenaPool *pool, size_t nb); - -extern JS_PUBLIC_API(void *) -JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr); - -extern JS_PUBLIC_API(void *) -JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr); - -extern JS_PUBLIC_API(void) -JS_ArenaRelease(JSArenaPool *pool, char *mark); - -JS_END_EXTERN_C - -#ifdef __cplusplus - -namespace js { - -template -inline T * -ArenaArray(JSArenaPool &pool, unsigned count) -{ - void *v; - JS_ARENA_ALLOCATE(v, &pool, count * sizeof(T)); - return (T *) v; -} - -template -inline T * -ArenaNew(JSArenaPool &pool) -{ - void *v; - JS_ARENA_ALLOCATE(v, &pool, sizeof(T)); - return v ? new (v) T() : NULL; -} - -template -inline T * -ArenaNew(JSArenaPool &pool, const A &a) -{ - void *v; - JS_ARENA_ALLOCATE(v, &pool, sizeof(T)); - return v ? new (v) T(a) : NULL; -} - -template -inline T * -ArenaNew(JSArenaPool &pool, const A &a, const B &b) -{ - void *v; - JS_ARENA_ALLOCATE(v, &pool, sizeof(T)); - return v ? new (v) T(a, b) : NULL; -} - -template -inline T * -ArenaNew(JSArenaPool &pool, const A &a, const B &b, const C &c) -{ - void *v; - JS_ARENA_ALLOCATE(v, &pool, sizeof(T)); - return v ? new (v) T(a, b, c) : NULL; -} - -template -inline T * -ArenaNew(JSArenaPool &pool, const A &a, const B &b, const C &c, const D &d) -{ - void *v; - JS_ARENA_ALLOCATE(v, &pool, sizeof(T)); - return v ? new (v) T(a, b, c, d) : NULL; -} - -template -inline T * -ArenaNew(JSArenaPool &pool, const A &a, const B &b, const C &c, const D &d, const E &e) -{ - void *v; - JS_ARENA_ALLOCATE(v, &pool, sizeof(T)); - return v ? new (v) T(a, b, c, d, e) : NULL; -} - -inline uintN -ArenaAllocatedSize(const JSArenaPool &pool) -{ - uintN res = 0; - const JSArena *a = &pool.first; - while (a) { - res += (a->limit - (jsuword)a); - a = a->next; - } - return res; -} - -/* Move the contents of oldPool into newPool, and reset oldPool. */ -inline void -MoveArenaPool(JSArenaPool *oldPool, JSArenaPool *newPool) -{ - *newPool = *oldPool; - JS_InitArenaPool(oldPool, NULL, newPool->arenasize, newPool->mask + 1); -} - -} /* namespace js */ - -#endif /* __cplusplus */ - -#endif /* jsarena_h___ */ diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 52ebdc41f604..1c545b718242 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -57,7 +57,6 @@ #include "jsstdint.h" #include "jstypes.h" -#include "jsarena.h" #include "jsutil.h" #include "jsclist.h" #include "jsprf.h" @@ -112,6 +111,7 @@ ThreadData::ThreadData() maxCodeCacheBytes(DEFAULT_JIT_CACHE_SIZE), #endif waiveGCQuota(false), + tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), dtoaState(NULL), nativeStackBase(GetNativeStackBase()), pendingProxyOperation(NULL), @@ -316,9 +316,6 @@ js_PurgeThreads(JSContext *cx) #endif } -static const size_t ARENA_HEADER_SIZE_HACK = 40; -static const size_t TEMP_POOL_CHUNK_SIZE = 4096 - ARENA_HEADER_SIZE_HACK; - JSContext * js_NewContext(JSRuntime *rt, size_t stackChunkSize) { @@ -345,9 +342,6 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize) JS_ASSERT(cx->findVersion() == JSVERSION_DEFAULT); VOUCH_DOES_NOT_REQUIRE_STACK(); - JS_InitArenaPool(&cx->tempPool, "temp", TEMP_POOL_CHUNK_SIZE, sizeof(jsdouble)); - JS_InitArenaPool(&cx->regExpPool, "regExp", TEMP_POOL_CHUNK_SIZE, sizeof(int)); - JS_ASSERT(cx->resolveFlags == 0); if (!cx->busyArrays.init()) { @@ -1373,9 +1367,6 @@ JSContext::~JSContext() if (parseMapPool_) Foreground::delete_(parseMapPool_); - JS_FinishArenaPool(®ExpPool); - JS_FinishArenaPool(&tempPool); - if (lastMessage) Foreground::free_(lastMessage); @@ -1502,25 +1493,9 @@ JSRuntime::onOutOfMemory(void *p, size_t nbytes, JSContext *cx) return NULL; } -/* - * Release pool's arenas if the stackPool has existed for longer than the - * limit specified by gcEmptyArenaPoolLifespan. - */ -static void -FreeOldArenas(JSRuntime *rt, JSArenaPool *pool) -{ - JSArena *a = pool->current; - if (a == pool->first.next && a->avail == a->base + sizeof(int64)) { - int64 age = JS_Now() - *(int64 *) a->base; - if (age > int64(rt->gcEmptyArenaPoolLifespan) * 1000) - JS_FreeArenaPool(pool); - } -} - void JSContext::purge() { - FreeOldArenas(runtime, ®ExpPool); if (!activeCompilations) { Foreground::delete_(parseMapPool_); parseMapPool_ = NULL; diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 3a8b0be74e9a..12c98871c82b 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -46,7 +46,6 @@ #include #include "jsprvtd.h" -#include "jsarena.h" #include "jsclist.h" #include "jsatom.h" #include "jsdhash.h" @@ -64,6 +63,7 @@ #include "jsvector.h" #include "prmjtime.h" +#include "ds/LifoAlloc.h" #include "vm/Stack.h" #include "vm/String.h" @@ -190,6 +190,10 @@ struct ThreadData { */ bool waiveGCQuota; + /* Temporary arena pool used while compiling and decompiling. */ + static const size_t TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12; + LifoAlloc tempLifoAlloc; + /* * The GSN cache is per thread since even multi-cx-per-thread embeddings * do not interleave js_GetSrcNote calls. @@ -224,6 +228,7 @@ struct ThreadData { } void purge(JSContext *cx) { + tempLifoAlloc.freeUnused(); gsnCache.purge(); /* FIXME: bug 506341. */ @@ -994,17 +999,11 @@ struct JSContext /* Wrap cx->exception for the current compartment. */ void wrapPendingException(); - /* Temporary arena pool used while compiling and decompiling. */ - JSArenaPool tempPool; - private: /* Lazily initialized pool of maps used during parse/emit. */ js::ParseMapPool *parseMapPool_; public: - /* Temporary arena pool used while evaluate regular expressions. */ - JSArenaPool regExpPool; - /* Top-level object and pointer to top stack frame's scope chain. */ JSObject *globalObject; @@ -1144,6 +1143,9 @@ struct JSContext bool hasWErrorOption() const { return hasRunOption(JSOPTION_WERROR); } bool hasAtLineOption() const { return hasRunOption(JSOPTION_ATLINE); } + js::LifoAlloc &tempLifoAlloc() { return JS_THREAD_DATA(this)->tempLifoAlloc; } + inline js::LifoAlloc &typeLifoAlloc(); + #ifdef JS_THREADSAFE private: JSThread *thread_; @@ -1877,28 +1879,6 @@ class AutoKeepAtoms { ~AutoKeepAtoms() { JS_UNKEEP_ATOMS(rt); } }; -class AutoArenaAllocator { - JSArenaPool *pool; - void *mark; - JS_DECL_USE_GUARD_OBJECT_NOTIFIER - - public: - explicit AutoArenaAllocator(JSArenaPool *pool - JS_GUARD_OBJECT_NOTIFIER_PARAM) - : pool(pool), mark(JS_ARENA_MARK(pool)) - { - JS_GUARD_OBJECT_NOTIFIER_INIT; - } - ~AutoArenaAllocator() { JS_ARENA_RELEASE(pool, mark); } - - template - T *alloc(size_t elems) { - void *ptr; - JS_ARENA_ALLOCATE(ptr, pool, elems * sizeof(T)); - return static_cast(ptr); - } -}; - class AutoReleasePtr { JSContext *cx; void *ptr; diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index ca50a4cb7413..ddca361cb3a4 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -407,6 +407,12 @@ inline js::mjit::JaegerCompartment *JSContext::jaegerCompartment() } #endif +inline js::LifoAlloc & +JSContext::typeLifoAlloc() +{ + return compartment->typeLifoAlloc; +} + inline bool JSContext::ensureGeneratorStackSpace() { diff --git a/js/src/jscompartment.cpp b/js/src/jscompartment.cpp index 237e77516f1e..ac6d982d294a 100644 --- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -74,6 +74,7 @@ JSCompartment::JSCompartment(JSRuntime *rt) gcTriggerBytes(0), gcLastBytes(0), hold(false), + typeLifoAlloc(TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE), #ifdef JS_TRACER traceMonitor_(NULL), #endif @@ -132,11 +133,6 @@ JSCompartment::init(JSContext *cx) activeAnalysis = activeInference = false; types.init(cx); - /* Duplicated from jscntxt.cpp. :XXX: bug 675150 fix hack. */ - static const size_t ARENA_HEADER_SIZE_HACK = 40; - - JS_InitArenaPool(&pool, "analysis", 4096 - ARENA_HEADER_SIZE_HACK, 8); - if (!crossCompartmentWrappers.init()) return false; @@ -622,8 +618,8 @@ JSCompartment::sweep(JSContext *cx, uint32 releaseInterval) * Clear the analysis pool, but don't release its data yet. While * sweeping types any live data will be allocated into the pool. */ - JSArenaPool oldPool; - MoveArenaPool(&pool, &oldPool); + LifoAlloc oldAlloc(typeLifoAlloc.defaultChunkSize()); + oldAlloc.steal(&typeLifoAlloc); /* * Sweep analysis information and everything depending on it from the @@ -656,9 +652,6 @@ JSCompartment::sweep(JSContext *cx, uint32 releaseInterval) JSScript *script = i.get(); script->clearAnalysis(); } - - /* Reset the analysis pool, releasing all analysis and intermediate type data. */ - JS_FinishArenaPool(&oldPool); } active = false; diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h index cfd240ac3969..c85d8f99c48d 100644 --- a/js/src/jscompartment.h +++ b/js/src/jscompartment.h @@ -408,7 +408,8 @@ struct JS_FRIEND_API(JSCompartment) { * Cleared on every GC, unless the GC happens during analysis (indicated * by activeAnalysis, which is implied by activeInference). */ - JSArenaPool pool; + static const size_t TYPE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12; + js::LifoAlloc typeLifoAlloc; bool activeAnalysis; bool activeInference; diff --git a/js/src/jsdbgapi.cpp b/js/src/jsdbgapi.cpp index ffd1e4e04f6c..4191f41e4ef1 100644 --- a/js/src/jsdbgapi.cpp +++ b/js/src/jsdbgapi.cpp @@ -485,10 +485,9 @@ JS_GetFunctionLocalNameArray(JSContext *cx, JSFunction *fun, void **markp) return NULL; /* Munge data into the API this method implements. Avert your eyes! */ - *markp = JS_ARENA_MARK(&cx->tempPool); + *markp = cx->tempLifoAlloc().mark(); - jsuword *names; - JS_ARENA_ALLOCATE_CAST(names, jsuword *, &cx->tempPool, localNames.length() * sizeof *names); + jsuword *names = cx->tempLifoAlloc().newArray(localNames.length()); if (!names) { js_ReportOutOfMemory(cx); return NULL; @@ -513,7 +512,7 @@ JS_AtomKey(JSAtom *atom) extern JS_PUBLIC_API(void) JS_ReleaseFunctionLocalNameArray(JSContext *cx, void *mark) { - JS_ARENA_RELEASE(&cx->tempPool, mark); + cx->tempLifoAlloc().release(mark); } JS_PUBLIC_API(JSScript *) @@ -2167,9 +2166,9 @@ JS_PUBLIC_API(void) JS_DumpBytecode(JSContext *cx, JSScript *script) { #if defined(DEBUG) - AutoArenaAllocator mark(&cx->tempPool); + LifoAlloc lifoAlloc(1024); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &lifoAlloc, 0); fprintf(stdout, "--- SCRIPT %s:%d ---\n", script->filename, script->lineno); js_Disassemble(cx, script, true, &sprinter); diff --git a/js/src/jsemit.cpp b/js/src/jsemit.cpp index fef098dee5c8..a64d5b86a183 100644 --- a/js/src/jsemit.cpp +++ b/js/src/jsemit.cpp @@ -48,7 +48,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsutil.h" #include "jsbit.h" #include "jsprf.h" @@ -75,6 +74,7 @@ #include "jsscriptinlines.h" #include "frontend/ParseMaps-inl.h" +#include "ds/LifoAlloc.h" /* Allocation chunk counts, must be powers of two in general. */ #define BYTECODE_CHUNK_LENGTH 1024 /* initial bytecode chunk length */ @@ -515,8 +515,7 @@ AddJumpTarget(AddJumpTargetArgs *args, JSJumpTarget **jtp) if (jt) { cg->jtFreeList = jt->kids[JT_LEFT]; } else { - JS_ARENA_ALLOCATE_CAST(jt, JSJumpTarget *, &args->cx->tempPool, - sizeof *jt); + jt = args->cx->tempLifoAlloc().new_(); if (!jt) { js_ReportOutOfMemory(args->cx); return 0; @@ -3312,9 +3311,7 @@ EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg) static Value * AllocateSwitchConstant(JSContext *cx) { - Value *pv; - JS_ARENA_ALLOCATE_TYPE(pv, Value, &cx->tempPool); - return pv; + return cx->tempLifoAlloc().new_(); } /* @@ -7792,14 +7789,12 @@ static JSBool NewTryNote(JSContext *cx, JSCodeGenerator *cg, JSTryNoteKind kind, uintN stackDepth, size_t start, size_t end) { - JSTryNode *tryNode; - JS_ASSERT((uintN)(uint16)stackDepth == stackDepth); JS_ASSERT(start <= end); JS_ASSERT((size_t)(uint32)start == start); JS_ASSERT((size_t)(uint32)end == end); - JS_ARENA_ALLOCATE_TYPE(tryNode, JSTryNode, &cx->tempPool); + JSTryNode *tryNode = cx->tempLifoAlloc().new_(); if (!tryNode) { js_ReportOutOfMemory(cx); return JS_FALSE; diff --git a/js/src/jsemit.h b/js/src/jsemit.h index dc3cfb16ecd5..c5295a538b36 100644 --- a/js/src/jsemit.h +++ b/js/src/jsemit.h @@ -668,11 +668,9 @@ struct JSCodeGenerator : public JSTreeContext } /* - * Release cg->codePool, cg->notePool, and parser->context->tempPool to - * marks set by JSCodeGenerator's ctor. Note that cgs are magic: they own - * the arena pool "tops-of-stack" space above their codeMark, noteMark, and - * tempMark points. This means you cannot alloc from tempPool and save the - * pointer beyond the next JSCodeGenerator destructor call. + * Note that cgs are magic: they own the arena "top-of-stack" space above + * their tempMark points. This means that you cannot alloc from tempPool + * and save the pointer beyond the next JSCodeGenerator destructor call. */ ~JSCodeGenerator(); diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 7465230d297f..9911188b150b 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -2182,8 +2182,8 @@ Function(JSContext *cx, uintN argc, Value *vp) * for a terminating 0. Mark cx->tempPool for later release, to free * collected_args and its tokenstream in one swoop. */ - AutoArenaAllocator aaa(&cx->tempPool); - jschar *cp = aaa.alloc(args_length + 1); + LifoAllocScope las(&cx->tempLifoAlloc()); + jschar *cp = cx->tempLifoAlloc().newArray(args_length + 1); if (!cp) { js_ReportOutOfMemory(cx); return false; diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 26d0f286bdbf..2644947fb187 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -352,7 +352,7 @@ TypeSet::make(JSContext *cx, const char *name) { JS_ASSERT(cx->compartment->activeInference); - TypeSet *res = ArenaNew(cx->compartment->pool); + TypeSet *res = cx->typeLifoAlloc().new_(); if (!res) { cx->compartment->types.setPendingNukeTypes(cx); return NULL; @@ -492,7 +492,7 @@ public: void TypeSet::addSubset(JSContext *cx, TypeSet *target) { - add(cx, ArenaNew(cx->compartment->pool, target)); + add(cx, cx->typeLifoAlloc().new_(target)); } /* Constraints for reads/writes on object properties. */ @@ -527,14 +527,14 @@ void TypeSet::addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target, jsid id) { - add(cx, ArenaNew(cx->compartment->pool, script, pc, target, id, false)); + add(cx, cx->typeLifoAlloc().new_(script, pc, target, id, false)); } void TypeSet::addSetProperty(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target, jsid id) { - add(cx, ArenaNew(cx->compartment->pool, script, pc, target, id, true)); + add(cx, cx->typeLifoAlloc().new_(script, pc, target, id, true)); } /* @@ -575,7 +575,7 @@ TypeSet::addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, jsid i if (JSOp(*callpc) == JSOP_NEW) return; - add(cx, ArenaNew(cx->compartment->pool, script, callpc, id)); + add(cx, cx->typeLifoAlloc().new_(script, callpc, id)); } /* @@ -608,8 +608,8 @@ void TypeSet::addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *objectTypes, TypeSet *valueTypes) { - add(cx, ArenaNew(cx->compartment->pool, script, pc, - objectTypes, valueTypes)); + add(cx, cx->typeLifoAlloc().new_(script, pc, objectTypes, + valueTypes)); } /* @@ -633,7 +633,7 @@ public: void TypeSet::addCall(JSContext *cx, TypeCallsite *site) { - add(cx, ArenaNew(cx->compartment->pool, site)); + add(cx, cx->typeLifoAlloc().new_(site)); } /* Constraints for arithmetic operations. */ @@ -658,7 +658,7 @@ public: void TypeSet::addArith(JSContext *cx, TypeSet *target, TypeSet *other) { - add(cx, ArenaNew(cx->compartment->pool, target, other)); + add(cx, cx->typeLifoAlloc().new_(target, other)); } /* Subset constraint which transforms primitive values into appropriate objects. */ @@ -678,7 +678,7 @@ public: void TypeSet::addTransformThis(JSContext *cx, JSScript *script, TypeSet *target) { - add(cx, ArenaNew(cx->compartment->pool, script, target)); + add(cx, cx->typeLifoAlloc().new_(script, target)); } /* @@ -709,7 +709,7 @@ TypeSet::addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc, Type if (JSOp(*callpc) == JSOP_NEW) return; - add(cx, ArenaNew(cx->compartment->pool, script, callpc, type, types)); + add(cx, cx->typeLifoAlloc().new_(script, callpc, type, types)); } /* Subset constraint which filters out primitive types. */ @@ -752,7 +752,7 @@ public: void TypeSet::addFilterPrimitives(JSContext *cx, TypeSet *target, FilterKind filter) { - add(cx, ArenaNew(cx->compartment->pool, target, filter)); + add(cx, cx->typeLifoAlloc().new_(target, filter)); } /* If id is a normal slotful 'own' property of an object, get its shape. */ @@ -876,7 +876,7 @@ public: void TypeSet::addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target) { - add(cx, ArenaNew(cx->compartment->pool, script, pc, target)); + add(cx, cx->typeLifoAlloc().new_(script, pc, target)); } /* @@ -904,7 +904,7 @@ public: void TypeSet::addLazyArguments(JSContext *cx, TypeSet *target) { - add(cx, ArenaNew(cx->compartment->pool, target)); + add(cx, cx->typeLifoAlloc().new_(target)); } ///////////////////////////////////////////////////////////////////// @@ -1086,9 +1086,8 @@ TypeConstraintCallProp::newType(JSContext *cx, TypeSet *source, Type type) if (!types->hasPropagatedProperty()) object->getFromPrototypes(cx, id, types); /* Bypass addPropagateThis, we already have the callpc. */ - types->add(cx, ArenaNew(cx->compartment->pool, - script, callpc, type, - (TypeSet *) NULL)); + types->add(cx, cx->typeLifoAlloc().new_( + script, callpc, type, (TypeSet *) NULL)); } } } @@ -1389,8 +1388,8 @@ public: void TypeSet::addFreeze(JSContext *cx) { - add(cx, ArenaNew(cx->compartment->pool, - cx->compartment->types.compiledScript), false); + add(cx, cx->typeLifoAlloc().new_( + cx->compartment->types.compiledScript), false); } /* @@ -1473,8 +1472,8 @@ TypeSet::getKnownTypeTag(JSContext *cx) JS_ASSERT_IF(empty, type == JSVAL_TYPE_UNKNOWN); if (cx->compartment->types.compiledScript && (empty || type != JSVAL_TYPE_UNKNOWN)) { - add(cx, ArenaNew(cx->compartment->pool, - cx->compartment->types.compiledScript), false); + add(cx, cx->typeLifoAlloc().new_( + cx->compartment->types.compiledScript), false); } return type; @@ -1553,9 +1552,8 @@ public: TypeSet *types = object->getProperty(cx, JSID_EMPTY, false); if (!types) return; - types->add(cx, - ArenaNew(cx->compartment->pool, - script, flags, &marked), false); + types->add(cx, cx->typeLifoAlloc().new_( + script, flags, &marked), false); return; } } else { @@ -1596,8 +1594,8 @@ TypeSet::hasObjectFlags(JSContext *cx, TypeObjectFlags flags) * Watch for new objects of different kind, and re-traverse existing types * in this set to add any needed FreezeArray constraints. */ - add(cx, ArenaNew(cx->compartment->pool, - cx->compartment->types.compiledScript, flags)); + add(cx, cx->typeLifoAlloc().new_( + cx->compartment->types.compiledScript, flags)); return false; } @@ -1611,9 +1609,8 @@ TypeSet::HasObjectFlags(JSContext *cx, TypeObject *object, TypeObjectFlags flags TypeSet *types = object->getProperty(cx, JSID_EMPTY, false); if (!types) return true; - types->add(cx, - ArenaNew(cx->compartment->pool, - cx->compartment->types.compiledScript, flags), false); + types->add(cx, cx->typeLifoAlloc().new_( + cx->compartment->types.compiledScript, flags), false); return false; } @@ -1694,9 +1691,9 @@ TypeSet::WatchObjectStateChange(JSContext *cx, TypeObject *obj) * Use a constraint which triggers recompilation when markStateChange is * called, which will set 'force' to true. */ - types->add(cx, ArenaNew(cx->compartment->pool, - cx->compartment->types.compiledScript, - 0)); + types->add(cx, cx->typeLifoAlloc().new_( + cx->compartment->types.compiledScript, + 0)); } class TypeConstraintFreezeOwnProperty : public TypeConstraint @@ -1749,7 +1746,7 @@ TypeSet::isOwnProperty(JSContext *cx, TypeObject *object, bool configurable) if (isOwnProperty(configurable)) return true; - add(cx, ArenaNew(cx->compartment->pool, + add(cx, cx->typeLifoAlloc().new_( cx->compartment->types.compiledScript, configurable), false); return false; @@ -1761,8 +1758,8 @@ TypeSet::knownNonEmpty(JSContext *cx) if (baseFlags() != 0 || baseObjectCount() != 0) return true; - add(cx, ArenaNew(cx->compartment->pool, - cx->compartment->types.compiledScript), false); + add(cx, cx->typeLifoAlloc().new_( + cx->compartment->types.compiledScript), false); return false; } @@ -1821,7 +1818,7 @@ TypeSet::getSingleton(JSContext *cx, bool freeze) return NULL; if (freeze) { - add(cx, ArenaNew(cx->compartment->pool, + add(cx, cx->typeLifoAlloc().new_( cx->compartment->types.compiledScript), false); } @@ -1879,9 +1876,8 @@ TypeSet::hasGlobalObject(JSContext *cx, JSObject *global) return false; } - add(cx, ArenaNew(cx->compartment->pool, - cx->compartment->types.compiledScript, - global), false); + add(cx, cx->typeLifoAlloc().new_( + cx->compartment->types.compiledScript, global), false); return true; } @@ -2309,8 +2305,7 @@ ScriptAnalysis::addTypeBarrier(JSContext *cx, const jsbytecode *pc, TypeSet *tar InferSpewColor(target), target, InferSpewColorReset(), TypeString(type)); - barrier = ArenaNew(cx->compartment->pool, target, type, - (JSObject *) NULL, JSID_VOID); + barrier = cx->typeLifoAlloc().new_(target, type, (JSObject *) NULL, JSID_VOID); barrier->next = code.typeBarriers; code.typeBarriers = barrier; @@ -2335,8 +2330,7 @@ ScriptAnalysis::addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc, Typ InferSpewColor(target), target, InferSpewColorReset(), (void *) singleton, TypeIdString(singletonId)); - TypeBarrier *barrier = - ArenaNew(cx->compartment->pool, target, Type::UndefinedType(), + TypeBarrier *barrier = cx->typeLifoAlloc().new_(target, Type::UndefinedType(), singleton, singletonId); barrier->next = code.typeBarriers; @@ -2701,7 +2695,7 @@ bool TypeObject::addProperty(JSContext *cx, jsid id, Property **pprop) { JS_ASSERT(!*pprop); - Property *base = ArenaNew(cx->compartment->pool, id); + Property *base = cx->typeLifoAlloc().new_(id); if (!base) { cx->compartment->types.setPendingNukeTypes(cx); return false; @@ -3251,7 +3245,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, if (ExtendedDef(pc)) defCount++; - TypeSet *pushed = ArenaArray(cx->compartment->pool, defCount); + TypeSet *pushed = cx->typeLifoAlloc().newArrayUninitialized(defCount); if (!pushed) return false; PodZero(pushed, defCount); @@ -3774,7 +3768,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, /* Construct the base call information about this site. */ unsigned argCount = GetUseCount(script, offset) - 2; - TypeCallsite *callsite = ArenaNew(cx->compartment->pool, + TypeCallsite *callsite = cx->typeLifoAlloc().new_( cx, script, pc, op == JSOP_NEW, argCount); if (!callsite || (argCount && !callsite->argumentTypes)) { cx->compartment->types.setPendingNukeTypes(cx); @@ -4496,8 +4490,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO if (!parentTypes || parentTypes->unknown()) return false; parentObject->getFromPrototypes(cx, id, parentTypes); - parentTypes->add(cx, - ArenaNew(cx->compartment->pool, type)); + parentTypes->add(cx, cx->typeLifoAlloc().new_(type)); } else if (op == JSOP_FUNCALL && uses->u.which == GET_ARGC(pc) - 1) { /* * Passed as the first parameter to Function.call. Follow control @@ -4546,9 +4539,9 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, JSO * should the Function.call or callee itself change in the future. */ analysis->pushedTypes(calleev.pushedOffset(), 0)->add(cx, - ArenaNew(cx->compartment->pool, type)); + cx->typeLifoAlloc().new_(type)); analysis->pushedTypes(calleev.pushedOffset(), 1)->add(cx, - ArenaNew(cx->compartment->pool, type)); + cx->typeLifoAlloc().new_(type)); TypeNewScript::Initializer pushframe(TypeNewScript::Initializer::FRAME_PUSH, uses->offset); if (!initializerList->append(pushframe)) { @@ -5424,7 +5417,7 @@ JSScript::makeAnalysis(JSContext *cx) AutoEnterAnalysis enter(cx); - types->analysis = ArenaNew(cx->compartment->pool, this); + types->analysis = cx->typeLifoAlloc().new_(this); if (!types->analysis) return false; @@ -5815,7 +5808,7 @@ TypeObject::sweep(JSContext *cx) for (unsigned i = 0; i < oldCapacity; i++) { Property *prop = oldArray[i]; if (prop && prop->types.isOwnProperty(false)) { - Property *newProp = ArenaNew(compartment->pool, *prop); + Property *newProp = compartment->typeLifoAlloc.new_(*prop); if (newProp) { Property **pentry = HashSetInsert @@ -5835,7 +5828,7 @@ TypeObject::sweep(JSContext *cx) } else if (propertyCount == 1) { Property *prop = (Property *) propertySet; if (prop->types.isOwnProperty(false)) { - Property *newProp = ArenaNew(compartment->pool, *prop); + Property *newProp = compartment->typeLifoAlloc.new_(*prop); if (newProp) { propertySet = (Property **) newProp; newProp->types.sweep(cx, compartment); @@ -6109,7 +6102,7 @@ JS_GetTypeInferenceMemoryStats(JSContext *cx, JSCompartment *compartment, * by being copied to the replacement pool. This memory will be counted too * and deducted from the amount of temporary data. */ - stats->temporary += ArenaAllocatedSize(compartment->pool); + stats->temporary += compartment->typeLifoAlloc.used(); /* Pending arrays are cleared on GC along with the analysis pool. */ stats->temporary += sizeof(TypeCompartment::PendingWork) * compartment->types.pendingCapacity; diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index f36d3795a765..dc1a731c297c 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -43,29 +43,16 @@ #define jsinfer_h___ #include "jsalloc.h" -#include "jsarena.h" #include "jscell.h" #include "jstl.h" #include "jsprvtd.h" #include "jshashtable.h" -namespace js { - class CallArgs; - namespace analyze { - class ScriptAnalysis; - } - class GlobalObject; -} +#include "ds/LifoAlloc.h" namespace js { namespace types { -/* Forward declarations. */ -class TypeSet; -struct TypeCallsite; -struct TypeObject; -struct TypeCompartment; - /* Type set entry for either a JSObject with singleton type or a non-singleton TypeObject. */ struct TypeObjectKey { static intptr_t keyBits(TypeObjectKey *obj) { return (intptr_t) obj; } diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 8253f6ebcacd..a45bc87adb8c 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -820,7 +820,7 @@ HashSetInsertTry(JSCompartment *compartment, U **&values, unsigned &count, T key return &values[insertpos]; } - U **newValues = ArenaArray(compartment->pool, newCapacity); + U **newValues = compartment->typeLifoAlloc.newArray(newCapacity); if (!newValues) return NULL; PodZero(newValues, newCapacity); @@ -861,7 +861,7 @@ HashSetInsert(JSCompartment *compartment, U **&values, unsigned &count, T key) if (KEY::getKey(oldData) == key) return (U **) &values; - values = ArenaArray(compartment->pool, SET_ARRAY_SIZE); + values = compartment->typeLifoAlloc.newArray(SET_ARRAY_SIZE); if (!values) { values = (U **) oldData; return NULL; @@ -1097,7 +1097,7 @@ TypeCallsite::TypeCallsite(JSContext *cx, JSScript *script, jsbytecode *pc, thisTypes(NULL), returnTypes(NULL) { /* Caller must check for failure. */ - argumentTypes = ArenaArray(cx->compartment->pool, argumentCount); + argumentTypes = cx->typeLifoAlloc().newArray(argumentCount); } ///////////////////////////////////////////////////////////////////// diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index f1d143d547bb..a2ebf4c6b7c0 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -46,7 +46,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsutil.h" #include "jsprf.h" #include "jsapi.h" diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index f19bb4842d07..fb9638cb77b9 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -45,7 +45,6 @@ #include "jstypes.h" #include "jsstdint.h" #include "jsutil.h" -#include "jsarena.h" #include "jsapi.h" #include "jsarray.h" #include "jsatom.h" diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 5546e1226fe2..58f8f4fe74c0 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -45,7 +45,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsbit.h" #include "jsutil.h" #include "jshash.h" diff --git a/js/src/json.cpp b/js/src/json.cpp index dd84259a6535..575c50cfd608 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -41,7 +41,6 @@ #include #include "jsapi.h" -#include "jsarena.h" #include "jsarray.h" #include "jsatom.h" #include "jsbool.h" diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 18a4975fe5b3..0bbd462797d3 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -50,7 +50,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsutil.h" #include "jsprf.h" #include "jsapi.h" @@ -319,9 +318,7 @@ js_DisassembleAtPC(JSContext *cx, JSScript *script, JSBool lines, jsbytecode *pc else SprintCString(sp, " "); } - len = js_Disassemble1(cx, script, next, - next - script->code, - lines, sp); + len = js_Disassemble1(cx, script, next, next - script->code, lines, sp); if (!len) return JS_FALSE; next += len; @@ -338,24 +335,22 @@ js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, Sprinter *sp) JS_FRIEND_API(JSBool) js_DumpPC(JSContext *cx) { - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); JSBool ok = js_DisassembleAtPC(cx, cx->fp()->script(), true, cx->regs().pc, &sprinter); fprintf(stdout, "%s", sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); return ok; } JSBool js_DumpScript(JSContext *cx, JSScript *script) { - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); JSBool ok = js_Disassemble(cx, script, true, &sprinter); fprintf(stdout, "%s", sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); return ok; } @@ -367,13 +362,13 @@ ToDisassemblySource(JSContext *cx, jsval v, JSAutoByteString *bytes) { if (JSVAL_IS_STRING(v)) { Sprinter sprinter; - void *mark = JS_ARENA_MARK(&cx->tempPool); - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + LifoAlloc &tla = cx->tempLifoAlloc(); + LifoAllocScope las(&tla); + INIT_SPRINTER(cx, &sprinter, &tla, 0); char *nbytes = QuoteString(&sprinter, JSVAL_TO_STRING(v), '"'); if (!nbytes) return false; nbytes = JS_sprintf_append(NULL, "%s", nbytes); - JS_ARENA_RELEASE(&cx->tempPool, mark); if (!nbytes) return false; bytes->initBytes(nbytes); @@ -687,11 +682,10 @@ SprintEnsureBuffer(Sprinter *sp, size_t len) if (nb < 0) return JS_TRUE; base = sp->base; - if (!base) { - JS_ARENA_ALLOCATE_CAST(base, char *, sp->pool, nb); - } else { - JS_ARENA_GROW_CAST(base, char *, sp->pool, sp->size, nb); - } + if (!base) + base = static_cast(sp->pool->allocUnaligned(nb)); + else + base = static_cast(sp->pool->reallocUnaligned(base, sp->size, nb)); if (!base) { js_ReportOutOfMemory(sp->context); return JS_FALSE; @@ -876,16 +870,11 @@ QuoteString(Sprinter *sp, JSString *str, uint32 quote) JSString * js_QuoteString(JSContext *cx, JSString *str, jschar quote) { - void *mark; + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - char *bytes; - JSString *escstr; - - mark = JS_ARENA_MARK(&cx->tempPool); - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); - bytes = QuoteString(&sprinter, str, quote); - escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL; - JS_ARENA_RELEASE(&cx->tempPool, mark); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); + char *bytes = QuoteString(&sprinter, str, quote); + JSString *escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL; return escstr; } @@ -893,7 +882,7 @@ js_QuoteString(JSContext *cx, JSString *str, jschar quote) struct JSPrinter { Sprinter sprinter; /* base class state */ - JSArenaPool pool; /* string allocation pool */ + LifoAlloc pool; /* string allocation pool */ uintN indent; /* indentation in spaces */ bool pretty; /* pretty-print: indent, use newlines */ bool grouped; /* in parenthesized expression context */ @@ -909,13 +898,11 @@ JSPrinter * js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun, uintN indent, JSBool pretty, JSBool grouped, JSBool strict) { - JSPrinter *jp; - - jp = (JSPrinter *) cx->malloc_(sizeof(JSPrinter)); + JSPrinter *jp = (JSPrinter *) cx->malloc_(sizeof(JSPrinter)); if (!jp) return NULL; INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0); - JS_InitArenaPool(&jp->pool, name, 256, 1); + new (&jp->pool) LifoAlloc(1024); jp->indent = indent; jp->pretty = !!pretty; jp->grouped = !!grouped; @@ -938,7 +925,7 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun, void js_DestroyPrinter(JSPrinter *jp) { - JS_FinishArenaPool(&jp->pool); + jp->pool.freeAll(); Foreground::delete_(jp->localNames); jp->sprinter.context->free_(jp); } @@ -955,7 +942,7 @@ js_GetPrinterOutput(JSPrinter *jp) str = JS_NewStringCopyZ(cx, jp->sprinter.base); if (!str) return NULL; - JS_FreeArenaPool(&jp->pool); + jp->pool.freeAll(); INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0); return str; } @@ -1906,15 +1893,12 @@ DecompileGroupAssignment(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc, static JSBool InitSprintStack(JSContext *cx, SprintStack *ss, JSPrinter *jp, uintN depth) { - size_t offsetsz, opcodesz; - void *space; - - INIT_SPRINTER(cx, &ss->sprinter, &cx->tempPool, PAREN_SLOP); + INIT_SPRINTER(cx, &ss->sprinter, &cx->tempLifoAlloc(), PAREN_SLOP); /* Allocate the parallel (to avoid padding) offset and opcode stacks. */ - offsetsz = depth * sizeof(ptrdiff_t); - opcodesz = depth * sizeof(jsbytecode); - JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz); + size_t offsetsz = depth * sizeof(ptrdiff_t); + size_t opcodesz = depth * sizeof(jsbytecode); + void *space = cx->tempLifoAlloc().alloc(offsetsz + opcodesz); if (!space) { js_ReportOutOfMemory(cx); return JS_FALSE; @@ -4064,7 +4048,6 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) #if JS_HAS_GENERATOR_EXPRS sn = js_GetSrcNote(jp->script, pc); if (sn && SN_TYPE(sn) == SRC_GENEXP) { - void *mark; Vector *innerLocalNames; Vector *outerLocalNames; JSScript *inner, *outer; @@ -4079,7 +4062,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) * Therefore after InitSprintStack succeeds, we must * release to mark before returning. */ - mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); if (fun->script()->bindings.hasLocalNames()) { innerLocalNames = cx->new_ >(cx); if (!innerLocalNames || @@ -4091,10 +4074,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) innerLocalNames = NULL; } inner = fun->script(); - if (!InitSprintStack(cx, &ss2, jp, StackDepth(inner))) { - JS_ARENA_RELEASE(&cx->tempPool, mark); + if (!InitSprintStack(cx, &ss2, jp, StackDepth(inner))) return NULL; - } ss2.inGenExp = JS_TRUE; /* @@ -4122,10 +4103,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) jp->script = outer; jp->fun = outerfun; jp->localNames = outerLocalNames; - if (!ok) { - JS_ARENA_RELEASE(&cx->tempPool, mark); + if (!ok) return NULL; - } /* * Advance over this op and its global |this| push, and @@ -4195,7 +4174,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop) * from cx's tempPool. */ rval = JS_strdup(cx, PopStr(&ss2, op)); - JS_ARENA_RELEASE(&cx->tempPool, mark); + las.releaseEarly(); if (!rval) return NULL; todo = SprintCString(&ss->sprinter, rval); @@ -4833,8 +4812,6 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len, uintN depth, i; SprintStack ss; JSContext *cx; - void *mark; - JSBool ok; JSScript *oldscript; char *last; @@ -4845,10 +4822,9 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len, AutoScriptUntrapper untrapper(cx, script, &pc); /* Initialize a sprinter for use with the offset stack. */ - mark = JS_ARENA_MARK(&cx->tempPool); - ok = InitSprintStack(cx, &ss, jp, depth); - if (!ok) - goto out; + LifoAllocScope las(&cx->tempLifoAlloc()); + if (!InitSprintStack(cx, &ss, jp, depth)) + return false; /* * If we are called from js_DecompileValueGenerator with a portion of @@ -4872,7 +4848,7 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len, /* Call recursive subroutine to do the hard work. */ oldscript = jp->script; jp->script = script; - ok = Decompile(&ss, pc, len, JSOP_NOP) != NULL; + bool ok = Decompile(&ss, pc, len, JSOP_NOP) != NULL; jp->script = oldscript; /* If the given code didn't empty the stack, do it now. */ @@ -4883,9 +4859,6 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len, js_printf(jp, "%s", last); } -out: - /* Free all temporary stuff allocated under this call. */ - JS_ARENA_RELEASE(&cx->tempPool, mark); return ok; } @@ -4998,7 +4971,6 @@ js_DecompileFunction(JSPrinter *jp) JSScript *script = fun->script(); #if JS_HAS_DESTRUCTURING SprintStack ss; - void *mark; #endif /* Print the parameters. */ @@ -5010,7 +4982,7 @@ js_DecompileFunction(JSPrinter *jp) #if JS_HAS_DESTRUCTURING ss.printer = NULL; jp->script = script; - mark = JS_ARENA_MARK(&jp->sprinter.context->tempPool); + LifoAllocScope las(&jp->sprinter.context->tempLifoAlloc()); #endif for (i = 0; i < fun->nargs; i++) { @@ -5061,7 +5033,7 @@ js_DecompileFunction(JSPrinter *jp) #if JS_HAS_DESTRUCTURING jp->script = NULL; - JS_ARENA_RELEASE(&jp->sprinter.context->tempPool, mark); + las.releaseEarly(); #endif if (!ok) return JS_FALSE; diff --git a/js/src/jsopcode.h b/js/src/jsopcode.h index 89107d97dbe9..67a4b92606e4 100644 --- a/js/src/jsopcode.h +++ b/js/src/jsopcode.h @@ -46,7 +46,6 @@ #include "jsprvtd.h" #include "jspubtd.h" #include "jsutil.h" -#include "jsarena.h" JS_BEGIN_EXTERN_C @@ -505,7 +504,7 @@ DecompileValueGenerator(JSContext *cx, intN spindex, const Value &v, */ struct Sprinter { JSContext *context; /* context executing the decompiler */ - JSArenaPool *pool; /* string allocation pool */ + LifoAlloc *pool; /* string allocation pool */ char *base; /* base address of buffer in pool */ size_t size; /* size of buffer allocated at base */ ptrdiff_t offset; /* offset of next free char in buffer */ diff --git a/js/src/jsparse.cpp b/js/src/jsparse.cpp index 7b5616fb7e4c..dd741e026ac7 100644 --- a/js/src/jsparse.cpp +++ b/js/src/jsparse.cpp @@ -56,7 +56,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsutil.h" #include "jsapi.h" #include "jsarray.h" @@ -209,9 +208,9 @@ Parser::init(const jschar *base, size_t length, const char *filename, uintN line JSContext *cx = context; if (!cx->ensureParseMapPool()) return false; - tempPoolMark = JS_ARENA_MARK(&cx->tempPool); + tempPoolMark = cx->tempLifoAlloc().mark(); if (!tokenStream.init(base, length, filename, lineno, version)) { - JS_ARENA_RELEASE(&cx->tempPool, tempPoolMark); + cx->tempLifoAlloc().release(tempPoolMark); return false; } return true; @@ -223,7 +222,7 @@ Parser::~Parser() if (principals) JSPRINCIPALS_DROP(cx, principals); - JS_ARENA_RELEASE(&cx->tempPool, tempPoolMark); + cx->tempLifoAlloc().release(tempPoolMark); cx->activeCompilations--; } @@ -247,8 +246,7 @@ Parser::newObjectBox(JSObject *obj) * containing the entries must be alive until we are done with scanning, * parsing and code generation for the whole script or top-level function. */ - JSObjectBox *objbox; - JS_ARENA_ALLOCATE_TYPE(objbox, JSObjectBox, &context->tempPool); + JSObjectBox *objbox = context->tempLifoAlloc().new_(); if (!objbox) { js_ReportOutOfMemory(context); return NULL; @@ -273,8 +271,7 @@ Parser::newFunctionBox(JSObject *obj, JSParseNode *fn, JSTreeContext *tc) * containing the entries must be alive until we are done with scanning, * parsing and code generation for the whole script or top-level function. */ - JSFunctionBox *funbox; - JS_ARENA_ALLOCATE_TYPE(funbox, JSFunctionBox, &context->tempPool); + JSFunctionBox *funbox = context->tempLifoAlloc().newPod(); if (!funbox) { js_ReportOutOfMemory(context); return NULL; @@ -677,8 +674,7 @@ NewOrRecycledNode(JSTreeContext *tc) pn = tc->parser->nodeList; if (!pn) { JSContext *cx = tc->parser->context; - - JS_ARENA_ALLOCATE_TYPE(pn, JSParseNode, &cx->tempPool); + pn = cx->tempLifoAlloc().new_(); if (!pn) js_ReportOutOfMemory(cx); } else { diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index 6c1631f8c01f..bc4c19b8e285 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -164,6 +164,8 @@ class CrossCompartmentWrapper; class TempAllocPolicy; class RuntimeAllocPolicy; +class GlobalObject; + template @@ -188,6 +190,8 @@ template class InlineMap; +class LifoAlloc; + class PropertyCache; struct PropertyCacheEntry; @@ -215,6 +219,26 @@ typedef JSPropertyOp PropertyOp; typedef JSStrictPropertyOp StrictPropertyOp; typedef JSPropertyDescriptor PropertyDescriptor; +namespace analyze { + +struct LifetimeVariable; +class LoopAnalysis; +class ScriptAnalysis; +class SlotValue; +class SSAValue; +class SSAUseChain; + +} /* namespace analyze */ + +namespace types { + +class TypeSet; +struct TypeCallsite; +struct TypeObject; +struct TypeCompartment; + +} /* namespace types */ + } /* namespace js */ } /* export "C++" */ diff --git a/js/src/jsregexpinlines.h b/js/src/jsregexpinlines.h index d2dbf8d344ed..4b3ad5f09872 100644 --- a/js/src/jsregexpinlines.h +++ b/js/src/jsregexpinlines.h @@ -149,7 +149,6 @@ class RegExp void reportPCREError(JSContext *cx, int error); #endif void reportYarrError(JSContext *cx, TokenStream *ts, JSC::Yarr::ErrorCode error); - static inline bool initArena(JSContext *cx); static inline void checkMatchPairs(JSString *input, int *buf, size_t matchItemCount); static JSObject *createResult(JSContext *cx, JSString *input, int *buf, size_t matchItemCount); inline bool executeInternal(JSContext *cx, RegExpStatics *res, JSString *input, @@ -255,27 +254,6 @@ class RegExpMatchBuilder /* RegExp inlines. */ -inline bool -RegExp::initArena(JSContext *cx) -{ - if (cx->regExpPool.first.next) - return true; - - /* - * The regular expression arena pool is special... we want to hang on to it - * until a GC is performed so rapid subsequent regexp executions don't - * thrash malloc/freeing arena chunks. - * - * Stick a timestamp at the base of that pool. - */ - int64 *timestamp; - JS_ARENA_ALLOCATE_CAST(timestamp, int64 *, &cx->regExpPool, sizeof *timestamp); - if (!timestamp) - return false; - *timestamp = JS_Now(); - return true; -} - inline void RegExp::checkMatchPairs(JSString *input, int *buf, size_t matchItemCount) { @@ -339,11 +317,8 @@ RegExp::executeInternal(JSContext *cx, RegExpStatics *res, JSString *inputstr, const size_t bufCount = pairCount * 3; /* Should be x2, but PCRE has... needs. */ const size_t matchItemCount = pairCount * 2; - if (!initArena(cx)) - return false; - - AutoArenaAllocator aaa(&cx->regExpPool); - int *buf = aaa.alloc(bufCount); + LifoAllocScope las(&cx->tempLifoAlloc()); + int *buf = cx->tempLifoAlloc().newArray(bufCount); if (!buf) return false; diff --git a/js/src/jsscan.cpp b/js/src/jsscan.cpp index 338147b80986..54f3e9e63005 100644 --- a/js/src/jsscan.cpp +++ b/js/src/jsscan.cpp @@ -54,7 +54,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsbit.h" #include "jsutil.h" #include "jsprf.h" diff --git a/js/src/jsscope.cpp b/js/src/jsscope.cpp index 00586eeeb7e8..d8fdfcec992b 100644 --- a/js/src/jsscope.cpp +++ b/js/src/jsscope.cpp @@ -46,7 +46,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsbit.h" #include "jsclist.h" #include "jsdhash.h" diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index d51ea6e3fbf2..083714c9a451 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -384,14 +384,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp) Bindings bindings(cx); uint32 nameCount = nargs + nvars + nupvars; if (nameCount > 0) { - struct AutoMark { - JSArenaPool * const pool; - void * const mark; - AutoMark(JSArenaPool *pool) : pool(pool), mark(JS_ARENA_MARK(pool)) { } - ~AutoMark() { - JS_ARENA_RELEASE(pool, mark); - } - } automark(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); /* * To xdr the names we prefix the names with a bitmap descriptor and @@ -402,9 +395,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp) * name is declared as const, not as ordinary var. * */ uintN bitmapLength = JS_HOWMANY(nameCount, JS_BITS_PER_UINT32); - uint32 *bitmap; - JS_ARENA_ALLOCATE_CAST(bitmap, uint32 *, &cx->tempPool, - bitmapLength * sizeof *bitmap); + uint32 *bitmap = cx->tempLifoAlloc().newArray(bitmapLength); if (!bitmap) { js_ReportOutOfMemory(cx); return false; diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 595cc3e06cb9..7df2fcb8d95c 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -146,8 +146,6 @@ typedef struct JSConstArray { uint32 length; } JSConstArray; -struct JSArenaPool; - namespace js { struct GlobalSlotArray { diff --git a/js/src/jstl.h b/js/src/jstl.h index 81cbc62a0bea..d62b45d6392b 100644 --- a/js/src/jstl.h +++ b/js/src/jstl.h @@ -40,7 +40,7 @@ #ifndef jstl_h_ #define jstl_h_ -#include "jspubtd.h" +#include "jsprvtd.h" #include "jsbit.h" #include "jsstaticcheck.h" #include "jsstdint.h" @@ -167,6 +167,7 @@ template <> struct IsPodType { static const bool result = template <> struct IsPodType { static const bool result = true; }; template <> struct IsPodType { static const bool result = true; }; template <> struct IsPodType { static const bool result = true; }; +template <> struct IsPodType { static const bool result = true; }; template struct IsPodType { static const bool result = true; }; /* Return the size/end of an array without using macros. */ diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index 5d128f5bc2e8..5fe8323f5bd6 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -7390,9 +7390,9 @@ TraceRecorder::monitorRecording(JSOp op) debug_only_stmt( if (LogController.lcbits & LC_TMRecorder) { - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); debug_only_print0(LC_TMRecorder, "\n"); js_Disassemble1(cx, cx->fp()->script(), cx->regs().pc, @@ -7401,7 +7401,6 @@ TraceRecorder::monitorRecording(JSOp op) !cx->fp()->hasImacropc(), &sprinter); fprintf(stdout, "%s", sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); } ) @@ -10415,14 +10414,13 @@ TraceRecorder::record_EnterFrame() callDepth); debug_only_stmt( if (LogController.lcbits & LC_TMRecorder) { - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); js_Disassemble(cx, cx->fp()->script(), JS_TRUE, &sprinter); debug_only_printf(LC_TMTracer, "%s", sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); debug_only_print0(LC_TMTracer, "----\n"); } ) diff --git a/js/src/jsutil.h b/js/src/jsutil.h index 68de3a24b5a5..473f9add429c 100644 --- a/js/src/jsutil.h +++ b/js/src/jsutil.h @@ -70,6 +70,8 @@ using namespace mozilla; JS_BEGIN_EXTERN_C +#define JS_UPTRDIFF(a_, b_) (uintptr_t(a_) - uintptr_t(b_)) + #define JS_CRASH_UNLESS(__cond) \ JS_BEGIN_MACRO \ if (!(__cond)) { \ diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index cff6d4e3fa24..25a8ef41083d 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -1462,13 +1462,12 @@ public: JS_BEGIN_MACRO \ if (IsJaegerSpewChannelActive(JSpew_JSOps)) { \ JaegerSpew(JSpew_JSOps, " %2d ", frame.stackDepth()); \ - void *mark = JS_ARENA_MARK(&cx->tempPool); \ + LifoAllocScope las(&cx->tempLifoAlloc()); \ Sprinter sprinter; \ - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); \ + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); \ js_Disassemble1(cx, script, PC, PC - script->code, \ JS_TRUE, &sprinter); \ fprintf(stdout, "%s", sprinter.base); \ - JS_ARENA_RELEASE(&cx->tempPool, mark); \ } \ JS_END_MACRO; #else @@ -6683,7 +6682,7 @@ mjit::Compiler::jumpAndTrace(Jump j, jsbytecode *target, Jump *slow, bool *tramp if (cx->typeInferenceEnabled()) { RegisterAllocation *&alloc = analysis->getAllocation(target); if (!alloc) { - alloc = ArenaNew(cx->compartment->pool, false); + alloc = cx->typeLifoAlloc().new_(false); if (!alloc) return false; } diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index 6373a3101aec..c0bd80da60d0 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -575,7 +575,7 @@ RegisterAllocation * FrameState::computeAllocation(jsbytecode *target) { JS_ASSERT(cx->typeInferenceEnabled()); - RegisterAllocation *alloc = ArenaNew(cx->compartment->pool, false); + RegisterAllocation *alloc = cx->typeLifoAlloc().new_(false); if (!alloc) return NULL; @@ -853,7 +853,7 @@ FrameState::discardForJoin(RegisterAllocation *&alloc, uint32 stackDepth) * This shows up for loop entries which are not reachable from the * loop head, and for exception, switch target and trap safe points. */ - alloc = ArenaNew(cx->compartment->pool, false); + alloc = cx->typeLifoAlloc().new_(false); if (!alloc) return false; } diff --git a/js/src/methodjit/LoopState.cpp b/js/src/methodjit/LoopState.cpp index e04d4abf5131..4777446f2d7e 100644 --- a/js/src/methodjit/LoopState.cpp +++ b/js/src/methodjit/LoopState.cpp @@ -157,7 +157,7 @@ LoopState::init(jsbytecode *head, Jump entry, jsbytecode *entryTarget) RegisterAllocation *&alloc = outerAnalysis->getAllocation(head); JS_ASSERT(!alloc); - alloc = ArenaNew(cx->compartment->pool, true); + alloc = cx->typeLifoAlloc().new_(true); if (!alloc) return false; diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 3932b56fcf70..d2c8bba4d90d 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -50,7 +50,6 @@ #include #include "jstypes.h" #include "jsstdint.h" -#include "jsarena.h" #include "jsutil.h" #include "jsprf.h" #include "jswrapper.h" @@ -1952,16 +1951,13 @@ SrcNotes(JSContext *cx, JSScript *script, Sprinter *sp) static JSBool Notes(JSContext *cx, uintN argc, jsval *vp) { - uintN i; - JSScript *script; - - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); jsval *argv = JS_ARGV(cx, vp); - for (i = 0; i < argc; i++) { - script = ValueToScript(cx, argv[i]); + for (uintN i = 0; i < argc; i++) { + JSScript *script = ValueToScript(cx, argv[i]); if (!script) continue; @@ -1969,7 +1965,6 @@ Notes(JSContext *cx, uintN argc, jsval *vp) } JSString *str = JS_NewStringCopyZ(cx, sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); if (!str) return JS_FALSE; JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str)); @@ -2110,9 +2105,9 @@ DisassembleToString(JSContext *cx, uintN argc, jsval *vp) if (!p.parse(cx)) return false; - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); Sprinter *sp = &sprinter; bool ok = true; @@ -2136,7 +2131,6 @@ DisassembleToString(JSContext *cx, uintN argc, jsval *vp) } JSString *str = ok ? JS_NewStringCopyZ(cx, sprinter.base) : NULL; - JS_ARENA_RELEASE(&cx->tempPool, mark); if (!str) return false; JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(str)); @@ -2150,9 +2144,9 @@ Disassemble(JSContext *cx, uintN argc, jsval *vp) if (!p.parse(cx)) return false; - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); Sprinter *sp = &sprinter; bool ok = true; @@ -2177,7 +2171,6 @@ Disassemble(JSContext *cx, uintN argc, jsval *vp) if (ok) fprintf(stdout, "%s\n", sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); JS_SET_RVAL(cx, vp, JSVAL_VOID); return ok; } @@ -2213,13 +2206,12 @@ DisassFile(JSContext *cx, uintN argc, jsval *vp) if (!script) return false; - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; - INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + INIT_SPRINTER(cx, &sprinter, &cx->tempLifoAlloc(), 0); bool ok = DisassembleScript(cx, script, NULL, p.lines, p.recursive, &sprinter); if (ok) fprintf(stdout, "%s\n", sprinter.base); - JS_ARENA_RELEASE(&cx->tempPool, mark); if (!ok) return false; @@ -2263,18 +2255,17 @@ DisassWithSrc(JSContext *cx, uintN argc, jsval *vp) pc = script->code; end = pc + script->length; - void *mark = JS_ARENA_MARK(&cx->tempPool); + LifoAllocScope las(&cx->tempLifoAlloc()); Sprinter sprinter; Sprinter *sp = &sprinter; - INIT_SPRINTER(cx, sp, &cx->tempPool, 0); + INIT_SPRINTER(cx, sp, &cx->tempLifoAlloc(), 0); /* burn the leading lines */ line2 = JS_PCToLineNumber(cx, script, pc); for (line1 = 0; line1 < line2 - 1; line1++) { char *tmp = fgets(linebuf, LINE_BUF_LEN, file); if (!tmp) { - JS_ReportError(cx, "failed to read %s fully", - script->filename); + JS_ReportError(cx, "failed to read %s fully", script->filename); ok = JS_FALSE; goto bail; } @@ -2315,7 +2306,6 @@ DisassWithSrc(JSContext *cx, uintN argc, jsval *vp) } bail: - JS_ARENA_RELEASE(&cx->tempPool, mark); fclose(file); } JS_SET_RVAL(cx, vp, JSVAL_VOID); diff --git a/mfbt/Util.h b/mfbt/Util.h index 8a343b2baae6..00fc9b8c73d0 100644 --- a/mfbt/Util.h +++ b/mfbt/Util.h @@ -177,12 +177,15 @@ struct DebugOnly T& operator->() { return value; } + bool operator<(const T& other) { return value < other; } + #else DebugOnly() {} DebugOnly(const T&) {} DebugOnly& operator=(const T&) { return *this; } void operator++(int) {} void operator--(int) {} + bool operator<(const T&) { return false; } #endif /* From 2e6a5d289e2c6f4f528620081e6a5bb1e3f4819a Mon Sep 17 00:00:00 2001 From: Marco Bonardo Date: Wed, 28 Sep 2011 12:04:21 +0200 Subject: [PATCH 08/65] Bug 666580 - Use a transaction for indexedDB schema creation. r=bent --- dom/indexedDB/IDBFactory.cpp | 6 ++++++ dom/indexedDB/IDBTransaction.cpp | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index 7dee39e66a35..584792c0ad73 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -412,11 +412,17 @@ CreateDatabaseConnection(const nsAString& aName, NS_ENSURE_SUCCESS(rv, rv); } + mozStorageTransaction transaction(connection, PR_FALSE, + mozIStorageConnection::TRANSACTION_IMMEDIATE); + rv = CreateTables(connection); NS_ENSURE_SUCCESS(rv, rv); rv = CreateMetaData(connection, aName); NS_ENSURE_SUCCESS(rv, rv); + + rv = transaction.Commit(); + NS_ENSURE_SUCCESS(rv, rv); } // Check to make sure that the database schema is correct again. diff --git a/dom/indexedDB/IDBTransaction.cpp b/dom/indexedDB/IDBTransaction.cpp index 03b798905772..2f040652f732 100644 --- a/dom/indexedDB/IDBTransaction.cpp +++ b/dom/indexedDB/IDBTransaction.cpp @@ -280,7 +280,7 @@ IDBTransaction::GetOrCreateConnection(mozIStorageConnection** aResult) NS_ENSURE_TRUE(connection, NS_ERROR_FAILURE); nsCString beginTransaction; - if (mMode == nsIIDBTransaction::READ_WRITE) { + if (mMode != nsIIDBTransaction::READ_ONLY) { beginTransaction.AssignLiteral("BEGIN IMMEDIATE TRANSACTION;"); } else { @@ -978,7 +978,7 @@ CommitHelper::Run() IndexedDatabaseManager::SetCurrentDatabase(database); if (!mAborted) { - NS_NAMED_LITERAL_CSTRING(release, "END TRANSACTION"); + NS_NAMED_LITERAL_CSTRING(release, "COMMIT TRANSACTION"); if (NS_FAILED(mConnection->ExecuteSimpleSQL(release))) { mAborted = true; } From 3a6204ae726a52e7f135c1e183013078513bec43 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Wed, 28 Sep 2011 09:42:36 -0400 Subject: [PATCH 09/65] Bug 689277 - Memory leak on low resource situations for Windows software updates. r=rstrong --- toolkit/xre/nsWindowsRestart.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/toolkit/xre/nsWindowsRestart.cpp b/toolkit/xre/nsWindowsRestart.cpp index d2d27a322c72..aa5549453d0c 100644 --- a/toolkit/xre/nsWindowsRestart.cpp +++ b/toolkit/xre/nsWindowsRestart.cpp @@ -243,6 +243,7 @@ WinLaunchChild(const PRUnichar *exePath, int argc, char **argv) for (int i = 0; i < argc; ++i) { argvConverted[i] = AllocConvertUTF8toUTF16(argv[i]); if (!argvConverted[i]) { + FreeAllocStrings(i, argvConverted); return FALSE; } } From cfec1877c3483665e03420239e6e786ce5eb6370 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Wed, 28 Sep 2011 10:02:36 -0400 Subject: [PATCH 10/65] Bug 596222 - Crash [@ mozilla::widget::WindowHook::Lookup] on shutdown with MaxTo enabled. r=robarnold --- widget/src/windows/TaskbarPreview.cpp | 11 +++++++++++ widget/src/windows/TaskbarPreview.h | 3 +++ widget/src/windows/TaskbarTabPreview.cpp | 5 ++++- widget/src/windows/TaskbarWindowPreview.cpp | 5 ++++- widget/src/xpwidgets/nsBaseWidget.h | 5 +++++ 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/widget/src/windows/TaskbarPreview.cpp b/widget/src/windows/TaskbarPreview.cpp index 71fedd5d9ab4..f40e3b54de5f 100644 --- a/widget/src/windows/TaskbarPreview.cpp +++ b/widget/src/windows/TaskbarPreview.cpp @@ -282,6 +282,17 @@ TaskbarPreview::Disable() { return NS_OK; } +PRBool +TaskbarPreview::IsWindowAvailable() const { + if (mWnd) { + nsWindow* win = nsWindow::GetNSWindowPtr(mWnd); + if(win && !win->HasDestroyStarted()) { + return PR_TRUE; + } + } + return PR_FALSE; +} + void TaskbarPreview::DetachFromNSWindow() { WindowHook &hook = GetWindowHook(); diff --git a/widget/src/windows/TaskbarPreview.h b/widget/src/windows/TaskbarPreview.h index 5626c9a49891..4ecc38865b2d 100644 --- a/widget/src/windows/TaskbarPreview.h +++ b/widget/src/windows/TaskbarPreview.h @@ -76,6 +76,9 @@ protected: // Detaches this preview from the nsWindow instance it's tied to virtual void DetachFromNSWindow(); + // Determines if the window is available and a destroy has not yet started + PRBool IsWindowAvailable() const; + // Marks this preview as being active virtual nsresult ShowActive(PRBool active) = 0; // Gets a reference to the window used to handle the preview messages diff --git a/widget/src/windows/TaskbarTabPreview.cpp b/widget/src/windows/TaskbarTabPreview.cpp index 3ec016e46982..c7a3aa996504 100644 --- a/widget/src/windows/TaskbarTabPreview.cpp +++ b/widget/src/windows/TaskbarTabPreview.cpp @@ -76,8 +76,11 @@ TaskbarTabPreview::~TaskbarTabPreview() { NS_ASSERTION(!mProxyWindow, "Taskbar proxy window was not destroyed!"); - if (mWnd) + if (IsWindowAvailable()) { DetachFromNSWindow(); + } else { + mWnd = NULL; + } } nsresult diff --git a/widget/src/windows/TaskbarWindowPreview.cpp b/widget/src/windows/TaskbarWindowPreview.cpp index 3d0cfc8ad09a..d31ab35182f8 100644 --- a/widget/src/windows/TaskbarWindowPreview.cpp +++ b/widget/src/windows/TaskbarWindowPreview.cpp @@ -101,8 +101,11 @@ TaskbarWindowPreview::TaskbarWindowPreview(ITaskbarList4 *aTaskbar, nsITaskbarPr } TaskbarWindowPreview::~TaskbarWindowPreview() { - if (mWnd) + if (IsWindowAvailable()) { DetachFromNSWindow(); + } else { + mWnd = NULL; + } } nsresult diff --git a/widget/src/xpwidgets/nsBaseWidget.h b/widget/src/xpwidgets/nsBaseWidget.h index 8cc4a82958ef..2f92cd2e8871 100644 --- a/widget/src/xpwidgets/nsBaseWidget.h +++ b/widget/src/xpwidgets/nsBaseWidget.h @@ -219,6 +219,11 @@ public: }; friend class AutoUseBasicLayerManager; + PRBool HasDestroyStarted() const + { + return mOnDestroyCalled; + } + PRBool Destroyed() { return mOnDestroyCalled; } protected: From 97b3261d71bd16abbd3eaddb8bc06d98ff867dc6 Mon Sep 17 00:00:00 2001 From: Jeff Muizelaar Date: Tue, 27 Sep 2011 12:24:03 -0400 Subject: [PATCH 11/65] Bug 688238. imglib: Move Decoder::Init() arguments into the constructor. r=joedrew This makes the lifetime of the arguments more clear. i.e. that they stay the same for the lifetime of the decoder. --HG-- extra : rebase_source : 99726522b99d9d546f41d1d4e78e44224101e9b3 --- modules/libpr0n/decoders/nsBMPDecoder.cpp | 21 +++++++------- modules/libpr0n/decoders/nsBMPDecoder.h | 2 +- modules/libpr0n/decoders/nsGIFDecoder2.cpp | 5 ++-- modules/libpr0n/decoders/nsGIFDecoder2.h | 2 +- modules/libpr0n/decoders/nsICODecoder.cpp | 11 ++++---- modules/libpr0n/decoders/nsICODecoder.h | 2 +- modules/libpr0n/decoders/nsIconDecoder.cpp | 15 +++++----- modules/libpr0n/decoders/nsIconDecoder.h | 2 +- modules/libpr0n/decoders/nsJPEGDecoder.cpp | 3 +- modules/libpr0n/decoders/nsJPEGDecoder.h | 2 +- modules/libpr0n/decoders/nsPNGDecoder.cpp | 15 +++++----- modules/libpr0n/decoders/nsPNGDecoder.h | 2 +- modules/libpr0n/src/Decoder.cpp | 32 ++++++++-------------- modules/libpr0n/src/Decoder.h | 6 ++-- modules/libpr0n/src/RasterImage.cpp | 16 +++++------ 15 files changed, 67 insertions(+), 69 deletions(-) diff --git a/modules/libpr0n/decoders/nsBMPDecoder.cpp b/modules/libpr0n/decoders/nsBMPDecoder.cpp index aba276bcf091..0e7b9a2a4125 100644 --- a/modules/libpr0n/decoders/nsBMPDecoder.cpp +++ b/modules/libpr0n/decoders/nsBMPDecoder.cpp @@ -63,17 +63,18 @@ PRLogModuleInfo *gBMPLog = PR_NewLogModule("BMPDecoder"); #define LINE(row) ((mBIH.height < 0) ? (-mBIH.height - (row)) : ((row) - 1)) #define PIXEL_OFFSET(row, col) (LINE(row) * mBIH.width + col) -nsBMPDecoder::nsBMPDecoder() +nsBMPDecoder::nsBMPDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver) + : Decoder(aImage, aObserver) { - mColors = nsnull; - mRow = nsnull; - mImageData = nsnull; - mCurPos = mPos = mNumColors = mRowBytes = 0; - mOldLine = mCurLine = 1; // Otherwise decoder will never start - mState = eRLEStateInitial; - mStateData = 0; - mLOH = WIN_HEADER_LENGTH; - mUseAlphaData = mHaveAlphaData = PR_FALSE; + mColors = nsnull; + mRow = nsnull; + mImageData = nsnull; + mCurPos = mPos = mNumColors = mRowBytes = 0; + mOldLine = mCurLine = 1; // Otherwise decoder will never start + mState = eRLEStateInitial; + mStateData = 0; + mLOH = WIN_HEADER_LENGTH; + mUseAlphaData = mHaveAlphaData = PR_FALSE; } nsBMPDecoder::~nsBMPDecoder() diff --git a/modules/libpr0n/decoders/nsBMPDecoder.h b/modules/libpr0n/decoders/nsBMPDecoder.h index 4576b23f3357..d6dbc2319c6b 100644 --- a/modules/libpr0n/decoders/nsBMPDecoder.h +++ b/modules/libpr0n/decoders/nsBMPDecoder.h @@ -59,7 +59,7 @@ class nsBMPDecoder : public Decoder { public: - nsBMPDecoder(); + nsBMPDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver); ~nsBMPDecoder(); // Specifies whether or not the BMP file will contain alpha data diff --git a/modules/libpr0n/decoders/nsGIFDecoder2.cpp b/modules/libpr0n/decoders/nsGIFDecoder2.cpp index e1a36015ba45..2bbe7fdc425d 100644 --- a/modules/libpr0n/decoders/nsGIFDecoder2.cpp +++ b/modules/libpr0n/decoders/nsGIFDecoder2.cpp @@ -107,8 +107,9 @@ namespace imagelib { ////////////////////////////////////////////////////////////////////// // GIF Decoder Implementation -nsGIFDecoder2::nsGIFDecoder2() - : mCurrentRow(-1) +nsGIFDecoder2::nsGIFDecoder2(RasterImage *aImage, imgIDecoderObserver* aObserver) + : Decoder(aImage, aObserver) + , mCurrentRow(-1) , mLastFlushedRow(-1) , mImageData(nsnull) , mOldColor(0) diff --git a/modules/libpr0n/decoders/nsGIFDecoder2.h b/modules/libpr0n/decoders/nsGIFDecoder2.h index a9c419ac2a2d..d022316c41e0 100644 --- a/modules/libpr0n/decoders/nsGIFDecoder2.h +++ b/modules/libpr0n/decoders/nsGIFDecoder2.h @@ -58,7 +58,7 @@ class nsGIFDecoder2 : public Decoder { public: - nsGIFDecoder2(); + nsGIFDecoder2(RasterImage *aImage, imgIDecoderObserver* aObserver); ~nsGIFDecoder2(); virtual void WriteInternal(const char* aBuffer, PRUint32 aCount); diff --git a/modules/libpr0n/decoders/nsICODecoder.cpp b/modules/libpr0n/decoders/nsICODecoder.cpp index f6f5d2a1b97c..b19846c4b439 100644 --- a/modules/libpr0n/decoders/nsICODecoder.cpp +++ b/modules/libpr0n/decoders/nsICODecoder.cpp @@ -99,7 +99,8 @@ nsICODecoder::GetNumColors() } -nsICODecoder::nsICODecoder() +nsICODecoder::nsICODecoder(RasterImage *aImage, imgIDecoderObserver* aObserver) + : Decoder(aImage, aObserver) { mPos = mImageOffset = mCurrIcon = mNumIcons = mBPP = mRowBytes = 0; mIsPNG = PR_FALSE; @@ -317,8 +318,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) mIsPNG = !memcmp(mSignature, nsPNGDecoder::pngSignatureBytes, PNGSIGNATURESIZE); if (mIsPNG) { - mContainedDecoder = new nsPNGDecoder(); - mContainedDecoder->InitSharedDecoder(mImage, mObserver); + mContainedDecoder = new nsPNGDecoder(mImage, mObserver); + mContainedDecoder->InitSharedDecoder(); mContainedDecoder->Write(mSignature, PNGSIGNATURESIZE); mDataError = mContainedDecoder->HasDataError(); if (mContainedDecoder->HasDataError()) { @@ -386,11 +387,11 @@ nsICODecoder::WriteInternal(const char* aBuffer, PRUint32 aCount) // Init the bitmap decoder which will do most of the work for us // It will do everything except the AND mask which isn't present in bitmaps // bmpDecoder is for local scope ease, it will be freed by mContainedDecoder - nsBMPDecoder *bmpDecoder = new nsBMPDecoder(); + nsBMPDecoder *bmpDecoder = new nsBMPDecoder(mImage, mObserver); mContainedDecoder = bmpDecoder; bmpDecoder->SetUseAlphaData(PR_TRUE); mContainedDecoder->SetSizeDecode(IsSizeDecode()); - mContainedDecoder->InitSharedDecoder(mImage, mObserver); + mContainedDecoder->InitSharedDecoder(); // The ICO format when containing a BMP does not include the 14 byte // bitmap file header. To use the code of the BMP decoder we need to diff --git a/modules/libpr0n/decoders/nsICODecoder.h b/modules/libpr0n/decoders/nsICODecoder.h index 3f012c58acdb..c9f9b4499a4f 100644 --- a/modules/libpr0n/decoders/nsICODecoder.h +++ b/modules/libpr0n/decoders/nsICODecoder.h @@ -58,7 +58,7 @@ class nsICODecoder : public Decoder { public: - nsICODecoder(); + nsICODecoder(RasterImage *aImage, imgIDecoderObserver* aObserver); virtual ~nsICODecoder(); // Obtains the width of the icon directory entry diff --git a/modules/libpr0n/decoders/nsIconDecoder.cpp b/modules/libpr0n/decoders/nsIconDecoder.cpp index 1c833e024f25..2e0708f922c6 100644 --- a/modules/libpr0n/decoders/nsIconDecoder.cpp +++ b/modules/libpr0n/decoders/nsIconDecoder.cpp @@ -50,13 +50,14 @@ namespace mozilla { namespace imagelib { -nsIconDecoder::nsIconDecoder() : - mWidth(-1), - mHeight(-1), - mPixBytesRead(0), - mPixBytesTotal(0), - mImageData(nsnull), - mState(iconStateStart) +nsIconDecoder::nsIconDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver) + : Decoder(aImage, aObserver), + mWidth(-1), + mHeight(-1), + mPixBytesRead(0), + mPixBytesTotal(0), + mImageData(nsnull), + mState(iconStateStart) { // Nothing to do } diff --git a/modules/libpr0n/decoders/nsIconDecoder.h b/modules/libpr0n/decoders/nsIconDecoder.h index 3828e59f8e43..2f228cde330d 100644 --- a/modules/libpr0n/decoders/nsIconDecoder.h +++ b/modules/libpr0n/decoders/nsIconDecoder.h @@ -74,7 +74,7 @@ class nsIconDecoder : public Decoder { public: - nsIconDecoder(); + nsIconDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver); virtual ~nsIconDecoder(); virtual void WriteInternal(const char* aBuffer, PRUint32 aCount); diff --git a/modules/libpr0n/decoders/nsJPEGDecoder.cpp b/modules/libpr0n/decoders/nsJPEGDecoder.cpp index abb2b3f1a855..a123e1c5918e 100644 --- a/modules/libpr0n/decoders/nsJPEGDecoder.cpp +++ b/modules/libpr0n/decoders/nsJPEGDecoder.cpp @@ -109,7 +109,8 @@ METHODDEF(void) my_error_exit (j_common_ptr cinfo); #define MAX_JPEG_MARKER_LENGTH (((PRUint32)1 << 16) - 1) -nsJPEGDecoder::nsJPEGDecoder() +nsJPEGDecoder::nsJPEGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver) + : Decoder(aImage, aObserver) { mState = JPEG_HEADER; mReading = PR_TRUE; diff --git a/modules/libpr0n/decoders/nsJPEGDecoder.h b/modules/libpr0n/decoders/nsJPEGDecoder.h index ecee5ccfebb7..e4b1dadd6290 100644 --- a/modules/libpr0n/decoders/nsJPEGDecoder.h +++ b/modules/libpr0n/decoders/nsJPEGDecoder.h @@ -86,7 +86,7 @@ class RasterImage; class nsJPEGDecoder : public Decoder { public: - nsJPEGDecoder(); + nsJPEGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver); virtual ~nsJPEGDecoder(); virtual void InitInternal(); diff --git a/modules/libpr0n/decoders/nsPNGDecoder.cpp b/modules/libpr0n/decoders/nsPNGDecoder.cpp index ed1415c9c2a0..7b5838032170 100644 --- a/modules/libpr0n/decoders/nsPNGDecoder.cpp +++ b/modules/libpr0n/decoders/nsPNGDecoder.cpp @@ -81,13 +81,14 @@ static PRLogModuleInfo *gPNGDecoderAccountingLog = const PRUint8 nsPNGDecoder::pngSignatureBytes[] = { 137, 80, 78, 71, 13, 10, 26, 10 }; -nsPNGDecoder::nsPNGDecoder() : - mPNG(nsnull), mInfo(nsnull), - mCMSLine(nsnull), interlacebuf(nsnull), - mInProfile(nsnull), mTransform(nsnull), - mHeaderBuf(nsnull), mHeaderBytesRead(0), - mChannels(0), mFrameIsHidden(PR_FALSE), - mCMSMode(0), mDisablePremultipliedAlpha(PR_FALSE) +nsPNGDecoder::nsPNGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver) + : Decoder(aImage, aObserver), + mPNG(nsnull), mInfo(nsnull), + mCMSLine(nsnull), interlacebuf(nsnull), + mInProfile(nsnull), mTransform(nsnull), + mHeaderBuf(nsnull), mHeaderBytesRead(0), + mChannels(0), mFrameIsHidden(PR_FALSE), + mCMSMode(0), mDisablePremultipliedAlpha(PR_FALSE) { } diff --git a/modules/libpr0n/decoders/nsPNGDecoder.h b/modules/libpr0n/decoders/nsPNGDecoder.h index 58747986acf0..bba8d2368eeb 100644 --- a/modules/libpr0n/decoders/nsPNGDecoder.h +++ b/modules/libpr0n/decoders/nsPNGDecoder.h @@ -59,7 +59,7 @@ class RasterImage; class nsPNGDecoder : public Decoder { public: - nsPNGDecoder(); + nsPNGDecoder(RasterImage *aImage, imgIDecoderObserver* aObserver); virtual ~nsPNGDecoder(); virtual void InitInternal(); diff --git a/modules/libpr0n/src/Decoder.cpp b/modules/libpr0n/src/Decoder.cpp index 7cf7461c881e..c40a68a12f52 100644 --- a/modules/libpr0n/src/Decoder.cpp +++ b/modules/libpr0n/src/Decoder.cpp @@ -44,7 +44,7 @@ namespace mozilla { namespace imagelib { -Decoder::Decoder() +Decoder::Decoder(RasterImage *aImage, imgIDecoderObserver* aObserver) : mDecodeFlags(0) , mFrameCount(0) , mFailCode(NS_OK) @@ -54,6 +54,12 @@ Decoder::Decoder() , mDecodeDone(false) , mDataError(false) { + // We should always have an image + NS_ABORT_IF_FALSE(aImage, "Can't initialize decoder without an image!"); + + // Save our paremeters + mImage = aImage; + mObserver = aObserver; } Decoder::~Decoder() @@ -67,17 +73,10 @@ Decoder::~Decoder() */ void -Decoder::Init(RasterImage* aImage, imgIDecoderObserver* aObserver) +Decoder::Init() { - // We should always have an image - NS_ABORT_IF_FALSE(aImage, "Can't initialize decoder without an image!"); - // No re-initializing - NS_ABORT_IF_FALSE(mImage == nsnull, "Can't re-initialize a decoder!"); - - // Save our paremeters - mImage = aImage; - mObserver = aObserver; + NS_ABORT_IF_FALSE(!mInitialized, "Can't re-initialize a decoder!"); // Fire OnStartDecode at init time to support bug 512435 if (!IsSizeDecode() && mObserver) @@ -90,18 +89,11 @@ Decoder::Init(RasterImage* aImage, imgIDecoderObserver* aObserver) // Initializes a decoder whose aImage and aObserver is already being used by a // parent decoder -void -Decoder::InitSharedDecoder(RasterImage* aImage, imgIDecoderObserver* aObserver) +void +Decoder::InitSharedDecoder() { - // We should always have an image - NS_ABORT_IF_FALSE(aImage, "Can't initialize decoder without an image!"); - // No re-initializing - NS_ABORT_IF_FALSE(mImage == nsnull, "Can't re-initialize a decoder!"); - - // Save our parameters - mImage = aImage; - mObserver = aObserver; + NS_ABORT_IF_FALSE(!mInitialized, "Can't re-initialize a decoder!"); // Implementation-specific initialization InitInternal(); diff --git a/modules/libpr0n/src/Decoder.h b/modules/libpr0n/src/Decoder.h index 5053e8a61b94..869c509385e0 100644 --- a/modules/libpr0n/src/Decoder.h +++ b/modules/libpr0n/src/Decoder.h @@ -50,7 +50,7 @@ class Decoder { public: - Decoder(); + Decoder(RasterImage* aImage, imgIDecoderObserver* aObserver); virtual ~Decoder(); /** @@ -61,7 +61,7 @@ public: * * Notifications Sent: TODO */ - void Init(RasterImage* aImage, imgIDecoderObserver* aObserver); + void Init(); /** @@ -73,7 +73,7 @@ public: * * Notifications Sent: TODO */ - void InitSharedDecoder(RasterImage* aImage, imgIDecoderObserver* aObserver); + void InitSharedDecoder(); /** * Writes data to the decoder. diff --git a/modules/libpr0n/src/RasterImage.cpp b/modules/libpr0n/src/RasterImage.cpp index f3a27d613533..50ace6aaf116 100644 --- a/modules/libpr0n/src/RasterImage.cpp +++ b/modules/libpr0n/src/RasterImage.cpp @@ -2167,35 +2167,35 @@ RasterImage::InitDecoder(bool aDoSizeDecode) eDecoderType type = GetDecoderType(mSourceDataMimeType.get()); CONTAINER_ENSURE_TRUE(type != eDecoderType_unknown, NS_IMAGELIB_ERROR_NO_DECODER); + nsCOMPtr observer(do_QueryReferent(mObserver)); // Instantiate the appropriate decoder switch (type) { case eDecoderType_png: - mDecoder = new nsPNGDecoder(); + mDecoder = new nsPNGDecoder(this, observer); break; case eDecoderType_gif: - mDecoder = new nsGIFDecoder2(); + mDecoder = new nsGIFDecoder2(this, observer); break; case eDecoderType_jpeg: - mDecoder = new nsJPEGDecoder(); + mDecoder = new nsJPEGDecoder(this, observer); break; case eDecoderType_bmp: - mDecoder = new nsBMPDecoder(); + mDecoder = new nsBMPDecoder(this, observer); break; case eDecoderType_ico: - mDecoder = new nsICODecoder(); + mDecoder = new nsICODecoder(this, observer); break; case eDecoderType_icon: - mDecoder = new nsIconDecoder(); + mDecoder = new nsIconDecoder(this, observer); break; default: NS_ABORT_IF_FALSE(0, "Shouldn't get here!"); } // Initialize the decoder - nsCOMPtr observer(do_QueryReferent(mObserver)); mDecoder->SetSizeDecode(aDoSizeDecode); mDecoder->SetDecodeFlags(mFrameDecodeFlags); - mDecoder->Init(this, observer); + mDecoder->Init(); CONTAINER_ENSURE_SUCCESS(mDecoder->GetDecoderError()); // Create a decode worker From cfd701369563e7c56d8dec5bf2c2c1a41e398668 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 28 Sep 2011 11:54:50 -0400 Subject: [PATCH 12/65] Bug 689564. Only forward event attributes on body/frameset to the window if we also forward the corresponding on* property. r=smaug --- .../base/content/test/browser_tab_dragdrop.js | 2 +- content/base/src/nsGenericElement.cpp | 6 +- content/base/src/nsGenericElement.h | 2 +- content/events/public/nsEventNameList.h | 3 + content/events/test/Makefile.in | 1 + content/events/test/test_bug689564.html | 65 +++++++++++++++++++ .../html/content/src/nsGenericHTMLElement.cpp | 22 +++++-- .../html/content/src/nsGenericHTMLElement.h | 2 +- content/xul/content/src/nsXULElement.cpp | 4 +- content/xul/content/src/nsXULElement.h | 2 +- dom/tests/mochitest/bugs/test_bug531176.html | 6 ++ layout/base/tests/chrome/test_bug533845.xul | 9 ++- 12 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 content/events/test/test_bug689564.html diff --git a/browser/base/content/test/browser_tab_dragdrop.js b/browser/base/content/test/browser_tab_dragdrop.js index a1376f035144..b229dc927806 100644 --- a/browser/base/content/test/browser_tab_dragdrop.js +++ b/browser/base/content/test/browser_tab_dragdrop.js @@ -21,7 +21,7 @@ function test() } function clickTest(doc, win) { var clicks = doc.defaultView.clicks; - EventUtils.synthesizeMouse(doc.body, 100, 600, {}, win); + EventUtils.synthesizeMouseAtCenter(doc.body, {}, win); is(doc.defaultView.clicks, clicks+1, "adding 1 more click on BODY"); } function test1() { diff --git a/content/base/src/nsGenericElement.cpp b/content/base/src/nsGenericElement.cpp index 35f9bd680d95..32b00035d87a 100644 --- a/content/base/src/nsGenericElement.cpp +++ b/content/base/src/nsGenericElement.cpp @@ -4424,7 +4424,8 @@ nsGenericElement::AddScriptEventListener(nsIAtom* aEventName, NS_PRECONDITION(aEventName, "Must have event name!"); PRBool defer = PR_TRUE; - nsEventListenerManager* manager = GetEventListenerManagerForAttr(&defer); + nsEventListenerManager* manager = GetEventListenerManagerForAttr(aEventName, + &defer); if (!manager) { return NS_OK; } @@ -4701,7 +4702,8 @@ nsGenericElement::SetMappedAttribute(nsIDocument* aDocument, } nsEventListenerManager* -nsGenericElement::GetEventListenerManagerForAttr(PRBool* aDefer) +nsGenericElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName, + PRBool* aDefer) { *aDefer = PR_TRUE; return GetListenerManager(PR_TRUE); diff --git a/content/base/src/nsGenericElement.h b/content/base/src/nsGenericElement.h index 2cd0e4614fa4..6df162defa1a 100644 --- a/content/base/src/nsGenericElement.h +++ b/content/base/src/nsGenericElement.h @@ -780,7 +780,7 @@ protected: * needed for attachment of attribute-defined handlers */ virtual nsEventListenerManager* - GetEventListenerManagerForAttr(PRBool* aDefer); + GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer); /** * Copy attributes and state to another element diff --git a/content/events/public/nsEventNameList.h b/content/events/public/nsEventNameList.h index bd6c9c37b6d6..d0f3ee2b6166 100644 --- a/content/events/public/nsEventNameList.h +++ b/content/events/public/nsEventNameList.h @@ -78,6 +78,9 @@ * Event names that are not exposed as IDL attributes at all should be * enclosed in NON_IDL_EVENT. If NON_IDL_EVENT is not defined, it * will be defined to the empty string. + * + * If you change which macros event names are enclosed in, please + * update the tests for bug 689564 and bug 659350 as needed. */ #ifdef DEFINED_FORWARDED_EVENT diff --git a/content/events/test/Makefile.in b/content/events/test/Makefile.in index cb95a412c85d..991720700a24 100644 --- a/content/events/test/Makefile.in +++ b/content/events/test/Makefile.in @@ -111,6 +111,7 @@ _TEST_FILES = \ test_bug667919-2.html \ test_bug667612.html \ empty.js \ + test_bug689564.html \ $(NULL) #bug 585630 diff --git a/content/events/test/test_bug689564.html b/content/events/test/test_bug689564.html new file mode 100644 index 000000000000..4553c360d12f --- /dev/null +++ b/content/events/test/test_bug689564.html @@ -0,0 +1,65 @@ + + + + + Test for Bug 689564 + + + + +Mozilla Bug 689564 +

+ +
+
+
+ + diff --git a/content/html/content/src/nsGenericHTMLElement.cpp b/content/html/content/src/nsGenericHTMLElement.cpp index 7c702866dcb4..3af7aafcaf99 100644 --- a/content/html/content/src/nsGenericHTMLElement.cpp +++ b/content/html/content/src/nsGenericHTMLElement.cpp @@ -1235,11 +1235,24 @@ nsGenericHTMLElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName, } nsEventListenerManager* -nsGenericHTMLElement::GetEventListenerManagerForAttr(PRBool* aDefer) +nsGenericHTMLElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName, + PRBool* aDefer) { // Attributes on the body and frameset tags get set on the global object - if (mNodeInfo->Equals(nsGkAtoms::body) || - mNodeInfo->Equals(nsGkAtoms::frameset)) { + if ((mNodeInfo->Equals(nsGkAtoms::body) || + mNodeInfo->Equals(nsGkAtoms::frameset)) && + // We only forward some event attributes from body/frameset to window + (0 +#define EVENT(name_, id_, type_, struct_) /* nothing */ +#define FORWARDED_EVENT(name_, id_, type_, struct_) \ + || nsGkAtoms::on##name_ == aAttrName +#define WINDOW_EVENT FORWARDED_EVENT +#include "nsEventNameList.h" +#undef WINDOW_EVENT +#undef FORWARDED_EVENT +#undef EVENT + ) + ) { nsPIDOMWindow *win; // If we have a document, and it has a window, add the event @@ -1265,7 +1278,8 @@ nsGenericHTMLElement::GetEventListenerManagerForAttr(PRBool* aDefer) return nsnull; } - return nsGenericHTMLElementBase::GetEventListenerManagerForAttr(aDefer); + return nsGenericHTMLElementBase::GetEventListenerManagerForAttr(aAttrName, + aDefer); } nsresult diff --git a/content/html/content/src/nsGenericHTMLElement.h b/content/html/content/src/nsGenericHTMLElement.h index f152e1df360f..db5781a6e3e5 100644 --- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -607,7 +607,7 @@ protected: const nsAString* aValue, PRBool aNotify); virtual nsEventListenerManager* - GetEventListenerManagerForAttr(PRBool* aDefer); + GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer); virtual const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const; diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index 5b8acd7f6618..3a66ce79790e 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -509,7 +509,7 @@ nsXULElement::GetElementsByAttributeNS(const nsAString& aNamespaceURI, } nsEventListenerManager* -nsXULElement::GetEventListenerManagerForAttr(PRBool* aDefer) +nsXULElement::GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer) { // XXXbz sXBL/XBL2 issue: should we instead use GetCurrentDoc() // here, override BindToTree for those classes and munge event @@ -529,7 +529,7 @@ nsXULElement::GetEventListenerManagerForAttr(PRBool* aDefer) return piTarget->GetListenerManager(PR_TRUE); } - return nsStyledElement::GetEventListenerManagerForAttr(aDefer); + return nsStyledElement::GetEventListenerManagerForAttr(aAttrName, aDefer); } // returns true if the element is not a list diff --git a/content/xul/content/src/nsXULElement.h b/content/xul/content/src/nsXULElement.h index 14e6ff71cf3b..237394eb2c97 100644 --- a/content/xul/content/src/nsXULElement.h +++ b/content/xul/content/src/nsXULElement.h @@ -637,7 +637,7 @@ protected: nsAttrValue& aResult); virtual nsEventListenerManager* - GetEventListenerManagerForAttr(PRBool* aDefer); + GetEventListenerManagerForAttr(nsIAtom* aAttrName, PRBool* aDefer); /** * Return our prototype's attribute, if one exists. diff --git a/dom/tests/mochitest/bugs/test_bug531176.html b/dom/tests/mochitest/bugs/test_bug531176.html index 66a6c728c320..25c888871b9f 100644 --- a/dom/tests/mochitest/bugs/test_bug531176.html +++ b/dom/tests/mochitest/bugs/test_bug531176.html @@ -29,6 +29,8 @@ function errorHandler(msg, filename, linenr) { window.onerror = errorHandler; document.body.setAttribute("onclick", "var x=;"); +// Force eager compilation +document.body.onclick; is(errorCount, 1, "Error handler should have been called! (1)"); function recursiveHandler(msg, filename, linenr) { @@ -41,10 +43,14 @@ function recursiveHandler(msg, filename, linenr) { window.onerror = recursiveHandler; document.body.setAttribute("onclick", "var y=;"); +// Force eager compilation +document.body.onclick; is(errorCount, 2, "Error handler should have been called! (2)"); // Check that error handler works even after recursion error. document.body.setAttribute("onclick", "var foo=;"); +// Force eager compilation +document.body.onclick; is(errorCount, 3, "Error handler should have been called! (3)"); window.onerror = function() { ++errorCount; }; diff --git a/layout/base/tests/chrome/test_bug533845.xul b/layout/base/tests/chrome/test_bug533845.xul index 9fb0e0f67355..d51a41e85087 100644 --- a/layout/base/tests/chrome/test_bug533845.xul +++ b/layout/base/tests/chrome/test_bug533845.xul @@ -31,11 +31,14 @@ function continueTest() { ifrwindow.focus(); var utils = ifrwindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); - utils.sendMouseEvent("mousedown", 1, 1, 0, 1, 0); - utils.sendMouseEvent("mouseup", 1, 1, 0, 1, 0); + var rect = ifrwindow.document.body.getBoundingClientRect(); + var x = rect.left + (rect.width/2); + var y = rect.top + (rect.height/2); + utils.sendMouseEvent("mousedown", x, y, 0, 1, 0); + utils.sendMouseEvent("mouseup", x, y, 0, 1, 0); is(ifrwindow.document.body.textContent, 1, "Should have got a click event!"); SimpleTest.finish(); } ]]> - \ No newline at end of file + From a34e22a856e8f61f066ceb4147b451294d92566b Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Wed, 28 Sep 2011 17:22:41 +0100 Subject: [PATCH 13/65] Bug 689524 - Show title on tabs showing about:home (r=mbrubeck) --- mobile/chrome/content/browser-ui.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mobile/chrome/content/browser-ui.js b/mobile/chrome/content/browser-ui.js index 754361754e20..54a84081c077 100644 --- a/mobile/chrome/content/browser-ui.js +++ b/mobile/chrome/content/browser-ui.js @@ -117,16 +117,18 @@ var BrowserUI = { _titleChanged: function(aBrowser) { let url = this.getDisplayURI(aBrowser); - let caption = aBrowser.contentTitle || url; + let contentTitle = aBrowser.contentTitle; + let caption = contentTitle || url; + let tabCaption = contentTitle || (Util.isURLEmpty(url) ? "" : url); - if (aBrowser.contentTitle == "" && !Util.isURLEmpty(aBrowser.userTypedValue)) - caption = aBrowser.userTypedValue; + if (contentTitle == "" && !Util.isURLEmpty(aBrowser.userTypedValue)) + caption = tabCaption = aBrowser.userTypedValue; else if (Util.isURLEmpty(url)) caption = ""; let tab = Browser.getTabForBrowser(aBrowser); if (tab) - tab.chromeTab.updateTitle(caption); + tab.chromeTab.updateTitle(tabCaption); let browser = Browser.selectedBrowser; if (browser && aBrowser != browser) From 42b2e176fe825a99b488c02185eaa15d2575f18d Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Wed, 28 Sep 2011 17:50:19 +0100 Subject: [PATCH 14/65] Bug 689349 - Don't suggest values for password text boxes (r=mfinkle) --- mobile/chrome/content/forms.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mobile/chrome/content/forms.js b/mobile/chrome/content/forms.js index 4c6b8665c603..151a3739b3d9 100644 --- a/mobile/chrome/content/forms.js +++ b/mobile/chrome/content/forms.js @@ -546,6 +546,9 @@ FormAssistant.prototype = { _isAutocomplete: function formHelperIsAutocomplete(aElement) { if (aElement instanceof HTMLInputElement) { + if (aElement.getAttribute("type") == "password") + return false; + let autocomplete = aElement.getAttribute("autocomplete"); let allowedValues = ["off", "false", "disabled"]; if (allowedValues.indexOf(autocomplete) == -1) From c9c1e201ceccaf38f85c230872897e71531fedc7 Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Wed, 28 Sep 2011 08:48:16 -0700 Subject: [PATCH 15/65] Bug 683361 - Fix part 6: add and call Proxy::objectClassIs (r=waldo) --HG-- extra : rebase_source : b387bc288a45fc985df06ce2ca84823cf45803b3 --- .../tests/basic/testCrossCompartmentTransparency2.js | 10 ++++++++++ js/src/jsobjinlines.h | 2 +- js/src/jsproxy.cpp | 10 +++++++++- js/src/jsproxy.h | 3 ++- js/src/jswrapper.cpp | 2 +- js/src/jswrapper.h | 2 +- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js index 73a1f43d6778..74ae158f6d81 100644 --- a/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js +++ b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js @@ -13,3 +13,13 @@ assertEq(JSON.stringify({2:'ponies', unicorns:'not real'}, array), "{\"2\":\"pon assertEq(JSON.stringify({42:true, ponies:true, unicorns:'sad'}, [number, string]), "{\"42\":true,\"ponies\":true}"); assertEq(JSON.stringify({a:true,b:false}, undefined, number), "{\n \"a\": true,\n \"b\": false\n}"); assertEq(JSON.stringify({a:true,b:false}, undefined, string), "{\nponies\"a\": true,\nponies\"b\": false\n}"); + +var o = Proxy.create({getPropertyDescriptor:function(name) {}}, Object.prototype); +var threw = false; +try { + print([].concat(o).toString()); +} catch(e) { + assertEq(e instanceof TypeError, true); + threw = true; +} +assertEq(threw, true); diff --git a/js/src/jsobjinlines.h b/js/src/jsobjinlines.h index b098b22dd0b5..adc929515dcc 100644 --- a/js/src/jsobjinlines.h +++ b/js/src/jsobjinlines.h @@ -1753,7 +1753,7 @@ inline bool ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx) { if (JS_UNLIKELY(obj.isProxy())) - return obj.getProxyHandler()->classPropertyIs(cx, &obj, classValue); + return Proxy::objectClassIs(&obj, classValue, cx); switch (classValue) { case ESClass_Array: return obj.isArray(); diff --git a/js/src/jsproxy.cpp b/js/src/jsproxy.cpp index eb2b85b93da5..c5623d36580f 100644 --- a/js/src/jsproxy.cpp +++ b/js/src/jsproxy.cpp @@ -314,7 +314,7 @@ ProxyHandler::typeOf(JSContext *cx, JSObject *proxy) } bool -ProxyHandler::classPropertyIs(JSContext *cx, JSObject *proxy, ESClassValue classValue) +ProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx) { JS_ASSERT(OperationInProgress(cx, proxy)); return false; @@ -874,6 +874,14 @@ Proxy::typeOf(JSContext *cx, JSObject *proxy) return proxy->getProxyHandler()->typeOf(cx, proxy); } +bool +Proxy::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx) +{ + JS_CHECK_RECURSION(cx, JS_NOT_REACHED("cannot reenter")); + AutoPendingProxyOperation pending(cx, proxy); + return proxy->getProxyHandler()->objectClassIs(proxy, classValue, cx); +} + JSString * Proxy::obj_toString(JSContext *cx, JSObject *proxy) { diff --git a/js/src/jsproxy.h b/js/src/jsproxy.h index 75efa3ba3122..4e3d7a3db7d1 100644 --- a/js/src/jsproxy.h +++ b/js/src/jsproxy.h @@ -82,7 +82,7 @@ class JS_FRIEND_API(ProxyHandler) { virtual bool nativeCall(JSContext *cx, JSObject *proxy, Class *clasp, Native native, CallArgs args); virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp); virtual JSType typeOf(JSContext *cx, JSObject *proxy); - virtual bool classPropertyIs(JSContext *cx, JSObject *obj, ESClassValue classValue); + virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx); virtual JSString *obj_toString(JSContext *cx, JSObject *proxy); virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent); virtual bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp); @@ -131,6 +131,7 @@ class Proxy { static bool nativeCall(JSContext *cx, JSObject *proxy, Class *clasp, Native native, CallArgs args); static bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp); static JSType typeOf(JSContext *cx, JSObject *proxy); + static bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx); static JSString *obj_toString(JSContext *cx, JSObject *proxy); static JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent); static bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp); diff --git a/js/src/jswrapper.cpp b/js/src/jswrapper.cpp index 7d809d90c60c..63a4bedd6dca 100644 --- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -292,7 +292,7 @@ Wrapper::typeOf(JSContext *cx, JSObject *wrapper) } bool -Wrapper::classPropertyIs(JSContext *cx, JSObject *wrapper, ESClassValue classValue) +Wrapper::objectClassIs(JSObject *wrapper, ESClassValue classValue, JSContext *cx) { return ObjectClassIs(*wrappedObject(wrapper), classValue, cx); } diff --git a/js/src/jswrapper.h b/js/src/jswrapper.h index 6a218f771b34..6a93bbb163d9 100644 --- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -87,7 +87,7 @@ class JS_FRIEND_API(Wrapper) : public ProxyHandler virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args); virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp); virtual JSType typeOf(JSContext *cx, JSObject *proxy); - virtual bool classPropertyIs(JSContext *cx, JSObject *obj, ESClassValue classValue); + virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx); virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper); virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent); virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp); From fdea173fa72d8c9246a4ed3437d8e57998dde6fc Mon Sep 17 00:00:00 2001 From: Lucas Rocha Date: Wed, 28 Sep 2011 17:56:53 +0100 Subject: [PATCH 16/65] Bug 681944 - Immediately remove "empty" attribute from session-restored tabs (r=mfinkle) Otherwise user will not be able to restore a closed tab if he closes it before the session-restored thumbnail is loaded. --- mobile/components/SessionStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/components/SessionStore.js b/mobile/components/SessionStore.js index 115d80aee066..a2627805a4a4 100644 --- a/mobile/components/SessionStore.js +++ b/mobile/components/SessionStore.js @@ -787,12 +787,12 @@ SessionStore.prototype = { // Recreate the thumbnail if we are delay loading the tab let canvas = tab.chromeTab.thumbnail; canvas.setAttribute("restored", "true"); + canvas.removeAttribute("empty"); let image = new window.Image(); image.onload = function() { if (canvas) { canvas.getContext("2d").drawImage(image, 0, 0); - canvas.removeAttribute("empty"); } }; image.src = tabData.extData.thumbnail; From 79c05b8d5ca3f7834f5467cad3e114b24b021f1e Mon Sep 17 00:00:00 2001 From: Siddharth Agarwal Date: Thu, 29 Sep 2011 00:06:43 +0530 Subject: [PATCH 17/65] Bug 515907 - Support taskbar icon overlays in Windows 7. Original patch by Tim Miller . r=jimm, sr=roc --- widget/public/Makefile.in | 1 + .../nsITaskbarOverlayIconController.idl | 72 +++++++++++++++++++ widget/public/nsIWinTaskbar.idl | 14 +++- widget/src/windows/TaskbarPreviewButton.cpp | 4 +- widget/src/windows/TaskbarTabPreview.cpp | 4 +- widget/src/windows/TaskbarWindowPreview.cpp | 66 ++++++++++++++--- widget/src/windows/TaskbarWindowPreview.h | 18 +++-- widget/src/windows/WinTaskbar.cpp | 10 +++ widget/src/windows/nsWindow.cpp | 4 +- widget/src/windows/nsWindowGfx.cpp | 60 +++++++++++++++- widget/src/windows/nsWindowGfx.h | 7 +- 11 files changed, 238 insertions(+), 22 deletions(-) create mode 100644 widget/public/nsITaskbarOverlayIconController.idl diff --git a/widget/public/Makefile.in b/widget/public/Makefile.in index bafb5893adf0..33756e3f2593 100644 --- a/widget/public/Makefile.in +++ b/widget/public/Makefile.in @@ -140,6 +140,7 @@ XPIDLSRCS += nsIPrintSettingsWin.idl \ nsITaskbarPreviewButton.idl \ nsITaskbarProgress.idl \ nsITaskbarPreviewButton.idl \ + nsITaskbarOverlayIconController.idl \ nsIJumpListBuilder.idl \ nsIJumpListItem.idl \ $(NULL) diff --git a/widget/public/nsITaskbarOverlayIconController.idl b/widget/public/nsITaskbarOverlayIconController.idl new file mode 100644 index 000000000000..59fc8a21df42 --- /dev/null +++ b/widget/public/nsITaskbarOverlayIconController.idl @@ -0,0 +1,72 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Tim Miller . + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Siddharth Agarwal + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +interface imgIContainer; + +/** + * Starting in Windows 7, applications can display an overlay on the icon in + * the taskbar. This class wraps around the native functionality to do this. + */ +[scriptable, uuid(b1858889-a698-428a-a14b-b5d60cff6de2)] +interface nsITaskbarOverlayIconController : nsISupports +{ + /** + * Sets the overlay icon and its corresponding alt text. + * + * @param statusIcon The handle to the overlay icon. The icon will be scaled + * to the small icon size (16x16 at 96 dpi). Can be null, in + * which case if the taskbar button represents a single window + * the icon is removed. + * @param statusDescription The alt text version of the information + * conveyed by the overlay, for accessibility + * purposes. + * + * @note The behavior for window groups is managed by Windows. + * - If an overlay icon is set for any window in a window group and another + * overlay icon is already applied to the corresponding taskbar button, that + * existing overlay is replaced. + * - If null is passed in to replace the overlay currently being displayed, + * and if a previous overlay set for a different window in the group is + * still available, then that previous overlay is displayed. + */ + void setOverlayIcon(in imgIContainer statusIcon, + in AString statusDescription); +}; diff --git a/widget/public/nsIWinTaskbar.idl b/widget/public/nsIWinTaskbar.idl index ebebb188fd43..e0e88a5a8b63 100644 --- a/widget/public/nsIWinTaskbar.idl +++ b/widget/public/nsIWinTaskbar.idl @@ -48,6 +48,7 @@ interface nsITaskbarTabPreview; interface nsITaskbarWindowPreview; interface nsITaskbarPreviewController; interface nsITaskbarProgress; +interface nsITaskbarOverlayIconController; interface nsIJumpListBuilder; interface nsIDOMWindow; @@ -83,7 +84,7 @@ interface nsIDOMWindow; * See nsIJumpListBuilder for more information. */ -[scriptable, uuid(9fc572db-1089-4d43-9121-f4833d77a2df)] +[scriptable, uuid(3232f40a-e94b-432d-9496-096abf1387bd)] interface nsIWinTaskbar : nsISupports { /** @@ -132,6 +133,17 @@ interface nsIWinTaskbar : nsISupports */ nsITaskbarProgress getTaskbarProgress(in nsIDocShell shell); + /** + * Taskbar icon overlay + */ + + /** + * Gets the taskbar icon overlay controller for a window. The docshell is used + * to find the toplevel window. See the documentation in + * nsITaskbarOverlayIconController for more details. + */ + nsITaskbarOverlayIconController getOverlayIconController(in nsIDocShell shell); + /** * Taskbar and start menu jump list management */ diff --git a/widget/src/windows/TaskbarPreviewButton.cpp b/widget/src/windows/TaskbarPreviewButton.cpp index 645d1348a735..d23353f322bb 100644 --- a/widget/src/windows/TaskbarPreviewButton.cpp +++ b/widget/src/windows/TaskbarPreviewButton.cpp @@ -140,7 +140,9 @@ TaskbarPreviewButton::SetImage(imgIContainer *img) { ::DestroyIcon(Button().hIcon); if (img) { nsresult rv; - rv = nsWindowGfx::CreateIcon(img, PR_FALSE, 0, 0, &Button().hIcon); + rv = nsWindowGfx::CreateIcon(img, PR_FALSE, 0, 0, + nsWindowGfx::GetIconMetrics(nsWindowGfx::kRegularIcon), + &Button().hIcon); NS_ENSURE_SUCCESS(rv, rv); } else { Button().hIcon = NULL; diff --git a/widget/src/windows/TaskbarTabPreview.cpp b/widget/src/windows/TaskbarTabPreview.cpp index c7a3aa996504..1fb11d3c47d0 100644 --- a/widget/src/windows/TaskbarTabPreview.cpp +++ b/widget/src/windows/TaskbarTabPreview.cpp @@ -125,7 +125,9 @@ TaskbarTabPreview::SetIcon(imgIContainer *icon) { HICON hIcon = NULL; if (icon) { nsresult rv; - rv = nsWindowGfx::CreateIcon(icon, PR_FALSE, 0, 0, &hIcon); + rv = nsWindowGfx::CreateIcon(icon, PR_FALSE, 0, 0, + nsWindowGfx::GetIconMetrics(nsWindowGfx::kSmallIcon), + &hIcon); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/widget/src/windows/TaskbarWindowPreview.cpp b/widget/src/windows/TaskbarWindowPreview.cpp index d31ab35182f8..0eae47455610 100644 --- a/widget/src/windows/TaskbarWindowPreview.cpp +++ b/widget/src/windows/TaskbarWindowPreview.cpp @@ -47,6 +47,7 @@ #include "nsUXThemeData.h" #include "TaskbarPreviewButton.h" #include "nsWindow.h" +#include "nsWindowGfx.h" namespace mozilla { namespace widget { @@ -60,8 +61,9 @@ PRBool WindowHookProc(void *aContext, HWND hWnd, UINT nMsg, WPARAM wParam, LPARA } } -NS_IMPL_ISUPPORTS3(TaskbarWindowPreview, nsITaskbarWindowPreview, - nsITaskbarProgress, nsISupportsWeakReference) +NS_IMPL_ISUPPORTS4(TaskbarWindowPreview, nsITaskbarWindowPreview, + nsITaskbarProgress, nsITaskbarOverlayIconController, + nsISupportsWeakReference) /** * These correspond directly to the states defined in nsITaskbarProgress.idl, so @@ -82,7 +84,8 @@ TaskbarWindowPreview::TaskbarWindowPreview(ITaskbarList4 *aTaskbar, nsITaskbarPr mHaveButtons(PR_FALSE), mState(TBPF_NOPROGRESS), mCurrentValue(0), - mMaxValue(0) + mMaxValue(0), + mOverlayIcon(NULL) { // Window previews are visible by default (void) SetVisible(PR_TRUE); @@ -97,10 +100,15 @@ TaskbarWindowPreview::TaskbarWindowPreview(ITaskbarList4 *aTaskbar, nsITaskbarPr WindowHook &hook = GetWindowHook(); if (!CanMakeTaskbarCalls()) hook.AddMonitor(nsAppShell::GetTaskbarButtonCreatedMessage(), - TaskbarProgressWindowHook, this); + TaskbarWindowHook, this); } TaskbarWindowPreview::~TaskbarWindowPreview() { + if (mOverlayIcon) { + ::DestroyIcon(mOverlayIcon); + mOverlayIcon = NULL; + } + if (IsWindowAvailable()) { DetachFromNSWindow(); } else { @@ -199,6 +207,35 @@ TaskbarWindowPreview::SetProgressState(nsTaskbarProgressState aState, return CanMakeTaskbarCalls() ? UpdateTaskbarProgress() : NS_OK; } +NS_IMETHODIMP +TaskbarWindowPreview::SetOverlayIcon(imgIContainer* aStatusIcon, + const nsAString& aStatusDescription) { + nsresult rv; + if (aStatusIcon) { + // The image shouldn't be animated + PRBool isAnimated; + rv = aStatusIcon->GetAnimated(&isAnimated); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_FALSE(isAnimated, NS_ERROR_INVALID_ARG); + } + + HICON hIcon = NULL; + if (aStatusIcon) { + rv = nsWindowGfx::CreateIcon(aStatusIcon, false, 0, 0, + nsWindowGfx::GetIconMetrics(nsWindowGfx::kSmallIcon), + &hIcon); + NS_ENSURE_SUCCESS(rv, rv); + } + + if (mOverlayIcon) + ::DestroyIcon(mOverlayIcon); + mOverlayIcon = hIcon; + mIconDescription = aStatusDescription; + + // Only update if we can + return CanMakeTaskbarCalls() ? UpdateOverlayIcon() : NS_OK; +} + nsresult TaskbarWindowPreview::UpdateTaskbarProperties() { if (mHaveButtons) { @@ -207,6 +244,8 @@ TaskbarWindowPreview::UpdateTaskbarProperties() { } nsresult rv = UpdateTaskbarProgress(); NS_ENSURE_SUCCESS(rv, rv); + rv = UpdateOverlayIcon(); + NS_ENSURE_SUCCESS(rv, rv); return TaskbarPreview::UpdateTaskbarProperties(); } @@ -220,6 +259,13 @@ TaskbarWindowPreview::UpdateTaskbarProgress() { return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; } +nsresult +TaskbarWindowPreview::UpdateOverlayIcon() { + HRESULT hr = mTaskbar->SetOverlayIcon(mWnd, mOverlayIcon, + mIconDescription.get()); + return SUCCEEDED(hr) ? NS_OK : NS_ERROR_FAILURE; +} + LRESULT TaskbarWindowPreview::WndProc(UINT nMsg, WPARAM wParam, LPARAM lParam) { nsRefPtr kungFuDeathGrip(this); @@ -240,17 +286,17 @@ TaskbarWindowPreview::WndProc(UINT nMsg, WPARAM wParam, LPARAM lParam) { /* static */ PRBool -TaskbarWindowPreview::TaskbarProgressWindowHook(void *aContext, - HWND hWnd, UINT nMsg, - WPARAM wParam, LPARAM lParam, - LRESULT *aResult) +TaskbarWindowPreview::TaskbarWindowHook(void *aContext, + HWND hWnd, UINT nMsg, + WPARAM wParam, LPARAM lParam, + LRESULT *aResult) { NS_ASSERTION(nMsg == nsAppShell::GetTaskbarButtonCreatedMessage(), "Window hook proc called with wrong message"); TaskbarWindowPreview *preview = reinterpret_cast(aContext); // Now we can make all the calls to mTaskbar - preview->UpdateTaskbarProgress(); + preview->UpdateTaskbarProperties(); return PR_FALSE; } @@ -282,7 +328,7 @@ TaskbarWindowPreview::DetachFromNSWindow() { WindowHook &hook = GetWindowHook(); (void) hook.RemoveHook(WM_COMMAND, WindowHookProc, this); (void) hook.RemoveMonitor(nsAppShell::GetTaskbarButtonCreatedMessage(), - TaskbarProgressWindowHook, this); + TaskbarWindowHook, this); TaskbarPreview::DetachFromNSWindow(); } diff --git a/widget/src/windows/TaskbarWindowPreview.h b/widget/src/windows/TaskbarWindowPreview.h index 7c0b3865ad1f..465ab876a320 100644 --- a/widget/src/windows/TaskbarWindowPreview.h +++ b/widget/src/windows/TaskbarWindowPreview.h @@ -46,6 +46,7 @@ #include "nsITaskbarWindowPreview.h" #include "nsITaskbarProgress.h" +#include "nsITaskbarOverlayIconController.h" #include "TaskbarPreview.h" #include @@ -56,6 +57,7 @@ class TaskbarPreviewButton; class TaskbarWindowPreview : public TaskbarPreview, public nsITaskbarWindowPreview, public nsITaskbarProgress, + public nsITaskbarOverlayIconController, public nsSupportsWeakReference { public: @@ -65,6 +67,7 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSITASKBARWINDOWPREVIEW NS_DECL_NSITASKBARPROGRESS + NS_DECL_NSITASKBAROVERLAYICONCONTROLLER NS_FORWARD_NSITASKBARPREVIEW(TaskbarPreview::) virtual LRESULT WndProc(UINT nMsg, WPARAM wParam, LPARAM lParam); @@ -90,17 +93,22 @@ private: // Called to update ITaskbarList4 dependent properties nsresult UpdateTaskbarProgress(); + nsresult UpdateOverlayIcon(); // The taskbar progress TBPFLAG mState; ULONGLONG mCurrentValue; ULONGLONG mMaxValue; - // WindowHook procedure for hooking mWnd for taskbar progress stuff - static PRBool TaskbarProgressWindowHook(void *aContext, - HWND hWnd, UINT nMsg, - WPARAM wParam, LPARAM lParam, - LRESULT *aResult); + // Taskbar overlay icon + HICON mOverlayIcon; + nsString mIconDescription; + + // WindowHook procedure for hooking mWnd for taskbar progress and icon stuff + static PRBool TaskbarWindowHook(void *aContext, + HWND hWnd, UINT nMsg, + WPARAM wParam, LPARAM lParam, + LRESULT *aResult); friend class TaskbarPreviewButton; }; diff --git a/widget/src/windows/WinTaskbar.cpp b/widget/src/windows/WinTaskbar.cpp index eef10bb54521..7871e7d18cd3 100644 --- a/widget/src/windows/WinTaskbar.cpp +++ b/widget/src/windows/WinTaskbar.cpp @@ -416,6 +416,16 @@ WinTaskbar::GetTaskbarProgress(nsIDocShell *shell, nsITaskbarProgress **_retval) return CallQueryInterface(preview, _retval); } +NS_IMETHODIMP +WinTaskbar::GetOverlayIconController(nsIDocShell *shell, + nsITaskbarOverlayIconController **_retval) { + nsCOMPtr preview; + nsresult rv = GetTaskbarWindowPreview(shell, getter_AddRefs(preview)); + NS_ENSURE_SUCCESS(rv, rv); + + return CallQueryInterface(preview, _retval); +} + /* nsIJumpListBuilder createJumpListBuilder(); */ NS_IMETHODIMP WinTaskbar::CreateJumpListBuilder(nsIJumpListBuilder * *aJumpListBuilder) { diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 7027ebfe9f56..c49d01bea512 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -2453,7 +2453,9 @@ NS_IMETHODIMP nsWindow::SetCursor(imgIContainer* aCursor, return NS_ERROR_NOT_AVAILABLE; HCURSOR cursor; - rv = nsWindowGfx::CreateIcon(aCursor, PR_TRUE, aHotspotX, aHotspotY, &cursor); + // No scaling + gfxIntSize size(0, 0); + rv = nsWindowGfx::CreateIcon(aCursor, PR_TRUE, aHotspotX, aHotspotY, size, &cursor); NS_ENSURE_SUCCESS(rv, rv); mCursor = nsCursor(-1); diff --git a/widget/src/windows/nsWindowGfx.cpp b/widget/src/windows/nsWindowGfx.cpp index 1dec926f8c8a..cc0301f04fb5 100644 --- a/widget/src/windows/nsWindowGfx.cpp +++ b/widget/src/windows/nsWindowGfx.cpp @@ -103,6 +103,18 @@ using namespace mozilla::layers; static nsAutoPtr sSharedSurfaceData; static gfxIntSize sSharedSurfaceSize; +struct IconMetrics { + PRInt32 xMetric; + PRInt32 yMetric; + PRInt32 defaultSize; +}; + +// Corresponds 1:1 to the IconSizeType enum +static IconMetrics sIconMetrics[] = { + {SM_CXSMICON, SM_CYSMICON, 16}, // small icon + {SM_CXICON, SM_CYICON, 32} // regular icon +}; + /************************************************************** ************************************************************** ** @@ -613,10 +625,22 @@ PRBool nsWindow::OnPaint(HDC aDC, PRUint32 aNestingLevel) return result; } +gfxIntSize nsWindowGfx::GetIconMetrics(IconSizeType aSizeType) { + PRInt32 width = ::GetSystemMetrics(sIconMetrics[aSizeType].xMetric); + PRInt32 height = ::GetSystemMetrics(sIconMetrics[aSizeType].yMetric); + + if (width == 0 || height == 0) { + width = height = sIconMetrics[aSizeType].defaultSize; + } + + return gfxIntSize(width, height); +} + nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer, PRBool aIsCursor, PRUint32 aHotspotX, PRUint32 aHotspotY, + gfxIntSize aScaledSize, HICON *aIcon) { // Get the image data @@ -627,10 +651,42 @@ nsresult nsWindowGfx::CreateIcon(imgIContainer *aContainer, if (!frame) return NS_ERROR_NOT_AVAILABLE; - PRUint8 *data = frame->Data(); - PRInt32 width = frame->Width(); PRInt32 height = frame->Height(); + if (!width || !height) + return NS_ERROR_FAILURE; + + PRUint8 *data; + if ((aScaledSize.width == 0 && aScaledSize.height == 0) || + (aScaledSize.width == width && aScaledSize.height == height)) { + // We're not scaling the image. The data is simply what's in the frame. + data = frame->Data(); + } + else { + NS_ENSURE_ARG(aScaledSize.width > 0); + NS_ENSURE_ARG(aScaledSize.height > 0); + // Draw a scaled version of the image to a temporary surface + nsRefPtr dest = new gfxImageSurface(aScaledSize, + gfxASurface::ImageFormatARGB32); + if (!dest) + return NS_ERROR_OUT_OF_MEMORY; + + gfxContext ctx(dest); + + // Set scaling + gfxFloat sw = (double) aScaledSize.width / width; + gfxFloat sh = (double) aScaledSize.height / height; + ctx.Scale(sw, sh); + + // Paint a scaled image + ctx.SetOperator(gfxContext::OPERATOR_SOURCE); + ctx.SetSource(frame); + ctx.Paint(); + + data = dest->Data(); + width = aScaledSize.width; + height = aScaledSize.height; + } HBITMAP bmp = DataToBitmap(data, width, -height, 32); PRUint8* a1data = Data32BitTo1Bit(data, width, height); diff --git a/widget/src/windows/nsWindowGfx.h b/widget/src/windows/nsWindowGfx.h index 2fb957b5a31d..896a89eb39f8 100644 --- a/widget/src/windows/nsWindowGfx.h +++ b/widget/src/windows/nsWindowGfx.h @@ -60,7 +60,12 @@ public: static nsIntRegion ConvertHRGNToRegion(HRGN aRgn); - static nsresult CreateIcon(imgIContainer *aContainer, PRBool aIsCursor, PRUint32 aHotspotX, PRUint32 aHotspotY, HICON *aIcon); + enum IconSizeType { + kSmallIcon, + kRegularIcon + }; + static gfxIntSize GetIconMetrics(IconSizeType aSizeType); + static nsresult CreateIcon(imgIContainer *aContainer, PRBool aIsCursor, PRUint32 aHotspotX, PRUint32 aHotspotY, gfxIntSize aScaledSize, HICON *aIcon); private: /** From 77d1e9b38861c63fa700bdde78ea07b28f6ea401 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 28 Sep 2011 15:28:33 -0400 Subject: [PATCH 18/65] Bug 460323 testcase. --- layout/style/crashtests/460323-1.html | 30 +++++++++++++++++++++++++ layout/style/crashtests/crashtests.list | 1 + 2 files changed, 31 insertions(+) create mode 100644 layout/style/crashtests/460323-1.html diff --git a/layout/style/crashtests/460323-1.html b/layout/style/crashtests/460323-1.html new file mode 100644 index 000000000000..0bae55aaf1b3 --- /dev/null +++ b/layout/style/crashtests/460323-1.html @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index 43696c00184d..eab27482b1c4 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -34,6 +34,7 @@ load 448161-2.html load 452150-1.xhtml load 456196.html load 460217-1.html +load 460323-1.html load 466845-1.html load 469432-1.xhtml load 472195-1.html From 204f2b864c0ad57587e239561f52d084863d77bc Mon Sep 17 00:00:00 2001 From: Sriram Ramasubramanian Date: Wed, 28 Sep 2011 12:30:12 -0700 Subject: [PATCH 19/65] Bug 682412 - Theme settings on Honeycomb. r=mfinkle --- mobile/chrome/content/downloads.js | 1 + mobile/chrome/content/extensions.js | 2 + mobile/themes/core/honeycomb/browser.css | 97 ++++++++---- mobile/themes/core/honeycomb/defines.inc | 20 ++- .../honeycomb/images/addons-default-hdpi.png | Bin 1039 -> 791 bytes .../honeycomb/images/check-selected-hdpi.png | Bin 1305 -> 906 bytes .../images/check-selected-tap-hdpi.png | Bin 0 -> 976 bytes .../images/check-unselected-hdpi.png | Bin 530 -> 209 bytes .../images/check-unselected-tap-hdpi.png | Bin 0 -> 295 bytes .../images/downloads-default-hdpi.png | Bin 1278 -> 486 bytes .../images/preferences-default-hdpi.png | Bin 1299 -> 530 bytes mobile/themes/core/honeycomb/platform.css | 149 ++++++++++++++---- mobile/themes/core/jar.mn | 2 + 13 files changed, 205 insertions(+), 66 deletions(-) create mode 100644 mobile/themes/core/honeycomb/images/check-selected-tap-hdpi.png create mode 100644 mobile/themes/core/honeycomb/images/check-unselected-tap-hdpi.png diff --git a/mobile/chrome/content/downloads.js b/mobile/chrome/content/downloads.js index ebc85d970690..ae222bfb0ddc 100644 --- a/mobile/chrome/content/downloads.js +++ b/mobile/chrome/content/downloads.js @@ -89,6 +89,7 @@ var DownloadsView = { item.setAttribute("downloadID", aAttrs.id); item.setAttribute("iconURL", "moz-icon://" + aAttrs.file + "?size=32"); item.setAttribute("lastSeconds", Infinity); + item.setAttribute("class", "panel-listitem"); // Initialize more complex attributes this._updateTime(item); diff --git a/mobile/chrome/content/extensions.js b/mobile/chrome/content/extensions.js index 844586a9828e..423feaf0d5e5 100644 --- a/mobile/chrome/content/extensions.js +++ b/mobile/chrome/content/extensions.js @@ -89,6 +89,7 @@ var ExtensionsView = { item.setAttribute("name", aAddon.name); item.setAttribute("version", aAddon.version); item.setAttribute("iconURL", aAddon.iconURL); + item.setAttribute("class", "panel-listitem"); return item; }, @@ -620,6 +621,7 @@ var ExtensionsView = { let whatare = document.createElement("richlistitem"); whatare.setAttribute("typeName", "banner"); + whatare.setAttribute("class", "panel-listitem"); whatare.setAttribute("label", strings.GetStringFromName("addonsWhatAre.label")); let desc = strings.GetStringFromName("addonsWhatAre.description"); diff --git a/mobile/themes/core/honeycomb/browser.css b/mobile/themes/core/honeycomb/browser.css index 26f8341ad358..ce0366c585d5 100644 --- a/mobile/themes/core/honeycomb/browser.css +++ b/mobile/themes/core/honeycomb/browser.css @@ -409,6 +409,10 @@ toolbarbutton.urlbar-button { border: @border_width_small@ solid @color_url_border@; -moz-border-radius: 100%; } + +#tool-back2 image { + -moz-margin-end: 0; +} #tool-forward2 { margin: 0px; @@ -548,12 +552,27 @@ remotetabslist[message] > .remotetabs-list-children { /* browser tools panel UI ------------------------------------------------ */ .panel-header { margin: 0; - padding: @padding_small@ @padding_normal@ @padding_normal@ @padding_normal@; - font-weight: bold; - background-color: @color_background_header@; - color: @color_text_header@ !important; - background-repeat: repeat-x; - background-size: auto 100%; + padding: @padding_small@ @padding_normal@ @padding_xlarge@ @padding_normal@; + border-bottom: @border_width_tiny@ solid @color_text_default@; + background-color: transparent; + color: @color_text_panel_header@ !important; + font-size: @font_snormal@; +} + +.panel-listitem { + padding-top: @padding_xxxnormal@; + padding-bottom: @padding_tiny@; + -moz-padding-start: @padding_xlarge@; + -moz-padding-end: 0; +} + +.panel-listitem:not([class="section-header"])[selected="true"] { + background-color: @color_background_settings@; +} + +.panel-listitem label.normal, +.panel-listitem description.normal { + color: @color_subtext_settings@; } #tool-addons { @@ -583,6 +602,10 @@ remotetabslist[message] > .remotetabs-list-children { } /* addons panel UI ------------------------------------------------------- */ +#addons-list .addon-options { + -moz-margin-start: @margin_xlarge@; +} + #addons-repo { -moz-box-orient: horizontal; -moz-box-align: center; @@ -600,8 +623,7 @@ remotetabslist[message] > .remotetabs-list-children { list-style-image: url("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png"); width: 32px; height: 32px; - -moz-margin-start: @margin_normal@; - -moz-margin-end: @margin_normal@; + -moz-margin-end: @margin_xxxnormal@; } .addon-rating[rating] { @@ -643,16 +665,11 @@ remotetabslist[message] > .remotetabs-list-children { -moz-margin-end: @margin_normal@; } -richlistitem[isDisabled="true"] .title, -richlistitem[isDisabled="true"] .normal { - color: @color_text_disabled@; -} - -richlistitem[isDisabled="true"] image { - opacity: 0.25; -} - /* downloads panel UI ---------------------------------------------------- */ +#downloads-list image { + -moz-margin-end: @margin_xxxnormal@; +} + .download-retry-failed { color: red !important; display: none; @@ -667,10 +684,11 @@ richlistitem[isDisabled="true"] image { margin-top: -moz-calc(2 * @touch_row@); /* 2 times row height */ font-style: italic; border-bottom: none; + background-color: @color_background_settings@; } #dl-empty-message:active { - background-color: @color_background_default@; + background-color: @color_background_settings@; } #dl-empty-message > label { @@ -1409,28 +1427,43 @@ pageaction:not([image]) > hbox >.pageaction-image { /* Preferences window ---------------------------------------------------- */ .settings-title { min-height: 0; - color: @color_text_header@; - background-color: @color_background_header@; - font-size: smaller; + color: @color_text_panel_subheader@; + background-color: @color_background_button@; + font-size: @font_xtiny@; font-weight: bold; margin: 0; - padding: @autocompleteresult_padding@ @padding_xnormal@; - border-bottom: @border_width_tiny@ solid @color_divider_border@; + padding: @padding_xxnormal@ @padding_large@; + border-top: @border_width_tiny@ solid @color_background_settings@; + border-bottom: @border_width_large@ solid; + -moz-border-bottom-colors: @color_background_button@ @color_background_settings@; } .setting { - padding-left: @padding_xnormal@; - border-bottom: @border_width_tiny@ solid #cacdd5; + -moz-padding-start: @padding_xxlarge@; + border-bottom: @border_width_tiny@ solid @color_background_button@; } setting { padding: @padding_xsmall@; - border-bottom: @border_width_tiny@ solid @color_divider_border@; + -moz-padding-start: @padding_xxlarge@; + border-bottom: @border_width_tiny@ solid @color_background_button@; min-height: @touch_row@; /* row size */ -moz-box-align: center; -moz-box-orient: horizontal; } +setting:hover:active { + background-color: @color_background_highlight@; +} + +setting[type="bool"]:hover:active .setting-input > checkbox > .checkbox-spacer-box > .checkbox-check { + background-image: url("chrome://browser/skin/images/check-unselected-tap-hdpi.png"); +} + +setting[type="bool"]:hover:active .setting-input > checkbox[checked="true"] > .checkbox-spacer-box > .checkbox-check { + background-image: url("chrome://browser/skin/images/check-selected-tap-hdpi.png"); +} + .setting-label { -moz-box-flex: 1; } @@ -1464,7 +1497,7 @@ setting { } .options-box { - -moz-margin-start: 28px; /* sized based on the 32px addon image */ + -moz-margin-start: @margin_xlarge@; } .options-box > setting:last-child { @@ -1473,13 +1506,13 @@ setting { /* XXX should be a richlistitem description.title */ .preferences-title { - font-size: @font_normal@ !important; + font-size: @font_snormal@ !important; } /* XXX should be a richlistitem description.normal */ .preferences-description { - font-size: @font_small@ !important; - color: @color_subtext_default@; + font-size: @font_xtiny@ !important; + color: @color_subtext_settings@; } /* alerts popup ----------------------------------------------------------- */ @@ -1666,10 +1699,6 @@ setting { background-color: transparent; } -#appmenu-popup-appcommands richlistitem:hover:active { - background-color: @color_background_highlight_overlay@; -} - #appmenu-popup-sitecommands { display: block; max-width: -moz-calc(4.51 * @touch_button_xlarge@ + 2 * @padding_normal@) !important; diff --git a/mobile/themes/core/honeycomb/defines.inc b/mobile/themes/core/honeycomb/defines.inc index 945d0e1ffb81..2ef80181f823 100644 --- a/mobile/themes/core/honeycomb/defines.inc +++ b/mobile/themes/core/honeycomb/defines.inc @@ -9,6 +9,9 @@ %define color_toolbar_border #d9d9d9 %define color_divider_border #6699ff %define color_url_border #737373 +%define color_background_button #d9d9d9 +%define color_background_button_disabled #e3e3e3 +%define color_background_button_overlay rgba(217, 217, 217, 0.8) %define color_button_border rgb(207,207,207) %define color_background_dialog #fff %define color_text_dialog #000 @@ -21,13 +24,17 @@ %define color_background_scroller #9a9a9a %define color_background_textbox #fff %define color_text_textbox #000 -%define color_text_button #000 %define color_text_disabled #808080 +%define color_text_button #222 +%define color_text_button_disabled #999 %define color_text_placeholder #808080 %define color_text_as_link #69f %define color_background_panelrow #c8c8c8 %define color_text_panelrow #222222 %define color_text_toolbutton_inverse #666666 +%define color_background_settings #efefef +%define color_text_panel_header #999 +%define color_text_panel_subheader #333 %define color_background_highlight #a7c5f4 %define color_background_highlight_overlay rgba(167, 197, 244, 0.8) @@ -39,6 +46,7 @@ %define color_shadow_grey rgba(200,200,200, 0.5) %define color_subtext_default #aaaaaa +%define color_subtext_settings #666666 %define font_xlarge 6.08mozmm %define font_xnormal 3.75mozmm @@ -50,12 +58,15 @@ %define font_xtiny 2.27mozmm %define font_xxtiny 1.93mozmm -%define touch_row 10.41mozmm +%define touch_row 10.478mozmm %define touch_button_xlarge 10.62mozmm %define touch_button_large 9.77mozmm %define touch_button_small 8.93mozmm %define touch_button_minwidth 11.86mozmm %define touch_action_minwidth 21.17mozmm +%define touch_button_tiny 3.75mozmm +%define touch_button_minwidth 16.30mozmm +%define touch_button_minwidth 11.86mozmm %define touch_normal 6.77mozmm %define margin_context_popup 3.39mozmm @@ -70,6 +81,8 @@ %define margin_tiny 0.21mozmm %define margin_xtiny 0.11mozmm +%define padding_xxxlarge 13.35mozmm +%define padding_xxlarge 7.938mozmm %define padding_xlarge 3.39mozmm %define padding_large 2.54mozmm %define padding_xxxnormal 1.69mozmm @@ -136,7 +149,10 @@ %define appmenu_button_height 10.48mozmm %define tablet_panel_controls 40mozmm +%define tablet_panel_controls_wide 55mozmm %define tablet_panel_minwidth 124mozmm +%define tablet_panel_item_width 69mozmm +%define tablet_panel_item_width_wide 90mozmm %ifdef MOZ_PLATFORM_MAEMO %define orientation -moz-device-orientation diff --git a/mobile/themes/core/honeycomb/images/addons-default-hdpi.png b/mobile/themes/core/honeycomb/images/addons-default-hdpi.png index 25f09906e011be78b7feebc4ff9323aaacf99561..90ea938027a99e644b82716390484bc50bf427ba 100644 GIT binary patch literal 791 zcmV+y1L*vTP)OL)9E`5WD7A^1P27#d7)4^ zSFKiWwA<~oTGZ?HEBSo>I>w!bqnRrJE9GLr(^m&^5BpXhKn zHY1V93qF5`Va`k(SY@&~x%4}l&*yvEY&I`w-vfcbeXrL`1Uz9#?J!xlb}g-m6VlF4 zXS3P6D7nu#sH&>e>-D_)3fOG6wlOah3T30w=xcNpCg{W!pj`{JIFW2z3H4y~jrp>| z{5jZGY-K`<^RVJs+9_5?pNZMhb7Cw25Uc~DeV&95X7*hwmHg#$`Lf63*?^2+(j)bb zX{G`ymkifiBO6;A{U%=W%3IEuPcfYhjK{L7Qf$rFOf(*K=&Ks*Qg3m zdA1>;4ORphjEV<-1b~URuJ;P9Vg5yYJkeXW82}n|YCa&#@|#pD^{`T@T-vYqfgL_T zf!l6<9*c>hsPNgV3zs3Ba6Oq!p2v0l{{OB7;cGA$e2i|F6*0RE$$r6!w}ZhzqU(56 z9`1-rCX>0!$EvanI}BoW0I^u?CY14kDhRGvb^-C1?*coQo_79Y&rVn@7O&AEcDK75{N}R>XJzz?~z#!jq$mw z)4mT7sFVCcVjD3}Bb2~CZ+cU6&i82nXdvuk0Q7l$)Qc#M{~3E#9{x8x@Bsb^FaSVI V4Px#0%A)?L;(MXkIcUS000SaNLh0L01FcU01FcV0GgZ_000A~NklzL{#oiwI@;BB&SnLZV6jZWI2EQMb0C8~461^#>F~i<8G7BC*N~^zxzAC z3;!1rttR8+JhCzPJvrSj)ZGGkY9cZosg0%&Fvi8?+_shwKlRn;vcaami@o07vx<}7 z^t^bi(e>!l_w`2lwgK%@O<&gE=*tirc8zWWy5h3bc`aM#$&%x@h5TIW(6(N_K)LX( zS?4f0Kb6(*thNJnIru$`>D#*x_(lh6j!VCO^wW(mC{o%&O2r#A-!e5#7-}6rEeXT5 z?kn#X_p~OhmeBagM)!llR1ICoy8V!@(&$SrojPBfY7mO~r{1~xF|wl6 znmwoNL?EpaItXiRNwxtU+S?f9uAt%X@~&tVs1f$;d|nD6%^No_p@_2ICp(I}r5f(q zo|Z$;eE0;wtq0BqEzgsoU16)kyq8K9+OJ3@@f<*cgVF5LV~5()c@=;`g4OZgNFhZP zTJ!|{HD!^55uiPtR`ozE(t}BXLVcbZZcBC2mZuE(=&_l5`F(&hMbcr zMGAZ9ZSvKt5FwlSKfewQzsK>+!y}rOoc-o{?jlxQ^4l*s$80LU4EBHLGMC9?*c6mT`(bJ_Rk=Eo*qdmA8cNP85lCM^MN+0nf%2x%$z{P3mA1dP$A=HINItOdg=q6^waZv%i3Ju|Myu@NCQ6S! zdwGVi=sr9ci#z77q)geio~9k1@CTFt(h%uRiu9_(4Z3Q0q3l`RDpa@NvoGy$_+vgl z2Q%~b^Sb5S^9R^H@VGs+aJ`s@?%|$@&8zVZrAl5peewu|Lpy6BD^0M?A4>a7{0AHBn&#fPHI4uP002ov JPDHLkV1m!P1UUcz diff --git a/mobile/themes/core/honeycomb/images/check-selected-hdpi.png b/mobile/themes/core/honeycomb/images/check-selected-hdpi.png index 2fa34331d93149a113646952e9095e3a338f7b1f..10b067f39d5eb6b4cbdcad2e44cbd4acd7051ca7 100644 GIT binary patch delta 882 zcmV-&1C9Kd3W^6IiBL{Q4GJ0x0000DNk~Le0000W0000W2nGNE0CReJ^pPPae*-K@ zL_t(|+U%EGYZE~f$7gnDH@lmQjcvD;Hqlh5J_tVe=8Jt01Zm$ZYC$OV3;3cw3hHMl z6u}!5u|kUlKY+f8mnWqcZ6(wunl{(H&v>RzGzhlYXzhbpIIufx=J!8m{&Qx78DnTK zFA44O)fPZ@YvRe5m?wut@Qc-Bf8xYXZCdIyKUL(5KbQMf?4;ecE6Ko|7=HHZ04|6_}cu zVy0;}foG@}&%o3!qPT?m2jXbazkbc~^TU++=GWTm+fg+&Vf*<)C;=Qke=;(Ho5-B6 zwISn3ry|Ew3x52R<*kng)XHFlJ&ef)WnSHg;dg<6pkG{Fe_Py&RjW%0f&h67G3 zgQ}bT0Pq~VTWP5Re77i4Opix0rW@f7*%%WC<&p;}=d>z3fds5K~ikHPZDwe_&3a$k8J;cWn&r zd!Xz9H)kR9>FmeqC^df%4~js?jn-0QE^w#g2R*F*SvQ| z!t!HSisdLxpzYvc8c_i2Z3Aed(>OjZVU@2Z;^30AbbbqtB->C9OoJmI0ep#<9Wxzm z2X9gUt~=g_R$3@Je~T*}+Tc|Xk*}MH@AIhIe-AM>1C8g0;V@IscJMG2;FH)8MK364 z%kIj%4(;d_Ap${%n}lU~(g^37H#EFI6Ch45UWFP&0Yt1q`QIcWnREN~V`mr(?!#fT zAlzQrsq8IvLM{Rt5*K0diokZXAaWuJPgKa^_szmXpN0*UNZ>Hu)%d~k1!7ZFCltJ; z?|}vp!9V#V%jI%tZf>rn&nEuc9rsxKe?eP7Tfl!W;F|yg0Gb7+$-zFqF#rGn07*qo IM6N<$g0=XSRsaA1 delta 1284 zcmV+f1^fDn2bl^XiBL{Q4GJ0x0000DNk~Le0000k0000k2nGNE09UyyH<2MHe+0Wp zL_t(|+U#0QXcIvcp506fLR%>q1+CQzN~s5h=F);E4?T#2C|)d-qVy8b>b*44yJ#T? ziz0;{R9ZxD1w9m@1H%4BP= zm#Si%R~z~-*-j)9zNMuly1cwx1K*pPnzovon=^jDKkEh_@KU^5D+zjPYHHu~^mHQw z-e3VwcXV{5Iy*am%fQ<>seL2cPm~k%#Kgp*SS;4k|MKK8LqHx~d*7E%r$Mh*F?dWY zt+Z|Pprg^~soUenBVRW^e-i*6eBLzt@JcjjH5G!-lS9$oqB5Y5MZRkbB%N6?t`xh6 zy4l&;!!t88b?fWvifn+!}e>lk8z8qBS-)W<^q%$9TE4T*mY-e+C*@&UY%5ytuwU z*xK5<($?1YqrSdg8sJd8eJr<4f79j}(@DmzX1-~nIH1S74+aB)z+6{X*Q!Vod1py? ztKVLohIk<^GNw(?09d#Fe59rzXgmQbi|a~p8Y0ltd7veT(n{5C+ z*6sHUdWXyR5;KA$0EYmM!F=tDjKR18BE#&pf4n8~;PQuC@p!xr+Al0D9KHMM#87I7 z;Sa;!6wH`o?@uS z?#x3LzEM%y0T*xt;1HhleC)aKcx@z;(}?xP8JniZ19cmCdwRf_D1go|(8L67n@A~4 zV{%nd-UJtL1mFA%OcFg;Ps zu22Ntuz5?bO^;YU&<^loc7+)H>)u%3rDtD;;r>nUf04dG;LQBr2E8NZEH<~ogKubP z&_3N;z6kZ_&J~W=w*YoCnpgKg>;K;MRdR_(|5PiVz={Bd>&dv zzuV`WTD*|7uBso;M? uD0Dn60^$~M%lZ>}M6cTp_$P!v0t^5bAgTJ0Y~Y#z0000~!@2 diff --git a/mobile/themes/core/honeycomb/images/check-selected-tap-hdpi.png b/mobile/themes/core/honeycomb/images/check-selected-tap-hdpi.png new file mode 100644 index 0000000000000000000000000000000000000000..85c7ff80ff6f1db5f24af1185c40bd4d1efacce0 GIT binary patch literal 976 zcmV;>126oEP){>SJsRtpXNM ziHceYJ`xv(AQ}k^h#Ob_1y?4`bfo{BTI^PUs&bjxV`^~7=?iiqGAzUYPTkDOCFyRH^60cSI*iU#x2w-!9 z6Ff)gBb<=wV`vk}7YB0=$(E8@MIX1IZX@noE|&;pUYHjoiGC$sSVs{ab)(2jr6Nj& zJc`AFIG1GwilRYQh?3S75$gJrmj!v=$Pm)v$mgoV1&31?P-IzDf5)rB$SC@-LaTMlZCzF|27?+)U zo?!BckBE#uM0P$3MRQ}@?k=<*?1k$f#{@a|yd`uBK7SCpFR(0m)dD1#TWDQVyXb2%pFw2!9#T7x6QKw3 zpKnn#5|A|)8uy(-%l;lg&Yq}m+_@}y)fpU;zI*h;Ly#7XMFMvVqc${n+z)AQ5&6N38XioQvsk$B+f_Iis4guSvjS5egGgmP=kX_=k2zJLGG6 zACQD860000b*87aH+HAJ2B=woiE`p^GY zqk%C#K7JDK{XLbRGxWf^+++=2H6#YeHm?c^SnKAqv(Hyw@qooGeTd{9W(Fo6hJtpf W*##G3mohK_9p~xl=d#Wzp$Pyq;yqIU delta 503 zcmVR_LlNyfZljJB)$t!)6i6CyjH2e@YBgAM!Dd%}^t+lh)rIf9g z@tbQby|0&O9M_FG*w5>EjQ8Mu_I)q6KHeL=2tPXO#~L@r_Fu+$&oPJR9mi1}PFI*9 z=1Rl~B!UmeV=Ly&ZUt}dr~PbLfArBlA-X!|M0Cip7Teg5hg#hxABt&lUigiluPtGz zwce3Q9$mje@tH(tE}d3WA{ynzRG`8_Yph>0a~p-zNJq-R#aG55BUDE1GmDs=<5EyT z%WEo7VZX@~t>!P`*;OG6=!*f$PCP?d7b@(m%MiYD)>ErP6%I2pTnXc7e=Pk zDByeQtEfO`;M`Q8!b~+4h`fbv{BWa!b60a~Lj#oE$wKB@6h$jw-4!%Ss8v)1lAS?| zo`e;gEQ{VOGF!|y1B9GcFhVlkq3rVnr)*3?6^15X$@siLMK#KI&LFqe?pO5aN}yNy zQO4>Os78oz)RD84_!UAwO{Kk8M9&V&b3%1EGPY4f9mS;44SY)KM#Ro?_$vlIL${vL tpKX5SPXQ~-i+T9}z+}1y}a{fG9$;5#vS4vxeIclnwC4%uyk}g=7=dQ zq;TQ(`C@-al}X{~je#vEtA*K`(}o2vuNr>_NuxR*J&uE!&pTR1@`~;(^!=F3`9rl}%%tZ%G6|ONq p0tz(oiS2K=#k%RUltTj}LzSrd^1VD0rU5<0;OXk;vd$@?2>`q0Y+e8W literal 0 HcmV?d00001 diff --git a/mobile/themes/core/honeycomb/images/downloads-default-hdpi.png b/mobile/themes/core/honeycomb/images/downloads-default-hdpi.png index f9afa2cec9fb6e797bd5f8b40c9e8cf84744590f..cdcd2db8b549c65c648b634c0902a08155a672a1 100644 GIT binary patch literal 486 zcmV@P)X=sH1S-@kuXB4jHwGxJwYPR_g7u-U(V|8$^*+|-P3VPWB&m6er+K;}DG2%rb^dr-;c;o))0(a|vz{==0EK#q7zO-GP6Do)(as)A!6H^kB> c06>5N0J(4}ALP^;bN~PV07*qoM6N<$f_KivcmMzZ literal 1278 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_000D$Nkl`906`dtw7; zIm^F0reeO-)7xKF%AkJVY^vhWp5Fcs%26S|Z}w5e%HP%9$9(kh?N5yo)79N~%hAwi zE@bRNrqHBo8c`ILF7*d%npPugM^ogHJ=J7+xk=3B0-yYChNQ?(%QRfJIO zQ!E=|n1QPaS*d%&W`o&GPGv3fJdf2-7z+yvbGL8b`A$(3P7wIDY5)|^Z*LMpwXiH3 zWEjS&$ZDO~-cK)&MGYt%k$c z;RSfT-syXv+?z}zy#RIr!~y7;it2~4(;OFMt~1VfJYGi#1*_FsnM#Jk5O@J@_xGOR zq2XV5UkSf#MmK)XLTUhv?CyOOJIw_dX27YaY8@dIXqtv$plnwt6amlkaJ$`}vC&cA z;^M++JifOE;8ivf01h8BN3fHVlY!38u5*M?4nmQAY#F9I6pnxw1b94d&v+V{2ELx| z3^Et=2-ae;q}VAo*3s#*n+fG0gp^#_a2E3M*jNU+o4yih!+{)kaA&Y7NfLPrO{cgi zR&=>K?Szom*kTfiL?8$PCMG<`A#*-TpY#ty2ap7yOQOhIXxiYWSgFI+xnEgxVU^W1 z9g9m#5Jd?S6CTgk(qMzo$#BzCc>xm}iJ@ca%$QIx+N z{-P|%VxbwVmN^)Be&^-pMzo#~D%RZG(w;~p_L2VbAWMN}x2_C!aWfjNSCh%j=g)qg znJ*)<=oh&;o@A{6>;UY|EtlR=Rb?x>u^uQFvRu$?>^T5+>7^m1cX-LjazZm$3jjI| ol>w;bK$aVtxnI?xzW@KqU&~)2;tU(Xv;Y7A07*qoM6N<$f*s^jS^xk5 diff --git a/mobile/themes/core/honeycomb/images/preferences-default-hdpi.png b/mobile/themes/core/honeycomb/images/preferences-default-hdpi.png index 49d89c1df278bb35478c9a740b1a05b20fdad51f..41d0f35acd87eeec65dca94ac9b9fa2ffeed2e35 100644 GIT binary patch literal 530 zcmV+t0`2{YP)DtpFBJ~jslrKf%r32m>-CR*Q{CNOh6q;4gkrqf-FCA;=~jrgD(LMz5rx?L<@Ru zBGe7OL^!A&z(|CCc3NdaA!v$b10^O`8-0_TwxOqejC0z?-S6m$ToAGB})^V6qKWu82F5>G(?WFY=DY!l(IasWFiY2Xhi zl^YouT?f)R-@kw7ef##U2E5Q`W&JEJE`9^b{R&Mppxp3_h}`lMBd_CV55OxSVEOKi zUc@#uG{iv5_rJ)w1s8zkmN(ccCS2vfd#LZE@R$p7057GvWi%HIi6$97@HHePWG@h# zfH=SeYk}4vxrUTme$m1KAE0eNPy&<0(jWolmbXyLKhh!!eiLf*LG%6_Tn*IGL^$9M zU?k8r6NQ%L$nE`K&{X{zsktoz#e~$6>;P71o1YEMVDz>=vFb>6z-S_*IRFSS02=+O URV3%76aWAK07*qoM6N<$f8XP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipM+ z5;6{MO}R+`00fgsL_t(o!|hm0ZyQw<{^n&ni5k-+kcWhX3M^<7yF^G85_E&upjIqE zffb7`kYK?oDiVkd{Q*@Jkjfr}1X2G0FOjloOHvX91t-C3oy4)*CVqw3GxwguB4aff z-`F$5G-bhA-nr-8@1Aq+cfUKp{}!!jK_;itjV=bU#^_LRgK4olt$0QW{c< zH~`c8ty-;ELWu65exZR1DPqF0FKGLEYosk zXMZ}z%-XMuH?AET(7~Z$Q%V^-efq^${07_H+|s_DnRyPtbpU)QJzA|+EGb1-kYGXx zi%7;E1e+WfaF?tp79^OI(ja2fFNsG|`X*T~EwA_vR;|^5T@pWh9<9}CK}zpCM!ivw z2B>W}2mmf!`s@q8!E(9Pd*yQJJMXxvDuqHZvW!wDbMwpEcJ+C`!5WRm+P%AXRsnD- zJ+A+8^EUuMGTD2}JGWda6#yWSNa*!?=j^uAf^h&x0rWNxhpy|oLIv$r>U98{sr2}p z09Z;HcN{xOk`fHwx0a@9(lCr2%ZgQWU3WT(=yn-(0F>Rujc1OJz18Nl-_HE``wsw| z?w%e&M8+>S=05dXiKXS0rHP3*E&}-WApUJzdKYBl#Axc&nKNgfxNza)_q>yqmsgf1 zCMKo;R9v695Tcs`(7h1*M6?s;)H48(B*S*>7&EI*x;X7iscuH2|&c?EKwPMEe5D%sPQJQUE0))%VrR<#R3nat(HuCH9E5Vg39~>Hfs#OwhH~ZIa2QXBRvcHVpzk?mel#-O>FQqV~luiDP4k#Z`dTIldm<(nz zNqJF_#!Qyq*Fc~iRbt|{yVJnXI{0ak0+mE47F%zSN~O}#H>_W{Upi8vSZuvO%9XMY zpyB)i18vmng|*dO>E~-#ue849H%n5=yX~GcLH&X%{H7TIk^_%EmP#fcd0CO^Vm7;S z8NeM^zwWi3qka9y`}+o7^*N;- zC;(V4$b^SZn)md!yD%#@+2wB34B!_UXme3R;X^KAbHsl8>>tyB*uRwYqqG13002ov JPDHLkV1n;@RvrKV diff --git a/mobile/themes/core/honeycomb/platform.css b/mobile/themes/core/honeycomb/platform.css index 525261e203f2..9196da3bc300 100644 --- a/mobile/themes/core/honeycomb/platform.css +++ b/mobile/themes/core/honeycomb/platform.css @@ -142,33 +142,30 @@ dialog > .prompt-header > .button-checkbox { .button-text, .toolbarbutton-text { font-weight: normal; - font-size: @font_snormal@ !important; + font-size: @font_xtiny@ !important; } button { -moz-appearance: none; min-width: @touch_button_minwidth@ !important; - min-height: @touch_button_small@ !important; /* button size */ + min-height: @touch_button_tiny@ !important; /* button size */ color: @color_text_button@; + background-image: none; + background-color: @color_background_button@; margin: @margin_normal@; padding: @padding_xnormal@; - background-image: url("chrome://browser/skin/images/button-bg.png"); - background-size: auto 100%; - border: @border_width_tiny@ solid @color_button_border@; + border-width: 0px; + border-radius: 0px; } button[disabled="true"] { - color: @color_text_disabled@ !important; - border: @border_width_tiny@ solid @color_button_border@ !important; -} - -button:focus > .button-box { - border: @border_width_tiny@ solid transparent; + color: @color_text_button_disabled@ !important; + background-color: @color_background_button_disabled@; } button:not([disabled]):hover:active, button:not([disabled])[checked="true"] { - background-image: url("chrome://browser/skin/images/toggle-off.png"); + background-color: @color_background_highlight@; } /* Override GTK2 system setting */ @@ -409,20 +406,20 @@ richlistitem[selector="last-child"] { richlistitem label.title, richlistitem description.title { - font-size: @font_normal@ !important; + font-size: @font_snormal@ !important; } richlistitem label.normal, richlistitem description.normal { color: @color_subtext_default@; - font-size: @font_small@ !important; + font-size: @font_xtiny@ !important; white-space: pre-wrap; word-wrap: break-word; } richlistitem label.normal-black, richlistitem description.normal-black { - font-size: @font_small@ !important; + font-size: @font_xtiny@ !important; white-space: pre-wrap; word-wrap: break-word; } @@ -430,7 +427,7 @@ richlistitem description.normal-black { richlistitem label.normal-bold, richlistitem description.normal-bold { font-weight: bold; - font-size: @font_small@ !important; + font-size: @font_xtiny@ !important; white-space: pre-wrap; word-wrap: break-word; } @@ -441,6 +438,7 @@ richlistitem[selected="true"] { } richlistitem:hover:active:not([selected="true"]):not([nohighlight="true"]), +richlistitem:hover:active:not([selected="true"]):not([class="section-header"]), richlistitem:hover:active:not([selected="true"]):not([nohighlight="true"]) label.normal, richlistitem:hover:active:not([selected="true"]):not([nohighlight="true"]) description.normal { background-color: @color_background_highlight@; @@ -449,9 +447,15 @@ richlistitem:hover:active:not([selected="true"]):not([nohighlight="true"]) descr richlistitem.section-header, richlistitem[selected="true"].section-header { + font-size: @font_xtiny@; font-weight: bold; - color: @color_text_header@; - background-color: @color_background_header@; + color: @color_text_panel_subheader@; + background-color: @color_background_button@; + margin: 0; + padding: @padding_xxnormal@ @padding_large@; + border-top: @border_width_tiny@ solid @color_background_settings@; + border-bottom: @border_width_large@ solid; + -moz-border-bottom-colors: @color_background_button@ @color_background_settings@; } richlistitem .show-on-select { @@ -474,6 +478,24 @@ richlistitem[typeName="message"] { border-bottom: 0; } +richlistitem setting { + -moz-padding-start: 0; + -moz-padding-end: 0; +} + +richlistitem setting:first-child { + border-top: @border_width_tiny@ solid @color_background_button@; +} + +richlistitem[isDisabled="true"] .title, +richlistitem[isDisabled="true"] .normal { + color: @color_text_disabled@; +} + +richlistitem[isDisabled="true"] image { + opacity: 0.25; +} + /* colorpicker ------------------------------------------------------------- */ colorpicker > panel { background-color: #767973; @@ -498,7 +520,7 @@ colorpicker > vbox { .menulist-label { font-family: "Nokia Sans", Tahoma, sans-serif !important; font-weight: normal; - font-size: @font_snormal@ !important; + font-size: @font_xtiny@; background-color: transparent !important; } @@ -506,22 +528,22 @@ menulist { -moz-appearance: none !important; -moz-user-focus: ignore; min-width: @touch_button_minwidth@ !important; - min-height: @touch_button_small@ !important; /* button size */ + min-height: @touch_button_tiny@ !important; /* button size */ color: @color_text_button@ !important; + background-color: @color_background_button@; margin: @margin_normal@; - padding: @padding_small@ @padding_xnormal@; - background-image: url("chrome://browser/skin/images/button-bg.png"); - background-size: auto 100%; - border: @border_width_tiny@ solid @color_button_border@; + padding: @padding_xnormal@; + border-width: 0; + border-radius: 0; } menulist[disabled="true"] { - color: @color_text_disabled@ !important; - border: @border_width_tiny@ solid @color_button_border@ !important; + color: @color_text_button_disabled@ !important; + background-color: @color_background_button_disabled@; } menulist:not([disabled="true"]):hover:active { - background-image: url("chrome://browser/skin/images/toggle-off.png"); + background-color: @color_background_highlight@; } menulist > dropmarker { @@ -709,6 +731,11 @@ dialog { .prompt-button { min-width: 33%; + min-height: @touch_button_small@; +} + +.prompt-button .button-text { + font-size: @font_snormal@ !important; } .panel-row-button:first-child { @@ -725,6 +752,26 @@ dialog { } } +@media (@orientation@: portrait) and (min-width: @tablet_panel_minwidth@) { + #panel-controls > .panel-row-button { + min-width: @tablet_panel_controls@ !important; + } + + #panel-items { + max-width: @tablet_panel_item_width@ !important; + } +} + +@media (@orientation@: landscape) and (min-width: @tablet_panel_minwidth@) { + #panel-controls > .panel-row-button { + min-width: @tablet_panel_controls_wide@ !important; + } + + #panel-items { + max-width: @tablet_panel_item_width_wide@ !important; + } +} + .panel-row-button .toolbarbutton-text { text-align: left; font-size: @font_xtiny@ !important; @@ -756,12 +803,51 @@ dialog { pointer-events: none; } +#panel-container { + background-color: @color_background_settings@ !important; +} + #panel-container-inner { -moz-box-orient: vertical; + background-color: transparent !important; +} + +#panel-container-inner > vbox { + border: @border_width_large@ solid @color_background_active@; + box-shadow: 0 0 @shadow_width_tiny@ @shadow_width_medium@ @color_background_button_overlay@; } #panel-controls { -moz-box-orient: horizontal; + background-color: transparent !important; + padding: @padding_xxxnormal@ 0 !important; +} + +#panel-controls .toolbarbutton-text { + font-size: @font_snormal@ !important; +} + +#panel-controls .toolbarbutton-icon[label]:not([label=""]), +#panel-controls .toolbarbutton-icon[type="menu"] { + -moz-margin-start: @margin_xxxnormal@; + -moz-margin-end: @margin_xnormal@; +} + +#panel-controls > .panel-row-button { + border-top: @border_width_tiny@ solid @color_background_settings@ !important; + border-bottom: @border_width_large@ solid !important; + -moz-border-bottom-colors: @color_background_button@ @color_background_settings@ !important; + -moz-border-start: 0 solid; + -moz-border-end: 0 solid; +} + +#panel-controls > .panel-row-button[checked="true"] { + background-color: @color_background_highlight@; + color: @color_text_default@; +} + +.panel-list { + background: transparent; } @media (min-width: @tablet_panel_minwidth@) { @@ -771,7 +857,6 @@ dialog { } #panel-items { - max-width: @tablet_panel_minwidth@; min-width: 0px !important; } @@ -782,9 +867,9 @@ dialog { } #panel-controls > .panel-row-button { + margin: 0; -moz-box-orient: horizontal; -moz-box-flex: 0; - min-width: @tablet_panel_controls@ !important; } #panel-controls .toolbarbutton-text { @@ -794,7 +879,11 @@ dialog { #panel-container { -moz-box-pack: center; - padding: @padding_xlarge@ 0px; + padding: @padding_xxxlarge@ 0 @padding_xlarge@ 0; + } + + #panel-container-inner > vbox { + padding: @padding_xlarge@ @padding_xxlarge@; } } diff --git a/mobile/themes/core/jar.mn b/mobile/themes/core/jar.mn index 3785401b27e1..b6e55eb6f895 100644 --- a/mobile/themes/core/jar.mn +++ b/mobile/themes/core/jar.mn @@ -391,6 +391,8 @@ chrome.jar: skin/honeycomb/images/check-30.png (images/check-30.png) skin/honeycomb/images/check-selected-hdpi.png (honeycomb/images/check-selected-hdpi.png) skin/honeycomb/images/check-unselected-hdpi.png (honeycomb/images/check-unselected-hdpi.png) + skin/honeycomb/images/check-selected-tap-hdpi.png (honeycomb/images/check-selected-tap-hdpi.png) + skin/honeycomb/images/check-unselected-tap-hdpi.png (honeycomb/images/check-unselected-tap-hdpi.png) skin/honeycomb/images/search-glass-30.png (honeycomb/images/search-glass-30.png) skin/honeycomb/images/search-clear-30.png (honeycomb/images/search-clear-30.png) skin/honeycomb/images/section-expanded-16.png (images/section-expanded-16.png) From 4fd7a69c9e89880c53e35c62015467f131b96b1f Mon Sep 17 00:00:00 2001 From: Wes Johnston Date: Wed, 28 Sep 2011 12:30:15 -0700 Subject: [PATCH 20/65] Bug 689562 - Fix highlight state for reload button. r=lucasr --- mobile/themes/core/honeycomb/browser.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mobile/themes/core/honeycomb/browser.css b/mobile/themes/core/honeycomb/browser.css index ce0366c585d5..8a98ef6b6a76 100644 --- a/mobile/themes/core/honeycomb/browser.css +++ b/mobile/themes/core/honeycomb/browser.css @@ -261,7 +261,9 @@ toolbarbutton.urlbar-button { background-position: bottom right; background-repeat: no-repeat; border-bottom: @border_width_small@ solid @color_url_border@; - padding: 0px @padding_normal@ @padding_tiny@ @padding_tiny@; + padding: 0px @padding_tiny@ @padding_tiny@; + /* larger padding on the end to account for the background-image */ + -moz-padding-end: @padding_xsmall@ !important; } #urlbar-icons:-moz-locale-dir(rtl) { @@ -274,7 +276,7 @@ toolbarbutton.urlbar-button { } #urlbar-icons toolbarbutton { - padding: 0px @padding_normal@ !important; + padding: 0px @padding_xxxnormal@ !important; margin: 0px !important; border: none; } From 5cecc378f22e84a2d72572caaf89f6acc6832634 Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Tue, 27 Sep 2011 15:19:24 -0700 Subject: [PATCH 21/65] Bug 686742 - Move YUV conversion code into gfxUtil functions. r=derf --HG-- extra : rebase_source : 0993d4fc7558c40fd6df97278919c01fc8e92918 --- gfx/layers/ImageLayers.h | 3 +- gfx/layers/basic/BasicImages.cpp | 117 +------------------------- gfx/thebes/gfxUtils.cpp | 138 +++++++++++++++++++++++++++++++ gfx/thebes/gfxUtils.h | 27 ++++++ 4 files changed, 171 insertions(+), 114 deletions(-) diff --git a/gfx/layers/ImageLayers.h b/gfx/layers/ImageLayers.h index f1ebe3c47fe2..28fa8e313eff 100644 --- a/gfx/layers/ImageLayers.h +++ b/gfx/layers/ImageLayers.h @@ -42,11 +42,12 @@ #include "gfxPattern.h" #include "nsThreadUtils.h" -#include "nsCoreAnimationSupport.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/TimeStamp.h" #include "mozilla/mozalloc.h" +class nsIOSurface; + namespace mozilla { namespace layers { diff --git a/gfx/layers/basic/BasicImages.cpp b/gfx/layers/basic/BasicImages.cpp index 065596b82d17..e42abb30e20f 100644 --- a/gfx/layers/basic/BasicImages.cpp +++ b/gfx/layers/basic/BasicImages.cpp @@ -47,8 +47,7 @@ #include "cairo.h" -#include "yuv_convert.h" -#include "ycbcr_to_rgb565.h" +#include "gfxUtils.h" #include "gfxPlatform.h" @@ -156,54 +155,10 @@ BasicPlanarYCbCrImage::SetData(const Data& aData) return; } - gfx::YUVType type = - gfx::TypeFromSize(aData.mYSize.width, - aData.mYSize.height, - aData.mCbCrSize.width, - aData.mCbCrSize.height); - gfxASurface::gfxImageFormat format = GetOffscreenFormat(); - // 'prescale' is true if the scaling is to be done as part of the - // YCbCr to RGB conversion rather than on the RGB data when rendered. - PRBool prescale = mScaleHint.width > 0 && mScaleHint.height > 0 && - mScaleHint != aData.mPicSize; - if (format == gfxASurface::ImageFormatRGB16_565) { -#if defined(HAVE_YCBCR_TO_RGB565) - if (prescale && - !gfx::IsScaleYCbCrToRGB565Fast(aData.mPicX, - aData.mPicY, - aData.mPicSize.width, - aData.mPicSize.height, - mScaleHint.width, - mScaleHint.height, - type, - gfx::FILTER_BILINEAR) && - gfx::IsConvertYCbCrToRGB565Fast(aData.mPicX, - aData.mPicY, - aData.mPicSize.width, - aData.mPicSize.height, - type)) { - prescale = PR_FALSE; - } -#else - // yuv2rgb16 function not available - format = gfxASurface::ImageFormatRGB24; -#endif - } - else if (format != gfxASurface::ImageFormatRGB24) { - // No other formats are currently supported. - format = gfxASurface::ImageFormatRGB24; - } - if (format == gfxASurface::ImageFormatRGB24) { - /* ScaleYCbCrToRGB32 does not support a picture offset, nor 4:4:4 data. - See bugs 639415 and 640073. */ - if (aData.mPicX != 0 || aData.mPicY != 0 || type == gfx::YV24) - prescale = PR_FALSE; - } - - gfxIntSize size(prescale ? mScaleHint.width : aData.mPicSize.width, - prescale ? mScaleHint.height : aData.mPicSize.height); + gfxIntSize size(mScaleHint); + gfxUtils::GetYCbCrToRGBDestFormatAndSize(aData, format, size); mStride = gfxASurface::FormatStrideForWidth(format, size.width); mBuffer = AllocateBuffer(size.height * mStride); @@ -212,71 +167,7 @@ BasicPlanarYCbCrImage::SetData(const Data& aData) return; } - // Convert from YCbCr to RGB now, scaling the image if needed. - if (size != aData.mPicSize) { -#if defined(HAVE_YCBCR_TO_RGB565) - if (format == gfxASurface::ImageFormatRGB16_565) { - gfx::ScaleYCbCrToRGB565(aData.mYChannel, - aData.mCbChannel, - aData.mCrChannel, - mBuffer, - aData.mPicX, - aData.mPicY, - aData.mPicSize.width, - aData.mPicSize.height, - size.width, - size.height, - aData.mYStride, - aData.mCbCrStride, - mStride, - type, - gfx::FILTER_BILINEAR); - } else -#endif - gfx::ScaleYCbCrToRGB32(aData.mYChannel, - aData.mCbChannel, - aData.mCrChannel, - mBuffer, - aData.mPicSize.width, - aData.mPicSize.height, - size.width, - size.height, - aData.mYStride, - aData.mCbCrStride, - mStride, - type, - gfx::ROTATE_0, - gfx::FILTER_BILINEAR); - } else { // no prescale -#if defined(HAVE_YCBCR_TO_RGB565) - if (format == gfxASurface::ImageFormatRGB16_565) { - gfx::ConvertYCbCrToRGB565(aData.mYChannel, - aData.mCbChannel, - aData.mCrChannel, - mBuffer, - aData.mPicX, - aData.mPicY, - aData.mPicSize.width, - aData.mPicSize.height, - aData.mYStride, - aData.mCbCrStride, - mStride, - type); - } else // format != gfxASurface::ImageFormatRGB16_565 -#endif - gfx::ConvertYCbCrToRGB32(aData.mYChannel, - aData.mCbChannel, - aData.mCrChannel, - mBuffer, - aData.mPicX, - aData.mPicY, - aData.mPicSize.width, - aData.mPicSize.height, - aData.mYStride, - aData.mCbCrStride, - mStride, - type); - } + gfxUtils::ConvertYCbCrToRGB(aData, format, size, mBuffer, mStride); SetOffscreenFormat(format); mSize = size; } diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index f90af754f801..8fe055d5fed1 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -40,11 +40,16 @@ #include "gfxPlatform.h" #include "gfxDrawable.h" #include "nsRegion.h" +#include "yuv_convert.h" +#include "ycbcr_to_rgb565.h" #ifdef XP_WIN #include "gfxWindowsPlatform.h" #endif +using namespace mozilla; +using namespace mozilla::layers; + static PRUint8 sUnpremultiplyTable[256*256]; static PRUint8 sPremultiplyTable[256*256]; static PRBool sTablesInitialized = PR_FALSE; @@ -517,3 +522,136 @@ gfxUtils::GfxRectToIntRect(const gfxRect& aIn, nsIntRect* aOut) return gfxRect(aOut->x, aOut->y, aOut->width, aOut->height).IsEqualEdges(aIn); } +void +gfxUtils::GetYCbCrToRGBDestFormatAndSize(const PlanarYCbCrImage::Data& aData, + gfxASurface::gfxImageFormat& aSuggestedFormat, + gfxIntSize& aSuggestedSize) +{ + gfx::YUVType yuvtype = + gfx::TypeFromSize(aData.mYSize.width, + aData.mYSize.height, + aData.mCbCrSize.width, + aData.mCbCrSize.height); + + // 'prescale' is true if the scaling is to be done as part of the + // YCbCr to RGB conversion rather than on the RGB data when rendered. + PRBool prescale = aSuggestedSize.width > 0 && aSuggestedSize.height > 0 && + aSuggestedSize != aData.mPicSize; + + if (aSuggestedFormat == gfxASurface::ImageFormatRGB16_565) { +#if defined(HAVE_YCBCR_TO_RGB565) + if (prescale && + !gfx::IsScaleYCbCrToRGB565Fast(aData.mPicX, + aData.mPicY, + aData.mPicSize.width, + aData.mPicSize.height, + aSuggestedSize.width, + aSuggestedSize.height, + yuvtype, + gfx::FILTER_BILINEAR) && + gfx::IsConvertYCbCrToRGB565Fast(aData.mPicX, + aData.mPicY, + aData.mPicSize.width, + aData.mPicSize.height, + yuvtype)) { + prescale = PR_FALSE; + } +#else + // yuv2rgb16 function not available + aSuggestedFormat = gfxASurface::ImageFormatRGB24; +#endif + } + else if (aSuggestedFormat != gfxASurface::ImageFormatRGB24) { + // No other formats are currently supported. + aSuggestedFormat = gfxASurface::ImageFormatRGB24; + } + if (aSuggestedFormat == gfxASurface::ImageFormatRGB24) { + /* ScaleYCbCrToRGB32 does not support a picture offset, nor 4:4:4 data. + See bugs 639415 and 640073. */ + if (aData.mPicX != 0 || aData.mPicY != 0 || yuvtype == gfx::YV24) + prescale = PR_FALSE; + } + if (!prescale) { + aSuggestedSize = aData.mPicSize; + } +} + +void +gfxUtils::ConvertYCbCrToRGB(const PlanarYCbCrImage::Data& aData, + const gfxASurface::gfxImageFormat& aDestFormat, + const gfxIntSize& aDestSize, + unsigned char* aDestBuffer, + PRInt32 aStride) +{ + gfx::YUVType yuvtype = + gfx::TypeFromSize(aData.mYSize.width, + aData.mYSize.height, + aData.mCbCrSize.width, + aData.mCbCrSize.height); + + // Convert from YCbCr to RGB now, scaling the image if needed. + if (aDestSize != aData.mPicSize) { +#if defined(HAVE_YCBCR_TO_RGB565) + if (aDestFormat == gfxASurface::ImageFormatRGB16_565) { + gfx::ScaleYCbCrToRGB565(aData.mYChannel, + aData.mCbChannel, + aData.mCrChannel, + aDestBuffer, + aData.mPicX, + aData.mPicY, + aData.mPicSize.width, + aData.mPicSize.height, + aDestSize.width, + aDestSize.height, + aData.mYStride, + aData.mCbCrStride, + aStride, + yuvtype, + gfx::FILTER_BILINEAR); + } else +#endif + gfx::ScaleYCbCrToRGB32(aData.mYChannel, + aData.mCbChannel, + aData.mCrChannel, + aDestBuffer, + aData.mPicSize.width, + aData.mPicSize.height, + aDestSize.width, + aDestSize.height, + aData.mYStride, + aData.mCbCrStride, + aStride, + yuvtype, + gfx::ROTATE_0, + gfx::FILTER_BILINEAR); + } else { // no prescale +#if defined(HAVE_YCBCR_TO_RGB565) + if (aDestFormat == gfxASurface::ImageFormatRGB16_565) { + gfx::ConvertYCbCrToRGB565(aData.mYChannel, + aData.mCbChannel, + aData.mCrChannel, + aDestBuffer, + aData.mPicX, + aData.mPicY, + aData.mPicSize.width, + aData.mPicSize.height, + aData.mYStride, + aData.mCbCrStride, + aStride, + yuvtype); + } else // aDestFormat != gfxASurface::ImageFormatRGB16_565 +#endif + gfx::ConvertYCbCrToRGB32(aData.mYChannel, + aData.mCbChannel, + aData.mCrChannel, + aDestBuffer, + aData.mPicX, + aData.mPicY, + aData.mPicSize.width, + aData.mPicSize.height, + aData.mYStride, + aData.mCbCrStride, + aStride, + yuvtype); + } +} diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index 75ab02a2c4d2..3951c864af45 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -41,6 +41,7 @@ #include "gfxTypes.h" #include "gfxPattern.h" #include "gfxImageSurface.h" +#include "ImageLayers.h" class gfxDrawable; class nsIntRegion; @@ -123,6 +124,32 @@ public: * aVal. */ static gfxFloat ClampToScaleFactor(gfxFloat aVal); + + /** + * Helper function for ConvertYCbCrToRGB that finds the + * RGB buffer size and format for given YCbCrImage. + * @param aSuggestedFormat will be set to ImageFormatRGB24 + * if the desired format is not supported. + * @param aSuggestedSize will be set to the picture size from aData + * if either the suggested size was {0,0} + * or simultaneous scaling and conversion is not supported. + */ + static void + GetYCbCrToRGBDestFormatAndSize(const mozilla::layers::PlanarYCbCrImage::Data& aData, + gfxASurface::gfxImageFormat& aSuggestedFormat, + gfxIntSize& aSuggestedSize); + + /** + * Convert YCbCrImage into RGB aDestBuffer + * Format and Size parameters must have + * been passed to GetYCbCrToRGBDestFormatAndSize + */ + static void + ConvertYCbCrToRGB(const mozilla::layers::PlanarYCbCrImage::Data& aData, + const gfxASurface::gfxImageFormat& aDestFormat, + const gfxIntSize& aDestSize, + unsigned char* aDestBuffer, + PRInt32 aStride); }; #endif From 12f1dcd5d40318a6730979ce228e7b91968eaca9 Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Tue, 27 Sep 2011 15:19:26 -0700 Subject: [PATCH 22/65] Bug 687372 - ImageLayerOGL should not destroy surface given as argument. r=cjones --HG-- extra : rebase_source : 00d0c49f320c0969570917a321b8a95a3357a943 --- gfx/layers/basic/BasicLayers.cpp | 137 +++++++++++--------------- gfx/layers/d3d9/ImageLayerD3D9.cpp | 45 +++------ gfx/layers/d3d9/ImageLayerD3D9.h | 7 +- gfx/layers/ipc/PLayers.ipdl | 10 +- gfx/layers/ipc/ShadowLayers.cpp | 24 ++--- gfx/layers/ipc/ShadowLayers.h | 49 +++++---- gfx/layers/ipc/ShadowLayersParent.cpp | 43 +++----- gfx/layers/ipc/ShadowLayersParent.h | 7 +- gfx/layers/opengl/CanvasLayerOGL.cpp | 2 +- gfx/layers/opengl/ImageLayerOGL.cpp | 59 ++++++----- gfx/layers/opengl/ImageLayerOGL.h | 10 +- 11 files changed, 153 insertions(+), 240 deletions(-) diff --git a/gfx/layers/basic/BasicLayers.cpp b/gfx/layers/basic/BasicLayers.cpp index b102b1c168d3..40f2f57e568f 100644 --- a/gfx/layers/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -2359,9 +2359,7 @@ public: } virtual ~BasicShadowableImageLayer() { - if (IsSurfaceDescriptorValid(mBackBuffer)) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); - } + DestroyBackBuffer(); MOZ_COUNT_DTOR(BasicShadowableImageLayer); } @@ -2391,10 +2389,23 @@ public: virtual void Disconnect() { + mBackBufferY = mBackBufferU = mBackBufferV = nsnull; mBackBuffer = SurfaceDescriptor(); BasicShadowableLayer::Disconnect(); } + void DestroyBackBuffer() + { + if (IsSurfaceDescriptorValid(mBackBuffer)) { + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); + } + if (mBackBufferY) { + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferY); + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferU); + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferV); + } + } + private: BasicShadowLayerManager* BasicManager() { @@ -2427,50 +2438,21 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext) const PlanarYCbCrImage::Data *data = YCbCrImage->GetData(); NS_ASSERTION(data, "Must be able to retrieve yuv data from image!"); - if (mSize != data->mYSize || mCbCrSize != data->mCbCrSize) { - - if (mBackBufferY) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferY); - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferU); - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(mBackBufferV); - BasicManager()->DestroyedImageBuffer(BasicManager()->Hold(this)); - } + if (mSize != data->mYSize || mCbCrSize != data->mCbCrSize || !mBackBufferY) { + DestroyBackBuffer(); mSize = data->mYSize; mCbCrSize = data->mCbCrSize; - nsRefPtr tmpYSurface; - nsRefPtr tmpUSurface; - nsRefPtr tmpVSurface; - - if (!BasicManager()->AllocDoubleBuffer( - mSize, - gfxASurface::CONTENT_ALPHA, - getter_AddRefs(tmpYSurface), getter_AddRefs(mBackBufferY))) + if (!BasicManager()->AllocBuffer(mSize, gfxASurface::CONTENT_ALPHA, + getter_AddRefs(mBackBufferY)) || + !BasicManager()->AllocBuffer(mCbCrSize, gfxASurface::CONTENT_ALPHA, + getter_AddRefs(mBackBufferU)) || + !BasicManager()->AllocBuffer(mCbCrSize, gfxASurface::CONTENT_ALPHA, + getter_AddRefs(mBackBufferV))) { NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!"); - - if (!BasicManager()->AllocDoubleBuffer( - mCbCrSize, - gfxASurface::CONTENT_ALPHA, - getter_AddRefs(tmpUSurface), getter_AddRefs(mBackBufferU))) - NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!"); - - if (!BasicManager()->AllocDoubleBuffer( - mCbCrSize, - gfxASurface::CONTENT_ALPHA, - getter_AddRefs(tmpVSurface), getter_AddRefs(mBackBufferV))) - NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!"); - - YUVImage yuv(tmpYSurface->GetShmem(), - tmpUSurface->GetShmem(), - tmpVSurface->GetShmem(), - nsIntRect()); - - BasicManager()->CreatedImageBuffer(BasicManager()->Hold(this), - nsIntSize(mSize.width, mSize.height), - yuv); - + } } - + for (int i = 0; i < data->mYSize.height; i++) { memcpy(mBackBufferY->Data() + i * mBackBufferY->Stride(), data->mYChannel + i * data->mYStride, @@ -2484,15 +2466,14 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext) data->mCrChannel + i * data->mCbCrStride, data->mCbCrSize.width); } - + YUVImage yuv(mBackBufferY->GetShmem(), mBackBufferU->GetShmem(), mBackBufferV->GetShmem(), data->GetPictureRect()); - + BasicManager()->PaintedImage(BasicManager()->Hold(this), yuv); - return; } @@ -2501,24 +2482,15 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext) if (!pat || !HasShadow()) return; - if (oldSize != mSize) { - if (IsSurfaceDescriptorValid(mBackBuffer)) { - BasicManager()->DestroyedImageBuffer(BasicManager()->Hold(this)); - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); - } + if (oldSize != mSize || !IsSurfaceDescriptorValid(mBackBuffer)) { + DestroyBackBuffer(); - SurfaceDescriptor tmpFrontSurface; - // XXX error handling? - if (!BasicManager()->AllocDoubleBuffer( + if (!BasicManager()->AllocBuffer( mSize, (GetContentFlags() & CONTENT_OPAQUE) ? gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA, - &tmpFrontSurface, &mBackBuffer)) + &mBackBuffer)) NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!"); - - BasicManager()->CreatedImageBuffer(BasicManager()->Hold(this), - nsIntSize(mSize.width, mSize.height), - tmpFrontSurface); } nsRefPtr backSurface = @@ -2741,7 +2713,7 @@ public: mOldValidRegion.SetEmpty(); if (IsSurfaceDescriptorValid(mFrontBufferDescriptor)) { - BasicManager()->ShadowLayerManager::DestroySharedSurface(&mFrontBufferDescriptor, mAllocator); + mAllocator->DestroySharedSurface(&mFrontBufferDescriptor); } } @@ -2902,18 +2874,17 @@ public: virtual void Disconnect() { - DestroyFrontBuffer(); + mFrontBuffer = SurfaceDescriptor(); ShadowImageLayer::Disconnect(); } - virtual PRBool Init(const SharedImage& front, const nsIntSize& size); - - virtual void Swap(const SharedImage& aNewFront, SharedImage* aNewBack); + virtual void Swap(const SharedImage& aNewFront, + SharedImage* aNewBack); virtual void DestroyFrontBuffer() { - if (IsSurfaceDescriptorValid(mFrontBuffer)) { - BasicManager()->ShadowLayerManager::DestroySharedSurface(&mFrontBuffer, mAllocator); + if (mAllocator && IsSurfaceDescriptorValid(mFrontBuffer)) { + mAllocator->DestroySharedSurface(&mFrontBuffer); } } @@ -2929,19 +2900,24 @@ protected: gfxIntSize mSize; }; -PRBool -BasicShadowImageLayer::Init(const SharedImage& front, - const nsIntSize& size) -{ - mFrontBuffer = front.get_SurfaceDescriptor(); - mSize = gfxIntSize(size.width, size.height); - return PR_TRUE; -} - void -BasicShadowImageLayer::Swap(const SharedImage& aNewFront, SharedImage* aNewBack) +BasicShadowImageLayer::Swap(const SharedImage& aNewFront, + SharedImage* aNewBack) { - *aNewBack = mFrontBuffer; + nsRefPtr surface = + BasicManager()->OpenDescriptor(aNewFront); + // Destroy mFrontBuffer if size different + if (surface->GetSize() != mSize) { + DestroyFrontBuffer(); + mSize = surface->GetSize(); + } + + // If mFrontBuffer + if (IsSurfaceDescriptorValid(mFrontBuffer)) { + *aNewBack = mFrontBuffer; + } else { + *aNewBack = null_t(); + } mFrontBuffer = aNewFront.get_SurfaceDescriptor(); } @@ -3017,7 +2993,7 @@ public: virtual void DestroyFrontBuffer() { if (IsSurfaceDescriptorValid(mFrontSurface)) { - BasicManager()->ShadowLayerManager::DestroySharedSurface(&mFrontSurface, mAllocator); + mAllocator->DestroySharedSurface(&mFrontSurface); } } @@ -3324,14 +3300,17 @@ BasicShadowLayerManager::ForwardTransaction() if (newBack.type() == SharedImage::TSurfaceDescriptor) { layer->SetBackBuffer(newBack.get_SurfaceDescriptor()); - } else { + } else if (newBack.type() == SharedImage::TYUVImage) { const YUVImage& yuv = newBack.get_YUVImage(); nsRefPtr YSurf = gfxSharedImageSurface::Open(yuv.Ydata()); nsRefPtr USurf = gfxSharedImageSurface::Open(yuv.Udata()); nsRefPtr VSurf = gfxSharedImageSurface::Open(yuv.Vdata()); layer->SetBackBufferYUVImage(YSurf, USurf, VSurf); + } else { + layer->SetBackBuffer(SurfaceDescriptor()); + layer->SetBackBufferYUVImage(nsnull, nsnull, nsnull); } - + break; } diff --git a/gfx/layers/d3d9/ImageLayerD3D9.cpp b/gfx/layers/d3d9/ImageLayerD3D9.cpp index d429c1f09e25..351cdfbb64ec 100644 --- a/gfx/layers/d3d9/ImageLayerD3D9.cpp +++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp @@ -610,40 +610,19 @@ ShadowImageLayerD3D9::ShadowImageLayerD3D9(LayerManagerD3D9* aManager) ShadowImageLayerD3D9::~ShadowImageLayerD3D9() {} -PRBool -ShadowImageLayerD3D9::Init(const SharedImage& aFront, - const nsIntSize& aSize) +void +ShadowImageLayerD3D9::Swap(const SharedImage& aNewFront, + SharedImage* aNewBack) { - if (aFront.type() == SharedImage::TSurfaceDescriptor) { - SurfaceDescriptor desc = aFront.get_SurfaceDescriptor(); - nsRefPtr surf = - ShadowLayerForwarder::OpenDescriptor(desc); - + if (aNewFront.type() == SharedImage::TSurfaceDescriptor) { if (!mBuffer) { mBuffer = new ShadowBufferD3D9(this); } - return !!mBuffer; - } else { - if (!mYCbCrImage) { - mYCbCrImage = new PlanarYCbCrImageD3D9(); - } - return !!mYCbCrImage; - } -} - -void -ShadowImageLayerD3D9::Swap(const SharedImage& aNewFront, SharedImage* aNewBack) -{ - - if (aNewFront.type() == SharedImage::TSurfaceDescriptor) { - nsRefPtr surf = + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.get_SurfaceDescriptor()); - - if (mBuffer) { - mBuffer->Upload(surf, GetVisibleRegion().GetBounds()); - } - } else { + mBuffer->Upload(surf, GetVisibleRegion().GetBounds()); + } else { const YUVImage& yuv = aNewFront.get_YUVImage(); nsRefPtr surfY = @@ -665,6 +644,10 @@ ShadowImageLayerD3D9::Swap(const SharedImage& aNewFront, SharedImage* aNewBack) data.mPicX = 0; data.mPicY = 0; + if (!mYCbCrImage) { + mYCbCrImage = new PlanarYCbCrImageD3D9(); + } + mYCbCrImage->SetData(data); } @@ -672,12 +655,6 @@ ShadowImageLayerD3D9::Swap(const SharedImage& aNewFront, SharedImage* aNewBack) *aNewBack = aNewFront; } -void -ShadowImageLayerD3D9::DestroyFrontBuffer() -{ - Destroy(); -} - void ShadowImageLayerD3D9::Disconnect() { diff --git a/gfx/layers/d3d9/ImageLayerD3D9.h b/gfx/layers/d3d9/ImageLayerD3D9.h index 2227a979953b..a2e40af255f7 100644 --- a/gfx/layers/d3d9/ImageLayerD3D9.h +++ b/gfx/layers/d3d9/ImageLayerD3D9.h @@ -185,11 +185,8 @@ public: virtual ~ShadowImageLayerD3D9(); // ShadowImageLayer impl - virtual PRBool Init(const SharedImage& aFront, const nsIntSize& aSize); - - virtual void Swap(const SharedImage& aFront, SharedImage* aNewBack); - - virtual void DestroyFrontBuffer(); + virtual void Swap(const SharedImage& aFront, + SharedImage* aNewBack); virtual void Disconnect(); diff --git a/gfx/layers/ipc/PLayers.ipdl b/gfx/layers/ipc/PLayers.ipdl index c323c6a3dceb..825f02badba6 100644 --- a/gfx/layers/ipc/PLayers.ipdl +++ b/gfx/layers/ipc/PLayers.ipdl @@ -94,6 +94,7 @@ struct YUVImage { union SharedImage { SurfaceDescriptor; YUVImage; + null_t; }; struct ThebesBuffer { @@ -122,13 +123,6 @@ struct OpCreateCanvasBuffer { }; struct OpDestroyCanvasFrontBuffer { PLayer layer; }; -struct OpCreateImageBuffer { - PLayer layer; - nsIntSize size; - SharedImage initialFront; -}; -struct OpDestroyImageFrontBuffer { PLayer layer; }; - // Change a layer's attributes struct CommonLayerAttributes { @@ -205,10 +199,8 @@ union Edit { OpCreateCanvasLayer; OpCreateCanvasBuffer; OpCreateThebesBuffer; - OpCreateImageBuffer; OpDestroyThebesFrontBuffer; OpDestroyCanvasFrontBuffer; - OpDestroyImageFrontBuffer; OpSetLayerAttributes; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 657f8f18cd02..415c9b68e6df 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -201,16 +201,6 @@ ShadowLayerForwarder::CreatedThebesBuffer(ShadowableLayer* aThebes, aFrontValidRegion)); } -void -ShadowLayerForwarder::CreatedImageBuffer(ShadowableLayer* aImage, - nsIntSize aSize, - const SharedImage& aTempFrontImage) -{ - mTxn->AddEdit(OpCreateImageBuffer(NULL, Shadow(aImage), - aSize, - aTempFrontImage)); -} - void ShadowLayerForwarder::CreatedCanvasBuffer(ShadowableLayer* aCanvas, nsIntSize aSize, @@ -231,12 +221,6 @@ ShadowLayerForwarder::DestroyedThebesBuffer(ShadowableLayer* aThebes, mTxn->AddBufferToDestroy(aBackBufferToDestroy); } -void -ShadowLayerForwarder::DestroyedImageBuffer(ShadowableLayer* aImage) -{ - mTxn->AddEdit(OpDestroyImageFrontBuffer(NULL, Shadow(aImage))); -} - void ShadowLayerForwarder::DestroyedCanvasBuffer(ShadowableLayer* aCanvas) { @@ -544,7 +528,9 @@ ShadowLayerForwarder::DestroySharedSurface(SurfaceDescriptor* aSurface) if (PlatformDestroySharedSurface(aSurface)) { return; } - DestroySharedShmemSurface(aSurface, mShadowManager); + if (aSurface->type() == SurfaceDescriptor::TShmem) { + DestroySharedShmemSurface(aSurface, mShadowManager); + } } @@ -570,7 +556,9 @@ ShadowLayerManager::DestroySharedSurface(SurfaceDescriptor* aSurface, if (PlatformDestroySharedSurface(aSurface)) { return; } - DestroySharedShmemSurface(aSurface, aDeallocator); + if (aSurface->type() == SurfaceDescriptor::TShmem) { + DestroySharedShmemSurface(aSurface, aDeallocator); + } } diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 2428fa937f2a..42a21a320156 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -160,12 +160,9 @@ public: const nsIntRect& aBufferRect, const SurfaceDescriptor& aInitialFrontBuffer); /** - * For the next two methods, |aSize| is the size of + * For the next method, |aSize| is the size of * |aInitialFrontSurface|. */ - void CreatedImageBuffer(ShadowableLayer* aImage, - nsIntSize aSize, - const SharedImage& aInitialFrontImage); void CreatedCanvasBuffer(ShadowableLayer* aCanvas, nsIntSize aSize, const SurfaceDescriptor& aInitialFrontSurface, @@ -181,7 +178,6 @@ public: */ void DestroyedThebesBuffer(ShadowableLayer* aThebes, const SurfaceDescriptor& aBackBufferToDestroy); - void DestroyedImageBuffer(ShadowableLayer* aImage); void DestroyedCanvasBuffer(ShadowableLayer* aCanvas); @@ -432,6 +428,17 @@ protected: PLayerChild* mShadow; }; +/** + * SurfaceDeallocator interface + */ +class ISurfaceDeAllocator +{ +public: + virtual void DestroySharedSurface(gfxSharedImageSurface* aSurface) = 0; + virtual void DestroySharedSurface(SurfaceDescriptor* aSurface) = 0; +protected: + ~ISurfaceDeAllocator() {}; +}; /** * A ShadowLayer is the representation of a child-context's Layer in a @@ -447,14 +454,18 @@ public: virtual ~ShadowLayer() {} /** - * CONSTRUCTION PHASE ONLY + * Set deallocator for data recieved from IPC protocol + * We should be able to set allocator right before swap call + * that is why allowed multiple call with the same Allocator */ - void SetAllocator(PLayersParent* aAllocator) + virtual void SetAllocator(ISurfaceDeAllocator* aAllocator) { - NS_ABORT_IF_FALSE(!mAllocator, "Stomping allocator?"); + NS_ASSERTION(!mAllocator || mAllocator == aAllocator, "Stomping allocator?"); mAllocator = aAllocator; } + virtual void DestroyFrontBuffer() { }; + /** * The following methods are * @@ -491,7 +502,7 @@ protected: , mUseShadowClipRect(PR_FALSE) {} - PLayersParent* mAllocator; + ISurfaceDeAllocator* mAllocator; nsIntRegion mShadowVisibleRegion; gfx3DMatrix mShadowTransform; nsIntRect mShadowClipRect; @@ -617,28 +628,12 @@ class ShadowImageLayer : public ShadowLayer, public ImageLayer { public: - /** - * CONSTRUCTION PHASE ONLY - * - * Initialize this with a (temporary) front surface with the given - * size. This is expected to be followed with a Swap() in the same - * transaction to bring in real pixels. Init() may only be called - * once. - */ - virtual PRBool Init(const SharedImage& front, const nsIntSize& aSize) = 0; - /** * CONSTRUCTION PHASE ONLY * @see ShadowCanvasLayer::Swap */ - virtual void Swap(const SharedImage& aFront, SharedImage* aNewBack) = 0; - - /** - * CONSTRUCTION PHASE ONLY - * - * Destroy the current front buffer. - */ - virtual void DestroyFrontBuffer() = 0; + virtual void Swap(const SharedImage& aFront, + SharedImage* aNewBack) = 0; virtual ShadowLayer* AsShadowLayer() { return this; } diff --git a/gfx/layers/ipc/ShadowLayersParent.cpp b/gfx/layers/ipc/ShadowLayersParent.cpp index 72e08c03a1e2..a969614e81d4 100644 --- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -184,7 +184,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, nsRefPtr layer = layer_manager()->CreateShadowImageLayer(); - layer->SetAllocator(this); AsShadowLayer(edit.get_OpCreateImageLayer())->Bind(layer); break; } @@ -226,17 +225,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, break; } - case Edit::TOpCreateImageBuffer: { - MOZ_LAYERS_LOG(("[ParentSide] CreateImageBuffer")); - - const OpCreateImageBuffer ocb = edit.get_OpCreateImageBuffer(); - ShadowImageLayer* image = static_cast( - AsShadowLayer(ocb)->AsLayer()); - - image->Init(ocb.initialFront(), ocb.size()); - - break; - } case Edit::TOpDestroyThebesFrontBuffer: { MOZ_LAYERS_LOG(("[ParentSide] DestroyThebesFrontBuffer")); @@ -261,19 +249,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, break; } - case Edit::TOpDestroyImageFrontBuffer: { - MOZ_LAYERS_LOG(("[ParentSide] DestroyImageFrontBuffer")); - - const OpDestroyImageFrontBuffer& odfb = - edit.get_OpDestroyImageFrontBuffer(); - ShadowImageLayer* image = static_cast( - AsShadowLayer(odfb)->AsLayer()); - - image->DestroyFrontBuffer(); - - break; - } - // Attributes case Edit::TOpSetLayerAttributes: { MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes")); @@ -431,13 +406,9 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, ShadowImageLayer* image = static_cast(shadow->AsLayer()); - SharedImage newFront = op.newFrontBuffer(); + image->SetAllocator(this); SharedImage newBack; image->Swap(op.newFrontBuffer(), &newBack); - if (newFront == newBack) { - newFront = SharedImage(); - } - replyv.push_back(OpImageSwap(shadow, NULL, newBack)); @@ -485,5 +456,17 @@ ShadowLayersParent::Frame() return static_cast(Manager()); } +void +ShadowLayersParent::DestroySharedSurface(gfxSharedImageSurface* aSurface) +{ + layer_manager()->DestroySharedSurface(aSurface, this); +} + +void +ShadowLayersParent::DestroySharedSurface(SurfaceDescriptor* aSurface) +{ + layer_manager()->DestroySharedSurface(aSurface, this); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/ShadowLayersParent.h b/gfx/layers/ipc/ShadowLayersParent.h index 31124818a424..e10672c68a84 100644 --- a/gfx/layers/ipc/ShadowLayersParent.h +++ b/gfx/layers/ipc/ShadowLayersParent.h @@ -42,6 +42,7 @@ #define mozilla_layers_ShadowLayersParent_h #include "mozilla/layers/PLayersParent.h" +#include "ShadowLayers.h" namespace mozilla { @@ -54,7 +55,8 @@ namespace layers { class Layer; class ShadowLayerManager; -class ShadowLayersParent : public PLayersParent +class ShadowLayersParent : public PLayersParent, + public ISurfaceDeAllocator { typedef mozilla::layout::RenderFrameParent RenderFrameParent; typedef InfallibleTArray EditArray; @@ -70,6 +72,9 @@ public: ContainerLayer* GetRoot() const { return mRoot; } + virtual void DestroySharedSurface(gfxSharedImageSurface* aSurface); + virtual void DestroySharedSurface(SurfaceDescriptor* aSurface); + protected: NS_OVERRIDE virtual bool RecvUpdate(const EditArray& cset, EditReplyArray* reply); diff --git a/gfx/layers/opengl/CanvasLayerOGL.cpp b/gfx/layers/opengl/CanvasLayerOGL.cpp index 2777eeae4f38..9df91231ad32 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.cpp +++ b/gfx/layers/opengl/CanvasLayerOGL.cpp @@ -332,7 +332,7 @@ ShadowCanvasLayerOGL::DestroyFrontBuffer() { mTexImage = nsnull; if (IsSurfaceDescriptorValid(mDeadweight)) { - mOGLManager->DestroySharedSurface(&mDeadweight, mAllocator); + mAllocator->DestroySharedSurface(&mDeadweight); } } diff --git a/gfx/layers/opengl/ImageLayerOGL.cpp b/gfx/layers/opengl/ImageLayerOGL.cpp index 0659bcac572c..1a507d6583b6 100644 --- a/gfx/layers/opengl/ImageLayerOGL.cpp +++ b/gfx/layers/opengl/ImageLayerOGL.cpp @@ -822,37 +822,35 @@ ShadowImageLayerOGL::ShadowImageLayerOGL(LayerManagerOGL* aManager) , LayerOGL(aManager) { mImplData = static_cast(this); -} +} ShadowImageLayerOGL::~ShadowImageLayerOGL() {} PRBool -ShadowImageLayerOGL::Init(const SharedImage& aFront, - const nsIntSize& aSize) +ShadowImageLayerOGL::Init(const SharedImage& aFront) { if (aFront.type() == SharedImage::TSurfaceDescriptor) { SurfaceDescriptor desc = aFront.get_SurfaceDescriptor(); - nsRefPtr surf = + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(desc); - gfxSize sz = surf->GetSize(); - mTexImage = gl()->CreateTextureImage(nsIntSize(sz.width, sz.height), + mSize = surf->GetSize(); + mTexImage = gl()->CreateTextureImage(nsIntSize(mSize.width, mSize.height), surf->GetContentType(), LOCAL_GL_CLAMP_TO_EDGE); - mOGLManager->DestroySharedSurface(&desc, mAllocator); return PR_TRUE; } else { YUVImage yuv = aFront.get_YUVImage(); - + nsRefPtr surfY = gfxSharedImageSurface::Open(yuv.Ydata()); nsRefPtr surfU = gfxSharedImageSurface::Open(yuv.Udata()); nsRefPtr surfV = gfxSharedImageSurface::Open(yuv.Vdata()); - - mSize = gfxIntSize(surfY->GetSize().width, surfY->GetSize().height); - gfxIntSize CbCrSize = gfxIntSize(surfU->GetSize().width, surfU->GetSize().height); + + mSize = surfY->GetSize(); + mCbCrSize = surfU->GetSize(); if (!mYUVTexture[0].IsAllocated()) { mYUVTexture[0].Allocate(mOGLManager->glForResources()); @@ -867,40 +865,45 @@ ShadowImageLayerOGL::Init(const SharedImage& aFront, gl()->MakeCurrent(); InitTexture(gl(), mYUVTexture[0].GetTextureID(), LOCAL_GL_LUMINANCE, mSize); - InitTexture(gl(), mYUVTexture[1].GetTextureID(), LOCAL_GL_LUMINANCE, CbCrSize); - InitTexture(gl(), mYUVTexture[2].GetTextureID(), LOCAL_GL_LUMINANCE, CbCrSize); - - mOGLManager->DestroySharedSurface(surfY, mAllocator); - mOGLManager->DestroySharedSurface(surfU, mAllocator); - mOGLManager->DestroySharedSurface(surfV, mAllocator); + InitTexture(gl(), mYUVTexture[1].GetTextureID(), LOCAL_GL_LUMINANCE, mCbCrSize); + InitTexture(gl(), mYUVTexture[2].GetTextureID(), LOCAL_GL_LUMINANCE, mCbCrSize); return PR_TRUE; } + return PR_FALSE; } void -ShadowImageLayerOGL::Swap(const SharedImage& aNewFront, SharedImage* aNewBack) +ShadowImageLayerOGL::Swap(const SharedImage& aNewFront, + SharedImage* aNewBack) { if (!mDestroyed) { if (aNewFront.type() == SharedImage::TSurfaceDescriptor) { - nsRefPtr surf = + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aNewFront.get_SurfaceDescriptor()); + gfxIntSize size = surf->GetSize(); + if (mSize != size || !mTexImage) { + Init(aNewFront); + } // XXX this is always just ridiculously slow - gfxSize sz = surf->GetSize(); - nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height)); + nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height)); mTexImage->DirectUpdate(surf, updateRegion); } else { const YUVImage& yuv = aNewFront.get_YUVImage(); - + nsRefPtr surfY = gfxSharedImageSurface::Open(yuv.Ydata()); nsRefPtr surfU = gfxSharedImageSurface::Open(yuv.Udata()); nsRefPtr surfV = gfxSharedImageSurface::Open(yuv.Vdata()); - mPictureRect = yuv.picture(); - mSize = surfY->GetSize(); - + + gfxIntSize size = surfY->GetSize(); + gfxIntSize CbCrSize = surfU->GetSize(); + if (size != mSize || mCbCrSize != CbCrSize || !mYUVTexture[0].IsAllocated()) { + Init(aNewFront); + } + PlanarYCbCrImage::Data data; data.mYChannel = surfY->Data(); data.mYStride = surfY->Stride(); @@ -917,12 +920,6 @@ ShadowImageLayerOGL::Swap(const SharedImage& aNewFront, SharedImage* aNewBack) *aNewBack = aNewFront; } -void -ShadowImageLayerOGL::DestroyFrontBuffer() -{ - mTexImage = nsnull; -} - void ShadowImageLayerOGL::Disconnect() { diff --git a/gfx/layers/opengl/ImageLayerOGL.h b/gfx/layers/opengl/ImageLayerOGL.h index e3d1102aee6e..617796029b40 100644 --- a/gfx/layers/opengl/ImageLayerOGL.h +++ b/gfx/layers/opengl/ImageLayerOGL.h @@ -253,11 +253,8 @@ public: virtual ~ShadowImageLayerOGL(); // ShadowImageLayer impl - virtual PRBool Init(const SharedImage& aFront, const nsIntSize& aSize); - - virtual void Swap(const SharedImage& aFront, SharedImage* aNewBack); - - virtual void DestroyFrontBuffer(); + virtual void Swap(const SharedImage& aFront, + SharedImage* aNewBack); virtual void Disconnect(); @@ -270,9 +267,12 @@ public: const nsIntPoint& aOffset); private: + PRBool Init(const SharedImage& aFront); + nsRefPtr mTexImage; GLTexture mYUVTexture[3]; gfxIntSize mSize; + gfxIntSize mCbCrSize; nsIntRect mPictureRect; }; From 131092869e1e861fde0548f384c2815870cc608c Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Tue, 27 Sep 2011 15:19:28 -0700 Subject: [PATCH 23/65] Bug 689045 - Canvas Shadow swap/Init API rework r=cjones --HG-- extra : rebase_source : 7b2acb0ffededb54815d7222d79999d32506bee5 --- gfx/layers/basic/BasicLayers.cpp | 89 ++++++++++++++++----------- gfx/layers/d3d9/CanvasLayerD3D9.cpp | 19 +++--- gfx/layers/d3d9/CanvasLayerD3D9.h | 9 +-- gfx/layers/ipc/PLayers.ipdl | 21 +++---- gfx/layers/ipc/ShadowLayers.cpp | 22 +------ gfx/layers/ipc/ShadowLayers.h | 33 ++-------- gfx/layers/ipc/ShadowLayersParent.cpp | 34 +--------- gfx/layers/opengl/CanvasLayerOGL.cpp | 22 +++---- gfx/layers/opengl/CanvasLayerOGL.h | 8 +-- 9 files changed, 100 insertions(+), 157 deletions(-) diff --git a/gfx/layers/basic/BasicLayers.cpp b/gfx/layers/basic/BasicLayers.cpp index 40f2f57e568f..df041191d179 100644 --- a/gfx/layers/basic/BasicLayers.cpp +++ b/gfx/layers/basic/BasicLayers.cpp @@ -2545,9 +2545,7 @@ public: } virtual ~BasicShadowableCanvasLayer() { - if (IsSurfaceDescriptorValid(mBackBuffer)) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); - } + DestroyBackBuffer(); MOZ_COUNT_DTOR(BasicShadowableCanvasLayer); } @@ -2573,6 +2571,14 @@ public: BasicShadowableLayer::Disconnect(); } + void DestroyBackBuffer() + { + if (IsSurfaceDescriptorValid(mBackBuffer)) { + BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); + mBackBuffer = SurfaceDescriptor(); + } + } + private: BasicShadowLayerManager* BasicManager() { @@ -2593,24 +2599,12 @@ BasicShadowableCanvasLayer::Initialize(const Data& aData) // canvas resizes if (IsSurfaceDescriptorValid(mBackBuffer)) { - BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer); - - BasicManager()->DestroyedCanvasBuffer(BasicManager()->Hold(this)); + nsRefPtr backSurface = + BasicManager()->OpenDescriptor(mBackBuffer); + if (gfxIntSize(mBounds.width, mBounds.height) != backSurface->GetSize()) { + DestroyBackBuffer(); + } } - - SurfaceDescriptor tmpFrontBuffer; - // XXX error handling? - if (!BasicManager()->AllocDoubleBuffer( - gfxIntSize(aData.mSize.width, aData.mSize.height), - (GetContentFlags() & CONTENT_OPAQUE) ? - gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA, - &tmpFrontBuffer, &mBackBuffer)) - NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!"); - - BasicManager()->CreatedCanvasBuffer(BasicManager()->Hold(this), - aData.mSize, - tmpFrontBuffer, - mNeedsYFlip ? true : false); } void @@ -2621,6 +2615,15 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext) return; } + if (!IsSurfaceDescriptorValid(mBackBuffer)) { + if (!BasicManager()->AllocBuffer( + gfxIntSize(mBounds.width, mBounds.height), + (GetContentFlags() & CONTENT_OPAQUE) ? + gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA, + &mBackBuffer)) + NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!"); + } + nsRefPtr backSurface = BasicManager()->OpenDescriptor(mBackBuffer); @@ -2628,6 +2631,7 @@ BasicShadowableCanvasLayer::Paint(gfxContext* aContext) FireDidTransactionCallback(); BasicManager()->PaintedCanvas(BasicManager()->Hold(this), + mNeedsYFlip ? true : false, mBackBuffer); } @@ -2976,19 +2980,18 @@ public: } virtual ~BasicShadowCanvasLayer() { + DestroyFrontBuffer(); MOZ_COUNT_DTOR(BasicShadowCanvasLayer); } virtual void Disconnect() { - DestroyFrontBuffer(); + mFrontSurface = SurfaceDescriptor(); ShadowCanvasLayer::Disconnect(); } virtual void Initialize(const Data& aData); - virtual void Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize, bool needYFlip); - - void Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack); + void Swap(const CanvasSurface& aNewFront, bool needYFlip, CanvasSurface* aNewBack); virtual void DestroyFrontBuffer() { @@ -3017,18 +3020,26 @@ BasicShadowCanvasLayer::Initialize(const Data& aData) } void -BasicShadowCanvasLayer::Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize, bool needYFlip) +BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip, + CanvasSurface* aNewBack) { - mNeedsYFlip = needYFlip; - mFrontSurface = aNewFront; - mBounds.SetRect(0, 0, aSize.width, aSize.height); -} + nsRefPtr surface = + BasicManager()->OpenDescriptor(aNewFront); + // Destroy mFrontBuffer if size different + gfxIntSize sz = surface->GetSize(); + if (sz != gfxIntSize(mBounds.width, mBounds.height)) { + DestroyFrontBuffer(); + mBounds.SetRect(0, 0, sz.width, sz.height); + } -void -BasicShadowCanvasLayer::Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack) -{ - *aNewBack = mFrontSurface; - mFrontSurface = aNewFront; + mNeedsYFlip = needYFlip; + // If mFrontBuffer + if (IsSurfaceDescriptorValid(mFrontSurface)) { + *aNewBack = mFrontSurface; + } else { + *aNewBack = null_t(); + } + mFrontSurface = aNewFront.get_SurfaceDescriptor(); } void @@ -3286,8 +3297,14 @@ BasicShadowLayerManager::ForwardTransaction() MOZ_LAYERS_LOG(("[LayersForwarder] BufferSwap")); const OpBufferSwap& obs = reply.get_OpBufferSwap(); - const SurfaceDescriptor& descr = obs.newBackBuffer(); - GetBasicShadowable(obs)->SetBackBuffer(descr); + const CanvasSurface& newBack = obs.newBackBuffer(); + if (newBack.type() == CanvasSurface::TSurfaceDescriptor) { + GetBasicShadowable(obs)->SetBackBuffer(newBack.get_SurfaceDescriptor()); + } else if (newBack.type() == CanvasSurface::Tnull_t) { + GetBasicShadowable(obs)->SetBackBuffer(SurfaceDescriptor()); + } else { + NS_RUNTIMEABORT("Unknown back image type"); + } break; } diff --git a/gfx/layers/d3d9/CanvasLayerD3D9.cpp b/gfx/layers/d3d9/CanvasLayerD3D9.cpp index 55386c54f314..78dab111c050 100644 --- a/gfx/layers/d3d9/CanvasLayerD3D9.cpp +++ b/gfx/layers/d3d9/CanvasLayerD3D9.cpp @@ -307,10 +307,8 @@ ShadowCanvasLayerD3D9::Initialize(const Data& aData) } void -ShadowCanvasLayerD3D9::Init(const SurfaceDescriptor& aNewFront, - const nsIntSize& aSize, bool needYFlip) +ShadowCanvasLayerD3D9::Init(bool needYFlip) { - if (!mBuffer) { mBuffer = new ShadowBufferD3D9(this); } @@ -319,18 +317,19 @@ ShadowCanvasLayerD3D9::Init(const SurfaceDescriptor& aNewFront, } void -ShadowCanvasLayerD3D9::Swap(const SurfaceDescriptor& aNewFront, - SurfaceDescriptor* aNewBack) +ShadowCanvasLayerD3D9::Swap(const CanvasSurface& aNewFront, + bool needYFlip, + CanvasSurface* aNewBack) { - NS_ASSERTION(aNewFront.type() == SharedImage::TSurfaceDescriptor, - "ShadowCanvasLayerD3D9::Swap expected SharedImage surface"); + NS_ASSERTION(aNewFront.type() == CanvasSurface::TSurfaceDescriptor, + "ShadowCanvasLayerD3D9::Swap expected CanvasSurface surface"); nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aNewFront); - - if (mBuffer) { - mBuffer->Upload(surf, GetVisibleRegion().GetBounds()); + if (!mBuffer) { + Init(needYFlip); } + mBuffer->Upload(surf, GetVisibleRegion().GetBounds()); *aNewBack = aNewFront; } diff --git a/gfx/layers/d3d9/CanvasLayerD3D9.h b/gfx/layers/d3d9/CanvasLayerD3D9.h index 7637ced48801..29823088abd7 100644 --- a/gfx/layers/d3d9/CanvasLayerD3D9.h +++ b/gfx/layers/d3d9/CanvasLayerD3D9.h @@ -105,14 +105,13 @@ public: // CanvasLayer impl virtual void Initialize(const Data& aData); - virtual void Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize, bool needYFlip); - // This isn't meaningful for shadow canvas. virtual void Updated(const nsIntRect&) {} // ShadowCanvasLayer impl - virtual void Swap(const SurfaceDescriptor& aNewFront, - SurfaceDescriptor* aNewBack); + virtual void Swap(const CanvasSurface& aNewFront, + bool needYFlip, + CanvasSurface* aNewBack); virtual void DestroyFrontBuffer(); virtual void Disconnect(); @@ -125,6 +124,8 @@ public: virtual void LayerManagerDestroyed(); private: + virtual void Init(bool needYFlip); + PRPackedBool mNeedsYFlip; nsRefPtr mBuffer; }; diff --git a/gfx/layers/ipc/PLayers.ipdl b/gfx/layers/ipc/PLayers.ipdl index 825f02badba6..3e59964f5b4c 100644 --- a/gfx/layers/ipc/PLayers.ipdl +++ b/gfx/layers/ipc/PLayers.ipdl @@ -104,6 +104,11 @@ struct ThebesBuffer { }; union OptionalThebesBuffer { ThebesBuffer; null_t; }; +union CanvasSurface { + SurfaceDescriptor; + null_t; +}; + // For the "buffer creation" operations, we send an initial front // buffer that only contains (transparent) black pixels just so that // we can swap it back after the first OpPaint without a special case. @@ -115,15 +120,6 @@ struct OpCreateThebesBuffer { }; struct OpDestroyThebesFrontBuffer { PLayer layer; }; -struct OpCreateCanvasBuffer { - PLayer layer; - nsIntSize size; - SurfaceDescriptor initialFront; - bool needYFlip; -}; -struct OpDestroyCanvasFrontBuffer { PLayer layer; }; - - // Change a layer's attributes struct CommonLayerAttributes { nsIntRegion visibleRegion; @@ -181,7 +177,8 @@ struct OpPaintThebesBuffer { struct OpPaintCanvas { PLayer layer; - SurfaceDescriptor newFrontBuffer; + CanvasSurface newFrontBuffer; + bool needYFlip; }; struct OpPaintImage { @@ -197,10 +194,8 @@ union Edit { OpCreateImageLayer; OpCreateColorLayer; OpCreateCanvasLayer; - OpCreateCanvasBuffer; OpCreateThebesBuffer; OpDestroyThebesFrontBuffer; - OpDestroyCanvasFrontBuffer; OpSetLayerAttributes; @@ -216,7 +211,7 @@ union Edit { // Replies to operations -struct OpBufferSwap { PLayer layer; SurfaceDescriptor newBackBuffer; }; +struct OpBufferSwap { PLayer layer; CanvasSurface newBackBuffer; }; struct OpImageSwap { PLayer layer; SharedImage newBackImage; }; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 415c9b68e6df..4dfaf01c74de 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -201,18 +201,6 @@ ShadowLayerForwarder::CreatedThebesBuffer(ShadowableLayer* aThebes, aFrontValidRegion)); } -void -ShadowLayerForwarder::CreatedCanvasBuffer(ShadowableLayer* aCanvas, - nsIntSize aSize, - const SurfaceDescriptor& aTempFrontSurface, - bool aNeedYFlip) -{ - mTxn->AddEdit(OpCreateCanvasBuffer(NULL, Shadow(aCanvas), - aSize, - aTempFrontSurface, - aNeedYFlip)); -} - void ShadowLayerForwarder::DestroyedThebesBuffer(ShadowableLayer* aThebes, const SurfaceDescriptor& aBackBufferToDestroy) @@ -221,12 +209,6 @@ ShadowLayerForwarder::DestroyedThebesBuffer(ShadowableLayer* aThebes, mTxn->AddBufferToDestroy(aBackBufferToDestroy); } -void -ShadowLayerForwarder::DestroyedCanvasBuffer(ShadowableLayer* aCanvas) -{ - mTxn->AddEdit(OpDestroyCanvasFrontBuffer(NULL, Shadow(aCanvas))); -} - void ShadowLayerForwarder::Mutated(ShadowableLayer* aMutant) { @@ -281,10 +263,12 @@ ShadowLayerForwarder::PaintedImage(ShadowableLayer* aImage, } void ShadowLayerForwarder::PaintedCanvas(ShadowableLayer* aCanvas, + bool aNeedYFlip, const SurfaceDescriptor& aNewFrontSurface) { mTxn->AddPaint(OpPaintCanvas(NULL, Shadow(aCanvas), - aNewFrontSurface)); + aNewFrontSurface, + aNeedYFlip)); } PRBool diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 42a21a320156..6f5df8f67350 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -67,6 +67,7 @@ class SurfaceDescriptor; class ThebesBuffer; class Transaction; class SharedImage; +class CanvasSurface; /** * We want to share layer trees across thread contexts and address @@ -159,14 +160,6 @@ public: const nsIntRegion& aFrontValidRegion, const nsIntRect& aBufferRect, const SurfaceDescriptor& aInitialFrontBuffer); - /** - * For the next method, |aSize| is the size of - * |aInitialFrontSurface|. - */ - void CreatedCanvasBuffer(ShadowableLayer* aCanvas, - nsIntSize aSize, - const SurfaceDescriptor& aInitialFrontSurface, - bool aNeedYFlip); /** * The specified layer is destroying its buffers. @@ -178,8 +171,6 @@ public: */ void DestroyedThebesBuffer(ShadowableLayer* aThebes, const SurfaceDescriptor& aBackBufferToDestroy); - void DestroyedCanvasBuffer(ShadowableLayer* aCanvas); - /** * At least one attribute of |aMutant| has changed, and |aMutant| @@ -224,6 +215,7 @@ public: void PaintedImage(ShadowableLayer* aImage, const SharedImage& aNewFrontImage); void PaintedCanvas(ShadowableLayer* aCanvas, + bool aNeedYFlip, const SurfaceDescriptor& aNewFrontSurface); /** @@ -586,17 +578,6 @@ class ShadowCanvasLayer : public ShadowLayer, public CanvasLayer { public: - - /** - * CONSTRUCTION PHASE ONLY - * - * Initialize this with a (temporary) front surface with the given - * size. This is expected to be followed with a Swap() in the same - * transaction to bring in real pixels. Init() may only be called - * once. - */ - virtual void Init(const SurfaceDescriptor& front, const nsIntSize& aSize, bool needYFlip) = 0; - /** * CONSTRUCTION PHASE ONLY * @@ -604,14 +585,8 @@ public: * out the old front surface (the new back surface for the remote * layer). */ - virtual void Swap(const SurfaceDescriptor& aNewFront, SurfaceDescriptor* aNewBack) = 0; - - /** - * CONSTRUCTION PHASE ONLY - * - * Destroy the current front buffer. - */ - virtual void DestroyFrontBuffer() = 0; + virtual void Swap(const CanvasSurface& aNewFront, bool needYFlip, + CanvasSurface* aNewBack) = 0; virtual ShadowLayer* AsShadowLayer() { return this; } diff --git a/gfx/layers/ipc/ShadowLayersParent.cpp b/gfx/layers/ipc/ShadowLayersParent.cpp index a969614e81d4..625183b40122 100644 --- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -214,17 +214,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, break; } - case Edit::TOpCreateCanvasBuffer: { - MOZ_LAYERS_LOG(("[ParentSide] CreateCanvasBuffer")); - - const OpCreateCanvasBuffer& ocb = edit.get_OpCreateCanvasBuffer(); - ShadowCanvasLayer* canvas = static_cast( - AsShadowLayer(ocb)->AsLayer()); - - canvas->Init(ocb.initialFront(), ocb.size(), ocb.needYFlip()); - - break; - } case Edit::TOpDestroyThebesFrontBuffer: { MOZ_LAYERS_LOG(("[ParentSide] DestroyThebesFrontBuffer")); @@ -237,18 +226,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, break; } - case Edit::TOpDestroyCanvasFrontBuffer: { - MOZ_LAYERS_LOG(("[ParentSide] DestroyCanvasFrontBuffer")); - - const OpDestroyCanvasFrontBuffer& odfb = - edit.get_OpDestroyCanvasFrontBuffer(); - ShadowCanvasLayer* canvas = static_cast( - AsShadowLayer(odfb)->AsLayer()); - - canvas->DestroyFrontBuffer(); - - break; - } // Attributes case Edit::TOpSetLayerAttributes: { MOZ_LAYERS_LOG(("[ParentSide] SetLayerAttributes")); @@ -384,15 +361,10 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, ShadowCanvasLayer* canvas = static_cast(shadow->AsLayer()); - SurfaceDescriptor newFront = op.newFrontBuffer(); - SurfaceDescriptor newBack; - canvas->Swap(op.newFrontBuffer(), &newBack); - if (newFront == newBack) { - newFront = SurfaceDescriptor(); - } - + canvas->SetAllocator(this); + CanvasSurface newBack; + canvas->Swap(op.newFrontBuffer(), op.needYFlip(), &newBack); canvas->Updated(); - replyv.push_back(OpBufferSwap(shadow, NULL, newBack)); diff --git a/gfx/layers/opengl/CanvasLayerOGL.cpp b/gfx/layers/opengl/CanvasLayerOGL.cpp index 9df91231ad32..bb8280188f1d 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.cpp +++ b/gfx/layers/opengl/CanvasLayerOGL.cpp @@ -302,24 +302,27 @@ ShadowCanvasLayerOGL::Initialize(const Data& aData) } void -ShadowCanvasLayerOGL::Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize, bool needYFlip) +ShadowCanvasLayerOGL::Init(const CanvasSurface& aNewFront, bool needYFlip) { - mDeadweight = aNewFront; - nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(mDeadweight); + nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aNewFront); - mTexImage = gl()->CreateTextureImage(nsIntSize(aSize.width, aSize.height), + mTexImage = gl()->CreateTextureImage(surf->GetSize(), surf->GetContentType(), LOCAL_GL_CLAMP_TO_EDGE); mNeedsYFlip = needYFlip; } void -ShadowCanvasLayerOGL::Swap(const SurfaceDescriptor& aNewFront, - SurfaceDescriptor* aNewBack) +ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront, + bool needYFlip, + CanvasSurface* aNewBack) { - if (!mDestroyed && mTexImage) { + if (!mDestroyed) { nsRefPtr surf = ShadowLayerForwarder::OpenDescriptor(aNewFront); - gfxSize sz = surf->GetSize(); + gfxIntSize sz = surf->GetSize(); + if (!mTexImage || mTexImage->GetSize() != sz) { + Init(aNewFront, needYFlip); + } nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height)); mTexImage->DirectUpdate(surf, updateRegion); } @@ -331,9 +334,6 @@ void ShadowCanvasLayerOGL::DestroyFrontBuffer() { mTexImage = nsnull; - if (IsSurfaceDescriptorValid(mDeadweight)) { - mAllocator->DestroySharedSurface(&mDeadweight); - } } void diff --git a/gfx/layers/opengl/CanvasLayerOGL.h b/gfx/layers/opengl/CanvasLayerOGL.h index 7ec2a8ddce4c..e05ab876ac09 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.h +++ b/gfx/layers/opengl/CanvasLayerOGL.h @@ -108,14 +108,15 @@ public: // CanvasLayer impl virtual void Initialize(const Data& aData); - virtual void Init(const SurfaceDescriptor& aNewFront, const nsIntSize& aSize, bool needYFlip); + virtual void Init(const CanvasSurface& aNewFront, bool needYFlip); // This isn't meaningful for shadow canvas. virtual void Updated(const nsIntRect&) {} // ShadowCanvasLayer impl - virtual void Swap(const SurfaceDescriptor& aNewFront, - SurfaceDescriptor* aNewBack); + virtual void Swap(const CanvasSurface& aNewFront, + bool needYFlip, + CanvasSurface* aNewBack); virtual void DestroyFrontBuffer(); @@ -130,7 +131,6 @@ public: private: nsRefPtr mTexImage; - SurfaceDescriptor mDeadweight; PRPackedBool mNeedsYFlip; }; From 1dd0e000557558a2a0d1cd690ca0818ee6e5906f Mon Sep 17 00:00:00 2001 From: Allison Naaktgeboren Date: Wed, 28 Sep 2011 12:27:57 -0700 Subject: [PATCH 24/65] Bug 689832 - SyncSetup.js refers to outdated string change.password.pwSameAsSyncKey r=philikon --- browser/base/content/syncSetup.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/base/content/syncSetup.js b/browser/base/content/syncSetup.js index 5257ee41fec6..3aa4c159ac01 100644 --- a/browser/base/content/syncSetup.js +++ b/browser/base/content/syncSetup.js @@ -339,7 +339,7 @@ var gSyncSetup = { if (password.value == document.getElementById("weavePassphrase").value) { // xxxmpc - hack, sigh valid = false; - errorString = Weave.Utils.getErrorString("change.password.pwSameAsSyncKey"); + errorString = Weave.Utils.getErrorString("change.password.pwSameAsRecoveryKey"); } else { let pwconfirm = document.getElementById("weavePasswordConfirm"); From 446a1a8009b33b02f014b61ad3fcf1726fe33b7d Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Wed, 28 Sep 2011 13:31:27 -0700 Subject: [PATCH 25/65] Bug 690017 - Use -moz-crisp-edges scaling for favicons in tablet portrait tab menu [r=wesj] --- mobile/themes/core/tablet.css | 1 + 1 file changed, 1 insertion(+) diff --git a/mobile/themes/core/tablet.css b/mobile/themes/core/tablet.css index 0956263e4e4e..3d4b4f7c1499 100644 --- a/mobile/themes/core/tablet.css +++ b/mobile/themes/core/tablet.css @@ -185,6 +185,7 @@ arrowbox { .documenttab-popup-favicon { width: 32px; height: 32px; + image-rendering: -moz-crisp-edges; } .tab-popup-item.selected .documenttab-popup-checkmark { From 4af04ea2e4941163f05630507767b46ec4123358 Mon Sep 17 00:00:00 2001 From: James Willcox Date: Wed, 28 Sep 2011 14:43:02 -0400 Subject: [PATCH 26/65] Bug 689948 - Fix regressions caused by bug 686992 [r=blassey] From 3d547ae760f1106b7e5414e05b4f80c2e7533926 Mon Sep 17 00:00:00 2001 Accidentally removed a call to GeckoAppShell.scheduleRedraw() which caused a deadlock. Also, this fixes an issue with uninitialized member variables in AndroidBridge. --- embedding/android/GeckoSurfaceView.java | 2 ++ widget/src/android/AndroidBridge.cpp | 15 +++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/embedding/android/GeckoSurfaceView.java b/embedding/android/GeckoSurfaceView.java index d6abeb7aad21..e4354dc530b4 100644 --- a/embedding/android/GeckoSurfaceView.java +++ b/embedding/android/GeckoSurfaceView.java @@ -288,6 +288,8 @@ class GeckoSurfaceView } if (doSyncDraw) { + GeckoAppShell.scheduleRedraw(); + Object syncDrawObject = null; try { syncDrawObject = mSyncDraws.take(); diff --git a/widget/src/android/AndroidBridge.cpp b/widget/src/android/AndroidBridge.cpp index 530aae9b9517..c1f8f0873acc 100644 --- a/widget/src/android/AndroidBridge.cpp +++ b/widget/src/android/AndroidBridge.cpp @@ -988,6 +988,8 @@ AndroidBridge::OpenGraphicsLibraries() // Try to dlopen libjnigraphics.so for direct bitmap access on // Android 2.2+ (API level 8) mOpenedGraphicsLibraries = true; + mHasNativeWindowAccess = false; + mHasNativeBitmapAccess = false; void *handle = dlopen("/system/lib/libjnigraphics.so", RTLD_LAZY | RTLD_LOCAL); if (handle) { @@ -995,7 +997,9 @@ AndroidBridge::OpenGraphicsLibraries() AndroidBitmap_lockPixels = (int (*)(JNIEnv *, jobject, void **))dlsym(handle, "AndroidBitmap_lockPixels"); AndroidBitmap_unlockPixels = (int (*)(JNIEnv *, jobject))dlsym(handle, "AndroidBitmap_unlockPixels"); - ALOG_BRIDGE("Successfully opened libjnigraphics.so"); + mHasNativeBitmapAccess = AndroidBitmap_getInfo && AndroidBitmap_lockPixels && AndroidBitmap_unlockPixels; + + ALOG_BRIDGE("Successfully opened libjnigraphics.so, have native bitmap access? %d", mHasNativeBitmapAccess); } // Try to dlopen libandroid.so for and native window access on @@ -1007,12 +1011,11 @@ AndroidBridge::OpenGraphicsLibraries() ANativeWindow_setBuffersGeometry = (int (*)(void*, int, int, int)) dlsym(handle, "ANativeWindow_setBuffersGeometry"); ANativeWindow_lock = (int (*)(void*, void*, void*)) dlsym(handle, "ANativeWindow_lock"); ANativeWindow_unlockAndPost = (int (*)(void*))dlsym(handle, "ANativeWindow_unlockAndPost"); - - ALOG_BRIDGE("Successfully opened libandroid.so"); - } - mHasNativeBitmapAccess = AndroidBitmap_getInfo && AndroidBitmap_lockPixels && AndroidBitmap_unlockPixels; - mHasNativeWindowAccess = ANativeWindow_fromSurface && ANativeWindow_release && ANativeWindow_lock && ANativeWindow_unlockAndPost; + mHasNativeWindowAccess = ANativeWindow_fromSurface && ANativeWindow_release && ANativeWindow_lock && ANativeWindow_unlockAndPost; + + ALOG_BRIDGE("Successfully opened libandroid.so, have native window access? %d", mHasNativeWindowAccess); + } } } From b0786f922ac939f5ad4cab6c653cb83f859834a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Wed, 28 Sep 2011 16:46:06 -0400 Subject: [PATCH 27/65] Bug 689609 - Don't enable c++11 on systems that don't really support it. r=ehsan,glandium. --HG-- extra : rebase_source : 2735225fb50875a91c46230c1602920d6ae69f9a --- configure.in | 28 +++++++++++++++----------- dom/plugins/base/android/ANPCanvas.cpp | 4 ++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/configure.in b/configure.in index 49046aa572e9..ba5b608975da 100644 --- a/configure.in +++ b/configure.in @@ -2824,24 +2824,28 @@ fi AC_SUBST(_MOZ_RTTI_FLAGS_ON) -dnl Check whether we can use gcc's c++0x mode +dnl Check whether we can use gcc's c++0x mode. We check for some basic +dnl features that we need. AC_LANG_CPLUSPLUS if test "$GNU_CXX"; then _SAVE_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS -std=gnu++0x" - if test -z "$_MOZ_USE_RTTI"; then - CXXFLAGS="$CXXFLAGS $_MOZ_RTTI_FLAGS" - AC_CACHE_CHECK(for gcc c++0x headers bug without rtti, - ac_cv_cxx0x_headers_bug, - [AC_TRY_COMPILE([#include ], [], - ac_cv_cxx0x_headers_bug="no", - ac_cv_cxx0x_headers_bug="yes")]) - CXXFLAGS="$_SAVE_CXXFLAGS" - if test "$ac_cv_cxx0x_headers_bug" = "no"; then - CXXFLAGS="$CXXFLAGS -std=gnu++0x" - fi + CXXFLAGS="$CXXFLAGS $_MOZ_RTTI_FLAGS" + AC_CACHE_CHECK(for c++0x support, + ac_cv_cxx0x_support, + [AC_TRY_COMPILE([#include + #include + void f(int&&);], [ + int a; + f(std::move(a)); + ], + ac_cv_cxx0x_support="yes", + ac_cv_cxx0x_support="no")]) + CXXFLAGS="$_SAVE_CXXFLAGS" + if test "$ac_cv_cxx0x_support" = "yes"; then + CXXFLAGS="$CXXFLAGS -std=gnu++0x" fi fi diff --git a/dom/plugins/base/android/ANPCanvas.cpp b/dom/plugins/base/android/ANPCanvas.cpp index 30c953e46355..918d4fd60dbd 100644 --- a/dom/plugins/base/android/ANPCanvas.cpp +++ b/dom/plugins/base/android/ANPCanvas.cpp @@ -57,11 +57,11 @@ anp_canvas_newCanvas(const ANPBitmap* bitmap) PRUint32 stride; gfxASurface::gfxImageFormat format; - if (bitmap->format == ANPBitmapFormats::kRGBA_8888_ANPBitmapFormat) { + if (bitmap->format == kRGBA_8888_ANPBitmapFormat) { stride = bitmap->width * 4; format = gfxImageSurface::ImageFormatARGB32; } - else if (bitmap->format == ANPBitmapFormats::kRGB_565_ANPBitmapFormat) { + else if (bitmap->format == kRGB_565_ANPBitmapFormat) { stride = bitmap->width * 2; format = gfxImageSurface::ImageFormatRGB16_565; } From aad78d3d83fd2e8cf92cd0ea951247870a5d17f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Wed, 28 Sep 2011 17:13:23 -0400 Subject: [PATCH 28/65] Switch android back to c++11. There are more dependencies on it now. r=revert. CLOSED TREE --- configure.in | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/configure.in b/configure.in index ba5b608975da..49046aa572e9 100644 --- a/configure.in +++ b/configure.in @@ -2824,28 +2824,24 @@ fi AC_SUBST(_MOZ_RTTI_FLAGS_ON) -dnl Check whether we can use gcc's c++0x mode. We check for some basic -dnl features that we need. +dnl Check whether we can use gcc's c++0x mode AC_LANG_CPLUSPLUS if test "$GNU_CXX"; then _SAVE_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS -std=gnu++0x" - CXXFLAGS="$CXXFLAGS $_MOZ_RTTI_FLAGS" - AC_CACHE_CHECK(for c++0x support, - ac_cv_cxx0x_support, - [AC_TRY_COMPILE([#include - #include - void f(int&&);], [ - int a; - f(std::move(a)); - ], - ac_cv_cxx0x_support="yes", - ac_cv_cxx0x_support="no")]) - CXXFLAGS="$_SAVE_CXXFLAGS" - if test "$ac_cv_cxx0x_support" = "yes"; then - CXXFLAGS="$CXXFLAGS -std=gnu++0x" + if test -z "$_MOZ_USE_RTTI"; then + CXXFLAGS="$CXXFLAGS $_MOZ_RTTI_FLAGS" + AC_CACHE_CHECK(for gcc c++0x headers bug without rtti, + ac_cv_cxx0x_headers_bug, + [AC_TRY_COMPILE([#include ], [], + ac_cv_cxx0x_headers_bug="no", + ac_cv_cxx0x_headers_bug="yes")]) + CXXFLAGS="$_SAVE_CXXFLAGS" + if test "$ac_cv_cxx0x_headers_bug" = "no"; then + CXXFLAGS="$CXXFLAGS -std=gnu++0x" + fi fi fi From aac1c5db8b6ca342d335ba019946ff65aa567600 Mon Sep 17 00:00:00 2001 From: Mounir Lamouri Date: Wed, 28 Sep 2011 23:23:36 +0200 Subject: [PATCH 29/65] Bug 675574 - Do not allow more than one call to window.open() when we allow popups. r=jst --- docshell/test/navigation/test_bug13871.html | 4 + docshell/test/navigation/test_bug270414.html | 4 + docshell/test/navigation/test_not-opener.html | 4 + .../test_popup-navigates-children.html | 4 + .../navigation/test_sibling-off-domain.html | 4 + docshell/test/test_bug598895.html | 4 + docshell/test/test_bug637644.html | 4 + dom/base/nsGlobalWindow.cpp | 40 +++ dom/base/nsGlobalWindow.h | 2 + dom/base/nsPIDOMWindow.h | 29 +- dom/tests/browser/Makefile.in | 1 + .../browser_popup_blocker_multiple_popups.js | 300 ++++++++++++++++++ dom/tests/mochitest/bugs/test_bug346659.html | 4 + dom/tests/mochitest/bugs/test_bug406375.html | 5 + dom/tests/mochitest/bugs/test_bug61098.html | 5 + .../chrome/test_popup_blocker_chrome.xul | 93 +++++- modules/libpref/src/init/all.js | 2 + .../mixedcontent/mixedContentTest.js | 9 +- 18 files changed, 500 insertions(+), 18 deletions(-) create mode 100644 dom/tests/browser/browser_popup_blocker_multiple_popups.js diff --git a/docshell/test/navigation/test_bug13871.html b/docshell/test/navigation/test_bug13871.html index 9ff0b9bb553f..6e8534e29855 100644 --- a/docshell/test/navigation/test_bug13871.html +++ b/docshell/test/navigation/test_bug13871.html @@ -27,10 +27,14 @@ window.onload = function () { window3.close(); xpcCleanupWindows(); + SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups); SimpleTest.finish(); }, 4); } +var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups"); +SpecialPowers.setBoolPref("dom.block_multiple_popups", false); + var window0 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window0", "width=10,height=10"); var window1 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window1", "width=10,height=10"); var window2 = window.open("http://test1.example.org:80/tests/docshell/test/navigation/parent.html", "window2", "width=10,height=10"); diff --git a/docshell/test/navigation/test_bug270414.html b/docshell/test/navigation/test_bug270414.html index 98dcf42f8df1..811280956226 100644 --- a/docshell/test/navigation/test_bug270414.html +++ b/docshell/test/navigation/test_bug270414.html @@ -9,6 +9,9 @@ iframe { width: 90%; height: 50px; } "); +} + +/** + * window.open followed by w.open with w being the first popup. + */ +function test2() +{ + prefs.setBoolPref("dom.block_multiple_popups", true); + + let gPopupsCount = 0; + + gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () { + gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true); + + ww.registerNotification(function(aSubject, aTopic, aData) { + if (aTopic != "domwindowopened") { + return; + } + + gPopupsCount++; + + if (gPopupsCount > 1) { + return; + } + + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + ww.unregisterNotification(arguments.callee); + + is(gPopupsCount, 1, "Only one popup appeared"); + cleanUp(); + nextOrFinish(); + }); + }); + }); + }); + }); + + waitForFocus(function() { + var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0]; + EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow); + }); + }, true); + + gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,"); +} + +/** + * window.open followed by w.open with w being the first popup and the second popup being actually a tab. + */ +function test3() +{ + prefs.setBoolPref("dom.block_multiple_popups", true); + + let gPopupsCount = 0; + + gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () { + gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true); + + ww.registerNotification(function(aSubject, aTopic, aData) { + if (aTopic != "domwindowopened") { + return; + } + + gPopupsCount++; + + if (gPopupsCount > 1) { + return; + } + + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + ww.unregisterNotification(arguments.callee); + + is(gPopupsCount, 1, "Only one popup appeared"); + cleanUp(); + nextOrFinish(); + }); + }); + }); + }); + }); + + waitForFocus(function() { + var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0]; + EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow); + }); + }, true); + + gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,"); +} + +/** + * window.open and .click() on the element opening the window. + */ +function test4() +{ + prefs.setBoolPref("dom.block_multiple_popups", true); + + gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () { + gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true); + + gBrowser.addEventListener("DOMPopupBlocked", function() { + gBrowser.removeEventListener("DOMPopupBlocked", arguments.callee, true); + + ok(true, "The popup has been blocked"); + + cleanUp(); + nextOrFinish(); + }, true); + + waitForFocus(function() { + var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0]; + EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow); + }); + }, true); + + gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,"); +} + +/** + * Two window.open from the chrome. + */ +function test5() +{ + prefs.setBoolPref("dom.block_multiple_popups", true); + + let gPopupsCount = 0; + + ww.registerNotification(function(aSubject, aTopic, aData) { + if (aTopic != "domwindowopened") { + return; + } + + gPopupsCount++; + + if (gPopupsCount != 2) { + return; + } + + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + ww.unregisterNotification(arguments.callee); + + is(gPopupsCount, 2, "Both window appeared"); + cleanUp(); + nextOrFinish(); + }); + }); + }); + }); + }); + + window.open("data:text/html,foo", '', 'foo'); + window.open("data:text/html,foo", '', 'foo'); +} + +/** + * Two window.open with the pref being disabled. + */ +function test6() +{ + prefs.setBoolPref("dom.block_multiple_popups", false); + + let gPopupsCount = 0; + + gBrowser.selectedTab.linkedBrowser.addEventListener("load", function () { + gBrowser.selectedTab.linkedBrowser.removeEventListener("load", arguments.callee, true); + + ww.registerNotification(function(aSubject, aTopic, aData) { + if (aTopic != "domwindowopened") { + return; + } + + gPopupsCount++; + + if (gPopupsCount != 2) { + return; + } + + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + executeSoon(function() { + ww.unregisterNotification(arguments.callee); + + is(gPopupsCount, 2, "Both window appeared"); + cleanUp(); + nextOrFinish(); + }); + }); + }); + }); + }); + + waitForFocus(function() { + var button = gBrowser.selectedTab.linkedBrowser.contentDocument.getElementsByTagName('button')[0]; + EventUtils.synthesizeMouseAtCenter(button, {}, gBrowser.selectedTab.linkedBrowser.contentWindow); + }); + }, true); + + gBrowser.selectedTab.linkedBrowser.loadURI("data:text/html,"); +} diff --git a/dom/tests/mochitest/bugs/test_bug346659.html b/dom/tests/mochitest/bugs/test_bug346659.html index d8ff23e76a95..612bc11fdcb6 100644 --- a/dom/tests/mochitest/bugs/test_bug346659.html +++ b/dom/tests/mochitest/bugs/test_bug346659.html @@ -28,6 +28,9 @@ SimpleTest.waitForExplicitFinish(); var wins = []; +var gBlockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups"); +SpecialPowers.setBoolPref("dom.block_multiple_popups", false); + function r(base, tail) { return base.replace(/\/[^\/]*$/, "/" + tail); } @@ -153,6 +156,7 @@ function handleTestEnd() { setTimeout(startThirdBatch, 0); } } else if (!--numTestsSet3) { + SpecialPowers.setBoolPref("dom.block_multiple_popups", gBlockMultiplePopups); SimpleTest.finish(); } } diff --git a/dom/tests/mochitest/bugs/test_bug406375.html b/dom/tests/mochitest/bugs/test_bug406375.html index cfade43c57a6..0ee13c081475 100644 --- a/dom/tests/mochitest/bugs/test_bug406375.html +++ b/dom/tests/mochitest/bugs/test_bug406375.html @@ -23,8 +23,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=406375 SimpleTest.waitForExplicitFinish(); function runTest() { + var blockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups"); + SpecialPowers.setBoolPref("dom.block_multiple_popups", false); + window.showModalDialog("file_bug406375.html"); ok(true, "This test should not hang"); + + SpecialPowers.setBoolPref("dom.block_multiple_popups", blockMultiplePopups); SimpleTest.finish(); } diff --git a/dom/tests/mochitest/bugs/test_bug61098.html b/dom/tests/mochitest/bugs/test_bug61098.html index b1c3952880ca..bdcd7b0d9076 100644 --- a/dom/tests/mochitest/bugs/test_bug61098.html +++ b/dom/tests/mochitest/bugs/test_bug61098.html @@ -242,6 +242,9 @@ var expectedState; function runtests() { + var blockMultiplePopups = SpecialPowers.getBoolPref("dom.block_multiple_popups"); + SpecialPowers.setBoolPref("dom.block_multiple_popups", false); + registerMockPromptService(); enableDialogLoopBlocking(); @@ -348,6 +351,8 @@ function runtests() mockPromptFactoryRegisterer.unregister(); mockPromptServiceRegisterer.unregister(); + SpecialPowers.setBoolPref("dom.block_multiple_popups", blockMultiplePopups); + SimpleTest.finish(); } diff --git a/dom/tests/mochitest/chrome/test_popup_blocker_chrome.xul b/dom/tests/mochitest/chrome/test_popup_blocker_chrome.xul index d2e421651265..00c553efcebe 100644 --- a/dom/tests/mochitest/chrome/test_popup_blocker_chrome.xul +++ b/dom/tests/mochitest/chrome/test_popup_blocker_chrome.xul @@ -4,7 +4,7 @@ - @@ -12,6 +12,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=662519 Mozilla Bug 662519 + Mozilla Bug 675574 + @@ -20,35 +23,93 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=662519 /** Test for Bug 662519 **/ + let Cc = Components.classes; + let Ci = Components.interfaces; + SimpleTest.waitForExplicitFinish(); // We have to enable dom.disable_open_during_load which is disabled // by the test harness. - let prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - var gLastDomLoadValue = prefs.getBoolPref("dom.disable_open_during_load"); + let prefs = Cc["@mozilla.org/preferences-service;1"] + .getService(Ci.nsIPrefBranch); + let gLastDomLoadValue = prefs.getBoolPref("dom.disable_open_during_load"); + let gMultiplePopupsPref = prefs.getBoolPref("dom.block_multiple_popups"); + prefs.setBoolPref("dom.disable_open_during_load", true); + prefs.setBoolPref("dom.block_multiple_popups", true); - let w = window.open("data:text/html,foobar", "", "width=200,height=200"); - ok(w, "The window object shouldn't be null"); - - SimpleTest.waitForFocus(function() { - w.close(); - ok(true, "The popup appeared"); + function test1() { + let w = window.open("data:text/html,foobar", "", "width=200,height=200"); + ok(w, "The window object shouldn't be null"); SimpleTest.waitForFocus(function() { - let w = window.open("data:text/html,foobar", "", "width=200,height=200"); - ok(w, "The window object shouldn't be null"); + w.close(); + ok(true, "The popup appeared"); SimpleTest.waitForFocus(function() { - w.close(); + let w = window.open("data:text/html,foobar", "", "width=200,height=200"); + ok(w, "The window object shouldn't be null"); - ok(true, "The popup appeared"); + SimpleTest.waitForFocus(function() { + w.close(); + + ok(true, "The popup appeared"); + test2(); + }, w, false); + }); + }, w, false); + } + + function test2() { + let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"] + .getService(Ci.nsIWindowWatcher); + + let gPopupsCount = 0; + + ww.registerNotification(function(aSubject, aTopic, aData) { + if (aTopic != "domwindowopened") { + return; + } + + gPopupsCount++; + + if (gPopupsCount != 2) { + return; + } + + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + SimpleTest.executeSoon(function() { + ww.unregisterNotification(arguments.callee); + + is(gPopupsCount, 2, "Both window appeared"); + + // Clean-up and finish. + let windowEnumerator = wm.getEnumerator(null); + + while (windowEnumerator.hasMoreElements()) { + let win = windowEnumerator.getNext(); + + // Close all windows except ourself. + if (win != window && !win.closed) { + win.close(); + } + } + + prefs.setBoolPref("dom.block_multiple_popups", gMultiplePopupsPref); prefs.setBoolPref("dom.disable_open_during_load", gLastDomLoadValue); SimpleTest.finish(); - }, w, false); + }); + }); + }); + }); }); - }, w, false); + + EventUtils.synthesizeMouseAtCenter(document.getElementsByTagName('button')[0], {}); + } + + SimpleTest.waitForFocus(test1); ]]> diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 213b1393b28d..b60882ac65ce 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -562,6 +562,8 @@ pref("capability.policy.default.Clipboard.cutcopy", "noAccess"); pref("capability.policy.default.Clipboard.paste", "noAccess"); // Scripts & Windows prefs +pref("dom.block_multiple_popups", true); + pref("dom.disable_image_src_set", false); pref("dom.disable_window_flip", false); pref("dom.disable_window_move_resize", false); diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js index 1dead1c345fc..914b9f767577 100644 --- a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js @@ -24,6 +24,8 @@ var testPage = ""; // Assign a function to this variable to have a clean up at the end var testCleanUp = null; +// Backup the dom.block_multiple_popups pref value to re-set it on finish. +var blockMultiplePopupsPref; // Internal variables var _windowCount = 0; @@ -67,6 +69,8 @@ window.onload = function onLoad() if (openTwoWindows) { _windowCount = 2; + blockMultiplePopupsPref = SpecialPowers.getBoolPref("dom.block_multiple_popups"); + SpecialPowers.setBoolPref("dom.block_multiple_popups", false); window.open(secureTestLocation, "_new1", ""); window.open(secureTestLocation, "_new2", ""); } @@ -88,7 +92,10 @@ function onMessageReceived(event) { if (testCleanUp) testCleanUp(); - + + if (openTwoWindows) { + SpecialPowers.setBoolPref("dom.block_multiple_popups", blockMultiplePopupsPref); + } SimpleTest.finish(); } break; From 99813b5f1f2f33bfc1e8fca920568528dfab1815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Wed, 28 Sep 2011 17:49:18 -0400 Subject: [PATCH 30/65] Bug 689609 - Move the changes back in. Needs a clobber. r=re-revert. --- configure.in | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/configure.in b/configure.in index 49046aa572e9..ba5b608975da 100644 --- a/configure.in +++ b/configure.in @@ -2824,24 +2824,28 @@ fi AC_SUBST(_MOZ_RTTI_FLAGS_ON) -dnl Check whether we can use gcc's c++0x mode +dnl Check whether we can use gcc's c++0x mode. We check for some basic +dnl features that we need. AC_LANG_CPLUSPLUS if test "$GNU_CXX"; then _SAVE_CXXFLAGS=$CXXFLAGS CXXFLAGS="$CXXFLAGS -std=gnu++0x" - if test -z "$_MOZ_USE_RTTI"; then - CXXFLAGS="$CXXFLAGS $_MOZ_RTTI_FLAGS" - AC_CACHE_CHECK(for gcc c++0x headers bug without rtti, - ac_cv_cxx0x_headers_bug, - [AC_TRY_COMPILE([#include ], [], - ac_cv_cxx0x_headers_bug="no", - ac_cv_cxx0x_headers_bug="yes")]) - CXXFLAGS="$_SAVE_CXXFLAGS" - if test "$ac_cv_cxx0x_headers_bug" = "no"; then - CXXFLAGS="$CXXFLAGS -std=gnu++0x" - fi + CXXFLAGS="$CXXFLAGS $_MOZ_RTTI_FLAGS" + AC_CACHE_CHECK(for c++0x support, + ac_cv_cxx0x_support, + [AC_TRY_COMPILE([#include + #include + void f(int&&);], [ + int a; + f(std::move(a)); + ], + ac_cv_cxx0x_support="yes", + ac_cv_cxx0x_support="no")]) + CXXFLAGS="$_SAVE_CXXFLAGS" + if test "$ac_cv_cxx0x_support" = "yes"; then + CXXFLAGS="$CXXFLAGS -std=gnu++0x" fi fi From 6c25ae970c798e5e08f00f237f89a56f04fe10ac Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Wed, 28 Sep 2011 15:40:23 -0700 Subject: [PATCH 31/65] (no bug): Fix comment reference to RejoinInterpreter (now js_InternalInterpret). r=bhackett DONTBUILD --- js/src/methodjit/MethodJIT.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h index e20eb400d77e..c65f2dd95fbc 100644 --- a/js/src/methodjit/MethodJIT.h +++ b/js/src/methodjit/MethodJIT.h @@ -225,7 +225,7 @@ namespace mjit { /* * For a C++ or scripted call made from JIT code, indicates properties of the - * register and stack state after the call finishes, which RejoinInterpreter + * register and stack state after the call finishes, which js_InternalInterpret * must use to construct a coherent state for rejoining into the interpreter. */ enum RejoinState { From 2c59e05b59d59e674703d37d9db20c10f74c8725 Mon Sep 17 00:00:00 2001 From: "Adam Dane [:hobophobe]" Date: Mon, 26 Sep 2011 15:55:04 -0500 Subject: [PATCH 32/65] bug 591249 - event dragleave not properly dispatched if drag-and-drop aborted with ESC within iframe. r=smaug --- .../src/html/nsHTMLImageMapAccessible.cpp | 2 +- content/events/src/nsDOMEvent.cpp | 2 +- content/events/src/nsEventStateManager.cpp | 83 ++++++++++--------- content/events/src/nsEventStateManager.h | 4 +- content/events/test/Makefile.in | 2 + content/events/test/bug591249_iframe.xul | 33 ++++++++ content/events/test/test_bug591249.xul | 74 +++++++++++++++++ layout/base/nsPresShell.cpp | 6 +- layout/generic/nsCanvasFrame.cpp | 11 +-- layout/generic/nsCanvasFrame.h | 3 +- layout/generic/nsFrame.cpp | 3 +- layout/generic/nsFrame.h | 3 +- layout/generic/nsIFrame.h | 3 +- layout/generic/nsImageFrame.cpp | 26 +++--- layout/generic/nsImageFrame.h | 5 +- layout/generic/nsImageMap.cpp | 4 +- layout/generic/nsImageMap.h | 3 +- 17 files changed, 184 insertions(+), 83 deletions(-) create mode 100644 content/events/test/bug591249_iframe.xul create mode 100644 content/events/test/test_bug591249.xul diff --git a/accessible/src/html/nsHTMLImageMapAccessible.cpp b/accessible/src/html/nsHTMLImageMapAccessible.cpp index 01af9130e5ce..ab2f7dc90456 100644 --- a/accessible/src/html/nsHTMLImageMapAccessible.cpp +++ b/accessible/src/html/nsHTMLImageMapAccessible.cpp @@ -201,7 +201,7 @@ nsHTMLAreaAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY, NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE); nsImageFrame *imageFrame = do_QueryFrame(frame); - nsImageMap* map = imageFrame->GetImageMap(presContext); + nsImageMap* map = imageFrame->GetImageMap(); NS_ENSURE_TRUE(map, NS_ERROR_FAILURE); nsRect rect; diff --git a/content/events/src/nsDOMEvent.cpp b/content/events/src/nsDOMEvent.cpp index 650d1e0be0eb..2cbf8a718cda 100644 --- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -320,7 +320,7 @@ nsDOMEvent::GetTargetFromFrame() // get the real content nsCOMPtr realEventContent; - targetFrame->GetContentForEvent(mPresContext, mEvent, getter_AddRefs(realEventContent)); + targetFrame->GetContentForEvent(mEvent, getter_AddRefs(realEventContent)); return realEventContent.forget(); } diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 635bfb0093e8..01cc0a7f096d 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -159,6 +159,8 @@ PRInt32 nsEventStateManager::sUserInputEventDepth = 0; PRBool nsEventStateManager::sNormalLMouseEventInProcess = PR_FALSE; nsEventStateManager* nsEventStateManager::sActiveESM = nsnull; nsIDocument* nsEventStateManager::sMouseOverDocument = nsnull; +nsWeakFrame nsEventStateManager::sLastDragOverFrame = nsnull; +nsCOMPtr nsEventStateManager::sDragOverContent = nsnull; static PRUint32 gMouseOrKeyboardEventCounter = 0; static nsITimer* gUserInteractionTimer = nsnull; @@ -773,7 +775,6 @@ nsEventStateManager::nsEventStateManager() : mLockCursor(0), mCurrentTarget(nsnull), mLastMouseOverFrame(nsnull), - mLastDragOverFrame(nsnull), // init d&d gesture state machine variables mGestureDownPoint(0,0), mPresContext(nsnull), @@ -890,6 +891,10 @@ nsEventStateManager::~nsEventStateManager() } } + if (sDragOverContent && sDragOverContent->GetOwnerDoc() == mDocument) { + sDragOverContent = nsnull; + } + if (!m_haveShutdown) { Shutdown(); @@ -994,7 +999,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsEventStateManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLastRightMouseDownContentParent); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mActiveContent); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mHoverContent); - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDragOverContent); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mURLTargetContent); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstMouseOverEventElement); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstMouseOutEventElement); @@ -1015,7 +1019,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEventStateManager) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLastRightMouseDownContentParent); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mActiveContent); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mHoverContent); - NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDragOverContent); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mURLTargetContent); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstMouseOverEventElement); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstMouseOutEventElement); @@ -1969,7 +1972,7 @@ nsEventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext, mGestureDownPoint = inDownEvent->refPoint + inDownEvent->widget->WidgetToScreenOffset(); - inDownFrame->GetContentForEvent(aPresContext, inDownEvent, + inDownFrame->GetContentForEvent(inDownEvent, getter_AddRefs(mGestureDownContent)); mGestureDownFrameOwner = inDownFrame->GetContent(); @@ -2082,8 +2085,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext, PRBool isInEditor = PR_FALSE; PRBool isSelection = PR_FALSE; nsCOMPtr eventContent, targetContent; - mCurrentTarget->GetContentForEvent(aPresContext, aEvent, - getter_AddRefs(eventContent)); + mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent)); if (eventContent) DetermineDragTarget(aPresContext, eventContent, dataTransfer, &isSelection, &isInEditor, @@ -3066,7 +3068,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, nsCOMPtr newFocus; PRBool suppressBlur = PR_FALSE; if (mCurrentTarget) { - mCurrentTarget->GetContentForEvent(mPresContext, aEvent, getter_AddRefs(newFocus)); + mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(newFocus)); const nsStyleUserInterface* ui = mCurrentTarget->GetStyleUserInterface(); suppressBlur = (ui->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE); activeContent = mCurrentTarget->GetContent(); @@ -3397,7 +3399,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, // now fire the dragdrop event, for compatibility with XUL if (mCurrentTarget && nsEventStatus_eConsumeNoDefault != *aStatus) { nsCOMPtr targetContent; - mCurrentTarget->GetContentForEvent(presContext, aEvent, + mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent)); nsCOMPtr widget = mCurrentTarget->GetNearestWidget(); @@ -3469,8 +3471,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, case NS_MOUSE_ENTER: if (mCurrentTarget) { nsCOMPtr targetContent; - mCurrentTarget->GetContentForEvent(presContext, aEvent, - getter_AddRefs(targetContent)); + mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent)); SetContentState(targetContent, NS_EVENT_STATE_HOVER); } break; @@ -3479,8 +3480,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, case NS_MOUSE_ACTIVATE: if (mCurrentTarget) { nsCOMPtr targetContent; - mCurrentTarget->GetContentForEvent(presContext, aEvent, - getter_AddRefs(targetContent)); + mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent)); if (!NodeAllowsClickThrough(targetContent)) { *aStatus = nsEventStatus_eConsumeNoDefault; } @@ -4067,29 +4067,31 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext, { // when dragging from one frame to another, events are fired in the // order: dragexit, dragenter, dragleave - if (mLastDragOverFrame != mCurrentTarget) { + if (sLastDragOverFrame != mCurrentTarget) { //We'll need the content, too, to check if it changed separately from the frames. nsCOMPtr lastContent; nsCOMPtr targetContent; - mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(targetContent)); + mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(targetContent)); - if (mLastDragOverFrame) { + if (sLastDragOverFrame) { //The frame has changed but the content may not have. Check before dispatching to content - mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent)); + sLastDragOverFrame->GetContentForEvent(aEvent, getter_AddRefs(lastContent)); - FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH, - targetContent, lastContent, mLastDragOverFrame); + FireDragEnterOrExit(sLastDragOverFrame->PresContext(), + aEvent, NS_DRAGDROP_EXIT_SYNTH, + targetContent, lastContent, sLastDragOverFrame); } FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_ENTER, lastContent, targetContent, mCurrentTarget); - if (mLastDragOverFrame) { - FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH, - targetContent, lastContent, mLastDragOverFrame); + if (sLastDragOverFrame) { + FireDragEnterOrExit(sLastDragOverFrame->PresContext(), + aEvent, NS_DRAGDROP_LEAVE_SYNTH, + targetContent, lastContent, sLastDragOverFrame); } - mLastDragOverFrame = mCurrentTarget; + sLastDragOverFrame = mCurrentTarget; } } break; @@ -4097,16 +4099,19 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext, case NS_DRAGDROP_EXIT: { //This is actually the window mouse exit event. - if (mLastDragOverFrame) { + if (sLastDragOverFrame) { nsCOMPtr lastContent; - mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent)); + sLastDragOverFrame->GetContentForEvent(aEvent, getter_AddRefs(lastContent)); - FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH, - nsnull, lastContent, mLastDragOverFrame); - FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH, - nsnull, lastContent, mLastDragOverFrame); + nsRefPtr lastDragOverFramePresContext = sLastDragOverFrame->PresContext(); + FireDragEnterOrExit(lastDragOverFramePresContext, + aEvent, NS_DRAGDROP_EXIT_SYNTH, + nsnull, lastContent, sLastDragOverFrame); + FireDragEnterOrExit(lastDragOverFramePresContext, + aEvent, NS_DRAGDROP_LEAVE_SYNTH, + nsnull, lastContent, sLastDragOverFrame); - mLastDragOverFrame = nsnull; + sLastDragOverFrame = nsnull; } } break; @@ -4199,7 +4204,7 @@ nsEventStateManager::SetClickCount(nsPresContext* aPresContext, { nsCOMPtr mouseContent; nsIContent* mouseContentParent = nsnull; - mCurrentTarget->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(mouseContent)); + mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(mouseContent)); if (mouseContent) { if (mouseContent->IsNodeOfType(nsINode::eTEXT)) { mouseContent = mouseContent->GetParent(); @@ -4382,7 +4387,7 @@ nsEventStateManager::GetEventTargetContent(nsEvent* aEvent) // Some events here may set mCurrentTarget but not set the corresponding // event target in the PresShell. if (!content && mCurrentTarget) { - mCurrentTarget->GetContentForEvent(mPresContext, aEvent, &content); + mCurrentTarget->GetContentForEvent(aEvent, &content); } return content; @@ -4560,10 +4565,10 @@ nsEventStateManager::SetContentState(nsIContent *aContent, nsEventStates aState) } else { updateAncestors = PR_FALSE; if (aState == NS_EVENT_STATE_DRAGOVER) { - if (aContent != mDragOverContent) { + if (aContent != sDragOverContent) { notifyContent1 = aContent; - notifyContent2 = mDragOverContent; - mDragOverContent = aContent; + notifyContent2 = sDragOverContent; + sDragOverContent = aContent; } } else if (aState == NS_EVENT_STATE_URLTARGET) { if (aContent != mURLTargetContent) { @@ -4641,9 +4646,10 @@ nsEventStateManager::ContentRemoved(nsIDocument* aDocument, nsIContent* aContent SetContentState(aContent->GetParent(), NS_EVENT_STATE_ACTIVE); } - if (mDragOverContent && - nsContentUtils::ContentIsDescendantOf(mDragOverContent, aContent)) { - mDragOverContent = nsnull; + if (sDragOverContent && + sDragOverContent->GetOwnerDoc() == aContent->GetOwnerDoc() && + nsContentUtils::ContentIsDescendantOf(sDragOverContent, aContent)) { + sDragOverContent = nsnull; } if (mLastMouseOverElement && @@ -4933,6 +4939,9 @@ nsEventStateManager::ClearGlobalActiveContent(nsEventStateManager* aClearer) { if (aClearer) { aClearer->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE); + if (sDragOverContent) { + aClearer->SetContentState(nsnull, NS_EVENT_STATE_DRAGOVER); + } } if (sActiveESM && aClearer != sActiveESM) { sActiveESM->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE); diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index 0e3c73b80a6e..0cdc92daf958 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -486,7 +486,7 @@ private: nsCOMPtr mCurrentTargetContent; nsWeakFrame mLastMouseOverFrame; nsCOMPtr mLastMouseOverElement; - nsWeakFrame mLastDragOverFrame; + static nsWeakFrame sLastDragOverFrame; // member variables for the d&d gesture state machine nsIntPoint mGestureDownPoint; // screen coordinates @@ -511,7 +511,7 @@ private: nsCOMPtr mActiveContent; nsCOMPtr mHoverContent; - nsCOMPtr mDragOverContent; + static nsCOMPtr sDragOverContent; nsCOMPtr mURLTargetContent; // The last element on which we fired a mouseover event, or null if diff --git a/content/events/test/Makefile.in b/content/events/test/Makefile.in index 991720700a24..b8be8e02a4ac 100644 --- a/content/events/test/Makefile.in +++ b/content/events/test/Makefile.in @@ -136,6 +136,8 @@ _CHROME_FILES = \ test_bug415498.xul \ bug415498-doc1.html \ bug415498-doc2.html \ + test_bug591249.xul \ + bug591249_iframe.xul \ bug602962.xul \ test_bug602962.xul \ test_bug617528.xul \ diff --git a/content/events/test/bug591249_iframe.xul b/content/events/test/bug591249_iframe.xul new file mode 100644 index 000000000000..7c7d7642b109 --- /dev/null +++ b/content/events/test/bug591249_iframe.xul @@ -0,0 +1,33 @@ + + + + + + + #drop-target { + width: 50px; + height: 50px; + border: 4px dotted black; + } + #drop-target { + background-color: red; + } + #drop-target:-moz-drag-over { + background-color: yellow; + } + + + + Iframe for Bug 591249 + + + + + diff --git a/content/events/test/test_bug591249.xul b/content/events/test/test_bug591249.xul new file mode 100644 index 000000000000..aa78761047bb --- /dev/null +++ b/content/events/test/test_bug591249.xul @@ -0,0 +1,74 @@ + + + + + + + + + diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index e13fbd347d48..2ce6dac41ee2 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -5453,7 +5453,7 @@ PresShell::GetEventTargetContent(nsEvent* aEvent) } else { nsIFrame* currentEventFrame = GetCurrentEventFrame(); if (currentEventFrame) { - currentEventFrame->GetContentForEvent(mPresContext, aEvent, &content); + currentEventFrame->GetContentForEvent(aEvent, &content); } else { content = nsnull; } @@ -6086,7 +6086,7 @@ PresShell::HandlePositionedEvent(nsIView* aView, if (mCurrentEventFrame) { nsCOMPtr targetElement; - mCurrentEventFrame->GetContentForEvent(mPresContext, aEvent, + mCurrentEventFrame->GetContentForEvent(aEvent, getter_AddRefs(targetElement)); // If there is no content for this frame, target it anyway. Some @@ -6334,7 +6334,7 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView, } else { nsCOMPtr targetContent; - rv = mCurrentEventFrame->GetContentForEvent(mPresContext, aEvent, + rv = mCurrentEventFrame->GetContentForEvent(aEvent, getter_AddRefs(targetContent)); if (NS_SUCCEEDED(rv) && targetContent) { nsEventDispatcher::Dispatch(targetContent, mPresContext, aEvent, diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp index b77f51edc79c..2f7d44c7aa58 100644 --- a/layout/generic/nsCanvasFrame.cpp +++ b/layout/generic/nsCanvasFrame.cpp @@ -620,19 +620,16 @@ nsCanvasFrame::GetType() const } NS_IMETHODIMP -nsCanvasFrame::GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, - nsIContent** aContent) +nsCanvasFrame::GetContentForEvent(nsEvent* aEvent, + nsIContent** aContent) { NS_ENSURE_ARG_POINTER(aContent); - nsresult rv = nsFrame::GetContentForEvent(aPresContext, - aEvent, + nsresult rv = nsFrame::GetContentForEvent(aEvent, aContent); if (NS_FAILED(rv) || !*aContent) { nsIFrame* kid = mFrames.FirstChild(); if (kid) { - rv = kid->GetContentForEvent(aPresContext, - aEvent, + rv = kid->GetContentForEvent(aEvent, aContent); } } diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h index 9e716d8b1624..d8436dc10cb1 100644 --- a/layout/generic/nsCanvasFrame.h +++ b/layout/generic/nsCanvasFrame.h @@ -140,8 +140,7 @@ public: #ifdef DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif - NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, + NS_IMETHOD GetContentForEvent(nsEvent* aEvent, nsIContent** aContent); nsRect CanvasArea() const; diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 0c78fa61da08..f825b9a79300 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1961,8 +1961,7 @@ nsIFrame::WrapReplacedContentForBorderRadius(nsDisplayListBuilder* aBuilder, } NS_IMETHODIMP -nsFrame::GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, +nsFrame::GetContentForEvent(nsEvent* aEvent, nsIContent** aContent) { nsIFrame* f = nsLayoutUtils::GetNonGeneratedAncestor(this); diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 5e15177187d5..e22e4c55dbd2 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -198,8 +198,7 @@ public: NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, nsEventStatus* aEventStatus); - NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, + NS_IMETHOD GetContentForEvent(nsEvent* aEvent, nsIContent** aContent); NS_IMETHOD GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 557d2bbda90a..c976ede28f1e 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1240,8 +1240,7 @@ public: nsGUIEvent* aEvent, nsEventStatus* aEventStatus) = 0; - NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, + NS_IMETHOD GetContentForEvent(nsEvent* aEvent, nsIContent** aContent) = 0; // This structure keeps track of the content node and offsets associated with diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index 48e2a82dfd88..ad65bddaf604 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1175,12 +1175,11 @@ static void PaintDebugImageMap(nsIFrame* aFrame, nsRenderingContext* aCtx, const nsRect& aDirtyRect, nsPoint aPt) { nsImageFrame* f = static_cast(aFrame); nsRect inner = f->GetInnerArea() + aPt; - nsPresContext* pc = f->PresContext(); aCtx->SetColor(NS_RGB(0, 0, 0)); aCtx->PushState(); aCtx->Translate(inner.TopLeft()); - f->GetImageMap(pc)->Draw(aFrame, *aCtx); + f->GetImageMap()->Draw(aFrame, *aCtx); aCtx->PopState(); } #endif @@ -1284,8 +1283,7 @@ nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt, nsLayoutUtils::GetGraphicsFilterForFrame(this), dest, aDirtyRect, aFlags); - nsPresContext* presContext = PresContext(); - nsImageMap* map = GetImageMap(presContext); + nsImageMap* map = GetImageMap(); if (nsnull != map) { aRenderingContext.PushState(); aRenderingContext.SetColor(NS_RGB(0, 0, 0)); @@ -1365,7 +1363,7 @@ nsImageFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, #ifdef DEBUG - if (GetShowFrameBorders() && GetImageMap(PresContext())) { + if (GetShowFrameBorders() && GetImageMap()) { rv = aLists.Outlines()->AppendNewToTop(new (aBuilder) nsDisplayGeneric(aBuilder, this, PaintDebugImageMap, "DebugImageMap", nsDisplayItem::TYPE_DEBUG_IMAGE_MAP)); @@ -1445,7 +1443,7 @@ nsImageFrame::ShouldDisplaySelection() } nsImageMap* -nsImageFrame::GetImageMap(nsPresContext* aPresContext) +nsImageFrame::GetImageMap() { if (!mImageMap) { nsIDocument* doc = mContent->GetDocument(); @@ -1460,7 +1458,7 @@ nsImageFrame::GetImageMap(nsPresContext* aPresContext) if (map) { mImageMap = new nsImageMap(); NS_ADDREF(mImageMap); - mImageMap->Init(aPresContext->PresShell(), this, map); + mImageMap->Init(this, map); } } @@ -1525,15 +1523,14 @@ nsImageFrame::GetAnchorHREFTargetAndNode(nsIURI** aHref, nsString& aTarget, } NS_IMETHODIMP -nsImageFrame::GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, +nsImageFrame::GetContentForEvent(nsEvent* aEvent, nsIContent** aContent) { NS_ENSURE_ARG_POINTER(aContent); nsIFrame* f = nsLayoutUtils::GetNonGeneratedAncestor(this); if (f != this) { - return f->GetContentForEvent(aPresContext, aEvent, aContent); + return f->GetContentForEvent(aEvent, aContent); } // XXX We need to make this special check for area element's capturing the @@ -1546,8 +1543,7 @@ nsImageFrame::GetContentForEvent(nsPresContext* aPresContext, return NS_OK; } - nsImageMap* map; - map = GetImageMap(aPresContext); + nsImageMap* map = GetImageMap(); if (nsnull != map) { nsIntPoint p; @@ -1575,13 +1571,12 @@ nsImageFrame::HandleEvent(nsPresContext* aPresContext, nsEventStatus* aEventStatus) { NS_ENSURE_ARG_POINTER(aEventStatus); - nsImageMap* map; if ((aEvent->eventStructType == NS_MOUSE_EVENT && aEvent->message == NS_MOUSE_BUTTON_UP && static_cast(aEvent)->button == nsMouseEvent::eLeftButton) || aEvent->message == NS_MOUSE_MOVE) { - map = GetImageMap(aPresContext); + nsImageMap* map = GetImageMap(); PRBool isServerMap = IsServerImageMap(); if ((nsnull != map) || isServerMap) { nsIntPoint p; @@ -1637,8 +1632,7 @@ NS_IMETHODIMP nsImageFrame::GetCursor(const nsPoint& aPoint, nsIFrame::Cursor& aCursor) { - nsPresContext* context = PresContext(); - nsImageMap* map = GetImageMap(context); + nsImageMap* map = GetImageMap(); if (nsnull != map) { nsIntPoint p; TranslateEventCoords(aPoint, p); diff --git a/layout/generic/nsImageFrame.h b/layout/generic/nsImageFrame.h index 75bac2b3a85e..8575f898eb9b 100644 --- a/layout/generic/nsImageFrame.h +++ b/layout/generic/nsImageFrame.h @@ -128,8 +128,7 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); - NS_IMETHOD GetContentForEvent(nsPresContext* aPresContext, - nsEvent* aEvent, + NS_IMETHOD GetContentForEvent(nsEvent* aEvent, nsIContent** aContent); NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent, @@ -183,7 +182,7 @@ public: nsRect GetInnerArea() const; - nsImageMap* GetImageMap(nsPresContext* aPresContext); + nsImageMap* GetImageMap(); virtual void AddInlineMinWidth(nsRenderingContext *aRenderingContext, InlineMinWidthData *aData); diff --git a/layout/generic/nsImageMap.cpp b/layout/generic/nsImageMap.cpp index ae6b3e0fef59..74b745b3c1cc 100644 --- a/layout/generic/nsImageMap.cpp +++ b/layout/generic/nsImageMap.cpp @@ -692,7 +692,6 @@ void CircleArea::GetRect(nsIFrame* aFrame, nsRect& aRect) nsImageMap::nsImageMap() : - mPresShell(nsnull), mImageFrame(nsnull), mContainsBlockContents(PR_FALSE) { @@ -749,13 +748,12 @@ nsImageMap::FreeAreas() } nsresult -nsImageMap::Init(nsIPresShell* aPresShell, nsIFrame* aImageFrame, nsIContent* aMap) +nsImageMap::Init(nsIFrame* aImageFrame, nsIContent* aMap) { NS_PRECONDITION(aMap, "null ptr"); if (!aMap) { return NS_ERROR_NULL_POINTER; } - mPresShell = aPresShell; mImageFrame = aImageFrame; mMap = aMap; diff --git a/layout/generic/nsImageMap.h b/layout/generic/nsImageMap.h index f8b07dd84dd2..579d3342aa93 100644 --- a/layout/generic/nsImageMap.h +++ b/layout/generic/nsImageMap.h @@ -57,7 +57,7 @@ class nsImageMap : public nsStubMutationObserver, public: nsImageMap(); - nsresult Init(nsIPresShell* aPresShell, nsIFrame* aImageFrame, nsIContent* aMap); + nsresult Init(nsIFrame* aImageFrame, nsIContent* aMap); /** * See if the given aX,aY pixel coordinates are in the image @@ -104,7 +104,6 @@ protected: void MaybeUpdateAreas(nsIContent *aContent); - nsIPresShell* mPresShell; // WEAK - owns the frame that owns us nsIFrame* mImageFrame; // the frame that owns us nsCOMPtr mMap; nsAutoTArray mAreas; // almost always has some entries From 80c37cdd5a1788ec7cee072436f66dd515675da4 Mon Sep 17 00:00:00 2001 From: Wolfgang Germund Date: Wed, 28 Sep 2011 16:14:45 -0700 Subject: [PATCH 33/65] Bug 296795: ZipReader doesn't handle non-ASCII characters r=taras --- caps/src/nsScriptSecurityManager.cpp | 2 +- modules/libjar/nsIZipReader.idl | 46 +++++++------- modules/libjar/nsJAR.cpp | 60 +++++++++--------- modules/libjar/nsJAR.h | 2 +- modules/libjar/nsJARChannel.cpp | 10 +-- .../libjar/test/unit/data/test_umlaute.zip | Bin 0 -> 179 bytes modules/libjar/test/unit/test_umlaute.js | 40 ++++++++++++ modules/libjar/test/unit/xpcshell.ini | 2 + modules/libpref/src/Preferences.cpp | 4 +- xpcom/components/nsComponentManager.cpp | 2 +- xpinstall/src/nsXPInstallManager.cpp | 10 +-- 11 files changed, 109 insertions(+), 69 deletions(-) create mode 100644 modules/libjar/test/unit/data/test_umlaute.zip create mode 100644 modules/libjar/test/unit/test_umlaute.js diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index 70121998a0ce..152de4e8901a 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -2974,7 +2974,7 @@ nsScriptSecurityManager::SetCanEnableCapability(const nsACString& certFingerprin rv = systemCertZip->Open(systemCertFile); if (NS_SUCCEEDED(rv)) { - rv = systemCertZip->GetCertificatePrincipal(nsnull, + rv = systemCertZip->GetCertificatePrincipal(EmptyCString(), getter_AddRefs(mSystemCertificate)); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; } diff --git a/modules/libjar/nsIZipReader.idl b/modules/libjar/nsIZipReader.idl index aae3fa01b516..2eefe84fa368 100644 --- a/modules/libjar/nsIZipReader.idl +++ b/modules/libjar/nsIZipReader.idl @@ -91,7 +91,7 @@ interface nsIZipEntry : nsISupports readonly attribute boolean isSynthetic; }; -[scriptable, uuid(7bb925d6-833a-486c-8ef2-9bc15c670a60)] +[scriptable, uuid(8fbf5023-3827-4fbc-a464-5db546e7f747)] interface nsIZipReader : nsISupports { /** @@ -104,7 +104,7 @@ interface nsIZipReader : nsISupports /** * Opens a zip file inside a zip file for reading. */ - void openInner(in nsIZipReader zipReader, in string zipEntry); + void openInner(in nsIZipReader zipReader, in AUTF8String zipEntry); /** * The file that represents the zip with which this zip reader was @@ -121,10 +121,11 @@ interface nsIZipReader : nsISupports /** * Tests the integrity of the archive by performing a CRC check * on each item expanded into memory. If an entry is specified - * the integrity of only that item is tested. If NULL is passed - * in the integrity of all items in the archive are tested. + * the integrity of only that item is tested. If null (javascript) + * or EmptyCString() (c++) is passed in the integrity of all items + * in the archive are tested. */ - void test(in string aEntryName); + void test(in AUTF8String aEntryName); /** * Extracts a zip entry into a local file specified by outFile. @@ -133,12 +134,12 @@ interface nsIZipReader : nsISupports * If the entry is a directory, the directory will be extracted * non-recursively. */ - void extract(in string zipEntry, in nsIFile outFile); + void extract(in AUTF8String zipEntry, in nsIFile outFile); /** * Returns a nsIZipEntry describing a specified zip entry. */ - nsIZipEntry getEntry(in string zipEntry); + nsIZipEntry getEntry(in AUTF8String zipEntry); /** * Checks whether the zipfile contains an entry specified by entryName. @@ -150,7 +151,8 @@ interface nsIZipReader : nsISupports * * @param aPattern * A regular expression used to find matching entries in the zip file. - * Set this parameter to null to get all entries; otherwise, use the + * Set this parameter to null (javascript) or EmptyCString() (c++) or "*" + * to get all entries; otherwise, use the * following syntax: * * o * matches anything @@ -187,14 +189,14 @@ interface nsIZipReader : nsISupports * @throws NS_ERROR_ILLEGAL_VALUE on many but not all invalid aPattern * values. */ - nsIUTF8StringEnumerator findEntries(in string aPattern); + nsIUTF8StringEnumerator findEntries(in AUTF8String aPattern); /** * Returns an input stream containing the contents of the specified zip * entry. * @param zipEntry the name of the entry to open the stream from */ - nsIInputStream getInputStream(in string zipEntry); + nsIInputStream getInputStream(in AUTF8String zipEntry); /** * Returns an input stream containing the contents of the specified zip @@ -203,7 +205,7 @@ interface nsIZipReader : nsISupports * @param aJarSpec the Spec of the URI for the JAR (only used for directory streams) * @param zipEntry the name of the entry to open the stream from */ - nsIInputStream getInputStreamWithSpec(in AUTF8String aJarSpec, in string zipEntry); + nsIInputStream getInputStreamWithSpec(in AUTF8String aJarSpec, in AUTF8String zipEntry); /** * Returns an object describing the entity which signed @@ -213,7 +215,7 @@ interface nsIZipReader : nsISupports * stored in the jar, verifyExternalFile (not yet implemented) must * be called before getPrincipal. */ - nsIPrincipal getCertificatePrincipal(in string aEntryName); + nsIPrincipal getCertificatePrincipal(in AUTF8String aEntryName); readonly attribute PRUint32 manifestEntriesCount; }; @@ -221,7 +223,7 @@ interface nsIZipReader : nsISupports //////////////////////////////////////////////////////////////////////////////// // nsIZipReaderCache -[scriptable, uuid(52c45d86-0cc3-11d4-986e-00c04fa0cf4a)] +[scriptable, uuid(72fc56e5-3e6e-4d11-8967-26ab96071032)] interface nsIZipReaderCache : nsISupports { /** @@ -251,7 +253,7 @@ interface nsIZipReaderCache : nsISupports * * See getZip */ - nsIZipReader getInnerZip(in nsIFile zipFile, in string zipEntry); + nsIZipReader getInnerZip(in nsIFile zipFile, in AUTF8String zipEntry); }; //////////////////////////////////////////////////////////////////////////////// @@ -259,19 +261,15 @@ interface nsIZipReaderCache : nsISupports %{C++ #define NS_ZIPREADER_CID \ -{ /* 7526a738-9632-11d3-8cd9-0060b0fc14a3 */ \ - 0x7526a738, \ - 0x9632, \ - 0x11d3, \ - {0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \ +{ /* 88e2fd0b-f7f4-480c-9483-7846b00e8dad */ \ + 0x88e2fd0b, 0xf7f4, 0x480c, \ + { 0x94, 0x83, 0x78, 0x46, 0xb0, 0x0e, 0x8d, 0xad } \ } #define NS_ZIPREADERCACHE_CID \ -{ /* 1b117e16-0cad-11d4-986e-00c04fa0cf4a */ \ - 0x1b117e16, \ - 0x0cad, \ - 0x11d4, \ - {0x98, 0x6e, 0x00, 0xc0, 0x4f, 0xa0, 0xcf, 0x4a} \ +{ /* 608b7f6f-4b60-40d6-87ed-d933bf53d8c1 */ \ + 0x608b7f6f, 0x4b60, 0x40d6, \ + { 0x87, 0xed, 0xd9, 0x33, 0xbf, 0x53, 0xd8, 0xc1 } \ } %} diff --git a/modules/libjar/nsJAR.cpp b/modules/libjar/nsJAR.cpp index 80c66b4f4abe..b04763508b89 100644 --- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -188,14 +188,13 @@ nsJAR::Open(nsIFile* zipFile) } NS_IMETHODIMP -nsJAR::OpenInner(nsIZipReader *aZipReader, const char *aZipEntry) +nsJAR::OpenInner(nsIZipReader *aZipReader, const nsACString &aZipEntry) { NS_ENSURE_ARG_POINTER(aZipReader); - NS_ENSURE_ARG_POINTER(aZipEntry); if (mOpened) return NS_ERROR_FAILURE; // Already open! PRBool exist; - nsresult rv = aZipReader->HasEntry(nsDependentCString(aZipEntry), &exist); + nsresult rv = aZipReader->HasEntry(aZipEntry, &exist); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(exist, NS_ERROR_FILE_NOT_FOUND); @@ -207,7 +206,7 @@ nsJAR::OpenInner(nsIZipReader *aZipReader, const char *aZipEntry) mOuterZipEntry.Assign(aZipEntry); nsRefPtr handle; - rv = nsZipHandle::Init(static_cast(aZipReader)->mZip.get(), aZipEntry, + rv = nsZipHandle::Init(static_cast(aZipReader)->mZip.get(), PromiseFlatCString(aZipEntry).get(), getter_AddRefs(handle)); if (NS_FAILED(rv)) return rv; @@ -242,13 +241,13 @@ nsJAR::Close() } NS_IMETHODIMP -nsJAR::Test(const char *aEntryName) +nsJAR::Test(const nsACString &aEntryName) { - return mZip->Test(aEntryName); + return mZip->Test(aEntryName.IsEmpty()? nsnull : PromiseFlatCString(aEntryName).get()); } NS_IMETHODIMP -nsJAR::Extract(const char *zipEntry, nsIFile* outFile) +nsJAR::Extract(const nsACString &aEntryName, nsIFile* outFile) { // nsZipArchive and zlib are not thread safe // we need to use a lock to prevent bug #51267 @@ -258,7 +257,7 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile) nsCOMPtr localFile = do_QueryInterface(outFile, &rv); if (NS_FAILED(rv)) return rv; - nsZipItem *item = mZip->GetItem(zipEntry); + nsZipItem *item = mZip->GetItem(PromiseFlatCString(aEntryName).get()); NS_ENSURE_TRUE(item, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST); // Remove existing file or directory so we set permissions correctly. @@ -305,9 +304,9 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile) } NS_IMETHODIMP -nsJAR::GetEntry(const char *aEntryName, nsIZipEntry* *result) +nsJAR::GetEntry(const nsACString &aEntryName, nsIZipEntry* *result) { - nsZipItem* zipItem = mZip->GetItem(aEntryName); + nsZipItem* zipItem = mZip->GetItem(PromiseFlatCString(aEntryName).get()); NS_ENSURE_TRUE(zipItem, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST); nsJARItem* jarItem = new nsJARItem(zipItem); @@ -325,12 +324,12 @@ nsJAR::HasEntry(const nsACString &aEntryName, PRBool *result) } NS_IMETHODIMP -nsJAR::FindEntries(const char *aPattern, nsIUTF8StringEnumerator **result) +nsJAR::FindEntries(const nsACString &aPattern, nsIUTF8StringEnumerator **result) { NS_ENSURE_ARG_POINTER(result); nsZipFind *find; - nsresult rv = mZip->FindInit(aPattern, &find); + nsresult rv = mZip->FindInit(aPattern.IsEmpty()? nsnull : PromiseFlatCString(aPattern).get(), &find); NS_ENSURE_SUCCESS(rv, rv); nsIUTF8StringEnumerator *zipEnum = new nsJAREnumerator(find); @@ -344,23 +343,23 @@ nsJAR::FindEntries(const char *aPattern, nsIUTF8StringEnumerator **result) } NS_IMETHODIMP -nsJAR::GetInputStream(const char* aFilename, nsIInputStream** result) +nsJAR::GetInputStream(const nsACString &aFilename, nsIInputStream** result) { return GetInputStreamWithSpec(EmptyCString(), aFilename, result); } NS_IMETHODIMP nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec, - const char* aEntryName, nsIInputStream** result) + const nsACString &aEntryName, nsIInputStream** result) { - NS_ENSURE_ARG_POINTER(aEntryName); NS_ENSURE_ARG_POINTER(result); // Watch out for the jar:foo.zip!/ (aDir is empty) top-level special case! nsZipItem *item = nsnull; - if (*aEntryName) { + const char *entry = PromiseFlatCString(aEntryName).get(); + if (*entry) { // First check if item exists in jar - item = mZip->GetItem(aEntryName); + item = mZip->GetItem(entry); if (!item) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST; } nsJARInputStream* jis = new nsJARInputStream(); @@ -370,7 +369,7 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec, nsresult rv = NS_OK; if (!item || item->IsDirectory()) { - rv = jis->InitDirectory(this, aJarDirSpec, aEntryName); + rv = jis->InitDirectory(this, aJarDirSpec, entry); } else { rv = jis->InitFile(this, item); } @@ -381,7 +380,7 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec, } NS_IMETHODIMP -nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal) +nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsIPrincipal** aPrincipal) { //-- Parameter check if (!aPrincipal) @@ -401,10 +400,11 @@ nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal) return NS_OK; PRInt16 requestedStatus; - if (aFilename) + const char *filename = PromiseFlatCString(aFilename).get(); + if (*filename) { //-- Find the item - nsCStringKey key(aFilename); + nsCStringKey key(filename); nsJARManifestItem* manItem = static_cast(mManifestData.Get(&key)); if (!manItem) return NS_OK; @@ -424,7 +424,7 @@ nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal) requestedStatus = mGlobalStatus; if (requestedStatus != JAR_VALID_MANIFEST) - ReportError(aFilename, requestedStatus); + ReportError(filename, requestedStatus); else // Valid signature { *aPrincipal = mPrincipal; @@ -452,7 +452,7 @@ nsJAR::GetJarPath(nsACString& aResult) // nsJAR private implementation //---------------------------------------------- nsresult -nsJAR::LoadEntry(const char* aFilename, char** aBuf, PRUint32* aBufLen) +nsJAR::LoadEntry(const nsACString &aFilename, char** aBuf, PRUint32* aBufLen) { //-- Get a stream for reading the file nsresult rv; @@ -529,7 +529,7 @@ nsJAR::ParseManifest() return NS_OK; //-- (1)Manifest (MF) file nsCOMPtr files; - nsresult rv = FindEntries(JAR_MF_SEARCH_STRING, getter_AddRefs(files)); + nsresult rv = FindEntries(nsDependentCString(JAR_MF_SEARCH_STRING), getter_AddRefs(files)); if (!files) rv = NS_ERROR_FAILURE; if (NS_FAILED(rv)) return rv; @@ -559,7 +559,7 @@ nsJAR::ParseManifest() nsXPIDLCString manifestBuffer; PRUint32 manifestLen; - rv = LoadEntry(manifestFilename.get(), getter_Copies(manifestBuffer), &manifestLen); + rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer), &manifestLen); if (NS_FAILED(rv)) return rv; //-- Parse it @@ -568,7 +568,7 @@ nsJAR::ParseManifest() //-- (2)Signature (SF) file // If there are multiple signatures, we select one. - rv = FindEntries(JAR_SF_SEARCH_STRING, getter_AddRefs(files)); + rv = FindEntries(nsDependentCString(JAR_SF_SEARCH_STRING), getter_AddRefs(files)); if (!files) rv = NS_ERROR_FAILURE; if (NS_FAILED(rv)) return rv; //-- Get an SF file @@ -583,7 +583,7 @@ nsJAR::ParseManifest() rv = files->GetNext(manifestFilename); if (NS_FAILED(rv)) return rv; - rv = LoadEntry(manifestFilename.get(), getter_Copies(manifestBuffer), &manifestLen); + rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer), &manifestLen); if (NS_FAILED(rv)) return rv; //-- Get its corresponding signature file @@ -595,12 +595,12 @@ nsJAR::ParseManifest() PRUint32 sigLen; { nsCAutoString tempFilename(sigFilename); tempFilename.Append("rsa", 3); - rv = LoadEntry(tempFilename.get(), getter_Copies(sigBuffer), &sigLen); + rv = LoadEntry(tempFilename, getter_Copies(sigBuffer), &sigLen); } if (NS_FAILED(rv)) { nsCAutoString tempFilename(sigFilename); tempFilename.Append("RSA", 3); - rv = LoadEntry(tempFilename.get(), getter_Copies(sigBuffer), &sigLen); + rv = LoadEntry(tempFilename, getter_Copies(sigBuffer), &sigLen); } if (NS_FAILED(rv)) { @@ -1152,7 +1152,7 @@ nsZipReaderCache::GetZip(nsIFile* zipFile, nsIZipReader* *result) } NS_IMETHODIMP -nsZipReaderCache::GetInnerZip(nsIFile* zipFile, const char *entry, +nsZipReaderCache::GetInnerZip(nsIFile* zipFile, const nsACString &entry, nsIZipReader* *result) { NS_ENSURE_ARG_POINTER(zipFile); diff --git a/modules/libjar/nsJAR.h b/modules/libjar/nsJAR.h index a4bd6b8edf23..146414293b0a 100644 --- a/modules/libjar/nsJAR.h +++ b/modules/libjar/nsJAR.h @@ -147,7 +147,7 @@ class nsJAR : public nsIZipReader nsresult ParseManifest(); void ReportError(const char* aFilename, PRInt16 errorCode); - nsresult LoadEntry(const char* aFilename, char** aBuf, + nsresult LoadEntry(const nsACString &aFilename, char** aBuf, PRUint32* aBufLen = nsnull); PRInt32 ReadLine(const char** src); nsresult ParseOneFile(const char* filebuf, PRInt16 aFileType); diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp index 17a553bedff7..584bb30ab8e5 100644 --- a/modules/libjar/nsJARChannel.cpp +++ b/modules/libjar/nsJARChannel.cpp @@ -149,11 +149,11 @@ nsJARInputThunk::EnsureJarStream() NS_ENSURE_STATE(!mJarDirSpec.IsEmpty()); rv = mJarReader->GetInputStreamWithSpec(mJarDirSpec, - mJarEntry.get(), + mJarEntry, getter_AddRefs(mJarStream)); } else { - rv = mJarReader->GetInputStream(mJarEntry.get(), + rv = mJarReader->GetInputStream(mJarEntry, getter_AddRefs(mJarStream)); } if (NS_FAILED(rv)) { @@ -303,7 +303,7 @@ nsJARChannel::CreateJarInput(nsIZipReaderCache *jarCache) if (mInnerJarEntry.IsEmpty()) rv = jarCache->GetZip(mJarFile, getter_AddRefs(reader)); else - rv = jarCache->GetInnerZip(mJarFile, mInnerJarEntry.get(), + rv = jarCache->GetInnerZip(mJarFile, mInnerJarEntry, getter_AddRefs(reader)); } else { // create an uncached jar reader @@ -322,7 +322,7 @@ nsJARChannel::CreateJarInput(nsIZipReaderCache *jarCache) if (NS_FAILED(rv)) return rv; - rv = reader->OpenInner(outerReader, mInnerJarEntry.get()); + rv = reader->OpenInner(outerReader, mInnerJarEntry); } } if (NS_FAILED(rv)) @@ -535,7 +535,7 @@ nsJARChannel::GetOwner(nsISupports **result) return NS_ERROR_NOT_INITIALIZED; nsCOMPtr cert; - rv = jarReader->GetCertificatePrincipal(mJarEntry.get(), getter_AddRefs(cert)); + rv = jarReader->GetCertificatePrincipal(mJarEntry, getter_AddRefs(cert)); if (NS_FAILED(rv)) return rv; if (cert) { diff --git a/modules/libjar/test/unit/data/test_umlaute.zip b/modules/libjar/test/unit/data/test_umlaute.zip new file mode 100644 index 0000000000000000000000000000000000000000..d147138e185ab6a40eaab58cf13f79943785b64e GIT binary patch literal 179 zcmWIWW@h1HVBlb2c-_clpSS9ZKRW{h0|;|7$S{xgI1B(f<|iNk literal 0 HcmV?d00001 diff --git a/modules/libjar/test/unit/test_umlaute.js b/modules/libjar/test/unit/test_umlaute.js new file mode 100644 index 000000000000..84e1f4ae7ce9 --- /dev/null +++ b/modules/libjar/test/unit/test_umlaute.js @@ -0,0 +1,40 @@ + +const Cc = Components.classes; +const Ci = Components.interfaces; + +function run_test() { + var dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); + var tmpDir = dirService.get("TmpD", Ci.nsIFile); + + var zipfile = do_get_file("data/test_umlaute.zip"); + + var testFile = tmpDir.clone(); + testFile.append("test_\u00FC.txt"); + if (testFile.exists()) { + testFile.remove(false); + } + + var zipreader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader); + zipreader.open(zipfile); + + var entries = zipreader.findEntries(null); + do_check_true(entries.hasMore()); + + var entryName = entries.getNext(); + do_check_eq(entryName, "test_\u00FC.txt"); + + do_check_true(zipreader.hasEntry(entryName)); + + var target = tmpDir.clone(); + target.append(entryName); + target.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0640); + + zipreader.extract(entryName, target); + + var entry = zipreader.getEntry(entryName); + do_check_true(entry != null); + + zipreader.test(entryName); + + zipreader.close(); +} diff --git a/modules/libjar/test/unit/xpcshell.ini b/modules/libjar/test/unit/xpcshell.ini index fad7b4535bba..c76fa14696d3 100644 --- a/modules/libjar/test/unit/xpcshell.ini +++ b/modules/libjar/test/unit/xpcshell.ini @@ -20,3 +20,5 @@ tail = [test_jarinput_stream_zipreader_reference.js] [test_not_found.js] [test_uncompressed.js] +[test_umlaute.js] + diff --git a/modules/libpref/src/Preferences.cpp b/modules/libpref/src/Preferences.cpp index e5368e7de448..c7073340d514 100644 --- a/modules/libpref/src/Preferences.cpp +++ b/modules/libpref/src/Preferences.cpp @@ -472,7 +472,7 @@ Preferences::ReadExtensionPrefs(nsILocalFile *aFile) NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr files; - rv = reader->FindEntries("defaults/preferences/*.(J|j)(S|s)$", + rv = reader->FindEntries(nsDependentCString("defaults/preferences/*.(J|j)(S|s)$"), getter_AddRefs(files)); NS_ENSURE_SUCCESS(rv, rv); @@ -485,7 +485,7 @@ Preferences::ReadExtensionPrefs(nsILocalFile *aFile) NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr stream; - rv = reader->GetInputStream(entry.get(), getter_AddRefs(stream)); + rv = reader->GetInputStream(entry, getter_AddRefs(stream)); NS_ENSURE_SUCCESS(rv, rv); PRUint32 avail, read; diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index ceb209c48418..9c25d95b15cc 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -537,7 +537,7 @@ LoadEntry(nsIZipReader* aReader, const char* aName) return NULL; nsCOMPtr is; - nsresult rv = aReader->GetInputStream(aName, getter_AddRefs(is)); + nsresult rv = aReader->GetInputStream(nsDependentCString(aName), getter_AddRefs(is)); if (NS_FAILED(rv)) return NULL; diff --git a/xpinstall/src/nsXPInstallManager.cpp b/xpinstall/src/nsXPInstallManager.cpp index 8bbba3c7677c..c01efe84c65c 100644 --- a/xpinstall/src/nsXPInstallManager.cpp +++ b/xpinstall/src/nsXPInstallManager.cpp @@ -638,7 +638,7 @@ VerifySigning(nsIZipReader* hZip, nsIPrincipal* aPrincipal) // See if the archive is signed at all first nsCOMPtr principal; - nsresult rv = hZip->GetCertificatePrincipal(nsnull, getter_AddRefs(principal)); + nsresult rv = hZip->GetCertificatePrincipal(EmptyCString(), getter_AddRefs(principal)); if (NS_FAILED(rv) || !principal) return NS_ERROR_FAILURE; @@ -646,7 +646,7 @@ VerifySigning(nsIZipReader* hZip, nsIPrincipal* aPrincipal) // first verify all files in the jar are also in the manifest. nsCOMPtr entries; - rv = hZip->FindEntries(nsnull, getter_AddRefs(entries)); + rv = hZip->FindEntries(EmptyCString(), getter_AddRefs(entries)); if (NS_FAILED(rv)) return rv; @@ -667,7 +667,7 @@ VerifySigning(nsIZipReader* hZip, nsIPrincipal* aPrincipal) entryCount++; // Each entry must be signed - rv = hZip->GetCertificatePrincipal(name.get(), getter_AddRefs(principal)); + rv = hZip->GetCertificatePrincipal(name, getter_AddRefs(principal)); if (NS_FAILED(rv) || !principal) return NS_ERROR_FAILURE; PRBool equal; @@ -713,7 +713,7 @@ OpenAndValidateArchive(nsIZipReader* hZip, nsIFile* jarFile, nsIPrincipal* aPrin return nsInstall::CANT_READ_ARCHIVE; // CRC check the integrity of all items in this archive - rv = hZip->Test(nsnull); + rv = hZip->Test(EmptyCString()); if (NS_FAILED(rv)) { NS_WARNING("CRC check of archive failed!"); @@ -727,7 +727,7 @@ OpenAndValidateArchive(nsIZipReader* hZip, nsIFile* jarFile, nsIPrincipal* aPrin return nsInstall::INVALID_SIGNATURE; } - if (NS_FAILED(hZip->Test("install.rdf"))) + if (NS_FAILED(hZip->Test(nsDependentCString("install.rdf")))) { NS_WARNING("Archive did not contain an install manifest!"); return nsInstall::NO_INSTALL_SCRIPT; From 3d166246468cffe29632991af7bf53b7328bf295 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Wed, 28 Sep 2011 17:29:08 -0700 Subject: [PATCH 34/65] Bug 689966 - Pref are initialized twice because of reference to nonexistent element [r=wesj] --- mobile/chrome/content/preferences.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/mobile/chrome/content/preferences.js b/mobile/chrome/content/preferences.js index 743235943fcc..f89b5b06284b 100644 --- a/mobile/chrome/content/preferences.js +++ b/mobile/chrome/content/preferences.js @@ -37,7 +37,6 @@ var PreferencesView = { _currentLocale: null, - _languages: null, _msg: null, _messageActions: function pv__messageActions(aData) { @@ -93,11 +92,10 @@ var PreferencesView = { }, delayedInit: function pv__delayedInit() { - if (this._languages) + if (this._msg) return; this._msg = document.getElementById("prefs-messages"); - this._languages = document.getElementById("prefs-languages"); this._loadLocales(); this._loadHomePage(); From 7b37824ea6e1693d872eb1a1d68b6928db934832 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <21@vingtetun.org> Date: Wed, 28 Sep 2011 17:29:29 -0700 Subject: [PATCH 35/65] Bug 689494 - Don't resize the UI when dragging the tablet sidebar rightward [r=mbrubeck] --- mobile/chrome/content/tabs.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mobile/chrome/content/tabs.xml b/mobile/chrome/content/tabs.xml index 8e76e91f23cb..9b7662132c34 100644 --- a/mobile/chrome/content/tabs.xml +++ b/mobile/chrome/content/tabs.xml @@ -206,7 +206,9 @@ }, dragMove: function dragMove(dx, dy) { - if (!this._grabSidebar) { + let ltr = (Util.localeDir == Util.LOCALE_DIR_LTR); + let hiddingPan = ltr ? (dx > 0) : (dx < 0); + if (!this._grabSidebar && hiddingPan) { this._grabSidebar = dx && Util.isTablet() && !Util.isPortrait(); if (this._grabSidebar) Browser.grabSidebar(); From 7190cb937644182c312013e92fb307562f1fc4f8 Mon Sep 17 00:00:00 2001 From: Matt Brubeck Date: Wed, 28 Sep 2011 18:29:22 -0700 Subject: [PATCH 36/65] Bug 681995 - Zoom to viewport width by default instead of document width [r=mfinkle] --- mobile/chrome/content/browser.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mobile/chrome/content/browser.js b/mobile/chrome/content/browser.js index 8189ce927189..e55e81b3387e 100644 --- a/mobile/chrome/content/browser.js +++ b/mobile/chrome/content/browser.js @@ -3110,15 +3110,16 @@ Tab.prototype = { if (md && md.defaultZoom) return this.clampZoomLevel(md.defaultZoom); - let pageZoom = this.getPageZoomLevel(); + let browserWidth = this._browser.getBoundingClientRect().width; + let defaultZoom = browserWidth / this._browser.contentWindowWidth; - // If pageZoom is "almost" 100%, zoom in to exactly 100% (bug 454456). + // If defaultZoom is "almost" 100%, zoom in to exactly 100% (bug 454456). let granularity = Services.prefs.getIntPref("browser.ui.zoom.pageFitGranularity"); let threshold = 1 - 1 / granularity; - if (threshold < pageZoom && pageZoom < 1) - pageZoom = 1; + if (threshold < defaultZoom && defaultZoom < 1) + defaultZoom = 1; - return this.clampZoomLevel(pageZoom); + return this.clampZoomLevel(defaultZoom); }, /** From d764accfee3fdcefe4dfa77760fc027b2187132c Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Thu, 29 Sep 2011 12:13:08 +0900 Subject: [PATCH 37/65] Bug 687393 - HTML select options gets relation from containing label, r=tbsaunde --- accessible/src/base/AccIterator.cpp | 33 +++++---- accessible/src/base/AccIterator.h | 8 ++- accessible/src/base/nsAccessible.cpp | 6 +- .../src/base/nsFormControlAccessible.cpp | 18 +++++ accessible/src/base/nsFormControlAccessible.h | 6 ++ .../src/html/nsHTMLFormControlAccessible.cpp | 28 ++++++++ .../src/html/nsHTMLFormControlAccessible.h | 9 +++ .../tests/mochitest/name/test_general.html | 2 +- .../mochitest/relations/test_general.html | 71 ++++++++++++++++--- 9 files changed, 149 insertions(+), 32 deletions(-) diff --git a/accessible/src/base/AccIterator.cpp b/accessible/src/base/AccIterator.cpp index 7ab6bb51cd2d..f1436049f5ac 100644 --- a/accessible/src/base/AccIterator.cpp +++ b/accessible/src/base/AccIterator.cpp @@ -152,10 +152,10 @@ RelatedAccIterator::Next() //////////////////////////////////////////////////////////////////////////////// HTMLLabelIterator:: - HTMLLabelIterator(nsDocAccessible* aDocument, nsIContent* aElement, + HTMLLabelIterator(nsDocAccessible* aDocument, const nsAccessible* aAccessible, LabelFilter aFilter) : - mRelIter(aDocument, aElement, nsGkAtoms::_for), - mElement(aElement), mLabelFilter(aFilter) + mRelIter(aDocument, aAccessible->GetContent(), nsGkAtoms::_for), + mAcc(aAccessible), mLabelFilter(aFilter) { } @@ -170,20 +170,25 @@ HTMLLabelIterator::Next() return label; } - if (mLabelFilter == eSkipAncestorLabel) + // Ignore ancestor label on not widget accessible. + if (mLabelFilter == eSkipAncestorLabel || !mAcc->IsWidget()) return nsnull; - // Go up tree get name of ancestor label if there is one (an ancestor