Back out a5377cd1e45e (bug 945152 part 1) to clear way for other fixing. Also should reland in short order once those other fixes land. r=backout
authorJeff Walden <jwalden@mit.edu>
Fri, 14 Mar 2014 16:39:23 -0700
changeset 190915 2b29e7ac771ea62b0369bbbc0c2e985f8e7c24b8
parent 190914 963a4aa8327511fee587a251d1b082b1dffad7a2
child 190916 fa8369f3ad5799506ee984b86d731544d7145965
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs945152
milestone30.0a1
backs outa5377cd1e45e3b3cb68ea3012a6de8d57ed1d0c2
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
Back out a5377cd1e45e (bug 945152 part 1) to clear way for other fixing. Also should reland in short order once those other fixes land. r=backout
js/src/gc/Memory.cpp
js/src/gc/Memory.h
js/src/jsapi-tests/moz.build
js/src/jsapi-tests/testMappedArrayBuffer.cpp
js/src/jsapi.h
js/src/jsobjinlines.h
js/src/vm/ArrayBufferObject.cpp
js/src/vm/ArrayBufferObject.h
js/src/vm/ObjectImpl.h
js/src/vm/StructuredClone.cpp
--- a/js/src/gc/Memory.cpp
+++ b/js/src/gc/Memory.cpp
@@ -102,31 +102,16 @@ size_t
 gc::GetPageFaultCount()
 {
     PROCESS_MEMORY_COUNTERS pmc;
     if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
         return 0;
     return pmc.PageFaultCount;
 }
 
-void *
-gc::AllocateMappedObject(int fd, int *new_fd, size_t offset, size_t length,
-                         size_t alignment, size_t header)
-{
-    // TODO: to be implemented.
-    return nullptr;
-}
-
-// Deallocate mapped memory for object.
-void
-gc::DeallocateMappedObject(int fd, void *p, size_t length)
-{
-    // TODO: to be implemented.
-}
-
 #elif defined(SOLARIS)
 
 #include <sys/mman.h>
 #include <unistd.h>
 
 #ifndef MAP_NOSYNC
 # define MAP_NOSYNC 0
 #endif
@@ -175,38 +160,20 @@ gc::MarkPagesInUse(JSRuntime *rt, void *
 }
 
 size_t
 gc::GetPageFaultCount()
 {
     return 0;
 }
 
-void *
-gc::AllocateMappedObject(int fd, int *new_fd, size_t offset, size_t length,
-                         size_t alignment, size_t header)
-{
-    // TODO: to be implemented.
-    return nullptr;
-}
-
-// Deallocate mapped memory for object.
-void
-gc::DeallocateMappedObject(int fd, void *p, size_t length)
-{
-    // TODO: to be implemented.
-}
-
 #elif defined(XP_UNIX)
 
-#include <algorithm>
 #include <sys/mman.h>
 #include <sys/resource.h>
-#include <sys/stat.h>
-#include <sys/types.h>
 #include <unistd.h>
 
 void
 gc::InitMemorySubsystem(JSRuntime *rt)
 {
     rt->gcSystemPageSize = rt->gcSystemAllocGranularity = size_t(sysconf(_SC_PAGESIZE));
 }
 
@@ -313,95 +280,11 @@ gc::GetPageFaultCount()
 {
     struct rusage usage;
     int err = getrusage(RUSAGE_SELF, &usage);
     if (err)
         return 0;
     return usage.ru_majflt;
 }
 
