From 0cb3a2793ab86a93fc8c3afc3d7f2c4a1815d349 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Mon, 17 Mar 2014 16:42:48 +0800 Subject: [PATCH 01/13] Bug 982812 - Use UpdateThemeGeometry for windows region clearing. r=mstange --- gfx/src/nsITheme.h | 7 +++---- layout/base/FrameLayerBuilder.cpp | 9 --------- layout/base/nsDisplayList.cpp | 7 ++----- layout/base/nsDisplayList.h | 6 ------ widget/cocoa/nsNativeThemeCocoa.h | 3 +-- widget/cocoa/nsNativeThemeCocoa.mm | 3 +-- widget/gtk/nsNativeThemeGTK.cpp | 3 +-- widget/gtk/nsNativeThemeGTK.h | 3 +-- widget/windows/nsNativeThemeWin.cpp | 21 +++++---------------- widget/windows/nsNativeThemeWin.h | 3 +-- widget/windows/nsWindow.cpp | 23 +++++++++++++++++++++++ widget/windows/nsWindow.h | 2 ++ 12 files changed, 40 insertions(+), 50 deletions(-) diff --git a/gfx/src/nsITheme.h b/gfx/src/nsITheme.h index 1a30306839aa..3c1aee83faaa 100644 --- a/gfx/src/nsITheme.h +++ b/gfx/src/nsITheme.h @@ -30,8 +30,8 @@ class nsIWidget; // IID for the nsITheme interface // {b0f3efe9-0bd4-4f6b-8daa-0ec7f6006822} #define NS_ITHEME_IID \ -{ 0x2e49c679, 0x2130, 0x432c, \ - { 0x92, 0xcb, 0xd4, 0x8e, 0x9a, 0xe2, 0x34, 0x75 } } +{ 0x4440b5c7, 0xd8bd, 0x4d9c, \ + { 0x9c, 0x3e, 0xa5, 0xe6, 0x26, 0x81, 0x10, 0xa0 } } // {D930E29B-6909-44e5-AB4B-AF10D6923705} #define NS_THEMERENDERER_CID \ { 0x9020805b, 0x14a3, 0x4125, \ @@ -63,8 +63,7 @@ public: nsIFrame* aFrame, uint8_t aWidgetType, const nsRect& aRect, - const nsRect& aDirtyRect, - nsIntRegion* aRegionToClear = nullptr) = 0; + const nsRect& aDirtyRect) = 0; /** * Get the computed CSS border for the widget, in pixels. diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 6180fd6c8cb7..3871cac65aaf 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -3761,9 +3761,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer, nsRefPtr rc = new nsRenderingContext(); rc->Init(presContext->DeviceContext(), aContext); - nsIntRegion temp = builder->GetRegionToClear(); - builder->ResetRegionToClear(); - if (shouldDrawRectsSeparately) { nsIntRegionRectIterator it(aRegionToDraw); while (const nsIntRect* iterRect = it.Next()) { @@ -3805,12 +3802,6 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer, if (!aRegionToInvalidate.IsEmpty()) { aLayer->AddInvalidRect(aRegionToInvalidate.GetBounds()); } - - if (!builder->GetRegionToClear().IsEmpty()) { - aLayer->Manager()->SetRegionToClear(builder->GetRegionToClear()); - } - builder->ResetRegionToClear(); - builder->AddRegionToClear(temp); } bool diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 4a018ee482cf..5951ec2dd0ae 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -2358,6 +2358,7 @@ nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuil case NS_THEME_WINDOW_TITLEBAR: case NS_THEME_WINDOW_BUTTON_BOX: case NS_THEME_MOZ_MAC_FULLSCREEN_BUTTON: + case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED: RegisterThemeGeometry(aBuilder, aFrame); break; case NS_THEME_WIN_BORDERLESS_GLASS: @@ -2445,11 +2446,7 @@ nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder, theme->GetWidgetOverflow(presContext->DeviceContext(), mFrame, mAppearance, &drawing); drawing.IntersectRect(drawing, aBounds); - nsIntRegion clear; - theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing, &clear); - MOZ_ASSERT(clear.IsEmpty() || ReferenceFrame() == aBuilder->RootReferenceFrame(), - "Can't add to clear region if we're transformed!"); - aBuilder->AddRegionToClear(clear); + theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, borderArea, drawing); } bool nsDisplayThemedBackground::IsWindowActive() diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 5220569aa31b..97a51af7a4b6 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -641,10 +641,6 @@ public: DisplayListClipState& ClipState() { return mClipState; } - void AddRegionToClear(const nsIntRegion& aRegion) { mRegionToClear.Or(mRegionToClear, aRegion); } - const nsIntRegion& GetRegionToClear() { return mRegionToClear; } - void ResetRegionToClear() { mRegionToClear.SetEmpty(); } - private: void MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame, nsIFrame* aFrame, const nsRect& aDirtyRect); @@ -678,8 +674,6 @@ private: const nsIFrame* mCachedReferenceFrame; nsPoint mCachedOffset; nsRegion mExcludedGlassRegion; - // Area of the window (in pixels) to clear so the OS can draw them. - nsIntRegion mRegionToClear; // The display item for the Windows window glass background, if any nsDisplayItem* mGlassDisplayItem; nsTArray mDisplayItemClipsToDestroy; diff --git a/widget/cocoa/nsNativeThemeCocoa.h b/widget/cocoa/nsNativeThemeCocoa.h index 2a167b11341b..580c23181a3f 100644 --- a/widget/cocoa/nsNativeThemeCocoa.h +++ b/widget/cocoa/nsNativeThemeCocoa.h @@ -34,8 +34,7 @@ public: nsIFrame* aFrame, uint8_t aWidgetType, const nsRect& aRect, - const nsRect& aDirtyRect, - nsIntRegion* aRegionToClear); + const nsRect& aDirtyRect); NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, uint8_t aWidgetType, diff --git a/widget/cocoa/nsNativeThemeCocoa.mm b/widget/cocoa/nsNativeThemeCocoa.mm index 91ac17e0350e..55696549e75a 100644 --- a/widget/cocoa/nsNativeThemeCocoa.mm +++ b/widget/cocoa/nsNativeThemeCocoa.mm @@ -2080,8 +2080,7 @@ nsNativeThemeCocoa::DrawWidgetBackground(nsRenderingContext* aContext, nsIFrame* aFrame, uint8_t aWidgetType, const nsRect& aRect, - const nsRect& aDirtyRect, - nsIntRegion* aRegionToClear) + const nsRect& aDirtyRect) { NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT; diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp index 607ce690f256..054193f0cc30 100644 --- a/widget/gtk/nsNativeThemeGTK.cpp +++ b/widget/gtk/nsNativeThemeGTK.cpp @@ -752,8 +752,7 @@ nsNativeThemeGTK::DrawWidgetBackground(nsRenderingContext* aContext, nsIFrame* aFrame, uint8_t aWidgetType, const nsRect& aRect, - const nsRect& aDirtyRect, - nsIntRegion* aRegionToClear) + const nsRect& aDirtyRect) { GtkWidgetState state; GtkThemeWidgetType gtkWidgetType; diff --git a/widget/gtk/nsNativeThemeGTK.h b/widget/gtk/nsNativeThemeGTK.h index cca2271064ea..ddfc9d28e43e 100644 --- a/widget/gtk/nsNativeThemeGTK.h +++ b/widget/gtk/nsNativeThemeGTK.h @@ -24,8 +24,7 @@ public: NS_IMETHOD DrawWidgetBackground(nsRenderingContext* aContext, nsIFrame* aFrame, uint8_t aWidgetType, const nsRect& aRect, - const nsRect& aDirtyRect, - nsIntRegion* aRegionToClear); + const nsRect& aDirtyRect); NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, uint8_t aWidgetType, nsIntMargin* aResult); diff --git a/widget/windows/nsNativeThemeWin.cpp b/widget/windows/nsNativeThemeWin.cpp index 55aa6404ffd8..0e4fbe246dc5 100644 --- a/widget/windows/nsNativeThemeWin.cpp +++ b/widget/windows/nsNativeThemeWin.cpp @@ -1536,8 +1536,7 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext, nsIFrame* aFrame, uint8_t aWidgetType, const nsRect& aRect, - const nsRect& aDirtyRect, - nsIntRegion* aRegionToClear) + const nsRect& aDirtyRect) { HANDLE theme = GetTheme(aWidgetType); if (!theme) @@ -1568,6 +1567,10 @@ nsNativeThemeWin::DrawWidgetBackground(nsRenderingContext* aContext, case NS_THEME_WIN_BORDERLESS_GLASS: // Nothing to draw, this is the glass background. return NS_OK; + case NS_THEME_WINDOW_BUTTON_BOX: + case NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED: + // We handle these through nsIWidget::UpdateThemeGeometries + return NS_OK; break; } } @@ -1900,20 +1903,6 @@ RENDER_AGAIN: DrawThemeBackground(theme, hdc, gripPart, state, &widgetRect, &clipRect); } } - else if ((aWidgetType == NS_THEME_WINDOW_BUTTON_BOX || - aWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) && - nsUXThemeData::CheckForCompositor()) - { - // The caption buttons are drawn by the DWM, we just need to clear the area where they - // are because we might have drawn something above them (like a background-image). - NS_ASSERTION(aRegionToClear, "Must have a clear region to set!"); - if (aRegionToClear) { - // Create a rounded rectangle to follow the buttons' look. - *aRegionToClear = nsIntRect(dr.X(), dr.Y(), dr.Width(), dr.Height() - 2.0); - aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 1.0, dr.YMost() - 2.0, dr.Width() - 1.0, 1.0)); - aRegionToClear->Or(*aRegionToClear, nsIntRect(dr.X() + 2.0, dr.YMost() - 1.0, dr.Width() - 3.0, 1.0)); - } - } nativeDrawing.EndNativeDrawing(); diff --git a/widget/windows/nsNativeThemeWin.h b/widget/windows/nsNativeThemeWin.h index fe1320f63275..c296bbf17ccf 100644 --- a/widget/windows/nsNativeThemeWin.h +++ b/widget/windows/nsNativeThemeWin.h @@ -31,8 +31,7 @@ public: nsIFrame* aFrame, uint8_t aWidgetType, const nsRect& aRect, - const nsRect& aDirtyRect, - nsIntRegion* aRegionToClear); + const nsRect& aDirtyRect); NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 4468922463ca..2b5597d26a39 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -127,6 +127,7 @@ #include "nsToolkitCompsCID.h" #include "nsIAppStartup.h" #include "mozilla/WindowsVersion.h" +#include "nsThemeConstants.h" #ifdef MOZ_ENABLE_D3D9_LAYER #include "LayerManagerD3D9.h" @@ -3556,6 +3557,28 @@ nsWindow::EndRemoteDrawing() mCompositeDC = nullptr; } +void +nsWindow::UpdateThemeGeometries(const nsTArray& aThemeGeometries) +{ + nsIntRegion clearRegion; + for (size_t i = 0; i < aThemeGeometries.Length(); i++) { + if ((aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX || + aThemeGeometries[i].mWidgetType == NS_THEME_WINDOW_BUTTON_BOX_MAXIMIZED) && + nsUXThemeData::CheckForCompositor()) + { + nsIntRect bounds = aThemeGeometries[i].mRect; + clearRegion = nsIntRect(bounds.X(), bounds.Y(), bounds.Width(), bounds.Height() - 2.0); + clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 1.0, bounds.YMost() - 2.0, bounds.Width() - 1.0, 1.0)); + clearRegion.Or(clearRegion, nsIntRect(bounds.X() + 2.0, bounds.YMost() - 1.0, bounds.Width() - 3.0, 1.0)); + } + } + + nsRefPtr layerManager = GetLayerManager(); + if (layerManager) { + layerManager->SetRegionToClear(clearRegion); + } +} + /************************************************************** ************************************************************** ** diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 3096da589fc4..1e8bd1358ecc 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -196,6 +196,8 @@ public: mozilla::TemporaryRef StartRemoteDrawing() MOZ_OVERRIDE; virtual void EndRemoteDrawing() MOZ_OVERRIDE; + virtual void UpdateThemeGeometries(const nsTArray& aThemeGeometries) MOZ_OVERRIDE; + /** * Event helpers */ From 89bcebeed44f8680cd5854cdf4f709d8b3300132 Mon Sep 17 00:00:00 2001 From: Daniel Holbert Date: Mon, 17 Mar 2014 16:54:30 +0800 Subject: [PATCH 02/13] Bug 984254: Remove unnecessary nsresult return value on nsCaret::CheckCaretDrawingState(). r=roc --- layout/base/nsCaret.cpp | 4 ++-- layout/base/nsCaret.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 85046d182c1a..0aeea406932e 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -854,7 +854,8 @@ nsCaret::GetCaretFrameForNodeOffset(nsIContent* aContentNode, return NS_OK; } -nsresult nsCaret::CheckCaretDrawingState() +void +nsCaret::CheckCaretDrawingState() { if (mDrawn) { // The caret is drawn; if it shouldn't be, erase it. @@ -867,7 +868,6 @@ nsresult nsCaret::CheckCaretDrawingState() if (mPendingDraw && (mVisible && MustDrawCaret(true))) DrawCaret(true); } - return NS_OK; } /*----------------------------------------------------------------------------- diff --git a/layout/base/nsCaret.h b/layout/base/nsCaret.h index ee51fcf98229..336b2ed0da77 100644 --- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -163,7 +163,7 @@ class nsCaret : public nsISelectionListener nsIFrame** aReturnFrame, int32_t* aReturnOffset); - NS_IMETHOD CheckCaretDrawingState(); + void CheckCaretDrawingState(); protected: From a2c1bed380876415879adf484ee17d658853af3e Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Mon, 17 Mar 2014 10:11:21 +0100 Subject: [PATCH 03/13] Bug 981693 - Improve JIT code memory reporters. r=njn --- js/src/assembler/assembler/ARMAssembler.h | 5 +++ js/src/assembler/assembler/AssemblerBuffer.h | 12 +++++- js/src/assembler/assembler/LinkBuffer.h | 29 +++----------- .../assembler/MacroAssemblerCodeRef.h | 17 +++++---- js/src/assembler/assembler/X86Assembler.h | 2 + js/src/assembler/jit/ExecutableAllocator.cpp | 5 +++ js/src/assembler/jit/ExecutableAllocator.h | 38 ++++++++++++++++--- js/src/jit/Ion.cpp | 15 +++++--- js/src/jit/IonCode.h | 20 +++++++--- js/src/jit/IonLinker.h | 7 +++- js/src/yarr/YarrJIT.h | 8 ++-- 11 files changed, 103 insertions(+), 55 deletions(-) diff --git a/js/src/assembler/assembler/ARMAssembler.h b/js/src/assembler/assembler/ARMAssembler.h index fd959f846470..cc8a3a7bff04 100644 --- a/js/src/assembler/assembler/ARMAssembler.h +++ b/js/src/assembler/assembler/ARMAssembler.h @@ -906,6 +906,11 @@ namespace JSC { return m_buffer.uncheckedSize(); } + size_t allocSize() const + { + return m_buffer.allocSize(); + } + void ensureSpace(int insnSpace, int constSpace) { m_buffer.ensureSpace(insnSpace, constSpace); diff --git a/js/src/assembler/assembler/AssemblerBuffer.h b/js/src/assembler/assembler/AssemblerBuffer.h index 03528aa305d4..a8af9323f57e 100644 --- a/js/src/assembler/assembler/AssemblerBuffer.h +++ b/js/src/assembler/assembler/AssemblerBuffer.h @@ -42,6 +42,7 @@ #include #include "jsfriendapi.h" #include "jsopcode.h" +#include "jsutil.h" #include "jit/IonSpewer.h" #include "js/RootingAPI.h" @@ -63,6 +64,7 @@ namespace JSC { : m_buffer(m_inlineBuffer) , m_capacity(inlineCapacity) , m_size(0) + , m_allocSize(0) , m_oom(false) { } @@ -143,6 +145,11 @@ namespace JSC { return m_size; } + size_t allocSize() const + { + return m_allocSize; + } + bool oom() const { return m_oom; @@ -159,7 +166,9 @@ namespace JSC { return 0; } - void* result = allocator->alloc(m_size, poolp, kind); + m_allocSize = js::AlignBytes(m_size, sizeof(void *)); + + void* result = allocator->alloc(m_allocSize, poolp, kind); if (!result) { *poolp = NULL; return 0; @@ -255,6 +264,7 @@ namespace JSC { char* m_buffer; size_t m_capacity; size_t m_size; + size_t m_allocSize; bool m_oom; }; diff --git a/js/src/assembler/assembler/LinkBuffer.h b/js/src/assembler/assembler/LinkBuffer.h index 57af1eda1f9d..1c8e12b210be 100644 --- a/js/src/assembler/assembler/LinkBuffer.h +++ b/js/src/assembler/assembler/LinkBuffer.h @@ -66,38 +66,19 @@ public: LinkBuffer(MacroAssembler* masm, ExecutableAllocator* executableAllocator, ExecutablePool** poolp, bool* ok, CodeKind codeKind) { + // LinkBuffer is only used by Yarr. MacroAssemblerCodeRef::release relies on this. + MOZ_ASSERT(codeKind == REGEXP_CODE); m_codeKind = codeKind; m_code = executableAllocAndCopy(*masm, executableAllocator, poolp); m_executablePool = *poolp; m_size = masm->m_assembler.size(); // must come after call to executableAllocAndCopy()! + m_allocSize = masm->m_assembler.allocSize(); #ifndef NDEBUG m_completed = false; #endif *ok = !!m_code; } - LinkBuffer(CodeKind kind) - : m_executablePool(NULL) - , m_code(NULL) - , m_size(0) - , m_codeKind(kind) -#ifndef NDEBUG - , m_completed(false) -#endif - { - } - - LinkBuffer(uint8_t* ncode, size_t size, CodeKind kind) - : m_executablePool(NULL) - , m_code(ncode) - , m_size(size) - , m_codeKind(kind) -#ifndef NDEBUG - , m_completed(false) -#endif - { - } - ~LinkBuffer() { ASSERT(!m_executablePool || m_completed); @@ -183,7 +164,8 @@ public: { performFinalization(); - return CodeRef(m_code, m_executablePool, m_size); + MOZ_ASSERT(m_allocSize >= m_size); + return CodeRef(m_code, m_executablePool, m_allocSize); } CodeLocationLabel finalizeCodeAddendum() { @@ -225,6 +207,7 @@ protected: ExecutablePool* m_executablePool; void* m_code; size_t m_size; + size_t m_allocSize; CodeKind m_codeKind; #ifndef NDEBUG bool m_completed; diff --git a/js/src/assembler/assembler/MacroAssemblerCodeRef.h b/js/src/assembler/assembler/MacroAssemblerCodeRef.h index b92cddc05e2b..0b2e401ce3a3 100644 --- a/js/src/assembler/assembler/MacroAssemblerCodeRef.h +++ b/js/src/assembler/assembler/MacroAssemblerCodeRef.h @@ -182,14 +182,14 @@ class MacroAssemblerCodeRef { public: MacroAssemblerCodeRef() : m_executablePool(NULL), - m_size(0) + m_allocSize(0) { } - MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t size) + MacroAssemblerCodeRef(void* code, ExecutablePool* executablePool, size_t allocSize) : m_code(code) , m_executablePool(executablePool) - , m_size(size) + , m_allocSize(allocSize) { } @@ -201,22 +201,23 @@ public: #if defined DEBUG && (defined WTF_CPU_X86 || defined WTF_CPU_X86_64) void *addr = m_code.executableAddress(); - memset(addr, 0xcc, m_size); + memset(addr, 0xcc, m_allocSize); #endif - m_executablePool->release(); + // MacroAssemblerCodeRef is only used by Yarr. + m_executablePool->release(m_allocSize, REGEXP_CODE); m_executablePool = NULL; } MacroAssemblerCodePtr code() const { return m_code; } - size_t size() const { - return m_size; + size_t allocSize() const { + return m_allocSize; } MacroAssemblerCodePtr m_code; ExecutablePool* m_executablePool; - size_t m_size; + size_t m_allocSize; }; } // namespace JSC diff --git a/js/src/assembler/assembler/X86Assembler.h b/js/src/assembler/assembler/X86Assembler.h index 4e16b33f3d21..0fe3b2e7e217 100644 --- a/js/src/assembler/assembler/X86Assembler.h +++ b/js/src/assembler/assembler/X86Assembler.h @@ -440,6 +440,7 @@ public: }; size_t size() const { return m_formatter.size(); } + size_t allocSize() const { return m_formatter.allocSize(); } unsigned char *buffer() const { return m_formatter.buffer(); } bool oom() const { return m_formatter.oom(); } @@ -3867,6 +3868,7 @@ private: // Administrative methods: size_t size() const { return m_buffer.size(); } + size_t allocSize() const { return m_buffer.allocSize(); } unsigned char *buffer() const { return m_buffer.buffer(); } bool oom() const { return m_buffer.oom(); } bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); } diff --git a/js/src/assembler/jit/ExecutableAllocator.cpp b/js/src/assembler/jit/ExecutableAllocator.cpp index ffa6c73821ab..2341ee06cea2 100644 --- a/js/src/assembler/jit/ExecutableAllocator.cpp +++ b/js/src/assembler/jit/ExecutableAllocator.cpp @@ -38,6 +38,11 @@ size_t ExecutableAllocator::largeAllocSize = 0; ExecutablePool::~ExecutablePool() { + MOZ_ASSERT(m_ionCodeBytes == 0); + MOZ_ASSERT(m_baselineCodeBytes == 0); + MOZ_ASSERT(m_regexpCodeBytes == 0); + MOZ_ASSERT(m_otherCodeBytes == 0); + m_allocator->releasePoolPages(this); } diff --git a/js/src/assembler/jit/ExecutableAllocator.h b/js/src/assembler/jit/ExecutableAllocator.h index d2d915d55d91..c6842c27b86f 100644 --- a/js/src/assembler/jit/ExecutableAllocator.h +++ b/js/src/assembler/jit/ExecutableAllocator.h @@ -85,7 +85,7 @@ namespace JSC { class ExecutableAllocator; - enum CodeKind { ION_CODE, BASELINE_CODE, REGEXP_CODE, OTHER_CODE }; + enum CodeKind { ION_CODE = 0, BASELINE_CODE, REGEXP_CODE, OTHER_CODE }; // These are reference-counted. A new one starts with a count of 1. class ExecutablePool { @@ -130,6 +130,31 @@ public: if (--m_refCount == 0) js_delete(this); } + void release(size_t n, CodeKind kind) + { + switch (kind) { + case ION_CODE: + m_ionCodeBytes -= n; + MOZ_ASSERT(m_ionCodeBytes < m_allocation.size); // Shouldn't underflow. + break; + case BASELINE_CODE: + m_baselineCodeBytes -= n; + MOZ_ASSERT(m_baselineCodeBytes < m_allocation.size); + break; + case REGEXP_CODE: + m_regexpCodeBytes -= n; + MOZ_ASSERT(m_regexpCodeBytes < m_allocation.size); + break; + case OTHER_CODE: + m_otherCodeBytes -= n; + MOZ_ASSERT(m_otherCodeBytes < m_allocation.size); + break; + default: + MOZ_ASSUME_UNREACHABLE("bad code kind"); + } + + release(); + } ExecutablePool(ExecutableAllocator* allocator, Allocation a) : m_allocator(allocator), m_freePtr(a.pages), m_end(m_freePtr + a.size), m_allocation(a), @@ -223,10 +248,11 @@ public: // pool; i.e. alloc() increments the count before returning the object. void* alloc(size_t n, ExecutablePool** poolp, CodeKind type) { - // Round 'n' up to a multiple of word size; if all allocations are of - // word sized quantities, then all subsequent allocations will be + // Caller must ensure 'n' is word-size aligned. If all allocations are + // of word sized quantities, then all subsequent allocations will be // aligned. - n = roundUpAllocationSize(n, sizeof(void*)); + JS_ASSERT(roundUpAllocationSize(n, sizeof(void*)) == n); + if (n == OVERSIZE_ALLOCATION) { *poolp = NULL; return NULL; @@ -347,7 +373,7 @@ public: ExecutablePool* pool = createPool(largeAllocSize); if (!pool) return NULL; - // At this point, local |pool| is the owner. + // At this point, local |pool| is the owner. if (m_smallPools.length() < maxSmallPools) { // We haven't hit the maximum number of live pools; add the new pool. @@ -373,7 +399,7 @@ public: } } - // Pass ownership to the caller. + // Pass ownership to the caller. return pool; } diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 1cded87568dc..71950f19aaa3 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -615,25 +615,28 @@ JitRuntime::getVMWrapper(const VMFunction &f) const template JitCode * -JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool) +JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize, + JSC::ExecutablePool *pool, JSC::CodeKind kind) { JitCode *codeObj = js::NewJitCode(cx); if (!codeObj) { - pool->release(); + pool->release(headerSize + bufferSize, kind); return nullptr; } - new (codeObj) JitCode(code, bufferSize, pool); + new (codeObj) JitCode(code, bufferSize, headerSize, pool, kind); return codeObj; } template JitCode * -JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); +JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize, + JSC::ExecutablePool *pool, JSC::CodeKind kind); template JitCode * -JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); +JitCode::New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize, + JSC::ExecutablePool *pool, JSC::CodeKind kind); void JitCode::copyFrom(MacroAssembler &masm) @@ -696,7 +699,7 @@ JitCode::finalize(FreeOp *fop) // Horrible hack: if we are using perf integration, we don't // want to reuse code addresses, so we just leak the memory instead. if (!PerfEnabled()) - pool_->release(); + pool_->release(headerSize_ + bufferSize_, JSC::CodeKind(kind_)); pool_ = nullptr; } } diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index 9d0bff5c437b..4cea5e5119ee 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -14,6 +14,7 @@ #include "jsinfer.h" #include "jstypes.h" +#include "assembler/jit/ExecutableAllocator.h" #include "gc/Heap.h" #include "jit/IonOptimizationLevels.h" #include "jit/IonTypes.h" @@ -37,13 +38,15 @@ class JitCode : public gc::BarrieredCell protected: uint8_t *code_; JSC::ExecutablePool *pool_; - uint32_t bufferSize_; // Total buffer size. + uint32_t bufferSize_; // Total buffer size. Does not include headerSize_. uint32_t insnSize_; // Instruction stream size. uint32_t dataSize_; // Size of the read-only data area. uint32_t jumpRelocTableBytes_; // Size of the jump relocation table. uint32_t dataRelocTableBytes_; // Size of the data relocation table. uint32_t preBarrierTableBytes_; // Size of the prebarrier table. - bool invalidated_; // Whether the code object has been invalidated. + uint8_t headerSize_ : 5; // Number of bytes allocated before codeStart. + uint8_t kind_ : 3; // JSC::CodeKind, for the memory reporters. + bool invalidated_ : 1; // Whether the code object has been invalidated. // This is necessary to prevent GC tracing. #if JS_BITS_PER_WORD == 32 @@ -55,7 +58,8 @@ class JitCode : public gc::BarrieredCell : code_(nullptr), pool_(nullptr) { } - JitCode(uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool) + JitCode(uint8_t *code, uint32_t bufferSize, uint32_t headerSize, JSC::ExecutablePool *pool, + JSC::CodeKind kind) : code_(code), pool_(pool), bufferSize_(bufferSize), @@ -64,8 +68,13 @@ class JitCode : public gc::BarrieredCell jumpRelocTableBytes_(0), dataRelocTableBytes_(0), preBarrierTableBytes_(0), + headerSize_(headerSize), + kind_(kind), invalidated_(false) - { } + { + MOZ_ASSERT(JSC::CodeKind(kind_) == kind); + MOZ_ASSERT(headerSize_ == headerSize); + } uint32_t dataOffset() const { return insnSize_; @@ -126,7 +135,8 @@ class JitCode : public gc::BarrieredCell // object can be allocated, nullptr is returned. On failure, |pool| is // automatically released, so the code may be freed. template - static JitCode *New(JSContext *cx, uint8_t *code, uint32_t bufferSize, JSC::ExecutablePool *pool); + static JitCode *New(JSContext *cx, uint8_t *code, uint32_t bufferSize, uint32_t headerSize, + JSC::ExecutablePool *pool, JSC::CodeKind kind); public: static inline ThingRootKind rootKind() { return THING_ROOT_JIT_CODE; } diff --git a/js/src/jit/IonLinker.h b/js/src/jit/IonLinker.h index 4af0d01dbb5b..84907feb1731 100644 --- a/js/src/jit/IonLinker.h +++ b/js/src/jit/IonLinker.h @@ -44,6 +44,9 @@ class Linker if (bytesNeeded >= MAX_BUFFER_SIZE) return fail(cx); + // ExecutableAllocator requires bytesNeeded to be word-size aligned. + bytesNeeded = AlignBytes(bytesNeeded, sizeof(void *)); + uint8_t *result = (uint8_t *)execAlloc->alloc(bytesNeeded, &pool, kind); if (!result) return fail(cx); @@ -54,8 +57,8 @@ class Linker // Bump the code up to a nice alignment. codeStart = (uint8_t *)AlignBytes((uintptr_t)codeStart, CodeAlignment); uint32_t headerSize = codeStart - result; - JitCode *code = JitCode::New(cx, codeStart, - bytesNeeded - headerSize, pool); + JitCode *code = JitCode::New(cx, codeStart, bytesNeeded - headerSize, + headerSize, pool, kind); if (!code) return nullptr; if (masm.oom()) diff --git a/js/src/yarr/YarrJIT.h b/js/src/yarr/YarrJIT.h index 6792b700e1b6..16fdf58465ec 100644 --- a/js/src/yarr/YarrJIT.h +++ b/js/src/yarr/YarrJIT.h @@ -82,16 +82,16 @@ public: bool isFallBack() { return m_needFallBack; } #ifdef YARR_8BIT_CHAR_SUPPORT - bool has8BitCode() const { return m_ref8.size(); } + bool has8BitCode() const { return m_ref8.allocSize(); } void set8BitCode(MacroAssemblerCodeRef ref) { m_ref8 = ref; } - bool has8BitCodeMatchOnly() const { return m_matchOnly8.size(); } + bool has8BitCodeMatchOnly() const { return m_matchOnly8.allocSize(); } void set8BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly8 = matchOnly; } #endif - bool has16BitCode() const { return m_ref16.size(); } + bool has16BitCode() const { return m_ref16.allocSize(); } void set16BitCode(MacroAssemblerCodeRef ref) { m_ref16 = ref; } - bool has16BitCodeMatchOnly() const { return m_matchOnly16.size(); } + bool has16BitCodeMatchOnly() const { return m_matchOnly16.allocSize(); } void set16BitCodeMatchOnly(MacroAssemblerCodeRef matchOnly) { m_matchOnly16 = matchOnly; } #if YARR_8BIT_CHAR_SUPPORT From c15568fa91bbfeede757e99a37d31ec11edc9456 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Mon, 17 Mar 2014 10:51:39 +0100 Subject: [PATCH 04/13] Bug 980860: Rename test to match bug number. DONTBUILD --HG-- rename : js/src/jit-test/tests/ion/bug980960.js => js/src/jit-test/tests/ion/bug980860.js --- js/src/jit-test/tests/ion/{bug980960.js => bug980860.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename js/src/jit-test/tests/ion/{bug980960.js => bug980860.js} (100%) diff --git a/js/src/jit-test/tests/ion/bug980960.js b/js/src/jit-test/tests/ion/bug980860.js similarity index 100% rename from js/src/jit-test/tests/ion/bug980960.js rename to js/src/jit-test/tests/ion/bug980860.js From 5e75612291be5fabfc11c84b375c18a763a51123 Mon Sep 17 00:00:00 2001 From: Chris Lord Date: Mon, 17 Mar 2014 09:54:24 +0000 Subject: [PATCH 05/13] Bug 983202 - Don't call Mutated more than necessary. r=mattwoodrow We call Mutated when the invalid region isn't empty, but progressive updates mean that we're calling this more frequently than is necessary as transactions are repeated and the invalid region doesn't change between them. --- gfx/layers/client/ClientContainerLayer.h | 7 ++++--- gfx/layers/client/ClientLayerManager.cpp | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/gfx/layers/client/ClientContainerLayer.h b/gfx/layers/client/ClientContainerLayer.h index 8711214c2016..dbc4ff825c3d 100644 --- a/gfx/layers/client/ClientContainerLayer.h +++ b/gfx/layers/client/ClientContainerLayer.h @@ -76,11 +76,12 @@ public: continue; } - if (!child->GetInvalidRegion().IsEmpty()) { + ToClientLayer(child)->RenderLayer(); + + if (!ClientManager()->GetRepeatTransaction() && + !child->GetInvalidRegion().IsEmpty()) { child->Mutated(); } - - ToClientLayer(child)->RenderLayer(); } } diff --git a/gfx/layers/client/ClientLayerManager.cpp b/gfx/layers/client/ClientLayerManager.cpp index d561213a4345..cc81f5683ed5 100644 --- a/gfx/layers/client/ClientLayerManager.cpp +++ b/gfx/layers/client/ClientLayerManager.cpp @@ -194,10 +194,10 @@ ClientLayerManager::EndTransactionInternal(DrawThebesLayerCallback aCallback, GetRoot()->ComputeEffectiveTransforms(Matrix4x4()); - if (!GetRoot()->GetInvalidRegion().IsEmpty()) { + root->RenderLayer(); + if (!mRepeatTransaction && !GetRoot()->GetInvalidRegion().IsEmpty()) { GetRoot()->Mutated(); } - root->RenderLayer(); mThebesLayerCallback = nullptr; mThebesLayerCallbackData = nullptr; From 2f85dabaa8e048683afb15ffc0bf8f4a3f8776db Mon Sep 17 00:00:00 2001 From: Trevor Saunders Date: Thu, 13 Mar 2014 16:37:20 -0400 Subject: [PATCH 06/13] bug 983335 - install .gdbinit to the objdir as well as dist/bin r=mshal --- build/Makefile.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/Makefile.in b/build/Makefile.in index 6f07573ab261..5fe722621c79 100644 --- a/build/Makefile.in +++ b/build/Makefile.in @@ -44,8 +44,12 @@ endif # by GDB when we debug executables there. # NOTE: Keep .gdbinit in the topsrcdir for people who run gdb from the topsrcdir. GDBINIT_FILES := $(topsrcdir)/.gdbinit +GDBINIT_OBJDIR_FILES = $(topsrcdir)/.gdbinit GDBINIT_DEST = $(FINAL_TARGET) -INSTALL_TARGETS += GDBINIT + +# needs to be absolute to be distinct from $(topsrcdir)/.gdbinit +GDBINIT_OBJDIR_DEST = $(abspath $(DEPTH)) +INSTALL_TARGETS += GDBINIT GDBINIT_OBJDIR # Put a .lldbinit in the bin directory and the objdir, to be picked up # automatically by LLDB when we debug executables using either of those two From 1be05a870259487eaa2e3048b922705e40be8d08 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 17 Mar 2014 12:57:29 +0100 Subject: [PATCH 07/13] =?UTF-8?q?Bug=20983513=20-=20js/src/jsobj.cpp:2552:?= =?UTF-8?q?48:=20error:=20reference=20to=20=E2=80=98NullPtr=E2=80=99=20is?= =?UTF-8?q?=20ambiguous=20(--disable-ion).=20r=3Dnbp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/src/jsobj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 24a5b2629c78..1a8e5871ff04 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2549,7 +2549,7 @@ DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, H * (FIXME: remove this dependency on the exact identity of the parent, * perhaps as part of bug 638316.) */ - RootedFunction fun(cx, NewFunction(cx, NullPtr(), constructor, nargs, + RootedFunction fun(cx, NewFunction(cx, js::NullPtr(), constructor, nargs, JSFunction::NATIVE_CTOR, obj, atom, ctorKind)); if (!fun) goto bad; From 4a5d9bb2dcc0d030591df9a7ca15d01fac9f8b56 Mon Sep 17 00:00:00 2001 From: Tor Arvid Lund Date: Mon, 17 Mar 2014 10:49:04 -0400 Subject: [PATCH 08/13] Bug 973976 - Remove redundant work in CopyableCanvasLayer. r=jrmuizel This operator was already initialized to OP_SOURCE, so no need to do it again. --- gfx/layers/CopyableCanvasLayer.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/gfx/layers/CopyableCanvasLayer.cpp b/gfx/layers/CopyableCanvasLayer.cpp index 5691b44ec74b..aaf0c8508b02 100644 --- a/gfx/layers/CopyableCanvasLayer.cpp +++ b/gfx/layers/CopyableCanvasLayer.cpp @@ -286,13 +286,6 @@ CopyableCanvasLayer::PaintWithOpacity(gfx::DrawTarget* aTarget, DrawOptions options = DrawOptions(aOpacity, CompositionOp::OP_SOURCE); - // If content opaque, then save off current operator and set to source. - // This ensures that alpha is not applied even if the source surface - // has an alpha channel - if (GetContentFlags() & CONTENT_OPAQUE) { - options.mCompositionOp = CompositionOp::OP_SOURCE; - } - if (aOperator != CompositionOp::OP_OVER) { options.mCompositionOp = aOperator; } From 0d38ee722938b26b2338e147dffeb06817850e66 Mon Sep 17 00:00:00 2001 From: Tor Arvid Lund Date: Mon, 17 Mar 2014 10:49:21 -0400 Subject: [PATCH 09/13] Bug 973976 - Revert to Thebes path for CopyableCanvasLayer. r=jmuizelaar The performance on the Mac platform degraded after porting the code to Moz2D in Bug 948765. This patch chooses the old thebes path instead of the Moz2D path, so that performance is unaffected. This way we can easily revert this patch at a later time when the perf issue has been fixed. --- gfx/layers/CopyableCanvasLayer.cpp | 3 +++ gfx/layers/client/CanvasClient.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/gfx/layers/CopyableCanvasLayer.cpp b/gfx/layers/CopyableCanvasLayer.cpp index aaf0c8508b02..ba6c0899cc96 100644 --- a/gfx/layers/CopyableCanvasLayer.cpp +++ b/gfx/layers/CopyableCanvasLayer.cpp @@ -290,8 +290,11 @@ CopyableCanvasLayer::PaintWithOpacity(gfx::DrawTarget* aTarget, options.mCompositionOp = aOperator; } + // XXX: This needs rewriting for acceptable performance using CoreGraphics. + // Therefore - this ::PaintWithOpacity is currently not used Rect rect = Rect(0, 0, mBounds.width, mBounds.height); aTarget->FillRect(rect, pat, options); + if (aMaskSurface) { aTarget->MaskSurface(pat, aMaskSurface, Point(0, 0), options); } diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index aed99d92b2bd..43ef1eaeaabb 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -79,10 +79,10 @@ CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer) bool updated = false; { // Restrict drawTarget to a scope so that terminates before Unlock. - RefPtr drawTarget = - mBuffer->AsTextureClientDrawTarget()->GetAsDrawTarget(); - if (drawTarget) { - aLayer->UpdateTarget(drawTarget); + nsRefPtr surface = + mBuffer->AsTextureClientSurface()->GetAsSurface(); + if (surface) { + aLayer->DeprecatedUpdateSurface(surface); updated = true; } } From c1ed0c1a1916eb5418fb0d3d8cc2ba469853bbba Mon Sep 17 00:00:00 2001 From: Rick Eyre Date: Wed, 12 Mar 2014 13:55:45 -0400 Subject: [PATCH 10/13] Bug 982183 - Put VTTRegion DOM API behind a pref. r=rillian, r=bz --- content/media/TextTrackRegion.h | 7 +++++++ content/media/test/test_texttrackcue.html | 3 ++- content/media/test/test_texttrackregion.html | 3 ++- dom/tests/mochitest/general/test_interfaces.html | 2 +- dom/webidl/VTTCue.webidl | 1 + dom/webidl/VTTRegion.webidl | 2 +- modules/libpref/src/init/all.js | 1 + 7 files changed, 15 insertions(+), 4 deletions(-) diff --git a/content/media/TextTrackRegion.h b/content/media/TextTrackRegion.h index 775af6cf30ad..fa4f1c63c980 100644 --- a/content/media/TextTrackRegion.h +++ b/content/media/TextTrackRegion.h @@ -13,6 +13,7 @@ #include "nsWrapperCache.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/TextTrack.h" +#include "mozilla/Preferences.h" namespace mozilla { namespace dom { @@ -28,6 +29,12 @@ public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TextTrackRegion) + static bool RegionsEnabled(JSContext* cx, JSObject* obj) + { + return Preferences::GetBool("media.webvtt.enabled") && + Preferences::GetBool("media.webvtt.regions.enabled"); + } + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aScope) MOZ_OVERRIDE; diff --git a/content/media/test/test_texttrackcue.html b/content/media/test/test_texttrackcue.html index 0652ef6956a9..56e8056daa70 100644 --- a/content/media/test/test_texttrackcue.html +++ b/content/media/test/test_texttrackcue.html @@ -17,7 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=833386