Bug 605362, part 1: Allocate page-aligned shmem segments in ShmImage, to match other allocators which more honestly report address space and system mem taken by alloc. r=joe
authorChris Jones <jones.chris.g@gmail.com>
Fri, 05 Nov 2010 02:17:07 -0500
changeset 56906 f5e82d1422e6a32df20373b16533c9868cdbf679
parent 56905 1e1c3519b5a911246dcd980c360c6d0a86a0271f
child 56907 62bbf0aed452646c77fcf9074c31545cc37154e7
push idunknown
push userunknown
push dateunknown
reviewersjoe
bugs605362
milestone2.0b8pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 605362, part 1: Allocate page-aligned shmem segments in ShmImage, to match other allocators which more honestly report address space and system mem taken by alloc. r=joe
ipc/glue/Makefile.in
ipc/glue/SharedMemory.cpp
ipc/glue/SharedMemory.h
ipc/glue/Shmem.cpp
widget/src/shared/nsShmImage.cpp
widget/src/shared/nsShmImage.h
--- a/ipc/glue/Makefile.in
+++ b/ipc/glue/Makefile.in
@@ -84,16 +84,17 @@ ENABLE_CXX_EXCEPTIONS = 1
 CPPSRCS += \
   AsyncChannel.cpp \
   BrowserProcessSubThread.cpp \
   GeckoChildProcessHost.cpp \
   MessagePump.cpp \
   ProcessChild.cpp \
   RPCChannel.cpp \
   ScopedXREEmbed.cpp \
+  SharedMemory.cpp \
   Shmem.cpp \
   StringUtil.cpp \
   SyncChannel.cpp \
   $(NULL)
 
 ifeq ($(OS_ARCH),WINNT)
 CPPSRCS += \
   SharedMemory_windows.cpp \
new file mode 100644
--- /dev/null
+++ b/ipc/glue/SharedMemory.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * vim: sw=2 ts=8 et :
+ */
+/* ***** 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 Code.
+ *
+ * The Initial Developer of the Original Code is
+ *   The Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Chris Jones <jones.chris.g@gmail.com>
+ *
+ * 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 <math.h>
+
+#include "mozilla/ipc/SharedMemory.h"
+
+namespace mozilla {
+namespace ipc {
+
+/*static*/ size_t
+SharedMemory::PageAlignedSize(size_t aSize)
+{
+  size_t pageSize = SystemPageSize();
+  size_t nPagesNeeded = size_t(ceil(double(aSize) / double(pageSize)));
+  return pageSize * nPagesNeeded;
+}
+
+} // namespace ipc
+} // namespace mozilla
--- a/ipc/glue/SharedMemory.h
+++ b/ipc/glue/SharedMemory.h
@@ -98,15 +98,16 @@ public:
     // checks alignment etc.
     SystemProtect(aAddr, aSize, aRights);
   }
 
   NS_INLINE_DECL_REFCOUNTING(SharedMemory)
 
   static void SystemProtect(char* aAddr, size_t aSize, int aRights);
   static size_t SystemPageSize();
+  static size_t PageAlignedSize(size_t aSize);
 };
 
 } // namespace ipc
 } // namespace mozilla
 
 
 #endif // ifndef mozilla_ipc_SharedMemory_h
--- a/ipc/glue/Shmem.cpp
+++ b/ipc/glue/Shmem.cpp
@@ -33,18 +33,16 @@
  * 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 <math.h>
-
 #include "Shmem.h"
 
 #include "ProtocolUtils.h"
 #include "SharedMemoryBasic.h"
 #include "SharedMemorySysV.h"
 
 #include "nsAutoPtr.h"
 
@@ -191,24 +189,16 @@ CreateSegment(size_t aNBytes, SharedMemo
 static void
 DestroySegment(SharedMemory* aSegment)
 {
   // the SharedMemory dtor closes and unmaps the actual OS shmem segment
   if (aSegment)
     aSegment->Release();
 }
 
-static size_t
-PageAlignedSize(size_t aSize)
-{
-  size_t pageSize = SharedMemory::SystemPageSize();
-  size_t nPagesNeeded = int(ceil(double(aSize) / double(pageSize)));
-  return pageSize * nPagesNeeded;
-}
-
 
 #if defined(DEBUG)
 
 static const char sMagic[] =
     "This little piggy went to market.\n"
     "This little piggy stayed at home.\n"
     "This little piggy has roast beef,\n"
     "This little piggy had none.\n"
@@ -396,17 +386,17 @@ Shmem::Alloc(IHadBetterBeIPDLCodeCalling
              bool aProtect)
 {
   NS_ASSERTION(aNBytes <= PR_UINT32_MAX, "Will truncate shmem segment size!");
   NS_ABORT_IF_FALSE(!aProtect || !aUnsafe, "protect => !unsafe");
 
   size_t pageSize = SharedMemory::SystemPageSize();
   SharedMemory* segment = nsnull;
   // |2*pageSize| is for the front and back sentinel
-  size_t segmentSize = PageAlignedSize(aNBytes + 2*pageSize);
+  size_t segmentSize = SharedMemory::PageAlignedSize(aNBytes + 2*pageSize);
 
   if (aType == SharedMemory::TYPE_BASIC)
     segment = CreateSegment(segmentSize, SharedMemoryBasic::NULLHandle());
 #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
   else if (aType == SharedMemory::TYPE_SYSV)
     segment = CreateSegment(segmentSize, SharedMemorySysV::NULLHandle());
 #endif
   else
@@ -452,17 +442,17 @@ Shmem::OpenExisting(IHadBetterBeIPDLCode
   SharedMemory::SharedMemoryType type;
   size_t size;
   if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, &size, &type))
     return 0;
 
   SharedMemory* segment = 0;
   size_t pageSize = SharedMemory::SystemPageSize();
   // |2*pageSize| is for the front and back sentinels
-  size_t segmentSize = PageAlignedSize(size + 2*pageSize);
+  size_t segmentSize = SharedMemory::PageAlignedSize(size + 2*pageSize);
 
   if (SharedMemory::TYPE_BASIC == type) {
     SharedMemoryBasic::Handle handle;
     if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle))
       return 0;
 
     if (!SharedMemoryBasic::IsHandleValid(handle))
       NS_RUNTIMEABORT("trying to open invalid handle");