-void *
-gc::AllocateMappedObject(int fd, int *new_fd, size_t offset, size_t length,
-                         size_t alignment, size_t header)
-{
-#define NEED_PAGE_ALIGNED 0
-    size_t pa_start; // Page aligned starting
-    size_t pa_end; // Page aligned ending
-    size_t pa_size; // Total page aligned size
-    size_t page_size = sysconf(_SC_PAGESIZE); // Page size
-    bool page_for_header = false; // Do we need an additional page for header?
-    struct stat st;
-    uint8_t *buf;
-
-    // Make sure file exists and do sanity check for offset and size.
-    if (fstat(fd, &st) < 0 || offset >= (size_t) st.st_size ||
-        length == 0 || length > (size_t) st.st_size - offset)
-        return nullptr;
-
-    // Check for minimal alignment requirement.
-#if NEED_PAGE_ALIGNED
-    alignment = std::max(alignment, page_size);
-#endif
-    if (offset & (alignment - 1))
-        return nullptr;
-
-    // Page aligned starting of the offset.
-    pa_start = offset & ~(page_size - 1);
-    // Calculate page aligned ending by adding one page to the page aligned
-    // starting of data end position(offset + length - 1).
-    pa_end = ((offset + length - 1) & ~(page_size - 1)) + page_size;
-    pa_size = pa_end - pa_start;
-
-    // Do we need one more page for header?
-    if (offset - pa_start < header) {
-        page_for_header = true;
-        pa_size += page_size;
-    }
-
-    // Ask for a continuous memory location.
-    buf = (uint8_t *) MapMemory(pa_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
-    if (buf == MAP_FAILED)
-        return nullptr;
-
-    // Duplicate a new fd for mapping, so each cloned object uses a different fd.
-    *new_fd = dup(fd);
-
-    // If there's an additional page for header, don't map that page to file.
-    if (page_for_header) {
-        buf = (uint8_t *) mmap(buf + page_size, pa_size - page_size,
-                               PROT_READ | PROT_WRITE,
-                               MAP_PRIVATE | MAP_FIXED, *new_fd, pa_start);
-    } else {
-        buf = (uint8_t *) mmap(buf, pa_size, PROT_READ | PROT_WRITE,
-                               MAP_PRIVATE | MAP_FIXED, *new_fd, pa_start);
-    }
-    if (buf == MAP_FAILED) {
-        close(*new_fd);
-        return nullptr;
-    }
-
-    // Reset the data before target file, which we don't need to see.
-    memset(buf, 0, offset - pa_start);
-
-    // Reset the data after target file, which we don't need to see.
-    memset(buf + (offset - pa_start) + length, 0, pa_end - (offset + length));
-
-    return buf + (offset - pa_start) - header;
-}
-
-void
-gc::DeallocateMappedObject(int fd, void *p, size_t length)
-{
-    void *pa_start; // Page aligned starting
-    size_t page_size = sysconf(_SC_PAGESIZE); // Page size
-    size_t total_size; // Total allocated size
-
-    // The fd is not needed anymore.
-    close(fd);
-
-    pa_start = (void *)(uintptr_t(p) & ~(page_size - 1));
-    total_size = ((uintptr_t(p) + length) & ~(page_size - 1)) + page_size - uintptr_t(pa_start);
-    munmap(pa_start, total_size);
-}
-
 #else
 #error "Memory mapping functions are not defined for your OS."
 #endif
--- a/js/src/gc/Memory.h
+++ b/js/src/gc/Memory.h
@@ -36,25 +36,12 @@ MarkPagesUnused(JSRuntime *rt, void *p, 
 // platforms.
 bool
 MarkPagesInUse(JSRuntime *rt, void *p, size_t size);
 
 // Returns #(hard faults) + #(soft faults)
 size_t
 GetPageFaultCount();
 
-// Allocate mapped memory for object from file descriptor, offset and length
-// of the file.
-// The new_fd is duplicated from original fd, for the purpose of cloned object.
-// The offset must be aligned according to alignment requirement.
-// An additional page might be allocated depending on offset and header size given.
-void *
-AllocateMappedObject(int fd, int *new_fd, size_t offset, size_t length,
-                     size_t alignment, size_t header);
-
-// Deallocate mapped memory of the object.
-void
-DeallocateMappedObject(int fd, void *p, size_t length);
-
 } // namespace gc
 } // namespace js
 
 #endif /* gc_Memory_h */
--- a/js/src/jsapi-tests/moz.build
+++ b/js/src/jsapi-tests/moz.build
@@ -40,17 +40,16 @@ UNIFIED_SOURCES += [
     'testHashTableInit.cpp',
     'testIndexToString.cpp',
     'testIntern.cpp',
     'testIntString.cpp',
     'testIntTypesABI.cpp',
     'testJSEvaluateScript.cpp',
     'testLookup.cpp',
     'testLooselyEqual.cpp',
-    'testMappedArrayBuffer.cpp',
     'testNewObject.cpp',
     'testNullRoot.cpp',
     'testObjectEmulatingUndefined.cpp',
     'testOOM.cpp',
     'testOps.cpp',
     'testOriginPrincipals.cpp',
     'testParseJSON.cpp',
     'testPersistentRooted.cpp',
deleted file mode 100644
--- a/js/src/jsapi-tests/testMappedArrayBuffer.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sts=4 et sw=4 tw=99:
- */
-
-#ifdef XP_UNIX
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "jsfriendapi.h"
-#include "js/StructuredClone.h"
-#include "jsapi-tests/tests.h"
-#include "vm/ArrayBufferObject.h"
-
-const char test_data[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-const char test_filename[] = "temp-bug945152_MappedArrayBuffer";
-
-BEGIN_TEST(testMappedArrayBuffer_bug945152)
-{
-    TempFile test_file;
-    FILE *test_stream = test_file.open(test_filename);
-    CHECK(fputs(test_data, test_stream) != EOF);
-    test_file.close();
-
-    // Offset 0.
-    CHECK(TestCreateObject(0, 12));
-
-    // Aligned offset.
-    CHECK(TestCreateObject(8, 12));
-
-    // Unaligned offset.
-    CHECK(CreateNewObject(11, 12) == nullptr);
-
-    // Offset + length greater than file size.
-    CHECK(CreateNewObject(8, sizeof(test_data) - 7) == nullptr);
-
-    // Release the mapped content.
-    CHECK(TestReleaseContents());
-
-#ifdef JSGC_USE_EXACT_ROOTING
-    // Ensure that fd is closed after object been GCed.
-    // Check the fd returned from object created in a function,
-    // then do the GC, in order to guarantee the object is freed when
-    // exact rooting is not on.
-    int fd = GetNewObjectFD();
-    GC(cx);
-    CHECK(!fd_is_valid(fd));
-#endif
-
-    // Neuter mapped array buffer.
-    CHECK(TestNeuterObject());
-
-    // Clone mapped array buffer.
-    CHECK(TestCloneObject());
-
-    test_file.remove();
-
-    return true;
-}
-
-JSObject *CreateNewObject(const int offset, const int length)
-{
-    int fd = open(test_filename, O_RDONLY);
-    void *ptr;
-    int new_fd;
-    if (!JS_CreateMappedArrayBufferContents(fd, &new_fd, offset, length, &ptr))
-        return nullptr;
-    JSObject *obj = JS_NewArrayBufferWithContents(cx, ptr);
-    close(fd);
-
-    return obj;
-}
-
-// Return the fd from object created in the stack.
-int GetNewObjectFD()
-{
-    JS::RootedObject obj(cx, CreateNewObject(0, 12));
-    int fd = getFD(obj);
-    CHECK(fd_is_valid(fd));
-
-    return fd;
-}
-
-bool VerifyObject(JS::HandleObject obj, const int offset, const int length)
-{
-    CHECK(obj != nullptr);
-    CHECK(JS_IsArrayBufferObject(obj));
-    CHECK_EQUAL(JS_GetArrayBufferByteLength(obj), length);
-    js::ArrayBufferObject *buf = &obj->as<js::ArrayBufferObject>();
-    CHECK(buf->isMappedArrayBuffer());
-    const char *data = reinterpret_cast<const char *>(JS_GetArrayBufferData(obj));
-    CHECK(data != nullptr);
-    CHECK(memcmp(data, test_data + offset, length) == 0);
-
-    return true;
-}
-
-bool TestCreateObject(const int offset, const int length)
-{
-    JS::RootedObject obj(cx, CreateNewObject(offset, length));
-    CHECK(VerifyObject(obj, offset, length));
-
-    return true;
-}
-
-bool TestReleaseContents()
-{
-    int fd = open(test_filename, O_RDONLY);
-    void *ptr;
-    int new_fd;
-    if (!JS_CreateMappedArrayBufferContents(fd, &new_fd, 0, 12, &ptr))
-        return false;
-    CHECK(fd_is_valid(new_fd));
-    JS_ReleaseMappedArrayBufferContents(new_fd, ptr, 12);
-    CHECK(!fd_is_valid(new_fd));
-    close(fd);
-
-    return true;
-}
-
-bool TestNeuterObject()
-{
-    JS::RootedObject obj(cx, CreateNewObject(8, 12));
-    CHECK(obj != nullptr);
-    int fd = getFD(obj);
-    CHECK(fd_is_valid(fd));
-    JS_NeuterArrayBuffer(cx, obj);
-    CHECK(isNeutered(obj));
-    CHECK(!fd_is_valid(fd));
-
-    return true;
-}
-
-bool TestCloneObject()
-{
-    JS::RootedObject obj1(cx, CreateNewObject(8, 12));
-    CHECK(obj1 != nullptr);
-    JSAutoStructuredCloneBuffer cloned_buffer;
-    JS::RootedValue v1(cx, OBJECT_TO_JSVAL(obj1));
-    const JSStructuredCloneCallbacks *callbacks = js::GetContextStructuredCloneCallbacks(cx);
-    CHECK(cloned_buffer.write(cx, v1, callbacks, nullptr));
-    JS::RootedValue v2(cx);
-    CHECK(cloned_buffer.read(cx, &v2, callbacks, nullptr));
-    JS::RootedObject obj2(cx, JSVAL_TO_OBJECT(v2));
-    CHECK(VerifyObject(obj2, 8, 12));
-
-    return true;
-}
-
-bool isNeutered(JS::HandleObject obj)
-{
-    JS::RootedValue v(cx);
-    return JS_GetProperty(cx, obj, "byteLength", &v) && v.toInt32() == 0;
-}
-
-int getFD(JS::HandleObject obj)
-{
-    CHECK(obj != nullptr);
-    js::ArrayBufferObject *buf = &obj->as<js::ArrayBufferObject>();
-    return buf->getMappingFD();
-}
-
-static bool fd_is_valid(int fd)
-{
-     return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
-}
-
-static void GC(JSContext *cx)
-{
-    JS_GC(JS_GetRuntime(cx));
-    // Trigger another to wait for background finalization to end.
-    JS_GC(JS_GetRuntime(cx));
-}
-
-END_TEST(testMappedArrayBuffer_bug945152)
-#endif
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -3156,36 +3156,16 @@ JS_AllocateArrayBufferContents(JSContext
 /*
  * Reallocate memory allocated by JS_AllocateArrayBufferContents, growing or
  * shrinking it as appropriate.  The new data pointer will be returned in data.
  * If *contents is nullptr, behaves like JS_AllocateArrayBufferContents.
  */
 extern JS_PUBLIC_API(bool)
 JS_ReallocateArrayBufferContents(JSContext *cx, uint32_t nbytes, void **contents, uint8_t **data);
 
-/*
- * Create memory mapped array buffer contents.
- * For cloning, the fd will not be closed after mapping, and the caller must
- * take care of closing fd after calling this function.
- * A new duplicated fd used by the mapping is returned in new_fd.
- */
-extern JS_PUBLIC_API(bool)
-JS_CreateMappedArrayBufferContents(int fd, int *new_fd, size_t offset,
-                                   size_t length, void **contents);
-
-/*
- * Release the allocated resource of mapped array buffer contents before the
- * object is created.
- * If a new object has been created by JS_NewArrayBufferWithContents() with
- * this content, then JS_NeuterArrayBuffer() should be used instead to release
- * the resource used by the object.
- */
-extern JS_PUBLIC_API(void)
-JS_ReleaseMappedArrayBufferContents(int fd, void *contents, size_t length);
-
 extern JS_PUBLIC_API(JSIdArray *)
 JS_Enumerate(JSContext *cx, JSObject *obj);
 
 /*
  * Create an object to iterate over enumerable properties of obj, in arbitrary
  * property definition order.  NB: This differs from longstanding for..in loop
  * order, which uses order of property definition in obj.
  */
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -572,18 +572,16 @@ inline void
 JSObject::finish(js::FreeOp *fop)
 {
     if (hasDynamicSlots())
         fop->free_(slots);
     if (hasDynamicElements()) {
         js::ObjectElements *elements = getElementsHeader();
         if (MOZ_UNLIKELY(elements->isAsmJSArrayBuffer()))
             js::ArrayBufferObject::releaseAsmJSArrayBuffer(fop, this);
-        else if (MOZ_UNLIKELY(elements->isMappedArrayBuffer()))
-            js::ArrayBufferObject::releaseMappedArrayBuffer(fop, this);
         else
             fop->free_(elements);
     }
 }
 
 /* static */ inline bool
 JSObject::hasProperty(JSContext *cx, js::HandleObject obj,
                       js::HandleId id, bool *foundp, unsigned flags)
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -25,17 +25,16 @@
 #include "jsutil.h"
 #ifdef XP_WIN
 # include "jswin.h"
 #endif
 #include "jswrapper.h"
 
 #include "gc/Barrier.h"
 #include "gc/Marking.h"
-#include "gc/Memory.h"
 #include "jit/AsmJS.h"
 #include "jit/AsmJSModule.h"
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/NumericConversions.h"
 #include "vm/SharedArrayObject.h"
 #include "vm/WrapperObject.h"
 
@@ -474,20 +473,17 @@ ArrayBufferObject::changeContents(JSCont
 }
 
 void
 ArrayBufferObject::neuter(JSContext *cx)
 {
     JS_ASSERT(!isSharedArrayBuffer());
 
     JS_ASSERT(cx);
-    if (isMappedArrayBuffer()) {
-        releaseMappedArrayBuffer(nullptr, this);
-        setFixedElements();
-    } else if (hasDynamicElements() && !isAsmJSArrayBuffer()) {
+    if (hasDynamicElements() && !isAsmJSArrayBuffer()) {
         ObjectElements *oldHeader = getElementsHeader();
         changeContents(cx, ObjectElements::fromElements(fixedElements()));
 
         FreeOp fop(cx->runtime(), false);
         fop.free_(oldHeader);
     }
 
     uint32_t byteLen = 0;
@@ -629,43 +625,16 @@ ArrayBufferObject::neuterAsmJSArrayBuffe
 
     js_ReportOverRecursed(cx);
     return false;
 #else
     return true;
 #endif
 }
 
-void *
-ArrayBufferObject::createMappedArrayBuffer(int fd, int *new_fd, size_t offset, size_t length)
-{
-    void *ptr = AllocateMappedObject(fd, new_fd, offset, length, 8,
-                                     sizeof(MappingInfoHeader) + sizeof(ObjectElements));
-    if (!ptr)
-        return nullptr;
-
-    ptr = reinterpret_cast<void *>(uintptr_t(ptr) + sizeof(MappingInfoHeader));
-    ObjectElements *header = reinterpret_cast<ObjectElements *>(ptr);
-    initMappedElementsHeader(header, *new_fd, offset, length);
-
-    return ptr;
-}
-
-void
-ArrayBufferObject::releaseMappedArrayBuffer(FreeOp *fop, JSObject *obj)
-{
-    ArrayBufferObject &buffer = obj->as<ArrayBufferObject>();
-    if(!buffer.isMappedArrayBuffer() || buffer.isNeutered())
-        return;
-
-    ObjectElements *header = buffer.getElementsHeader();
-    if (header)
-        DeallocateMappedObject(buffer.getMappingFD(), header, header->initializedLength);
-}
-
 void
 ArrayBufferObject::addView(ArrayBufferViewObject *view)
 {
     // This view should never have been associated with a buffer before
     JS_ASSERT(view->bufferLink() == UNSET_BUFFER_LINK);
 
     // Note that pre-barriers are not needed here because either the list was
     // previously empty, in which case no pointer is being overwritten, or the
@@ -1385,31 +1354,16 @@ JS_StealArrayBufferContents(JSContext *c
 
     Rooted<ArrayBufferObject*> buffer(cx, &obj->as<ArrayBufferObject>());
     if (!ArrayBufferObject::stealContents(cx, buffer, contents, data))
         return false;
 
     return true;
 }
 
-JS_PUBLIC_API(bool)
-JS_CreateMappedArrayBufferContents(int fd, int *new_fd, size_t offset,
-                                   size_t length, void **contents)
-{
-    *contents = ArrayBufferObject::createMappedArrayBuffer(fd, new_fd, offset, length);
-
-    return *contents;
-}
-
-JS_PUBLIC_API(void)
-JS_ReleaseMappedArrayBufferContents(int fd, void *contents, size_t length)
-{
-    DeallocateMappedObject(fd, contents, length);
-}
-
 JS_FRIEND_API(void *)
 JS_GetArrayBufferViewData(JSObject *obj)
 {
     obj = CheckedUnwrap(obj);
     if (!obj)
         return nullptr;
     return obj->is<DataViewObject>() ? obj->as<DataViewObject>().dataPointer()
                                      : obj->as<TypedArrayObject>().viewData();
--- a/js/src/vm/ArrayBufferObject.h
+++ b/js/src/vm/ArrayBufferObject.h
@@ -13,23 +13,16 @@
 #include "vm/Runtime.h"
 
 typedef struct JSProperty JSProperty;
 
 namespace js {
 
 class ArrayBufferViewObject;
 
-// Header for mapped array buffer
-struct MappingInfoHeader
-{
-    uint32_t fd;
-    uint32_t offset;
-};
-
 // The inheritance hierarchy for the various classes relating to typed arrays
 // is as follows.
 //
 // - JSObject
 //   - ArrayBufferObject
 //     - SharedArrayBufferObject
 //   - ArrayBufferViewObject
 //     - DataViewObject
@@ -152,43 +145,16 @@ class ArrayBufferObject : public JSObjec
         header->capacity = 0;
     }
 
     static void initElementsHeader(js::ObjectElements *header, uint32_t bytes) {
         header->flags = 0;
         updateElementsHeader(header, bytes);
     }
 
-    static void initMappedElementsHeader(js::ObjectElements *header, uint32_t fd,
-                                         uint32_t offset, uint32_t bytes) {
-        initElementsHeader(header, bytes);
-        header->setIsMappedArrayBuffer();
-        MappingInfoHeader *mh = getMappingInfoHeader(header);
-        mh->fd = fd;
-        mh->offset = offset;
-    }
-
-    static MappingInfoHeader *getMappingInfoHeader(js::ObjectElements *header) {
-        MOZ_ASSERT(header->isMappedArrayBuffer());
-        return reinterpret_cast<MappingInfoHeader *>(uintptr_t(header) -
-                                                     sizeof(MappingInfoHeader));
-    }
-
-    uint32_t getMappingFD() {
-        MOZ_ASSERT(getElementsHeader()->isMappedArrayBuffer());
-        MappingInfoHeader *mh = getMappingInfoHeader(getElementsHeader());
-        return mh->fd;
-    }
-
-    uint32_t getMappingOffset() const {
-        MOZ_ASSERT(getElementsHeader()->isMappedArrayBuffer());
-        MappingInfoHeader *mh = getMappingInfoHeader(getElementsHeader());
-        return mh->offset;
-    }
-
     static uint32_t headerInitializedLength(const js::ObjectElements *header) {
         return header->initializedLength;
     }
 
     void addView(ArrayBufferViewObject *view);
 
     void changeContents(JSContext *cx, ObjectElements *newHeader);
 
@@ -231,25 +197,16 @@ class ArrayBufferObject : public JSObjec
         return getElementsHeader()->isAsmJSArrayBuffer();
     }
     bool isNeutered() const {
         return getElementsHeader()->isNeuteredBuffer();
     }
     static bool prepareForAsmJS(JSContext *cx, Handle<ArrayBufferObject*> buffer);
     static bool neuterAsmJSArrayBuffer(JSContext *cx, ArrayBufferObject &buffer);
     static void releaseAsmJSArrayBuffer(FreeOp *fop, JSObject *obj);
-
-    bool isMappedArrayBuffer() const {
-        return getElementsHeader()->isMappedArrayBuffer();
-    }
-    void setIsMappedArrayBuffer() {
-        getElementsHeader()->setIsMappedArrayBuffer();
-    }
-    static void *createMappedArrayBuffer(int fd, int *new_fd, size_t offset, size_t length);
-    static void releaseMappedArrayBuffer(FreeOp *fop, JSObject *obj);
 };
 
 /*
  * ArrayBufferViewObject
  *
  * Common definitions shared by all ArrayBufferViews.
  */
 
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -166,21 +166,20 @@ ArraySetLength(typename ExecutionModeTra
 class ObjectElements
 {
   public:
     enum Flags {
         CONVERT_DOUBLE_ELEMENTS     = 0x1,
         ASMJS_ARRAY_BUFFER          = 0x2,
         NEUTERED_BUFFER             = 0x4,
         SHARED_ARRAY_BUFFER         = 0x8,
-        MAPPED_ARRAY_BUFFER         = 0x10,
 
         // Present only if these elements correspond to an array with
         // non-writable length; never present for non-arrays.
-        NONWRITABLE_ARRAY_LENGTH    = 0x20,
+        NONWRITABLE_ARRAY_LENGTH    = 0x10
     };
 
   private:
     friend class ::JSObject;
     friend class ObjectImpl;
     friend class ArrayObject;
     friend class ArrayBufferObject;
     friend class ArrayBufferViewObject;
@@ -245,22 +244,16 @@ class ObjectElements
         flags |= NEUTERED_BUFFER;
     }
     bool isSharedArrayBuffer() const {
         return flags & SHARED_ARRAY_BUFFER;
     }
     void setIsSharedArrayBuffer() {
         flags |= SHARED_ARRAY_BUFFER;
     }
-    bool isMappedArrayBuffer() const {
-        return flags & MAPPED_ARRAY_BUFFER;
-    }
-    void setIsMappedArrayBuffer() {
-        flags |= MAPPED_ARRAY_BUFFER;
-    }
     bool hasNonwritableArrayLength() const {
         return flags & NONWRITABLE_ARRAY_LENGTH;
     }
     void setNonwritableArrayLength() {
         flags |= NONWRITABLE_ARRAY_LENGTH;
     }
 
   public:
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -61,17 +61,16 @@ enum StructuredDataType {
     SCTAG_BOOLEAN,
     SCTAG_INDEX,
     SCTAG_STRING,
     SCTAG_DATE_OBJECT,
     SCTAG_REGEXP_OBJECT,
     SCTAG_ARRAY_OBJECT,
     SCTAG_OBJECT_OBJECT,
     SCTAG_ARRAY_BUFFER_OBJECT,
-    SCTAG_MAPPED_ARRAY_BUFFER_OBJECT,
     SCTAG_BOOLEAN_OBJECT,
     SCTAG_STRING_OBJECT,
     SCTAG_NUMBER_OBJECT,
     SCTAG_BACK_REFERENCE_OBJECT,
     SCTAG_DO_NOT_USE_1,
     SCTAG_DO_NOT_USE_2,
     SCTAG_TYPED_ARRAY_OBJECT,
     SCTAG_TYPED_ARRAY_V1_MIN = 0xFFFF0100,
@@ -208,17 +207,16 @@ struct JSStructuredCloneReader {
     JSContext *context() { return in.context(); }
 
     bool readTransferMap();
 
     bool checkDouble(double d);
     JSString *readString(uint32_t nchars);
     bool readTypedArray(uint32_t arrayType, uint32_t nelems, js::Value *vp, bool v1Read = false);
     bool readArrayBuffer(uint32_t nbytes, js::Value *vp);
-    bool readMappedArrayBuffer(Value *vp, uint32_t fd, uint32_t offset, uint32_t length);
     bool readV1ArrayBuffer(uint32_t arrayType, uint32_t nelems, js::Value *vp);
     bool readId(jsid *idp);
     bool startRead(js::Value *vp);
 
     js::SCInput &in;
 
     // Stack of objects with properties remaining to be read.
     js::AutoValueVector objs;
@@ -828,22 +826,16 @@ JSStructuredCloneWriter::writeTypedArray
 
     return out.write(tarr->byteOffset());
 }
 
 bool
 JSStructuredCloneWriter::writeArrayBuffer(HandleObject obj)
 {
     ArrayBufferObject &buffer = obj->as<ArrayBufferObject>();
-
-    if (buffer.isMappedArrayBuffer()) {
-        return out.writePair(SCTAG_MAPPED_ARRAY_BUFFER_OBJECT, buffer.byteLength()) &&
-               out.writePair(buffer.getMappingFD(), buffer.getMappingOffset());
-    }
-
     return out.writePair(SCTAG_ARRAY_BUFFER_OBJECT, buffer.byteLength()) &&
            out.writeBytes(buffer.dataPointer(), buffer.byteLength());
 }
 
 bool
 JSStructuredCloneWriter::startObject(HandleObject obj, bool *backref)
 {
     /* Handle cycles in the object graph. */
@@ -1231,36 +1223,16 @@ JSStructuredCloneReader::readArrayBuffer
     if (!obj)
         return false;
     vp->setObject(*obj);
     ArrayBufferObject &buffer = obj->as<ArrayBufferObject>();
     JS_ASSERT(buffer.byteLength() == nbytes);
     return in.readArray(buffer.dataPointer(), nbytes);
 }
 
-bool
-JSStructuredCloneReader::readMappedArrayBuffer(Value *vp, uint32_t fd,
-                                               uint32_t offset, uint32_t length)
-{
-    void *ptr;
-    int new_fd;
-    if(!JS_CreateMappedArrayBufferContents(fd, &new_fd, offset, length, &ptr)) {
-        JS_ReportError(context(), "Failed to create mapped array buffer contents");
-        return false;
-    }
-    JSObject *obj = JS_NewArrayBufferWithContents(context(), ptr);
-    if (!obj) {
-        JS_ReleaseMappedArrayBufferContents(new_fd, ptr, length);
-        return false;
-    }
-    vp->setObject(*obj);
-
-    return true;
-}
-
 static size_t
 bytesPerTypedArrayElement(uint32_t arrayType)
 {
     switch (arrayType) {
       case ScalarTypeDescr::TYPE_INT8:
       case ScalarTypeDescr::TYPE_UINT8:
       case ScalarTypeDescr::TYPE_UINT8_CLAMPED:
         return sizeof(uint8_t);
@@ -1435,24 +1407,16 @@ JSStructuredCloneReader::startRead(Value
                              "invalid input");
         return false;
 
       case SCTAG_ARRAY_BUFFER_OBJECT:
         if (!readArrayBuffer(data, vp))
             return false;
         break;
 
-      case SCTAG_MAPPED_ARRAY_BUFFER_OBJECT:
-        uint32_t fd, offset;
-        if (!in.readPair(&fd, &offset))
-            return false;
-        if (!readMappedArrayBuffer(vp, fd, offset, data))
-            return false;
-        break;
-
       case SCTAG_TYPED_ARRAY_OBJECT:
         // readTypedArray adds the array to allObjs
         uint64_t arrayType;
         if (!in.read(&arrayType))
             return false;
         return readTypedArray(arrayType, data, vp);
         break;