@@ -527,21 +517,21 @@ Shmem::Alloc(IHadBetterBeIPDLCodeCalling
              size_t aNBytes, 
              SharedMemoryType aType,
              bool /*unused*/,
              bool /*unused*/)
 {
   SharedMemory *segment = nsnull;
 
   if (aType == SharedMemory::TYPE_BASIC)
-    segment = CreateSegment(PageAlignedSize(aNBytes + sizeof(uint32)),
+    segment = CreateSegment(SharedMemory::PageAlignedSize(aNBytes + sizeof(uint32)),
                             SharedMemoryBasic::NULLHandle());
 #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
   else if (aType == SharedMemory::TYPE_SYSV)
-    segment = CreateSegment(PageAlignedSize(aNBytes + sizeof(uint32)),
+    segment = CreateSegment(SharedMemory::PageAlignedSize(aNBytes + sizeof(uint32)),
                             SharedMemorySysV::NULLHandle());
 #endif
   else
     // Unhandled!!
     NS_ABORT();
 
   if (!segment)
     return 0;
@@ -563,17 +553,17 @@ Shmem::OpenExisting(IHadBetterBeIPDLCode
 
   SharedMemory::SharedMemoryType type;
   void* iter = 0;
   size_t size;
   if (!ShmemCreated::ReadInfo(&aDescriptor, &iter, aId, &size, &type))
     return 0;
 
   SharedMemory* segment = 0;
-  size_t segmentSize = PageAlignedSize(size + sizeof(size_t));
+  size_t segmentSize = SharedMemory::PageAlignedSize(size + sizeof(size_t));
 
   if (SharedMemory::TYPE_BASIC == type) {
     SharedMemoryBasic::Handle handle;
     if (!ShmemCreated::ReadHandle(&aDescriptor, &iter, &handle))
       return 0;
 
     if (!SharedMemoryBasic::IsHandleValid(handle))
       NS_RUNTIMEABORT("trying to open invalid handle");
--- a/widget/src/shared/nsShmImage.cpp
+++ b/widget/src/shared/nsShmImage.cpp
@@ -46,16 +46,18 @@
 #endif
 
 #include "nsShmImage.h"
 #include "gfxPlatform.h"
 #include "gfxImageSurface.h"
 
 #ifdef MOZ_HAVE_SHMIMAGE
 
+using namespace mozilla::ipc;
+
 // If XShm isn't available to our client, we'll try XShm once, fail,
 // set this to false and then never try again.
 static PRBool gShmAvailable = PR_TRUE;
 PRBool nsShmImage::UseShm()
 {
     return gfxPlatform::GetPlatform()->
         ScreenReferenceSurface()->GetType() == gfxASurface::SurfaceTypeImage
         && gShmAvailable;
@@ -71,17 +73,18 @@ nsShmImage::Create(const gfxIntSize& aSi
     shm->mImage = XShmCreateImage(dpy, aVisual, aDepth,
                                   ZPixmap, nsnull,
                                   &(shm->mInfo),
                                   aSize.width, aSize.height);
     if (!shm->mImage) {
         return nsnull;
     }
 
-    size_t size = shm->mImage->bytes_per_line * shm->mImage->height;
+    size_t size = SharedMemory::PageAlignedSize(
+        shm->mImage->bytes_per_line * shm->mImage->height);
     shm->mSegment = new SharedMemorySysV();
     if (!shm->mSegment->Create(size) || !shm->mSegment->Map(size)) {
         return nsnull;
     }
 
     shm->mInfo.shmid = shm->mSegment->GetHandle();
     shm->mInfo.shmaddr =
         shm->mImage->data = static_cast<char*>(shm->mSegment->memory());
--- a/widget/src/shared/nsShmImage.h
+++ b/widget/src/shared/nsShmImage.h
@@ -63,21 +63,21 @@
 #elif defined(MOZ_WIDGET_QT)
 #include "QX11Info"
 #define DISPLAY QX11Info().display
 #endif
 
 class QRect;
 class QWidget;
 
-using mozilla::ipc::SharedMemorySysV;
-
 class nsShmImage {
     NS_INLINE_DECL_REFCOUNTING(nsShmImage)
 
+    typedef mozilla::ipc::SharedMemorySysV SharedMemorySysV;
+
 public:
     typedef gfxASurface::gfxImageFormat Format;
 
     static PRBool UseShm();
     static already_AddRefed<nsShmImage>
         Create(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth);
     static already_AddRefed<gfxASurface>
         EnsureShmImage(const gfxIntSize& aSize, Visual* aVisual, unsigned int aDepth,